xorg-server-1.20.13/0000755000175000017500000000000014100574023011136 500000000000000xorg-server-1.20.13/composite/0000755000175000017500000000000014100574020013135 500000000000000xorg-server-1.20.13/composite/meson.build0000644000175000017500000000051514100573755015236 00000000000000srcs_composite = [ 'compalloc.c', 'compext.c', 'compinit.c', 'compoverlay.c', 'compwindow.c', ] hdrs_composite = [ 'compositeext.h', ] libxserver_composite = static_library('libxserver_composite', srcs_composite, include_directories: inc, dependencies: common_dep, ) install_data(hdrs_composite, install_dir: xorgsdkdir) xorg-server-1.20.13/composite/Makefile.am0000644000175000017500000000034714100573755015133 00000000000000noinst_LTLIBRARIES = libcomposite.la AM_CFLAGS = $(DIX_CFLAGS) if XORG sdk_HEADERS = compositeext.h endif libcomposite_la_SOURCES = \ compalloc.c \ compext.c \ compint.h \ compinit.c \ compoverlay.c \ compwindow.c xorg-server-1.20.13/composite/compositeext.h0000644000175000017500000000367614100573755016003 00000000000000/* * Copyright © 2009 NVIDIA Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef _COMPOSITEEXT_H_ #define _COMPOSITEEXT_H_ #include "misc.h" #include "scrnintstr.h" extern _X_EXPORT Bool CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids, int nVisuals); extern _X_EXPORT Bool CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen, VisualID parentVisual, VisualID winVisual); extern _X_EXPORT Bool compIsAlternateVisual(ScreenPtr pScreen, XID visual); extern _X_EXPORT RESTYPE CompositeClientWindowType; #endif /* _COMPOSITEEXT_H_ */ xorg-server-1.20.13/composite/Makefile.in0000644000175000017500000007166014100573774015153 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = composite ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__sdk_HEADERS_DIST) \ $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcomposite_la_LIBADD = am_libcomposite_la_OBJECTS = compalloc.lo compext.lo compinit.lo \ compoverlay.lo compwindow.lo libcomposite_la_OBJECTS = $(am_libcomposite_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/compalloc.Plo \ ./$(DEPDIR)/compext.Plo ./$(DEPDIR)/compinit.Plo \ ./$(DEPDIR)/compoverlay.Plo ./$(DEPDIR)/compwindow.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcomposite_la_SOURCES) DIST_SOURCES = $(libcomposite_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__sdk_HEADERS_DIST = compositeext.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 = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(sdkdir)" HEADERS = $(sdk_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libcomposite.la AM_CFLAGS = $(DIX_CFLAGS) @XORG_TRUE@sdk_HEADERS = compositeext.h libcomposite_la_SOURCES = \ compalloc.c \ compext.c \ compint.h \ compinit.c \ compoverlay.c \ compwindow.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign composite/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign composite/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcomposite.la: $(libcomposite_la_OBJECTS) $(libcomposite_la_DEPENDENCIES) $(EXTRA_libcomposite_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcomposite_la_OBJECTS) $(libcomposite_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compalloc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compext.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compinit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compoverlay.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compwindow.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-sdkHEADERS: $(sdk_HEADERS) @$(NORMAL_INSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sdkdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sdkdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(sdkdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(sdkdir)" || exit $$?; \ done uninstall-sdkHEADERS: @$(NORMAL_UNINSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(sdkdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/compalloc.Plo -rm -f ./$(DEPDIR)/compext.Plo -rm -f ./$(DEPDIR)/compinit.Plo -rm -f ./$(DEPDIR)/compoverlay.Plo -rm -f ./$(DEPDIR)/compwindow.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-sdkHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/compalloc.Plo -rm -f ./$(DEPDIR)/compext.Plo -rm -f ./$(DEPDIR)/compinit.Plo -rm -f ./$(DEPDIR)/compoverlay.Plo -rm -f ./$(DEPDIR)/compwindow.Plo -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 TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am 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 tags-am uninstall uninstall-am \ uninstall-sdkHEADERS .PRECIOUS: Makefile # 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: xorg-server-1.20.13/composite/compalloc.c0000644000175000017500000005116714100573755015222 00000000000000/* * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright © 2003 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 #endif #include "compint.h" static Bool compScreenUpdate(ClientPtr pClient, void *closure) { ScreenPtr pScreen = closure; CompScreenPtr cs = GetCompScreen(pScreen); compCheckTree(pScreen); compPaintChildrenToWindow(pScreen->root); /* Next damage will restore the worker */ cs->pendingScreenUpdate = FALSE; return TRUE; } void compMarkAncestors(WindowPtr pWin) { pWin = pWin->parent; while (pWin) { if (pWin->damagedDescendants) return; pWin->damagedDescendants = TRUE; pWin = pWin->parent; } } static void compReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure) { WindowPtr pWin = (WindowPtr) closure; ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); CompWindowPtr cw = GetCompWindow(pWin); if (!cs->pendingScreenUpdate) { QueueWorkProc(compScreenUpdate, serverClient, pScreen); cs->pendingScreenUpdate = TRUE; } cw->damaged = TRUE; compMarkAncestors(pWin); } static void compDestroyDamage(DamagePtr pDamage, void *closure) { WindowPtr pWin = (WindowPtr) closure; CompWindowPtr cw = GetCompWindow(pWin); cw->damage = 0; } static Bool compMarkWindows(WindowPtr pWin, WindowPtr *ppLayerWin) { ScreenPtr pScreen = pWin->drawable.pScreen; WindowPtr pLayerWin = pWin; if (!pWin->viewable) return FALSE; (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); (*pScreen->MarkWindow) (pLayerWin->parent); *ppLayerWin = pLayerWin; return TRUE; } static void compHandleMarkedWindows(WindowPtr pWin, WindowPtr pLayerWin) { ScreenPtr pScreen = pWin->drawable.pScreen; (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTOther); (*pScreen->HandleExposures) (pLayerWin->parent); if (pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, VTOther); } /* * Redirect one window for one client */ int compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update) { CompWindowPtr cw = GetCompWindow(pWin); CompClientWindowPtr ccw; CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); WindowPtr pLayerWin; Bool anyMarked = FALSE; if (pWin == cs->pOverlayWin) { return Success; } if (!pWin->parent) return BadMatch; /* * Only one Manual update is allowed */ if (cw && update == CompositeRedirectManual) for (ccw = cw->clients; ccw; ccw = ccw->next) if (ccw->update == CompositeRedirectManual) return BadAccess; /* * Allocate per-client per-window structure * The client *could* allocate multiple, but while supported, * it is not expected to be common */ ccw = malloc(sizeof(CompClientWindowRec)); if (!ccw) return BadAlloc; ccw->id = FakeClientID(pClient->index); ccw->update = update; /* * Now make sure there's a per-window structure to hang this from */ if (!cw) { cw = malloc(sizeof(CompWindowRec)); if (!cw) { free(ccw); return BadAlloc; } cw->damage = DamageCreate(compReportDamage, compDestroyDamage, DamageReportNonEmpty, FALSE, pWin->drawable.pScreen, pWin); if (!cw->damage) { free(ccw); free(cw); return BadAlloc; } anyMarked = compMarkWindows(pWin, &pLayerWin); RegionNull(&cw->borderClip); cw->update = CompositeRedirectAutomatic; cw->clients = 0; cw->oldx = COMP_ORIGIN_INVALID; cw->oldy = COMP_ORIGIN_INVALID; cw->damageRegistered = FALSE; cw->damaged = FALSE; cw->pOldPixmap = NullPixmap; dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw); } ccw->next = cw->clients; cw->clients = ccw; if (!AddResource(ccw->id, CompositeClientWindowType, pWin)) return BadAlloc; if (ccw->update == CompositeRedirectManual) { if (!anyMarked) anyMarked = compMarkWindows(pWin, &pLayerWin); if (cw->damageRegistered) { DamageUnregister(cw->damage); cw->damageRegistered = FALSE; } cw->update = CompositeRedirectManual; } else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered) { if (!anyMarked) anyMarked = compMarkWindows(pWin, &pLayerWin); } if (!compCheckRedirect(pWin)) { FreeResource(ccw->id, RT_NONE); return BadAlloc; } if (anyMarked) compHandleMarkedWindows(pWin, pLayerWin); return Success; } void compRestoreWindow(WindowPtr pWin, PixmapPtr pPixmap) { ScreenPtr pScreen = pWin->drawable.pScreen; WindowPtr pParent = pWin->parent; if (pParent->drawable.depth == pWin->drawable.depth) { GCPtr pGC = GetScratchGC(pWin->drawable.depth, pScreen); int bw = (int) pWin->borderWidth; int x = bw; int y = bw; int w = pWin->drawable.width; int h = pWin->drawable.height; if (pGC) { ChangeGCVal val; val.val = IncludeInferiors; ChangeGC(NullClient, pGC, GCSubwindowMode, &val); ValidateGC(&pWin->drawable, pGC); (*pGC->ops->CopyArea) (&pPixmap->drawable, &pWin->drawable, pGC, x, y, w, h, 0, 0); FreeScratchGC(pGC); } } } /* * Free one of the per-client per-window resources, clearing * redirect and the per-window pointer as appropriate */ void compFreeClientWindow(WindowPtr pWin, XID id) { ScreenPtr pScreen = pWin->drawable.pScreen; CompWindowPtr cw = GetCompWindow(pWin); CompClientWindowPtr ccw, *prev; Bool anyMarked = FALSE; WindowPtr pLayerWin; PixmapPtr pPixmap = NULL; if (!cw) return; for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next) { if (ccw->id == id) { *prev = ccw->next; if (ccw->update == CompositeRedirectManual) cw->update = CompositeRedirectAutomatic; free(ccw); break; } } if (!cw->clients) { anyMarked = compMarkWindows(pWin, &pLayerWin); if (pWin->redirectDraw != RedirectDrawNone) { pPixmap = (*pScreen->GetWindowPixmap) (pWin); compSetParentPixmap(pWin); } if (cw->damage) DamageDestroy(cw->damage); RegionUninit(&cw->borderClip); dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL); free(cw); } else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone) { anyMarked = compMarkWindows(pWin, &pLayerWin); DamageRegister(&pWin->drawable, cw->damage); cw->damageRegistered = TRUE; pWin->redirectDraw = RedirectDrawAutomatic; DamageDamageRegion(&pWin->drawable, &pWin->borderSize); } if (anyMarked) compHandleMarkedWindows(pWin, pLayerWin); if (pPixmap) { compRestoreWindow(pWin, pPixmap); (*pScreen->DestroyPixmap) (pPixmap); } } /* * This is easy, just free the appropriate resource. */ int compUnredirectWindow(ClientPtr pClient, WindowPtr pWin, int update) { CompWindowPtr cw = GetCompWindow(pWin); CompClientWindowPtr ccw; if (!cw) return BadValue; for (ccw = cw->clients; ccw; ccw = ccw->next) if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index) { FreeResource(ccw->id, RT_NONE); return Success; } return BadValue; } /* * Redirect all subwindows for one client */ int compRedirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update) { CompSubwindowsPtr csw = GetCompSubwindows(pWin); CompClientWindowPtr ccw; WindowPtr pChild; /* * Only one Manual update is allowed */ if (csw && update == CompositeRedirectManual) for (ccw = csw->clients; ccw; ccw = ccw->next) if (ccw->update == CompositeRedirectManual) return BadAccess; /* * Allocate per-client per-window structure * The client *could* allocate multiple, but while supported, * it is not expected to be common */ ccw = malloc(sizeof(CompClientWindowRec)); if (!ccw) return BadAlloc; ccw->id = FakeClientID(pClient->index); ccw->update = update; /* * Now make sure there's a per-window structure to hang this from */ if (!csw) { csw = malloc(sizeof(CompSubwindowsRec)); if (!csw) { free(ccw); return BadAlloc; } csw->update = CompositeRedirectAutomatic; csw->clients = 0; dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, csw); } /* * Redirect all existing windows */ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) { int ret = compRedirectWindow(pClient, pChild, update); if (ret != Success) { for (pChild = pChild->nextSib; pChild; pChild = pChild->nextSib) (void) compUnredirectWindow(pClient, pChild, update); if (!csw->clients) { free(csw); dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, 0); } free(ccw); return ret; } } /* * Hook into subwindows list */ ccw->next = csw->clients; csw->clients = ccw; if (!AddResource(ccw->id, CompositeClientSubwindowsType, pWin)) return BadAlloc; if (ccw->update == CompositeRedirectManual) { csw->update = CompositeRedirectManual; /* * tell damage extension that damage events for this client are * critical output */ DamageExtSetCritical(pClient, TRUE); pWin->inhibitBGPaint = TRUE; } return Success; } /* * Free one of the per-client per-subwindows resources, * which frees one redirect per subwindow */ void compFreeClientSubwindows(WindowPtr pWin, XID id) { CompSubwindowsPtr csw = GetCompSubwindows(pWin); CompClientWindowPtr ccw, *prev; WindowPtr pChild; if (!csw) return; for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next) { if (ccw->id == id) { ClientPtr pClient = clients[CLIENT_ID(id)]; *prev = ccw->next; if (ccw->update == CompositeRedirectManual) { /* * tell damage extension that damage events for this client are * critical output */ DamageExtSetCritical(pClient, FALSE); csw->update = CompositeRedirectAutomatic; pWin->inhibitBGPaint = FALSE; if (pWin->mapped) (*pWin->drawable.pScreen->ClearToBackground) (pWin, 0, 0, 0, 0, TRUE); } /* * Unredirect all existing subwindows */ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) (void) compUnredirectWindow(pClient, pChild, ccw->update); free(ccw); break; } } /* * Check if all of the per-client records are gone */ if (!csw->clients) { dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, NULL); free(csw); } } /* * This is easy, just free the appropriate resource. */ int compUnredirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update) { CompSubwindowsPtr csw = GetCompSubwindows(pWin); CompClientWindowPtr ccw; if (!csw) return BadValue; for (ccw = csw->clients; ccw; ccw = ccw->next) if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index) { FreeResource(ccw->id, RT_NONE); return Success; } return BadValue; } /* * Add redirection information for one subwindow (during reparent) */ int compRedirectOneSubwindow(WindowPtr pParent, WindowPtr pWin) { CompSubwindowsPtr csw = GetCompSubwindows(pParent); CompClientWindowPtr ccw; if (!csw) return Success; for (ccw = csw->clients; ccw; ccw = ccw->next) { int ret = compRedirectWindow(clients[CLIENT_ID(ccw->id)], pWin, ccw->update); if (ret != Success) return ret; } return Success; } /* * Remove redirection information for one subwindow (during reparent) */ int compUnredirectOneSubwindow(WindowPtr pParent, WindowPtr pWin) { CompSubwindowsPtr csw = GetCompSubwindows(pParent); CompClientWindowPtr ccw; if (!csw) return Success; for (ccw = csw->clients; ccw; ccw = ccw->next) { int ret = compUnredirectWindow(clients[CLIENT_ID(ccw->id)], pWin, ccw->update); if (ret != Success) return ret; } return Success; } static PixmapPtr compNewPixmap(WindowPtr pWin, int x, int y, int w, int h) { ScreenPtr pScreen = pWin->drawable.pScreen; WindowPtr pParent = pWin->parent; PixmapPtr pPixmap; pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth, CREATE_PIXMAP_USAGE_BACKING_PIXMAP); if (!pPixmap) return 0; pPixmap->screen_x = x; pPixmap->screen_y = y; if (pParent->drawable.depth == pWin->drawable.depth) { GCPtr pGC = GetScratchGC(pWin->drawable.depth, pScreen); if (pGC) { ChangeGCVal val; val.val = IncludeInferiors; ChangeGC(NullClient, pGC, GCSubwindowMode, &val); ValidateGC(&pPixmap->drawable, pGC); (*pGC->ops->CopyArea) (&pParent->drawable, &pPixmap->drawable, pGC, x - pParent->drawable.x, y - pParent->drawable.y, w, h, 0, 0); FreeScratchGC(pGC); } } else { PictFormatPtr pSrcFormat = PictureWindowFormat(pParent); PictFormatPtr pDstFormat = PictureWindowFormat(pWin); XID inferiors = IncludeInferiors; int error; PicturePtr pSrcPicture = CreatePicture(None, &pParent->drawable, pSrcFormat, CPSubwindowMode, &inferiors, serverClient, &error); PicturePtr pDstPicture = CreatePicture(None, &pPixmap->drawable, pDstFormat, 0, 0, serverClient, &error); if (pSrcPicture && pDstPicture) { CompositePicture(PictOpSrc, pSrcPicture, NULL, pDstPicture, x - pParent->drawable.x, y - pParent->drawable.y, 0, 0, 0, 0, w, h); } if (pSrcPicture) FreePicture(pSrcPicture, 0); if (pDstPicture) FreePicture(pDstPicture, 0); } return pPixmap; } Bool compAllocPixmap(WindowPtr pWin) { int bw = (int) pWin->borderWidth; int x = pWin->drawable.x - bw; int y = pWin->drawable.y - bw; int w = pWin->drawable.width + (bw << 1); int h = pWin->drawable.height + (bw << 1); PixmapPtr pPixmap = compNewPixmap(pWin, x, y, w, h); CompWindowPtr cw = GetCompWindow(pWin); if (!pPixmap) return FALSE; if (cw->update == CompositeRedirectAutomatic) pWin->redirectDraw = RedirectDrawAutomatic; else pWin->redirectDraw = RedirectDrawManual; compSetPixmap(pWin, pPixmap, bw); cw->oldx = COMP_ORIGIN_INVALID; cw->oldy = COMP_ORIGIN_INVALID; cw->damageRegistered = FALSE; if (cw->update == CompositeRedirectAutomatic) { DamageRegister(&pWin->drawable, cw->damage); cw->damageRegistered = TRUE; } /* Make sure our borderClip is up to date */ RegionUninit(&cw->borderClip); RegionCopy(&cw->borderClip, &pWin->borderClip); cw->borderClipX = pWin->drawable.x; cw->borderClipY = pWin->drawable.y; return TRUE; } void compSetParentPixmap(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; PixmapPtr pParentPixmap; CompWindowPtr cw = GetCompWindow(pWin); if (cw->damageRegistered) { DamageUnregister(cw->damage); cw->damageRegistered = FALSE; DamageEmpty(cw->damage); } /* * Move the parent-constrained border clip region back into * the window so that ValidateTree will handle the unmap * case correctly. Unmap adds the window borderClip to the * parent exposed area; regions beyond the parent cause crashes */ RegionCopy(&pWin->borderClip, &cw->borderClip); pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent); pWin->redirectDraw = RedirectDrawNone; compSetPixmap(pWin, pParentPixmap, pWin->borderWidth); } /* * Make sure the pixmap is the right size and offset. Allocate a new * pixmap to change size, adjust origin to change offset, leaving the * old pixmap in cw->pOldPixmap so bits can be recovered */ Bool compReallocPixmap(WindowPtr pWin, int draw_x, int draw_y, unsigned int w, unsigned int h, int bw) { ScreenPtr pScreen = pWin->drawable.pScreen; PixmapPtr pOld = (*pScreen->GetWindowPixmap) (pWin); PixmapPtr pNew; CompWindowPtr cw = GetCompWindow(pWin); int pix_x, pix_y; int pix_w, pix_h; assert(cw && pWin->redirectDraw != RedirectDrawNone); cw->oldx = pOld->screen_x; cw->oldy = pOld->screen_y; pix_x = draw_x - bw; pix_y = draw_y - bw; pix_w = w + (bw << 1); pix_h = h + (bw << 1); if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height) { pNew = compNewPixmap(pWin, pix_x, pix_y, pix_w, pix_h); if (!pNew) return FALSE; cw->pOldPixmap = pOld; compSetPixmap(pWin, pNew, bw); } else { pNew = pOld; cw->pOldPixmap = 0; } pNew->screen_x = pix_x; pNew->screen_y = pix_y; return TRUE; } xorg-server-1.20.13/composite/compext.c0000644000175000017500000006464214100573755014732 00000000000000/* * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright © 2003 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 #endif #include "compint.h" #include "xace.h" #include "protocol-versions.h" #include "extinit.h" static CARD8 CompositeReqCode; static DevPrivateKeyRec CompositeClientPrivateKeyRec; #define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec) RESTYPE CompositeClientWindowType; RESTYPE CompositeClientSubwindowsType; RESTYPE CompositeClientOverlayType; typedef struct _CompositeClient { int major_version; int minor_version; } CompositeClientRec, *CompositeClientPtr; #define GetCompositeClient(pClient) ((CompositeClientPtr) \ dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey)) static int FreeCompositeClientWindow(void *value, XID ccwid) { WindowPtr pWin = value; compFreeClientWindow(pWin, ccwid); return Success; } static int FreeCompositeClientSubwindows(void *value, XID ccwid) { WindowPtr pWin = value; compFreeClientSubwindows(pWin, ccwid); return Success; } static int FreeCompositeClientOverlay(void *value, XID ccwid) { CompOverlayClientPtr pOc = (CompOverlayClientPtr) value; compFreeOverlayClient(pOc); return Success; } static int ProcCompositeQueryVersion(ClientPtr client) { CompositeClientPtr pCompositeClient = GetCompositeClient(client); xCompositeQueryVersionReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0 }; REQUEST(xCompositeQueryVersionReq); REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) { rep.majorVersion = stuff->majorVersion; rep.minorVersion = stuff->minorVersion; } else { rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION; rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION; } pCompositeClient->major_version = rep.majorVersion; pCompositeClient->minor_version = rep.minorVersion; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.majorVersion); swapl(&rep.minorVersion); } WriteToClient(client, sizeof(xCompositeQueryVersionReply), &rep); return Success; } #define VERIFY_WINDOW(pWindow, wid, client, mode) \ do { \ int err; \ err = dixLookupResourceByType((void **) &pWindow, wid, \ RT_WINDOW, client, mode); \ if (err != Success) { \ client->errorValue = wid; \ return err; \ } \ } while (0) static int ProcCompositeRedirectWindow(ClientPtr client) { WindowPtr pWin; REQUEST(xCompositeRedirectWindowReq); REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); VERIFY_WINDOW(pWin, stuff->window, client, DixSetAttrAccess | DixManageAccess | DixBlendAccess); return compRedirectWindow(client, pWin, stuff->update); } static int ProcCompositeRedirectSubwindows(ClientPtr client) { WindowPtr pWin; REQUEST(xCompositeRedirectSubwindowsReq); REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); VERIFY_WINDOW(pWin, stuff->window, client, DixSetAttrAccess | DixManageAccess | DixBlendAccess); return compRedirectSubwindows(client, pWin, stuff->update); } static int ProcCompositeUnredirectWindow(ClientPtr client) { WindowPtr pWin; REQUEST(xCompositeUnredirectWindowReq); REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); VERIFY_WINDOW(pWin, stuff->window, client, DixSetAttrAccess | DixManageAccess | DixBlendAccess); return compUnredirectWindow(client, pWin, stuff->update); } static int ProcCompositeUnredirectSubwindows(ClientPtr client) { WindowPtr pWin; REQUEST(xCompositeUnredirectSubwindowsReq); REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); VERIFY_WINDOW(pWin, stuff->window, client, DixSetAttrAccess | DixManageAccess | DixBlendAccess); return compUnredirectSubwindows(client, pWin, stuff->update); } static int ProcCompositeCreateRegionFromBorderClip(ClientPtr client) { WindowPtr pWin; CompWindowPtr cw; RegionPtr pBorderClip, pRegion; REQUEST(xCompositeCreateRegionFromBorderClipReq); REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); LEGAL_NEW_RESOURCE(stuff->region, client); cw = GetCompWindow(pWin); if (cw) pBorderClip = &cw->borderClip; else pBorderClip = &pWin->borderClip; pRegion = XFixesRegionCopy(pBorderClip); if (!pRegion) return BadAlloc; RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y); if (!AddResource(stuff->region, RegionResType, (void *) pRegion)) return BadAlloc; return Success; } static int ProcCompositeNameWindowPixmap(ClientPtr client) { WindowPtr pWin; CompWindowPtr cw; PixmapPtr pPixmap; ScreenPtr pScreen; int rc; REQUEST(xCompositeNameWindowPixmapReq); REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); pScreen = pWin->drawable.pScreen; if (!pWin->viewable) return BadMatch; LEGAL_NEW_RESOURCE(stuff->pixmap, client); cw = GetCompWindow(pWin); if (!cw) return BadMatch; pPixmap = (*pScreen->GetWindowPixmap) (pWin); if (!pPixmap) return BadMatch; /* security creation/labeling check */ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, pPixmap, RT_WINDOW, pWin, DixCreateAccess); if (rc != Success) return rc; ++pPixmap->refcnt; if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pPixmap)) return BadAlloc; if (pScreen->NameWindowPixmap) { rc = pScreen->NameWindowPixmap(pWin, pPixmap, stuff->pixmap); if (rc != Success) { FreeResource(stuff->pixmap, RT_NONE); return rc; } } return Success; } static int ProcCompositeGetOverlayWindow(ClientPtr client) { REQUEST(xCompositeGetOverlayWindowReq); xCompositeGetOverlayWindowReply rep; WindowPtr pWin; ScreenPtr pScreen; CompScreenPtr cs; CompOverlayClientPtr pOc; int rc; REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); pScreen = pWin->drawable.pScreen; /* * Create an OverlayClient structure to mark this client's * interest in the overlay window */ pOc = compCreateOverlayClient(pScreen, client); if (pOc == NULL) return BadAlloc; /* * Make sure the overlay window exists */ cs = GetCompScreen(pScreen); if (cs->pOverlayWin == NULL) if (!compCreateOverlayWindow(pScreen)) { FreeResource(pOc->resource, RT_NONE); return BadAlloc; } rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id, RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess); if (rc != Success) { FreeResource(pOc->resource, RT_NONE); return rc; } rep = (xCompositeGetOverlayWindowReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .overlayWin = cs->pOverlayWin->drawable.id }; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.overlayWin); } WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep); return Success; } static int ProcCompositeReleaseOverlayWindow(ClientPtr client) { REQUEST(xCompositeReleaseOverlayWindowReq); WindowPtr pWin; CompOverlayClientPtr pOc; REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); /* * Has client queried a reference to the overlay window * on this screen? If not, generate an error. */ pOc = compFindOverlayClient(pWin->drawable.pScreen, client); if (pOc == NULL) return BadMatch; /* The delete function will free the client structure */ FreeResource(pOc->resource, RT_NONE); return Success; } static int (*ProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = { ProcCompositeQueryVersion, ProcCompositeRedirectWindow, ProcCompositeRedirectSubwindows, ProcCompositeUnredirectWindow, ProcCompositeUnredirectSubwindows, ProcCompositeCreateRegionFromBorderClip, ProcCompositeNameWindowPixmap, ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow,}; static int ProcCompositeDispatch(ClientPtr client) { REQUEST(xReq); if (stuff->data < CompositeNumberRequests) return (*ProcCompositeVector[stuff->data]) (client); else return BadRequest; } static int _X_COLD SProcCompositeQueryVersion(ClientPtr client) { REQUEST(xCompositeQueryVersionReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); swapl(&stuff->majorVersion); swapl(&stuff->minorVersion); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int _X_COLD SProcCompositeRedirectWindow(ClientPtr client) { REQUEST(xCompositeRedirectWindowReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); swapl(&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int _X_COLD SProcCompositeRedirectSubwindows(ClientPtr client) { REQUEST(xCompositeRedirectSubwindowsReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); swapl(&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int _X_COLD SProcCompositeUnredirectWindow(ClientPtr client) { REQUEST(xCompositeUnredirectWindowReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); swapl(&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int _X_COLD SProcCompositeUnredirectSubwindows(ClientPtr client) { REQUEST(xCompositeUnredirectSubwindowsReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); swapl(&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int _X_COLD SProcCompositeCreateRegionFromBorderClip(ClientPtr client) { REQUEST(xCompositeCreateRegionFromBorderClipReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); swapl(&stuff->region); swapl(&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int _X_COLD SProcCompositeNameWindowPixmap(ClientPtr client) { REQUEST(xCompositeNameWindowPixmapReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); swapl(&stuff->window); swapl(&stuff->pixmap); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int _X_COLD SProcCompositeGetOverlayWindow(ClientPtr client) { REQUEST(xCompositeGetOverlayWindowReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); swapl(&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int _X_COLD SProcCompositeReleaseOverlayWindow(ClientPtr client) { REQUEST(xCompositeReleaseOverlayWindowReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); swapl(&stuff->window); return (*ProcCompositeVector[stuff->compositeReqType]) (client); } static int (*SProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = { SProcCompositeQueryVersion, SProcCompositeRedirectWindow, SProcCompositeRedirectSubwindows, SProcCompositeUnredirectWindow, SProcCompositeUnredirectSubwindows, SProcCompositeCreateRegionFromBorderClip, SProcCompositeNameWindowPixmap, SProcCompositeGetOverlayWindow, SProcCompositeReleaseOverlayWindow, }; static int _X_COLD SProcCompositeDispatch(ClientPtr client) { REQUEST(xReq); if (stuff->data < CompositeNumberRequests) return (*SProcCompositeVector[stuff->data]) (client); else return BadRequest; } /** @see GetDefaultBytes */ static SizeType coreGetWindowBytes; static void GetCompositeWindowBytes(void *value, XID id, ResourceSizePtr size) { WindowPtr window = value; /* call down */ coreGetWindowBytes(value, id, size); /* account for redirection */ if (window->redirectDraw != RedirectDrawNone) { SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); ResourceSizeRec pixmapSize = { 0, 0 }; ScreenPtr screen = window->drawable.pScreen; PixmapPtr pixmap = screen->GetWindowPixmap(window); pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); size->pixmapRefSize += pixmapSize.pixmapRefSize; } } void CompositeExtensionInit(void) { ExtensionEntry *extEntry; int s; /* Assume initialization is going to fail */ noCompositeExtension = TRUE; for (s = 0; s < screenInfo.numScreens; s++) { ScreenPtr pScreen = screenInfo.screens[s]; VisualPtr vis; /* Composite on 8bpp pseudocolor root windows appears to fail, so * just disable it on anything pseudocolor for safety. */ for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++); if ((vis->class | DynamicClass) == PseudoColor) return; /* Ensure that Render is initialized, which is required for automatic * compositing. */ if (GetPictureScreenIfSet(pScreen) == NULL) return; } CompositeClientWindowType = CreateNewResourceType (FreeCompositeClientWindow, "CompositeClientWindow"); if (!CompositeClientWindowType) return; coreGetWindowBytes = GetResourceTypeSizeFunc(RT_WINDOW); SetResourceTypeSizeFunc(RT_WINDOW, GetCompositeWindowBytes); CompositeClientSubwindowsType = CreateNewResourceType (FreeCompositeClientSubwindows, "CompositeClientSubwindows"); if (!CompositeClientSubwindowsType) return; CompositeClientOverlayType = CreateNewResourceType (FreeCompositeClientOverlay, "CompositeClientOverlay"); if (!CompositeClientOverlayType) return; if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(CompositeClientRec))) return; for (s = 0; s < screenInfo.numScreens; s++) if (!compScreenInit(screenInfo.screens[s])) return; extEntry = AddExtension(COMPOSITE_NAME, 0, 0, ProcCompositeDispatch, SProcCompositeDispatch, NULL, StandardMinorOpcode); if (!extEntry) return; CompositeReqCode = (CARD8) extEntry->base; /* Initialization succeeded */ noCompositeExtension = FALSE; } #ifdef PANORAMIX #include "panoramiXsrv.h" int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr); static int PanoramiXCompositeRedirectWindow(ClientPtr client) { PanoramiXRes *win; int rc = 0, j; REQUEST(xCompositeRedirectWindowReq); REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, client, DixUnknownAccess))) { client->errorValue = stuff->window; return rc; } FOR_NSCREENS_FORWARD(j) { stuff->window = win->info[j].id; rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); if (rc != Success) break; } return rc; } static int PanoramiXCompositeRedirectSubwindows(ClientPtr client) { PanoramiXRes *win; int rc = 0, j; REQUEST(xCompositeRedirectSubwindowsReq); REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, client, DixUnknownAccess))) { client->errorValue = stuff->window; return rc; } FOR_NSCREENS_FORWARD(j) { stuff->window = win->info[j].id; rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); if (rc != Success) break; } return rc; } static int PanoramiXCompositeUnredirectWindow(ClientPtr client) { PanoramiXRes *win; int rc = 0, j; REQUEST(xCompositeUnredirectWindowReq); REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, client, DixUnknownAccess))) { client->errorValue = stuff->window; return rc; } FOR_NSCREENS_FORWARD(j) { stuff->window = win->info[j].id; rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); if (rc != Success) break; } return rc; } static int PanoramiXCompositeUnredirectSubwindows(ClientPtr client) { PanoramiXRes *win; int rc = 0, j; REQUEST(xCompositeUnredirectSubwindowsReq); REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, client, DixUnknownAccess))) { client->errorValue = stuff->window; return rc; } FOR_NSCREENS_FORWARD(j) { stuff->window = win->info[j].id; rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); if (rc != Success) break; } return rc; } static int PanoramiXCompositeNameWindowPixmap(ClientPtr client) { WindowPtr pWin; CompWindowPtr cw; PixmapPtr pPixmap; int rc; PanoramiXRes *win, *newPix; int i; REQUEST(xCompositeNameWindowPixmapReq); REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, client, DixUnknownAccess))) { client->errorValue = stuff->window; return rc; } LEGAL_NEW_RESOURCE(stuff->pixmap, client); if (!(newPix = malloc(sizeof(PanoramiXRes)))) return BadAlloc; newPix->type = XRT_PIXMAP; newPix->u.pix.shared = FALSE; panoramix_setup_ids(newPix, client, stuff->pixmap); FOR_NSCREENS(i) { rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, RT_WINDOW, client, DixGetAttrAccess); if (rc != Success) { client->errorValue = stuff->window; free(newPix); return rc; } if (!pWin->viewable) { free(newPix); return BadMatch; } cw = GetCompWindow(pWin); if (!cw) { free(newPix); return BadMatch; } pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); if (!pPixmap) { free(newPix); return BadMatch; } if (!AddResource(newPix->info[i].id, RT_PIXMAP, (void *) pPixmap)) return BadAlloc; ++pPixmap->refcnt; } if (!AddResource(stuff->pixmap, XRT_PIXMAP, (void *) newPix)) return BadAlloc; return Success; } static int PanoramiXCompositeGetOverlayWindow(ClientPtr client) { REQUEST(xCompositeGetOverlayWindowReq); xCompositeGetOverlayWindowReply rep; WindowPtr pWin; ScreenPtr pScreen; CompScreenPtr cs; CompOverlayClientPtr pOc; int rc; PanoramiXRes *win, *overlayWin = NULL; int i; REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, client, DixUnknownAccess))) { client->errorValue = stuff->window; return rc; } cs = GetCompScreen(screenInfo.screens[0]); if (!cs->pOverlayWin) { if (!(overlayWin = malloc(sizeof(PanoramiXRes)))) return BadAlloc; overlayWin->type = XRT_WINDOW; overlayWin->u.win.root = FALSE; } FOR_NSCREENS_BACKWARD(i) { rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, RT_WINDOW, client, DixGetAttrAccess); if (rc != Success) { client->errorValue = stuff->window; free(overlayWin); return rc; } pScreen = pWin->drawable.pScreen; /* * Create an OverlayClient structure to mark this client's * interest in the overlay window */ pOc = compCreateOverlayClient(pScreen, client); if (pOc == NULL) { free(overlayWin); return BadAlloc; } /* * Make sure the overlay window exists */ cs = GetCompScreen(pScreen); if (cs->pOverlayWin == NULL) if (!compCreateOverlayWindow(pScreen)) { FreeResource(pOc->resource, RT_NONE); free(overlayWin); return BadAlloc; } rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id, RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess); if (rc != Success) { FreeResource(pOc->resource, RT_NONE); free(overlayWin); return rc; } } if (overlayWin) { FOR_NSCREENS(i) { cs = GetCompScreen(screenInfo.screens[i]); overlayWin->info[i].id = cs->pOverlayWin->drawable.id; } AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin); } cs = GetCompScreen(screenInfo.screens[0]); rep = (xCompositeGetOverlayWindowReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .overlayWin = cs->pOverlayWin->drawable.id }; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.overlayWin); } WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep); return Success; } static int PanoramiXCompositeReleaseOverlayWindow(ClientPtr client) { REQUEST(xCompositeReleaseOverlayWindowReq); WindowPtr pWin; CompOverlayClientPtr pOc; PanoramiXRes *win; int i, rc; REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, client, DixUnknownAccess))) { client->errorValue = stuff->window; return rc; } FOR_NSCREENS_BACKWARD(i) { if ((rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, XRT_WINDOW, client, DixUnknownAccess))) { client->errorValue = stuff->window; return rc; } /* * Has client queried a reference to the overlay window * on this screen? If not, generate an error. */ pOc = compFindOverlayClient(pWin->drawable.pScreen, client); if (pOc == NULL) return BadMatch; /* The delete function will free the client structure */ FreeResource(pOc->resource, RT_NONE); } return Success; } void PanoramiXCompositeInit(void) { int i; for (i = 0; i < CompositeNumberRequests; i++) PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i]; /* * Stuff in Xinerama aware request processing hooks */ ProcCompositeVector[X_CompositeRedirectWindow] = PanoramiXCompositeRedirectWindow; ProcCompositeVector[X_CompositeRedirectSubwindows] = PanoramiXCompositeRedirectSubwindows; ProcCompositeVector[X_CompositeUnredirectWindow] = PanoramiXCompositeUnredirectWindow; ProcCompositeVector[X_CompositeUnredirectSubwindows] = PanoramiXCompositeUnredirectSubwindows; ProcCompositeVector[X_CompositeNameWindowPixmap] = PanoramiXCompositeNameWindowPixmap; ProcCompositeVector[X_CompositeGetOverlayWindow] = PanoramiXCompositeGetOverlayWindow; ProcCompositeVector[X_CompositeReleaseOverlayWindow] = PanoramiXCompositeReleaseOverlayWindow; } void PanoramiXCompositeReset(void) { int i; for (i = 0; i < CompositeNumberRequests; i++) ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i]; } #endif xorg-server-1.20.13/composite/compint.h0000644000175000017500000002153514100573755014723 00000000000000/* * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright © 2003 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 #endif #ifndef _COMPINT_H_ #define _COMPINT_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 "dixevents.h" #include "globals.h" #include "picturestr.h" #include "extnsionst.h" #include "privates.h" #include "mi.h" #include "damage.h" #include "damageextint.h" #include "xfixes.h" #include #include "compositeext.h" #include /* * enable this for debugging #define COMPOSITE_DEBUG */ typedef struct _CompClientWindow { struct _CompClientWindow *next; XID id; int update; } CompClientWindowRec, *CompClientWindowPtr; typedef struct _CompWindow { RegionRec borderClip; DamagePtr damage; /* for automatic update mode */ Bool damageRegistered; Bool damaged; int update; CompClientWindowPtr clients; int oldx; int oldy; PixmapPtr pOldPixmap; int borderClipX, borderClipY; } CompWindowRec, *CompWindowPtr; #define COMP_ORIGIN_INVALID 0x80000000 typedef struct _CompSubwindows { int update; CompClientWindowPtr clients; } CompSubwindowsRec, *CompSubwindowsPtr; #ifndef COMP_INCLUDE_RGB24_VISUAL #define COMP_INCLUDE_RGB24_VISUAL 0 #endif typedef struct _CompOverlayClientRec *CompOverlayClientPtr; typedef struct _CompOverlayClientRec { CompOverlayClientPtr pNext; ClientPtr pClient; ScreenPtr pScreen; XID resource; } CompOverlayClientRec; typedef struct _CompImplicitRedirectException { XID parentVisual; XID winVisual; } CompImplicitRedirectException; typedef struct _CompScreen { PositionWindowProcPtr PositionWindow; CopyWindowProcPtr CopyWindow; CreateWindowProcPtr CreateWindow; DestroyWindowProcPtr DestroyWindow; RealizeWindowProcPtr RealizeWindow; UnrealizeWindowProcPtr UnrealizeWindow; ClipNotifyProcPtr ClipNotify; /* * Called from ConfigureWindow, these * three track changes to the offscreen storage * geometry */ ConfigNotifyProcPtr ConfigNotify; MoveWindowProcPtr MoveWindow; ResizeWindowProcPtr ResizeWindow; ChangeBorderWidthProcPtr ChangeBorderWidth; /* * Reparenting has an effect on Subwindows redirect */ ReparentWindowProcPtr ReparentWindow; /* * Colormaps for new visuals better not get installed */ InstallColormapProcPtr InstallColormap; /* * Fake backing store via automatic redirection */ ChangeWindowAttributesProcPtr ChangeWindowAttributes; Bool pendingScreenUpdate; CloseScreenProcPtr CloseScreen; int numAlternateVisuals; VisualID *alternateVisuals; int numImplicitRedirectExceptions; CompImplicitRedirectException *implicitRedirectExceptions; WindowPtr pOverlayWin; Window overlayWid; CompOverlayClientPtr pOverlayClients; GetImageProcPtr GetImage; GetSpansProcPtr GetSpans; SourceValidateProcPtr SourceValidate; } CompScreenRec, *CompScreenPtr; extern DevPrivateKeyRec CompScreenPrivateKeyRec; #define CompScreenPrivateKey (&CompScreenPrivateKeyRec) extern DevPrivateKeyRec CompWindowPrivateKeyRec; #define CompWindowPrivateKey (&CompWindowPrivateKeyRec) extern DevPrivateKeyRec CompSubwindowsPrivateKeyRec; #define CompSubwindowsPrivateKey (&CompSubwindowsPrivateKeyRec) #define GetCompScreen(s) ((CompScreenPtr) \ dixLookupPrivate(&(s)->devPrivates, CompScreenPrivateKey)) #define GetCompWindow(w) ((CompWindowPtr) \ dixLookupPrivate(&(w)->devPrivates, CompWindowPrivateKey)) #define GetCompSubwindows(w) ((CompSubwindowsPtr) \ dixLookupPrivate(&(w)->devPrivates, CompSubwindowsPrivateKey)) extern RESTYPE CompositeClientSubwindowsType; extern RESTYPE CompositeClientOverlayType; /* * compalloc.c */ Bool compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update); void compFreeClientWindow(WindowPtr pWin, XID id); int compUnredirectWindow(ClientPtr pClient, WindowPtr pWin, int update); int compRedirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update); void compFreeClientSubwindows(WindowPtr pWin, XID id); int compUnredirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update); int compRedirectOneSubwindow(WindowPtr pParent, WindowPtr pWin); int compUnredirectOneSubwindow(WindowPtr pParent, WindowPtr pWin); Bool compAllocPixmap(WindowPtr pWin); void compSetParentPixmap(WindowPtr pWin); void compRestoreWindow(WindowPtr pWin, PixmapPtr pPixmap); Bool compReallocPixmap(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, int bw); void compMarkAncestors(WindowPtr pWin); /* * compinit.c */ Bool compScreenInit(ScreenPtr pScreen); /* * compoverlay.c */ void compFreeOverlayClient(CompOverlayClientPtr pOcToDel); CompOverlayClientPtr compFindOverlayClient(ScreenPtr pScreen, ClientPtr pClient); CompOverlayClientPtr compCreateOverlayClient(ScreenPtr pScreen, ClientPtr pClient); Bool compCreateOverlayWindow(ScreenPtr pScreen); void compDestroyOverlayWindow(ScreenPtr pScreen); /* * compwindow.c */ #ifdef COMPOSITE_DEBUG void compCheckTree(ScreenPtr pScreen); #else #define compCheckTree(s) #endif void compSetPixmap(WindowPtr pWin, PixmapPtr pPixmap, int bw); Bool compCheckRedirect(WindowPtr pWin); Bool compPositionWindow(WindowPtr pWin, int x, int y); Bool compRealizeWindow(WindowPtr pWin); Bool compUnrealizeWindow(WindowPtr pWin); void compClipNotify(WindowPtr pWin, int dx, int dy); void compMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind); void compResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, WindowPtr pSib); void compChangeBorderWidth(WindowPtr pWin, unsigned int border_width); void compReparentWindow(WindowPtr pWin, WindowPtr pPriorParent); Bool compCreateWindow(WindowPtr pWin); Bool compDestroyWindow(WindowPtr pWin); void compSetRedirectBorderClip(WindowPtr pWin, RegionPtr pRegion); RegionPtr compGetRedirectBorderClip(WindowPtr pWin); void compCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); void compPaintChildrenToWindow(WindowPtr pWin); WindowPtr CompositeRealChildHead(WindowPtr pWin); int DeleteWindowNoInputDevices(void *value, XID wid); int compConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw, WindowPtr pSib); void PanoramiXCompositeInit(void); void PanoramiXCompositeReset(void); #endif /* _COMPINT_H_ */ xorg-server-1.20.13/composite/compinit.c0000644000175000017500000003532314100573755015067 00000000000000/* * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright © 2003 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 #endif #include "compint.h" #include "compositeext.h" DevPrivateKeyRec CompScreenPrivateKeyRec; DevPrivateKeyRec CompWindowPrivateKeyRec; DevPrivateKeyRec CompSubwindowsPrivateKeyRec; static Bool compCloseScreen(ScreenPtr pScreen) { CompScreenPtr cs = GetCompScreen(pScreen); Bool ret; free(cs->alternateVisuals); pScreen->CloseScreen = cs->CloseScreen; pScreen->InstallColormap = cs->InstallColormap; pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes; pScreen->ReparentWindow = cs->ReparentWindow; pScreen->ConfigNotify = cs->ConfigNotify; pScreen->MoveWindow = cs->MoveWindow; pScreen->ResizeWindow = cs->ResizeWindow; pScreen->ChangeBorderWidth = cs->ChangeBorderWidth; pScreen->ClipNotify = cs->ClipNotify; pScreen->UnrealizeWindow = cs->UnrealizeWindow; pScreen->RealizeWindow = cs->RealizeWindow; pScreen->DestroyWindow = cs->DestroyWindow; pScreen->CreateWindow = cs->CreateWindow; pScreen->CopyWindow = cs->CopyWindow; pScreen->PositionWindow = cs->PositionWindow; pScreen->GetImage = cs->GetImage; pScreen->GetSpans = cs->GetSpans; pScreen->SourceValidate = cs->SourceValidate; free(cs); dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL); ret = (*pScreen->CloseScreen) (pScreen); return ret; } static void compInstallColormap(ColormapPtr pColormap) { VisualPtr pVisual = pColormap->pVisual; ScreenPtr pScreen = pColormap->pScreen; CompScreenPtr cs = GetCompScreen(pScreen); int a; for (a = 0; a < cs->numAlternateVisuals; a++) if (pVisual->vid == cs->alternateVisuals[a]) return; pScreen->InstallColormap = cs->InstallColormap; (*pScreen->InstallColormap) (pColormap); cs->InstallColormap = pScreen->InstallColormap; pScreen->InstallColormap = compInstallColormap; } static void compCheckBackingStore(WindowPtr pWin) { if (pWin->backingStore != NotUseful && !pWin->backStorage) { compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic); pWin->backStorage = TRUE; } else if (pWin->backingStore == NotUseful && pWin->backStorage) { compUnredirectWindow(serverClient, pWin, CompositeRedirectAutomatic); pWin->backStorage = FALSE; } } /* Fake backing store via automatic redirection */ static Bool compChangeWindowAttributes(WindowPtr pWin, unsigned long mask) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); Bool ret; pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes; ret = pScreen->ChangeWindowAttributes(pWin, mask); if (ret && (mask & CWBackingStore) && pScreen->backingStoreSupport != NotUseful) compCheckBackingStore(pWin); pScreen->ChangeWindowAttributes = compChangeWindowAttributes; return ret; } static void compGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, unsigned int format, unsigned long planemask, char *pdstLine) { ScreenPtr pScreen = pDrawable->pScreen; CompScreenPtr cs = GetCompScreen(pScreen); pScreen->GetImage = cs->GetImage; if (pDrawable->type == DRAWABLE_WINDOW) compPaintChildrenToWindow((WindowPtr) pDrawable); (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine); cs->GetImage = pScreen->GetImage; pScreen->GetImage = compGetImage; } static void compGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart) { ScreenPtr pScreen = pDrawable->pScreen; CompScreenPtr cs = GetCompScreen(pScreen); pScreen->GetSpans = cs->GetSpans; if (pDrawable->type == DRAWABLE_WINDOW) compPaintChildrenToWindow((WindowPtr) pDrawable); (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); cs->GetSpans = pScreen->GetSpans; pScreen->GetSpans = compGetSpans; } static void compSourceValidate(DrawablePtr pDrawable, int x, int y, int width, int height, unsigned int subWindowMode) { ScreenPtr pScreen = pDrawable->pScreen; CompScreenPtr cs = GetCompScreen(pScreen); pScreen->SourceValidate = cs->SourceValidate; if (pDrawable->type == DRAWABLE_WINDOW && subWindowMode == IncludeInferiors) compPaintChildrenToWindow((WindowPtr) pDrawable); if (pScreen->SourceValidate) (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode); cs->SourceValidate = pScreen->SourceValidate; pScreen->SourceValidate = compSourceValidate; } /* * Add alternate visuals -- always expose an ARGB32 and RGB24 visual */ static DepthPtr compFindVisuallessDepth(ScreenPtr pScreen, int d) { int i; for (i = 0; i < pScreen->numDepths; i++) { DepthPtr depth = &pScreen->allowedDepths[i]; if (depth->depth == d) { /* * Make sure it doesn't have visuals already */ if (depth->numVids) return 0; /* * looks fine */ return depth; } } /* * If there isn't one, then it's gonna be hard to have * an associated visual */ return 0; } /* * Add a list of visual IDs to the list of visuals to implicitly redirect. */ static Bool compRegisterAlternateVisuals(CompScreenPtr cs, VisualID * vids, int nVisuals) { VisualID *p; p = reallocarray(cs->alternateVisuals, cs->numAlternateVisuals + nVisuals, sizeof(VisualID)); if (p == NULL) return FALSE; memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals); cs->alternateVisuals = p; cs->numAlternateVisuals += nVisuals; return TRUE; } Bool CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids, int nVisuals) { CompScreenPtr cs = GetCompScreen(pScreen); return compRegisterAlternateVisuals(cs, vids, nVisuals); } Bool CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen, VisualID parentVisual, VisualID winVisual) { CompScreenPtr cs = GetCompScreen(pScreen); CompImplicitRedirectException *p; p = reallocarray(cs->implicitRedirectExceptions, cs->numImplicitRedirectExceptions + 1, sizeof(p[0])); if (p == NULL) return FALSE; p[cs->numImplicitRedirectExceptions].parentVisual = parentVisual; p[cs->numImplicitRedirectExceptions].winVisual = winVisual; cs->implicitRedirectExceptions = p; cs->numImplicitRedirectExceptions++; return TRUE; } typedef struct _alternateVisual { int depth; CARD32 format; } CompAlternateVisual; static CompAlternateVisual altVisuals[] = { #if COMP_INCLUDE_RGB24_VISUAL {24, PICT_r8g8b8}, #endif {32, PICT_a8r8g8b8}, }; static Bool compAddAlternateVisual(ScreenPtr pScreen, CompScreenPtr cs, CompAlternateVisual * alt) { VisualPtr visual; DepthPtr depth; PictFormatPtr pPictFormat; unsigned long alphaMask; /* * The ARGB32 visual is always available. Other alternate depth visuals * are only provided if their depth is less than the root window depth. * There's no deep reason for this. */ if (alt->depth >= pScreen->rootDepth && alt->depth != 32) return FALSE; depth = compFindVisuallessDepth(pScreen, alt->depth); if (!depth) /* alt->depth doesn't exist or already has alternate visuals. */ return TRUE; pPictFormat = PictureMatchFormat(pScreen, alt->depth, alt->format); if (!pPictFormat) return FALSE; if (ResizeVisualArray(pScreen, 1, depth) == FALSE) { return FALSE; } visual = pScreen->visuals + (pScreen->numVisuals - 1); /* the new one */ /* Initialize the visual */ visual->bitsPerRGBValue = 8; if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) { visual->class = PseudoColor; visual->nplanes = PICT_FORMAT_BPP(alt->format); visual->ColormapEntries = 1 << visual->nplanes; } else { DirectFormatRec *direct = &pPictFormat->direct; visual->class = TrueColor; visual->redMask = ((unsigned long) direct->redMask) << direct->red; visual->greenMask = ((unsigned long) direct->greenMask) << direct->green; visual->blueMask = ((unsigned long) direct->blueMask) << direct->blue; alphaMask = ((unsigned long) direct->alphaMask) << direct->alpha; visual->offsetRed = direct->red; visual->offsetGreen = direct->green; visual->offsetBlue = direct->blue; /* * Include A bits in this (unlike GLX which includes only RGB) * This lets DIX compute suitable masks for colormap allocations */ visual->nplanes = Ones(visual->redMask | visual->greenMask | visual->blueMask | alphaMask); /* find widest component */ visual->ColormapEntries = (1 << max(Ones(visual->redMask), max(Ones(visual->greenMask), Ones(visual->blueMask)))); } /* remember the visual ID to detect auto-update windows */ compRegisterAlternateVisuals(cs, &visual->vid, 1); return TRUE; } static Bool compAddAlternateVisuals(ScreenPtr pScreen, CompScreenPtr cs) { int alt, ret = 0; for (alt = 0; alt < ARRAY_SIZE(altVisuals); alt++) ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt); return ! !ret; } Bool compScreenInit(ScreenPtr pScreen) { CompScreenPtr cs; if (!dixRegisterPrivateKey(&CompScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) return FALSE; if (!dixRegisterPrivateKey(&CompWindowPrivateKeyRec, PRIVATE_WINDOW, 0)) return FALSE; if (!dixRegisterPrivateKey(&CompSubwindowsPrivateKeyRec, PRIVATE_WINDOW, 0)) return FALSE; if (GetCompScreen(pScreen)) return TRUE; cs = (CompScreenPtr) malloc(sizeof(CompScreenRec)); if (!cs) return FALSE; cs->overlayWid = FakeClientID(0); cs->pOverlayWin = NULL; cs->pOverlayClients = NULL; cs->pendingScreenUpdate = FALSE; cs->numAlternateVisuals = 0; cs->alternateVisuals = NULL; cs->numImplicitRedirectExceptions = 0; cs->implicitRedirectExceptions = NULL; if (!compAddAlternateVisuals(pScreen, cs)) { free(cs); return FALSE; } if (!disableBackingStore) pScreen->backingStoreSupport = WhenMapped; cs->PositionWindow = pScreen->PositionWindow; pScreen->PositionWindow = compPositionWindow; cs->CopyWindow = pScreen->CopyWindow; pScreen->CopyWindow = compCopyWindow; cs->CreateWindow = pScreen->CreateWindow; pScreen->CreateWindow = compCreateWindow; cs->DestroyWindow = pScreen->DestroyWindow; pScreen->DestroyWindow = compDestroyWindow; cs->RealizeWindow = pScreen->RealizeWindow; pScreen->RealizeWindow = compRealizeWindow; cs->UnrealizeWindow = pScreen->UnrealizeWindow; pScreen->UnrealizeWindow = compUnrealizeWindow; cs->ClipNotify = pScreen->ClipNotify; pScreen->ClipNotify = compClipNotify; cs->ConfigNotify = pScreen->ConfigNotify; pScreen->ConfigNotify = compConfigNotify; cs->MoveWindow = pScreen->MoveWindow; pScreen->MoveWindow = compMoveWindow; cs->ResizeWindow = pScreen->ResizeWindow; pScreen->ResizeWindow = compResizeWindow; cs->ChangeBorderWidth = pScreen->ChangeBorderWidth; pScreen->ChangeBorderWidth = compChangeBorderWidth; cs->ReparentWindow = pScreen->ReparentWindow; pScreen->ReparentWindow = compReparentWindow; cs->InstallColormap = pScreen->InstallColormap; pScreen->InstallColormap = compInstallColormap; cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; pScreen->ChangeWindowAttributes = compChangeWindowAttributes; cs->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = compCloseScreen; cs->GetImage = pScreen->GetImage; pScreen->GetImage = compGetImage; cs->GetSpans = pScreen->GetSpans; pScreen->GetSpans = compGetSpans; cs->SourceValidate = pScreen->SourceValidate; pScreen->SourceValidate = compSourceValidate; dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs); RegisterRealChildHeadProc(CompositeRealChildHead); return TRUE; } xorg-server-1.20.13/composite/compoverlay.c0000644000175000017500000001255714100573755015611 00000000000000/* * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright © 2003 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 #endif #include "compint.h" #include "xace.h" #ifdef PANORAMIX #include "panoramiXsrv.h" #endif /* * Delete the given overlay client list element from its screen list. */ void compFreeOverlayClient(CompOverlayClientPtr pOcToDel) { ScreenPtr pScreen = pOcToDel->pScreen; CompScreenPtr cs = GetCompScreen(pScreen); CompOverlayClientPtr *pPrev, pOc; for (pPrev = &cs->pOverlayClients; (pOc = *pPrev); pPrev = &pOc->pNext) { if (pOc == pOcToDel) { *pPrev = pOc->pNext; free(pOc); break; } } /* Destroy overlay window when there are no more clients using it */ if (cs->pOverlayClients == NULL) compDestroyOverlayWindow(pScreen); } /* * Return the client's first overlay client rec from the given screen */ CompOverlayClientPtr compFindOverlayClient(ScreenPtr pScreen, ClientPtr pClient) { CompScreenPtr cs = GetCompScreen(pScreen); CompOverlayClientPtr pOc; for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext) if (pOc->pClient == pClient) return pOc; return NULL; } /* * Create an overlay client object for the given client */ CompOverlayClientPtr compCreateOverlayClient(ScreenPtr pScreen, ClientPtr pClient) { CompScreenPtr cs = GetCompScreen(pScreen); CompOverlayClientPtr pOc; pOc = (CompOverlayClientPtr) malloc(sizeof(CompOverlayClientRec)); if (pOc == NULL) return NULL; pOc->pClient = pClient; pOc->pScreen = pScreen; pOc->resource = FakeClientID(pClient->index); pOc->pNext = cs->pOverlayClients; cs->pOverlayClients = pOc; /* * Create a resource for this element so it can be deleted * when the client goes away. */ if (!AddResource(pOc->resource, CompositeClientOverlayType, (void *) pOc)) return NULL; return pOc; } /* * Create the overlay window and map it */ Bool compCreateOverlayWindow(ScreenPtr pScreen) { CompScreenPtr cs = GetCompScreen(pScreen); WindowPtr pRoot = pScreen->root; WindowPtr pWin; XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */ int result; int w = pScreen->width; int h = pScreen->height; int x = 0, y = 0; #ifdef PANORAMIX if (!noPanoramiXExtension) { x = -pScreen->x; y = -pScreen->y; w = PanoramiXPixWidth; h = PanoramiXPixHeight; } #endif pWin = cs->pOverlayWin = CreateWindow(cs->overlayWid, pRoot, x, y, w, h, 0, InputOutput, CWBackPixmap | CWOverrideRedirect, &attrs[0], pRoot->drawable.depth, serverClient, pScreen->rootVisual, &result); if (pWin == NULL) return FALSE; if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pWin)) return FALSE; MapWindow(pWin, serverClient); return TRUE; } /* * Destroy the overlay window */ void compDestroyOverlayWindow(ScreenPtr pScreen) { CompScreenPtr cs = GetCompScreen(pScreen); cs->pOverlayWin = NullWindow; FreeResource(cs->overlayWid, RT_NONE); } xorg-server-1.20.13/composite/compwindow.c0000644000175000017500000006110014100573755015423 00000000000000/* * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright © 2003 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 #endif #include "compint.h" #ifdef PANORAMIX #include "panoramiXsrv.h" #endif #ifdef COMPOSITE_DEBUG static int compCheckWindow(WindowPtr pWin, void *data) { ScreenPtr pScreen = pWin->drawable.pScreen; PixmapPtr pWinPixmap = (*pScreen->GetWindowPixmap) (pWin); PixmapPtr pParentPixmap = pWin->parent ? (*pScreen->GetWindowPixmap) (pWin->parent) : 0; PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap) (pScreen); if (!pWin->parent) { assert(pWin->redirectDraw == RedirectDrawNone); assert(pWinPixmap == pScreenPixmap); } else if (pWin->redirectDraw != RedirectDrawNone) { assert(pWinPixmap != pParentPixmap); assert(pWinPixmap != pScreenPixmap); } else { assert(pWinPixmap == pParentPixmap); } assert(0 < pWinPixmap->refcnt && pWinPixmap->refcnt < 3); assert(0 < pScreenPixmap->refcnt && pScreenPixmap->refcnt < 3); if (pParentPixmap) assert(0 <= pParentPixmap->refcnt && pParentPixmap->refcnt < 3); return WT_WALKCHILDREN; } void compCheckTree(ScreenPtr pScreen) { WalkTree(pScreen, compCheckWindow, 0); } #endif typedef struct _compPixmapVisit { WindowPtr pWindow; PixmapPtr pPixmap; int bw; } CompPixmapVisitRec, *CompPixmapVisitPtr; static Bool compRepaintBorder(ClientPtr pClient, void *closure) { WindowPtr pWindow; int rc = dixLookupWindow(&pWindow, (XID) (intptr_t) closure, pClient, DixWriteAccess); if (rc == Success) { RegionRec exposed; RegionNull(&exposed); RegionSubtract(&exposed, &pWindow->borderClip, &pWindow->winSize); pWindow->drawable.pScreen->PaintWindow(pWindow, &exposed, PW_BORDER); RegionUninit(&exposed); } return TRUE; } static int compSetPixmapVisitWindow(WindowPtr pWindow, void *data) { CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data; ScreenPtr pScreen = pWindow->drawable.pScreen; if (pWindow != pVisit->pWindow && pWindow->redirectDraw != RedirectDrawNone) return WT_DONTWALKCHILDREN; (*pScreen->SetWindowPixmap) (pWindow, pVisit->pPixmap); /* * Recompute winSize and borderSize. This is duplicate effort * when resizing pixmaps, but necessary when changing redirection. * Might be nice to fix this. */ SetWinSize(pWindow); SetBorderSize(pWindow); if (pVisit->bw) QueueWorkProc(compRepaintBorder, serverClient, (void *) (intptr_t) pWindow->drawable.id); return WT_WALKCHILDREN; } void compSetPixmap(WindowPtr pWindow, PixmapPtr pPixmap, int bw) { CompPixmapVisitRec visitRec; visitRec.pWindow = pWindow; visitRec.pPixmap = pPixmap; visitRec.bw = bw; TraverseTree(pWindow, compSetPixmapVisitWindow, (void *) &visitRec); compCheckTree(pWindow->drawable.pScreen); } Bool compCheckRedirect(WindowPtr pWin) { CompWindowPtr cw = GetCompWindow(pWin); CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); Bool should; should = pWin->realized && (pWin->drawable.class != InputOnly) && (cw != NULL) && (pWin->parent != NULL); /* Never redirect the overlay window */ if (cs->pOverlayWin != NULL) { if (pWin == cs->pOverlayWin) { should = FALSE; } } if (should != (pWin->redirectDraw != RedirectDrawNone)) { if (should) return compAllocPixmap(pWin); else { ScreenPtr pScreen = pWin->drawable.pScreen; PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); compSetParentPixmap(pWin); compRestoreWindow(pWin, pPixmap); (*pScreen->DestroyPixmap) (pPixmap); } } else if (should) { if (cw->update == CompositeRedirectAutomatic) pWin->redirectDraw = RedirectDrawAutomatic; else pWin->redirectDraw = RedirectDrawManual; } return TRUE; } static int updateOverlayWindow(ScreenPtr pScreen) { CompScreenPtr cs; WindowPtr pWin; /* overlay window */ XID vlist[2]; int w = pScreen->width; int h = pScreen->height; #ifdef PANORAMIX if (!noPanoramiXExtension) { w = PanoramiXPixWidth; h = PanoramiXPixHeight; } #endif cs = GetCompScreen(pScreen); if ((pWin = cs->pOverlayWin) != NULL) { if ((pWin->drawable.width == w) && (pWin->drawable.height == h)) return Success; /* Let's resize the overlay window. */ vlist[0] = w; vlist[1] = h; return ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin)); } /* Let's be on the safe side and not assume an overlay window is always allocated. */ return Success; } Bool compPositionWindow(WindowPtr pWin, int x, int y) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); Bool ret = TRUE; pScreen->PositionWindow = cs->PositionWindow; /* * "Shouldn't need this as all possible places should be wrapped * compCheckRedirect (pWin); */ #ifdef COMPOSITE_DEBUG if ((pWin->redirectDraw != RedirectDrawNone) != (pWin->viewable && (GetCompWindow(pWin) != NULL))) OsAbort(); #endif if (pWin->redirectDraw != RedirectDrawNone) { PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); int bw = wBorderWidth(pWin); int nx = pWin->drawable.x - bw; int ny = pWin->drawable.y - bw; if (pPixmap->screen_x != nx || pPixmap->screen_y != ny) { pPixmap->screen_x = nx; pPixmap->screen_y = ny; pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; } } if (!(*pScreen->PositionWindow) (pWin, x, y)) ret = FALSE; cs->PositionWindow = pScreen->PositionWindow; pScreen->PositionWindow = compPositionWindow; compCheckTree(pWin->drawable.pScreen); if (updateOverlayWindow(pScreen) != Success) ret = FALSE; return ret; } Bool compRealizeWindow(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); Bool ret = TRUE; pScreen->RealizeWindow = cs->RealizeWindow; compCheckRedirect(pWin); if (!(*pScreen->RealizeWindow) (pWin)) ret = FALSE; cs->RealizeWindow = pScreen->RealizeWindow; pScreen->RealizeWindow = compRealizeWindow; compCheckTree(pWin->drawable.pScreen); return ret; } Bool compUnrealizeWindow(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); Bool ret = TRUE; pScreen->UnrealizeWindow = cs->UnrealizeWindow; compCheckRedirect(pWin); if (!(*pScreen->UnrealizeWindow) (pWin)) ret = FALSE; cs->UnrealizeWindow = pScreen->UnrealizeWindow; pScreen->UnrealizeWindow = compUnrealizeWindow; compCheckTree(pWin->drawable.pScreen); return ret; } /* * Called after the borderClip for the window has settled down * We use this to make sure our extra borderClip has the right origin */ void compClipNotify(WindowPtr pWin, int dx, int dy) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); CompWindowPtr cw = GetCompWindow(pWin); if (cw) { if (cw->borderClipX != pWin->drawable.x || cw->borderClipY != pWin->drawable.y) { RegionTranslate(&cw->borderClip, pWin->drawable.x - cw->borderClipX, pWin->drawable.y - cw->borderClipY); cw->borderClipX = pWin->drawable.x; cw->borderClipY = pWin->drawable.y; } } if (cs->ClipNotify) { pScreen->ClipNotify = cs->ClipNotify; (*pScreen->ClipNotify) (pWin, dx, dy); cs->ClipNotify = pScreen->ClipNotify; pScreen->ClipNotify = compClipNotify; } } Bool compIsAlternateVisual(ScreenPtr pScreen, XID visual) { CompScreenPtr cs = GetCompScreen(pScreen); int i; for (i = 0; cs && i < cs->numAlternateVisuals; i++) if (cs->alternateVisuals[i] == visual) return TRUE; return FALSE; } static Bool compIsImplicitRedirectException(ScreenPtr pScreen, XID parentVisual, XID winVisual) { CompScreenPtr cs = GetCompScreen(pScreen); int i; for (i = 0; i < cs->numImplicitRedirectExceptions; i++) if (cs->implicitRedirectExceptions[i].parentVisual == parentVisual && cs->implicitRedirectExceptions[i].winVisual == winVisual) return TRUE; return FALSE; } static Bool compImplicitRedirect(WindowPtr pWin, WindowPtr pParent) { if (pParent) { ScreenPtr pScreen = pWin->drawable.pScreen; XID winVisual = wVisual(pWin); XID parentVisual = wVisual(pParent); if (compIsImplicitRedirectException(pScreen, parentVisual, winVisual)) return FALSE; if (winVisual != parentVisual && (compIsAlternateVisual(pScreen, winVisual) || compIsAlternateVisual(pScreen, parentVisual))) return TRUE; } return FALSE; } static void compFreeOldPixmap(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; if (pWin->redirectDraw != RedirectDrawNone) { CompWindowPtr cw = GetCompWindow(pWin); if (cw->pOldPixmap) { (*pScreen->DestroyPixmap) (cw->pOldPixmap); cw->pOldPixmap = NullPixmap; } } } void compMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); pScreen->MoveWindow = cs->MoveWindow; (*pScreen->MoveWindow) (pWin, x, y, pSib, kind); cs->MoveWindow = pScreen->MoveWindow; pScreen->MoveWindow = compMoveWindow; compFreeOldPixmap(pWin); compCheckTree(pScreen); } void compResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, WindowPtr pSib) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); pScreen->ResizeWindow = cs->ResizeWindow; (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib); cs->ResizeWindow = pScreen->ResizeWindow; pScreen->ResizeWindow = compResizeWindow; compFreeOldPixmap(pWin); compCheckTree(pWin->drawable.pScreen); } void compChangeBorderWidth(WindowPtr pWin, unsigned int bw) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); pScreen->ChangeBorderWidth = cs->ChangeBorderWidth; (*pScreen->ChangeBorderWidth) (pWin, bw); cs->ChangeBorderWidth = pScreen->ChangeBorderWidth; pScreen->ChangeBorderWidth = compChangeBorderWidth; compFreeOldPixmap(pWin); compCheckTree(pWin->drawable.pScreen); } void compReparentWindow(WindowPtr pWin, WindowPtr pPriorParent) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); CompWindowPtr cw; pScreen->ReparentWindow = cs->ReparentWindow; /* * Remove any implicit redirect due to synthesized visual */ if (compImplicitRedirect(pWin, pPriorParent)) compUnredirectWindow(serverClient, pWin, CompositeRedirectAutomatic); /* * Handle subwindows redirection */ compUnredirectOneSubwindow(pPriorParent, pWin); compRedirectOneSubwindow(pWin->parent, pWin); /* * Add any implict redirect due to synthesized visual */ if (compImplicitRedirect(pWin, pWin->parent)) compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic); /* * Allocate any necessary redirect pixmap * (this actually should never be true; pWin is always unmapped) */ compCheckRedirect(pWin); /* * Reset pixmap pointers as appropriate */ if (pWin->parent && pWin->redirectDraw == RedirectDrawNone) compSetPixmap(pWin, (*pScreen->GetWindowPixmap) (pWin->parent), pWin->borderWidth); /* * Call down to next function */ if (pScreen->ReparentWindow) (*pScreen->ReparentWindow) (pWin, pPriorParent); cs->ReparentWindow = pScreen->ReparentWindow; pScreen->ReparentWindow = compReparentWindow; cw = GetCompWindow(pWin); if (pWin->damagedDescendants || (cw && cw->damaged)) compMarkAncestors(pWin); compCheckTree(pWin->drawable.pScreen); } void compCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); int dx = 0, dy = 0; if (pWin->redirectDraw != RedirectDrawNone) { PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); CompWindowPtr cw = GetCompWindow(pWin); assert(cw->oldx != COMP_ORIGIN_INVALID); assert(cw->oldy != COMP_ORIGIN_INVALID); if (cw->pOldPixmap) { /* * Ok, the old bits are available in pOldPixmap and * need to be copied to pNewPixmap. */ RegionRec rgnDst; GCPtr pGC; dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; RegionTranslate(prgnSrc, -dx, -dy); RegionNull(&rgnDst); RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc); RegionTranslate(&rgnDst, -pPixmap->screen_x, -pPixmap->screen_y); dx = dx + pPixmap->screen_x - cw->oldx; dy = dy + pPixmap->screen_y - cw->oldy; pGC = GetScratchGC(pPixmap->drawable.depth, pScreen); if (pGC) { BoxPtr pBox = RegionRects(&rgnDst); int nBox = RegionNumRects(&rgnDst); ValidateGC(&pPixmap->drawable, pGC); while (nBox--) { (void) (*pGC->ops->CopyArea) (&cw->pOldPixmap->drawable, &pPixmap->drawable, pGC, pBox->x1 + dx, pBox->y1 + dy, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1, pBox->x1, pBox->y1); pBox++; } FreeScratchGC(pGC); } RegionUninit(&rgnDst); return; } dx = pPixmap->screen_x - cw->oldx; dy = pPixmap->screen_y - cw->oldy; ptOldOrg.x += dx; ptOldOrg.y += dy; } pScreen->CopyWindow = cs->CopyWindow; if (ptOldOrg.x != pWin->drawable.x || ptOldOrg.y != pWin->drawable.y) { if (dx || dy) RegionTranslate(prgnSrc, dx, dy); (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc); if (dx || dy) RegionTranslate(prgnSrc, -dx, -dy); } else { ptOldOrg.x -= dx; ptOldOrg.y -= dy; RegionTranslate(prgnSrc, pWin->drawable.x - ptOldOrg.x, pWin->drawable.y - ptOldOrg.y); DamageDamageRegion(&pWin->drawable, prgnSrc); } cs->CopyWindow = pScreen->CopyWindow; pScreen->CopyWindow = compCopyWindow; compCheckTree(pWin->drawable.pScreen); } Bool compCreateWindow(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); Bool ret; pScreen->CreateWindow = cs->CreateWindow; ret = (*pScreen->CreateWindow) (pWin); if (pWin->parent && ret) { CompSubwindowsPtr csw = GetCompSubwindows(pWin->parent); CompClientWindowPtr ccw; PixmapPtr parent_pixmap = (*pScreen->GetWindowPixmap)(pWin->parent); PixmapPtr window_pixmap = (*pScreen->GetWindowPixmap)(pWin); if (window_pixmap != parent_pixmap) (*pScreen->SetWindowPixmap) (pWin, parent_pixmap); if (csw) for (ccw = csw->clients; ccw; ccw = ccw->next) compRedirectWindow(clients[CLIENT_ID(ccw->id)], pWin, ccw->update); if (compImplicitRedirect(pWin, pWin->parent)) compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic); } cs->CreateWindow = pScreen->CreateWindow; pScreen->CreateWindow = compCreateWindow; compCheckTree(pWin->drawable.pScreen); return ret; } Bool compDestroyWindow(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); CompWindowPtr cw; CompSubwindowsPtr csw; Bool ret; pScreen->DestroyWindow = cs->DestroyWindow; while ((cw = GetCompWindow(pWin))) FreeResource(cw->clients->id, RT_NONE); while ((csw = GetCompSubwindows(pWin))) FreeResource(csw->clients->id, RT_NONE); if (pWin->redirectDraw != RedirectDrawNone) { PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); compSetParentPixmap(pWin); (*pScreen->DestroyPixmap) (pPixmap); } ret = (*pScreen->DestroyWindow) (pWin); cs->DestroyWindow = pScreen->DestroyWindow; pScreen->DestroyWindow = compDestroyWindow; /* compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/ return ret; } void compSetRedirectBorderClip(WindowPtr pWin, RegionPtr pRegion) { CompWindowPtr cw = GetCompWindow(pWin); RegionRec damage; RegionNull(&damage); /* * Align old border clip with new border clip */ RegionTranslate(&cw->borderClip, pWin->drawable.x - cw->borderClipX, pWin->drawable.y - cw->borderClipY); /* * Compute newly visible portion of window for repaint */ RegionSubtract(&damage, pRegion, &cw->borderClip); /* * Report that as damaged so it will be redrawn */ DamageDamageRegion(&pWin->drawable, &damage); RegionUninit(&damage); /* * Save the new border clip region */ RegionCopy(&cw->borderClip, pRegion); cw->borderClipX = pWin->drawable.x; cw->borderClipY = pWin->drawable.y; } RegionPtr compGetRedirectBorderClip(WindowPtr pWin) { CompWindowPtr cw = GetCompWindow(pWin); return &cw->borderClip; } static void compWindowUpdateAutomatic(WindowPtr pWin) { CompWindowPtr cw = GetCompWindow(pWin); ScreenPtr pScreen = pWin->drawable.pScreen; WindowPtr pParent = pWin->parent; PixmapPtr pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin); PictFormatPtr pSrcFormat = PictureWindowFormat(pWin); PictFormatPtr pDstFormat = PictureWindowFormat(pWin->parent); int error; RegionPtr pRegion = DamageRegion(cw->damage); PicturePtr pSrcPicture = CreatePicture(0, &pSrcPixmap->drawable, pSrcFormat, 0, 0, serverClient, &error); XID subwindowMode = IncludeInferiors; PicturePtr pDstPicture = CreatePicture(0, &pParent->drawable, pDstFormat, CPSubwindowMode, &subwindowMode, serverClient, &error); /* * First move the region from window to screen coordinates */ RegionTranslate(pRegion, pWin->drawable.x, pWin->drawable.y); /* * Clip against the "real" border clip */ RegionIntersect(pRegion, pRegion, &cw->borderClip); /* * Now translate from screen to dest coordinates */ RegionTranslate(pRegion, -pParent->drawable.x, -pParent->drawable.y); /* * Clip the picture */ SetPictureClipRegion(pDstPicture, 0, 0, pRegion); /* * And paint */ CompositePicture(PictOpSrc, pSrcPicture, 0, pDstPicture, 0, 0, /* src_x, src_y */ 0, 0, /* msk_x, msk_y */ pSrcPixmap->screen_x - pParent->drawable.x, pSrcPixmap->screen_y - pParent->drawable.y, pSrcPixmap->drawable.width, pSrcPixmap->drawable.height); FreePicture(pSrcPicture, 0); FreePicture(pDstPicture, 0); /* * Empty the damage region. This has the nice effect of * rendering the translations above harmless */ DamageEmpty(cw->damage); } static void compPaintWindowToParent(WindowPtr pWin) { compPaintChildrenToWindow(pWin); if (pWin->redirectDraw != RedirectDrawNone) { CompWindowPtr cw = GetCompWindow(pWin); if (cw->damaged) { compWindowUpdateAutomatic(pWin); cw->damaged = FALSE; } } } void compPaintChildrenToWindow(WindowPtr pWin) { WindowPtr pChild; if (!pWin->damagedDescendants) return; for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) compPaintWindowToParent(pChild); pWin->damagedDescendants = FALSE; } WindowPtr CompositeRealChildHead(WindowPtr pWin) { WindowPtr pChild, pChildBefore; CompScreenPtr cs; if (!pWin->parent && (screenIsSaved == SCREEN_SAVER_ON) && (HasSaverWindow(pWin->drawable.pScreen))) { /* First child is the screen saver; see if next child is the overlay */ pChildBefore = pWin->firstChild; pChild = pChildBefore->nextSib; } else { pChildBefore = NullWindow; pChild = pWin->firstChild; } if (!pChild) { return NullWindow; } cs = GetCompScreen(pWin->drawable.pScreen); if (pChild == cs->pOverlayWin) { return pChild; } else { return pChildBefore; } } int compConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw, WindowPtr pSib) { ScreenPtr pScreen = pWin->drawable.pScreen; CompScreenPtr cs = GetCompScreen(pScreen); Bool ret = 0; WindowPtr pParent = pWin->parent; int draw_x, draw_y; Bool alloc_ret; if (cs->ConfigNotify) { pScreen->ConfigNotify = cs->ConfigNotify; ret = (*pScreen->ConfigNotify) (pWin, x, y, w, h, bw, pSib); cs->ConfigNotify = pScreen->ConfigNotify; pScreen->ConfigNotify = compConfigNotify; if (ret) return ret; } if (pWin->redirectDraw == RedirectDrawNone) return Success; compCheckTree(pScreen); draw_x = pParent->drawable.x + x + bw; draw_y = pParent->drawable.y + y + bw; alloc_ret = compReallocPixmap(pWin, draw_x, draw_y, w, h, bw); if (alloc_ret == FALSE) return BadAlloc; return Success; } xorg-server-1.20.13/config/0000755000175000017500000000000014100574020012400 500000000000000xorg-server-1.20.13/config/meson.build0000644000175000017500000000120214100573755014473 00000000000000srcs_config = [ 'config.c', ] config_dep = [common_dep] if build_dbus srcs_config += 'dbus-core.c' config_dep += dbus_dep endif if build_hal srcs_config += 'hal.c' config_dep += hal_dep endif if build_udev srcs_config += 'udev.c' config_dep += udev_dep endif if host_machine.system() == 'openbsd' srcs_config += 'wscons.c' endif if build_xorg install_data('10-quirks.conf', install_dir: join_paths(get_option('datadir'), 'X11/xorg.conf.d')) endif libxserver_config = static_library('libxserver_config', srcs_config, include_directories: inc, dependencies: config_dep, ) xorg-server-1.20.13/config/Makefile.am0000644000175000017500000000135714100573755014400 00000000000000AM_CFLAGS = $(DIX_CFLAGS) noinst_LTLIBRARIES = libconfig.la libconfig_la_SOURCES = config.c config-backends.h libconfig_la_LIBADD = if NEED_DBUS AM_CFLAGS += $(DBUS_CFLAGS) libconfig_la_SOURCES += dbus-core.c libconfig_la_LIBADD += $(DBUS_LIBS) endif if CONFIG_UDEV AM_CFLAGS += $(UDEV_CFLAGS) libconfig_la_SOURCES += udev.c libconfig_la_LIBADD += $(UDEV_LIBS) if XORG xorgconfddir = $(datadir)/X11/$(XF86CONFIGDIR) xorgconfd_DATA = 10-quirks.conf endif else if CONFIG_HAL AM_CFLAGS += $(HAL_CFLAGS) libconfig_la_SOURCES += hal.c libconfig_la_LIBADD += $(HAL_LIBS) else if CONFIG_WSCONS libconfig_la_SOURCES += wscons.c endif # CONFIG_WSCONS endif # !CONFIG_HAL endif # !CONFIG_UDEV EXTRA_DIST = x11-input.fdi fdi2iclass.py 10-quirks.conf xorg-server-1.20.13/config/Makefile.in0000644000175000017500000007442314100573775014417 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @NEED_DBUS_TRUE@am__append_1 = $(DBUS_CFLAGS) @NEED_DBUS_TRUE@am__append_2 = dbus-core.c @NEED_DBUS_TRUE@am__append_3 = $(DBUS_LIBS) @CONFIG_UDEV_TRUE@am__append_4 = $(UDEV_CFLAGS) @CONFIG_UDEV_TRUE@am__append_5 = udev.c @CONFIG_UDEV_TRUE@am__append_6 = $(UDEV_LIBS) @CONFIG_HAL_TRUE@@CONFIG_UDEV_FALSE@am__append_7 = $(HAL_CFLAGS) @CONFIG_HAL_TRUE@@CONFIG_UDEV_FALSE@am__append_8 = hal.c @CONFIG_HAL_TRUE@@CONFIG_UDEV_FALSE@am__append_9 = $(HAL_LIBS) @CONFIG_HAL_FALSE@@CONFIG_UDEV_FALSE@@CONFIG_WSCONS_TRUE@am__append_10 = wscons.c subdir = config ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = @NEED_DBUS_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) @CONFIG_UDEV_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) @CONFIG_HAL_TRUE@@CONFIG_UDEV_FALSE@am__DEPENDENCIES_4 = \ @CONFIG_HAL_TRUE@@CONFIG_UDEV_FALSE@ $(am__DEPENDENCIES_1) libconfig_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_4) am__libconfig_la_SOURCES_DIST = config.c config-backends.h dbus-core.c \ udev.c hal.c wscons.c @NEED_DBUS_TRUE@am__objects_1 = dbus-core.lo @CONFIG_UDEV_TRUE@am__objects_2 = udev.lo @CONFIG_HAL_TRUE@@CONFIG_UDEV_FALSE@am__objects_3 = hal.lo @CONFIG_HAL_FALSE@@CONFIG_UDEV_FALSE@@CONFIG_WSCONS_TRUE@am__objects_4 = wscons.lo am_libconfig_la_OBJECTS = config.lo $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) libconfig_la_OBJECTS = $(am_libconfig_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/config.Plo ./$(DEPDIR)/dbus-core.Plo \ ./$(DEPDIR)/hal.Plo ./$(DEPDIR)/udev.Plo \ ./$(DEPDIR)/wscons.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libconfig_la_SOURCES) DIST_SOURCES = $(am__libconfig_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(xorgconfddir)" DATA = $(xorgconfd_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CFLAGS = $(DIX_CFLAGS) $(am__append_1) $(am__append_4) \ $(am__append_7) noinst_LTLIBRARIES = libconfig.la libconfig_la_SOURCES = config.c config-backends.h $(am__append_2) \ $(am__append_5) $(am__append_8) $(am__append_10) libconfig_la_LIBADD = $(am__append_3) $(am__append_6) $(am__append_9) @CONFIG_UDEV_TRUE@@XORG_TRUE@xorgconfddir = $(datadir)/X11/$(XF86CONFIGDIR) @CONFIG_UDEV_TRUE@@XORG_TRUE@xorgconfd_DATA = 10-quirks.conf EXTRA_DIST = x11-input.fdi fdi2iclass.py 10-quirks.conf all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign config/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign config/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libconfig.la: $(libconfig_la_OBJECTS) $(libconfig_la_DEPENDENCIES) $(EXTRA_libconfig_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libconfig_la_OBJECTS) $(libconfig_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbus-core.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hal.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udev.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wscons.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-xorgconfdDATA: $(xorgconfd_DATA) @$(NORMAL_INSTALL) @list='$(xorgconfd_DATA)'; test -n "$(xorgconfddir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(xorgconfddir)'"; \ $(MKDIR_P) "$(DESTDIR)$(xorgconfddir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(xorgconfddir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(xorgconfddir)" || exit $$?; \ done uninstall-xorgconfdDATA: @$(NORMAL_UNINSTALL) @list='$(xorgconfd_DATA)'; test -n "$(xorgconfddir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(xorgconfddir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) installdirs: for dir in "$(DESTDIR)$(xorgconfddir)"; 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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/config.Plo -rm -f ./$(DEPDIR)/dbus-core.Plo -rm -f ./$(DEPDIR)/hal.Plo -rm -f ./$(DEPDIR)/udev.Plo -rm -f ./$(DEPDIR)/wscons.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-xorgconfdDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/config.Plo -rm -f ./$(DEPDIR)/dbus-core.Plo -rm -f ./$(DEPDIR)/hal.Plo -rm -f ./$(DEPDIR)/udev.Plo -rm -f ./$(DEPDIR)/wscons.Plo -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-xorgconfdDATA .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ install-xorgconfdDATA installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-xorgconfdDATA .PRECIOUS: Makefile # 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: xorg-server-1.20.13/config/config.c0000644000175000017500000001010114100573755013740 00000000000000/* * Copyright © 2006-2007 Daniel Stone * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Daniel Stone */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "os.h" #include "inputstr.h" #include "hotplug.h" #include "config-backends.h" #include "systemd-logind.h" void config_pre_init(void) { #ifdef CONFIG_UDEV if (!config_udev_pre_init()) ErrorF("[config] failed to pre-init udev\n"); #endif } void config_init(void) { #ifdef CONFIG_UDEV if (!config_udev_init()) ErrorF("[config] failed to initialise udev\n"); #elif defined(CONFIG_HAL) if (!config_hal_init()) ErrorF("[config] failed to initialise HAL\n"); #elif defined(CONFIG_WSCONS) if (!config_wscons_init()) ErrorF("[config] failed to initialise wscons\n"); #endif } void config_fini(void) { #if defined(CONFIG_UDEV) config_udev_fini(); #elif defined(CONFIG_HAL) config_hal_fini(); #elif defined(CONFIG_WSCONS) config_wscons_fini(); #endif } void config_odev_probe(config_odev_probe_proc_ptr probe_callback) { #if defined(CONFIG_UDEV_KMS) config_udev_odev_probe(probe_callback); #endif } static void remove_device(const char *backend, DeviceIntPtr dev) { /* this only gets called for devices that have already been added */ LogMessage(X_INFO, "config/%s: removing device %s\n", backend, dev->name); /* Call PIE here so we don't try to dereference a device that's * already been removed. */ input_lock(); ProcessInputEvents(); DeleteInputDeviceRequest(dev); input_unlock(); } void remove_devices(const char *backend, const char *config_info) { DeviceIntPtr dev, next; for (dev = inputInfo.devices; dev; dev = next) { next = dev->next; if (dev->config_info && strcmp(dev->config_info, config_info) == 0) remove_device(backend, dev); } for (dev = inputInfo.off_devices; dev; dev = next) { next = dev->next; if (dev->config_info && strcmp(dev->config_info, config_info) == 0) remove_device(backend, dev); } RemoveInputDeviceTraces(config_info); } BOOL device_is_duplicate(const char *config_info) { DeviceIntPtr dev; for (dev = inputInfo.devices; dev; dev = dev->next) { if (dev->config_info && (strcmp(dev->config_info, config_info) == 0)) return TRUE; } for (dev = inputInfo.off_devices; dev; dev = dev->next) { if (dev->config_info && (strcmp(dev->config_info, config_info) == 0)) return TRUE; } return FALSE; } struct OdevAttributes * config_odev_allocate_attributes(void) { struct OdevAttributes *attribs = xnfcalloc(1, sizeof (struct OdevAttributes)); attribs->fd = -1; return attribs; } void config_odev_free_attributes(struct OdevAttributes *attribs) { if (attribs->fd != -1) systemd_logind_release_fd(attribs->major, attribs->minor, attribs->fd); free(attribs->path); free(attribs->syspath); free(attribs->busid); free(attribs->driver); free(attribs); } xorg-server-1.20.13/config/config-backends.h0000644000175000017500000000336214100573755015530 00000000000000/* * Copyright © 2006-2007 Daniel Stone * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Daniel Stone */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "input.h" #include "list.h" void remove_devices(const char *backend, const char *config_info); BOOL device_is_duplicate(const char *config_info); #ifdef CONFIG_UDEV int config_udev_pre_init(void); int config_udev_init(void); void config_udev_fini(void); void config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback); #elif defined(CONFIG_HAL) int config_hal_init(void); void config_hal_fini(void); #elif defined(CONFIG_WSCONS) int config_wscons_init(void); void config_wscons_fini(void); #endif xorg-server-1.20.13/config/dbus-core.c0000644000175000017500000001517014100573755014371 00000000000000/* * Copyright © 2006-2007 Daniel Stone * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Daniel Stone */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include "dix.h" #include "os.h" #include "dbus-core.h" /* How often to attempt reconnecting when we get booted off the bus. */ #define RECONNECT_DELAY (10 * 1000) /* in ms */ struct dbus_core_info { int fd; DBusConnection *connection; OsTimerPtr timer; struct dbus_core_hook *hooks; }; static struct dbus_core_info bus_info = { .fd = -1 }; static CARD32 reconnect_timer(OsTimerPtr timer, CARD32 time, void *arg); static void socket_handler(int fd, int ready, void *data) { struct dbus_core_info *info = data; if (info->connection) { do { dbus_connection_read_write_dispatch(info->connection, 0); } while (info->connection && dbus_connection_get_is_connected(info->connection) && dbus_connection_get_dispatch_status(info->connection) == DBUS_DISPATCH_DATA_REMAINS); } } /** * Disconnect (if we haven't already been forcefully disconnected), clean up * after ourselves, and call all registered disconnect hooks. */ static void teardown(void) { struct dbus_core_hook *hook; if (bus_info.timer) { TimerFree(bus_info.timer); bus_info.timer = NULL; } /* We should really have pre-disconnect hooks and run them here, for * completeness. But then it gets awkward, given that you can't * guarantee that they'll be called ... */ if (bus_info.connection) dbus_connection_unref(bus_info.connection); if (bus_info.fd != -1) RemoveNotifyFd(bus_info.fd); bus_info.fd = -1; bus_info.connection = NULL; for (hook = bus_info.hooks; hook; hook = hook->next) { if (hook->disconnect) hook->disconnect(hook->data); } } /** * This is a filter, which only handles the disconnected signal, which * doesn't go to the normal message handling function. This takes * precedence over the message handling function, so have have to be * careful to ignore anything we don't want to deal with here. */ static DBusHandlerResult message_filter(DBusConnection * connection, DBusMessage * message, void *data) { /* If we get disconnected, then take everything down, and attempt to * reconnect immediately (assuming it's just a restart). The * connection isn't valid at this point, so throw it out immediately. */ if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { DebugF("[dbus-core] disconnected from bus\n"); bus_info.connection = NULL; teardown(); if (bus_info.timer) TimerFree(bus_info.timer); bus_info.timer = TimerSet(NULL, 0, 1, reconnect_timer, NULL); return DBUS_HANDLER_RESULT_HANDLED; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } /** * Attempt to connect to the system bus, and set a filter to deal with * disconnection (see message_filter above). * * @return 1 on success, 0 on failure. */ static int connect_to_bus(void) { DBusError error; struct dbus_core_hook *hook; dbus_error_init(&error); bus_info.connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); if (!bus_info.connection || dbus_error_is_set(&error)) { LogMessage(X_ERROR, "dbus-core: error connecting to system bus: %s (%s)\n", error.name, error.message); goto err_begin; } /* Thankyou. Really, thankyou. */ dbus_connection_set_exit_on_disconnect(bus_info.connection, FALSE); if (!dbus_connection_get_unix_fd(bus_info.connection, &bus_info.fd)) { ErrorF("[dbus-core] couldn't get fd for system bus\n"); goto err_unref; } if (!dbus_connection_add_filter(bus_info.connection, message_filter, &bus_info, NULL)) { ErrorF("[dbus-core] couldn't add filter: %s (%s)\n", error.name, error.message); goto err_fd; } dbus_error_free(&error); SetNotifyFd(bus_info.fd, socket_handler, X_NOTIFY_READ, &bus_info); for (hook = bus_info.hooks; hook; hook = hook->next) { if (hook->connect) hook->connect(bus_info.connection, hook->data); } return 1; err_fd: bus_info.fd = -1; err_unref: dbus_connection_unref(bus_info.connection); bus_info.connection = NULL; err_begin: dbus_error_free(&error); return 0; } static CARD32 reconnect_timer(OsTimerPtr timer, CARD32 time, void *arg) { if (connect_to_bus()) { TimerFree(bus_info.timer); bus_info.timer = NULL; return 0; } else { return RECONNECT_DELAY; } } int dbus_core_add_hook(struct dbus_core_hook *hook) { struct dbus_core_hook **prev; for (prev = &bus_info.hooks; *prev; prev = &(*prev)->next); hook->next = NULL; *prev = hook; /* If we're already connected, call the connect hook. */ if (bus_info.connection) hook->connect(bus_info.connection, hook->data); return 1; } void dbus_core_remove_hook(struct dbus_core_hook *hook) { struct dbus_core_hook **prev; for (prev = &bus_info.hooks; *prev; prev = &(*prev)->next) { if (*prev == hook) { *prev = hook->next; break; } } } int dbus_core_init(void) { memset(&bus_info, 0, sizeof(bus_info)); bus_info.fd = -1; bus_info.hooks = NULL; if (!connect_to_bus()) bus_info.timer = TimerSet(NULL, 0, 1, reconnect_timer, NULL); return 1; } void dbus_core_fini(void) { teardown(); } xorg-server-1.20.13/config/udev.c0000644000175000017500000004107014100573755013447 00000000000000/* * Copyright © 2009 Julien Cristau * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Julien Cristau */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include "input.h" #include "inputstr.h" #include "hotplug.h" #include "config-backends.h" #include "os.h" #include "globals.h" #include "systemd-logind.h" #define UDEV_XKB_PROP_KEY "xkb" #define LOG_PROPERTY(path, prop, val) \ LogMessageVerb(X_INFO, 10, \ "config/udev: getting property %s on %s " \ "returned \"%s\"\n", \ (prop), (path), (val) ? (val) : "(null)") #define LOG_SYSATTR(path, attr, val) \ LogMessageVerb(X_INFO, 10, \ "config/udev: getting attribute %s on %s " \ "returned \"%s\"\n", \ (attr), (path), (val) ? (val) : "(null)") static struct udev_monitor *udev_monitor; #ifdef CONFIG_UDEV_KMS static void config_udev_odev_setup_attribs(const char *path, const char *syspath, int major, int minor, config_odev_probe_proc_ptr probe_callback); #endif static char itoa_buf[16]; static const char *itoa(int i) { snprintf(itoa_buf, sizeof(itoa_buf), "%d", i); return itoa_buf; } static Bool check_seat(struct udev_device *udev_device) { const char *dev_seat; dev_seat = udev_device_get_property_value(udev_device, "ID_SEAT"); if (!dev_seat) dev_seat = "seat0"; if (SeatId && strcmp(dev_seat, SeatId)) return FALSE; if (!SeatId && strcmp(dev_seat, "seat0")) return FALSE; return TRUE; } static void device_added(struct udev_device *udev_device) { const char *path, *name = NULL; char *config_info = NULL; const char *syspath; const char *tags_prop; const char *key, *value, *tmp; InputOption *input_options; InputAttributes attrs = { }; DeviceIntPtr dev = NULL; struct udev_list_entry *set, *entry; struct udev_device *parent; int rc; dev_t devnum; path = udev_device_get_devnode(udev_device); syspath = udev_device_get_syspath(udev_device); if (!path || !syspath) return; if (!check_seat(udev_device)) return; devnum = udev_device_get_devnum(udev_device); #ifdef CONFIG_UDEV_KMS if (!strcmp(udev_device_get_subsystem(udev_device), "drm")) { const char *sysname = udev_device_get_sysname(udev_device); if (strncmp(sysname, "card", 4) != 0) return; /* Check for devices already added through xf86platformProbe() */ if (xf86_find_platform_device_by_devnum(major(devnum), minor(devnum))) return; LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path); config_udev_odev_setup_attribs(path, syspath, major(devnum), minor(devnum), NewGPUDeviceRequest); return; } #endif value = udev_device_get_property_value(udev_device, "ID_INPUT"); if (!value || !strcmp(value, "0")) { LogMessageVerb(X_INFO, 10, "config/udev: ignoring device %s without " "property ID_INPUT set\n", path); return; } input_options = input_option_new(NULL, "_source", "server/udev"); if (!input_options) return; parent = udev_device_get_parent(udev_device); if (parent) { const char *ppath = udev_device_get_devnode(parent); const char *product = udev_device_get_property_value(parent, "PRODUCT"); const char *pnp_id = udev_device_get_sysattr_value(parent, "id"); unsigned int usb_vendor, usb_model; name = udev_device_get_sysattr_value(parent, "name"); LOG_SYSATTR(ppath, "name", name); if (!name) { name = udev_device_get_property_value(parent, "NAME"); LOG_PROPERTY(ppath, "NAME", name); } /* construct USB ID in lowercase hex - "0000:ffff" */ if (product && sscanf(product, "%*x/%4x/%4x/%*x", &usb_vendor, &usb_model) == 2) { char *usb_id; if (asprintf(&usb_id, "%04x:%04x", usb_vendor, usb_model) == -1) usb_id = NULL; else LOG_PROPERTY(ppath, "PRODUCT", product); attrs.usb_id = usb_id; } while (!pnp_id && (parent = udev_device_get_parent(parent))) { pnp_id = udev_device_get_sysattr_value(parent, "id"); if (!pnp_id) continue; attrs.pnp_id = strdup(pnp_id); ppath = udev_device_get_devnode(parent); LOG_SYSATTR(ppath, "id", pnp_id); } } if (!name) name = "(unnamed)"; else attrs.product = strdup(name); input_options = input_option_new(input_options, "name", name); input_options = input_option_new(input_options, "path", path); input_options = input_option_new(input_options, "device", path); input_options = input_option_new(input_options, "major", itoa(major(devnum))); input_options = input_option_new(input_options, "minor", itoa(minor(devnum))); if (path) attrs.device = strdup(path); tags_prop = udev_device_get_property_value(udev_device, "ID_INPUT.tags"); LOG_PROPERTY(path, "ID_INPUT.tags", tags_prop); attrs.tags = xstrtokenize(tags_prop, ","); if (asprintf(&config_info, "udev:%s", syspath) == -1) { config_info = NULL; goto unwind; } if (device_is_duplicate(config_info)) { LogMessage(X_WARNING, "config/udev: device %s already added. " "Ignoring.\n", name); goto unwind; } set = udev_device_get_properties_list_entry(udev_device); udev_list_entry_foreach(entry, set) { key = udev_list_entry_get_name(entry); if (!key) continue; value = udev_list_entry_get_value(entry); if (!strncasecmp(key, UDEV_XKB_PROP_KEY, sizeof(UDEV_XKB_PROP_KEY) - 1)) { LOG_PROPERTY(path, key, value); tmp = key + sizeof(UDEV_XKB_PROP_KEY) - 1; if (!strcasecmp(tmp, "rules")) input_options = input_option_new(input_options, "xkb_rules", value); else if (!strcasecmp(tmp, "layout")) input_options = input_option_new(input_options, "xkb_layout", value); else if (!strcasecmp(tmp, "variant")) input_options = input_option_new(input_options, "xkb_variant", value); else if (!strcasecmp(tmp, "model")) input_options = input_option_new(input_options, "xkb_model", value); else if (!strcasecmp(tmp, "options")) input_options = input_option_new(input_options, "xkb_options", value); } else if (!strcmp(key, "ID_VENDOR")) { LOG_PROPERTY(path, key, value); attrs.vendor = strdup(value); } else if (!strncmp(key, "ID_INPUT_", 9)) { const struct pfmap { const char *property; unsigned int flag; } map[] = { { "ID_INPUT_KEY", ATTR_KEY }, { "ID_INPUT_KEYBOARD", ATTR_KEYBOARD }, { "ID_INPUT_MOUSE", ATTR_POINTER }, { "ID_INPUT_JOYSTICK", ATTR_JOYSTICK }, { "ID_INPUT_TABLET", ATTR_TABLET }, { "ID_INPUT_TABLET_PAD", ATTR_TABLET_PAD }, { "ID_INPUT_TOUCHPAD", ATTR_TOUCHPAD }, { "ID_INPUT_TOUCHSCREEN", ATTR_TOUCHSCREEN }, { NULL, 0 }, }; /* Anything but the literal string "0" is considered a * boolean true. The empty string isn't a thing with udev * properties anyway */ if (value && strcmp(value, "0")) { const struct pfmap *m = map; while (m->property != NULL) { if (!strcmp(m->property, key)) { LOG_PROPERTY(path, key, value); attrs.flags |= m->flag; } m++; } } } } input_options = input_option_new(input_options, "config_info", config_info); /* Default setting needed for non-seat0 seats */ if (ServerIsNotSeat0()) input_options = input_option_new(input_options, "GrabDevice", "on"); LogMessage(X_INFO, "config/udev: Adding input device %s (%s)\n", name, path); rc = NewInputDeviceRequest(input_options, &attrs, &dev); if (rc != Success) goto unwind; unwind: free(config_info); input_option_free_list(&input_options); free(attrs.usb_id); free(attrs.pnp_id); free(attrs.product); free(attrs.device); free(attrs.vendor); if (attrs.tags) { char **tag = attrs.tags; while (*tag) { free(*tag); tag++; } free(attrs.tags); } return; } static void device_removed(struct udev_device *device) { char *value; const char *syspath = udev_device_get_syspath(device); #ifdef CONFIG_UDEV_KMS if (!strcmp(udev_device_get_subsystem(device), "drm")) { const char *sysname = udev_device_get_sysname(device); const char *path = udev_device_get_devnode(device); dev_t devnum = udev_device_get_devnum(device); if ((strncmp(sysname,"card", 4) != 0) || (path == NULL)) return; LogMessage(X_INFO, "config/udev: removing GPU device %s %s\n", syspath, path); config_udev_odev_setup_attribs(path, syspath, major(devnum), minor(devnum), DeleteGPUDeviceRequest); /* Retry vtenter after a drm node removal */ systemd_logind_vtenter(); return; } #endif if (asprintf(&value, "udev:%s", syspath) == -1) return; remove_devices("udev", value); free(value); } static void socket_handler(int fd, int ready, void *data) { struct udev_device *udev_device; const char *action; input_lock(); udev_device = udev_monitor_receive_device(udev_monitor); if (!udev_device) { input_unlock(); return; } action = udev_device_get_action(udev_device); if (action) { if (!strcmp(action, "add")) { device_removed(udev_device); device_added(udev_device); } else if (!strcmp(action, "change")) { /* ignore change for the drm devices */ if (strcmp(udev_device_get_subsystem(udev_device), "drm")) { device_removed(udev_device); device_added(udev_device); } } else if (!strcmp(action, "remove")) device_removed(udev_device); } udev_device_unref(udev_device); input_unlock(); } int config_udev_pre_init(void) { struct udev *udev; udev = udev_new(); if (!udev) return 0; udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); if (!udev_monitor) return 0; udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input", NULL); /* For Wacom serial devices */ udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL); #ifdef CONFIG_UDEV_KMS /* For output GPU devices */ udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "drm", NULL); #endif #ifdef HAVE_UDEV_MONITOR_FILTER_ADD_MATCH_TAG if (ServerIsNotSeat0()) udev_monitor_filter_add_match_tag(udev_monitor, SeatId); #endif if (udev_monitor_enable_receiving(udev_monitor)) { ErrorF("config/udev: failed to bind the udev monitor\n"); return 0; } return 1; } int config_udev_init(void) { struct udev *udev; struct udev_enumerate *enumerate; struct udev_list_entry *devices, *device; udev = udev_monitor_get_udev(udev_monitor); enumerate = udev_enumerate_new(udev); if (!enumerate) return 0; udev_enumerate_add_match_subsystem(enumerate, "input"); udev_enumerate_add_match_subsystem(enumerate, "tty"); #ifdef CONFIG_UDEV_KMS udev_enumerate_add_match_subsystem(enumerate, "drm"); #endif #ifdef HAVE_UDEV_ENUMERATE_ADD_MATCH_TAG if (ServerIsNotSeat0()) udev_enumerate_add_match_tag(enumerate, SeatId); #endif udev_enumerate_scan_devices(enumerate); devices = udev_enumerate_get_list_entry(enumerate); udev_list_entry_foreach(device, devices) { const char *syspath = udev_list_entry_get_name(device); struct udev_device *udev_device = udev_device_new_from_syspath(udev, syspath); /* Device might be gone by the time we try to open it */ if (!udev_device) continue; device_added(udev_device); udev_device_unref(udev_device); } udev_enumerate_unref(enumerate); SetNotifyFd(udev_monitor_get_fd(udev_monitor), socket_handler, X_NOTIFY_READ, NULL); return 1; } void config_udev_fini(void) { struct udev *udev; if (!udev_monitor) return; udev = udev_monitor_get_udev(udev_monitor); RemoveNotifyFd(udev_monitor_get_fd(udev_monitor)); udev_monitor_unref(udev_monitor); udev_monitor = NULL; udev_unref(udev); } #ifdef CONFIG_UDEV_KMS static void config_udev_odev_setup_attribs(const char *path, const char *syspath, int major, int minor, config_odev_probe_proc_ptr probe_callback) { struct OdevAttributes *attribs = config_odev_allocate_attributes(); attribs->path = XNFstrdup(path); attribs->syspath = XNFstrdup(syspath); attribs->major = major; attribs->minor = minor; /* ownership of attribs is passed to probe layer */ probe_callback(attribs); } void config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback) { struct udev *udev; struct udev_enumerate *enumerate; struct udev_list_entry *devices, *device; udev = udev_monitor_get_udev(udev_monitor); enumerate = udev_enumerate_new(udev); if (!enumerate) return; udev_enumerate_add_match_subsystem(enumerate, "drm"); udev_enumerate_add_match_sysname(enumerate, "card[0-9]*"); #ifdef HAVE_UDEV_ENUMERATE_ADD_MATCH_TAG if (ServerIsNotSeat0()) udev_enumerate_add_match_tag(enumerate, SeatId); #endif udev_enumerate_scan_devices(enumerate); devices = udev_enumerate_get_list_entry(enumerate); udev_list_entry_foreach(device, devices) { const char *syspath = udev_list_entry_get_name(device); struct udev_device *udev_device = udev_device_new_from_syspath(udev, syspath); const char *path = udev_device_get_devnode(udev_device); const char *sysname = udev_device_get_sysname(udev_device); dev_t devnum = udev_device_get_devnum(udev_device); if (!path || !syspath) goto no_probe; else if (strcmp(udev_device_get_subsystem(udev_device), "drm") != 0) goto no_probe; else if (strncmp(sysname, "card", 4) != 0) goto no_probe; else if (!check_seat(udev_device)) goto no_probe; config_udev_odev_setup_attribs(path, syspath, major(devnum), minor(devnum), probe_callback); no_probe: udev_device_unref(udev_device); } udev_enumerate_unref(enumerate); return; } #endif xorg-server-1.20.13/config/hal.c0000644000175000017500000005406314100573755013256 00000000000000/* * Copyright © 2007 Daniel Stone * Copyright © 2007 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Daniel Stone */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include "dbus-core.h" #include "input.h" #include "inputstr.h" #include "hotplug.h" #include "config-backends.h" #include "os.h" #define LIBHAL_PROP_KEY "input.x11_options." #define LIBHAL_XKB_PROP_KEY "input.xkb." struct config_hal_info { DBusConnection *system_bus; LibHalContext *hal_ctx; }; /* Used for special handling of xkb options. */ struct xkb_options { char *layout; char *model; char *rules; char *variant; char *options; }; static void device_removed(LibHalContext * ctx, const char *udi) { char *value; if (asprintf(&value, "hal:%s", udi) == -1) return; remove_devices("hal", value); free(value); } static char * get_prop_string(LibHalContext * hal_ctx, const char *udi, const char *name) { char *prop, *ret; prop = libhal_device_get_property_string(hal_ctx, udi, name, NULL); LogMessageVerb(X_INFO, 10, "config/hal: getting %s on %s returned %s\n", name, udi, prop ? prop : "(null)"); if (prop) { ret = strdup(prop); libhal_free_string(prop); } else { return NULL; } return ret; } static char * get_prop_string_array(LibHalContext * hal_ctx, const char *udi, const char *prop) { char **props, *ret, *str; int i, len = 0; props = libhal_device_get_property_strlist(hal_ctx, udi, prop, NULL); if (props) { for (i = 0; props[i]; i++) len += strlen(props[i]); ret = calloc(sizeof(char), len + i); /* i - 1 commas, 1 NULL */ if (!ret) { libhal_free_string_array(props); return NULL; } str = ret; for (i = 0; props[i]; i++) { strcpy(str, props[i]); str += strlen(props[i]); *str++ = ','; } *(str - 1) = '\0'; libhal_free_string_array(props); } else { return NULL; } return ret; } static void device_added(LibHalContext * hal_ctx, const char *udi) { char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL; char *hal_tags, *parent; InputOption *input_options = NULL; InputAttributes attrs = { 0 }; DeviceIntPtr dev = NULL; DBusError error; struct xkb_options xkb_opts = { 0 }; int rc; LibHalPropertySet *set = NULL; LibHalPropertySetIterator set_iter; char *psi_key = NULL, *tmp_val; dbus_error_init(&error); driver = get_prop_string(hal_ctx, udi, "input.x11_driver"); if (!driver) { /* verbose, don't tell the user unless they _want_ to see it */ LogMessageVerb(X_INFO, 7, "config/hal: no driver specified for device %s\n", udi); goto unwind; } path = get_prop_string(hal_ctx, udi, "input.device"); if (!path) { LogMessage(X_WARNING, "config/hal: no driver or path specified for %s\n", udi); goto unwind; } attrs.device = strdup(path); name = get_prop_string(hal_ctx, udi, "info.product"); if (!name) name = strdup("(unnamed)"); else attrs.product = strdup(name); attrs.vendor = get_prop_string(hal_ctx, udi, "info.vendor"); hal_tags = get_prop_string(hal_ctx, udi, "input.tags"); attrs.tags = xstrtokenize(hal_tags, ","); free(hal_tags); if (libhal_device_query_capability(hal_ctx, udi, "input.keys", NULL)) attrs.flags |= ATTR_KEY | ATTR_KEYBOARD; if (libhal_device_query_capability(hal_ctx, udi, "input.mouse", NULL)) attrs.flags |= ATTR_POINTER; if (libhal_device_query_capability(hal_ctx, udi, "input.joystick", NULL)) attrs.flags |= ATTR_JOYSTICK; if (libhal_device_query_capability(hal_ctx, udi, "input.tablet", NULL)) attrs.flags |= ATTR_TABLET; if (libhal_device_query_capability(hal_ctx, udi, "input.tablet_pad", NULL)) attrs.flags |= ATTR_TABLET_PAD; if (libhal_device_query_capability(hal_ctx, udi, "input.touchpad", NULL)) attrs.flags |= ATTR_TOUCHPAD; if (libhal_device_query_capability(hal_ctx, udi, "input.touchscreen", NULL)) attrs.flags |= ATTR_TOUCHSCREEN; parent = get_prop_string(hal_ctx, udi, "info.parent"); if (parent) { int usb_vendor, usb_product; char *old_parent; /* construct USB ID in lowercase - "0000:ffff" */ usb_vendor = libhal_device_get_property_int(hal_ctx, parent, "usb.vendor_id", NULL); LogMessageVerb(X_INFO, 10, "config/hal: getting usb.vendor_id on %s " "returned %04x\n", parent, usb_vendor); usb_product = libhal_device_get_property_int(hal_ctx, parent, "usb.product_id", NULL); LogMessageVerb(X_INFO, 10, "config/hal: getting usb.product_id on %s " "returned %04x\n", parent, usb_product); if (usb_vendor && usb_product) if (asprintf(&attrs.usb_id, "%04x:%04x", usb_vendor, usb_product) == -1) attrs.usb_id = NULL; attrs.pnp_id = get_prop_string(hal_ctx, parent, "pnp.id"); old_parent = parent; while (!attrs.pnp_id && (parent = get_prop_string(hal_ctx, parent, "info.parent"))) { attrs.pnp_id = get_prop_string(hal_ctx, parent, "pnp.id"); free(old_parent); old_parent = parent; } free(old_parent); } input_options = input_option_new(NULL, "_source", "server/hal"); if (!input_options) { LogMessage(X_ERROR, "config/hal: couldn't allocate first key/value pair\n"); goto unwind; } /* most drivers use device.. not path. evdev uses both however, but the * path version isn't documented apparently. support both for now. */ input_options = input_option_new(input_options, "path", path); input_options = input_option_new(input_options, "device", path); input_options = input_option_new(input_options, "driver", driver); input_options = input_option_new(input_options, "name", name); if (asprintf(&config_info, "hal:%s", udi) == -1) { config_info = NULL; LogMessage(X_ERROR, "config/hal: couldn't allocate name\n"); goto unwind; } /* Check for duplicate devices */ if (device_is_duplicate(config_info)) { LogMessage(X_WARNING, "config/hal: device %s already added. Ignoring.\n", name); goto unwind; } /* ok, grab options from hal.. iterate through all properties * and lets see if any of them are options that we can add */ set = libhal_device_get_all_properties(hal_ctx, udi, &error); if (!set) { LogMessage(X_ERROR, "config/hal: couldn't get property list for %s: %s (%s)\n", udi, error.name, error.message); goto unwind; } libhal_psi_init(&set_iter, set); while (libhal_psi_has_more(&set_iter)) { /* we are looking for supported keys.. extract and add to options */ psi_key = libhal_psi_get_key(&set_iter); if (psi_key) { /* normal options first (input.x11_options.) */ if (!strncasecmp (psi_key, LIBHAL_PROP_KEY, sizeof(LIBHAL_PROP_KEY) - 1)) { char *tmp; /* only support strings for all values */ tmp_val = get_prop_string(hal_ctx, udi, psi_key); if (tmp_val) { /* xkb needs special handling. HAL specs include * input.xkb.xyz options, but the x11-input.fdi specifies * input.x11_options.Xkbxyz options. By default, we use * the former, unless the specific X11 ones are specified. * Since we can't predict the order in which the keys * arrive, we need to store them. */ if ((tmp = strcasestr(psi_key, "xkb")) && strlen(tmp) >= 4) { if (!strcasecmp(&tmp[3], "layout")) { free(xkb_opts.layout); xkb_opts.layout = strdup(tmp_val); } else if (!strcasecmp(&tmp[3], "model")) { free(xkb_opts.model); xkb_opts.model = strdup(tmp_val); } else if (!strcasecmp(&tmp[3], "rules")) { free(xkb_opts.rules); xkb_opts.rules = strdup(tmp_val); } else if (!strcasecmp(&tmp[3], "variant")) { free(xkb_opts.variant); xkb_opts.variant = strdup(tmp_val); } else if (!strcasecmp(&tmp[3], "options")) { free(xkb_opts.options); xkb_opts.options = strdup(tmp_val); } } else { /* all others */ input_options = input_option_new(input_options, psi_key + sizeof(LIBHAL_PROP_KEY) - 1, tmp_val); free(tmp_val); } } else { /* server 1.4 had xkb_options as strlist. */ if ((tmp = strcasestr(psi_key, "xkb")) && (strlen(tmp) >= 4) && (!strcasecmp(&tmp[3], "options")) && (tmp_val = get_prop_string_array(hal_ctx, udi, psi_key))) { free(xkb_opts.options); xkb_opts.options = strdup(tmp_val); } } } else if (!strncasecmp (psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY) - 1)) { char *tmp; /* only support strings for all values */ tmp_val = get_prop_string(hal_ctx, udi, psi_key); if (tmp_val && strlen(psi_key) >= sizeof(LIBHAL_XKB_PROP_KEY)) { tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1]; if (!strcasecmp(tmp, "layout")) { if (!xkb_opts.layout) xkb_opts.layout = strdup(tmp_val); } else if (!strcasecmp(tmp, "rules")) { if (!xkb_opts.rules) xkb_opts.rules = strdup(tmp_val); } else if (!strcasecmp(tmp, "variant")) { if (!xkb_opts.variant) xkb_opts.variant = strdup(tmp_val); } else if (!strcasecmp(tmp, "model")) { if (!xkb_opts.model) xkb_opts.model = strdup(tmp_val); } else if (!strcasecmp(tmp, "options")) { if (!xkb_opts.options) xkb_opts.options = strdup(tmp_val); } free(tmp_val); } else { /* server 1.4 had xkb options as strlist */ tmp_val = get_prop_string_array(hal_ctx, udi, psi_key); if (tmp_val && strlen(psi_key) >= sizeof(LIBHAL_XKB_PROP_KEY)) { tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1]; if (!strcasecmp(tmp, ".options") && (!xkb_opts.options)) xkb_opts.options = strdup(tmp_val); } free(tmp_val); } } } /* psi_key doesn't need to be freed */ libhal_psi_next(&set_iter); } /* Now add xkb options */ if (xkb_opts.layout) input_options = input_option_new(input_options, "xkb_layout", xkb_opts.layout); if (xkb_opts.rules) input_options = input_option_new(input_options, "xkb_rules", xkb_opts.rules); if (xkb_opts.variant) input_options = input_option_new(input_options, "xkb_variant", xkb_opts.variant); if (xkb_opts.model) input_options = input_option_new(input_options, "xkb_model", xkb_opts.model); if (xkb_opts.options) input_options = input_option_new(input_options, "xkb_options", xkb_opts.options); input_options = input_option_new(input_options, "config_info", config_info); /* this isn't an error, but how else do you output something that the user can see? */ LogMessage(X_INFO, "config/hal: Adding input device %s\n", name); if ((rc = NewInputDeviceRequest(input_options, &attrs, &dev)) != Success) { LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed (%d)\n", rc); dev = NULL; goto unwind; } unwind: if (set) libhal_free_property_set(set); free(path); free(driver); free(name); free(config_info); input_option_free_list(&input_options); free(attrs.product); free(attrs.vendor); free(attrs.device); free(attrs.pnp_id); free(attrs.usb_id); if (attrs.tags) { char **tag = attrs.tags; while (*tag) { free(*tag); tag++; } free(attrs.tags); } free(xkb_opts.layout); free(xkb_opts.rules); free(xkb_opts.model); free(xkb_opts.variant); free(xkb_opts.options); dbus_error_free(&error); return; } static void disconnect_hook(void *data) { DBusError error; struct config_hal_info *info = data; if (info->hal_ctx) { if (dbus_connection_get_is_connected(info->system_bus)) { dbus_error_init(&error); if (!libhal_ctx_shutdown(info->hal_ctx, &error)) LogMessage(X_WARNING, "config/hal: disconnect_hook couldn't shut down context: %s (%s)\n", error.name, error.message); dbus_error_free(&error); } libhal_ctx_free(info->hal_ctx); } info->hal_ctx = NULL; info->system_bus = NULL; } static BOOL connect_and_register(DBusConnection * connection, struct config_hal_info *info) { DBusError error; char **devices; int num_devices, i; if (info->hal_ctx) return TRUE; /* already registered, pretend we did something */ info->system_bus = connection; dbus_error_init(&error); info->hal_ctx = libhal_ctx_new(); if (!info->hal_ctx) { LogMessage(X_ERROR, "config/hal: couldn't create HAL context\n"); goto out_err; } if (!libhal_ctx_set_dbus_connection(info->hal_ctx, info->system_bus)) { LogMessage(X_ERROR, "config/hal: couldn't associate HAL context with bus\n"); goto out_err; } if (!libhal_ctx_init(info->hal_ctx, &error)) { LogMessage(X_ERROR, "config/hal: couldn't initialise context: %s (%s)\n", error.name ? error.name : "unknown error", error.message ? error.message : "null"); goto out_err; } if (!libhal_device_property_watch_all(info->hal_ctx, &error)) { LogMessage(X_ERROR, "config/hal: couldn't watch all properties: %s (%s)\n", error.name ? error.name : "unknown error", error.message ? error.message : "null"); goto out_ctx; } libhal_ctx_set_device_added(info->hal_ctx, device_added); libhal_ctx_set_device_removed(info->hal_ctx, device_removed); devices = libhal_find_device_by_capability(info->hal_ctx, "input", &num_devices, &error); /* FIXME: Get default devices if error is set. */ if (dbus_error_is_set(&error)) { LogMessage(X_ERROR, "config/hal: couldn't find input device: %s (%s)\n", error.name ? error.name : "unknown error", error.message ? error.message : "null"); goto out_ctx; } for (i = 0; i < num_devices; i++) device_added(info->hal_ctx, devices[i]); libhal_free_string_array(devices); dbus_error_free(&error); return TRUE; out_ctx: dbus_error_free(&error); if (!libhal_ctx_shutdown(info->hal_ctx, &error)) { LogMessage(X_WARNING, "config/hal: couldn't shut down context: %s (%s)\n", error.name ? error.name : "unknown error", error.message ? error.message : "null"); dbus_error_free(&error); } out_err: dbus_error_free(&error); if (info->hal_ctx) { libhal_ctx_free(info->hal_ctx); } info->hal_ctx = NULL; info->system_bus = NULL; return FALSE; } /** * Handle NewOwnerChanged signals to deal with HAL startup at X server runtime. * * NewOwnerChanged is send once when HAL shuts down, and once again when it * comes back up. Message has three arguments, first is the name * (org.freedesktop.Hal), the second one is the old owner, third one is new * owner. */ static DBusHandlerResult ownerchanged_handler(DBusConnection * connection, DBusMessage * message, void *data) { int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; if (dbus_message_is_signal(message, "org.freedesktop.DBus", "NameOwnerChanged")) { DBusError error; char *name, *old_owner, *new_owner; dbus_error_init(&error); dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old_owner, DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID); if (dbus_error_is_set(&error)) { ErrorF ("[config/hal] failed to get NameOwnerChanged args: %s (%s)\n", error.name, error.message); } else if (name && strcmp(name, "org.freedesktop.Hal") == 0) { if (!old_owner || !strlen(old_owner)) { DebugF("[config/hal] HAL startup detected.\n"); if (connect_and_register (connection, (struct config_hal_info *) data)) dbus_connection_unregister_object_path(connection, "/org/freedesktop/DBus"); else ErrorF("[config/hal] Failed to connect to HAL bus.\n"); } ret = DBUS_HANDLER_RESULT_HANDLED; } dbus_error_free(&error); } return ret; } /** * Register a handler for the NameOwnerChanged signal. */ static BOOL listen_for_startup(DBusConnection * connection, void *data) { DBusObjectPathVTable vtable = {.message_function = ownerchanged_handler, }; DBusError error; const char MATCH_RULE[] = "sender='org.freedesktop.DBus'," "interface='org.freedesktop.DBus'," "type='signal'," "path='/org/freedesktop/DBus'," "member='NameOwnerChanged'"; int rc = FALSE; dbus_error_init(&error); dbus_bus_add_match(connection, MATCH_RULE, &error); if (!dbus_error_is_set(&error)) { if (dbus_connection_register_object_path(connection, "/org/freedesktop/DBus", &vtable, data)) rc = TRUE; else ErrorF("[config/hal] cannot register object path.\n"); } else { ErrorF("[config/hal] couldn't add match rule: %s (%s)\n", error.name, error.message); ErrorF("[config/hal] cannot detect a HAL startup.\n"); } dbus_error_free(&error); return rc; } static void connect_hook(DBusConnection * connection, void *data) { struct config_hal_info *info = data; if (listen_for_startup(connection, data) && connect_and_register(connection, info)) dbus_connection_unregister_object_path(connection, "/org/freedesktop/DBus"); return; } static struct config_hal_info hal_info; static struct dbus_core_hook hook = { .connect = connect_hook, .disconnect = disconnect_hook, .data = &hal_info, }; int config_hal_init(void) { memset(&hal_info, 0, sizeof(hal_info)); hal_info.system_bus = NULL; hal_info.hal_ctx = NULL; if (!dbus_core_add_hook(&hook)) { LogMessage(X_ERROR, "config/hal: failed to add D-Bus hook\n"); return 0; } /* verbose message */ LogMessageVerb(X_INFO, 7, "config/hal: initialized\n"); return 1; } void config_hal_fini(void) { dbus_core_remove_hook(&hook); } xorg-server-1.20.13/config/wscons.c0000644000175000017500000001762714100573755014033 00000000000000/* * Copyright (c) 2011 Matthieu Herrb * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include #include #include "input.h" #include "inputstr.h" #include "os.h" #include "config-backends.h" #define WSCONS_KBD_DEVICE "/dev/wskbd" #define WSCONS_MOUSE_PREFIX "/dev/wsmouse" #define KB_OVRENC \ { KB_UK, "gb" }, \ { KB_SV, "se" }, \ { KB_SG, "ch" }, \ { KB_SF, "ch" }, \ { KB_LA, "latam" }, \ { KB_CF, "ca" } struct nameint { int val; char *name; } kbdenc[] = { KB_OVRENC, KB_ENCTAB, {0} }; struct nameint kbdvar[] = { {KB_NODEAD | KB_SG, "de_nodeadkeys"}, {KB_NODEAD | KB_SF, "fr_nodeadkeys"}, {KB_SF, "fr"}, {KB_DVORAK | KB_CF, "fr-dvorak"}, {KB_DVORAK | KB_FR, "bepo"}, {KB_DVORAK, "dvorak"}, {KB_CF, "fr-legacy"}, {KB_NODEAD, "nodeadkeys"}, {0} }; struct nameint kbdopt[] = { {KB_SWAPCTRLCAPS, "ctrl:swapcaps"}, {0} }; struct nameint kbdmodel[] = { {WSKBD_TYPE_ZAURUS, "zaurus"}, {0} }; static void wscons_add_keyboard(void) { InputAttributes attrs = { }; DeviceIntPtr dev = NULL; InputOption *input_options = NULL; char *config_info = NULL; int fd, i, rc; unsigned int type; kbd_t wsenc = 0; /* Find keyboard configuration */ fd = open(WSCONS_KBD_DEVICE, O_RDWR | O_NONBLOCK | O_EXCL); if (fd == -1) { LogMessage(X_ERROR, "wskbd: open %s: %s\n", WSCONS_KBD_DEVICE, strerror(errno)); return; } if (ioctl(fd, WSKBDIO_GETENCODING, &wsenc) == -1) { LogMessage(X_WARNING, "wskbd: ioctl(WSKBDIO_GETENCODING) " "failed: %s\n", strerror(errno)); close(fd); return; } if (ioctl(fd, WSKBDIO_GTYPE, &type) == -1) { LogMessage(X_WARNING, "wskbd: ioctl(WSKBDIO_GTYPE) " "failed: %s\n", strerror(errno)); close(fd); return; } close(fd); input_options = input_option_new(input_options, "_source", "server/wscons"); if (input_options == NULL) return; LogMessage(X_INFO, "config/wscons: checking input device %s\n", WSCONS_KBD_DEVICE); input_options = input_option_new(input_options, "name", WSCONS_KBD_DEVICE); input_options = input_option_new(input_options, "driver", "kbd"); config_info = Xprintf("wscons:%s", WSCONS_KBD_DEVICE); if (!config_info) goto unwind; if (KB_ENCODING(wsenc) == KB_USER) { /* Ignore wscons "user" layout */ LogMessageVerb(X_INFO, 3, "wskbd: ignoring \"user\" layout\n"); goto kbd_config_done; } for (i = 0; kbdenc[i].val; i++) if (KB_ENCODING(wsenc) == kbdenc[i].val) { LogMessageVerb(X_INFO, 3, "wskbd: using layout %s\n", kbdenc[i].name); input_options = input_option_new(input_options, "xkb_layout", kbdenc[i].name); break; } for (i = 0; kbdvar[i].val; i++) if (wsenc == kbdvar[i].val || KB_VARIANT(wsenc) == kbdvar[i].val) { LogMessageVerb(X_INFO, 3, "wskbd: using variant %s\n", kbdvar[i].name); input_options = input_option_new(input_options, "xkb_variant", kbdvar[i].name); break; } for (i = 0; kbdopt[i].val; i++) if (KB_VARIANT(wsenc) == kbdopt[i].val) { LogMessageVerb(X_INFO, 3, "wskbd: using option %s\n", kbdopt[i].name); input_options = input_option_new(input_options, "xkb_options", kbdopt[i].name); break; } for (i = 0; kbdmodel[i].val; i++) if (type == kbdmodel[i].val) { LogMessageVerb(X_INFO, 3, "wskbd: using model %s\n", kbdmodel[i].name); input_options = input_option_new(input_options, "xkb_model", kbdmodel[i].name); break; } kbd_config_done: attrs.flags |= ATTR_KEY | ATTR_KEYBOARD; rc = NewInputDeviceRequest(input_options, &attrs, &dev); if (rc != Success) goto unwind; for (; dev; dev = dev->next) { free(dev->config_info); dev->config_info = strdup(config_info); } unwind: input_option_free_list(&input_options); } static void wscons_add_pointer(const char *path, const char *driver, int flags) { InputAttributes attrs = { }; DeviceIntPtr dev = NULL; InputOption *input_options = NULL; char *config_info = NULL; int rc; config_info = Xprintf("wscons:%s", path); if (!config_info) return; input_options = input_option_new(input_options, "_source", "server/wscons"); if (input_options == NULL) return; input_options = input_option_new(input_options, "name", strdup(path)); input_options = input_option_new(input_options, "driver", strdup(driver)); input_options = input_option_new(input_options, "device", strdup(path)); LogMessage(X_INFO, "config/wscons: checking input device %s\n", path); attrs.flags |= flags; rc = NewInputDeviceRequest(input_options, &attrs, &dev); if (rc != Success) goto unwind; for (; dev; dev = dev->next) { free(dev->config_info); dev->config_info = strdup(config_info); } unwind: input_option_free_list(&input_options); } static void wscons_add_pointers(void) { char devname[256]; int fd, i, wsmouse_type; /* Check pointing devices */ for (i = 0; i < 4; i++) { snprintf(devname, sizeof(devname), "%s%d", WSCONS_MOUSE_PREFIX, i); LogMessageVerb(X_INFO, 10, "wsmouse: checking %s\n", devname); fd = open_device(devnamem O_RDWR | O_NONBLOCK | O_EXCL); if (fd == -1) { LogMessageVerb(X_WARNING, 10, "%s: %s\n", devname, strerror(errno)); continue; } if (ioctl(fd, WSMOUSEIO_GTYPE, &wsmouse_type) != 0) { LogMessageVerb(X_WARNING, 10, "%s: WSMOUSEIO_GTYPE failed\n", devname); close(fd); continue; } close(fd); switch (wsmouse_type) { case WSMOUSE_TYPE_SYNAPTICS: wscons_add_pointer(devname, "synaptics", ATTR_TOUCHPAD); break; case WSMOUSE_TYPE_TPANEL: wscons_add_pointer(devname, "ws", ATTR_TOUCHSCREEN); break; default: break; } } /* Add a default entry catching all other mux elements as "mouse" */ wscons_add_pointer(WSCONS_MOUSE_PREFIX, "mouse", ATTR_POINTER); } int config_wscons_init(void) { wscons_add_keyboard(); wscons_add_pointers(); return 1; } void config_wscons_fini(void) { /* Not much to do ? */ } xorg-server-1.20.13/config/x11-input.fdi0000644000175000017500000000712014100573755014570 00000000000000 mouse evdev usbms VUID base kbd pc105 evdev evdev usbkbm VUID us xorg-server-1.20.13/config/fdi2iclass.py0000755000175000017500000001550514100573755014744 00000000000000#!/usr/bin/python # # Convert xorg keys from hal FDIs files to xorg.conf InputClass sections. # Modified from Martin Pitt's original fdi2mpi.py script: # http://cgit.freedesktop.org/media-player-info/tree/tools/fdi2mpi.py # # (C) 2010 Dan Nicholson # (C) 2009 Canonical Ltd. # Author: Dan Nicholson # Author: Martin Pitt # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # fur- nished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FIT- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- # NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import sys, xml.dom.minidom # dict converting tags to Match* entries match_table = { 'info.product': 'MatchProduct', 'input.product': 'MatchProduct', 'info.vendor': 'MatchVendor', 'input.vendor': 'MatchVendor', 'info.device': 'MatchDevicePath', 'linux.device_file': 'MatchDevicePath', '/org/freedesktop/Hal/devices/computer:system.kernel.name': 'MatchOS', '@info.parent:pnp.id': 'MatchPnPID', } # dict converting info.capabilities list to Match* entries cap_match_table = { 'input.keys': 'MatchIsKeyboard', 'input.keyboard': 'MatchIsKeyboard', 'input.keypad': 'MatchIsKeyboard', 'input.mouse': 'MatchIsPointer', 'input.joystick': 'MatchIsJoystick', 'input.tablet': 'MatchIsTablet', 'input.touchpad': 'MatchIsTouchpad', 'input.touchscreen': 'MatchIsTouchscreen', } def device_glob(path): '''Convert a contains device path to a glob entry''' if path[0] != '/': path = '*' + path return path + '*' def parse_match(node): '''Parse a tag to a tuple with InputClass values''' match = None value = None booltype = False # see what type of key we have if node.attributes.has_key('key'): key = node.attributes['key'].nodeValue if key in match_table: match = match_table[key] elif key == 'info.capabilities': booltype = True # bail out now if it's unrecognized if not match and not booltype: return (match, value) if node.attributes.has_key('string'): value = node.attributes['string'].nodeValue elif node.attributes.has_key('contains'): value = node.attributes['contains'].nodeValue if match == 'MatchDevicePath': value = device_glob(value) elif booltype and value in cap_match_table: match = cap_match_table[value] value = 'yes' elif node.attributes.has_key('string_outof'): value = node.attributes['string_outof'].nodeValue.replace(';','|') elif node.attributes.has_key('contains_outof'): all_values = node.attributes['contains_outof'].nodeValue.split(';') for v in all_values: if match == 'MatchDevicePath': v = device_glob(v) elif match == 'MatchPnPID' and len(v) < 7: v += '*' if value: value += '|' + v else: value = v return (match, value) def parse_options(node): '''Parse the x11_* options and return InputClass entries''' driver = '' ignore = False options = [] for n in node.childNodes: if n.nodeType != xml.dom.minidom.Node.ELEMENT_NODE: continue tag = n.tagName key = n.attributes['key'].nodeValue value = '' if n.hasChildNodes(): content_node = n.childNodes[0] assert content_node.nodeType == xml.dom.Node.TEXT_NODE value = content_node.nodeValue if tag == 'match': continue assert tag in ('addset', 'merge', 'append', 'remove') if tag == 'remove' and key == 'input.x11_driver': ignore = True elif key == 'input.x11_driver': driver = value elif key.startswith('input.x11_options.'): option = key.split('.', 2)[2] options.append((option, value)) return (driver, ignore, options) def is_match_node(node): '''Check if a node is a element''' return node.nodeType == xml.dom.minidom.Node.ELEMENT_NODE and \ node.tagName == 'match' def parse_all_matches(node): '''Parse a x11 match tag and any parents that don't supply their own options''' matches = [] while True: (key, value) = parse_match(node) if key and value: matches.append((key, value)) # walk up to a parent match node node = node.parentNode if node == None or not is_match_node(node): break # leave if there other options at this level children = set([n.tagName for n in node.childNodes if n.nodeType == xml.dom.minidom.Node.ELEMENT_NODE]) if children & set(['addset', 'merge', 'append']): break return matches # stupid counter to give "unique" rule names num_sections = 1 def print_section(matches, driver, ignore, options): '''Print a valid InputClass section to stdout''' global num_sections print 'Section "InputClass"' print '\tIdentifier "Converted Class %d"' % num_sections num_sections += 1 for m, v in matches: print '\t%s "%s"' % (m, v) if driver: print '\tDriver "%s"' % driver if ignore: print '\tOption "Ignore" "yes"' for o, v in options: print '\tOption "%s" "%s"' % (o, v) print 'EndSection' def parse_fdi(fdi): '''Parse x11 matches from fdi''' # find all leaf nodes num = 0 for match_node in fdi.getElementsByTagName('match'): children = set([n.tagName for n in match_node.childNodes if n.nodeType == xml.dom.minidom.Node.ELEMENT_NODE]) # see if there are any options at this level (driver, ignore, options) = parse_options(match_node) if not driver and not ignore and not options: continue matches = parse_all_matches(match_node) if num > 0: print print_section(matches, driver, ignore, options) num += 1 for f in sys.argv[1:]: parse_fdi(xml.dom.minidom.parse(f)) xorg-server-1.20.13/config/10-quirks.conf0000644000175000017500000000250614100573755014744 00000000000000# Collection of quirks and blacklist/whitelists for specific devices. # Accelerometer device, posts data through ABS_X/ABS_Y, making X unusable # http://bugs.freedesktop.org/show_bug.cgi?id=22442 Section "InputClass" Identifier "ThinkPad HDAPS accelerometer blacklist" MatchProduct "ThinkPad HDAPS accelerometer data" Option "Ignore" "on" EndSection # https://bugzilla.redhat.com/show_bug.cgi?id=523914 # Mouse does not move in PV Xen guest # Explicitly tell evdev to not ignore the absolute axes. Section "InputClass" Identifier "Xen Virtual Pointer axis blacklist" MatchProduct "Xen Virtual Pointer" Option "IgnoreAbsoluteAxes" "off" Option "IgnoreRelativeAxes" "off" EndSection # https://bugs.freedesktop.org/show_bug.cgi?id=55867 # Bug 55867 - Doesn't know how to tag XI_TRACKBALL Section "InputClass" Identifier "Tag trackballs as XI_TRACKBALL" MatchProduct "trackball" MatchDriver "evdev" Option "TypeName" "TRACKBALL" EndSection # https://bugs.freedesktop.org/show_bug.cgi?id=62831 # Bug 62831 - Mionix Naos 5000 mouse detected incorrectly Section "InputClass" Identifier "Tag Mionix Naos 5000 mouse XI_MOUSE" MatchProduct "La-VIEW Technology Naos 5000 Mouse" MatchDriver "evdev" Option "TypeName" "MOUSE" EndSection xorg-server-1.20.13/damageext/0000755000175000017500000000000014100574020013072 500000000000000xorg-server-1.20.13/damageext/meson.build0000644000175000017500000000025514100573755015174 00000000000000srcs_damageext = [ 'damageext.c', ] libxserver_damageext = static_library('libxserver_damageext', srcs_damageext, include_directories: inc, dependencies: common_dep, ) xorg-server-1.20.13/damageext/Makefile.am0000644000175000017500000000017614100573755015070 00000000000000noinst_LTLIBRARIES = libdamageext.la AM_CFLAGS = $(DIX_CFLAGS) libdamageext_la_SOURCES = \ damageext.c \ damageextint.h xorg-server-1.20.13/damageext/Makefile.in0000644000175000017500000006347314100573775015114 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = damageext ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libdamageext_la_LIBADD = am_libdamageext_la_OBJECTS = damageext.lo libdamageext_la_OBJECTS = $(am_libdamageext_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/damageext.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libdamageext_la_SOURCES) DIST_SOURCES = $(libdamageext_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libdamageext.la AM_CFLAGS = $(DIX_CFLAGS) libdamageext_la_SOURCES = \ damageext.c \ damageextint.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign damageext/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign damageext/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libdamageext.la: $(libdamageext_la_OBJECTS) $(libdamageext_la_DEPENDENCIES) $(EXTRA_libdamageext_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libdamageext_la_OBJECTS) $(libdamageext_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/damageext.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: 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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/damageext.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/damageext.Plo -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: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: xorg-server-1.20.13/damageext/damageext.c0000644000175000017500000005131114100573755015134 00000000000000/* * Copyright © 2002 Keith Packard * Copyright 2013 Red Hat, 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 #endif #include "damageextint.h" #include "damagestr.h" #include "protocol-versions.h" #include "extinit.h" #ifdef PANORAMIX #include "panoramiX.h" #include "panoramiXsrv.h" typedef struct { DamageExtPtr ext; DamagePtr damage[MAXSCREENS]; } PanoramiXDamageRes; static RESTYPE XRT_DAMAGE; static int (*PanoramiXSaveDamageCreate) (ClientPtr); #endif static unsigned char DamageReqCode; static int DamageEventBase; static RESTYPE DamageExtType; static DevPrivateKeyRec DamageClientPrivateKeyRec; #define DamageClientPrivateKey (&DamageClientPrivateKeyRec) static void DamageNoteCritical(ClientPtr pClient) { DamageClientPtr pDamageClient = GetDamageClient(pClient); /* Composite extension marks clients with manual Subwindows as critical */ if (pDamageClient->critical > 0) { SetCriticalOutputPending(); pClient->smart_priority = SMART_MAX_PRIORITY; } } static void damageGetGeometry(DrawablePtr draw, int *x, int *y, int *w, int *h) { #ifdef PANORAMIX if (!noPanoramiXExtension && draw->type == DRAWABLE_WINDOW) { WindowPtr win = (WindowPtr)draw; if (!win->parent) { *x = screenInfo.x; *y = screenInfo.y; *w = screenInfo.width; *h = screenInfo.height; return; } } #endif *x = draw->x; *y = draw->y; *w = draw->width; *h = draw->height; } static void DamageExtNotify(DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes) { ClientPtr pClient = pDamageExt->pClient; DrawablePtr pDrawable = pDamageExt->pDrawable; xDamageNotifyEvent ev; int i, x, y, w, h; damageGetGeometry(pDrawable, &x, &y, &w, &h); UpdateCurrentTimeIf(); ev = (xDamageNotifyEvent) { .type = DamageEventBase + XDamageNotify, .level = pDamageExt->level, .drawable = pDamageExt->drawable, .damage = pDamageExt->id, .timestamp = currentTime.milliseconds, .geometry.x = x, .geometry.y = y, .geometry.width = w, .geometry.height = h }; if (pBoxes) { for (i = 0; i < nBoxes; i++) { ev.level = pDamageExt->level; if (i < nBoxes - 1) ev.level |= DamageNotifyMore; ev.area.x = pBoxes[i].x1; ev.area.y = pBoxes[i].y1; ev.area.width = pBoxes[i].x2 - pBoxes[i].x1; ev.area.height = pBoxes[i].y2 - pBoxes[i].y1; WriteEventsToClient(pClient, 1, (xEvent *) &ev); } } else { ev.area.x = 0; ev.area.y = 0; ev.area.width = w; ev.area.height = h; WriteEventsToClient(pClient, 1, (xEvent *) &ev); } DamageNoteCritical(pClient); } static void DamageExtReport(DamagePtr pDamage, RegionPtr pRegion, void *closure) { DamageExtPtr pDamageExt = closure; switch (pDamageExt->level) { case DamageReportRawRegion: case DamageReportDeltaRegion: DamageExtNotify(pDamageExt, RegionRects(pRegion), RegionNumRects(pRegion)); break; case DamageReportBoundingBox: DamageExtNotify(pDamageExt, RegionExtents(pRegion), 1); break; case DamageReportNonEmpty: DamageExtNotify(pDamageExt, NullBox, 0); break; case DamageReportNone: break; } } static void DamageExtDestroy(DamagePtr pDamage, void *closure) { DamageExtPtr pDamageExt = closure; pDamageExt->pDamage = 0; if (pDamageExt->id) FreeResource(pDamageExt->id, RT_NONE); } void DamageExtSetCritical(ClientPtr pClient, Bool critical) { DamageClientPtr pDamageClient = GetDamageClient(pClient); if (pDamageClient) pDamageClient->critical += critical ? 1 : -1; } static int ProcDamageQueryVersion(ClientPtr client) { DamageClientPtr pDamageClient = GetDamageClient(client); xDamageQueryVersionReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0 }; REQUEST(xDamageQueryVersionReq); REQUEST_SIZE_MATCH(xDamageQueryVersionReq); if (stuff->majorVersion < SERVER_DAMAGE_MAJOR_VERSION) { rep.majorVersion = stuff->majorVersion; rep.minorVersion = stuff->minorVersion; } else { rep.majorVersion = SERVER_DAMAGE_MAJOR_VERSION; if (stuff->majorVersion == SERVER_DAMAGE_MAJOR_VERSION && stuff->minorVersion < SERVER_DAMAGE_MINOR_VERSION) rep.minorVersion = stuff->minorVersion; else rep.minorVersion = SERVER_DAMAGE_MINOR_VERSION; } pDamageClient->major_version = rep.majorVersion; pDamageClient->minor_version = rep.minorVersion; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.majorVersion); swapl(&rep.minorVersion); } WriteToClient(client, sizeof(xDamageQueryVersionReply), &rep); return Success; } static void DamageExtRegister(DrawablePtr pDrawable, DamagePtr pDamage, Bool report) { DamageSetReportAfterOp(pDamage, TRUE); DamageRegister(pDrawable, pDamage); if (report) { RegionPtr pRegion = &((WindowPtr) pDrawable)->borderClip; RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y); DamageReportDamage(pDamage, pRegion); RegionTranslate(pRegion, pDrawable->x, pDrawable->y); } } static DamageExtPtr DamageExtCreate(DrawablePtr pDrawable, DamageReportLevel level, ClientPtr client, XID id, XID drawable) { DamageExtPtr pDamageExt = malloc(sizeof(DamageExtRec)); if (!pDamageExt) return NULL; pDamageExt->id = id; pDamageExt->drawable = drawable; pDamageExt->pDrawable = pDrawable; pDamageExt->level = level; pDamageExt->pClient = client; pDamageExt->pDamage = DamageCreate(DamageExtReport, DamageExtDestroy, level, FALSE, pDrawable->pScreen, pDamageExt); if (!pDamageExt->pDamage) { free(pDamageExt); return NULL; } if (!AddResource(id, DamageExtType, (void *) pDamageExt)) return NULL; DamageExtRegister(pDrawable, pDamageExt->pDamage, pDrawable->type == DRAWABLE_WINDOW); return pDamageExt; } static DamageExtPtr doDamageCreate(ClientPtr client, int *rc) { DrawablePtr pDrawable; DamageExtPtr pDamageExt; DamageReportLevel level; REQUEST(xDamageCreateReq); *rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, DixGetAttrAccess | DixReadAccess); if (*rc != Success) return NULL; switch (stuff->level) { case XDamageReportRawRectangles: level = DamageReportRawRegion; break; case XDamageReportDeltaRectangles: level = DamageReportDeltaRegion; break; case XDamageReportBoundingBox: level = DamageReportBoundingBox; break; case XDamageReportNonEmpty: level = DamageReportNonEmpty; break; default: client->errorValue = stuff->level; *rc = BadValue; return NULL; } pDamageExt = DamageExtCreate(pDrawable, level, client, stuff->damage, stuff->drawable); if (!pDamageExt) *rc = BadAlloc; return pDamageExt; } static int ProcDamageCreate(ClientPtr client) { int rc; REQUEST(xDamageCreateReq); REQUEST_SIZE_MATCH(xDamageCreateReq); LEGAL_NEW_RESOURCE(stuff->damage, client); doDamageCreate(client, &rc); return rc; } static int ProcDamageDestroy(ClientPtr client) { REQUEST(xDamageDestroyReq); DamageExtPtr pDamageExt; REQUEST_SIZE_MATCH(xDamageDestroyReq); VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); FreeResource(stuff->damage, RT_NONE); return Success; } #ifdef PANORAMIX static RegionPtr DamageExtSubtractWindowClip(DamageExtPtr pDamageExt) { WindowPtr win = (WindowPtr)pDamageExt->pDrawable; PanoramiXRes *res = NULL; RegionPtr ret; int i; if (!win->parent) return &PanoramiXScreenRegion; dixLookupResourceByType((void **)&res, win->drawable.id, XRT_WINDOW, serverClient, DixReadAccess); if (!res) return NULL; ret = RegionCreate(NULL, 0); if (!ret) return NULL; FOR_NSCREENS_FORWARD(i) { ScreenPtr screen; if (Success != dixLookupWindow(&win, res->info[i].id, serverClient, DixReadAccess)) goto out; screen = win->drawable.pScreen; RegionTranslate(ret, -screen->x, -screen->y); if (!RegionUnion(ret, ret, &win->borderClip)) goto out; RegionTranslate(ret, screen->x, screen->y); } return ret; out: RegionDestroy(ret); return NULL; } static void DamageExtFreeWindowClip(RegionPtr reg) { if (reg != &PanoramiXScreenRegion) RegionDestroy(reg); } #endif /* * DamageSubtract intersects with borderClip, so we must reconstruct the * protocol's perspective of same... */ static Bool DamageExtSubtract(DamageExtPtr pDamageExt, const RegionPtr pRegion) { DamagePtr pDamage = pDamageExt->pDamage; #ifdef PANORAMIX if (!noPanoramiXExtension) { RegionPtr damage = DamageRegion(pDamage); RegionSubtract(damage, damage, pRegion); if (pDamageExt->pDrawable->type == DRAWABLE_WINDOW) { DrawablePtr pDraw = pDamageExt->pDrawable; RegionPtr clip = DamageExtSubtractWindowClip(pDamageExt); if (clip) { RegionTranslate(clip, -pDraw->x, -pDraw->y); RegionIntersect(damage, damage, clip); RegionTranslate(clip, pDraw->x, pDraw->y); DamageExtFreeWindowClip(clip); } } return RegionNotEmpty(damage); } #endif return DamageSubtract(pDamage, pRegion); } static int ProcDamageSubtract(ClientPtr client) { REQUEST(xDamageSubtractReq); DamageExtPtr pDamageExt; RegionPtr pRepair; RegionPtr pParts; REQUEST_SIZE_MATCH(xDamageSubtractReq); VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, DixWriteAccess); VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, DixWriteAccess); if (pDamageExt->level != DamageReportRawRegion) { DamagePtr pDamage = pDamageExt->pDamage; if (pRepair) { if (pParts) RegionIntersect(pParts, DamageRegion(pDamage), pRepair); if (DamageExtSubtract(pDamageExt, pRepair)) DamageExtReport(pDamage, DamageRegion(pDamage), (void *) pDamageExt); } else { if (pParts) RegionCopy(pParts, DamageRegion(pDamage)); DamageEmpty(pDamage); } } return Success; } static int ProcDamageAdd(ClientPtr client) { REQUEST(xDamageAddReq); DrawablePtr pDrawable; RegionPtr pRegion; int rc; REQUEST_SIZE_MATCH(xDamageAddReq); VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, DixWriteAccess); if (rc != Success) return rc; /* The region is relative to the drawable origin, so translate it out to * screen coordinates like damage expects. */ RegionTranslate(pRegion, pDrawable->x, pDrawable->y); DamageDamageRegion(pDrawable, pRegion); RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y); return Success; } /* Major version controls available requests */ static const int version_requests[] = { X_DamageQueryVersion, /* before client sends QueryVersion */ X_DamageAdd, /* Version 1 */ }; static int (*ProcDamageVector[XDamageNumberRequests]) (ClientPtr) = { /*************** Version 1 ******************/ ProcDamageQueryVersion, ProcDamageCreate, ProcDamageDestroy, ProcDamageSubtract, /*************** Version 1.1 ****************/ ProcDamageAdd, }; static int ProcDamageDispatch(ClientPtr client) { REQUEST(xDamageReq); DamageClientPtr pDamageClient = GetDamageClient(client); if (pDamageClient->major_version >= ARRAY_SIZE(version_requests)) return BadRequest; if (stuff->damageReqType > version_requests[pDamageClient->major_version]) return BadRequest; return (*ProcDamageVector[stuff->damageReqType]) (client); } static int _X_COLD SProcDamageQueryVersion(ClientPtr client) { REQUEST(xDamageQueryVersionReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xDamageQueryVersionReq); swapl(&stuff->majorVersion); swapl(&stuff->minorVersion); return (*ProcDamageVector[stuff->damageReqType]) (client); } static int _X_COLD SProcDamageCreate(ClientPtr client) { REQUEST(xDamageCreateReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xDamageCreateReq); swapl(&stuff->damage); swapl(&stuff->drawable); return (*ProcDamageVector[stuff->damageReqType]) (client); } static int _X_COLD SProcDamageDestroy(ClientPtr client) { REQUEST(xDamageDestroyReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xDamageDestroyReq); swapl(&stuff->damage); return (*ProcDamageVector[stuff->damageReqType]) (client); } static int _X_COLD SProcDamageSubtract(ClientPtr client) { REQUEST(xDamageSubtractReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xDamageSubtractReq); swapl(&stuff->damage); swapl(&stuff->repair); swapl(&stuff->parts); return (*ProcDamageVector[stuff->damageReqType]) (client); } static int _X_COLD SProcDamageAdd(ClientPtr client) { REQUEST(xDamageAddReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xDamageSubtractReq); swapl(&stuff->drawable); swapl(&stuff->region); return (*ProcDamageVector[stuff->damageReqType]) (client); } static int (*SProcDamageVector[XDamageNumberRequests]) (ClientPtr) = { /*************** Version 1 ******************/ SProcDamageQueryVersion, SProcDamageCreate, SProcDamageDestroy, SProcDamageSubtract, /*************** Version 1.1 ****************/ SProcDamageAdd, }; static int _X_COLD SProcDamageDispatch(ClientPtr client) { REQUEST(xDamageReq); if (stuff->damageReqType >= XDamageNumberRequests) return BadRequest; return (*SProcDamageVector[stuff->damageReqType]) (client); } static int FreeDamageExt(void *value, XID did) { DamageExtPtr pDamageExt = (DamageExtPtr) value; /* * Get rid of the resource table entry hanging from the window id */ pDamageExt->id = 0; if (pDamageExt->pDamage) { DamageDestroy(pDamageExt->pDamage); } free(pDamageExt); return Success; } static void _X_COLD SDamageNotifyEvent(xDamageNotifyEvent * from, xDamageNotifyEvent * to) { to->type = from->type; cpswaps(from->sequenceNumber, to->sequenceNumber); cpswapl(from->drawable, to->drawable); cpswapl(from->damage, to->damage); cpswaps(from->area.x, to->area.x); cpswaps(from->area.y, to->area.y); cpswaps(from->area.width, to->area.width); cpswaps(from->area.height, to->area.height); cpswaps(from->geometry.x, to->geometry.x); cpswaps(from->geometry.y, to->geometry.y); cpswaps(from->geometry.width, to->geometry.width); cpswaps(from->geometry.height, to->geometry.height); } #ifdef PANORAMIX static void PanoramiXDamageReport(DamagePtr pDamage, RegionPtr pRegion, void *closure) { PanoramiXDamageRes *res = closure; DamageExtPtr pDamageExt = res->ext; WindowPtr pWin = (WindowPtr)pDamage->pDrawable; ScreenPtr pScreen = pDamage->pScreen; /* happens on unmap? sigh xinerama */ if (RegionNil(pRegion)) return; /* translate root windows if necessary */ if (!pWin->parent) RegionTranslate(pRegion, pScreen->x, pScreen->y); /* add our damage to the protocol view */ DamageReportDamage(pDamageExt->pDamage, pRegion); /* empty our view */ DamageEmpty(pDamage); } static void PanoramiXDamageExtDestroy(DamagePtr pDamage, void *closure) { PanoramiXDamageRes *damage = closure; damage->damage[pDamage->pScreen->myNum] = NULL; } static int PanoramiXDamageCreate(ClientPtr client) { PanoramiXDamageRes *damage; PanoramiXRes *draw; int i, rc; REQUEST(xDamageCreateReq); REQUEST_SIZE_MATCH(xDamageCreateReq); LEGAL_NEW_RESOURCE(stuff->damage, client); rc = dixLookupResourceByClass((void **)&draw, stuff->drawable, XRC_DRAWABLE, client, DixGetAttrAccess | DixReadAccess); if (rc != Success) return rc; if (!(damage = calloc(1, sizeof(PanoramiXDamageRes)))) return BadAlloc; if (!AddResource(stuff->damage, XRT_DAMAGE, damage)) return BadAlloc; damage->ext = doDamageCreate(client, &rc); if (rc == Success && draw->type == XRT_WINDOW) { FOR_NSCREENS_FORWARD(i) { DrawablePtr pDrawable; DamagePtr pDamage = DamageCreate(PanoramiXDamageReport, PanoramiXDamageExtDestroy, DamageReportRawRegion, FALSE, screenInfo.screens[i], damage); if (!pDamage) { rc = BadAlloc; } else { damage->damage[i] = pDamage; rc = dixLookupDrawable(&pDrawable, draw->info[i].id, client, M_WINDOW, DixGetAttrAccess | DixReadAccess); } if (rc != Success) break; DamageExtRegister(pDrawable, pDamage, i != 0); } } if (rc != Success) FreeResource(stuff->damage, RT_NONE); return rc; } static int PanoramiXDamageDelete(void *res, XID id) { int i; PanoramiXDamageRes *damage = res; FOR_NSCREENS_BACKWARD(i) { if (damage->damage[i]) { DamageDestroy(damage->damage[i]); damage->damage[i] = NULL; } } free(damage); return 1; } void PanoramiXDamageInit(void) { XRT_DAMAGE = CreateNewResourceType(PanoramiXDamageDelete, "XineramaDamage"); if (!XRT_DAMAGE) FatalError("Couldn't Xineramify Damage extension\n"); PanoramiXSaveDamageCreate = ProcDamageVector[X_DamageCreate]; ProcDamageVector[X_DamageCreate] = PanoramiXDamageCreate; } void PanoramiXDamageReset(void) { ProcDamageVector[X_DamageCreate] = PanoramiXSaveDamageCreate; } #endif /* PANORAMIX */ void DamageExtensionInit(void) { ExtensionEntry *extEntry; int s; for (s = 0; s < screenInfo.numScreens; s++) DamageSetup(screenInfo.screens[s]); DamageExtType = CreateNewResourceType(FreeDamageExt, "DamageExt"); if (!DamageExtType) return; if (!dixRegisterPrivateKey (&DamageClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(DamageClientRec))) return; if ((extEntry = AddExtension(DAMAGE_NAME, XDamageNumberEvents, XDamageNumberErrors, ProcDamageDispatch, SProcDamageDispatch, NULL, StandardMinorOpcode)) != 0) { DamageReqCode = (unsigned char) extEntry->base; DamageEventBase = extEntry->eventBase; EventSwapVector[DamageEventBase + XDamageNotify] = (EventSwapPtr) SDamageNotifyEvent; SetResourceTypeErrorValue(DamageExtType, extEntry->errorBase + BadDamage); #ifdef PANORAMIX if (XRT_DAMAGE) SetResourceTypeErrorValue(XRT_DAMAGE, extEntry->errorBase + BadDamage); #endif } } xorg-server-1.20.13/damageext/damageextint.h0000644000175000017500000000457014100573755015661 00000000000000/* * 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 #endif #ifndef _DAMAGEEXTINT_H_ #define _DAMAGEEXTINT_H_ #include #include #include "misc.h" #include "os.h" #include "dixstruct.h" #include "extnsionst.h" #include #include "windowstr.h" #include "selection.h" #include "scrnintstr.h" #include "damage.h" #include "xfixes.h" typedef struct _DamageClient { CARD32 major_version; CARD32 minor_version; int critical; } DamageClientRec, *DamageClientPtr; #define GetDamageClient(pClient) ((DamageClientPtr)dixLookupPrivate(&(pClient)->devPrivates, DamageClientPrivateKey)) typedef struct _DamageExt { DamagePtr pDamage; DrawablePtr pDrawable; DamageReportLevel level; ClientPtr pClient; XID id; XID drawable; } DamageExtRec, *DamageExtPtr; #define VERIFY_DAMAGEEXT(pDamageExt, rid, client, mode) { \ int rc = dixLookupResourceByType((void **)&(pDamageExt), rid, \ DamageExtType, client, mode); \ if (rc != Success) \ return rc; \ } void DamageExtSetCritical(ClientPtr pClient, Bool critical); void PanoramiXDamageInit(void); void PanoramiXDamageReset(void); #endif /* _DAMAGEEXTINT_H_ */ xorg-server-1.20.13/dbe/0000755000175000017500000000000014100574020011665 500000000000000xorg-server-1.20.13/dbe/meson.build0000644000175000017500000000035414100573755013767 00000000000000srcs_dbe = [ 'dbe.c', 'midbe.c', ] hdrs_dbe = [ 'dbestruct.h', ] libxserver_dbe = static_library('libxserver_dbe', srcs_dbe, include_directories: inc, dependencies: common_dep, ) install_data(hdrs_dbe, install_dir: xorgsdkdir) xorg-server-1.20.13/dbe/Makefile.am0000644000175000017500000000025414100573755013660 00000000000000noinst_LTLIBRARIES = libdbe.la AM_CFLAGS = $(DIX_CFLAGS) if XORG sdk_HEADERS = dbestruct.h endif libdbe_la_SOURCES = \ dbe.c \ midbe.c \ midbe.h xorg-server-1.20.13/dbe/dbestruct.h0000644000175000017500000001622014100573755013774 00000000000000/****************************************************************************** * * Copyright (c) 1994, 1995 Hewlett-Packard Company * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of the Hewlett-Packard * Company shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization from the Hewlett-Packard Company. * * Header file for DIX-related DBE * *****************************************************************************/ #ifndef DBE_STRUCT_H #define DBE_STRUCT_H /* INCLUDES */ #define NEED_DBE_PROTOCOL #include #include "windowstr.h" #include "privates.h" typedef struct { VisualID visual; /* one visual ID that supports double-buffering */ int depth; /* depth of visual in bits */ int perflevel; /* performance level of visual */ } XdbeVisualInfo; typedef struct { int count; /* number of items in visual_depth */ XdbeVisualInfo *visinfo; /* list of visuals & depths for scrn */ } XdbeScreenVisualInfo; /* DEFINES */ #define DBE_SCREEN_PRIV(pScreen) ((DbeScreenPrivPtr) \ dixLookupPrivate(&(pScreen)->devPrivates, dbeScreenPrivKey)) #define DBE_SCREEN_PRIV_FROM_DRAWABLE(pDrawable) \ DBE_SCREEN_PRIV((pDrawable)->pScreen) #define DBE_SCREEN_PRIV_FROM_WINDOW_PRIV(pDbeWindowPriv) \ DBE_SCREEN_PRIV((pDbeWindowPriv)->pWindow->drawable.pScreen) #define DBE_SCREEN_PRIV_FROM_WINDOW(pWindow) \ DBE_SCREEN_PRIV((pWindow)->drawable.pScreen) #define DBE_SCREEN_PRIV_FROM_PIXMAP(pPixmap) \ DBE_SCREEN_PRIV((pPixmap)->drawable.pScreen) #define DBE_SCREEN_PRIV_FROM_GC(pGC)\ DBE_SCREEN_PRIV((pGC)->pScreen) #define DBE_WINDOW_PRIV(pWin) ((DbeWindowPrivPtr) \ dixLookupPrivate(&(pWin)->devPrivates, dbeWindowPrivKey)) /* Initial size of the buffer ID array in the window priv. */ #define DBE_INIT_MAX_IDS 2 /* Reallocation increment for the buffer ID array. */ #define DBE_INCR_MAX_IDS 4 /* Marker for free elements in the buffer ID array. */ #define DBE_FREE_ID_ELEMENT 0 /* TYPEDEFS */ /* Record used to pass swap information between DIX and DDX swapping * procedures. */ typedef struct _DbeSwapInfoRec { WindowPtr pWindow; unsigned char swapAction; } DbeSwapInfoRec, *DbeSwapInfoPtr; /* ****************************************************************************** ** Per-window data ****************************************************************************** */ typedef struct _DbeWindowPrivRec { /* A pointer to the window with which the DBE window private (buffer) is * associated. */ WindowPtr pWindow; /* Last known swap action for this buffer. Legal values for this field * are XdbeUndefined, XdbeBackground, XdbeUntouched, and XdbeCopied. */ unsigned char swapAction; /* Last known buffer size. */ unsigned short width, height; /* Coordinates used for static gravity when the window is positioned. */ short x, y; /* Number of XIDs associated with this buffer. */ int nBufferIDs; /* Capacity of the current buffer ID array, IDs. */ int maxAvailableIDs; /* Pointer to the array of buffer IDs. This initially points to initIDs. * When the static limit of the initIDs array is reached, the array is * reallocated and this pointer is set to the new array instead of initIDs. */ XID *IDs; /* Initial array of buffer IDs. We are defining the XID array within the * window priv to optimize for data locality. In most cases, only one * buffer will be associated with a window. Having the array declared * here can prevent us from accessing the data in another memory page, * possibly resulting in a page swap and loss of performance. Initially we * will use this array to store buffer IDs. For situations where we have * more IDs than can fit in this static array, we will allocate a larger * array to use, possibly suffering a performance loss. */ XID initIDs[DBE_INIT_MAX_IDS]; /* Pointer to a drawable that contains the contents of the back buffer. */ PixmapPtr pBackBuffer; /* Pointer to a drawable that contains the contents of the front buffer. * This pointer is only used for the XdbeUntouched swap action. For that * swap action, we need to copy the front buffer (window) contents into * this drawable, copy the contents of current back buffer drawable (the * back buffer) into the window, swap the front and back drawable pointers, * and then swap the drawable/resource associations in the resource * database. */ PixmapPtr pFrontBuffer; /* Device-specific private information. */ PrivateRec *devPrivates; } DbeWindowPrivRec, *DbeWindowPrivPtr; /* ****************************************************************************** ** Per-screen data ****************************************************************************** */ typedef struct _DbeScreenPrivRec { /* Wrapped functions * It is the responsibilty of the DDX layer to wrap PositionWindow(). * DbeExtensionInit wraps DestroyWindow(). */ PositionWindowProcPtr PositionWindow; DestroyWindowProcPtr DestroyWindow; /* Per-screen DIX routines */ Bool (*SetupBackgroundPainter) (WindowPtr /*pWin */ , GCPtr /*pGC */ ); /* Per-screen DDX routines */ Bool (*GetVisualInfo) (ScreenPtr /*pScreen */ , XdbeScreenVisualInfo * /*pVisInfo */ ); int (*AllocBackBufferName) (WindowPtr /*pWin */ , XID /*bufId */ , int /*swapAction */ ); int (*SwapBuffers) (ClientPtr /*client */ , int * /*pNumWindows */ , DbeSwapInfoPtr /*swapInfo */ ); void (*WinPrivDelete) (DbeWindowPrivPtr /*pDbeWindowPriv */ , XID /*bufId */ ); } DbeScreenPrivRec, *DbeScreenPrivPtr; #endif /* DBE_STRUCT_H */ xorg-server-1.20.13/dbe/Makefile.in0000644000175000017500000007020014100573775013671 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = dbe ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__sdk_HEADERS_DIST) \ $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libdbe_la_LIBADD = am_libdbe_la_OBJECTS = dbe.lo midbe.lo libdbe_la_OBJECTS = $(am_libdbe_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dbe.Plo ./$(DEPDIR)/midbe.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libdbe_la_SOURCES) DIST_SOURCES = $(libdbe_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__sdk_HEADERS_DIST = dbestruct.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 = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(sdkdir)" HEADERS = $(sdk_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libdbe.la AM_CFLAGS = $(DIX_CFLAGS) @XORG_TRUE@sdk_HEADERS = dbestruct.h libdbe_la_SOURCES = \ dbe.c \ midbe.c \ midbe.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign dbe/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign dbe/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libdbe.la: $(libdbe_la_OBJECTS) $(libdbe_la_DEPENDENCIES) $(EXTRA_libdbe_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libdbe_la_OBJECTS) $(libdbe_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbe.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midbe.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-sdkHEADERS: $(sdk_HEADERS) @$(NORMAL_INSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sdkdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sdkdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(sdkdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(sdkdir)" || exit $$?; \ done uninstall-sdkHEADERS: @$(NORMAL_UNINSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(sdkdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dbe.Plo -rm -f ./$(DEPDIR)/midbe.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-sdkHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dbe.Plo -rm -f ./$(DEPDIR)/midbe.Plo -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 TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am 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 tags-am uninstall uninstall-am \ uninstall-sdkHEADERS .PRECIOUS: Makefile # 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: xorg-server-1.20.13/dbe/dbe.c0000644000175000017500000013304614100573755012530 00000000000000/****************************************************************************** * * Copyright (c) 1994, 1995 Hewlett-Packard Company * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of the Hewlett-Packard * Company shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization from the Hewlett-Packard Company. * * DIX DBE code * *****************************************************************************/ /* INCLUDES */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include "scrnintstr.h" #include "extnsionst.h" #include "extinit.h" #include "gcstruct.h" #include "dixstruct.h" #define NEED_DBE_PROTOCOL #include "dbestruct.h" #include "midbe.h" #include "xace.h" /* GLOBALS */ /* These are globals for use by DDX */ DevPrivateKeyRec dbeScreenPrivKeyRec; DevPrivateKeyRec dbeWindowPrivKeyRec; /* These are globals for use by DDX */ RESTYPE dbeDrawableResType; RESTYPE dbeWindowPrivResType; /* Used to generate DBE's BadBuffer error. */ static int dbeErrorBase; /****************************************************************************** * * DBE DIX Procedure: DbeStubScreen * * Description: * * This is function stubs the function pointers in the given DBE screen * private and increments the number of stubbed screens. * *****************************************************************************/ static void DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens) { /* Stub DIX. */ pDbeScreenPriv->SetupBackgroundPainter = NULL; /* Do not unwrap PositionWindow nor DestroyWindow. If the DDX * initialization function failed, we assume that it did not wrap * PositionWindow. Also, DestroyWindow is only wrapped if the DDX * initialization function succeeded. */ /* Stub DDX. */ pDbeScreenPriv->GetVisualInfo = NULL; pDbeScreenPriv->AllocBackBufferName = NULL; pDbeScreenPriv->SwapBuffers = NULL; pDbeScreenPriv->WinPrivDelete = NULL; (*nStubbedScreens)++; } /* DbeStubScreen() */ /****************************************************************************** * * DBE DIX Procedure: ProcDbeGetVersion * * Description: * * This function is for processing a DbeGetVersion request. * This request returns the major and minor version numbers of this * extension. * * Return Values: * * Success * *****************************************************************************/ static int ProcDbeGetVersion(ClientPtr client) { /* REQUEST(xDbeGetVersionReq); */ xDbeGetVersionReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .majorVersion = DBE_MAJOR_VERSION, .minorVersion = DBE_MINOR_VERSION }; REQUEST_SIZE_MATCH(xDbeGetVersionReq); if (client->swapped) { swaps(&rep.sequenceNumber); } WriteToClient(client, sizeof(xDbeGetVersionReply), &rep); return Success; } /* ProcDbeGetVersion() */ /****************************************************************************** * * DBE DIX Procedure: ProcDbeAllocateBackBufferName * * Description: * * This function is for processing a DbeAllocateBackBufferName request. * This request allocates a drawable ID used to refer to the back buffer * of a window. * * Return Values: * * BadAlloc - server can not allocate resources * BadIDChoice - id is out of range for client; id is already in use * BadMatch - window is not an InputOutput window; * visual of window is not on list returned by * DBEGetVisualInfo; * BadValue - invalid swap action is specified * BadWindow - window is not a valid window * Success * *****************************************************************************/ static int ProcDbeAllocateBackBufferName(ClientPtr client) { REQUEST(xDbeAllocateBackBufferNameReq); WindowPtr pWin; DbeScreenPrivPtr pDbeScreenPriv; DbeWindowPrivPtr pDbeWindowPriv; XdbeScreenVisualInfo scrVisInfo; register int i; Bool visualMatched = FALSE; xDbeSwapAction swapAction; VisualID visual; int status; int add_index; REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq); /* The window must be valid. */ status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); if (status != Success) return status; /* The window must be InputOutput. */ if (pWin->drawable.class != InputOutput) { return BadMatch; } /* The swap action must be valid. */ swapAction = stuff->swapAction; /* use local var for performance. */ if ((swapAction != XdbeUndefined) && (swapAction != XdbeBackground) && (swapAction != XdbeUntouched) && (swapAction != XdbeCopied)) { return BadValue; } /* The id must be in range and not already in use. */ LEGAL_NEW_RESOURCE(stuff->buffer, client); /* The visual of the window must be in the list returned by * GetVisualInfo. */ pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); if (!pDbeScreenPriv->GetVisualInfo) return BadMatch; /* screen doesn't support double buffering */ if (!(*pDbeScreenPriv->GetVisualInfo) (pWin->drawable.pScreen, &scrVisInfo)) { /* GetVisualInfo() failed to allocate visual info data. */ return BadAlloc; } /* See if the window's visual is on the list. */ visual = wVisual(pWin); for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++) { if (scrVisInfo.visinfo[i].visual == visual) { visualMatched = TRUE; } } /* Free what was allocated by the GetVisualInfo() call above. */ free(scrVisInfo.visinfo); if (!visualMatched) { return BadMatch; } if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL) { /* There is no buffer associated with the window. * Allocate a window priv. */ pDbeWindowPriv = calloc(1, sizeof(DbeWindowPrivRec)); if (!pDbeWindowPriv) return BadAlloc; /* Fill out window priv information. */ pDbeWindowPriv->pWindow = pWin; pDbeWindowPriv->width = pWin->drawable.width; pDbeWindowPriv->height = pWin->drawable.height; pDbeWindowPriv->x = pWin->drawable.x; pDbeWindowPriv->y = pWin->drawable.y; pDbeWindowPriv->nBufferIDs = 0; /* Set the buffer ID array pointer to the initial (static) array). */ pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs; /* Initialize the buffer ID list. */ pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS; pDbeWindowPriv->IDs[0] = stuff->buffer; add_index = 0; for (i = 0; i < DBE_INIT_MAX_IDS; i++) { pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT; } /* Actually connect the window priv to the window. */ dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv); } /* if -- There is no buffer associated with the window. */ else { /* A buffer is already associated with the window. * Add the new buffer ID to the array, reallocating the array memory * if necessary. */ /* Determine if there is a free element in the ID array. */ for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++) { if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT) { /* There is still room in the ID array. */ break; } } if (i == pDbeWindowPriv->maxAvailableIDs) { /* No more room in the ID array -- reallocate another array. */ XID *pIDs; /* Setup an array pointer for the realloc operation below. */ if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) { /* We will malloc a new array. */ pIDs = NULL; } else { /* We will realloc a new array. */ pIDs = pDbeWindowPriv->IDs; } /* malloc/realloc a new array and initialize all elements to 0. */ pDbeWindowPriv->IDs = reallocarray(pIDs, pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS, sizeof(XID)); if (!pDbeWindowPriv->IDs) { return BadAlloc; } memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0, (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS - pDbeWindowPriv->nBufferIDs) * sizeof(XID)); if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) { /* We just went from using the initial (static) array to a * newly allocated array. Copy the IDs from the initial array * to the new array. */ memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs, DBE_INIT_MAX_IDS * sizeof(XID)); } pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS; } add_index = i; } /* else -- A buffer is already associated with the window. */ /* Call the DDX routine to allocate the back buffer. */ status = (*pDbeScreenPriv->AllocBackBufferName) (pWin, stuff->buffer, stuff->swapAction); if (status == Success) { pDbeWindowPriv->IDs[add_index] = stuff->buffer; if (!AddResource(stuff->buffer, dbeWindowPrivResType, (void *) pDbeWindowPriv)) { pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT; if (pDbeWindowPriv->nBufferIDs == 0) { status = BadAlloc; goto out_free; } } } else { /* The DDX buffer allocation routine failed for the first buffer of * this window. */ if (pDbeWindowPriv->nBufferIDs == 0) { goto out_free; } } /* Increment the number of buffers (XIDs) associated with this window. */ pDbeWindowPriv->nBufferIDs++; /* Set swap action on all calls. */ pDbeWindowPriv->swapAction = stuff->swapAction; return status; out_free: dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL); free(pDbeWindowPriv); return status; } /* ProcDbeAllocateBackBufferName() */ /****************************************************************************** * * DBE DIX Procedure: ProcDbeDeallocateBackBufferName * * Description: * * This function is for processing a DbeDeallocateBackBufferName request. * This request frees a drawable ID that was obtained by a * DbeAllocateBackBufferName request. * * Return Values: * * BadBuffer - buffer to deallocate is not associated with a window * Success * *****************************************************************************/ static int ProcDbeDeallocateBackBufferName(ClientPtr client) { REQUEST(xDbeDeallocateBackBufferNameReq); DbeWindowPrivPtr pDbeWindowPriv; int rc, i; void *val; REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq); /* Buffer name must be valid */ rc = dixLookupResourceByType((void **) &pDbeWindowPriv, stuff->buffer, dbeWindowPrivResType, client, DixDestroyAccess); if (rc != Success) return rc; rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType, client, DixDestroyAccess); if (rc != Success) return rc; /* Make sure that the id is valid for the window. * This is paranoid code since we already looked up the ID by type * above. */ for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) { /* Loop through the ID list to find the ID. */ if (pDbeWindowPriv->IDs[i] == stuff->buffer) { break; } } if (i == pDbeWindowPriv->nBufferIDs) { /* We did not find the ID in the ID list. */ client->errorValue = stuff->buffer; return dbeErrorBase + DbeBadBuffer; } FreeResource(stuff->buffer, RT_NONE); return Success; } /* ProcDbeDeallocateBackBufferName() */ /****************************************************************************** * * DBE DIX Procedure: ProcDbeSwapBuffers * * Description: * * This function is for processing a DbeSwapBuffers request. * This request swaps the buffers for all windows listed, applying the * appropriate swap action for each window. * * Return Values: * * BadAlloc - local allocation failed; this return value is not defined * by the protocol * BadMatch - a window in request is not double-buffered; a window in * request is listed more than once * BadValue - invalid swap action is specified; no swap action is * specified * BadWindow - a window in request is not valid * Success * *****************************************************************************/ static int ProcDbeSwapBuffers(ClientPtr client) { REQUEST(xDbeSwapBuffersReq); WindowPtr pWin; DbeScreenPrivPtr pDbeScreenPriv; DbeSwapInfoPtr swapInfo; xDbeSwapInfo *dbeSwapInfo; int error; unsigned int i, j; unsigned int nStuff; int nStuff_i; /* DDX API requires int for nStuff */ REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); nStuff = stuff->n; /* use local variable for performance. */ if (nStuff == 0) { REQUEST_SIZE_MATCH(xDbeSwapBuffersReq); return Success; } if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec)) return BadAlloc; REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo)); /* Get to the swap info appended to the end of the request. */ dbeSwapInfo = (xDbeSwapInfo *) &stuff[1]; /* Allocate array to record swap information. */ swapInfo = xallocarray(nStuff, sizeof(DbeSwapInfoRec)); if (swapInfo == NULL) { return BadAlloc; } for (i = 0; i < nStuff; i++) { /* Check all windows to swap. */ /* Each window must be a valid window - BadWindow. */ error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client, DixWriteAccess); if (error != Success) { free(swapInfo); return error; } /* Each window must be double-buffered - BadMatch. */ if (DBE_WINDOW_PRIV(pWin) == NULL) { free(swapInfo); return BadMatch; } /* Each window must only be specified once - BadMatch. */ for (j = i + 1; j < nStuff; j++) { if (dbeSwapInfo[i].window == dbeSwapInfo[j].window) { free(swapInfo); return BadMatch; } } /* Each swap action must be valid - BadValue. */ if ((dbeSwapInfo[i].swapAction != XdbeUndefined) && (dbeSwapInfo[i].swapAction != XdbeBackground) && (dbeSwapInfo[i].swapAction != XdbeUntouched) && (dbeSwapInfo[i].swapAction != XdbeCopied)) { free(swapInfo); return BadValue; } /* Everything checks out OK. Fill in the swap info array. */ swapInfo[i].pWindow = pWin; swapInfo[i].swapAction = dbeSwapInfo[i].swapAction; } /* for (i = 0; i < nStuff; i++) */ /* Call the DDX routine to perform the swap(s). The DDX routine should * scan the swap list (swap info), swap any buffers that it knows how to * handle, delete them from the list, and update nStuff to indicate how * many windows it did not handle. * * This scheme allows a range of sophistication in the DDX SwapBuffers() * implementation. Naive implementations could just swap the first buffer * in the list, move the last buffer to the front, decrement nStuff, and * return. The next level of sophistication could be to scan the whole * list for windows on the same screen. Up another level, the DDX routine * could deal with cross-screen synchronization. */ nStuff_i = nStuff; while (nStuff_i > 0) { pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow); error = (*pDbeScreenPriv->SwapBuffers) (client, &nStuff_i, swapInfo); if (error != Success) { free(swapInfo); return error; } } free(swapInfo); return Success; } /* ProcDbeSwapBuffers() */ /****************************************************************************** * * DBE DIX Procedure: ProcDbeGetVisualInfo * * Description: * * This function is for processing a ProcDbeGetVisualInfo request. * This request returns information about which visuals support * double buffering. * * Return Values: * * BadDrawable - value in screen specifiers is not a valid drawable * Success * *****************************************************************************/ static int ProcDbeGetVisualInfo(ClientPtr client) { REQUEST(xDbeGetVisualInfoReq); DbeScreenPrivPtr pDbeScreenPriv; xDbeGetVisualInfoReply rep; Drawable *drawables; DrawablePtr *pDrawables = NULL; register int i, j, rc; register int count; /* number of visual infos in reply */ register int length; /* length of reply */ ScreenPtr pScreen; XdbeScreenVisualInfo *pScrVisInfo; REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq); if (stuff->n > UINT32_MAX / sizeof(CARD32)) return BadLength; REQUEST_FIXED_SIZE(xDbeGetVisualInfoReq, stuff->n * sizeof(CARD32)); if (stuff->n > UINT32_MAX / sizeof(DrawablePtr)) return BadAlloc; /* Make sure any specified drawables are valid. */ if (stuff->n != 0) { if (!(pDrawables = xallocarray(stuff->n, sizeof(DrawablePtr)))) { return BadAlloc; } drawables = (Drawable *) &stuff[1]; for (i = 0; i < stuff->n; i++) { rc = dixLookupDrawable(pDrawables + i, drawables[i], client, 0, DixGetAttrAccess); if (rc != Success) { free(pDrawables); return rc; } } } count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n; if (!(pScrVisInfo = calloc(count, sizeof(XdbeScreenVisualInfo)))) { free(pDrawables); return BadAlloc; } length = 0; for (i = 0; i < count; i++) { pScreen = (stuff->n == 0) ? screenInfo.screens[i] : pDrawables[i]->pScreen; pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); if (rc != Success) goto freeScrVisInfo; if (!(*pDbeScreenPriv->GetVisualInfo) (pScreen, &pScrVisInfo[i])) { /* We failed to alloc pScrVisInfo[i].visinfo. */ rc = BadAlloc; /* Free visinfos that we allocated for previous screen infos. */ goto freeScrVisInfo; } /* Account for n, number of xDbeVisInfo items in list. */ length += sizeof(CARD32); /* Account for n xDbeVisInfo items */ length += pScrVisInfo[i].count * sizeof(xDbeVisInfo); } rep = (xDbeGetVisualInfoReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = bytes_to_int32(length), .m = count }; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.m); } /* Send off reply. */ WriteToClient(client, sizeof(xDbeGetVisualInfoReply), &rep); for (i = 0; i < count; i++) { CARD32 data32; /* For each screen in the reply, send off the visual info */ /* Send off number of visuals. */ data32 = (CARD32) pScrVisInfo[i].count; if (client->swapped) { swapl(&data32); } WriteToClient(client, sizeof(CARD32), &data32); /* Now send off visual info items. */ for (j = 0; j < pScrVisInfo[i].count; j++) { xDbeVisInfo visInfo; /* Copy the data in the client data structure to a protocol * data structure. We will send data to the client from the * protocol data structure. */ visInfo.visualID = (CARD32) pScrVisInfo[i].visinfo[j].visual; visInfo.depth = (CARD8) pScrVisInfo[i].visinfo[j].depth; visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel; if (client->swapped) { swapl(&visInfo.visualID); /* We do not need to swap depth and perfLevel since they are * already 1 byte quantities. */ } /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */ WriteToClient(client, 2 * sizeof(CARD32), &visInfo.visualID); } } rc = Success; freeScrVisInfo: /* Clean up memory. */ for (i = 0; i < count; i++) { free(pScrVisInfo[i].visinfo); } free(pScrVisInfo); free(pDrawables); return rc; } /* ProcDbeGetVisualInfo() */ /****************************************************************************** * * DBE DIX Procedure: ProcDbeGetbackBufferAttributes * * Description: * * This function is for processing a ProcDbeGetbackBufferAttributes * request. This request returns information about a back buffer. * * Return Values: * * Success * *****************************************************************************/ static int ProcDbeGetBackBufferAttributes(ClientPtr client) { REQUEST(xDbeGetBackBufferAttributesReq); xDbeGetBackBufferAttributesReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0 }; DbeWindowPrivPtr pDbeWindowPriv; int rc; REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq); rc = dixLookupResourceByType((void **) &pDbeWindowPriv, stuff->buffer, dbeWindowPrivResType, client, DixGetAttrAccess); if (rc == Success) { rep.attributes = pDbeWindowPriv->pWindow->drawable.id; } else { rep.attributes = None; } if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.attributes); } WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply), &rep); return Success; } /* ProcDbeGetbackBufferAttributes() */ /****************************************************************************** * * DBE DIX Procedure: ProcDbeDispatch * * Description: * * This function dispatches DBE requests. * *****************************************************************************/ static int ProcDbeDispatch(ClientPtr client) { REQUEST(xReq); switch (stuff->data) { case X_DbeGetVersion: return (ProcDbeGetVersion(client)); case X_DbeAllocateBackBufferName: return (ProcDbeAllocateBackBufferName(client)); case X_DbeDeallocateBackBufferName: return (ProcDbeDeallocateBackBufferName(client)); case X_DbeSwapBuffers: return (ProcDbeSwapBuffers(client)); case X_DbeBeginIdiom: return Success; case X_DbeEndIdiom: return Success; case X_DbeGetVisualInfo: return (ProcDbeGetVisualInfo(client)); case X_DbeGetBackBufferAttributes: return (ProcDbeGetBackBufferAttributes(client)); default: return BadRequest; } } /* ProcDbeDispatch() */ /****************************************************************************** * * DBE DIX Procedure: SProcDbeGetVersion * * Description: * * This function is for processing a DbeGetVersion request on a swapped * server. This request returns the major and minor version numbers of * this extension. * * Return Values: * * Success * *****************************************************************************/ static int _X_COLD SProcDbeGetVersion(ClientPtr client) { REQUEST(xDbeGetVersionReq); swaps(&stuff->length); return (ProcDbeGetVersion(client)); } /* SProcDbeGetVersion() */ /****************************************************************************** * * DBE DIX Procedure: SProcDbeAllocateBackBufferName * * Description: * * This function is for processing a DbeAllocateBackBufferName request on * a swapped server. This request allocates a drawable ID used to refer * to the back buffer of a window. * * Return Values: * * BadAlloc - server can not allocate resources * BadIDChoice - id is out of range for client; id is already in use * BadMatch - window is not an InputOutput window; * visual of window is not on list returned by * DBEGetVisualInfo; * BadValue - invalid swap action is specified * BadWindow - window is not a valid window * Success * *****************************************************************************/ static int _X_COLD SProcDbeAllocateBackBufferName(ClientPtr client) { REQUEST(xDbeAllocateBackBufferNameReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq); swapl(&stuff->window); swapl(&stuff->buffer); /* stuff->swapAction is a byte. We do not need to swap this field. */ return (ProcDbeAllocateBackBufferName(client)); } /* SProcDbeAllocateBackBufferName() */ /****************************************************************************** * * DBE DIX Procedure: SProcDbeDeallocateBackBufferName * * Description: * * This function is for processing a DbeDeallocateBackBufferName request * on a swapped server. This request frees a drawable ID that was * obtained by a DbeAllocateBackBufferName request. * * Return Values: * * BadBuffer - buffer to deallocate is not associated with a window * Success * *****************************************************************************/ static int _X_COLD SProcDbeDeallocateBackBufferName(ClientPtr client) { REQUEST(xDbeDeallocateBackBufferNameReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq); swapl(&stuff->buffer); return (ProcDbeDeallocateBackBufferName(client)); } /* SProcDbeDeallocateBackBufferName() */ /****************************************************************************** * * DBE DIX Procedure: SProcDbeSwapBuffers * * Description: * * This function is for processing a DbeSwapBuffers request on a swapped * server. This request swaps the buffers for all windows listed, * applying the appropriate swap action for each window. * * Return Values: * * BadMatch - a window in request is not double-buffered; a window in * request is listed more than once; all windows in request do * not have the same root * BadValue - invalid swap action is specified * BadWindow - a window in request is not valid * Success * *****************************************************************************/ static int _X_COLD SProcDbeSwapBuffers(ClientPtr client) { REQUEST(xDbeSwapBuffersReq); unsigned int i; xDbeSwapInfo *pSwapInfo; swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); swapl(&stuff->n); if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec)) return BadLength; REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo)); if (stuff->n != 0) { pSwapInfo = (xDbeSwapInfo *) stuff + 1; /* The swap info following the fix part of this request is a window(32) * followed by a 1 byte swap action and then 3 pad bytes. We only need * to swap the window information. */ for (i = 0; i < stuff->n; i++) { swapl(&pSwapInfo->window); } } return (ProcDbeSwapBuffers(client)); } /* SProcDbeSwapBuffers() */ /****************************************************************************** * * DBE DIX Procedure: SProcDbeGetVisualInfo * * Description: * * This function is for processing a ProcDbeGetVisualInfo request on a * swapped server. This request returns information about which visuals * support double buffering. * * Return Values: * * BadDrawable - value in screen specifiers is not a valid drawable * Success * *****************************************************************************/ static int _X_COLD SProcDbeGetVisualInfo(ClientPtr client) { REQUEST(xDbeGetVisualInfoReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq); swapl(&stuff->n); SwapRestL(stuff); return (ProcDbeGetVisualInfo(client)); } /* SProcDbeGetVisualInfo() */ /****************************************************************************** * * DBE DIX Procedure: SProcDbeGetbackBufferAttributes * * Description: * * This function is for processing a ProcDbeGetbackBufferAttributes * request on a swapped server. This request returns information about a * back buffer. * * Return Values: * * Success * *****************************************************************************/ static int _X_COLD SProcDbeGetBackBufferAttributes(ClientPtr client) { REQUEST(xDbeGetBackBufferAttributesReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq); swapl(&stuff->buffer); return (ProcDbeGetBackBufferAttributes(client)); } /* SProcDbeGetBackBufferAttributes() */ /****************************************************************************** * * DBE DIX Procedure: SProcDbeDispatch * * Description: * * This function dispatches DBE requests on a swapped server. * *****************************************************************************/ static int _X_COLD SProcDbeDispatch(ClientPtr client) { REQUEST(xReq); switch (stuff->data) { case X_DbeGetVersion: return (SProcDbeGetVersion(client)); case X_DbeAllocateBackBufferName: return (SProcDbeAllocateBackBufferName(client)); case X_DbeDeallocateBackBufferName: return (SProcDbeDeallocateBackBufferName(client)); case X_DbeSwapBuffers: return (SProcDbeSwapBuffers(client)); case X_DbeBeginIdiom: return Success; case X_DbeEndIdiom: return Success; case X_DbeGetVisualInfo: return (SProcDbeGetVisualInfo(client)); case X_DbeGetBackBufferAttributes: return (SProcDbeGetBackBufferAttributes(client)); default: return BadRequest; } } /* SProcDbeDispatch() */ /****************************************************************************** * * DBE DIX Procedure: DbeSetupBackgroundPainter * * Description: * * This function sets up pGC to clear pixmaps. * * Return Values: * * TRUE - setup was successful * FALSE - the window's background state is NONE * *****************************************************************************/ static Bool DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC) { ChangeGCVal gcvalues[4]; int ts_x_origin, ts_y_origin; PixUnion background; int backgroundState; Mask gcmask; /* First take care of any ParentRelative stuff by altering the * tile/stipple origin to match the coordinates of the upper-left * corner of the first ancestor without a ParentRelative background. * This coordinate is, of course, negative. */ ts_x_origin = ts_y_origin = 0; while (pWin->backgroundState == ParentRelative) { ts_x_origin -= pWin->origin.x; ts_y_origin -= pWin->origin.y; pWin = pWin->parent; } backgroundState = pWin->backgroundState; background = pWin->background; switch (backgroundState) { case BackgroundPixel: gcvalues[0].val = background.pixel; gcvalues[1].val = FillSolid; gcmask = GCForeground | GCFillStyle; break; case BackgroundPixmap: gcvalues[0].val = FillTiled; gcvalues[1].ptr = background.pixmap; gcvalues[2].val = ts_x_origin; gcvalues[3].val = ts_y_origin; gcmask = GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; break; default: /* pWin->backgroundState == None */ return FALSE; } return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0; } /* DbeSetupBackgroundPainter() */ /****************************************************************************** * * DBE DIX Procedure: DbeDrawableDelete * * Description: * * This is the resource delete function for dbeDrawableResType. * It is registered when the drawable resource type is created in * DbeExtensionInit(). * * To make resource deletion simple, we do not do anything in this function * and leave all resource deleteion to DbeWindowPrivDelete(), which will * eventually be called or already has been called. Deletion functions are * not guaranteed to be called in any particular order. * *****************************************************************************/ static int DbeDrawableDelete(void *pDrawable, XID id) { return Success; } /* DbeDrawableDelete() */ /****************************************************************************** * * DBE DIX Procedure: DbeWindowPrivDelete * * Description: * * This is the resource delete function for dbeWindowPrivResType. * It is registered when the drawable resource type is created in * DbeExtensionInit(). * *****************************************************************************/ static int DbeWindowPrivDelete(void *pDbeWinPriv, XID id) { DbeScreenPrivPtr pDbeScreenPriv; DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr) pDbeWinPriv; int i; /* ************************************************************************** ** Remove the buffer ID from the ID array. ************************************************************************** */ /* Find the ID in the ID array. */ i = 0; while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id)) { i++; } if (i == pDbeWindowPriv->nBufferIDs) { /* We did not find the ID in the array. We should never get here. */ return BadValue; } /* Remove the ID from the array. */ if (i < (pDbeWindowPriv->nBufferIDs - 1)) { /* Compress the buffer ID array, overwriting the ID in the process. */ memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i + 1], (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID)); } else { /* We are removing the last ID in the array, in which case, the * assignement below is all that we need to do. */ } pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT; pDbeWindowPriv->nBufferIDs--; /* If an extended array was allocated, then check to see if the remaining * buffer IDs will fit in the static array. */ if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) && (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS)) { /* Copy the IDs back into the static array. */ memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs, DBE_INIT_MAX_IDS * sizeof(XID)); /* Free the extended array; use the static array. */ free(pDbeWindowPriv->IDs); pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs; pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS; } /* ************************************************************************** ** Perform DDX level tasks. ************************************************************************** */ pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV((DbeWindowPrivPtr) pDbeWindowPriv); (*pDbeScreenPriv->WinPrivDelete) ((DbeWindowPrivPtr) pDbeWindowPriv, id); /* ************************************************************************** ** Perform miscellaneous tasks if this is the last buffer associated ** with the window. ************************************************************************** */ if (pDbeWindowPriv->nBufferIDs == 0) { /* Reset the DBE window priv pointer. */ dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey, NULL); /* We are done with the window priv. */ free(pDbeWindowPriv); } return Success; } /* DbeWindowPrivDelete() */ /****************************************************************************** * * DBE DIX Procedure: DbeResetProc * * Description: * * This routine is called at the end of every server generation. * It deallocates any memory reserved for the extension and performs any * other tasks related to shutting down the extension. * *****************************************************************************/ static void DbeResetProc(ExtensionEntry * extEntry) { int i; ScreenPtr pScreen; DbeScreenPrivPtr pDbeScreenPriv; for (i = 0; i < screenInfo.numScreens; i++) { pScreen = screenInfo.screens[i]; pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); if (pDbeScreenPriv) { /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit(). */ pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; free(pDbeScreenPriv); } } } /* DbeResetProc() */ /****************************************************************************** * * DBE DIX Procedure: DbeDestroyWindow * * Description: * * This is the wrapper for pScreen->DestroyWindow. * This function frees buffer resources for a window before it is * destroyed. * *****************************************************************************/ static Bool DbeDestroyWindow(WindowPtr pWin) { DbeScreenPrivPtr pDbeScreenPriv; DbeWindowPrivPtr pDbeWindowPriv; ScreenPtr pScreen; Bool ret; /* ************************************************************************** ** 1. Unwrap the member routine. ************************************************************************** */ pScreen = pWin->drawable.pScreen; pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; /* ************************************************************************** ** 2. Do any work necessary before the member routine is called. ** ** Call the window priv delete function for all buffer IDs associated ** with this window. ************************************************************************** */ if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) { while (pDbeWindowPriv) { /* *DbeWinPrivDelete() will free the window private and set it to * NULL if there are no more buffer IDs associated with this * window. */ FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); } } /* ************************************************************************** ** 3. Call the member routine, saving its result if necessary. ************************************************************************** */ ret = (*pScreen->DestroyWindow) (pWin); /* ************************************************************************** ** 4. Rewrap the member routine, restoring the wrapper value first in case ** the wrapper (or something that it wrapped) change this value. ************************************************************************** */ pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; pScreen->DestroyWindow = DbeDestroyWindow; /* ************************************************************************** ** 5. Do any work necessary after the member routine has been called. ** ** In this case we do not need to do anything. ************************************************************************** */ return ret; } /* DbeDestroyWindow() */ /****************************************************************************** * * DBE DIX Procedure: DbeExtensionInit * * Description: * * Called from InitExtensions in main() * *****************************************************************************/ void DbeExtensionInit(void) { ExtensionEntry *extEntry; register int i, j; ScreenPtr pScreen = NULL; DbeScreenPrivPtr pDbeScreenPriv; int nStubbedScreens = 0; Bool ddxInitSuccess; #ifdef PANORAMIX if (!noPanoramiXExtension) return; #endif /* Create the resource types. */ dbeDrawableResType = CreateNewResourceType(DbeDrawableDelete, "dbeDrawable"); if (!dbeDrawableResType) return; dbeDrawableResType |= RC_DRAWABLE; dbeWindowPrivResType = CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow"); if (!dbeWindowPrivResType) return; if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0)) return; if (!dixRegisterPrivateKey(&dbeWindowPrivKeyRec, PRIVATE_WINDOW, 0)) return; for (i = 0; i < screenInfo.numScreens; i++) { /* For each screen, set up DBE screen privates and init DIX and DDX * interface. */ pScreen = screenInfo.screens[i]; if (!(pDbeScreenPriv = malloc(sizeof(DbeScreenPrivRec)))) { /* If we can not alloc a window or screen private, * then free any privates that we already alloc'ed and return */ for (j = 0; j < i; j++) { free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates, dbeScreenPrivKey)); dixSetPrivate(&screenInfo.screens[j]->devPrivates, dbeScreenPrivKey, NULL); } return; } dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv); { /* We don't have DDX support for DBE anymore */ #ifndef DISABLE_MI_DBE_BY_DEFAULT /* Setup DIX. */ pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter; /* Setup DDX. */ ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv); /* DDX DBE initialization may have the side affect of * reallocating pDbeScreenPriv, so we need to update it. */ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); if (ddxInitSuccess) { /* Wrap DestroyWindow. The DDX initialization function * already wrapped PositionWindow for us. */ pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; pScreen->DestroyWindow = DbeDestroyWindow; } else { /* DDX initialization failed. Stub the screen. */ DbeStubScreen(pDbeScreenPriv, &nStubbedScreens); } #else DbeStubScreen(pDbeScreenPriv, &nStubbedScreens); #endif } } /* for (i = 0; i < screenInfo.numScreens; i++) */ if (nStubbedScreens == screenInfo.numScreens) { /* All screens stubbed. Clean up and return. */ for (i = 0; i < screenInfo.numScreens; i++) { free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates, dbeScreenPrivKey)); dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL); } return; } /* Now add the extension. */ extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents, DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch, DbeResetProc, StandardMinorOpcode); dbeErrorBase = extEntry->errorBase; SetResourceTypeErrorValue(dbeWindowPrivResType, dbeErrorBase + DbeBadBuffer); SetResourceTypeErrorValue(dbeDrawableResType, dbeErrorBase + DbeBadBuffer); } /* DbeExtensionInit() */ xorg-server-1.20.13/dbe/midbe.c0000644000175000017500000005537214100573755013063 00000000000000/****************************************************************************** * * Copyright (c) 1994, 1995 Hewlett-Packard Company * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of the Hewlett-Packard * Company shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization from the Hewlett-Packard Company. * * Machine-independent DBE code * *****************************************************************************/ /* INCLUDES */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include "misc.h" #include "os.h" #include "windowstr.h" #include "scrnintstr.h" #include "pixmapstr.h" #include "extnsionst.h" #include "dixstruct.h" #include "resource.h" #include "opaque.h" #include "dbestruct.h" #include "regionstr.h" #include "gcstruct.h" #include "inputstr.h" #include "midbe.h" #include "xace.h" #include /****************************************************************************** * * DBE MI Procedure: miDbeGetVisualInfo * * Description: * * This is the MI function for the DbeGetVisualInfo request. This function * is called through pDbeScreenPriv->GetVisualInfo. This function is also * called for the DbeAllocateBackBufferName request at the extension level; * it is called by ProcDbeAllocateBackBufferName() in dbe.c. * * If memory allocation fails or we can not get the visual info, this * function returns FALSE. Otherwise, it returns TRUE for success. * *****************************************************************************/ static Bool miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo * pScrVisInfo) { register int i, j, k; register int count; DepthPtr pDepth; XdbeVisualInfo *visInfo; /* Determine number of visuals for this screen. */ for (i = 0, count = 0; i < pScreen->numDepths; i++) { count += pScreen->allowedDepths[i].numVids; } /* Allocate an array of XdbeVisualInfo items. */ if (!(visInfo = xallocarray(count, sizeof(XdbeVisualInfo)))) { return FALSE; /* memory alloc failure */ } for (i = 0, k = 0; i < pScreen->numDepths; i++) { /* For each depth of this screen, get visual information. */ pDepth = &pScreen->allowedDepths[i]; for (j = 0; j < pDepth->numVids; j++) { /* For each visual for this depth of this screen, get visual ID * and visual depth. Since this is MI code, we will always return * the same performance level for all visuals (0). A higher * performance level value indicates higher performance. */ visInfo[k].visual = pDepth->vids[j]; visInfo[k].depth = pDepth->depth; visInfo[k].perflevel = 0; k++; } } /* Record the number of visuals and point visual_depth to * the array of visual info. */ pScrVisInfo->count = count; pScrVisInfo->visinfo = visInfo; return TRUE; /* success */ } /* miDbeGetVisualInfo() */ /****************************************************************************** * * DBE MI Procedure: miAllocBackBufferName * * Description: * * This is the MI function for the DbeAllocateBackBufferName request. * *****************************************************************************/ static int miDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction) { ScreenPtr pScreen; DbeWindowPrivPtr pDbeWindowPriv; DbeScreenPrivPtr pDbeScreenPriv; GCPtr pGC; xRectangle clearRect; int rc; pScreen = pWin->drawable.pScreen; pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); if (pDbeWindowPriv->nBufferIDs == 0) { /* There is no buffer associated with the window. * We have to create the window priv priv. Remember, the window * priv was created at the DIX level, so all we need to do is * create the priv priv and attach it to the priv. */ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); /* Get a front pixmap. */ if (!(pDbeWindowPriv->pFrontBuffer = (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width, pDbeWindowPriv->height, pWin->drawable.depth, 0))) { return BadAlloc; } /* Get a back pixmap. */ if (!(pDbeWindowPriv->pBackBuffer = (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width, pDbeWindowPriv->height, pWin->drawable.depth, 0))) { (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); return BadAlloc; } /* Security creation/labeling check. */ rc = XaceHook(XACE_RESOURCE_ACCESS, serverClient, bufId, dbeDrawableResType, pDbeWindowPriv->pBackBuffer, RT_WINDOW, pWin, DixCreateAccess); /* Make the back pixmap a DBE drawable resource. */ if (rc != Success || !AddResource(bufId, dbeDrawableResType, pDbeWindowPriv->pBackBuffer)) { /* free the buffer and the drawable resource */ FreeResource(bufId, RT_NONE); return (rc == Success) ? BadAlloc : rc; } /* Clear the back buffer. */ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC); clearRect.x = clearRect.y = 0; clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width; clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height; (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv-> pBackBuffer, pGC, 1, &clearRect); } FreeScratchGC(pGC); } /* if no buffer associated with the window */ else { /* A buffer is already associated with the window. * Place the new buffer ID information at the head of the ID list. */ /* Associate the new ID with an existing pixmap. */ if (!AddResource(bufId, dbeDrawableResType, (void *) pDbeWindowPriv->pBackBuffer)) { return BadAlloc; } } return Success; } /* miDbeAllocBackBufferName() */ /****************************************************************************** * * DBE MI Procedure: miDbeAliasBuffers * * Description: * * This function associates all XIDs of a buffer with the back pixmap * stored in the window priv. * *****************************************************************************/ static void miDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv) { int i; for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) { ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType, (void *) pDbeWindowPriv->pBackBuffer); } } /* miDbeAliasBuffers() */ /****************************************************************************** * * DBE MI Procedure: miDbeSwapBuffers * * Description: * * This is the MI function for the DbeSwapBuffers request. * *****************************************************************************/ static int miDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo) { DbeScreenPrivPtr pDbeScreenPriv; DbeWindowPrivPtr pDbeWindowPriv; GCPtr pGC; WindowPtr pWin; PixmapPtr pTmpBuffer; xRectangle clearRect; pWin = swapInfo[0].pWindow; pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); /* ********************************************************************** ** Setup before swap. ********************************************************************** */ switch (swapInfo[0].swapAction) { case XdbeUndefined: break; case XdbeBackground: break; case XdbeUntouched: ValidateGC((DrawablePtr) pDbeWindowPriv->pFrontBuffer, pGC); (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pDbeWindowPriv->pFrontBuffer, pGC, 0, 0, pWin->drawable.width, pWin->drawable.height, 0, 0); break; case XdbeCopied: break; } /* ********************************************************************** ** Swap. ********************************************************************** */ ValidateGC((DrawablePtr) pWin, pGC); (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer, (DrawablePtr) pWin, pGC, 0, 0, pWin->drawable.width, pWin->drawable.height, 0, 0); /* ********************************************************************** ** Tasks after swap. ********************************************************************** */ switch (swapInfo[0].swapAction) { case XdbeUndefined: break; case XdbeBackground: if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC); clearRect.x = 0; clearRect.y = 0; clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width; clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height; (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv-> pBackBuffer, pGC, 1, &clearRect); } break; case XdbeUntouched: /* Swap pixmap pointers. */ pTmpBuffer = pDbeWindowPriv->pBackBuffer; pDbeWindowPriv->pBackBuffer = pDbeWindowPriv->pFrontBuffer; pDbeWindowPriv->pFrontBuffer = pTmpBuffer; miDbeAliasBuffers(pDbeWindowPriv); break; case XdbeCopied: break; } /* Remove the swapped window from the swap information array and decrement * pNumWindows to indicate to the DIX level how many windows were actually * swapped. */ if (*pNumWindows > 1) { /* We were told to swap more than one window, but we only swapped the * first one. Remove the first window in the list by moving the last * window to the beginning. */ swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow; swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction; /* Clear the last window information just to be safe. */ swapInfo[*pNumWindows - 1].pWindow = (WindowPtr) NULL; swapInfo[*pNumWindows - 1].swapAction = 0; } else { /* Clear the window information just to be safe. */ swapInfo[0].pWindow = (WindowPtr) NULL; swapInfo[0].swapAction = 0; } (*pNumWindows)--; FreeScratchGC(pGC); return Success; } /* miSwapBuffers() */ /****************************************************************************** * * DBE MI Procedure: miDbeWinPrivDelete * * Description: * * This is the MI function for deleting the dbeWindowPrivResType resource. * This function is invoked indirectly by calling FreeResource() to free * the resources associated with a DBE buffer ID. There are 5 ways that * miDbeWinPrivDelete() can be called by FreeResource(). They are: * * - A DBE window is destroyed, in which case the DbeDestroyWindow() * wrapper is invoked. The wrapper calls FreeResource() for all DBE * buffer IDs. * * - miDbeAllocBackBufferName() calls FreeResource() to clean up resources * after a buffer allocation failure. * * - The PositionWindow wrapper, miDbePositionWindow(), calls * FreeResource() when it fails to create buffers of the new size. * FreeResource() is called for all DBE buffer IDs. * * - FreeClientResources() calls FreeResource() when a client dies or the * the server resets. * * When FreeResource() is called for a DBE buffer ID, the delete function * for the only other type of DBE resource, dbeDrawableResType, is also * invoked. This delete function (DbeDrawableDelete) is a NOOP to make * resource deletion easier. It is not guaranteed which delete function is * called first. Hence, we will let miDbeWinPrivDelete() free all DBE * resources. * * This function deletes/frees the following stuff associated with * the window private: * * - the ID node in the ID list representing the passed in ID. * * In addition, pDbeWindowPriv->nBufferIDs is decremented. * * If this function is called for the last/only buffer ID for a window, * these are additionally deleted/freed: * * - the front and back pixmaps * - the window priv itself * *****************************************************************************/ static void miDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId) { if (pDbeWindowPriv->nBufferIDs != 0) { /* We still have at least one more buffer ID associated with this * window. */ return; } /* We have no more buffer IDs associated with this window. We need to * free some stuff. */ /* Destroy the front and back pixmaps. */ if (pDbeWindowPriv->pFrontBuffer) { (*pDbeWindowPriv->pWindow->drawable.pScreen-> DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); } if (pDbeWindowPriv->pBackBuffer) { (*pDbeWindowPriv->pWindow->drawable.pScreen-> DestroyPixmap) (pDbeWindowPriv->pBackBuffer); } } /* miDbeWinPrivDelete() */ /****************************************************************************** * * DBE MI Procedure: miDbePositionWindow * * Description: * * This function was cloned from miMbxPositionWindow() in mimultibuf.c. * This function resizes the buffer when the window is resized. * *****************************************************************************/ static Bool miDbePositionWindow(WindowPtr pWin, int x, int y) { ScreenPtr pScreen; DbeScreenPrivPtr pDbeScreenPriv; DbeWindowPrivPtr pDbeWindowPriv; int width, height; int dx, dy, dw, dh; int sourcex, sourcey; int destx, desty; int savewidth, saveheight; PixmapPtr pFrontBuffer; PixmapPtr pBackBuffer; Bool clear; GCPtr pGC; xRectangle clearRect; Bool ret; /* ************************************************************************** ** 1. Unwrap the member routine. ************************************************************************** */ pScreen = pWin->drawable.pScreen; pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; /* ************************************************************************** ** 2. Do any work necessary before the member routine is called. ** ** In this case we do not need to do anything. ************************************************************************** */ /* ************************************************************************** ** 3. Call the member routine, saving its result if necessary. ************************************************************************** */ ret = (*pScreen->PositionWindow) (pWin, x, y); /* ************************************************************************** ** 4. Rewrap the member routine, restoring the wrapper value first in case ** the wrapper (or something that it wrapped) change this value. ************************************************************************** */ pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; pScreen->PositionWindow = miDbePositionWindow; /* ************************************************************************** ** 5. Do any work necessary after the member routine has been called. ************************************************************************** */ if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) { return ret; } if (pDbeWindowPriv->width == pWin->drawable.width && pDbeWindowPriv->height == pWin->drawable.height) { return ret; } width = pWin->drawable.width; height = pWin->drawable.height; dx = pWin->drawable.x - pDbeWindowPriv->x; dy = pWin->drawable.y - pDbeWindowPriv->y; dw = width - pDbeWindowPriv->width; dh = height - pDbeWindowPriv->height; GravityTranslate(0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty); clear = ((pDbeWindowPriv->width < (unsigned short) width) || (pDbeWindowPriv->height < (unsigned short) height) || (pWin->bitGravity == ForgetGravity)); sourcex = 0; sourcey = 0; savewidth = pDbeWindowPriv->width; saveheight = pDbeWindowPriv->height; /* Clip rectangle to source and destination. */ if (destx < 0) { savewidth += destx; sourcex -= destx; destx = 0; } if (destx + savewidth > width) { savewidth = width - destx; } if (desty < 0) { saveheight += desty; sourcey -= desty; desty = 0; } if (desty + saveheight > height) { saveheight = height - desty; } pDbeWindowPriv->width = width; pDbeWindowPriv->height = height; pDbeWindowPriv->x = pWin->drawable.x; pDbeWindowPriv->y = pWin->drawable.y; pGC = GetScratchGC(pWin->drawable.depth, pScreen); if (clear) { if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { clearRect.x = 0; clearRect.y = 0; clearRect.width = width; clearRect.height = height; } else { clear = FALSE; } } /* Create DBE buffer pixmaps equal to size of resized window. */ pFrontBuffer = (*pScreen->CreatePixmap) (pScreen, width, height, pWin->drawable.depth, 0); pBackBuffer = (*pScreen->CreatePixmap) (pScreen, width, height, pWin->drawable.depth, 0); if (!pFrontBuffer || !pBackBuffer) { /* We failed at creating 1 or 2 of the pixmaps. */ if (pFrontBuffer) { (*pScreen->DestroyPixmap) (pFrontBuffer); } if (pBackBuffer) { (*pScreen->DestroyPixmap) (pBackBuffer); } /* Destroy all buffers for this window. */ while (pDbeWindowPriv) { /* DbeWindowPrivDelete() will free the window private if there no * more buffer IDs associated with this window. */ FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); } FreeScratchGC(pGC); return FALSE; } else { /* Clear out the new DBE buffer pixmaps. */ /* I suppose this could avoid quite a bit of work if * it computed the minimal area required. */ ValidateGC(&pFrontBuffer->drawable, pGC); if (clear) { (*pGC->ops->PolyFillRect) ((DrawablePtr) pFrontBuffer, pGC, 1, &clearRect); } /* Copy the contents of the old front pixmap to the new one. */ if (pWin->bitGravity != ForgetGravity) { (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pFrontBuffer, (DrawablePtr) pFrontBuffer, pGC, sourcex, sourcey, savewidth, saveheight, destx, desty); } ValidateGC(&pBackBuffer->drawable, pGC); if (clear) { (*pGC->ops->PolyFillRect) ((DrawablePtr) pBackBuffer, pGC, 1, &clearRect); } /* Copy the contents of the old back pixmap to the new one. */ if (pWin->bitGravity != ForgetGravity) { (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer, (DrawablePtr) pBackBuffer, pGC, sourcex, sourcey, savewidth, saveheight, destx, desty); } /* Destroy the old pixmaps, and point the DBE window priv to the new * pixmaps. */ (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); (*pScreen->DestroyPixmap) (pDbeWindowPriv->pBackBuffer); pDbeWindowPriv->pFrontBuffer = pFrontBuffer; pDbeWindowPriv->pBackBuffer = pBackBuffer; /* Make sure all XID are associated with the new back pixmap. */ miDbeAliasBuffers(pDbeWindowPriv); FreeScratchGC(pGC); } return ret; } /* miDbePositionWindow() */ /****************************************************************************** * * DBE MI Procedure: miDbeInit * * Description: * * This is the MI initialization function called by DbeExtensionInit(). * *****************************************************************************/ Bool miDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv) { /* Wrap functions. */ pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; pScreen->PositionWindow = miDbePositionWindow; /* Initialize the per-screen DBE function pointers. */ pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo; pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName; pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers; pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete; return TRUE; } /* miDbeInit() */ xorg-server-1.20.13/dbe/midbe.h0000644000175000017500000000412214100573755013053 00000000000000/****************************************************************************** * Copyright (c) 1994, 1995 Hewlett-Packard Company * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of the Hewlett-Packard * Company shall not be used in advertising or otherwise to promote the * sale, use or other dealings in this Software without prior written * authorization from the Hewlett-Packard Company. * * Header file for users of machine-independent DBE code * *****************************************************************************/ #ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef MIDBE_H #define MIDBE_H #include "privates.h" /* EXTERNS */ extern Bool miDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv); extern DevPrivateKeyRec dbeScreenPrivKeyRec; #define dbeScreenPrivKey (&dbeScreenPrivKeyRec) extern DevPrivateKeyRec dbeWindowPrivKeyRec; #define dbeWindowPrivKey (&dbeWindowPrivKeyRec) extern RESTYPE dbeDrawableResType; extern RESTYPE dbeWindowPrivResType; #endif /* MIDBE_H */ xorg-server-1.20.13/dix/0000755000175000017500000000000014100574017011725 500000000000000xorg-server-1.20.13/dix/meson.build0000644000175000017500000000160314100573756014020 00000000000000srcs_dix = [ 'atom.c', 'colormap.c', 'cursor.c', 'devices.c', 'dispatch.c', 'dixfonts.c', 'main.c', 'dixutils.c', 'enterleave.c', 'events.c', 'eventconvert.c', 'extension.c', 'gc.c', 'getevents.c', 'globals.c', 'glyphcurs.c', 'grabs.c', 'initatoms.c', 'inpututils.c', 'pixmap.c', 'privates.c', 'property.c', 'ptrveloc.c', 'region.c', 'registry.c', 'resource.c', 'selection.c', 'swaprep.c', 'swapreq.c', 'tables.c', 'touch.c', 'window.c', ] libxserver_dix = static_library('libxserver_dix', srcs_dix, include_directories: inc, dependencies: common_dep, ) libxserver_main = static_library('libxserver_main', 'stubmain.c', include_directories: inc, dependencies: common_dep, ) install_data( 'protocol.txt', install_dir: serverconfigdir, ) xorg-server-1.20.13/dix/Makefile.am0000644000175000017500000000266314100573755013720 00000000000000noinst_LTLIBRARIES = libdix.la libmain.la AM_CPPFLAGS = -I$(top_srcdir)/include AM_CFLAGS = $(DIX_CFLAGS) libmain_la_SOURCES = \ stubmain.c libdix_la_SOURCES = \ atom.c \ colormap.c \ cursor.c \ devices.c \ dispatch.c \ dispatch.h \ dixfonts.c \ main.c \ dixutils.c \ enterleave.c \ enterleave.h \ events.c \ eventconvert.c \ extension.c \ gc.c \ getevents.c \ globals.c \ glyphcurs.c \ grabs.c \ initatoms.c \ inpututils.c \ pixmap.c \ privates.c \ property.c \ ptrveloc.c \ region.c \ registry.c \ resource.c \ selection.c \ swaprep.c \ swapreq.c \ tables.c \ touch.c \ window.c EXTRA_DIST = buildatoms BuiltInAtoms Xserver.d Xserver-dtrace.h.in # Install list of protocol names miscconfigdir = $(SERVER_MISC_CONFIG_PATH) dist_miscconfig_DATA = protocol.txt if XSERVER_DTRACE # Generate dtrace header file for C sources to include BUILT_SOURCES = Xserver-dtrace.h Xserver-dtrace.h: $(srcdir)/Xserver.d $(AM_V_GEN)$(DTRACE) -C -h -o $@ -s $(srcdir)/Xserver.d \ || cp Xserver-dtrace.h.in $@ endif if SPECIAL_DTRACE_OBJECTS # Generate dtrace object code for probes in libdix dtrace-dix.o: $(top_srcdir)/dix/Xserver.d libdix.la $(AM_V_GEN)$(DTRACE) -G -C -o $@ -s $(top_srcdir)/dix/Xserver.d $(am_libdix_la_OBJECTS:%.lo=.libs/%.o) noinst_PROGRAMS = dix.O dix_O_SOURCES = dix.O: dtrace-dix.o libdix.la $(AM_V_GEN)ld -r -o $@ $(am_libdix_la_OBJECTS:%.lo=.libs/%.o) endif CLEANFILES = Xserver-dtrace.h xorg-server-1.20.13/dix/protocol.txt0000644000175000017500000006214314100573756014266 00000000000000# Registry of protocol names used by X Server # This will eventually be replaced by server-side XCB # # Format is Xnnn : # R=Request, V=Event, E=Error # # This is a security-sensitive file, please set permissions as appropriate. # R000 Apple-DRI:QueryVersion R001 Apple-DRI:QueryDirectRenderingCapable R002 Apple-DRI:CreateSurface R003 Apple-DRI:DestroySurface R004 Apple-DRI:AuthConnection V000 Apple-DRI:ObsoleteEvent1 V001 Apple-DRI:ObsoleteEvent2 V002 Apple-DRI:ObsoleteEvent3 V003 Apple-DRI:SurfaceNotify E000 Apple-DRI:ClientNotLocal E001 Apple-DRI:OperationNotSupported R000 Apple-WM:QueryVersion R001 Apple-WM:FrameGetRect R002 Apple-WM:FrameHitTest R003 Apple-WM:FrameDraw R004 Apple-WM:DisableUpdate R005 Apple-WM:ReenableUpdate R006 Apple-WM:SelectInput R007 Apple-WM:SetWindowMenuCheck R008 Apple-WM:SetFrontProcess R009 Apple-WM:SetWindowLevel R010 Apple-WM:SetCanQuit R011 Apple-WM:SetWindowMenu V000 Apple-WM:ControllerNotify V001 Apple-WM:ActivationNotify V002 Apple-WM:PasteboardNotify E000 Apple-WM:ClientNotLocal E001 Apple-WM:OperationNotSupported R000 BIG-REQUESTS:Enable R000 Composite:CompositeQueryVersion R001 Composite:CompositeRedirectWindow R002 Composite:CompositeRedirectSubwindows R003 Composite:CompositeUnredirectWindow R004 Composite:CompositeUnredirectSubwindows R005 Composite:CompositeCreateRegionFromBorderClip R006 Composite:CompositeNameWindowPixmap R007 Composite:CompositeGetOverlayWindow R008 Composite:CompositeReleaseOverlayWindow R000 DAMAGE:QueryVersion R001 DAMAGE:Create R002 DAMAGE:Destroy R003 DAMAGE:Subtract R004 DAMAGE:Add V000 DAMAGE:Notify E000 DAMAGE:BadDamage R000 DMX:DMXQueryVersion R001 DMX:DMXGetScreenCount R002 DMX:DMXGetScreenInfoDEPRECATED R003 DMX:DMXGetWindowAttributes R004 DMX:DMXGetInputCount R005 DMX:DMXGetInputAttributes R006 DMX:DMXForceWindowCreationDEPRECATED R007 DMX:DMXReconfigureScreenDEPRECATED R008 DMX:DMXSync R009 DMX:DMXForceWindowCreation R010 DMX:DMXGetScreenAttributes R011 DMX:DMXChangeScreensAttributes R012 DMX:DMXAddScreen R013 DMX:DMXRemoveScreen R014 DMX:DMXGetDesktopAttributes R015 DMX:DMXChangeDesktopAttributes R016 DMX:DMXAddInput R017 DMX:DMXRemoveInput R000 DOUBLE-BUFFER:GetVersion R001 DOUBLE-BUFFER:AllocateBackBufferName R002 DOUBLE-BUFFER:DeallocateBackBufferName R003 DOUBLE-BUFFER:SwapBuffers R004 DOUBLE-BUFFER:BeginIdiom R005 DOUBLE-BUFFER:EndIdiom R006 DOUBLE-BUFFER:GetVisualInfo R007 DOUBLE-BUFFER:GetBackBufferAttributes E000 DOUBLE-BUFFER:BadBuffer R000 DPMS:GetVersion R001 DPMS:Capable R002 DPMS:GetTimeouts R003 DPMS:SetTimeouts R004 DPMS:Enable R005 DPMS:Disable R006 DPMS:ForceLevel R007 DPMS:Info R000 DRI2:QueryVersion R001 DRI2:Connect R002 DRI2:Authenticate R003 DRI2:CreateDrawable R004 DRI2:DestroyDrawable R005 DRI2:GetBuffers R006 DRI2:CopyRegion R007 DRI2:GetBuffersWithFormat R008 DRI2:SwapBuffers R009 DRI2:GetMSC R010 DRI2:WaitMSC R011 DRI2:WaitSBC R012 DRI2:SwapInterval V000 DRI2:BufferSwapComplete V001 DRI2:InvalidateBuffers R000 DRI3:QueryVersion R001 DRI3:Open R002 DRI3:PixmapFromBuffer R003 DRI3:BufferFromPixmap R004 DRI3:FenceFromFD R005 DRI3:FDFromFence R000 Extended-Visual-Information:QueryVersion R001 Extended-Visual-Information:GetVisualInfo R000 FontCache:QueryVersion R001 FontCache:GetCacheSettings R002 FontCache:ChangeCacheSettings R003 FontCache:GetCacheStatistics E000 FontCache:BadProtocol E001 FontCache:CannotAllocMemory R001 GLX: R002 GLX:Large R003 GLX:CreateContext R004 GLX:DestroyContext R005 GLX:MakeCurrent R006 GLX:IsDirect R007 GLX:QueryVersion R008 GLX:WaitGL R009 GLX:WaitX R010 GLX:CopyContext R011 GLX:SwapBuffers R012 GLX:UseXFont R013 GLX:CreateGLXPixmap R014 GLX:GetVisualConfigs R015 GLX:DestroyGLXPixmap R016 GLX:VendorPrivate R017 GLX:VendorPrivateWithReply R018 GLX:QueryExtensionsString R019 GLX:QueryServerString R020 GLX:ClientInfo R021 GLX:GetFBConfigs R022 GLX:CreatePixmap R023 GLX:DestroyPixmap R024 GLX:CreateNewContext R025 GLX:QueryContext R026 GLX:MakeContextCurrent R027 GLX:CreatePbuffer R028 GLX:DestroyPbuffer R029 GLX:GetDrawableAttributes R030 GLX:ChangeDrawableAttributes R031 GLX:CreateWindow R032 GLX:DeleteWindow R033 GLX:SetClientInfoARB R034 GLX:CreateContextAttribsARB R035 GLX:SetClientInfo2ARB R101 GLX:NewList R102 GLX:EndList R103 GLX:DeleteLists R104 GLX:GenLists R105 GLX:FeedbackBuffer R106 GLX:SelectBuffer R107 GLX:Mode R108 GLX:Finish R109 GLX:PixelStoref R110 GLX:PixelStorei R111 GLX:ReadPixels R112 GLX:GetBooleanv R113 GLX:GetClipPlane R114 GLX:GetDoublev R115 GLX:GetError R116 GLX:GetFloatv R117 GLX:GetIntegerv R118 GLX:GetLightfv R119 GLX:GetLightiv R120 GLX:GetMapdv R121 GLX:GetMapfv R122 GLX:GetMapiv R123 GLX:GetMaterialfv R124 GLX:GetMaterialiv R125 GLX:GetPixelfv R126 GLX:GetPixelMapuiv R127 GLX:GetPixelMapusv R128 GLX:GetPolygonStipple R129 GLX:GetString R130 GLX:GetTexEnvfv R131 GLX:GetTexEnviv R132 GLX:GetTexGendv R133 GLX:GetTexGenfv R134 GLX:GetTexGeniv R135 GLX:GetTexImage R136 GLX:GetTexParameterfv R137 GLX:GetTexParameteriv R138 GLX:GetTexLevelParameterfv R139 GLX:GetTexLevelParameteriv R140 GLX:IsEnabled R141 GLX:IsList R142 GLX:Flush R143 GLX:AreTexturesResident R144 GLX:DeleteTextures R145 GLX:GenTextures R146 GLX:IsTexture R147 GLX:GetColorTable R148 GLX:GetColorTableParameterfv R149 GLX:GetColorTableParameterfv R150 GLX:GetConvolutionFilter R151 GLX:GetConvolutionParameterfv R152 GLX:GetConvolutionParameteriv R153 GLX:GetSeparableFilter R154 GLX:GetHistogram R155 GLX:GetHistogramParameterfv R156 GLX:GetHistogramParameteriv R157 GLX:GetMinmax R158 GLX:GetMinmaxParameterfv R159 GLX:GetMinmaxParameteriv R160 GLX:GetCompressedTexImage V000 GLX:PbufferClobber V001 GLX:BufferSwapComplete E000 GLX:BadContext E001 GLX:BadContextState E002 GLX:BadDrawable E003 GLX:BadPixmap E004 GLX:BadContextTag E005 GLX:BadCurrentWindow E006 GLX:BadRenderRequest E007 GLX:BadLargeRequest E008 GLX:UnsupportedPrivateRequest E009 GLX:BadFBConfig E010 GLX:BadPbuffer E011 GLX:BadCurrentDrawable E012 GLX:BadWindow R000 MIT-SCREEN-SAVER:QueryVersion R001 MIT-SCREEN-SAVER:QueryInfo R002 MIT-SCREEN-SAVER:SelectInput R003 MIT-SCREEN-SAVER:SetAttributes R004 MIT-SCREEN-SAVER:UnsetAttributes R005 MIT-SCREEN-SAVER:Suspend V000 MIT-SCREEN-SAVER:Notify R000 MIT-SHM:QueryVersion R001 MIT-SHM:Attach R002 MIT-SHM:Detach R003 MIT-SHM:PutImage R004 MIT-SHM:GetImage R005 MIT-SHM:CreatePixmap R006 MIT-SHM:AttachFd R007 MIT-SHM:CreateSegment V000 MIT-SHM:Completion E000 MIT-SHM:BadShmSeg R000 MIT-SUNDRY-NONSTANDARD:SetBugMode R001 MIT-SUNDRY-NONSTANDARD:GetBugMode R000 Present:QueryVersion R001 Present:Pixmap R002 Present:NotifyMSC R003 Present:SelectInput R004 Present:QueryCapabilities R000 RANDR:QueryVersion R001 RANDR:OldGetScreenInfo R002 RANDR:SetScreenConfig R003 RANDR:OldScreenChangeSelectInput R004 RANDR:SelectInput R005 RANDR:GetScreenInfo R006 RANDR:GetScreenSizeRange R007 RANDR:SetScreenSize R008 RANDR:GetScreenResources R009 RANDR:GetOutputInfo R010 RANDR:ListOutputProperties R011 RANDR:QueryOutputProperty R012 RANDR:ConfigureOutputProperty R013 RANDR:ChangeOutputProperty R014 RANDR:DeleteOutputProperty R015 RANDR:GetOutputProperty R016 RANDR:CreateMode R017 RANDR:DestroyMode R018 RANDR:AddOutputMode R019 RANDR:DeleteOutputMode R020 RANDR:GetCrtcInfo R021 RANDR:SetCrtcConfig R022 RANDR:GetCrtcGammaSize R023 RANDR:GetCrtcGamma R024 RANDR:SetCrtcGamma R025 RANDR:GetScreenResourcesCurrent R026 RANDR:SetCrtcTransform R027 RANDR:GetCrtcTransform R028 RANDR:GetPanning R029 RANDR:SetPanning R030 RANDR:SetOutputPrimary R031 RANDR:GetOutputPrimary R032 RANDR:RRGetProviders R033 RANDR:RRGetProviderInfo R034 RANDR:RRSetProviderOffloadSink R035 RANDR:RRSetProviderOutputSource R036 RANDR:RRListProviderProperties R037 RANDR:RRQueryProviderProperty R038 RANDR:RRConfigureProviderProperty R039 RANDR:RRChangeProviderProperty R040 RANDR:RRDeleteProviderProperty R041 RANDR:RRGetProviderProperty R042 RANDR:GetMonitors R043 RANDR:SetMonitor R044 RANDR:DeleteMonitor V000 RANDR:ScreenChangeNotify V001 RANDR:Notify E000 RANDR:BadRROutput E001 RANDR:BadRRCrtc E002 RANDR:BadRRMode E003 RANDR:BadRRProvider R000 RECORD:QueryVersion R001 RECORD:CreateContext R002 RECORD:RegisterClients R003 RECORD:UnregisterClients R004 RECORD:GetContext R005 RECORD:EnableContext R006 RECORD:DisableContext R007 RECORD:FreeContext E000 RECORD:BadContext R000 RENDER:QueryVersion R001 RENDER:QueryPictFormats R002 RENDER:QueryPictIndexValues R003 RENDER:QueryDithers R004 RENDER:CreatePicture R005 RENDER:ChangePicture R006 RENDER:SetPictureClipRectangles R007 RENDER:FreePicture R008 RENDER:Composite R009 RENDER:Scale R010 RENDER:Trapezoids R011 RENDER:Triangles R012 RENDER:TriStrip R013 RENDER:TriFan R014 RENDER:ColorTrapezoids R015 RENDER:ColorTriangles R016 RENDER:Transform R017 RENDER:CreateGlyphSet R018 RENDER:ReferenceGlyphSet R019 RENDER:FreeGlyphSet R020 RENDER:AddGlyphs R021 RENDER:AddGlyphsFromPicture R022 RENDER:FreeGlyphs R023 RENDER:CompositeGlyphs8 R024 RENDER:CompositeGlyphs16 R025 RENDER:CompositeGlyphs32 R026 RENDER:FillRectangles R027 RENDER:CreateCursor R028 RENDER:SetPictureTransform R029 RENDER:QueryFilters R030 RENDER:SetPictureFilter R031 RENDER:CreateAnimCursor R032 RENDER:AddTraps R033 RENDER:CreateSolidFill R034 RENDER:CreateLinearGradient R035 RENDER:CreateRadialGradient R036 RENDER:CreateConicalGradient E000 RENDER:BadPictFormat E001 RENDER:BadPicture E002 RENDER:BadPictOp E003 RENDER:BadGlyphSet E004 RENDER:BadGlyph R000 SECURITY:QueryVersion R001 SECURITY:GenerateAuthorization R002 SECURITY:RevokeAuthorization V000 SECURITY:AuthorizationRevoked E000 SECURITY:BadAuthorization E001 SECURITY:BadAuthorizationProtocol R000 SELinux:SELinuxQueryVersion R001 SELinux:SELinuxSetDeviceCreateContext R002 SELinux:SELinuxGetDeviceCreateContext R003 SELinux:SELinuxSetDeviceContext R004 SELinux:SELinuxGetDeviceContext R005 SELinux:SELinuxSetWindowCreateContext R006 SELinux:SELinuxGetWindowCreateContext R007 SELinux:SELinuxGetWindowContext R008 SELinux:SELinuxSetPropertyCreateContext R009 SELinux:SELinuxGetPropertyCreateContext R010 SELinux:SELinuxSetPropertyUseContext R011 SELinux:SELinuxGetPropertyUseContext R012 SELinux:SELinuxGetPropertyContext R013 SELinux:SELinuxGetPropertyDataContext R014 SELinux:SELinuxListProperties R015 SELinux:SELinuxSetSelectionCreateContext R016 SELinux:SELinuxGetSelectionCreateContext R017 SELinux:SELinuxSetSelectionUseContext R018 SELinux:SELinuxGetSelectionUseContext R019 SELinux:SELinuxGetSelectionContext R020 SELinux:SELinuxGetSelectionDataContext R021 SELinux:SELinuxListSelections R022 SELinux:SELinuxGetClientContext R000 SHAPE:QueryVersion R001 SHAPE:Rectangles R002 SHAPE:Mask R003 SHAPE:Combine R004 SHAPE:Offset R005 SHAPE:QueryExtents R006 SHAPE:SelectInput R007 SHAPE:InputSelected R008 SHAPE:GetRectangles V000 SHAPE:Notify R000 SYNC:Initialize R001 SYNC:ListSystemCounters R002 SYNC:CreateCounter R003 SYNC:SetCounter R004 SYNC:ChangeCounter R005 SYNC:QueryCounter R006 SYNC:DestroyCounter R007 SYNC:Await R008 SYNC:CreateAlarm R009 SYNC:ChangeAlarm R010 SYNC:QueryAlarm R011 SYNC:DestroyAlarm R012 SYNC:SetPriority R013 SYNC:GetPriority V000 SYNC:CounterNotify V001 SYNC:AlarmNotify E000 SYNC:BadCounter E001 SYNC:BadAlarm R000 TOG-CUP:QueryVersion R001 TOG-CUP:GetReservedColormapEntries R002 TOG-CUP:StoreColors R000 Windows-WM:QueryVersion R001 Windows-WM:FrameGetRect R002 Windows-WM:FrameDraw R003 Windows-WM:FrameSetTitle R004 Windows-WM:DisableUpdate R005 Windows-WM:ReenableUpdate R006 Windows-WM:SelectInput R007 Windows-WM:SetFrontProcess V000 Windows-WM:ControllerNotify V001 Windows-WM:ActivationNotify E000 Windows-WM:ClientNotLocal E001 Windows-WM:OperationNotSupported R000 X-Resource:QueryVersion R001 X-Resource:QueryClients R002 X-Resource:QueryClientResources R003 X-Resource:QueryClientPixmapBytes R001 X11:CreateWindow R002 X11:ChangeWindowAttributes R003 X11:GetWindowAttributes R004 X11:DestroyWindow R005 X11:DestroySubwindows R006 X11:ChangeSaveSet R007 X11:ReparentWindow R008 X11:MapWindow R009 X11:MapSubwindows R010 X11:UnmapWindow R011 X11:UnmapSubwindows R012 X11:ConfigureWindow R013 X11:CirculateWindow R014 X11:GetGeometry R015 X11:QueryTree R016 X11:InternAtom R017 X11:GetAtomName R018 X11:ChangeProperty R019 X11:DeleteProperty R020 X11:GetProperty R021 X11:ListProperties R022 X11:SetSelectionOwner R023 X11:GetSelectionOwner R024 X11:ConvertSelection R025 X11:SendEvent R026 X11:GrabPointer R027 X11:UngrabPointer R028 X11:GrabButton R029 X11:UngrabButton R030 X11:ChangeActivePointerGrab R031 X11:GrabKeyboard R032 X11:UngrabKeyboard R033 X11:GrabKey R034 X11:UngrabKey R035 X11:AllowEvents R036 X11:GrabServer R037 X11:UngrabServer R038 X11:QueryPointer R039 X11:GetMotionEvents R040 X11:TranslateCoords R041 X11:WarpPointer R042 X11:SetInputFocus R043 X11:GetInputFocus R044 X11:QueryKeymap R045 X11:OpenFont R046 X11:CloseFont R047 X11:QueryFont R048 X11:QueryTextExtents R049 X11:ListFonts R050 X11:ListFontsWithInfo R051 X11:SetFontPath R052 X11:GetFontPath R053 X11:CreatePixmap R054 X11:FreePixmap R055 X11:CreateGC R056 X11:ChangeGC R057 X11:CopyGC R058 X11:SetDashes R059 X11:SetClipRectangles R060 X11:FreeGC R061 X11:ClearArea R062 X11:CopyArea R063 X11:CopyPlane R064 X11:PolyPoint R065 X11:PolyLine R066 X11:PolySegment R067 X11:PolyRectangle R068 X11:PolyArc R069 X11:FillPoly R070 X11:PolyFillRectangle R071 X11:PolyFillArc R072 X11:PutImage R073 X11:GetImage R074 X11:PolyText8 R075 X11:PolyText16 R076 X11:ImageText8 R077 X11:ImageText16 R078 X11:CreateColormap R079 X11:FreeColormap R080 X11:CopyColormapAndFree R081 X11:InstallColormap R082 X11:UninstallColormap R083 X11:ListInstalledColormaps R084 X11:AllocColor R085 X11:AllocNamedColor R086 X11:AllocColorCells R087 X11:AllocColorPlanes R088 X11:FreeColors R089 X11:StoreColors R090 X11:StoreNamedColor R091 X11:QueryColors R092 X11:LookupColor R093 X11:CreateCursor R094 X11:CreateGlyphCursor R095 X11:FreeCursor R096 X11:RecolorCursor R097 X11:QueryBestSize R098 X11:QueryExtension R099 X11:ListExtensions R100 X11:ChangeKeyboardMapping R101 X11:GetKeyboardMapping R102 X11:ChangeKeyboardControl R103 X11:GetKeyboardControl R104 X11:Bell R105 X11:ChangePointerControl R106 X11:GetPointerControl R107 X11:SetScreenSaver R108 X11:GetScreenSaver R109 X11:ChangeHosts R110 X11:ListHosts R111 X11:SetAccessControl R112 X11:SetCloseDownMode R113 X11:KillClient R114 X11:RotateProperties R115 X11:ForceScreenSaver R116 X11:SetPointerMapping R117 X11:GetPointerMapping R118 X11:SetModifierMapping R119 X11:GetModifierMapping R127 X11:NoOperation V000 X11:X_Error V001 X11:X_Reply V002 X11:KeyPress V003 X11:KeyRelease V004 X11:ButtonPress V005 X11:ButtonRelease V006 X11:MotionNotify V007 X11:EnterNotify V008 X11:LeaveNotify V009 X11:FocusIn V010 X11:FocusOut V011 X11:KeymapNotify V012 X11:Expose V013 X11:GraphicsExpose V014 X11:NoExpose V015 X11:VisibilityNotify V016 X11:CreateNotify V017 X11:DestroyNotify V018 X11:UnmapNotify V019 X11:MapNotify V020 X11:MapRequest V021 X11:ReparentNotify V022 X11:ConfigureNotify V023 X11:ConfigureRequest V024 X11:GravityNotify V025 X11:ResizeRequest V026 X11:CirculateNotify V027 X11:CirculateRequest V028 X11:PropertyNotify V029 X11:SelectionClear V030 X11:SelectionRequest V031 X11:SelectionNotify V032 X11:ColormapNotify V033 X11:ClientMessage V034 X11:MappingNotify V035 X11:GenericEvent E000 X11:Success E001 X11:BadRequest E002 X11:BadValue E003 X11:BadWindow E004 X11:BadPixmap E005 X11:BadAtom E006 X11:BadCursor E007 X11:BadFont E008 X11:BadMatch E009 X11:BadDrawable E010 X11:BadAccess E011 X11:BadAlloc E012 X11:BadColor E013 X11:BadGC E014 X11:BadIDChoice E015 X11:BadName E016 X11:BadLength E017 X11:BadImplementation R000 XC-APPGROUP:QueryVersion R001 XC-APPGROUP:Create R002 XC-APPGROUP:Destroy R003 XC-APPGROUP:GetAttr R004 XC-APPGROUP:Query R005 XC-APPGROUP:CreateAssoc R006 XC-APPGROUP:DestroyAssoc E000 XC-APPGROUP:BadAppGroup R000 XC-MISC:GetVersion R001 XC-MISC:GetXIDRange R002 XC-MISC:GetXIDList R000 XFIXES:QueryVersion R001 XFIXES:ChangeSaveSet R002 XFIXES:SelectSelectionInput R003 XFIXES:SelectCursorInput R004 XFIXES:GetCursorImage R005 XFIXES:CreateRegion R006 XFIXES:CreateRegionFromBitmap R007 XFIXES:CreateRegionFromWindow R008 XFIXES:CreateRegionFromGC R009 XFIXES:CreateRegionFromPicture R010 XFIXES:DestroyRegion R011 XFIXES:SetRegion R012 XFIXES:CopyRegion R013 XFIXES:UnionRegion R014 XFIXES:IntersectRegion R015 XFIXES:SubtractRegion R016 XFIXES:InvertRegion R017 XFIXES:TranslateRegion R018 XFIXES:RegionExtents R019 XFIXES:FetchRegion R020 XFIXES:SetGCClipRegion R021 XFIXES:SetWindowShapeRegion R022 XFIXES:SetPictureClipRegion R023 XFIXES:SetCursorName R024 XFIXES:GetCursorName R025 XFIXES:GetCursorImageAndName R026 XFIXES:ChangeCursor R027 XFIXES:ChangeCursorByName R028 XFIXES:ExpandRegion R029 XFIXES:HideCursor R030 XFIXES:ShowCursor V000 XFIXES:SelectionNotify V001 XFIXES:CursorNotify E000 XFIXES:BadRegion R000 XFree86-Bigfont:QueryVersion R001 XFree86-Bigfont:QueryFont R000 XFree86-DGA:QueryVersion R001 XFree86-DGA:GetVideoLL R002 XFree86-DGA:DirectVideo R003 XFree86-DGA:GetViewPortSize R004 XFree86-DGA:SetViewPort R005 XFree86-DGA:GetVidPage R006 XFree86-DGA:SetVidPage R007 XFree86-DGA:InstallColormap R008 XFree86-DGA:QueryDirectVideo R009 XFree86-DGA:ViewPortChanged R010 XFree86-DGA:Obsolete1 R011 XFree86-DGA:Obsolete2 R012 XFree86-DGA:QueryModes R013 XFree86-DGA:SetMode R014 XFree86-DGA:SetViewport R015 XFree86-DGA:InstallColormap R016 XFree86-DGA:SelectInput R017 XFree86-DGA:FillRectangle R018 XFree86-DGA:CopyArea R019 XFree86-DGA:CopyTransparentArea R020 XFree86-DGA:GetViewportStatus R021 XFree86-DGA:Sync R022 XFree86-DGA:OpenFramebuffer R023 XFree86-DGA:CloseFramebuffer R024 XFree86-DGA:SetClientVersion R025 XFree86-DGA:ChangePixmapMode R026 XFree86-DGA:CreateColormap E000 XFree86-DGA:ClientNotLocal E001 XFree86-DGA:NoDirectVideoMode E002 XFree86-DGA:ScreenNotActive E003 XFree86-DGA:DirectNotActivated E004 XFree86-DGA:OperationNotSupported R000 XFree86-DRI:QueryVersion R001 XFree86-DRI:QueryDirectRenderingCapable R002 XFree86-DRI:OpenConnection R003 XFree86-DRI:CloseConnection R004 XFree86-DRI:GetClientDriverName R005 XFree86-DRI:CreateContext R006 XFree86-DRI:DestroyContext R007 XFree86-DRI:CreateDrawable R008 XFree86-DRI:DestroyDrawable R009 XFree86-DRI:GetDrawableInfo R010 XFree86-DRI:GetDeviceInfo R011 XFree86-DRI:AuthConnection R012 XFree86-DRI:OpenFullScreen R013 XFree86-DRI:CloseFullScreen E000 XFree86-DRI:ClientNotLocal E001 XFree86-DRI:OperationNotSupported R000 XFree86-Misc:QueryVersion R001 XFree86-Misc:GetSaver R002 XFree86-Misc:SetSaver R003 XFree86-Misc:GetMouseSettings R004 XFree86-Misc:GetKbdSettings R005 XFree86-Misc:SetMouseSettings R006 XFree86-Misc:SetKbdSettings R007 XFree86-Misc:SetGrabKeysState R008 XFree86-Misc:SetClientVersion R009 XFree86-Misc:GetFilePaths R010 XFree86-Misc:PassMessage E000 XFree86-Misc:BadMouseProtocol E001 XFree86-Misc:BadMouseBaudRate E002 XFree86-Misc:BadMouseFlags E003 XFree86-Misc:BadMouseCombo E004 XFree86-Misc:BadKbdType E005 XFree86-Misc:ModInDevDisabled E006 XFree86-Misc:ModInDevClientNotLocal E007 XFree86-Misc:NoModule R000 XFree86-VidModeExtension:QueryVersion R001 XFree86-VidModeExtension:GetModeLine R002 XFree86-VidModeExtension:ModModeLine R003 XFree86-VidModeExtension:SwitchMode R004 XFree86-VidModeExtension:GetMonitor R005 XFree86-VidModeExtension:LockModeSwitch R006 XFree86-VidModeExtension:GetAllModeLines R007 XFree86-VidModeExtension:AddModeLine R008 XFree86-VidModeExtension:DeleteModeLine R009 XFree86-VidModeExtension:ValidateModeLine R010 XFree86-VidModeExtension:SwitchToMode R011 XFree86-VidModeExtension:GetViewPort R012 XFree86-VidModeExtension:SetViewPort R013 XFree86-VidModeExtension:GetDotClocks R014 XFree86-VidModeExtension:SetClientVersion R015 XFree86-VidModeExtension:SetGamma R016 XFree86-VidModeExtension:GetGamma R017 XFree86-VidModeExtension:GetGammaRamp R018 XFree86-VidModeExtension:SetGammaRamp R019 XFree86-VidModeExtension:GetGammaRampSize R020 XFree86-VidModeExtension:GetPermissions V000 XFree86-VidModeExtension:Notify E000 XFree86-VidModeExtension:BadClock E001 XFree86-VidModeExtension:BadHTimings E002 XFree86-VidModeExtension:BadVTimings E003 XFree86-VidModeExtension:ModeUnsuitable E004 XFree86-VidModeExtension:ExtensionDisabled E005 XFree86-VidModeExtension:ClientNotLocal E006 XFree86-VidModeExtension:ZoomLocked R000 XINERAMA:QueryVersion R001 XINERAMA:GetState R002 XINERAMA:GetScreenCount R003 XINERAMA:GetScreenSize R004 XINERAMA:IsActive R005 XINERAMA:QueryScreens R001 XInputExtension:GetExtensionVersion R002 XInputExtension:ListInputDevices R003 XInputExtension:OpenDevice R004 XInputExtension:CloseDevice R005 XInputExtension:SetDeviceMode R006 XInputExtension:SelectExtensionEvent R007 XInputExtension:GetSelectedExtensionEvents R008 XInputExtension:ChangeDeviceDontPropagateList R009 XInputExtension:GetDeviceDontPropagageList R010 XInputExtension:GetDeviceMotionEvents R011 XInputExtension:ChangeKeyboardDevice R012 XInputExtension:ChangePointerDevice R013 XInputExtension:GrabDevice R014 XInputExtension:UngrabDevice R015 XInputExtension:GrabDeviceKey R016 XInputExtension:UngrabDeviceKey R017 XInputExtension:GrabDeviceButton R018 XInputExtension:UngrabDeviceButton R019 XInputExtension:AllowDeviceEvents R020 XInputExtension:GetDeviceFocus R021 XInputExtension:SetDeviceFocus R022 XInputExtension:GetFeedbackControl R023 XInputExtension:ChangeFeedbackControl R024 XInputExtension:GetDeviceKeyMapping R025 XInputExtension:ChangeDeviceKeyMapping R026 XInputExtension:GetDeviceModifierMapping R027 XInputExtension:SetDeviceModifierMapping R028 XInputExtension:GetDeviceButtonMapping R029 XInputExtension:SetDeviceButtonMapping R030 XInputExtension:QueryDeviceState R031 XInputExtension:SendExtensionEvent R032 XInputExtension:DeviceBell R033 XInputExtension:SetDeviceValuators R034 XInputExtension:GetDeviceControl R035 XInputExtension:ChangeDeviceControl R036 XInputExtension:ListDeviceProperties R037 XInputExtension:ChangeDeviceProperty R038 XInputExtension:DeleteDeviceProperty R039 XInputExtension:GetDeviceProperty R040 XInputExtension:QueryPointer R041 XInputExtension:WarpPointer R042 XInputExtension:ChangeCursor R043 XInputExtension:ChangeHierarchy R044 XInputExtension:SetClientPointer R045 XInputExtension:GetClientPointer R046 XInputExtension:SelectEvents R047 XInputExtension:QueryVersion R048 XInputExtension:QueryDevice R049 XInputExtension:SetFocus R050 XInputExtension:GetFocus R051 XInputExtension:GrabDevice R052 XInputExtension:UngrabDevice R053 XInputExtension:AllowEvents R054 XInputExtension:PassiveGrabDevice R055 XInputExtension:PassiveUngrabDevice R056 XInputExtension:ListProperties R057 XInputExtension:ChangeProperty R058 XInputExtension:DeleteProperty R059 XInputExtension:GetProperty R060 XInputExtension:GetSelectedEvents V000 XInputExtension:DeviceValuator V001 XInputExtension:DeviceKeyPress V002 XInputExtension:DeviceKeyRelease V003 XInputExtension:DeviceButtonPress V004 XInputExtension:DeviceButtonRelease V005 XInputExtension:DeviceMotionNotify V006 XInputExtension:DeviceFocusIn V007 XInputExtension:DeviceFocusOut V008 XInputExtension:ProximityIn V009 XInputExtension:ProximityOut V010 XInputExtension:DeviceStateNotify V011 XInputExtension:DeviceMappingNotify V012 XInputExtension:ChangeDeviceNotify V013 XInputExtension:DeviceKeystateNotify V014 XInputExtension:DeviceButtonstateNotify V015 XInputExtension:DevicePresenceNotify V016 XInputExtension:DevicePropertyNotify E000 XInputExtension:BadDevice E001 XInputExtension:BadEvent E002 XInputExtension:BadMode E003 XInputExtension:DeviceBusy E004 XInputExtension:BadClass R000 XKEYBOARD:UseExtension R001 XKEYBOARD:SelectEvents R002 XKEYBOARD:Obsolete R003 XKEYBOARD:Bell R004 XKEYBOARD:GetState R005 XKEYBOARD:LatchLockState R006 XKEYBOARD:GetControls R007 XKEYBOARD:SetControls R008 XKEYBOARD:GetMap R009 XKEYBOARD:SetMap R010 XKEYBOARD:GetCompatMap R011 XKEYBOARD:SetCompatMap R012 XKEYBOARD:GetIndicatorState R013 XKEYBOARD:GetIndicatorMap R014 XKEYBOARD:SetIndicatorMap R015 XKEYBOARD:GetNamedIndicator R016 XKEYBOARD:SetNamedIndicator R017 XKEYBOARD:GetNames R018 XKEYBOARD:SetNames R019 XKEYBOARD:GetGeometry R020 XKEYBOARD:SetGeometry R021 XKEYBOARD:PerClientFlags R022 XKEYBOARD:ListComponents R023 XKEYBOARD:GetKbdByName R024 XKEYBOARD:GetDeviceInfo R025 XKEYBOARD:SetDeviceInfo R101 XKEYBOARD:SetDebuggingFlags V000 XKEYBOARD:EventCode E000 XKEYBOARD:BadKeyboard R000 XTEST:GetVersion R001 XTEST:CompareCursor R002 XTEST:FakeInput R003 XTEST:GrabControl R000 XVideo:QueryExtension R001 XVideo:QueryAdaptors R002 XVideo:QueryEncodings R003 XVideo:GrabPort R004 XVideo:UngrabPort R005 XVideo:PutVideo R006 XVideo:PutStill R007 XVideo:GetVideo R008 XVideo:GetStill R009 XVideo:StopVideo R010 XVideo:SelectVideoNotify R011 XVideo:SelectPortNotify R012 XVideo:QueryBestSize R013 XVideo:SetPortAttribute R014 XVideo:GetPortAttribute R015 XVideo:QueryPortAttributes R016 XVideo:ListImageFormats R017 XVideo:QueryImageAttributes R018 XVideo:PutImage R019 XVideo:ShmPutImage V000 XVideo:VideoNotify V001 XVideo:PortNotify E000 XVideo:BadPort E001 XVideo:BadEncoding E002 XVideo:BadControl R000 XVideo-MotionCompensation:QueryVersion R001 XVideo-MotionCompensation:ListSurfaceTypes R002 XVideo-MotionCompensation:CreateContext R003 XVideo-MotionCompensation:DestroyContext R004 XVideo-MotionCompensation:CreateSurface R005 XVideo-MotionCompensation:DestroySurface R006 XVideo-MotionCompensation:CreateSubpicture R007 XVideo-MotionCompensation:DestroySubpicture R008 XVideo-MotionCompensation:ListSubpictureTypes R009 XVideo-MotionCompensation:GetDRInfo E000 XVideo-MotionCompensation:BadContext E001 XVideo-MotionCompensation:BadSurface E002 XVideo-MotionCompensation:BadSubpicture xorg-server-1.20.13/dix/Makefile.in0000644000175000017500000011173114100573775013730 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @SPECIAL_DTRACE_OBJECTS_TRUE@noinst_PROGRAMS = dix.O$(EXEEXT) subdir = dix ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_miscconfig_DATA) \ $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) LTLIBRARIES = $(noinst_LTLIBRARIES) libdix_la_LIBADD = am_libdix_la_OBJECTS = atom.lo colormap.lo cursor.lo devices.lo \ dispatch.lo dixfonts.lo main.lo dixutils.lo enterleave.lo \ events.lo eventconvert.lo extension.lo gc.lo getevents.lo \ globals.lo glyphcurs.lo grabs.lo initatoms.lo inpututils.lo \ pixmap.lo privates.lo property.lo ptrveloc.lo region.lo \ registry.lo resource.lo selection.lo swaprep.lo swapreq.lo \ tables.lo touch.lo window.lo libdix_la_OBJECTS = $(am_libdix_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libmain_la_LIBADD = am_libmain_la_OBJECTS = stubmain.lo libmain_la_OBJECTS = $(am_libmain_la_OBJECTS) am_dix_O_OBJECTS = dix_O_OBJECTS = $(am_dix_O_OBJECTS) dix_O_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/atom.Plo ./$(DEPDIR)/colormap.Plo \ ./$(DEPDIR)/cursor.Plo ./$(DEPDIR)/devices.Plo \ ./$(DEPDIR)/dispatch.Plo ./$(DEPDIR)/dixfonts.Plo \ ./$(DEPDIR)/dixutils.Plo ./$(DEPDIR)/enterleave.Plo \ ./$(DEPDIR)/eventconvert.Plo ./$(DEPDIR)/events.Plo \ ./$(DEPDIR)/extension.Plo ./$(DEPDIR)/gc.Plo \ ./$(DEPDIR)/getevents.Plo ./$(DEPDIR)/globals.Plo \ ./$(DEPDIR)/glyphcurs.Plo ./$(DEPDIR)/grabs.Plo \ ./$(DEPDIR)/initatoms.Plo ./$(DEPDIR)/inpututils.Plo \ ./$(DEPDIR)/main.Plo ./$(DEPDIR)/pixmap.Plo \ ./$(DEPDIR)/privates.Plo ./$(DEPDIR)/property.Plo \ ./$(DEPDIR)/ptrveloc.Plo ./$(DEPDIR)/region.Plo \ ./$(DEPDIR)/registry.Plo ./$(DEPDIR)/resource.Plo \ ./$(DEPDIR)/selection.Plo ./$(DEPDIR)/stubmain.Plo \ ./$(DEPDIR)/swaprep.Plo ./$(DEPDIR)/swapreq.Plo \ ./$(DEPDIR)/tables.Plo ./$(DEPDIR)/touch.Plo \ ./$(DEPDIR)/window.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libdix_la_SOURCES) $(libmain_la_SOURCES) $(dix_O_SOURCES) DIST_SOURCES = $(libdix_la_SOURCES) $(libmain_la_SOURCES) \ $(dix_O_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(miscconfigdir)" DATA = $(dist_miscconfig_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libdix.la libmain.la AM_CPPFLAGS = -I$(top_srcdir)/include AM_CFLAGS = $(DIX_CFLAGS) libmain_la_SOURCES = \ stubmain.c libdix_la_SOURCES = \ atom.c \ colormap.c \ cursor.c \ devices.c \ dispatch.c \ dispatch.h \ dixfonts.c \ main.c \ dixutils.c \ enterleave.c \ enterleave.h \ events.c \ eventconvert.c \ extension.c \ gc.c \ getevents.c \ globals.c \ glyphcurs.c \ grabs.c \ initatoms.c \ inpututils.c \ pixmap.c \ privates.c \ property.c \ ptrveloc.c \ region.c \ registry.c \ resource.c \ selection.c \ swaprep.c \ swapreq.c \ tables.c \ touch.c \ window.c EXTRA_DIST = buildatoms BuiltInAtoms Xserver.d Xserver-dtrace.h.in # Install list of protocol names miscconfigdir = $(SERVER_MISC_CONFIG_PATH) dist_miscconfig_DATA = protocol.txt # Generate dtrace header file for C sources to include @XSERVER_DTRACE_TRUE@BUILT_SOURCES = Xserver-dtrace.h @SPECIAL_DTRACE_OBJECTS_TRUE@dix_O_SOURCES = CLEANFILES = Xserver-dtrace.h all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign dix/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign dix/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libdix.la: $(libdix_la_OBJECTS) $(libdix_la_DEPENDENCIES) $(EXTRA_libdix_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libdix_la_OBJECTS) $(libdix_la_LIBADD) $(LIBS) libmain.la: $(libmain_la_OBJECTS) $(libmain_la_DEPENDENCIES) $(EXTRA_libmain_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libmain_la_OBJECTS) $(libmain_la_LIBADD) $(LIBS) @SPECIAL_DTRACE_OBJECTS_FALSE@dix.O$(EXEEXT): $(dix_O_OBJECTS) $(dix_O_DEPENDENCIES) $(EXTRA_dix_O_DEPENDENCIES) @SPECIAL_DTRACE_OBJECTS_FALSE@ @rm -f dix.O$(EXEEXT) @SPECIAL_DTRACE_OBJECTS_FALSE@ $(AM_V_CCLD)$(LINK) $(dix_O_OBJECTS) $(dix_O_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/colormap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cursor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devices.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dispatch.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dixfonts.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dixutils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enterleave.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventconvert.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/events.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extension.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getevents.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globals.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glyphcurs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grabs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initatoms.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inpututils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixmap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/privates.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/property.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptrveloc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/region.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/registry.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resource.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selection.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stubmain.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swaprep.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swapreq.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tables.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/touch.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_miscconfigDATA: $(dist_miscconfig_DATA) @$(NORMAL_INSTALL) @list='$(dist_miscconfig_DATA)'; test -n "$(miscconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(miscconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(miscconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(miscconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(miscconfigdir)" || exit $$?; \ done uninstall-dist_miscconfigDATA: @$(NORMAL_UNINSTALL) @list='$(dist_miscconfig_DATA)'; test -n "$(miscconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(miscconfigdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(DATA) installdirs: for dir in "$(DESTDIR)$(miscconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) 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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/atom.Plo -rm -f ./$(DEPDIR)/colormap.Plo -rm -f ./$(DEPDIR)/cursor.Plo -rm -f ./$(DEPDIR)/devices.Plo -rm -f ./$(DEPDIR)/dispatch.Plo -rm -f ./$(DEPDIR)/dixfonts.Plo -rm -f ./$(DEPDIR)/dixutils.Plo -rm -f ./$(DEPDIR)/enterleave.Plo -rm -f ./$(DEPDIR)/eventconvert.Plo -rm -f ./$(DEPDIR)/events.Plo -rm -f ./$(DEPDIR)/extension.Plo -rm -f ./$(DEPDIR)/gc.Plo -rm -f ./$(DEPDIR)/getevents.Plo -rm -f ./$(DEPDIR)/globals.Plo -rm -f ./$(DEPDIR)/glyphcurs.Plo -rm -f ./$(DEPDIR)/grabs.Plo -rm -f ./$(DEPDIR)/initatoms.Plo -rm -f ./$(DEPDIR)/inpututils.Plo -rm -f ./$(DEPDIR)/main.Plo -rm -f ./$(DEPDIR)/pixmap.Plo -rm -f ./$(DEPDIR)/privates.Plo -rm -f ./$(DEPDIR)/property.Plo -rm -f ./$(DEPDIR)/ptrveloc.Plo -rm -f ./$(DEPDIR)/region.Plo -rm -f ./$(DEPDIR)/registry.Plo -rm -f ./$(DEPDIR)/resource.Plo -rm -f ./$(DEPDIR)/selection.Plo -rm -f ./$(DEPDIR)/stubmain.Plo -rm -f ./$(DEPDIR)/swaprep.Plo -rm -f ./$(DEPDIR)/swapreq.Plo -rm -f ./$(DEPDIR)/tables.Plo -rm -f ./$(DEPDIR)/touch.Plo -rm -f ./$(DEPDIR)/window.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_miscconfigDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/atom.Plo -rm -f ./$(DEPDIR)/colormap.Plo -rm -f ./$(DEPDIR)/cursor.Plo -rm -f ./$(DEPDIR)/devices.Plo -rm -f ./$(DEPDIR)/dispatch.Plo -rm -f ./$(DEPDIR)/dixfonts.Plo -rm -f ./$(DEPDIR)/dixutils.Plo -rm -f ./$(DEPDIR)/enterleave.Plo -rm -f ./$(DEPDIR)/eventconvert.Plo -rm -f ./$(DEPDIR)/events.Plo -rm -f ./$(DEPDIR)/extension.Plo -rm -f ./$(DEPDIR)/gc.Plo -rm -f ./$(DEPDIR)/getevents.Plo -rm -f ./$(DEPDIR)/globals.Plo -rm -f ./$(DEPDIR)/glyphcurs.Plo -rm -f ./$(DEPDIR)/grabs.Plo -rm -f ./$(DEPDIR)/initatoms.Plo -rm -f ./$(DEPDIR)/inpututils.Plo -rm -f ./$(DEPDIR)/main.Plo -rm -f ./$(DEPDIR)/pixmap.Plo -rm -f ./$(DEPDIR)/privates.Plo -rm -f ./$(DEPDIR)/property.Plo -rm -f ./$(DEPDIR)/ptrveloc.Plo -rm -f ./$(DEPDIR)/region.Plo -rm -f ./$(DEPDIR)/registry.Plo -rm -f ./$(DEPDIR)/resource.Plo -rm -f ./$(DEPDIR)/selection.Plo -rm -f ./$(DEPDIR)/stubmain.Plo -rm -f ./$(DEPDIR)/swaprep.Plo -rm -f ./$(DEPDIR)/swapreq.Plo -rm -f ./$(DEPDIR)/tables.Plo -rm -f ./$(DEPDIR)/touch.Plo -rm -f ./$(DEPDIR)/window.Plo -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-dist_miscconfigDATA .MAKE: all check install install-am install-exec install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS cscopelist-am ctags ctags-am 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-dist_miscconfigDATA install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am \ uninstall-dist_miscconfigDATA .PRECIOUS: Makefile @XSERVER_DTRACE_TRUE@Xserver-dtrace.h: $(srcdir)/Xserver.d @XSERVER_DTRACE_TRUE@ $(AM_V_GEN)$(DTRACE) -C -h -o $@ -s $(srcdir)/Xserver.d \ @XSERVER_DTRACE_TRUE@ || cp Xserver-dtrace.h.in $@ # Generate dtrace object code for probes in libdix @SPECIAL_DTRACE_OBJECTS_TRUE@dtrace-dix.o: $(top_srcdir)/dix/Xserver.d libdix.la @SPECIAL_DTRACE_OBJECTS_TRUE@ $(AM_V_GEN)$(DTRACE) -G -C -o $@ -s $(top_srcdir)/dix/Xserver.d $(am_libdix_la_OBJECTS:%.lo=.libs/%.o) @SPECIAL_DTRACE_OBJECTS_TRUE@dix.O: dtrace-dix.o libdix.la @SPECIAL_DTRACE_OBJECTS_TRUE@ $(AM_V_GEN)ld -r -o $@ $(am_libdix_la_OBJECTS:%.lo=.libs/%.o) # 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: xorg-server-1.20.13/dix/atom.c0000644000175000017500000001337514100573755012772 00000000000000/*********************************************************** Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include #include #include #include "misc.h" #include "resource.h" #include "dix.h" #define InitialTableSize 256 typedef struct _Node { struct _Node *left, *right; Atom a; unsigned int fingerPrint; const char *string; } NodeRec, *NodePtr; static Atom lastAtom = None; static NodePtr atomRoot = NULL; static unsigned long tableLength; static NodePtr *nodeTable; Atom MakeAtom(const char *string, unsigned len, Bool makeit) { NodePtr *np; unsigned i; int comp; unsigned int fp = 0; np = &atomRoot; for (i = 0; i < (len + 1) / 2; i++) { fp = fp * 27 + string[i]; fp = fp * 27 + string[len - 1 - i]; } while (*np != NULL) { if (fp < (*np)->fingerPrint) np = &((*np)->left); else if (fp > (*np)->fingerPrint) np = &((*np)->right); else { /* now start testing the strings */ comp = strncmp(string, (*np)->string, (int) len); if ((comp < 0) || ((comp == 0) && (len < strlen((*np)->string)))) np = &((*np)->left); else if (comp > 0) np = &((*np)->right); else return (*np)->a; } } if (makeit) { NodePtr nd; nd = malloc(sizeof(NodeRec)); if (!nd) return BAD_RESOURCE; if (lastAtom < XA_LAST_PREDEFINED) { nd->string = string; } else { nd->string = strndup(string, len); if (!nd->string) { free(nd); return BAD_RESOURCE; } } if ((lastAtom + 1) >= tableLength) { NodePtr *table; table = reallocarray(nodeTable, tableLength, 2 * sizeof(NodePtr)); if (!table) { if (nd->string != string) { /* nd->string has been strdup'ed */ free((char *) nd->string); } free(nd); return BAD_RESOURCE; } tableLength <<= 1; nodeTable = table; } *np = nd; nd->left = nd->right = NULL; nd->fingerPrint = fp; nd->a = ++lastAtom; nodeTable[lastAtom] = nd; return nd->a; } else return None; } Bool ValidAtom(Atom atom) { return (atom != None) && (atom <= lastAtom); } const char * NameForAtom(Atom atom) { NodePtr node; if (atom > lastAtom) return 0; if ((node = nodeTable[atom]) == NULL) return 0; return node->string; } void AtomError(void) { FatalError("initializing atoms"); } static void FreeAtom(NodePtr patom) { if (patom->left) FreeAtom(patom->left); if (patom->right) FreeAtom(patom->right); if (patom->a > XA_LAST_PREDEFINED) { /* * All strings above XA_LAST_PREDEFINED are strdup'ed, so it's safe to * cast here */ free((char *) patom->string); } free(patom); } void FreeAllAtoms(void) { if (atomRoot == NULL) return; FreeAtom(atomRoot); atomRoot = NULL; free(nodeTable); nodeTable = NULL; lastAtom = None; } void InitAtoms(void) { FreeAllAtoms(); tableLength = InitialTableSize; nodeTable = xallocarray(InitialTableSize, sizeof(NodePtr)); if (!nodeTable) AtomError(); nodeTable[None] = NULL; MakePredeclaredAtoms(); if (lastAtom != XA_LAST_PREDEFINED) AtomError(); } xorg-server-1.20.13/dix/colormap.c0000644000175000017500000024653514100573755013654 00000000000000/*********************************************************** Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include #include #include #include #include "misc.h" #include "dix.h" #include "dixstruct.h" #include "colormapst.h" #include "os.h" #include "scrnintstr.h" #include "resource.h" #include "windowstr.h" #include "privates.h" #include "xace.h" typedef int (*ColorCompareProcPtr) (EntryPtr /*pent */ , xrgb * /*prgb */ ); static Pixel FindBestPixel(EntryPtr /*pentFirst */ , int /*size */ , xrgb * /*prgb */ , int /*channel */ ); static int AllComp(EntryPtr /*pent */ , xrgb * /*prgb */ ); static int RedComp(EntryPtr /*pent */ , xrgb * /*prgb */ ); static int GreenComp(EntryPtr /*pent */ , xrgb * /*prgb */ ); static int BlueComp(EntryPtr /*pent */ , xrgb * /*prgb */ ); static void FreePixels(ColormapPtr /*pmap */ , int /*client */ ); static void CopyFree(int /*channel */ , int /*client */ , ColormapPtr /*pmapSrc */ , ColormapPtr /*pmapDst */ ); static void FreeCell(ColormapPtr /*pmap */ , Pixel /*i */ , int /*channel */ ); static void UpdateColors(ColormapPtr /*pmap */ ); static int AllocDirect(int /*client */ , ColormapPtr /*pmap */ , int /*c */ , int /*r */ , int /*g */ , int /*b */ , Bool /*contig */ , Pixel * /*pixels */ , Pixel * /*prmask */ , Pixel * /*pgmask */ , Pixel * /*pbmask */ ); static int AllocPseudo(int /*client */ , ColormapPtr /*pmap */ , int /*c */ , int /*r */ , Bool /*contig */ , Pixel * /*pixels */ , Pixel * /*pmask */ , Pixel ** /*pppixFirst */ ); static Bool AllocCP(ColormapPtr /*pmap */ , EntryPtr /*pentFirst */ , int /*count */ , int /*planes */ , Bool /*contig */ , Pixel * /*pixels */ , Pixel * /*pMask */ ); static Bool AllocShared(ColormapPtr /*pmap */ , Pixel * /*ppix */ , int /*c */ , int /*r */ , int /*g */ , int /*b */ , Pixel /*rmask */ , Pixel /*gmask */ , Pixel /*bmask */ , Pixel * /*ppixFirst */ ); static int FreeCo(ColormapPtr /*pmap */ , int /*client */ , int /*color */ , int /*npixIn */ , Pixel * /*ppixIn */ , Pixel /*mask */ ); static int TellNoMap(WindowPtr /*pwin */ , Colormap * /*pmid */ ); static void FindColorInRootCmap(ColormapPtr /* pmap */ , EntryPtr /* pentFirst */ , int /* size */ , xrgb * /* prgb */ , Pixel * /* pPixel */ , int /* channel */ , ColorCompareProcPtr /* comp */ ); #define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1) #define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1) #define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1) #if COMPOSITE #define ALPHAMASK(vis) ((vis)->nplanes < 32 ? 0 : \ (CARD32) ~((vis)->redMask|(vis)->greenMask|(vis)->blueMask)) #else #define ALPHAMASK(vis) 0 #endif #define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis)) /* GetNextBitsOrBreak(bits, mask, base) -- * (Suggestion: First read the macro, then read this explanation. * * Either generate the next value to OR in to a pixel or break out of this * while loop * * This macro is used when we're trying to generate all 2^n combinations of * bits in mask. What we're doing here is counting in binary, except that * the bits we use to count may not be contiguous. This macro will be * called 2^n times, returning a different value in bits each time. Then * it will cause us to break out of a surrounding loop. (It will always be * called from within a while loop.) * On call: mask is the value we want to find all the combinations for * base has 1 bit set where the least significant bit of mask is set * * For example,if mask is 01010, base should be 0010 and we count like this: * 00010 (see this isn't so hard), * then we add base to bits and get 0100. (bits & ~mask) is (0100 & 0100) so * we add that to bits getting (0100 + 0100) = * 01000 for our next value. * then we add 0010 to get * 01010 and we're done (easy as 1, 2, 3) */ #define GetNextBitsOrBreak(bits, mask, base) \ if((bits) == (mask)) \ break; \ (bits) += (base); \ while((bits) & ~(mask)) \ (bits) += ((bits) & ~(mask)); /* ID of server as client */ #define SERVER_ID 0 typedef struct _colorResource { Colormap mid; int client; } colorResource; /* Invariants: * refcnt == 0 means entry is empty * refcnt > 0 means entry is useable by many clients, so it can't be changed * refcnt == AllocPrivate means entry owned by one client only * fShared should only be set if refcnt == AllocPrivate, and only in red map */ /** * Create and initialize the color map * * \param mid resource to use for this colormap * \param alloc 1 iff all entries are allocated writable */ int CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, ColormapPtr *ppcmap, int alloc, int client) { int class, size; unsigned long sizebytes; ColormapPtr pmap; EntryPtr pent; int i; Pixel *ppix, **pptr; class = pVisual->class; if (!(class & DynamicClass) && (alloc != AllocNone) && (client != SERVER_ID)) return BadMatch; size = pVisual->ColormapEntries; sizebytes = (size * sizeof(Entry)) + (LimitClients * sizeof(Pixel *)) + (LimitClients * sizeof(int)); if ((class | DynamicClass) == DirectColor) sizebytes *= 3; sizebytes += sizeof(ColormapRec); if (mid == pScreen->defColormap) { pmap = malloc(sizebytes); if (!pmap) return BadAlloc; if (!dixAllocatePrivates(&pmap->devPrivates, PRIVATE_COLORMAP)) { free(pmap); return BadAlloc; } } else { pmap = _dixAllocateObjectWithPrivates(sizebytes, sizebytes, offsetof(ColormapRec, devPrivates), PRIVATE_COLORMAP); if (!pmap) return BadAlloc; } pmap->red = (EntryPtr) ((char *) pmap + sizeof(ColormapRec)); sizebytes = size * sizeof(Entry); pmap->clientPixelsRed = (Pixel **) ((char *) pmap->red + sizebytes); pmap->numPixelsRed = (int *) ((char *) pmap->clientPixelsRed + (LimitClients * sizeof(Pixel *))); pmap->mid = mid; pmap->flags = 0; /* start out with all flags clear */ if (mid == pScreen->defColormap) pmap->flags |= IsDefault; pmap->pScreen = pScreen; pmap->pVisual = pVisual; pmap->class = class; if ((class | DynamicClass) == DirectColor) size = NUMRED(pVisual); pmap->freeRed = size; memset((char *) pmap->red, 0, (int) sizebytes); memset((char *) pmap->numPixelsRed, 0, LimitClients * sizeof(int)); for (pptr = &pmap->clientPixelsRed[LimitClients]; --pptr >= pmap->clientPixelsRed;) *pptr = (Pixel *) NULL; if (alloc == AllocAll) { if (class & DynamicClass) pmap->flags |= AllAllocated; for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--) pent->refcnt = AllocPrivate; pmap->freeRed = 0; ppix = xallocarray(size, sizeof(Pixel)); if (!ppix) { free(pmap); return BadAlloc; } pmap->clientPixelsRed[client] = ppix; for (i = 0; i < size; i++) ppix[i] = i; pmap->numPixelsRed[client] = size; } if ((class | DynamicClass) == DirectColor) { pmap->freeGreen = NUMGREEN(pVisual); pmap->green = (EntryPtr) ((char *) pmap->numPixelsRed + (LimitClients * sizeof(int))); pmap->clientPixelsGreen = (Pixel **) ((char *) pmap->green + sizebytes); pmap->numPixelsGreen = (int *) ((char *) pmap->clientPixelsGreen + (LimitClients * sizeof(Pixel *))); pmap->freeBlue = NUMBLUE(pVisual); pmap->blue = (EntryPtr) ((char *) pmap->numPixelsGreen + (LimitClients * sizeof(int))); pmap->clientPixelsBlue = (Pixel **) ((char *) pmap->blue + sizebytes); pmap->numPixelsBlue = (int *) ((char *) pmap->clientPixelsBlue + (LimitClients * sizeof(Pixel *))); memset((char *) pmap->green, 0, (int) sizebytes); memset((char *) pmap->blue, 0, (int) sizebytes); memmove((char *) pmap->clientPixelsGreen, (char *) pmap->clientPixelsRed, LimitClients * sizeof(Pixel *)); memmove((char *) pmap->clientPixelsBlue, (char *) pmap->clientPixelsRed, LimitClients * sizeof(Pixel *)); memset((char *) pmap->numPixelsGreen, 0, LimitClients * sizeof(int)); memset((char *) pmap->numPixelsBlue, 0, LimitClients * sizeof(int)); /* If every cell is allocated, mark its refcnt */ if (alloc == AllocAll) { size = pmap->freeGreen; for (pent = &pmap->green[size - 1]; pent >= pmap->green; pent--) pent->refcnt = AllocPrivate; pmap->freeGreen = 0; ppix = xallocarray(size, sizeof(Pixel)); if (!ppix) { free(pmap->clientPixelsRed[client]); free(pmap); return BadAlloc; } pmap->clientPixelsGreen[client] = ppix; for (i = 0; i < size; i++) ppix[i] = i; pmap->numPixelsGreen[client] = size; size = pmap->freeBlue; for (pent = &pmap->blue[size - 1]; pent >= pmap->blue; pent--) pent->refcnt = AllocPrivate; pmap->freeBlue = 0; ppix = xallocarray(size, sizeof(Pixel)); if (!ppix) { free(pmap->clientPixelsGreen[client]); free(pmap->clientPixelsRed[client]); free(pmap); return BadAlloc; } pmap->clientPixelsBlue[client] = ppix; for (i = 0; i < size; i++) ppix[i] = i; pmap->numPixelsBlue[client] = size; } } pmap->flags |= BeingCreated; if (!AddResource(mid, RT_COLORMAP, (void *) pmap)) return BadAlloc; /* * Security creation/labeling check */ i = XaceHook(XACE_RESOURCE_ACCESS, clients[client], mid, RT_COLORMAP, pmap, RT_NONE, NULL, DixCreateAccess); if (i != Success) { FreeResource(mid, RT_NONE); return i; } /* If the device wants a chance to initialize the colormap in any way, * this is it. In specific, if this is a Static colormap, this is the * time to fill in the colormap's values */ if (!(*pScreen->CreateColormap) (pmap)) { FreeResource(mid, RT_NONE); return BadAlloc; } pmap->flags &= ~BeingCreated; *ppcmap = pmap; return Success; } /** * * \param value must conform to DeleteType */ int FreeColormap(void *value, XID mid) { int i; EntryPtr pent; ColormapPtr pmap = (ColormapPtr) value; if (CLIENT_ID(mid) != SERVER_ID) { (*pmap->pScreen->UninstallColormap) (pmap); WalkTree(pmap->pScreen, (VisitWindowProcPtr) TellNoMap, (void *) &mid); } /* This is the device's chance to undo anything it needs to, especially * to free any storage it allocated */ (*pmap->pScreen->DestroyColormap) (pmap); if (pmap->clientPixelsRed) { for (i = 0; i < LimitClients; i++) free(pmap->clientPixelsRed[i]); } if ((pmap->class == PseudoColor) || (pmap->class == GrayScale)) { for (pent = &pmap->red[pmap->pVisual->ColormapEntries - 1]; pent >= pmap->red; pent--) { if (pent->fShared) { if (--pent->co.shco.red->refcnt == 0) free(pent->co.shco.red); if (--pent->co.shco.green->refcnt == 0) free(pent->co.shco.green); if (--pent->co.shco.blue->refcnt == 0) free(pent->co.shco.blue); } } } if ((pmap->class | DynamicClass) == DirectColor) { for (i = 0; i < LimitClients; i++) { free(pmap->clientPixelsGreen[i]); free(pmap->clientPixelsBlue[i]); } } if (pmap->flags & IsDefault) { dixFreePrivates(pmap->devPrivates, PRIVATE_COLORMAP); free(pmap); } else dixFreeObjectWithPrivates(pmap, PRIVATE_COLORMAP); return Success; } /* Tell window that pmid has disappeared */ static int TellNoMap(WindowPtr pwin, Colormap * pmid) { if (wColormap(pwin) == *pmid) { /* This should be call to DeliverEvent */ xEvent xE = { .u.colormap.window = pwin->drawable.id, .u.colormap.colormap = None, .u.colormap.new = TRUE, .u.colormap.state = ColormapUninstalled }; xE.u.u.type = ColormapNotify; #ifdef PANORAMIX if (noPanoramiXExtension || !pwin->drawable.pScreen->myNum) #endif DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL); if (pwin->optional) { pwin->optional->colormap = None; CheckWindowOptionalNeed(pwin); } } return WT_WALKCHILDREN; } /* Tell window that pmid got uninstalled */ int TellLostMap(WindowPtr pwin, void *value) { Colormap *pmid = (Colormap *) value; #ifdef PANORAMIX if (!noPanoramiXExtension && pwin->drawable.pScreen->myNum) return WT_STOPWALKING; #endif if (wColormap(pwin) == *pmid) { /* This should be call to DeliverEvent */ xEvent xE = { .u.colormap.window = pwin->drawable.id, .u.colormap.colormap = *pmid, .u.colormap.new = FALSE, .u.colormap.state = ColormapUninstalled }; xE.u.u.type = ColormapNotify; DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL); } return WT_WALKCHILDREN; } /* Tell window that pmid got installed */ int TellGainedMap(WindowPtr pwin, void *value) { Colormap *pmid = (Colormap *) value; #ifdef PANORAMIX if (!noPanoramiXExtension && pwin->drawable.pScreen->myNum) return WT_STOPWALKING; #endif if (wColormap(pwin) == *pmid) { /* This should be call to DeliverEvent */ xEvent xE = { .u.colormap.window = pwin->drawable.id, .u.colormap.colormap = *pmid, .u.colormap.new = FALSE, .u.colormap.state = ColormapInstalled }; xE.u.u.type = ColormapNotify; DeliverEvents(pwin, &xE, 1, (WindowPtr) NULL); } return WT_WALKCHILDREN; } int CopyColormapAndFree(Colormap mid, ColormapPtr pSrc, int client) { ColormapPtr pmap = (ColormapPtr) NULL; int result, alloc, size; Colormap midSrc; ScreenPtr pScreen; VisualPtr pVisual; pScreen = pSrc->pScreen; pVisual = pSrc->pVisual; midSrc = pSrc->mid; alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ? AllocAll : AllocNone; size = pVisual->ColormapEntries; /* If the create returns non-0, it failed */ result = CreateColormap(mid, pScreen, pVisual, &pmap, alloc, client); if (result != Success) return result; if (alloc == AllocAll) { memmove((char *) pmap->red, (char *) pSrc->red, size * sizeof(Entry)); if ((pmap->class | DynamicClass) == DirectColor) { memmove((char *) pmap->green, (char *) pSrc->green, size * sizeof(Entry)); memmove((char *) pmap->blue, (char *) pSrc->blue, size * sizeof(Entry)); } pSrc->flags &= ~AllAllocated; FreePixels(pSrc, client); UpdateColors(pmap); return Success; } CopyFree(REDMAP, client, pSrc, pmap); if ((pmap->class | DynamicClass) == DirectColor) { CopyFree(GREENMAP, client, pSrc, pmap); CopyFree(BLUEMAP, client, pSrc, pmap); } if (pmap->class & DynamicClass) UpdateColors(pmap); /* XXX should worry about removing any RT_CMAPENTRY resource */ return Success; } /* Helper routine for freeing large numbers of cells from a map */ static void CopyFree(int channel, int client, ColormapPtr pmapSrc, ColormapPtr pmapDst) { int z, npix; EntryPtr pentSrcFirst, pentDstFirst; EntryPtr pentSrc, pentDst; Pixel *ppix; int nalloc; switch (channel) { default: /* so compiler can see that everything gets initialized */ case REDMAP: ppix = (pmapSrc->clientPixelsRed)[client]; npix = (pmapSrc->numPixelsRed)[client]; pentSrcFirst = pmapSrc->red; pentDstFirst = pmapDst->red; break; case GREENMAP: ppix = (pmapSrc->clientPixelsGreen)[client]; npix = (pmapSrc->numPixelsGreen)[client]; pentSrcFirst = pmapSrc->green; pentDstFirst = pmapDst->green; break; case BLUEMAP: ppix = (pmapSrc->clientPixelsBlue)[client]; npix = (pmapSrc->numPixelsBlue)[client]; pentSrcFirst = pmapSrc->blue; pentDstFirst = pmapDst->blue; break; } nalloc = 0; if (pmapSrc->class & DynamicClass) { for (z = npix; --z >= 0; ppix++) { /* Copy entries */ pentSrc = pentSrcFirst + *ppix; pentDst = pentDstFirst + *ppix; if (pentDst->refcnt > 0) { pentDst->refcnt++; } else { *pentDst = *pentSrc; nalloc++; if (pentSrc->refcnt > 0) pentDst->refcnt = 1; else pentSrc->fShared = FALSE; } FreeCell(pmapSrc, *ppix, channel); } } /* Note that FreeCell has already fixed pmapSrc->free{Color} */ switch (channel) { case REDMAP: pmapDst->freeRed -= nalloc; (pmapDst->clientPixelsRed)[client] = (pmapSrc->clientPixelsRed)[client]; (pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL; (pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client]; (pmapSrc->numPixelsRed)[client] = 0; break; case GREENMAP: pmapDst->freeGreen -= nalloc; (pmapDst->clientPixelsGreen)[client] = (pmapSrc->clientPixelsGreen)[client]; (pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL; (pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client]; (pmapSrc->numPixelsGreen)[client] = 0; break; case BLUEMAP: pmapDst->freeBlue -= nalloc; pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client]; pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL; pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client]; pmapSrc->numPixelsBlue[client] = 0; break; } } /* Free the ith entry in a color map. Must handle freeing of * colors allocated through AllocColorPlanes */ static void FreeCell(ColormapPtr pmap, Pixel i, int channel) { EntryPtr pent; int *pCount; switch (channel) { default: /* so compiler can see that everything gets initialized */ case PSEUDOMAP: case REDMAP: pent = (EntryPtr) &pmap->red[i]; pCount = &pmap->freeRed; break; case GREENMAP: pent = (EntryPtr) &pmap->green[i]; pCount = &pmap->freeGreen; break; case BLUEMAP: pent = (EntryPtr) &pmap->blue[i]; pCount = &pmap->freeBlue; break; } /* If it's not privately allocated and it's not time to free it, just * decrement the count */ if (pent->refcnt > 1) pent->refcnt--; else { /* If the color type is shared, find the sharedcolor. If decremented * refcnt is 0, free the shared cell. */ if (pent->fShared) { if (--pent->co.shco.red->refcnt == 0) free(pent->co.shco.red); if (--pent->co.shco.green->refcnt == 0) free(pent->co.shco.green); if (--pent->co.shco.blue->refcnt == 0) free(pent->co.shco.blue); pent->fShared = FALSE; } pent->refcnt = 0; *pCount += 1; } } static void UpdateColors(ColormapPtr pmap) { xColorItem *defs; xColorItem *pdef; EntryPtr pent; VisualPtr pVisual; int i, n, size; pVisual = pmap->pVisual; size = pVisual->ColormapEntries; defs = xallocarray(size, sizeof(xColorItem)); if (!defs) return; n = 0; pdef = defs; if (pmap->class == DirectColor) { for (i = 0; i < size; i++) { if (!pmap->red[i].refcnt && !pmap->green[i].refcnt && !pmap->blue[i].refcnt) continue; pdef->pixel = ((Pixel) i << pVisual->offsetRed) | ((Pixel) i << pVisual->offsetGreen) | ((Pixel) i << pVisual->offsetBlue); pdef->red = pmap->red[i].co.local.red; pdef->green = pmap->green[i].co.local.green; pdef->blue = pmap->blue[i].co.local.blue; pdef->flags = DoRed | DoGreen | DoBlue; pdef++; n++; } } else { for (i = 0, pent = pmap->red; i < size; i++, pent++) { if (!pent->refcnt) continue; pdef->pixel = i; if (pent->fShared) { pdef->red = pent->co.shco.red->color; pdef->green = pent->co.shco.green->color; pdef->blue = pent->co.shco.blue->color; } else { pdef->red = pent->co.local.red; pdef->green = pent->co.local.green; pdef->blue = pent->co.local.blue; } pdef->flags = DoRed | DoGreen | DoBlue; pdef++; n++; } } if (n) (*pmap->pScreen->StoreColors) (pmap, n, defs); free(defs); } /* Tries to find a color in pmap that exactly matches the one requested in prgb * if it can't it allocates one. * Starts looking at pentFirst + *pPixel, so if you want a specific pixel, * load *pPixel with that value, otherwise set it to 0 */ static int FindColor(ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb * prgb, Pixel * pPixel, int channel, int client, ColorCompareProcPtr comp) { EntryPtr pent; Bool foundFree; Pixel pixel, Free = 0; int npix, count, *nump = NULL; Pixel **pixp = NULL, *ppix; xColorItem def; foundFree = FALSE; if ((pixel = *pPixel) >= size) pixel = 0; /* see if there is a match, and also look for a free entry */ for (pent = pentFirst + pixel, count = size; --count >= 0;) { if (pent->refcnt > 0) { if ((*comp) (pent, prgb)) { if (client >= 0) pent->refcnt++; *pPixel = pixel; switch (channel) { case REDMAP: *pPixel <<= pmap->pVisual->offsetRed; case PSEUDOMAP: break; case GREENMAP: *pPixel <<= pmap->pVisual->offsetGreen; break; case BLUEMAP: *pPixel <<= pmap->pVisual->offsetBlue; break; } goto gotit; } } else if (!foundFree && pent->refcnt == 0) { Free = pixel; foundFree = TRUE; /* If we're initializing the colormap, then we are looking for * the first free cell we can find, not to minimize the number * of entries we use. So don't look any further. */ if (pmap->flags & BeingCreated) break; } pixel++; if (pixel >= size) { pent = pentFirst; pixel = 0; } else pent++; } /* If we got here, we didn't find a match. If we also didn't find * a free entry, we're out of luck. Otherwise, we'll usurp a free * entry and fill it in */ if (!foundFree) return BadAlloc; pent = pentFirst + Free; pent->fShared = FALSE; pent->refcnt = (client >= 0) ? 1 : AllocTemporary; switch (channel) { case PSEUDOMAP: pent->co.local.red = prgb->red; pent->co.local.green = prgb->green; pent->co.local.blue = prgb->blue; def.red = prgb->red; def.green = prgb->green; def.blue = prgb->blue; def.flags = (DoRed | DoGreen | DoBlue); if (client >= 0) pmap->freeRed--; def.pixel = Free; break; case REDMAP: pent->co.local.red = prgb->red; def.red = prgb->red; def.green = pmap->green[0].co.local.green; def.blue = pmap->blue[0].co.local.blue; def.flags = DoRed; if (client >= 0) pmap->freeRed--; def.pixel = Free << pmap->pVisual->offsetRed; break; case GREENMAP: pent->co.local.green = prgb->green; def.red = pmap->red[0].co.local.red; def.green = prgb->green; def.blue = pmap->blue[0].co.local.blue; def.flags = DoGreen; if (client >= 0) pmap->freeGreen--; def.pixel = Free << pmap->pVisual->offsetGreen; break; case BLUEMAP: pent->co.local.blue = prgb->blue; def.red = pmap->red[0].co.local.red; def.green = pmap->green[0].co.local.green; def.blue = prgb->blue; def.flags = DoBlue; if (client >= 0) pmap->freeBlue--; def.pixel = Free << pmap->pVisual->offsetBlue; break; } (*pmap->pScreen->StoreColors) (pmap, 1, &def); pixel = Free; *pPixel = def.pixel; gotit: if (pmap->flags & BeingCreated || client == -1) return Success; /* Now remember the pixel, for freeing later */ switch (channel) { case PSEUDOMAP: case REDMAP: nump = pmap->numPixelsRed; pixp = pmap->clientPixelsRed; break; case GREENMAP: nump = pmap->numPixelsGreen; pixp = pmap->clientPixelsGreen; break; case BLUEMAP: nump = pmap->numPixelsBlue; pixp = pmap->clientPixelsBlue; break; } npix = nump[client]; ppix = reallocarray(pixp[client], npix + 1, sizeof(Pixel)); if (!ppix) { pent->refcnt--; if (!pent->fShared) switch (channel) { case PSEUDOMAP: case REDMAP: pmap->freeRed++; break; case GREENMAP: pmap->freeGreen++; break; case BLUEMAP: pmap->freeBlue++; break; } return BadAlloc; } ppix[npix] = pixel; pixp[client] = ppix; nump[client]++; return Success; } /* Get a read-only color from a ColorMap (probably slow for large maps) * Returns by changing the value in pred, pgreen, pblue and pPix */ int AllocColor(ColormapPtr pmap, unsigned short *pred, unsigned short *pgreen, unsigned short *pblue, Pixel * pPix, int client) { Pixel pixR, pixG, pixB; int entries; xrgb rgb; int class; VisualPtr pVisual; int npix; Pixel *ppix; pVisual = pmap->pVisual; (*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual); rgb.red = *pred; rgb.green = *pgreen; rgb.blue = *pblue; class = pmap->class; entries = pVisual->ColormapEntries; /* If the colormap is being created, then we want to be able to change * the colormap, even if it's a static type. Otherwise, we'd never be * able to initialize static colormaps */ if (pmap->flags & BeingCreated) class |= DynamicClass; /* If this is one of the static storage classes, and we're not initializing * it, the best we can do is to find the closest color entry to the * requested one and return that. */ switch (class) { case StaticColor: case StaticGray: /* Look up all three components in the same pmap */ *pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP); *pred = pmap->red[pixR].co.local.red; *pgreen = pmap->red[pixR].co.local.green; *pblue = pmap->red[pixR].co.local.blue; npix = pmap->numPixelsRed[client]; ppix = reallocarray(pmap->clientPixelsRed[client], npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixR; pmap->clientPixelsRed[client] = ppix; pmap->numPixelsRed[client]++; break; case TrueColor: /* Look up each component in its own map, then OR them together */ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP); pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP); pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP); *pPix = (pixR << pVisual->offsetRed) | (pixG << pVisual->offsetGreen) | (pixB << pVisual->offsetBlue) | ALPHAMASK(pVisual); *pred = pmap->red[pixR].co.local.red; *pgreen = pmap->green[pixG].co.local.green; *pblue = pmap->blue[pixB].co.local.blue; npix = pmap->numPixelsRed[client]; ppix = reallocarray(pmap->clientPixelsRed[client], npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixR; pmap->clientPixelsRed[client] = ppix; npix = pmap->numPixelsGreen[client]; ppix = reallocarray(pmap->clientPixelsGreen[client], npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixG; pmap->clientPixelsGreen[client] = ppix; npix = pmap->numPixelsBlue[client]; ppix = reallocarray(pmap->clientPixelsBlue[client], npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixB; pmap->clientPixelsBlue[client] = ppix; pmap->numPixelsRed[client]++; pmap->numPixelsGreen[client]++; pmap->numPixelsBlue[client]++; break; case GrayScale: case PseudoColor: if (pmap->mid != pmap->pScreen->defColormap && pmap->pVisual->vid == pmap->pScreen->rootVisual) { ColormapPtr prootmap; dixLookupResourceByType((void **) &prootmap, pmap->pScreen->defColormap, RT_COLORMAP, clients[client], DixReadAccess); if (pmap->class == prootmap->class) FindColorInRootCmap(prootmap, prootmap->red, entries, &rgb, pPix, PSEUDOMAP, AllComp); } if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP, client, AllComp) != Success) return BadAlloc; break; case DirectColor: if (pmap->mid != pmap->pScreen->defColormap && pmap->pVisual->vid == pmap->pScreen->rootVisual) { ColormapPtr prootmap; dixLookupResourceByType((void **) &prootmap, pmap->pScreen->defColormap, RT_COLORMAP, clients[client], DixReadAccess); if (pmap->class == prootmap->class) { pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed; FindColorInRootCmap(prootmap, prootmap->red, entries, &rgb, &pixR, REDMAP, RedComp); pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen; FindColorInRootCmap(prootmap, prootmap->green, entries, &rgb, &pixG, GREENMAP, GreenComp); pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue; FindColorInRootCmap(prootmap, prootmap->blue, entries, &rgb, &pixB, BLUEMAP, BlueComp); *pPix = pixR | pixG | pixB; } } pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed; if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP, client, RedComp) != Success) return BadAlloc; pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen; if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG, GREENMAP, client, GreenComp) != Success) { (void) FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel) 0); return BadAlloc; } pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue; if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP, client, BlueComp) != Success) { (void) FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel) 0); (void) FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel) 0); return BadAlloc; } *pPix = pixR | pixG | pixB | ALPHAMASK(pVisual); break; } /* if this is the client's first pixel in this colormap, tell the * resource manager that the client has pixels in this colormap which * should be freed when the client dies */ if ((pmap->numPixelsRed[client] == 1) && (CLIENT_ID(pmap->mid) != client) && !(pmap->flags & BeingCreated)) { colorResource *pcr; pcr = malloc(sizeof(colorResource)); if (!pcr) { (void) FreeColors(pmap, client, 1, pPix, (Pixel) 0); return BadAlloc; } pcr->mid = pmap->mid; pcr->client = client; if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (void *) pcr)) return BadAlloc; } return Success; } /* * FakeAllocColor -- fake an AllocColor request by * returning a free pixel if availible, otherwise returning * the closest matching pixel. This is used by the mi * software sprite code to recolor cursors. A nice side-effect * is that this routine will never return failure. */ void FakeAllocColor(ColormapPtr pmap, xColorItem * item) { Pixel pixR, pixG, pixB; Pixel temp; int entries; xrgb rgb; int class; VisualPtr pVisual; pVisual = pmap->pVisual; rgb.red = item->red; rgb.green = item->green; rgb.blue = item->blue; (*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual); class = pmap->class; entries = pVisual->ColormapEntries; switch (class) { case GrayScale: case PseudoColor: temp = 0; item->pixel = 0; if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP, -1, AllComp) == Success) { item->pixel = temp; break; } /* fall through ... */ case StaticColor: case StaticGray: item->pixel = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP); break; case DirectColor: /* Look up each component in its own map, then OR them together */ pixR = (item->pixel & pVisual->redMask) >> pVisual->offsetRed; pixG = (item->pixel & pVisual->greenMask) >> pVisual->offsetGreen; pixB = (item->pixel & pVisual->blueMask) >> pVisual->offsetBlue; if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP, -1, RedComp) != Success) pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP) << pVisual->offsetRed; if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG, GREENMAP, -1, GreenComp) != Success) pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP) << pVisual->offsetGreen; if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP, -1, BlueComp) != Success) pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP) << pVisual->offsetBlue; item->pixel = pixR | pixG | pixB; break; case TrueColor: /* Look up each component in its own map, then OR them together */ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP); pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP); pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP); item->pixel = (pixR << pVisual->offsetRed) | (pixG << pVisual->offsetGreen) | (pixB << pVisual->offsetBlue); break; } } /* free a pixel value obtained from FakeAllocColor */ void FakeFreeColor(ColormapPtr pmap, Pixel pixel) { VisualPtr pVisual; Pixel pixR, pixG, pixB; switch (pmap->class) { case GrayScale: case PseudoColor: if (pmap->red[pixel].refcnt == AllocTemporary) pmap->red[pixel].refcnt = 0; break; case DirectColor: pVisual = pmap->pVisual; pixR = (pixel & pVisual->redMask) >> pVisual->offsetRed; pixG = (pixel & pVisual->greenMask) >> pVisual->offsetGreen; pixB = (pixel & pVisual->blueMask) >> pVisual->offsetBlue; if (pmap->red[pixR].refcnt == AllocTemporary) pmap->red[pixR].refcnt = 0; if (pmap->green[pixG].refcnt == AllocTemporary) pmap->green[pixG].refcnt = 0; if (pmap->blue[pixB].refcnt == AllocTemporary) pmap->blue[pixB].refcnt = 0; break; } } typedef unsigned short BigNumUpper; typedef unsigned long BigNumLower; #define BIGNUMLOWERBITS 24 #define BIGNUMUPPERBITS 16 #define BIGNUMLOWER (1 << BIGNUMLOWERBITS) #define BIGNUMUPPER (1 << BIGNUMUPPERBITS) #define UPPERPART(i) ((i) >> BIGNUMLOWERBITS) #define LOWERPART(i) ((i) & (BIGNUMLOWER - 1)) typedef struct _bignum { BigNumUpper upper; BigNumLower lower; } BigNumRec, *BigNumPtr; #define BigNumGreater(x,y) (((x)->upper > (y)->upper) ||\ ((x)->upper == (y)->upper && (x)->lower > (y)->lower)) #define UnsignedToBigNum(u,r) (((r)->upper = UPPERPART(u)), \ ((r)->lower = LOWERPART(u))) #define MaxBigNum(r) (((r)->upper = BIGNUMUPPER-1), \ ((r)->lower = BIGNUMLOWER-1)) static void BigNumAdd(BigNumPtr x, BigNumPtr y, BigNumPtr r) { BigNumLower lower, carry = 0; lower = x->lower + y->lower; if (lower >= BIGNUMLOWER) { lower -= BIGNUMLOWER; carry = 1; } r->lower = lower; r->upper = x->upper + y->upper + carry; } static Pixel FindBestPixel(EntryPtr pentFirst, int size, xrgb * prgb, int channel) { EntryPtr pent; Pixel pixel, final; long dr, dg, db; unsigned long sq; BigNumRec minval, sum, temp; final = 0; MaxBigNum(&minval); /* look for the minimal difference */ for (pent = pentFirst, pixel = 0; pixel < size; pent++, pixel++) { dr = dg = db = 0; switch (channel) { case PSEUDOMAP: dg = (long) pent->co.local.green - prgb->green; db = (long) pent->co.local.blue - prgb->blue; case REDMAP: dr = (long) pent->co.local.red - prgb->red; break; case GREENMAP: dg = (long) pent->co.local.green - prgb->green; break; case BLUEMAP: db = (long) pent->co.local.blue - prgb->blue; break; } sq = dr * dr; UnsignedToBigNum(sq, &sum); sq = dg * dg; UnsignedToBigNum(sq, &temp); BigNumAdd(&sum, &temp, &sum); sq = db * db; UnsignedToBigNum(sq, &temp); BigNumAdd(&sum, &temp, &sum); if (BigNumGreater(&minval, &sum)) { final = pixel; minval = sum; } } return final; } static void FindColorInRootCmap(ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb * prgb, Pixel * pPixel, int channel, ColorCompareProcPtr comp) { EntryPtr pent; Pixel pixel; int count; if ((pixel = *pPixel) >= size) pixel = 0; for (pent = pentFirst + pixel, count = size; --count >= 0; pent++, pixel++) { if (pent->refcnt > 0 && (*comp) (pent, prgb)) { switch (channel) { case REDMAP: pixel <<= pmap->pVisual->offsetRed; break; case GREENMAP: pixel <<= pmap->pVisual->offsetGreen; break; case BLUEMAP: pixel <<= pmap->pVisual->offsetBlue; break; default: /* PSEUDOMAP */ break; } *pPixel = pixel; } } } /* Comparison functions -- passed to FindColor to determine if an * entry is already the color we're looking for or not */ static int AllComp(EntryPtr pent, xrgb * prgb) { if ((pent->co.local.red == prgb->red) && (pent->co.local.green == prgb->green) && (pent->co.local.blue == prgb->blue)) return 1; return 0; } static int RedComp(EntryPtr pent, xrgb * prgb) { if (pent->co.local.red == prgb->red) return 1; return 0; } static int GreenComp(EntryPtr pent, xrgb * prgb) { if (pent->co.local.green == prgb->green) return 1; return 0; } static int BlueComp(EntryPtr pent, xrgb * prgb) { if (pent->co.local.blue == prgb->blue) return 1; return 0; } /* Read the color value of a cell */ int QueryColors(ColormapPtr pmap, int count, Pixel * ppixIn, xrgb * prgbList, ClientPtr client) { Pixel *ppix, pixel; xrgb *prgb; VisualPtr pVisual; EntryPtr pent; Pixel i; int errVal = Success; pVisual = pmap->pVisual; if ((pmap->class | DynamicClass) == DirectColor) { int numred, numgreen, numblue; Pixel rgbbad; numred = NUMRED(pVisual); numgreen = NUMGREEN(pVisual); numblue = NUMBLUE(pVisual); rgbbad = ~RGBMASK(pVisual); for (ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++) { pixel = *ppix; if (pixel & rgbbad) { client->errorValue = pixel; errVal = BadValue; continue; } i = (pixel & pVisual->redMask) >> pVisual->offsetRed; if (i >= numred) { client->errorValue = pixel; errVal = BadValue; continue; } prgb->red = pmap->red[i].co.local.red; i = (pixel & pVisual->greenMask) >> pVisual->offsetGreen; if (i >= numgreen) { client->errorValue = pixel; errVal = BadValue; continue; } prgb->green = pmap->green[i].co.local.green; i = (pixel & pVisual->blueMask) >> pVisual->offsetBlue; if (i >= numblue) { client->errorValue = pixel; errVal = BadValue; continue; } prgb->blue = pmap->blue[i].co.local.blue; } } else { for (ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++) { pixel = *ppix; if (pixel >= pVisual->ColormapEntries) { client->errorValue = pixel; errVal = BadValue; } else { pent = (EntryPtr) &pmap->red[pixel]; if (pent->fShared) { prgb->red = pent->co.shco.red->color; prgb->green = pent->co.shco.green->color; prgb->blue = pent->co.shco.blue->color; } else { prgb->red = pent->co.local.red; prgb->green = pent->co.local.green; prgb->blue = pent->co.local.blue; } } } } return errVal; } static void FreePixels(ColormapPtr pmap, int client) { Pixel *ppix, *ppixStart; int n; int class; class = pmap->class; ppixStart = pmap->clientPixelsRed[client]; if (class & DynamicClass) { n = pmap->numPixelsRed[client]; for (ppix = ppixStart; --n >= 0;) { FreeCell(pmap, *ppix, REDMAP); ppix++; } } free(ppixStart); pmap->clientPixelsRed[client] = (Pixel *) NULL; pmap->numPixelsRed[client] = 0; if ((class | DynamicClass) == DirectColor) { ppixStart = pmap->clientPixelsGreen[client]; if (class & DynamicClass) for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;) FreeCell(pmap, *ppix++, GREENMAP); free(ppixStart); pmap->clientPixelsGreen[client] = (Pixel *) NULL; pmap->numPixelsGreen[client] = 0; ppixStart = pmap->clientPixelsBlue[client]; if (class & DynamicClass) for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0;) FreeCell(pmap, *ppix++, BLUEMAP); free(ppixStart); pmap->clientPixelsBlue[client] = (Pixel *) NULL; pmap->numPixelsBlue[client] = 0; } } /** * Frees all of a client's colors and cells. * * \param value must conform to DeleteType * \unused fakeid */ int FreeClientPixels(void *value, XID fakeid) { void *pmap; colorResource *pcr = value; int rc; rc = dixLookupResourceByType(&pmap, pcr->mid, RT_COLORMAP, serverClient, DixRemoveAccess); if (rc == Success) FreePixels((ColormapPtr) pmap, pcr->client); free(pcr); return Success; } int AllocColorCells(int client, ColormapPtr pmap, int colors, int planes, Bool contig, Pixel * ppix, Pixel * masks) { Pixel rmask, gmask, bmask, *ppixFirst, r, g, b; int n, class; int ok; int oldcount; colorResource *pcr = (colorResource *) NULL; class = pmap->class; if (!(class & DynamicClass)) return BadAlloc; /* Shouldn't try on this type */ oldcount = pmap->numPixelsRed[client]; if (pmap->class == DirectColor) oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client]; if (!oldcount && (CLIENT_ID(pmap->mid) != client)) { pcr = malloc(sizeof(colorResource)); if (!pcr) return BadAlloc; } if (pmap->class == DirectColor) { ok = AllocDirect(client, pmap, colors, planes, planes, planes, contig, ppix, &rmask, &gmask, &bmask); if (ok == Success) { for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b) { while (!(rmask & r)) r += r; while (!(gmask & g)) g += g; while (!(bmask & b)) b += b; *masks++ = r | g | b; } } } else { ok = AllocPseudo(client, pmap, colors, planes, contig, ppix, &rmask, &ppixFirst); if (ok == Success) { for (r = 1, n = planes; --n >= 0; r += r) { while (!(rmask & r)) r += r; *masks++ = r; } } } /* if this is the client's first pixels in this colormap, tell the * resource manager that the client has pixels in this colormap which * should be freed when the client dies */ if ((ok == Success) && pcr) { pcr->mid = pmap->mid; pcr->client = client; if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (void *) pcr)) ok = BadAlloc; } else free(pcr); return ok; } int AllocColorPlanes(int client, ColormapPtr pmap, int colors, int r, int g, int b, Bool contig, Pixel * pixels, Pixel * prmask, Pixel * pgmask, Pixel * pbmask) { int ok; Pixel mask, *ppixFirst; Pixel shift; int i; int class; int oldcount; colorResource *pcr = (colorResource *) NULL; class = pmap->class; if (!(class & DynamicClass)) return BadAlloc; /* Shouldn't try on this type */ oldcount = pmap->numPixelsRed[client]; if (class == DirectColor) oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client]; if (!oldcount && (CLIENT_ID(pmap->mid) != client)) { pcr = malloc(sizeof(colorResource)); if (!pcr) return BadAlloc; } if (class == DirectColor) { ok = AllocDirect(client, pmap, colors, r, g, b, contig, pixels, prmask, pgmask, pbmask); } else { /* Allocate the proper pixels */ /* XXX This is sort of bad, because of contig is set, we force all * r + g + b bits to be contiguous. Should only force contiguity * per mask */ ok = AllocPseudo(client, pmap, colors, r + g + b, contig, pixels, &mask, &ppixFirst); if (ok == Success) { /* now split that mask into three */ *prmask = *pgmask = *pbmask = 0; shift = 1; for (i = r; --i >= 0; shift += shift) { while (!(mask & shift)) shift += shift; *prmask |= shift; } for (i = g; --i >= 0; shift += shift) { while (!(mask & shift)) shift += shift; *pgmask |= shift; } for (i = b; --i >= 0; shift += shift) { while (!(mask & shift)) shift += shift; *pbmask |= shift; } /* set up the shared color cells */ if (!AllocShared(pmap, pixels, colors, r, g, b, *prmask, *pgmask, *pbmask, ppixFirst)) { (void) FreeColors(pmap, client, colors, pixels, mask); ok = BadAlloc; } } } /* if this is the client's first pixels in this colormap, tell the * resource manager that the client has pixels in this colormap which * should be freed when the client dies */ if ((ok == Success) && pcr) { pcr->mid = pmap->mid; pcr->client = client; if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (void *) pcr)) ok = BadAlloc; } else free(pcr); return ok; } static int AllocDirect(int client, ColormapPtr pmap, int c, int r, int g, int b, Bool contig, Pixel * pixels, Pixel * prmask, Pixel * pgmask, Pixel * pbmask) { Pixel *ppixRed, *ppixGreen, *ppixBlue; Pixel *ppix, *pDst, *p; int npix, npixR, npixG, npixB; Bool okR, okG, okB; Pixel *rpix = 0, *gpix = 0, *bpix = 0; npixR = c << r; npixG = c << g; npixB = c << b; if ((r >= 32) || (g >= 32) || (b >= 32) || (npixR > pmap->freeRed) || (npixR < c) || (npixG > pmap->freeGreen) || (npixG < c) || (npixB > pmap->freeBlue) || (npixB < c)) return BadAlloc; /* start out with empty pixels */ for (p = pixels; p < pixels + c; p++) *p = 0; ppixRed = xallocarray(npixR, sizeof(Pixel)); ppixGreen = xallocarray(npixG, sizeof(Pixel)); ppixBlue = xallocarray(npixB, sizeof(Pixel)); if (!ppixRed || !ppixGreen || !ppixBlue) { free(ppixBlue); free(ppixGreen); free(ppixRed); return BadAlloc; } okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask); okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask); okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask); if (okR && okG && okB) { rpix = reallocarray(pmap->clientPixelsRed[client], pmap->numPixelsRed[client] + (c << r), sizeof(Pixel)); if (rpix) pmap->clientPixelsRed[client] = rpix; gpix = reallocarray(pmap->clientPixelsGreen[client], pmap->numPixelsGreen[client] + (c << g), sizeof(Pixel)); if (gpix) pmap->clientPixelsGreen[client] = gpix; bpix = reallocarray(pmap->clientPixelsBlue[client], pmap->numPixelsBlue[client] + (c << b), sizeof(Pixel)); if (bpix) pmap->clientPixelsBlue[client] = bpix; } if (!okR || !okG || !okB || !rpix || !gpix || !bpix) { if (okR) for (ppix = ppixRed, npix = npixR; --npix >= 0; ppix++) pmap->red[*ppix].refcnt = 0; if (okG) for (ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++) pmap->green[*ppix].refcnt = 0; if (okB) for (ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++) pmap->blue[*ppix].refcnt = 0; free(ppixBlue); free(ppixGreen); free(ppixRed); return BadAlloc; } *prmask <<= pmap->pVisual->offsetRed; *pgmask <<= pmap->pVisual->offsetGreen; *pbmask <<= pmap->pVisual->offsetBlue; ppix = rpix + pmap->numPixelsRed[client]; for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++) { *ppix++ = *p; if (p < ppixRed + c) *pDst++ |= *p << pmap->pVisual->offsetRed; } pmap->numPixelsRed[client] += npixR; pmap->freeRed -= npixR; ppix = gpix + pmap->numPixelsGreen[client]; for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++) { *ppix++ = *p; if (p < ppixGreen + c) *pDst++ |= *p << pmap->pVisual->offsetGreen; } pmap->numPixelsGreen[client] += npixG; pmap->freeGreen -= npixG; ppix = bpix + pmap->numPixelsBlue[client]; for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++) { *ppix++ = *p; if (p < ppixBlue + c) *pDst++ |= *p << pmap->pVisual->offsetBlue; } pmap->numPixelsBlue[client] += npixB; pmap->freeBlue -= npixB; for (pDst = pixels; pDst < pixels + c; pDst++) *pDst |= ALPHAMASK(pmap->pVisual); free(ppixBlue); free(ppixGreen); free(ppixRed); return Success; } static int AllocPseudo(int client, ColormapPtr pmap, int c, int r, Bool contig, Pixel * pixels, Pixel * pmask, Pixel ** pppixFirst) { Pixel *ppix, *p, *pDst, *ppixTemp; int npix; Bool ok; npix = c << r; if ((r >= 32) || (npix > pmap->freeRed) || (npix < c)) return BadAlloc; if (!(ppixTemp = xallocarray(npix, sizeof(Pixel)))) return BadAlloc; ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask); if (ok) { /* all the allocated pixels are added to the client pixel list, * but only the unique ones are returned to the client */ ppix = reallocarray(pmap->clientPixelsRed[client], pmap->numPixelsRed[client] + npix, sizeof(Pixel)); if (!ppix) { for (p = ppixTemp; p < ppixTemp + npix; p++) pmap->red[*p].refcnt = 0; free(ppixTemp); return BadAlloc; } pmap->clientPixelsRed[client] = ppix; ppix += pmap->numPixelsRed[client]; *pppixFirst = ppix; pDst = pixels; for (p = ppixTemp; p < ppixTemp + npix; p++) { *ppix++ = *p; if (p < ppixTemp + c) *pDst++ = *p; } pmap->numPixelsRed[client] += npix; pmap->freeRed -= npix; } free(ppixTemp); return ok ? Success : BadAlloc; } /* Allocates count << planes pixels from colormap pmap for client. If * contig, then the plane mask is made of consecutive bits. Returns * all count << pixels in the array pixels. The first count of those * pixels are the unique pixels. *pMask has the mask to Or with the * unique pixels to get the rest of them. * * Returns True iff all pixels could be allocated * All cells allocated will have refcnt set to AllocPrivate and shared to FALSE * (see AllocShared for why we care) */ static Bool AllocCP(ColormapPtr pmap, EntryPtr pentFirst, int count, int planes, Bool contig, Pixel * pixels, Pixel * pMask) { EntryPtr ent; Pixel pixel, base, entries, maxp, save; int dplanes, found; Pixel *ppix; Pixel mask; Pixel finalmask; dplanes = pmap->pVisual->nplanes; /* Easy case. Allocate pixels only */ if (planes == 0) { /* allocate writable entries */ ppix = pixels; ent = pentFirst; pixel = 0; while (--count >= 0) { /* Just find count unallocated cells */ while (ent->refcnt) { ent++; pixel++; } ent->refcnt = AllocPrivate; *ppix++ = pixel; ent->fShared = FALSE; } *pMask = 0; return TRUE; } else if (planes > dplanes) { return FALSE; } /* General case count pixels * 2 ^ planes cells to be allocated */ /* make room for new pixels */ ent = pentFirst; /* first try for contiguous planes, since it's fastest */ for (mask = (((Pixel) 1) << planes) - 1, base = 1, dplanes -= (planes - 1); --dplanes >= 0; mask += mask, base += base) { ppix = pixels; found = 0; pixel = 0; entries = pmap->pVisual->ColormapEntries - mask; while (pixel < entries) { save = pixel; maxp = pixel + mask + base; /* check if all are free */ while (pixel != maxp && ent[pixel].refcnt == 0) pixel += base; if (pixel == maxp) { /* this one works */ *ppix++ = save; found++; if (found == count) { /* found enough, allocate them all */ while (--count >= 0) { pixel = pixels[count]; maxp = pixel + mask; while (1) { ent[pixel].refcnt = AllocPrivate; ent[pixel].fShared = FALSE; if (pixel == maxp) break; pixel += base; *ppix++ = pixel; } } *pMask = mask; return TRUE; } } pixel = save + 1; if (pixel & mask) pixel += mask; } } dplanes = pmap->pVisual->nplanes; if (contig || planes == 1 || dplanes < 3) return FALSE; /* this will be very slow for large maps, need a better algorithm */ /* we can generate the smallest and largest numbers that fits in dplanes bits and contain exactly planes bits set as follows. First, we need to check that it is possible to generate such a mask at all. (Non-contiguous masks need one more bit than contiguous masks). Then the smallest such mask consists of the rightmost planes-1 bits set, then a zero, then a one in position planes + 1. The formula is (3 << (planes-1)) -1 The largest such masks consists of the leftmost planes-1 bits set, then a zero, then a one bit in position dplanes-planes-1. If dplanes is smaller than 32 (the number of bits in a word) then the formula is: (1<>> */ finalmask = (((((Pixel) 1) << (planes - 1)) - 1) << (dplanes - planes + 1)) + (((Pixel) 1) << (dplanes - planes - 1)); for (mask = (((Pixel) 3) << (planes - 1)) - 1; mask <= finalmask; mask++) { /* next 3 magic statements count number of ones (HAKMEM #169) */ pixel = (mask >> 1) & 033333333333; pixel = mask - pixel - ((pixel >> 1) & 033333333333); if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes) continue; ppix = pixels; found = 0; entries = pmap->pVisual->ColormapEntries - mask; base = lowbit(mask); for (pixel = 0; pixel < entries; pixel++) { if (pixel & mask) continue; maxp = 0; /* check if all are free */ while (ent[pixel + maxp].refcnt == 0) { GetNextBitsOrBreak(maxp, mask, base); } if ((maxp < mask) || (ent[pixel + mask].refcnt != 0)) continue; /* this one works */ *ppix++ = pixel; found++; if (found < count) continue; /* found enough, allocate them all */ while (--count >= 0) { pixel = (pixels)[count]; maxp = 0; while (1) { ent[pixel + maxp].refcnt = AllocPrivate; ent[pixel + maxp].fShared = FALSE; GetNextBitsOrBreak(maxp, mask, base); *ppix++ = pixel + maxp; } } *pMask = mask; return TRUE; } } return FALSE; } /** * * \param ppixFirst First of the client's new pixels */ static Bool AllocShared(ColormapPtr pmap, Pixel * ppix, int c, int r, int g, int b, Pixel rmask, Pixel gmask, Pixel bmask, Pixel * ppixFirst) { Pixel *pptr, *cptr; int npix, z, npixClientNew, npixShared; Pixel basemask, base, bits, common; SHAREDCOLOR *pshared, **ppshared, **psharedList; npixClientNew = c << (r + g + b); npixShared = (c << r) + (c << g) + (c << b); psharedList = xallocarray(npixShared, sizeof(SHAREDCOLOR *)); if (!psharedList) return FALSE; ppshared = psharedList; for (z = npixShared; --z >= 0;) { if (!(ppshared[z] = malloc(sizeof(SHAREDCOLOR)))) { for (z++; z < npixShared; z++) free(ppshared[z]); free(psharedList); return FALSE; } } for (pptr = ppix, npix = c; --npix >= 0; pptr++) { basemask = ~(gmask | bmask); common = *pptr & basemask; if (rmask) { bits = 0; base = lowbit(rmask); while (1) { pshared = *ppshared++; pshared->refcnt = 1 << (g + b); for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) { if ((*cptr & basemask) == (common | bits)) { pmap->red[*cptr].fShared = TRUE; pmap->red[*cptr].co.shco.red = pshared; } } GetNextBitsOrBreak(bits, rmask, base); } } else { pshared = *ppshared++; pshared->refcnt = 1 << (g + b); for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) { if ((*cptr & basemask) == common) { pmap->red[*cptr].fShared = TRUE; pmap->red[*cptr].co.shco.red = pshared; } } } basemask = ~(rmask | bmask); common = *pptr & basemask; if (gmask) { bits = 0; base = lowbit(gmask); while (1) { pshared = *ppshared++; pshared->refcnt = 1 << (r + b); for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) { if ((*cptr & basemask) == (common | bits)) { pmap->red[*cptr].co.shco.green = pshared; } } GetNextBitsOrBreak(bits, gmask, base); } } else { pshared = *ppshared++; pshared->refcnt = 1 << (g + b); for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) { if ((*cptr & basemask) == common) { pmap->red[*cptr].co.shco.green = pshared; } } } basemask = ~(rmask | gmask); common = *pptr & basemask; if (bmask) { bits = 0; base = lowbit(bmask); while (1) { pshared = *ppshared++; pshared->refcnt = 1 << (r + g); for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) { if ((*cptr & basemask) == (common | bits)) { pmap->red[*cptr].co.shco.blue = pshared; } } GetNextBitsOrBreak(bits, bmask, base); } } else { pshared = *ppshared++; pshared->refcnt = 1 << (g + b); for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) { if ((*cptr & basemask) == common) { pmap->red[*cptr].co.shco.blue = pshared; } } } } free(psharedList); return TRUE; } /** FreeColors * Free colors and/or cells (probably slow for large numbers) */ int FreeColors(ColormapPtr pmap, int client, int count, Pixel * pixels, Pixel mask) { int rval, result, class; Pixel rmask; class = pmap->class; if (pmap->flags & AllAllocated) return BadAccess; if ((class | DynamicClass) == DirectColor) { rmask = mask & RGBMASK(pmap->pVisual); result = FreeCo(pmap, client, REDMAP, count, pixels, mask & pmap->pVisual->redMask); /* If any of the three calls fails, we must report that, if more * than one fails, it's ok that we report the last one */ rval = FreeCo(pmap, client, GREENMAP, count, pixels, mask & pmap->pVisual->greenMask); if (rval != Success) result = rval; rval = FreeCo(pmap, client, BLUEMAP, count, pixels, mask & pmap->pVisual->blueMask); if (rval != Success) result = rval; } else { rmask = mask & ((((Pixel) 1) << pmap->pVisual->nplanes) - 1); result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask); } if ((mask != rmask) && count) { clients[client]->errorValue = *pixels | mask; result = BadValue; } /* XXX should worry about removing any RT_CMAPENTRY resource */ return result; } /** * Helper for FreeColors -- frees all combinations of *newpixels and mask bits * which the client has allocated in channel colormap cells of pmap. * doesn't change newpixels if it doesn't need to * * \param pmap which colormap head * \param color which sub-map, eg, RED, BLUE, PSEUDO * \param npixIn number of pixels passed in * \param ppixIn number of base pixels * \param mask mask client gave us */ static int FreeCo(ColormapPtr pmap, int client, int color, int npixIn, Pixel * ppixIn, Pixel mask) { Pixel *ppixClient, pixTest; int npixClient, npixNew, npix; Pixel bits, base, cmask, rgbbad; Pixel *pptr, *cptr; int n, zapped; int errVal = Success; int offset, numents; if (npixIn == 0) return errVal; bits = 0; zapped = 0; base = lowbit(mask); switch (color) { case REDMAP: cmask = pmap->pVisual->redMask; rgbbad = ~RGBMASK(pmap->pVisual); offset = pmap->pVisual->offsetRed; numents = (cmask >> offset) + 1; ppixClient = pmap->clientPixelsRed[client]; npixClient = pmap->numPixelsRed[client]; break; case GREENMAP: cmask = pmap->pVisual->greenMask; rgbbad = ~RGBMASK(pmap->pVisual); offset = pmap->pVisual->offsetGreen; numents = (cmask >> offset) + 1; ppixClient = pmap->clientPixelsGreen[client]; npixClient = pmap->numPixelsGreen[client]; break; case BLUEMAP: cmask = pmap->pVisual->blueMask; rgbbad = ~RGBMASK(pmap->pVisual); offset = pmap->pVisual->offsetBlue; numents = (cmask >> offset) + 1; ppixClient = pmap->clientPixelsBlue[client]; npixClient = pmap->numPixelsBlue[client]; break; default: /* so compiler can see that everything gets initialized */ case PSEUDOMAP: cmask = ~((Pixel) 0); rgbbad = 0; offset = 0; numents = pmap->pVisual->ColormapEntries; ppixClient = pmap->clientPixelsRed[client]; npixClient = pmap->numPixelsRed[client]; break; } /* zap all pixels which match */ while (1) { /* go through pixel list */ for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++) { pixTest = ((*pptr | bits) & cmask) >> offset; if ((pixTest >= numents) || (*pptr & rgbbad)) { clients[client]->errorValue = *pptr | bits; errVal = BadValue; continue; } /* find match in client list */ for (cptr = ppixClient, npix = npixClient; --npix >= 0 && *cptr != pixTest; cptr++); if (npix >= 0) { if (pmap->class & DynamicClass) { FreeCell(pmap, pixTest, color); } *cptr = ~((Pixel) 0); zapped++; } else errVal = BadAccess; } /* generate next bits value */ GetNextBitsOrBreak(bits, mask, base); } /* delete freed pixels from client pixel list */ if (zapped) { npixNew = npixClient - zapped; if (npixNew) { /* Since the list can only get smaller, we can do a copy in * place and then realloc to a smaller size */ pptr = cptr = ppixClient; /* If we have all the new pixels, we don't have to examine the * rest of the old ones */ for (npix = 0; npix < npixNew; cptr++) { if (*cptr != ~((Pixel) 0)) { *pptr++ = *cptr; npix++; } } pptr = reallocarray(ppixClient, npixNew, sizeof(Pixel)); if (pptr) ppixClient = pptr; npixClient = npixNew; } else { npixClient = 0; free(ppixClient); ppixClient = (Pixel *) NULL; } switch (color) { case PSEUDOMAP: case REDMAP: pmap->clientPixelsRed[client] = ppixClient; pmap->numPixelsRed[client] = npixClient; break; case GREENMAP: pmap->clientPixelsGreen[client] = ppixClient; pmap->numPixelsGreen[client] = npixClient; break; case BLUEMAP: pmap->clientPixelsBlue[client] = ppixClient; pmap->numPixelsBlue[client] = npixClient; break; } } return errVal; } /* Redefine color values */ int StoreColors(ColormapPtr pmap, int count, xColorItem * defs, ClientPtr client) { Pixel pix; xColorItem *pdef; EntryPtr pent, pentT, pentLast; VisualPtr pVisual; SHAREDCOLOR *pred, *pgreen, *pblue; int n, ChgRed, ChgGreen, ChgBlue, idef; int class, errVal = Success; int ok; class = pmap->class; if (!(class & DynamicClass) && !(pmap->flags & BeingCreated)) { return BadAccess; } pVisual = pmap->pVisual; idef = 0; if ((class | DynamicClass) == DirectColor) { int numred, numgreen, numblue; Pixel rgbbad; numred = NUMRED(pVisual); numgreen = NUMGREEN(pVisual); numblue = NUMBLUE(pVisual); rgbbad = ~RGBMASK(pVisual); for (pdef = defs, n = 0; n < count; pdef++, n++) { ok = TRUE; (*pmap->pScreen->ResolveColor) (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual); if (pdef->pixel & rgbbad) { errVal = BadValue; client->errorValue = pdef->pixel; continue; } pix = (pdef->pixel & pVisual->redMask) >> pVisual->offsetRed; if (pix >= numred) { errVal = BadValue; ok = FALSE; } else if (pmap->red[pix].refcnt != AllocPrivate) { errVal = BadAccess; ok = FALSE; } else if (pdef->flags & DoRed) { pmap->red[pix].co.local.red = pdef->red; } else { pdef->red = pmap->red[pix].co.local.red; } pix = (pdef->pixel & pVisual->greenMask) >> pVisual->offsetGreen; if (pix >= numgreen) { errVal = BadValue; ok = FALSE; } else if (pmap->green[pix].refcnt != AllocPrivate) { errVal = BadAccess; ok = FALSE; } else if (pdef->flags & DoGreen) { pmap->green[pix].co.local.green = pdef->green; } else { pdef->green = pmap->green[pix].co.local.green; } pix = (pdef->pixel & pVisual->blueMask) >> pVisual->offsetBlue; if (pix >= numblue) { errVal = BadValue; ok = FALSE; } else if (pmap->blue[pix].refcnt != AllocPrivate) { errVal = BadAccess; ok = FALSE; } else if (pdef->flags & DoBlue) { pmap->blue[pix].co.local.blue = pdef->blue; } else { pdef->blue = pmap->blue[pix].co.local.blue; } /* If this is an o.k. entry, then it gets added to the list * to be sent to the hardware. If not, skip it. Once we've * skipped one, we have to copy all the others. */ if (ok) { if (idef != n) defs[idef] = defs[n]; idef++; } else client->errorValue = pdef->pixel; } } else { for (pdef = defs, n = 0; n < count; pdef++, n++) { ok = TRUE; if (pdef->pixel >= pVisual->ColormapEntries) { client->errorValue = pdef->pixel; errVal = BadValue; ok = FALSE; } else if (pmap->red[pdef->pixel].refcnt != AllocPrivate) { errVal = BadAccess; ok = FALSE; } /* If this is an o.k. entry, then it gets added to the list * to be sent to the hardware. If not, skip it. Once we've * skipped one, we have to copy all the others. */ if (ok) { if (idef != n) defs[idef] = defs[n]; idef++; } else continue; (*pmap->pScreen->ResolveColor) (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual); pent = &pmap->red[pdef->pixel]; if (pdef->flags & DoRed) { if (pent->fShared) { pent->co.shco.red->color = pdef->red; if (pent->co.shco.red->refcnt > 1) ok = FALSE; } else pent->co.local.red = pdef->red; } else { if (pent->fShared) pdef->red = pent->co.shco.red->color; else pdef->red = pent->co.local.red; } if (pdef->flags & DoGreen) { if (pent->fShared) { pent->co.shco.green->color = pdef->green; if (pent->co.shco.green->refcnt > 1) ok = FALSE; } else pent->co.local.green = pdef->green; } else { if (pent->fShared) pdef->green = pent->co.shco.green->color; else pdef->green = pent->co.local.green; } if (pdef->flags & DoBlue) { if (pent->fShared) { pent->co.shco.blue->color = pdef->blue; if (pent->co.shco.blue->refcnt > 1) ok = FALSE; } else pent->co.local.blue = pdef->blue; } else { if (pent->fShared) pdef->blue = pent->co.shco.blue->color; else pdef->blue = pent->co.local.blue; } if (!ok) { /* have to run through the colormap and change anybody who * shares this value */ pred = pent->co.shco.red; pgreen = pent->co.shco.green; pblue = pent->co.shco.blue; ChgRed = pdef->flags & DoRed; ChgGreen = pdef->flags & DoGreen; ChgBlue = pdef->flags & DoBlue; pentLast = pmap->red + pVisual->ColormapEntries; for (pentT = pmap->red; pentT < pentLast; pentT++) { if (pentT->fShared && (pentT != pent)) { xColorItem defChg; /* There are, alas, devices in this world too dumb * to read their own hardware colormaps. Sick, but * true. So we're going to be really nice and load * the xColorItem with the proper value for all the * fields. We will only set the flags for those * fields that actually change. Smart devices can * arrange to change only those fields. Dumb devices * can rest assured that we have provided for them, * and can change all three fields */ defChg.flags = 0; if (ChgRed && pentT->co.shco.red == pred) { defChg.flags |= DoRed; } if (ChgGreen && pentT->co.shco.green == pgreen) { defChg.flags |= DoGreen; } if (ChgBlue && pentT->co.shco.blue == pblue) { defChg.flags |= DoBlue; } if (defChg.flags != 0) { defChg.pixel = pentT - pmap->red; defChg.red = pentT->co.shco.red->color; defChg.green = pentT->co.shco.green->color; defChg.blue = pentT->co.shco.blue->color; (*pmap->pScreen->StoreColors) (pmap, 1, &defChg); } } } } } } /* Note that we use idef, the count of acceptable entries, and not * count, the count of proposed entries */ if (idef != 0) (*pmap->pScreen->StoreColors) (pmap, idef, defs); return errVal; } int IsMapInstalled(Colormap map, WindowPtr pWin) { Colormap *pmaps; int imap, nummaps, found; pmaps = xallocarray(pWin->drawable.pScreen->maxInstalledCmaps, sizeof(Colormap)); if (!pmaps) return FALSE; nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) (pWin->drawable.pScreen, pmaps); found = FALSE; for (imap = 0; imap < nummaps; imap++) { if (pmaps[imap] == map) { found = TRUE; break; } } free(pmaps); return found; } struct colormap_lookup_data { ScreenPtr pScreen; VisualPtr visuals; }; static void _colormap_find_resource(void *value, XID id, void *cdata) { struct colormap_lookup_data *cmap_data = cdata; VisualPtr visuals = cmap_data->visuals; ScreenPtr pScreen = cmap_data->pScreen; ColormapPtr cmap = value; int j; if (pScreen != cmap->pScreen) return; j = cmap->pVisual - pScreen->visuals; cmap->pVisual = &visuals[j]; } /* something has realloced the visuals, instead of breaking ABI fix it up here - glx and compsite did this wrong */ Bool ResizeVisualArray(ScreenPtr pScreen, int new_visual_count, DepthPtr depth) { struct colormap_lookup_data cdata; int numVisuals; VisualPtr visuals; XID *vids, vid; int first_new_vid, first_new_visual, i; first_new_vid = depth->numVids; first_new_visual = pScreen->numVisuals; vids = reallocarray(depth->vids, depth->numVids + new_visual_count, sizeof(XID)); if (!vids) return FALSE; /* its realloced now no going back if we fail the next one */ depth->vids = vids; numVisuals = pScreen->numVisuals + new_visual_count; visuals = reallocarray(pScreen->visuals, numVisuals, sizeof(VisualRec)); if (!visuals) { return FALSE; } cdata.visuals = visuals; cdata.pScreen = pScreen; FindClientResourcesByType(serverClient, RT_COLORMAP, _colormap_find_resource, &cdata); pScreen->visuals = visuals; for (i = 0; i < new_visual_count; i++) { vid = FakeClientID(0); pScreen->visuals[first_new_visual + i].vid = vid; vids[first_new_vid + i] = vid; } depth->numVids += new_visual_count; pScreen->numVisuals += new_visual_count; return TRUE; } xorg-server-1.20.13/dix/cursor.c0000644000175000017500000003617614100573755013353 00000000000000/*********************************************************** Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include #include "servermd.h" #include "scrnintstr.h" #include "dixstruct.h" #include "cursorstr.h" #include "dixfontstr.h" #include "opaque.h" #include "inputstr.h" #include "xace.h" typedef struct _GlyphShare { FontPtr font; unsigned short sourceChar; unsigned short maskChar; CursorBitsPtr bits; struct _GlyphShare *next; } GlyphShare, *GlyphSharePtr; static GlyphSharePtr sharedGlyphs = (GlyphSharePtr) NULL; DevScreenPrivateKeyRec cursorScreenDevPriv; static CARD32 cursorSerial; static void FreeCursorBits(CursorBitsPtr bits) { if (--bits->refcnt > 0) return; free(bits->source); free(bits->mask); free(bits->argb); dixFiniPrivates(bits, PRIVATE_CURSOR_BITS); if (bits->refcnt == 0) { GlyphSharePtr *prev, this; for (prev = &sharedGlyphs; (this = *prev) && (this->bits != bits); prev = &this->next); if (this) { *prev = this->next; CloseFont(this->font, (Font) 0); free(this); } free(bits); } } /** * To be called indirectly by DeleteResource; must use exactly two args. * * \param value must conform to DeleteType */ int FreeCursor(void *value, XID cid) { int nscr; CursorPtr pCurs = (CursorPtr) value; ScreenPtr pscr; DeviceIntPtr pDev = NULL; /* unused anyway */ UnrefCursor(pCurs); if (CursorRefCount(pCurs) != 0) return Success; BUG_WARN(CursorRefCount(pCurs) < 0); for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { pscr = screenInfo.screens[nscr]; (void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs); } FreeCursorBits(pCurs->bits); dixFiniPrivates(pCurs, PRIVATE_CURSOR); free(pCurs); return Success; } CursorPtr RefCursor(CursorPtr cursor) { if (cursor) cursor->refcnt++; return cursor; } CursorPtr UnrefCursor(CursorPtr cursor) { if (cursor) cursor->refcnt--; return cursor; } int CursorRefCount(const CursorPtr cursor) { return cursor ? cursor->refcnt : 0; } /* * We check for empty cursors so that we won't have to display them */ static void CheckForEmptyMask(CursorBitsPtr bits) { unsigned char *msk = bits->mask; int n = BitmapBytePad(bits->width) * bits->height; bits->emptyMask = FALSE; while (n--) if (*(msk++) != 0) return; if (bits->argb) { CARD32 *argb = bits->argb; n = bits->width * bits->height; while (n--) if (*argb++ & 0xff000000) return; } bits->emptyMask = TRUE; } /** * realize the cursor for every screen. Do not change the refcnt, this will be * changed when ChangeToCursor actually changes the sprite. * * @return Success if all cursors realize on all screens, BadAlloc if realize * failed for a device on a given screen. */ static int RealizeCursorAllScreens(CursorPtr pCurs) { DeviceIntPtr pDev; ScreenPtr pscr; int nscr; for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { pscr = screenInfo.screens[nscr]; for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { if (DevHasCursor(pDev)) { if (!(*pscr->RealizeCursor) (pDev, pscr, pCurs)) { /* Realize failed for device pDev on screen pscr. * We have to assume that for all devices before, realize * worked. We need to rollback all devices so far on the * current screen and then all devices on previous * screens. */ DeviceIntPtr pDevIt = inputInfo.devices; /*dev iterator */ while (pDevIt && pDevIt != pDev) { if (DevHasCursor(pDevIt)) (*pscr->UnrealizeCursor) (pDevIt, pscr, pCurs); pDevIt = pDevIt->next; } while (--nscr >= 0) { pscr = screenInfo.screens[nscr]; /* now unrealize all devices on previous screens */ pDevIt = inputInfo.devices; while (pDevIt) { if (DevHasCursor(pDevIt)) (*pscr->UnrealizeCursor) (pDevIt, pscr, pCurs); pDevIt = pDevIt->next; } (*pscr->UnrealizeCursor) (pDev, pscr, pCurs); } return BadAlloc; } } } } return Success; } /** * does nothing about the resource table, just creates the data structure. * does not copy the src and mask bits * * \param psrcbits server-defined padding * \param pmaskbits server-defined padding * \param argb no padding */ int AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits, CARD32 *argb, CursorMetricPtr cm, unsigned foreRed, unsigned foreGreen, unsigned foreBlue, unsigned backRed, unsigned backGreen, unsigned backBlue, CursorPtr *ppCurs, ClientPtr client, XID cid) { CursorBitsPtr bits; CursorPtr pCurs; int rc; *ppCurs = NULL; pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE + CURSOR_BITS_SIZE, 1); if (!pCurs) return BadAlloc; bits = (CursorBitsPtr) ((char *) pCurs + CURSOR_REC_SIZE); dixInitPrivates(pCurs, pCurs + 1, PRIVATE_CURSOR); dixInitPrivates(bits, bits + 1, PRIVATE_CURSOR_BITS) bits->source = psrcbits; bits->mask = pmaskbits; bits->argb = argb; bits->width = cm->width; bits->height = cm->height; bits->xhot = cm->xhot; bits->yhot = cm->yhot; pCurs->refcnt = 1; bits->refcnt = -1; CheckForEmptyMask(bits); pCurs->bits = bits; pCurs->serialNumber = ++cursorSerial; pCurs->name = None; pCurs->foreRed = foreRed; pCurs->foreGreen = foreGreen; pCurs->foreBlue = foreBlue; pCurs->backRed = backRed; pCurs->backGreen = backGreen; pCurs->backBlue = backBlue; pCurs->id = cid; /* security creation/labeling check */ rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, pCurs, RT_NONE, NULL, DixCreateAccess); if (rc != Success) goto error; rc = RealizeCursorAllScreens(pCurs); if (rc != Success) goto error; *ppCurs = pCurs; if (argb) { size_t i, size = bits->width * bits->height; for (i = 0; i < size; i++) { if ((argb[i] & 0xff000000) == 0 && (argb[i] & 0xffffff) != 0) { /* ARGB data doesn't seem pre-multiplied, fix it */ for (i = 0; i < size; i++) { CARD32 a, ar, ag, ab; a = argb[i] >> 24; ar = a * ((argb[i] >> 16) & 0xff) / 0xff; ag = a * ((argb[i] >> 8) & 0xff) / 0xff; ab = a * (argb[i] & 0xff) / 0xff; argb[i] = a << 24 | ar << 16 | ag << 8 | ab; } break; } } } return Success; error: FreeCursorBits(bits); dixFiniPrivates(pCurs, PRIVATE_CURSOR); free(pCurs); return rc; } int AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, unsigned foreRed, unsigned foreGreen, unsigned foreBlue, unsigned backRed, unsigned backGreen, unsigned backBlue, CursorPtr *ppCurs, ClientPtr client, XID cid) { FontPtr sourcefont, maskfont; unsigned char *srcbits; unsigned char *mskbits; CursorMetricRec cm; int rc; CursorBitsPtr bits; CursorPtr pCurs; GlyphSharePtr pShare; rc = dixLookupResourceByType((void **) &sourcefont, source, RT_FONT, client, DixUseAccess); if (rc != Success) { client->errorValue = source; return rc; } rc = dixLookupResourceByType((void **) &maskfont, mask, RT_FONT, client, DixUseAccess); if (rc != Success && mask != None) { client->errorValue = mask; return rc; } if (sourcefont != maskfont) pShare = (GlyphSharePtr) NULL; else { for (pShare = sharedGlyphs; pShare && ((pShare->font != sourcefont) || (pShare->sourceChar != sourceChar) || (pShare->maskChar != maskChar)); pShare = pShare->next); } if (pShare) { pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE, 1); if (!pCurs) return BadAlloc; dixInitPrivates(pCurs, pCurs + 1, PRIVATE_CURSOR); bits = pShare->bits; bits->refcnt++; } else { if (!CursorMetricsFromGlyph(sourcefont, sourceChar, &cm)) { client->errorValue = sourceChar; return BadValue; } if (!maskfont) { long n; unsigned char *mskptr; n = BitmapBytePad(cm.width) * (long) cm.height; mskptr = mskbits = malloc(n); if (!mskptr) return BadAlloc; while (--n >= 0) *mskptr++ = ~0; } else { if (!CursorMetricsFromGlyph(maskfont, maskChar, &cm)) { client->errorValue = maskChar; return BadValue; } if ((rc = ServerBitsFromGlyph(maskfont, maskChar, &cm, &mskbits))) return rc; } if ((rc = ServerBitsFromGlyph(sourcefont, sourceChar, &cm, &srcbits))) { free(mskbits); return rc; } if (sourcefont != maskfont) { pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE + CURSOR_BITS_SIZE, 1); if (pCurs) bits = (CursorBitsPtr) ((char *) pCurs + CURSOR_REC_SIZE); else bits = (CursorBitsPtr) NULL; } else { pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE, 1); if (pCurs) bits = (CursorBitsPtr) calloc(CURSOR_BITS_SIZE, 1); else bits = (CursorBitsPtr) NULL; } if (!bits) { free(pCurs); free(mskbits); free(srcbits); return BadAlloc; } dixInitPrivates(pCurs, pCurs + 1, PRIVATE_CURSOR); dixInitPrivates(bits, bits + 1, PRIVATE_CURSOR_BITS); bits->source = srcbits; bits->mask = mskbits; bits->argb = 0; bits->width = cm.width; bits->height = cm.height; bits->xhot = cm.xhot; bits->yhot = cm.yhot; if (sourcefont != maskfont) bits->refcnt = -1; else { bits->refcnt = 1; pShare = malloc(sizeof(GlyphShare)); if (!pShare) { FreeCursorBits(bits); return BadAlloc; } pShare->font = sourcefont; sourcefont->refcnt++; pShare->sourceChar = sourceChar; pShare->maskChar = maskChar; pShare->bits = bits; pShare->next = sharedGlyphs; sharedGlyphs = pShare; } } CheckForEmptyMask(bits); pCurs->bits = bits; pCurs->refcnt = 1; pCurs->serialNumber = ++cursorSerial; pCurs->name = None; pCurs->foreRed = foreRed; pCurs->foreGreen = foreGreen; pCurs->foreBlue = foreBlue; pCurs->backRed = backRed; pCurs->backGreen = backGreen; pCurs->backBlue = backBlue; pCurs->id = cid; /* security creation/labeling check */ rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, pCurs, RT_NONE, NULL, DixCreateAccess); if (rc != Success) goto error; rc = RealizeCursorAllScreens(pCurs); if (rc != Success) goto error; *ppCurs = pCurs; return Success; error: FreeCursorBits(bits); dixFiniPrivates(pCurs, PRIVATE_CURSOR); free(pCurs); return rc; } /** CreateRootCursor * * look up the name of a font * open the font * add the font to the resource table * make a cursor from the glyphs * add the cursor to the resource table *************************************************************/ CursorPtr CreateRootCursor(char *unused1, unsigned int unused2) { CursorPtr curs; FontPtr cursorfont; int err; XID fontID; fontID = FakeClientID(0); err = OpenFont(serverClient, fontID, FontLoadAll | FontOpenSync, (unsigned) strlen(defaultCursorFont), defaultCursorFont); if (err != Success) return NullCursor; err = dixLookupResourceByType((void **) &cursorfont, fontID, RT_FONT, serverClient, DixReadAccess); if (err != Success) return NullCursor; if (AllocGlyphCursor(fontID, 0, fontID, 1, 0, 0, 0, ~0, ~0, ~0, &curs, serverClient, (XID) 0) != Success) return NullCursor; if (!AddResource(FakeClientID(0), RT_CURSOR, (void *) curs)) return NullCursor; return curs; } xorg-server-1.20.13/dix/devices.c0000644000175000017500000023717014100573755013455 00000000000000/************************************************************ Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include "misc.h" #include "resource.h" #include #include #include "windowstr.h" #include "inputstr.h" #include "scrnintstr.h" #include "cursorstr.h" #include "dixstruct.h" #include "ptrveloc.h" #include "site.h" #include "xkbsrv.h" #include "privates.h" #include "xace.h" #include "mi.h" #include "dispatch.h" #include "swaprep.h" #include "dixevents.h" #include "mipointer.h" #include "eventstr.h" #include "dixgrabs.h" #include #include #include #include #include #include "exglobals.h" #include "exevents.h" #include "xiquerydevice.h" /* for SizeDeviceClasses */ #include "xiproperty.h" #include "enterleave.h" /* for EnterWindow() */ #include "xserver-properties.h" #include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */ #include "syncsrv.h" /** @file * This file handles input device-related stuff. */ static void RecalculateMasterButtons(DeviceIntPtr slave); static void DeviceSetTransform(DeviceIntPtr dev, float *transform_data) { struct pixman_f_transform scale; struct pixman_f_transform transform; double sx, sy; int x, y; /** * calculate combined transformation matrix: * * M = InvScale * Transform * Scale * * So we can later transform points using M * p * * Where: * Scale scales coordinates into 0..1 range * Transform is the user supplied (affine) transform * InvScale scales coordinates back up into their native range */ sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value + 1; sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value + 1; /* invscale */ pixman_f_transform_init_scale(&scale, sx, sy); scale.m[0][2] = dev->valuator->axes[0].min_value; scale.m[1][2] = dev->valuator->axes[1].min_value; /* transform */ for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) transform.m[y][x] = *transform_data++; pixman_f_transform_multiply(&dev->scale_and_transform, &scale, &transform); /* scale */ pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy); scale.m[0][2] = -dev->valuator->axes[0].min_value / sx; scale.m[1][2] = -dev->valuator->axes[1].min_value / sy; pixman_f_transform_multiply(&dev->scale_and_transform, &dev->scale_and_transform, &scale); /* remove translation component for relative movements */ dev->relative_transform = transform; dev->relative_transform.m[0][2] = 0; dev->relative_transform.m[1][2] = 0; } /** * DIX property handler. */ static int DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, BOOL checkonly) { if (property == XIGetKnownProperty(XI_PROP_ENABLED)) { if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1) return BadValue; /* Don't allow disabling of VCP/VCK or XTest devices */ if ((dev == inputInfo.pointer || dev == inputInfo.keyboard || IsXTestDevice(dev, NULL)) &&!(*(CARD8 *) prop->data)) return BadAccess; if (!checkonly) { if ((*((CARD8 *) prop->data)) && !dev->enabled) EnableDevice(dev, TRUE); else if (!(*((CARD8 *) prop->data)) && dev->enabled) DisableDevice(dev, TRUE); } } else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM)) { float *f = (float *) prop->data; int i; if (prop->format != 32 || prop->size != 9 || prop->type != XIGetKnownProperty(XATOM_FLOAT)) return BadValue; for (i = 0; i < 9; i++) if (!isfinite(f[i])) return BadValue; if (!dev->valuator) return BadMatch; if (!checkonly) DeviceSetTransform(dev, f); } return Success; } /* Pair the keyboard to the pointer device. Keyboard events will follow the * pointer sprite. Only applicable for master devices. */ static int PairDevices(DeviceIntPtr ptr, DeviceIntPtr kbd) { if (!ptr) return BadDevice; /* Don't allow pairing for slave devices */ if (!IsMaster(ptr) || !IsMaster(kbd)) return BadDevice; if (ptr->spriteInfo->paired) return BadDevice; if (kbd->spriteInfo->spriteOwner) { free(kbd->spriteInfo->sprite); kbd->spriteInfo->sprite = NULL; kbd->spriteInfo->spriteOwner = FALSE; } kbd->spriteInfo->sprite = ptr->spriteInfo->sprite; kbd->spriteInfo->paired = ptr; ptr->spriteInfo->paired = kbd; return Success; } /** * Find and return the next unpaired MD pointer device. */ static DeviceIntPtr NextFreePointerDevice(void) { DeviceIntPtr dev; for (dev = inputInfo.devices; dev; dev = dev->next) if (IsMaster(dev) && dev->spriteInfo->spriteOwner && !dev->spriteInfo->paired) return dev; return NULL; } /** * Create a new input device and init it to sane values. The device is added * to the server's off_devices list. * * @param deviceProc Callback for device control function (switch dev on/off). * @return The newly created device. */ DeviceIntPtr AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) { DeviceIntPtr dev, *prev; /* not a typo */ DeviceIntPtr devtmp; int devid; char devind[MAXDEVICES]; BOOL enabled; float transform[9]; /* Find next available id, 0 and 1 are reserved */ memset(devind, 0, sizeof(char) * MAXDEVICES); for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next) devind[devtmp->id]++; for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next) devind[devtmp->id]++; for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++); if (devid >= MAXDEVICES) return (DeviceIntPtr) NULL; dev = calloc(1, sizeof(DeviceIntRec) + sizeof(SpriteInfoRec)); if (!dev) return (DeviceIntPtr) NULL; if (!dixAllocatePrivates(&dev->devPrivates, PRIVATE_DEVICE)) { free(dev); return NULL; } if (!dev) return (DeviceIntPtr) NULL; dev->last.scroll = NULL; dev->last.touches = NULL; dev->id = devid; dev->public.processInputProc = ProcessOtherEvent; dev->public.realInputProc = ProcessOtherEvent; dev->public.enqueueInputProc = EnqueueEvent; dev->deviceProc = deviceProc; dev->startup = autoStart; /* device grab defaults */ UpdateCurrentTimeIf(); dev->deviceGrab.grabTime = currentTime; dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab; dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent)); XkbSetExtension(dev, ProcessKeyboardEvent); dev->coreEvents = TRUE; /* sprite defaults */ dev->spriteInfo = (SpriteInfoPtr) &dev[1]; /* security creation/labeling check */ if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) { dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE); free(dev); return NULL; } inputInfo.numDevices++; for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next); *prev = dev; dev->next = NULL; enabled = FALSE; XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), XA_INTEGER, 8, PropModeReplace, 1, &enabled, FALSE); XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), FALSE); /* unity matrix */ memset(transform, 0, sizeof(transform)); transform[0] = transform[4] = transform[8] = 1.0f; dev->relative_transform.m[0][0] = 1.0; dev->relative_transform.m[1][1] = 1.0; dev->relative_transform.m[2][2] = 1.0; dev->scale_and_transform = dev->relative_transform; XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM), XIGetKnownProperty(XATOM_FLOAT), 32, PropModeReplace, 9, transform, FALSE); XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM), FALSE); XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL); return dev; } void SendDevicePresenceEvent(int deviceid, int type) { DeviceIntRec dummyDev = { .id = XIAllDevices }; devicePresenceNotify ev; UpdateCurrentTimeIf(); ev.type = DevicePresenceNotify; ev.time = currentTime.milliseconds; ev.devchange = type; ev.deviceid = deviceid; SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, (xEvent *) &ev, 1); } /** * Enable the device through the driver, add the device to the device list. * Switch device ON through the driver and push it onto the global device * list. Initialize the DIX sprite or pair the device. All clients are * notified about the device being enabled. * * A master pointer device needs to be enabled before a master keyboard * device. * * @param The device to be enabled. * @param sendevent True if an XI2 event should be sent. * @return TRUE on success or FALSE otherwise. */ Bool EnableDevice(DeviceIntPtr dev, BOOL sendevent) { DeviceIntPtr *prev; int ret; DeviceIntPtr other; BOOL enabled; int flags[MAXDEVICES] = { 0 }; for (prev = &inputInfo.off_devices; *prev && (*prev != dev); prev = &(*prev)->next); if (!dev->spriteInfo->sprite) { if (IsMaster(dev)) { /* Sprites appear on first root window, so we can hardcode it */ if (dev->spriteInfo->spriteOwner) { InitializeSprite(dev, screenInfo.screens[0]->root); /* mode doesn't matter */ EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor); } else { other = NextFreePointerDevice(); BUG_RETURN_VAL_MSG(other == NULL, FALSE, "[dix] cannot find pointer to pair with.\n"); PairDevices(other, dev); } } else { if (dev->coreEvents) other = (IsPointerDevice(dev)) ? inputInfo.pointer: inputInfo.keyboard; else other = NULL; /* auto-float non-core devices */ AttachDevice(NULL, dev, other); } } input_lock(); if ((*prev != dev) || !dev->inited || ((ret = (*dev->deviceProc) (dev, DEVICE_ON)) != Success)) { ErrorF("[dix] couldn't enable device %d\n", dev->id); input_unlock(); return FALSE; } dev->enabled = TRUE; *prev = dev->next; for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next); *prev = dev; dev->next = NULL; input_unlock(); enabled = TRUE; XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE); SendDevicePresenceEvent(dev->id, DeviceEnabled); if (sendevent) { flags[dev->id] |= XIDeviceEnabled; XISendDeviceHierarchyEvent(flags); } if (!IsMaster(dev) && !IsFloating(dev)) XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0); RecalculateMasterButtons(dev); /* initialise an idle timer for this device*/ dev->idle_counter = SyncInitDeviceIdleTime(dev); return TRUE; } /** * Switch a device off through the driver and push it onto the off_devices * list. A device will not send events while disabled. All clients are * notified about the device being disabled. * * Master keyboard devices have to be disabled before master pointer devices * otherwise things turn bad. * * @param sendevent True if an XI2 event should be sent. * @return TRUE on success or FALSE otherwise. */ Bool DisableDevice(DeviceIntPtr dev, BOOL sendevent) { DeviceIntPtr *prev, other; BOOL enabled; int flags[MAXDEVICES] = { 0 }; if (!dev->enabled) return TRUE; for (prev = &inputInfo.devices; *prev && (*prev != dev); prev = &(*prev)->next); if (*prev != dev) return FALSE; TouchEndPhysicallyActiveTouches(dev); ReleaseButtonsAndKeys(dev); SyncRemoveDeviceIdleTime(dev->idle_counter); dev->idle_counter = NULL; /* float attached devices */ if (IsMaster(dev)) { for (other = inputInfo.devices; other; other = other->next) { if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) { AttachDevice(NULL, other, NULL); flags[other->id] |= XISlaveDetached; } } } else { for (other = inputInfo.devices; other; other = other->next) { if (IsMaster(other) && other->lastSlave == dev) other->lastSlave = NULL; } } if (IsMaster(dev) && dev->spriteInfo->sprite) { for (other = inputInfo.devices; other; other = other->next) if (other->spriteInfo->paired == dev && !other->spriteInfo->spriteOwner) DisableDevice(other, sendevent); } if (dev->spriteInfo->paired) dev->spriteInfo->paired = NULL; input_lock(); (void) (*dev->deviceProc) (dev, DEVICE_OFF); dev->enabled = FALSE; /* now that the device is disabled, we can reset the event reader's * last.slave */ for (other = inputInfo.devices; other; other = other->next) { if (other->last.slave == dev) other->last.slave = NULL; } input_unlock(); FreeSprite(dev); LeaveWindow(dev); SetFocusOut(dev); *prev = dev->next; dev->next = inputInfo.off_devices; inputInfo.off_devices = dev; enabled = FALSE; XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE); SendDevicePresenceEvent(dev->id, DeviceDisabled); if (sendevent) { flags[dev->id] = XIDeviceDisabled; XISendDeviceHierarchyEvent(flags); } RecalculateMasterButtons(dev); return TRUE; } void DisableAllDevices(void) { DeviceIntPtr dev, tmp; /* Disable slave devices first, excluding XTest devices */ nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { if (!IsXTestDevice(dev, NULL) && !IsMaster(dev)) DisableDevice(dev, FALSE); } /* Disable XTest devices */ nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { if (!IsMaster(dev)) DisableDevice(dev, FALSE); } /* master keyboards need to be disabled first */ nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { if (dev->enabled && IsMaster(dev) && IsKeyboardDevice(dev)) DisableDevice(dev, FALSE); } nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { if (dev->enabled) DisableDevice(dev, FALSE); } } /** * Initialise a new device through the driver and tell all clients about the * new device. * * Must be called before EnableDevice. * The device will NOT send events until it is enabled! * * @param sendevent True if an XI2 event should be sent. * @return Success or an error code on failure. */ int ActivateDevice(DeviceIntPtr dev, BOOL sendevent) { int ret = Success; ScreenPtr pScreen = screenInfo.screens[0]; if (!dev || !dev->deviceProc) return BadImplementation; input_lock(); ret = (*dev->deviceProc) (dev, DEVICE_INIT); input_unlock(); dev->inited = (ret == Success); if (!dev->inited) return ret; /* Initialize memory for sprites. */ if (IsMaster(dev) && dev->spriteInfo->spriteOwner) if (!pScreen->DeviceCursorInitialize(dev, pScreen)) ret = BadAlloc; SendDevicePresenceEvent(dev->id, DeviceAdded); if (sendevent) { int flags[MAXDEVICES] = { 0 }; flags[dev->id] = XISlaveAdded; XISendDeviceHierarchyEvent(flags); } return ret; } /** * Ring the bell. * The actual task of ringing the bell is the job of the DDX. */ static void CoreKeyboardBell(int volume, DeviceIntPtr pDev, void *arg, int something) { KeybdCtrl *ctrl = arg; DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration); } static void CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl * ctrl) { return; } /** * Device control function for the Virtual Core Keyboard. */ int CoreKeyboardProc(DeviceIntPtr pDev, int what) { switch (what) { case DEVICE_INIT: if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell, CoreKeyboardCtl)) { ErrorF("Keyboard initialization failed. This could be a missing " "or incorrect setup of xkeyboard-config.\n"); return BadValue; } return Success; case DEVICE_ON: case DEVICE_OFF: return Success; case DEVICE_CLOSE: return Success; } return BadMatch; } /** * Device control function for the Virtual Core Pointer. */ int CorePointerProc(DeviceIntPtr pDev, int what) { #define NBUTTONS 10 #define NAXES 2 BYTE map[NBUTTONS + 1]; int i = 0; Atom btn_labels[NBUTTONS] = { 0 }; Atom axes_labels[NAXES] = { 0 }; ScreenPtr scr = screenInfo.screens[0]; switch (what) { case DEVICE_INIT: for (i = 1; i <= NBUTTONS; i++) map[i] = i; btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); /* don't know about the rest */ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); if (!InitPointerDeviceStruct ((DevicePtr) pDev, map, NBUTTONS, btn_labels, (PtrCtrlProcPtr) NoopDDA, GetMotionHistorySize(), NAXES, axes_labels)) { ErrorF("Could not initialize device '%s'. Out of memory.\n", pDev->name); return BadAlloc; /* IPDS only fails on allocs */ } /* axisVal is per-screen, last.valuators is desktop-wide */ pDev->valuator->axisVal[0] = scr->width / 2; pDev->last.valuators[0] = pDev->valuator->axisVal[0] + scr->x; pDev->valuator->axisVal[1] = scr->height / 2; pDev->last.valuators[1] = pDev->valuator->axisVal[1] + scr->y; break; case DEVICE_CLOSE: break; default: break; } return Success; #undef NBUTTONS #undef NAXES } /** * Initialise the two core devices, VCP and VCK (see events.c). * Both devices are not tied to physical devices, but guarantee that there is * always a keyboard and a pointer present and keep the protocol semantics. * * Note that the server MUST have two core devices at all times, even if there * is no physical device connected. */ void InitCoreDevices(void) { int result; result = AllocDevicePair(serverClient, "Virtual core", &inputInfo.pointer, &inputInfo.keyboard, CorePointerProc, CoreKeyboardProc, TRUE); if (result != Success) { FatalError("Failed to allocate virtual core devices: %d", result); } result = ActivateDevice(inputInfo.pointer, TRUE); if (result != Success) { FatalError("Failed to activate virtual core pointer: %d", result); } result = ActivateDevice(inputInfo.keyboard, TRUE); if (result != Success) { FatalError("Failed to activate virtual core keyboard: %d", result); } if (!EnableDevice(inputInfo.pointer, TRUE)) { FatalError("Failed to enable virtual core pointer."); } if (!EnableDevice(inputInfo.keyboard, TRUE)) { FatalError("Failed to enable virtual core keyboard."); } InitXTestDevices(); } /** * Activate all switched-off devices and then enable all those devices. * * Will return an error if no core keyboard or core pointer is present. * In theory this should never happen if you call InitCoreDevices() first. * * InitAndStartDevices needs to be called AFTER the windows are initialized. * Devices will start sending events after InitAndStartDevices() has * completed. * * @return Success or error code on failure. */ int InitAndStartDevices(void) { DeviceIntPtr dev, next; for (dev = inputInfo.off_devices; dev; dev = dev->next) { DebugF("(dix) initialising device %d\n", dev->id); if (!dev->inited) ActivateDevice(dev, TRUE); } /* enable real devices */ for (dev = inputInfo.off_devices; dev; dev = next) { DebugF("(dix) enabling device %d\n", dev->id); next = dev->next; if (dev->inited && dev->startup) EnableDevice(dev, TRUE); } return Success; } /** * Free the given device class and reset the pointer to NULL. */ static void FreeDeviceClass(int type, void **class) { if (!(*class)) return; switch (type) { case KeyClass: { KeyClassPtr *k = (KeyClassPtr *) class; if ((*k)->xkbInfo) { XkbFreeInfo((*k)->xkbInfo); (*k)->xkbInfo = NULL; } free((*k)); break; } case ButtonClass: { ButtonClassPtr *b = (ButtonClassPtr *) class; free((*b)->xkb_acts); free((*b)); break; } case ValuatorClass: { ValuatorClassPtr *v = (ValuatorClassPtr *) class; free((*v)->motion); free((*v)); break; } case XITouchClass: { TouchClassPtr *t = (TouchClassPtr *) class; int i; for (i = 0; i < (*t)->num_touches; i++) { free((*t)->touches[i].sprite.spriteTrace); free((*t)->touches[i].listeners); free((*t)->touches[i].valuators); } free((*t)->touches); free((*t)); break; } case FocusClass: { FocusClassPtr *f = (FocusClassPtr *) class; free((*f)->trace); free((*f)); break; } case ProximityClass: { ProximityClassPtr *p = (ProximityClassPtr *) class; free((*p)); break; } } *class = NULL; } static void FreeFeedbackClass(int type, void **class) { if (!(*class)) return; switch (type) { case KbdFeedbackClass: { KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr *) class; KbdFeedbackPtr k, knext; for (k = (*kbdfeed); k; k = knext) { knext = k->next; if (k->xkb_sli) XkbFreeSrvLedInfo(k->xkb_sli); free(k); } break; } case PtrFeedbackClass: { PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr *) class; PtrFeedbackPtr p, pnext; for (p = (*ptrfeed); p; p = pnext) { pnext = p->next; free(p); } break; } case IntegerFeedbackClass: { IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr *) class; IntegerFeedbackPtr i, inext; for (i = (*intfeed); i; i = inext) { inext = i->next; free(i); } break; } case StringFeedbackClass: { StringFeedbackPtr *stringfeed = (StringFeedbackPtr *) class; StringFeedbackPtr s, snext; for (s = (*stringfeed); s; s = snext) { snext = s->next; free(s->ctrl.symbols_supported); free(s->ctrl.symbols_displayed); free(s); } break; } case BellFeedbackClass: { BellFeedbackPtr *bell = (BellFeedbackPtr *) class; BellFeedbackPtr b, bnext; for (b = (*bell); b; b = bnext) { bnext = b->next; free(b); } break; } case LedFeedbackClass: { LedFeedbackPtr *leds = (LedFeedbackPtr *) class; LedFeedbackPtr l, lnext; for (l = (*leds); l; l = lnext) { lnext = l->next; if (l->xkb_sli) XkbFreeSrvLedInfo(l->xkb_sli); free(l); } break; } } *class = NULL; } static void FreeAllDeviceClasses(ClassesPtr classes) { if (!classes) return; FreeDeviceClass(KeyClass, (void *) &classes->key); FreeDeviceClass(ValuatorClass, (void *) &classes->valuator); FreeDeviceClass(XITouchClass, (void *) &classes->touch); FreeDeviceClass(ButtonClass, (void *) &classes->button); FreeDeviceClass(FocusClass, (void *) &classes->focus); FreeDeviceClass(ProximityClass, (void *) &classes->proximity); FreeFeedbackClass(KbdFeedbackClass, (void *) &classes->kbdfeed); FreeFeedbackClass(PtrFeedbackClass, (void *) &classes->ptrfeed); FreeFeedbackClass(IntegerFeedbackClass, (void *) &classes->intfeed); FreeFeedbackClass(StringFeedbackClass, (void *) &classes->stringfeed); FreeFeedbackClass(BellFeedbackClass, (void *) &classes->bell); FreeFeedbackClass(LedFeedbackClass, (void *) &classes->leds); } /** * Close down a device and free all resources. * Once closed down, the driver will probably not expect you that you'll ever * enable it again and free associated structs. If you want the device to just * be disabled, DisableDevice(). * Don't call this function directly, use RemoveDevice() instead. * * Called with input lock held. */ static void CloseDevice(DeviceIntPtr dev) { ScreenPtr screen = screenInfo.screens[0]; ClassesPtr classes; int j; if (!dev) return; XIDeleteAllDeviceProperties(dev); if (dev->inited) (void) (*dev->deviceProc) (dev, DEVICE_CLOSE); FreeSprite(dev); if (IsMaster(dev)) screen->DeviceCursorCleanup(dev, screen); /* free acceleration info */ if (dev->valuator && dev->valuator->accelScheme.AccelCleanupProc) dev->valuator->accelScheme.AccelCleanupProc(dev); while (dev->xkb_interest) XkbRemoveResourceClient((DevicePtr) dev, dev->xkb_interest->resource); free(dev->name); classes = (ClassesPtr) &dev->key; FreeAllDeviceClasses(classes); if (IsMaster(dev)) { classes = dev->unused_classes; FreeAllDeviceClasses(classes); free(classes); } /* a client may have the device set as client pointer */ for (j = 0; j < currentMaxClients; j++) { if (clients[j] && clients[j]->clientPtr == dev) { clients[j]->clientPtr = NULL; clients[j]->clientPtr = PickPointer(clients[j]); } } if (dev->deviceGrab.grab) FreeGrab(dev->deviceGrab.grab); free(dev->deviceGrab.sync.event); free(dev->config_info); /* Allocated in xf86ActivateDevice. */ free(dev->last.scroll); for (j = 0; j < dev->last.num_touches; j++) free(dev->last.touches[j].valuators); free(dev->last.touches); dev->config_info = NULL; dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE); free(dev); } /** * Shut down all devices of one list and free all resources. */ static void CloseDeviceList(DeviceIntPtr *listHead) { /* Used to mark devices that we tried to free */ Bool freedIds[MAXDEVICES]; DeviceIntPtr dev; int i; if (listHead == NULL) return; for (i = 0; i < MAXDEVICES; i++) freedIds[i] = FALSE; dev = *listHead; while (dev != NULL) { freedIds[dev->id] = TRUE; DeleteInputDeviceRequest(dev); dev = *listHead; while (dev != NULL && freedIds[dev->id]) dev = dev->next; } } /** * Shut down all devices, free all resources, etc. * Only useful if you're shutting down the server! */ void CloseDownDevices(void) { DeviceIntPtr dev; input_lock(); /* Float all SDs before closing them. Note that at this point resources * (e.g. cursors) have been freed already, so we can't just call * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master * to NULL and pretend nothing happened. */ for (dev = inputInfo.devices; dev; dev = dev->next) { if (!IsMaster(dev) && !IsFloating(dev)) dev->master = NULL; } CloseDeviceList(&inputInfo.devices); CloseDeviceList(&inputInfo.off_devices); CloseDevice(inputInfo.pointer); CloseDevice(inputInfo.keyboard); inputInfo.devices = NULL; inputInfo.off_devices = NULL; inputInfo.keyboard = NULL; inputInfo.pointer = NULL; XkbDeleteRulesDflts(); XkbDeleteRulesUsed(); input_unlock(); } /** * Signal all devices that we're in the process of aborting. * This function is called from a signal handler. */ void AbortDevices(void) { DeviceIntPtr dev; /* Do not call input_lock as we don't know what * state the input thread might be in, and that could * cause a dead-lock. */ nt_list_for_each_entry(dev, inputInfo.devices, next) { if (!IsMaster(dev)) (*dev->deviceProc) (dev, DEVICE_ABORT); } nt_list_for_each_entry(dev, inputInfo.off_devices, next) { if (!IsMaster(dev)) (*dev->deviceProc) (dev, DEVICE_ABORT); } } /** * Remove the cursor sprite for all devices. This needs to be done before any * resources are freed or any device is deleted. */ void UndisplayDevices(void) { DeviceIntPtr dev; ScreenPtr screen = screenInfo.screens[0]; for (dev = inputInfo.devices; dev; dev = dev->next) screen->DisplayCursor(dev, screen, NullCursor); } /** * Remove a device from the device list, closes it and thus frees all * resources. * Removes both enabled and disabled devices and notifies all devices about * the removal of the device. * * No PresenceNotify is sent for device that the client never saw. This can * happen if a malloc fails during the addition of master devices. If * dev->init is FALSE it means the client never received a DeviceAdded event, * so let's not send a DeviceRemoved event either. * * @param sendevent True if an XI2 event should be sent. */ int RemoveDevice(DeviceIntPtr dev, BOOL sendevent) { DeviceIntPtr prev, tmp, next; int ret = BadMatch; ScreenPtr screen = screenInfo.screens[0]; int deviceid; int initialized; int flags[MAXDEVICES] = { 0 }; DebugF("(dix) removing device %d\n", dev->id); if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer) return BadImplementation; initialized = dev->inited; deviceid = dev->id; if (initialized) { if (DevHasCursor(dev)) screen->DisplayCursor(dev, screen, NullCursor); DisableDevice(dev, sendevent); flags[dev->id] = XIDeviceDisabled; } input_lock(); prev = NULL; for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) { next = tmp->next; if (tmp == dev) { if (prev == NULL) inputInfo.devices = next; else prev->next = next; flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; CloseDevice(tmp); ret = Success; break; } } prev = NULL; for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) { next = tmp->next; if (tmp == dev) { flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; CloseDevice(tmp); if (prev == NULL) inputInfo.off_devices = next; else prev->next = next; ret = Success; break; } } input_unlock(); if (ret == Success && initialized) { inputInfo.numDevices--; SendDevicePresenceEvent(deviceid, DeviceRemoved); if (sendevent) XISendDeviceHierarchyEvent(flags); } return ret; } int NumMotionEvents(void) { /* only called to fill data in initial connection reply. * VCP is ok here, it is the only fixed device we have. */ return inputInfo.pointer->valuator->numMotionEvents; } int dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode) { DeviceIntPtr dev; int rc; *pDev = NULL; for (dev = inputInfo.devices; dev; dev = dev->next) { if (dev->id == id) goto found; } for (dev = inputInfo.off_devices; dev; dev = dev->next) { if (dev->id == id) goto found; } return BadDevice; found: rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); if (rc == Success) *pDev = dev; return rc; } void QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode) { if (inputInfo.keyboard) { *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code; *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code; } } Bool InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom *labels, CARD8 *map) { ButtonClassPtr butc; int i; BUG_RETURN_VAL(dev == NULL, FALSE); BUG_RETURN_VAL(dev->button != NULL, FALSE); BUG_RETURN_VAL(numButtons >= MAX_BUTTONS, FALSE); butc = calloc(1, sizeof(ButtonClassRec)); if (!butc) return FALSE; butc->numButtons = numButtons; butc->sourceid = dev->id; for (i = 1; i <= numButtons; i++) butc->map[i] = map[i]; for (i = numButtons + 1; i < MAP_LENGTH; i++) butc->map[i] = i; memcpy(butc->labels, labels, numButtons * sizeof(Atom)); dev->button = butc; return TRUE; } /** * Allocate a valuator class and set up the pointers for the axis values * appropriately. * * @param src If non-NULL, the memory is reallocated from src. If NULL, the * memory is calloc'd. * @parma numAxes Number of axes to allocate. * @return The allocated valuator struct. */ ValuatorClassPtr AllocValuatorClass(ValuatorClassPtr src, int numAxes) { ValuatorClassPtr v; /* force alignment with double */ union align_u { ValuatorClassRec valc; double d; } *align; int size; size = sizeof(union align_u) + numAxes * (sizeof(double) + sizeof(AxisInfo)); align = (union align_u *) realloc(src, size); if (!align) return NULL; if (!src) memset(align, 0, size); v = &align->valc; v->numAxes = numAxes; v->axisVal = (double *) (align + 1); v->axes = (AxisInfoPtr) (v->axisVal + numAxes); return v; } Bool InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, int numMotionEvents, int mode) { int i; ValuatorClassPtr valc; BUG_RETURN_VAL(dev == NULL, FALSE); if (numAxes > MAX_VALUATORS) { LogMessage(X_WARNING, "Device '%s' has %d axes, only using first %d.\n", dev->name, numAxes, MAX_VALUATORS); numAxes = MAX_VALUATORS; } valc = AllocValuatorClass(NULL, numAxes); if (!valc) return FALSE; dev->last.scroll = valuator_mask_new(numAxes); if (!dev->last.scroll) { free(valc); return FALSE; } valc->sourceid = dev->id; valc->motion = NULL; valc->first_motion = 0; valc->last_motion = 0; valc->h_scroll_axis = -1; valc->v_scroll_axis = -1; valc->numMotionEvents = numMotionEvents; valc->motionHintWindow = NullWindow; if ((mode & OutOfProximity) && !dev->proximity) InitProximityClassDeviceStruct(dev); dev->valuator = valc; AllocateMotionHistory(dev); for (i = 0; i < numAxes; i++) { InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, mode); valc->axisVal[i] = 0; } dev->last.numValuators = numAxes; if (IsMaster(dev) || /* do not accelerate master or xtest devices */ IsXTestDevice(dev, NULL)) InitPointerAccelerationScheme(dev, PtrAccelNoOp); else InitPointerAccelerationScheme(dev, PtrAccelDefault); return TRUE; } /* global list of acceleration schemes */ ValuatorAccelerationRec pointerAccelerationScheme[] = { {PtrAccelNoOp, NULL, NULL, NULL, NULL}, {PtrAccelPredictable, acceleratePointerPredictable, NULL, InitPredictableAccelerationScheme, AccelerationDefaultCleanup}, {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL}, {-1, NULL, NULL, NULL, NULL} /* terminator */ }; /** * install an acceleration scheme. returns TRUE on success, and should not * change anything if unsuccessful. */ Bool InitPointerAccelerationScheme(DeviceIntPtr dev, int scheme) { int x, i = -1; ValuatorClassPtr val; val = dev->valuator; if (!val) return FALSE; if (IsMaster(dev) && scheme != PtrAccelNoOp) return FALSE; for (x = 0; pointerAccelerationScheme[x].number >= 0; x++) { if (pointerAccelerationScheme[x].number == scheme) { i = x; break; } } if (-1 == i) return FALSE; if (val->accelScheme.AccelCleanupProc) val->accelScheme.AccelCleanupProc(dev); if (pointerAccelerationScheme[i].AccelInitProc) { if (!pointerAccelerationScheme[i].AccelInitProc(dev, &pointerAccelerationScheme[i])) { return FALSE; } } else { val->accelScheme = pointerAccelerationScheme[i]; } return TRUE; } Bool InitFocusClassDeviceStruct(DeviceIntPtr dev) { FocusClassPtr focc; BUG_RETURN_VAL(dev == NULL, FALSE); BUG_RETURN_VAL(dev->focus != NULL, FALSE); focc = malloc(sizeof(FocusClassRec)); if (!focc) return FALSE; UpdateCurrentTimeIf(); focc->win = PointerRootWin; focc->revert = None; focc->time = currentTime; focc->trace = (WindowPtr *) NULL; focc->traceSize = 0; focc->traceGood = 0; focc->sourceid = dev->id; dev->focus = focc; return TRUE; } Bool InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc) { PtrFeedbackPtr feedc; BUG_RETURN_VAL(dev == NULL, FALSE); feedc = malloc(sizeof(PtrFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; feedc->ctrl = defaultPointerControl; feedc->ctrl.id = 0; if ((feedc->next = dev->ptrfeed)) feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1; dev->ptrfeed = feedc; (*controlProc) (dev, &feedc->ctrl); return TRUE; } static LedCtrl defaultLedControl = { DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0 }; static BellCtrl defaultBellControl = { DEFAULT_BELL, DEFAULT_BELL_PITCH, DEFAULT_BELL_DURATION, 0 }; static IntegerCtrl defaultIntegerControl = { DEFAULT_INT_RESOLUTION, DEFAULT_INT_MIN_VALUE, DEFAULT_INT_MAX_VALUE, DEFAULT_INT_DISPLAYED, 0 }; Bool InitStringFeedbackClassDeviceStruct(DeviceIntPtr dev, StringCtrlProcPtr controlProc, int max_symbols, int num_symbols_supported, KeySym * symbols) { int i; StringFeedbackPtr feedc; BUG_RETURN_VAL(dev == NULL, FALSE); feedc = malloc(sizeof(StringFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; feedc->ctrl.num_symbols_supported = num_symbols_supported; feedc->ctrl.num_symbols_displayed = 0; feedc->ctrl.max_symbols = max_symbols; feedc->ctrl.symbols_supported = xallocarray(num_symbols_supported, sizeof(KeySym)); feedc->ctrl.symbols_displayed = xallocarray(max_symbols, sizeof(KeySym)); if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) { free(feedc->ctrl.symbols_supported); free(feedc->ctrl.symbols_displayed); free(feedc); return FALSE; } for (i = 0; i < num_symbols_supported; i++) *(feedc->ctrl.symbols_supported + i) = *symbols++; for (i = 0; i < max_symbols; i++) *(feedc->ctrl.symbols_displayed + i) = (KeySym) 0; feedc->ctrl.id = 0; if ((feedc->next = dev->stringfeed)) feedc->ctrl.id = dev->stringfeed->ctrl.id + 1; dev->stringfeed = feedc; (*controlProc) (dev, &feedc->ctrl); return TRUE; } Bool InitBellFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc, BellCtrlProcPtr controlProc) { BellFeedbackPtr feedc; BUG_RETURN_VAL(dev == NULL, FALSE); feedc = malloc(sizeof(BellFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; feedc->BellProc = bellProc; feedc->ctrl = defaultBellControl; feedc->ctrl.id = 0; if ((feedc->next = dev->bell)) feedc->ctrl.id = dev->bell->ctrl.id + 1; dev->bell = feedc; (*controlProc) (dev, &feedc->ctrl); return TRUE; } Bool InitLedFeedbackClassDeviceStruct(DeviceIntPtr dev, LedCtrlProcPtr controlProc) { LedFeedbackPtr feedc; BUG_RETURN_VAL(dev == NULL, FALSE); feedc = malloc(sizeof(LedFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; feedc->ctrl = defaultLedControl; feedc->ctrl.id = 0; if ((feedc->next = dev->leds)) feedc->ctrl.id = dev->leds->ctrl.id + 1; feedc->xkb_sli = NULL; dev->leds = feedc; (*controlProc) (dev, &feedc->ctrl); return TRUE; } Bool InitIntegerFeedbackClassDeviceStruct(DeviceIntPtr dev, IntegerCtrlProcPtr controlProc) { IntegerFeedbackPtr feedc; BUG_RETURN_VAL(dev == NULL, FALSE); feedc = malloc(sizeof(IntegerFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; feedc->ctrl = defaultIntegerControl; feedc->ctrl.id = 0; if ((feedc->next = dev->intfeed)) feedc->ctrl.id = dev->intfeed->ctrl.id + 1; dev->intfeed = feedc; (*controlProc) (dev, &feedc->ctrl); return TRUE; } Bool InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, Atom *btn_labels, PtrCtrlProcPtr controlProc, int numMotionEvents, int numAxes, Atom *axes_labels) { DeviceIntPtr dev = (DeviceIntPtr) device; BUG_RETURN_VAL(dev == NULL, FALSE); BUG_RETURN_VAL(dev->button != NULL, FALSE); BUG_RETURN_VAL(dev->valuator != NULL, FALSE); BUG_RETURN_VAL(dev->ptrfeed != NULL, FALSE); return (InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) && InitValuatorClassDeviceStruct(dev, numAxes, axes_labels, numMotionEvents, Relative) && InitPtrFeedbackClassDeviceStruct(dev, controlProc)); } /** * Sets up multitouch capabilities on @device. * * @max_touches The maximum number of simultaneous touches, or 0 for unlimited. * @mode The mode of the touch device (XIDirectTouch or XIDependentTouch). * @num_axes The number of touch valuator axes. */ Bool InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches, unsigned int mode, unsigned int num_axes) { TouchClassPtr touch; int i; BUG_RETURN_VAL(device == NULL, FALSE); BUG_RETURN_VAL(device->touch != NULL, FALSE); BUG_RETURN_VAL(device->valuator == NULL, FALSE); /* Check the mode is valid, and at least X and Y axes. */ BUG_RETURN_VAL(mode != XIDirectTouch && mode != XIDependentTouch, FALSE); BUG_RETURN_VAL(num_axes < 2, FALSE); if (num_axes > MAX_VALUATORS) { LogMessage(X_WARNING, "Device '%s' has %d touch axes, only using first %d.\n", device->name, num_axes, MAX_VALUATORS); num_axes = MAX_VALUATORS; } touch = calloc(1, sizeof(*touch)); if (!touch) return FALSE; touch->max_touches = max_touches; if (max_touches == 0) max_touches = 5; /* arbitrary number plucked out of the air */ touch->touches = calloc(max_touches, sizeof(*touch->touches)); if (!touch->touches) goto err; touch->num_touches = max_touches; for (i = 0; i < max_touches; i++) TouchInitTouchPoint(touch, device->valuator, i); touch->mode = mode; touch->sourceid = device->id; device->touch = touch; device->last.touches = calloc(max_touches, sizeof(*device->last.touches)); device->last.num_touches = touch->num_touches; for (i = 0; i < touch->num_touches; i++) TouchInitDDXTouchPoint(device, &device->last.touches[i]); return TRUE; err: for (i = 0; i < touch->num_touches; i++) TouchFreeTouchPoint(device, i); free(touch->touches); free(touch); return FALSE; } /* * Check if the given buffer contains elements between low (inclusive) and * high (inclusive) only. * * @return TRUE if the device map is invalid, FALSE otherwise. */ Bool BadDeviceMap(BYTE * buff, int length, unsigned low, unsigned high, XID *errval) { int i; for (i = 0; i < length; i++) if (buff[i]) { /* only check non-zero elements */ if ((low > buff[i]) || (high < buff[i])) { *errval = buff[i]; return TRUE; } } return FALSE; } int ProcSetModifierMapping(ClientPtr client) { xSetModifierMappingReply rep; int rc; REQUEST(xSetModifierMappingReq); REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq); if (client->req_len != ((stuff->numKeyPerModifier << 1) + bytes_to_int32(sizeof(xSetModifierMappingReq)))) return BadLength; rep = (xSetModifierMappingReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0 }; rc = change_modmap(client, PickKeyboard(client), (KeyCode *) &stuff[1], stuff->numKeyPerModifier); if (rc == MappingFailed || rc == -1) return BadValue; if (rc != MappingSuccess && rc != MappingFailed && rc != MappingBusy) return rc; rep.success = rc; WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep); return Success; } int ProcGetModifierMapping(ClientPtr client) { xGetModifierMappingReply rep; int max_keys_per_mod = 0; KeyCode *modkeymap = NULL; REQUEST_SIZE_MATCH(xReq); generate_modkeymap(client, PickKeyboard(client), &modkeymap, &max_keys_per_mod); rep = (xGetModifierMappingReply) { .type = X_Reply, .numKeyPerModifier = max_keys_per_mod, .sequenceNumber = client->sequence, /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */ .length = max_keys_per_mod << 1 }; WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep); WriteToClient(client, max_keys_per_mod * 8, modkeymap); free(modkeymap); return Success; } int ProcChangeKeyboardMapping(ClientPtr client) { REQUEST(xChangeKeyboardMappingReq); unsigned len; KeySymsRec keysyms; DeviceIntPtr pDev, tmp; int rc; REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq); len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq)); if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode)) return BadLength; pDev = PickKeyboard(client); if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) || (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) { client->errorValue = stuff->firstKeyCode; return BadValue; } if (((unsigned) (stuff->firstKeyCode + stuff->keyCodes - 1) > pDev->key->xkbInfo->desc->max_key_code) || (stuff->keySymsPerKeyCode == 0)) { client->errorValue = stuff->keySymsPerKeyCode; return BadValue; } keysyms.minKeyCode = stuff->firstKeyCode; keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1; keysyms.mapWidth = stuff->keySymsPerKeyCode; keysyms.map = (KeySym *) &stuff[1]; rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); if (rc != Success) return rc; XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode, stuff->keyCodes, NULL, client); for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { if (IsMaster(tmp) || GetMaster(tmp, MASTER_KEYBOARD) != pDev) continue; if (!tmp->key) continue; rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); if (rc != Success) continue; XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode, stuff->keyCodes, NULL, client); } return Success; } int ProcSetPointerMapping(ClientPtr client) { BYTE *map; int ret; int i, j; DeviceIntPtr ptr = PickPointer(client); xSetPointerMappingReply rep; REQUEST(xSetPointerMappingReq); REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq); if (client->req_len != bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts)) return BadLength; rep = (xSetPointerMappingReply) { .type = X_Reply, .success = MappingSuccess, .sequenceNumber = client->sequence, .length = 0 }; map = (BYTE *) &stuff[1]; /* So we're bounded here by the number of core buttons. This check * probably wants disabling through XFixes. */ /* MPX: With ClientPointer, we can return the right number of buttons. * Let's just hope nobody changed ClientPointer between GetPointerMapping * and SetPointerMapping */ if (stuff->nElts != ptr->button->numButtons) { client->errorValue = stuff->nElts; return BadValue; } /* Core protocol specs don't allow for duplicate mappings; this check * almost certainly wants disabling through XFixes too. */ for (i = 0; i < stuff->nElts; i++) { for (j = i + 1; j < stuff->nElts; j++) { if (map[i] && map[i] == map[j]) { client->errorValue = map[i]; return BadValue; } } } ret = ApplyPointerMapping(ptr, map, stuff->nElts, client); if (ret == MappingBusy) rep.success = ret; else if (ret == -1) return BadValue; else if (ret != Success) return ret; WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); return Success; } int ProcGetKeyboardMapping(ClientPtr client) { xGetKeyboardMappingReply rep; DeviceIntPtr kbd = PickKeyboard(client); XkbDescPtr xkb; KeySymsPtr syms; int rc; REQUEST(xGetKeyboardMappingReq); REQUEST_SIZE_MATCH(xGetKeyboardMappingReq); rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess); if (rc != Success) return rc; xkb = kbd->key->xkbInfo->desc; if ((stuff->firstKeyCode < xkb->min_key_code) || (stuff->firstKeyCode > xkb->max_key_code)) { client->errorValue = stuff->firstKeyCode; return BadValue; } if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) { client->errorValue = stuff->count; return BadValue; } syms = XkbGetCoreMap(kbd); if (!syms) return BadAlloc; rep = (xGetKeyboardMappingReply) { .type = X_Reply, .keySymsPerKeyCode = syms->mapWidth, .sequenceNumber = client->sequence, /* length is a count of 4 byte quantities and KeySyms are 4 bytes */ .length = syms->mapWidth * stuff->count }; WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep); client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; WriteSwappedDataToClient(client, syms->mapWidth * stuff->count * sizeof(KeySym), &syms->map[syms->mapWidth * (stuff->firstKeyCode - syms->minKeyCode)]); free(syms->map); free(syms); return Success; } int ProcGetPointerMapping(ClientPtr client) { xGetPointerMappingReply rep; /* Apps may get different values each time they call GetPointerMapping as * the ClientPointer could change. */ DeviceIntPtr ptr = PickPointer(client); ButtonClassPtr butc = ptr->button; int nElts; int rc; REQUEST_SIZE_MATCH(xReq); rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess); if (rc != Success) return rc; nElts = (butc) ? butc->numButtons : 0; rep = (xGetPointerMappingReply) { .type = X_Reply, .nElts = nElts, .sequenceNumber = client->sequence, .length = ((unsigned) nElts + (4 - 1)) / 4 }; WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep); if (butc) WriteToClient(client, nElts, &butc->map[1]); return Success; } void NoteLedState(DeviceIntPtr keybd, int led, Bool on) { KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl; if (on) ctrl->leds |= ((Leds) 1 << (led - 1)); else ctrl->leds &= ~((Leds) 1 << (led - 1)); } int Ones(unsigned long mask) { /* HACKMEM 169 */ unsigned long y; y = (mask >> 1) & 033333333333; y = mask - y - ((y >> 1) & 033333333333); return (((y + (y >> 3)) & 030707070707) % 077); } static int DoChangeKeyboardControl(ClientPtr client, DeviceIntPtr keybd, XID *vlist, BITS32 vmask) { #define DO_ALL (-1) KeybdCtrl ctrl; int t; int led = DO_ALL; int key = DO_ALL; BITS32 index2; int mask = vmask, i; XkbEventCauseRec cause; ctrl = keybd->kbdfeed->ctrl; while (vmask) { index2 = (BITS32) lowbit(vmask); vmask &= ~index2; switch (index2) { case KBKeyClickPercent: t = (INT8) *vlist; vlist++; if (t == -1) { t = defaultKeyboardControl.click; } else if (t < 0 || t > 100) { client->errorValue = t; return BadValue; } ctrl.click = t; break; case KBBellPercent: t = (INT8) *vlist; vlist++; if (t == -1) { t = defaultKeyboardControl.bell; } else if (t < 0 || t > 100) { client->errorValue = t; return BadValue; } ctrl.bell = t; break; case KBBellPitch: t = (INT16) *vlist; vlist++; if (t == -1) { t = defaultKeyboardControl.bell_pitch; } else if (t < 0) { client->errorValue = t; return BadValue; } ctrl.bell_pitch = t; break; case KBBellDuration: t = (INT16) *vlist; vlist++; if (t == -1) t = defaultKeyboardControl.bell_duration; else if (t < 0) { client->errorValue = t; return BadValue; } ctrl.bell_duration = t; break; case KBLed: led = (CARD8) *vlist; vlist++; if (led < 1 || led > 32) { client->errorValue = led; return BadValue; } if (!(mask & KBLedMode)) return BadMatch; break; case KBLedMode: t = (CARD8) *vlist; vlist++; if (t == LedModeOff) { if (led == DO_ALL) ctrl.leds = 0x0; else ctrl.leds &= ~(((Leds) (1)) << (led - 1)); } else if (t == LedModeOn) { if (led == DO_ALL) ctrl.leds = ~0L; else ctrl.leds |= (((Leds) (1)) << (led - 1)); } else { client->errorValue = t; return BadValue; } XkbSetCauseCoreReq(&cause, X_ChangeKeyboardControl, client); XkbSetIndicators(keybd, ((led == DO_ALL) ? ~0L : (1L << (led - 1))), ctrl.leds, &cause); ctrl.leds = keybd->kbdfeed->ctrl.leds; break; case KBKey: key = (KeyCode) *vlist; vlist++; if ((KeyCode) key < keybd->key->xkbInfo->desc->min_key_code || (KeyCode) key > keybd->key->xkbInfo->desc->max_key_code) { client->errorValue = key; return BadValue; } if (!(mask & KBAutoRepeatMode)) return BadMatch; break; case KBAutoRepeatMode: i = (key >> 3); mask = (1 << (key & 7)); t = (CARD8) *vlist; vlist++; if (key != DO_ALL) XkbDisableComputedAutoRepeats(keybd, key); if (t == AutoRepeatModeOff) { if (key == DO_ALL) ctrl.autoRepeat = FALSE; else ctrl.autoRepeats[i] &= ~mask; } else if (t == AutoRepeatModeOn) { if (key == DO_ALL) ctrl.autoRepeat = TRUE; else ctrl.autoRepeats[i] |= mask; } else if (t == AutoRepeatModeDefault) { if (key == DO_ALL) ctrl.autoRepeat = defaultKeyboardControl.autoRepeat; else ctrl.autoRepeats[i] = (ctrl.autoRepeats[i] & ~mask) | (defaultKeyboardControl.autoRepeats[i] & mask); } else { client->errorValue = t; return BadValue; } break; default: client->errorValue = mask; return BadValue; } } keybd->kbdfeed->ctrl = ctrl; /* The XKB RepeatKeys control and core protocol global autorepeat */ /* value are linked */ XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat); return Success; #undef DO_ALL } /** * Changes kbd control on the ClientPointer and all attached SDs. */ int ProcChangeKeyboardControl(ClientPtr client) { XID *vlist; BITS32 vmask; int ret = Success, error = Success; DeviceIntPtr pDev = NULL, keyboard; REQUEST(xChangeKeyboardControlReq); REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq); vmask = stuff->mask; vlist = (XID *) &stuff[1]; if (client->req_len != (sizeof(xChangeKeyboardControlReq) >> 2) + Ones(vmask)) return BadLength; keyboard = PickKeyboard(client); for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { if ((pDev == keyboard || (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard)) && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); if (ret != Success) return ret; } } for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { if ((pDev == keyboard || (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard)) && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { ret = DoChangeKeyboardControl(client, pDev, vlist, vmask); if (ret != Success) error = ret; } } return error; } int ProcGetKeyboardControl(ClientPtr client) { int rc, i; DeviceIntPtr kbd = PickKeyboard(client); KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl; xGetKeyboardControlReply rep; REQUEST_SIZE_MATCH(xReq); rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess); if (rc != Success) return rc; rep = (xGetKeyboardControlReply) { .type = X_Reply, .globalAutoRepeat = ctrl->autoRepeat, .sequenceNumber = client->sequence, .length = 5, .ledMask = ctrl->leds, .keyClickPercent = ctrl->click, .bellPercent = ctrl->bell, .bellPitch = ctrl->bell_pitch, .bellDuration = ctrl->bell_duration }; for (i = 0; i < 32; i++) rep.map[i] = ctrl->autoRepeats[i]; WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep); return Success; } int ProcBell(ClientPtr client) { DeviceIntPtr dev, keybd = PickKeyboard(client); int base = keybd->kbdfeed->ctrl.bell; int newpercent; int rc; REQUEST(xBellReq); REQUEST_SIZE_MATCH(xBellReq); if (stuff->percent < -100 || stuff->percent > 100) { client->errorValue = stuff->percent; return BadValue; } newpercent = (base * stuff->percent) / 100; if (stuff->percent < 0) newpercent = base + newpercent; else newpercent = base - newpercent + stuff->percent; for (dev = inputInfo.devices; dev; dev = dev->next) { if ((dev == keybd || (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) && ((dev->kbdfeed && dev->kbdfeed->BellProc) || dev->xkb_interest)) { rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess); if (rc != Success) return rc; XkbHandleBell(FALSE, FALSE, dev, newpercent, &dev->kbdfeed->ctrl, 0, None, NULL, client); } } return Success; } int ProcChangePointerControl(ClientPtr client) { DeviceIntPtr dev, mouse = PickPointer(client); PtrCtrl ctrl; /* might get BadValue part way through */ int rc; REQUEST(xChangePointerControlReq); REQUEST_SIZE_MATCH(xChangePointerControlReq); /* If the device has no PtrFeedbackPtr, the xserver has a bug */ BUG_RETURN_VAL (!mouse->ptrfeed, BadImplementation); ctrl = mouse->ptrfeed->ctrl; if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) { client->errorValue = stuff->doAccel; return BadValue; } if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) { client->errorValue = stuff->doThresh; return BadValue; } if (stuff->doAccel) { if (stuff->accelNum == -1) { ctrl.num = defaultPointerControl.num; } else if (stuff->accelNum < 0) { client->errorValue = stuff->accelNum; return BadValue; } else { ctrl.num = stuff->accelNum; } if (stuff->accelDenum == -1) { ctrl.den = defaultPointerControl.den; } else if (stuff->accelDenum <= 0) { client->errorValue = stuff->accelDenum; return BadValue; } else { ctrl.den = stuff->accelDenum; } } if (stuff->doThresh) { if (stuff->threshold == -1) { ctrl.threshold = defaultPointerControl.threshold; } else if (stuff->threshold < 0) { client->errorValue = stuff->threshold; return BadValue; } else { ctrl.threshold = stuff->threshold; } } for (dev = inputInfo.devices; dev; dev = dev->next) { if ((dev == mouse || (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) && dev->ptrfeed) { rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); if (rc != Success) return rc; } } for (dev = inputInfo.devices; dev; dev = dev->next) { if ((dev == mouse || (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) && dev->ptrfeed) { dev->ptrfeed->ctrl = ctrl; } } return Success; } int ProcGetPointerControl(ClientPtr client) { DeviceIntPtr ptr = PickPointer(client); PtrCtrl *ctrl; xGetPointerControlReply rep; int rc; if (ptr->ptrfeed) ctrl = &ptr->ptrfeed->ctrl; else ctrl = &defaultPointerControl; REQUEST_SIZE_MATCH(xReq); rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess); if (rc != Success) return rc; rep = (xGetPointerControlReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .accelNumerator = ctrl->num, .accelDenominator = ctrl->den, .threshold = ctrl->threshold }; WriteReplyToClient(client, sizeof(xGenericReply), &rep); return Success; } void MaybeStopHint(DeviceIntPtr dev, ClientPtr client) { GrabPtr grab = dev->deviceGrab.grab; if ((grab && SameClient(grab, client) && ((grab->eventMask & PointerMotionHintMask) || (grab->ownerEvents && (EventMaskForClient(dev->valuator->motionHintWindow, client) & PointerMotionHintMask)))) || (!grab && (EventMaskForClient(dev->valuator->motionHintWindow, client) & PointerMotionHintMask))) dev->valuator->motionHintWindow = NullWindow; } int ProcGetMotionEvents(ClientPtr client) { WindowPtr pWin; xTimecoord *coords = (xTimecoord *) NULL; xGetMotionEventsReply rep; int i, count, xmin, xmax, ymin, ymax, rc; unsigned long nEvents; DeviceIntPtr mouse = PickPointer(client); TimeStamp start, stop; REQUEST(xGetMotionEventsReq); REQUEST_SIZE_MATCH(xGetMotionEventsReq); rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (rc != Success) return rc; rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess); if (rc != Success) return rc; UpdateCurrentTimeIf(); if (mouse->valuator->motionHintWindow) MaybeStopHint(mouse, client); rep = (xGetMotionEventsReply) { .type = X_Reply, .sequenceNumber = client->sequence }; nEvents = 0; start = ClientTimeToServerTime(stuff->start); stop = ClientTimeToServerTime(stuff->stop); if ((CompareTimeStamps(start, stop) != LATER) && (CompareTimeStamps(start, currentTime) != LATER) && mouse->valuator->numMotionEvents) { if (CompareTimeStamps(stop, currentTime) == LATER) stop = currentTime; count = GetMotionHistory(mouse, &coords, start.milliseconds, stop.milliseconds, pWin->drawable.pScreen, TRUE); xmin = pWin->drawable.x - wBorderWidth(pWin); xmax = pWin->drawable.x + (int) pWin->drawable.width + wBorderWidth(pWin); ymin = pWin->drawable.y - wBorderWidth(pWin); ymax = pWin->drawable.y + (int) pWin->drawable.height + wBorderWidth(pWin); for (i = 0; i < count; i++) if ((xmin <= coords[i].x) && (coords[i].x < xmax) && (ymin <= coords[i].y) && (coords[i].y < ymax)) { coords[nEvents].time = coords[i].time; coords[nEvents].x = coords[i].x - pWin->drawable.x; coords[nEvents].y = coords[i].y - pWin->drawable.y; nEvents++; } } rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord)); rep.nEvents = nEvents; WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep); if (nEvents) { client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite; WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord), (char *) coords); } free(coords); return Success; } int ProcQueryKeymap(ClientPtr client) { xQueryKeymapReply rep; int rc, i; DeviceIntPtr keybd = PickKeyboard(client); CARD8 *down = keybd->key->down; REQUEST_SIZE_MATCH(xReq); rep = (xQueryKeymapReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 2 }; rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess); /* If rc is Success, we're allowed to copy out the keymap. * If it's BadAccess, we leave it empty & lie to the client. */ if (rc == Success) { for (i = 0; i < 32; i++) rep.map[i] = down[i]; } else if (rc != BadAccess) return rc; WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep); return Success; } /** * Recalculate the number of buttons for the master device. The number of * buttons on the master device is equal to the number of buttons on the * slave device with the highest number of buttons. */ static void RecalculateMasterButtons(DeviceIntPtr slave) { DeviceIntPtr dev, master; int maxbuttons = 0; if (!slave->button || IsMaster(slave)) return; master = GetMaster(slave, MASTER_POINTER); if (!master) return; for (dev = inputInfo.devices; dev; dev = dev->next) { if (IsMaster(dev) || GetMaster(dev, MASTER_ATTACHED) != master || !dev->button) continue; maxbuttons = max(maxbuttons, dev->button->numButtons); } if (master->button && master->button->numButtons != maxbuttons) { int i; DeviceChangedEvent event = { .header = ET_Internal, .type = ET_DeviceChanged, .time = GetTimeInMillis(), .deviceid = master->id, .flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE, .buttons.num_buttons = maxbuttons }; master->button->numButtons = maxbuttons; memcpy(&event.buttons.names, master->button->labels, maxbuttons * sizeof(Atom)); if (master->valuator) { event.num_valuators = master->valuator->numAxes; for (i = 0; i < event.num_valuators; i++) { event.valuators[i].min = master->valuator->axes[i].min_value; event.valuators[i].max = master->valuator->axes[i].max_value; event.valuators[i].resolution = master->valuator->axes[i].resolution; event.valuators[i].mode = master->valuator->axes[i].mode; event.valuators[i].name = master->valuator->axes[i].label; } } if (master->key) { event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code; event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code; } XISendDeviceChangedEvent(master, &event); } } /** * Generate release events for all keys/button currently down on this * device. */ void ReleaseButtonsAndKeys(DeviceIntPtr dev) { InternalEvent *eventlist = InitEventList(GetMaximumEventsNum()); ButtonClassPtr b = dev->button; KeyClassPtr k = dev->key; int i, j, nevents; if (!eventlist) /* no release events for you */ return; /* Release all buttons */ for (i = 0; b && i < b->numButtons; i++) { if (BitIsOn(b->down, i)) { nevents = GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL); for (j = 0; j < nevents; j++) mieqProcessDeviceEvent(dev, &eventlist[j], NULL); } } /* Release all keys */ for (i = 0; k && i < MAP_LENGTH; i++) { if (BitIsOn(k->down, i)) { nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i); for (j = 0; j < nevents; j++) mieqProcessDeviceEvent(dev, &eventlist[j], NULL); } } FreeEventList(eventlist, GetMaximumEventsNum()); } /** * Attach device 'dev' to device 'master'. * Client is set to the client that issued the request, or NULL if it comes * from some internal automatic pairing. * * Master may be NULL to set the device floating. * * We don't allow multi-layer hierarchies right now. You can't attach a slave * to another slave. */ int AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) { ScreenPtr screen; if (!dev || IsMaster(dev)) return BadDevice; if (master && !IsMaster(master)) /* can't attach to slaves */ return BadDevice; /* set from floating to floating? */ if (IsFloating(dev) && !master && dev->enabled) return Success; /* free the existing sprite. */ if (IsFloating(dev) && dev->spriteInfo->paired == dev) { screen = miPointerGetScreen(dev); screen->DeviceCursorCleanup(dev, screen); free(dev->spriteInfo->sprite); } dev->master = master; /* If device is set to floating, we need to create a sprite for it, * otherwise things go bad. However, we don't want to render the cursor, * so we reset spriteOwner. * Sprite has to be forced to NULL first, otherwise InitializeSprite won't * alloc new memory but overwrite the previous one. */ if (!master) { WindowPtr currentRoot; if (dev->spriteInfo->sprite) currentRoot = GetCurrentRootWindow(dev); else /* new device auto-set to floating */ currentRoot = screenInfo.screens[0]->root; /* we need to init a fake sprite */ screen = currentRoot->drawable.pScreen; screen->DeviceCursorInitialize(dev, screen); dev->spriteInfo->sprite = NULL; InitializeSprite(dev, currentRoot); dev->spriteInfo->spriteOwner = FALSE; dev->spriteInfo->paired = dev; } else { dev->spriteInfo->sprite = master->spriteInfo->sprite; dev->spriteInfo->paired = master; dev->spriteInfo->spriteOwner = FALSE; XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0); RecalculateMasterButtons(master); } /* XXX: in theory, the MD should change back to its old, original * classes when the last SD is detached. Thanks to the XTEST devices, * we'll always have an SD attached until the MD is removed. * So let's not worry about that. */ return Success; } /** * Return the device paired with the given device or NULL. * Returns the device paired with the parent master if the given device is a * slave device. */ DeviceIntPtr GetPairedDevice(DeviceIntPtr dev) { if (!IsMaster(dev) && !IsFloating(dev)) dev = GetMaster(dev, MASTER_ATTACHED); return dev->spriteInfo? dev->spriteInfo->paired: NULL; } /** * Returns the requested master for this device. * The return values are: * - MASTER_ATTACHED: the master for this device or NULL for a floating * slave. * - MASTER_KEYBOARD: the master keyboard for this device or NULL for a * floating slave * - MASTER_POINTER: the master pointer for this device or NULL for a * floating slave * - POINTER_OR_FLOAT: the master pointer for this device or the device for * a floating slave * - KEYBOARD_OR_FLOAT: the master keyboard for this device or the device for * a floating slave * * @param which ::MASTER_KEYBOARD or ::MASTER_POINTER, ::MASTER_ATTACHED, * ::POINTER_OR_FLOAT or ::KEYBOARD_OR_FLOAT. * @return The requested master device */ DeviceIntPtr GetMaster(DeviceIntPtr dev, int which) { DeviceIntPtr master; if (IsMaster(dev)) master = dev; else { master = dev->master; if (!master && (which == POINTER_OR_FLOAT || which == KEYBOARD_OR_FLOAT)) return dev; } if (master && which != MASTER_ATTACHED) { if (which == MASTER_KEYBOARD || which == KEYBOARD_OR_FLOAT) { if (master->type != MASTER_KEYBOARD) master = GetPairedDevice(master); } else { if (master->type != MASTER_POINTER) master = GetPairedDevice(master); } } return master; } /** * Create a new device pair (== one pointer, one keyboard device). * Only allocates the devices, you will need to call ActivateDevice() and * EnableDevice() manually. * Either a master or a slave device can be created depending on * the value for master. */ int AllocDevicePair(ClientPtr client, const char *name, DeviceIntPtr *ptr, DeviceIntPtr *keybd, DeviceProc ptr_proc, DeviceProc keybd_proc, Bool master) { DeviceIntPtr pointer; DeviceIntPtr keyboard; char *dev_name; *ptr = *keybd = NULL; XkbInitPrivates(); pointer = AddInputDevice(client, ptr_proc, TRUE); if (!pointer) return BadAlloc; if (asprintf(&dev_name, "%s pointer", name) == -1) { RemoveDevice(pointer, FALSE); return BadAlloc; } pointer->name = dev_name; pointer->public.processInputProc = ProcessOtherEvent; pointer->public.realInputProc = ProcessOtherEvent; XkbSetExtension(pointer, ProcessPointerEvent); pointer->deviceGrab.ActivateGrab = ActivatePointerGrab; pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab; pointer->coreEvents = TRUE; pointer->spriteInfo->spriteOwner = TRUE; pointer->lastSlave = NULL; pointer->last.slave = NULL; pointer->type = (master) ? MASTER_POINTER : SLAVE; keyboard = AddInputDevice(client, keybd_proc, TRUE); if (!keyboard) { RemoveDevice(pointer, FALSE); return BadAlloc; } if (asprintf(&dev_name, "%s keyboard", name) == -1) { RemoveDevice(keyboard, FALSE); RemoveDevice(pointer, FALSE); return BadAlloc; } keyboard->name = dev_name; keyboard->public.processInputProc = ProcessOtherEvent; keyboard->public.realInputProc = ProcessOtherEvent; XkbSetExtension(keyboard, ProcessKeyboardEvent); keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab; keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; keyboard->coreEvents = TRUE; keyboard->spriteInfo->spriteOwner = FALSE; keyboard->lastSlave = NULL; keyboard->last.slave = NULL; keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE; /* The ClassesRec stores the device classes currently not used. */ if (IsMaster(pointer)) { pointer->unused_classes = calloc(1, sizeof(ClassesRec)); keyboard->unused_classes = calloc(1, sizeof(ClassesRec)); } *ptr = pointer; *keybd = keyboard; return Success; } /** * Return Relative or Absolute for the device. */ int valuator_get_mode(DeviceIntPtr dev, int axis) { return (dev->valuator->axes[axis].mode & DeviceMode); } /** * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then * set the mode for all axes. */ void valuator_set_mode(DeviceIntPtr dev, int axis, int mode) { if (axis != VALUATOR_MODE_ALL_AXES) dev->valuator->axes[axis].mode = mode; else { int i; for (i = 0; i < dev->valuator->numAxes; i++) dev->valuator->axes[i].mode = mode; } } xorg-server-1.20.13/dix/dispatch.c0000644000175000017500000035146514100573755013636 00000000000000/************************************************************ Copyright 1987, 1989, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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. ********************************************************/ /* The panoramix components contained the following notice */ /***************************************************************** Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Digital Equipment Corporation shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Digital Equipment Corporation. ******************************************************************/ /* XSERVER_DTRACE additions: * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #include #endif #ifdef PANORAMIX_DEBUG #include int ProcInitialConnection(); #endif #include "windowstr.h" #include #include #include "dixfontstr.h" #include "gcstruct.h" #include "selection.h" #include "colormapst.h" #include "cursorstr.h" #include "scrnintstr.h" #include "opaque.h" #include "input.h" #include "servermd.h" #include "extnsionst.h" #include "dixfont.h" #include "dispatch.h" #include "swaprep.h" #include "swapreq.h" #include "privates.h" #include "xace.h" #include "inputstr.h" #include "xkbsrv.h" #include "site.h" #include "client.h" #ifdef XSERVER_DTRACE #include "registry.h" #include "probes.h" #endif #define mskcnt ((MAXCLIENTS + 31) / 32) #define BITMASK(i) (1U << ((i) & 31)) #define MASKIDX(i) ((i) >> 5) #define MASKWORD(buf, i) buf[MASKIDX(i)] #define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i) #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) xConnSetupPrefix connSetupPrefix; PaddingInfo PixmapWidthPaddingInfo[33]; static ClientPtr grabClient; #define GrabNone 0 #define GrabActive 1 static int grabState = GrabNone; static long grabWaiters[mskcnt]; CallbackListPtr ServerGrabCallback = NULL; HWEventQueuePtr checkForInput[2]; int connBlockScreenStart; static void KillAllClients(void); static int nextFreeClientID; /* always MIN free client ID */ static int nClients; /* number of authorized clients */ CallbackListPtr ClientStateCallback; /* dispatchException & isItTimeToYield must be declared volatile since they * are modified by signal handlers - otherwise optimizer may assume it doesn't * need to actually check value in memory when used and may miss changes from * signal handlers. */ volatile char dispatchException = 0; volatile char isItTimeToYield; #define SAME_SCREENS(a, b) (\ (a.pScreen == b.pScreen)) void SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1) { checkForInput[0] = c0; checkForInput[1] = c1; } void UpdateCurrentTime(void) { TimeStamp systime; /* To avoid time running backwards, we must call GetTimeInMillis before * calling ProcessInputEvents. */ systime.months = currentTime.months; systime.milliseconds = GetTimeInMillis(); if (systime.milliseconds < currentTime.milliseconds) systime.months++; if (InputCheckPending()) ProcessInputEvents(); if (CompareTimeStamps(systime, currentTime) == LATER) currentTime = systime; } /* Like UpdateCurrentTime, but can't call ProcessInputEvents */ void UpdateCurrentTimeIf(void) { TimeStamp systime; systime.months = currentTime.months; systime.milliseconds = GetTimeInMillis(); if (systime.milliseconds < currentTime.milliseconds) systime.months++; if (CompareTimeStamps(systime, currentTime) == LATER) currentTime = systime; } #undef SMART_DEBUG /* in milliseconds */ #define SMART_SCHEDULE_DEFAULT_INTERVAL 5 #define SMART_SCHEDULE_MAX_SLICE 15 #ifdef HAVE_SETITIMER Bool SmartScheduleSignalEnable = TRUE; #endif long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; long SmartScheduleTime; int SmartScheduleLatencyLimited = 0; static ClientPtr SmartLastClient; static int SmartLastIndex[SMART_MAX_PRIORITY - SMART_MIN_PRIORITY + 1]; #ifdef SMART_DEBUG long SmartLastPrint; #endif void Dispatch(void); static struct xorg_list ready_clients; static struct xorg_list saved_ready_clients; struct xorg_list output_pending_clients; static void init_client_ready(void) { xorg_list_init(&ready_clients); xorg_list_init(&saved_ready_clients); xorg_list_init(&output_pending_clients); } Bool clients_are_ready(void) { return !xorg_list_is_empty(&ready_clients); } /* Client has requests queued or data on the network */ void mark_client_ready(ClientPtr client) { if (xorg_list_is_empty(&client->ready)) xorg_list_append(&client->ready, &ready_clients); } /* * Client has requests queued or data on the network, but awaits a * server grab release */ void mark_client_saved_ready(ClientPtr client) { if (xorg_list_is_empty(&client->ready)) xorg_list_append(&client->ready, &saved_ready_clients); } /* Client has no requests queued and no data on network */ void mark_client_not_ready(ClientPtr client) { xorg_list_del(&client->ready); } static void mark_client_grab(ClientPtr grab) { ClientPtr client, tmp; xorg_list_for_each_entry_safe(client, tmp, &ready_clients, ready) { if (client != grab) { xorg_list_del(&client->ready); xorg_list_append(&client->ready, &saved_ready_clients); } } } static void mark_client_ungrab(void) { ClientPtr client, tmp; xorg_list_for_each_entry_safe(client, tmp, &saved_ready_clients, ready) { xorg_list_del(&client->ready); xorg_list_append(&client->ready, &ready_clients); } } static ClientPtr SmartScheduleClient(void) { ClientPtr pClient, best = NULL; int bestRobin, robin; long now = SmartScheduleTime; long idle; int nready = 0; bestRobin = 0; idle = 2 * SmartScheduleSlice; xorg_list_for_each_entry(pClient, &ready_clients, ready) { nready++; /* Praise clients which haven't run in a while */ if ((now - pClient->smart_stop_tick) >= idle) { if (pClient->smart_priority < 0) pClient->smart_priority++; } /* check priority to select best client */ robin = (pClient->index - SmartLastIndex[pClient->smart_priority - SMART_MIN_PRIORITY]) & 0xff; /* pick the best client */ if (!best || pClient->priority > best->priority || (pClient->priority == best->priority && (pClient->smart_priority > best->smart_priority || (pClient->smart_priority == best->smart_priority && robin > bestRobin)))) { best = pClient; bestRobin = robin; } #ifdef SMART_DEBUG if ((now - SmartLastPrint) >= 5000) fprintf(stderr, " %2d: %3d", pClient->index, pClient->smart_priority); #endif } #ifdef SMART_DEBUG if ((now - SmartLastPrint) >= 5000) { fprintf(stderr, " use %2d\n", best->index); SmartLastPrint = now; } #endif SmartLastIndex[best->smart_priority - SMART_MIN_PRIORITY] = best->index; /* * Set current client pointer */ if (SmartLastClient != best) { best->smart_start_tick = now; SmartLastClient = best; } /* * Adjust slice */ if (nready == 1 && SmartScheduleLatencyLimited == 0) { /* * If it's been a long time since another client * has run, bump the slice up to get maximal * performance from a single client */ if ((now - best->smart_start_tick) > 1000 && SmartScheduleSlice < SmartScheduleMaxSlice) { SmartScheduleSlice += SmartScheduleInterval; } } else { SmartScheduleSlice = SmartScheduleInterval; } return best; } void EnableLimitedSchedulingLatency(void) { ++SmartScheduleLatencyLimited; SmartScheduleSlice = SmartScheduleInterval; } void DisableLimitedSchedulingLatency(void) { --SmartScheduleLatencyLimited; /* protect against bugs */ if (SmartScheduleLatencyLimited < 0) SmartScheduleLatencyLimited = 0; } void Dispatch(void) { int result; ClientPtr client; long start_tick; nextFreeClientID = 1; nClients = 0; SmartScheduleSlice = SmartScheduleInterval; init_client_ready(); while (!dispatchException) { if (InputCheckPending()) { ProcessInputEvents(); FlushIfCriticalOutputPending(); } if (!WaitForSomething(clients_are_ready())) continue; /***************** * Handle events in round robin fashion, doing input between * each round *****************/ if (!dispatchException && clients_are_ready()) { client = SmartScheduleClient(); isItTimeToYield = FALSE; start_tick = SmartScheduleTime; while (!isItTimeToYield) { if (InputCheckPending()) ProcessInputEvents(); FlushIfCriticalOutputPending(); if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice) { /* Penalize clients which consume ticks */ if (client->smart_priority > SMART_MIN_PRIORITY) client->smart_priority--; break; } /* now, finally, deal with client requests */ result = ReadRequestFromClient(client); if (result <= 0) { if (result < 0) CloseDownClient(client); break; } client->sequence++; client->majorOp = ((xReq *) client->requestBuffer)->reqType; client->minorOp = 0; if (client->majorOp >= EXTENSION_BASE) { ExtensionEntry *ext = GetExtensionEntry(client->majorOp); if (ext) client->minorOp = ext->MinorOpcode(client); } #ifdef XSERVER_DTRACE if (XSERVER_REQUEST_START_ENABLED()) XSERVER_REQUEST_START(LookupMajorName(client->majorOp), client->majorOp, ((xReq *) client->requestBuffer)->length, client->index, client->requestBuffer); #endif if (result > (maxBigRequestSize << 2)) result = BadLength; else { result = XaceHookDispatch(client, client->majorOp); if (result == Success) result = (*client->requestVector[client->majorOp]) (client); } if (!SmartScheduleSignalEnable) SmartScheduleTime = GetTimeInMillis(); #ifdef XSERVER_DTRACE if (XSERVER_REQUEST_DONE_ENABLED()) XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp), client->majorOp, client->sequence, client->index, result); #endif if (client->noClientException != Success) { CloseDownClient(client); break; } else if (result != Success) { SendErrorToClient(client, client->majorOp, client->minorOp, client->errorValue, result); break; } } FlushAllOutput(); if (client == SmartLastClient) client->smart_stop_tick = SmartScheduleTime; } dispatchException &= ~DE_PRIORITYCHANGE; } #if defined(DDXBEFORERESET) ddxBeforeReset(); #endif KillAllClients(); dispatchException &= ~DE_RESET; SmartScheduleLatencyLimited = 0; ResetOsBuffers(); } static int VendorRelease = VENDOR_RELEASE; static const char *VendorString = VENDOR_NAME; void SetVendorRelease(int release) { VendorRelease = release; } void SetVendorString(const char *vendor) { VendorString = vendor; } Bool CreateConnectionBlock(void) { xConnSetup setup; xWindowRoot root; xDepth depth; xVisualType visual; xPixmapFormat format; unsigned long vid; int i, j, k, lenofblock, sizesofar = 0; char *pBuf; memset(&setup, 0, sizeof(xConnSetup)); /* Leave off the ridBase and ridMask, these must be sent with connection */ setup.release = VendorRelease; /* * per-server image and bitmap parameters are defined in Xmd.h */ setup.imageByteOrder = screenInfo.imageByteOrder; setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit; setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad; setup.bitmapBitOrder = screenInfo.bitmapBitOrder; setup.motionBufferSize = NumMotionEvents(); setup.numRoots = screenInfo.numScreens; setup.nbytesVendor = strlen(VendorString); setup.numFormats = screenInfo.numPixmapFormats; setup.maxRequestSize = MAX_REQUEST_SIZE; QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode); lenofblock = sizeof(xConnSetup) + pad_to_int32(setup.nbytesVendor) + (setup.numFormats * sizeof(xPixmapFormat)) + (setup.numRoots * sizeof(xWindowRoot)); ConnectionInfo = malloc(lenofblock); if (!ConnectionInfo) return FALSE; memmove(ConnectionInfo, (char *) &setup, sizeof(xConnSetup)); sizesofar = sizeof(xConnSetup); pBuf = ConnectionInfo + sizeof(xConnSetup); memmove(pBuf, VendorString, (int) setup.nbytesVendor); sizesofar += setup.nbytesVendor; pBuf += setup.nbytesVendor; i = padding_for_int32(setup.nbytesVendor); sizesofar += i; while (--i >= 0) *pBuf++ = 0; memset(&format, 0, sizeof(xPixmapFormat)); for (i = 0; i < screenInfo.numPixmapFormats; i++) { format.depth = screenInfo.formats[i].depth; format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel; format.scanLinePad = screenInfo.formats[i].scanlinePad; memmove(pBuf, (char *) &format, sizeof(xPixmapFormat)); pBuf += sizeof(xPixmapFormat); sizesofar += sizeof(xPixmapFormat); } connBlockScreenStart = sizesofar; memset(&depth, 0, sizeof(xDepth)); memset(&visual, 0, sizeof(xVisualType)); for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr pScreen; DepthPtr pDepth; VisualPtr pVisual; pScreen = screenInfo.screens[i]; root.windowId = pScreen->root->drawable.id; root.defaultColormap = pScreen->defColormap; root.whitePixel = pScreen->whitePixel; root.blackPixel = pScreen->blackPixel; root.currentInputMask = 0; /* filled in when sent */ root.pixWidth = pScreen->width; root.pixHeight = pScreen->height; root.mmWidth = pScreen->mmWidth; root.mmHeight = pScreen->mmHeight; root.minInstalledMaps = pScreen->minInstalledCmaps; root.maxInstalledMaps = pScreen->maxInstalledCmaps; root.rootVisualID = pScreen->rootVisual; root.backingStore = pScreen->backingStoreSupport; root.saveUnders = FALSE; root.rootDepth = pScreen->rootDepth; root.nDepths = pScreen->numDepths; memmove(pBuf, (char *) &root, sizeof(xWindowRoot)); sizesofar += sizeof(xWindowRoot); pBuf += sizeof(xWindowRoot); pDepth = pScreen->allowedDepths; for (j = 0; j < pScreen->numDepths; j++, pDepth++) { lenofblock += sizeof(xDepth) + (pDepth->numVids * sizeof(xVisualType)); pBuf = (char *) realloc(ConnectionInfo, lenofblock); if (!pBuf) { free(ConnectionInfo); return FALSE; } ConnectionInfo = pBuf; pBuf += sizesofar; depth.depth = pDepth->depth; depth.nVisuals = pDepth->numVids; memmove(pBuf, (char *) &depth, sizeof(xDepth)); pBuf += sizeof(xDepth); sizesofar += sizeof(xDepth); for (k = 0; k < pDepth->numVids; k++) { vid = pDepth->vids[k]; for (pVisual = pScreen->visuals; pVisual->vid != vid; pVisual++); visual.visualID = vid; visual.class = pVisual->class; visual.bitsPerRGB = pVisual->bitsPerRGBValue; visual.colormapEntries = pVisual->ColormapEntries; visual.redMask = pVisual->redMask; visual.greenMask = pVisual->greenMask; visual.blueMask = pVisual->blueMask; memmove(pBuf, (char *) &visual, sizeof(xVisualType)); pBuf += sizeof(xVisualType); sizesofar += sizeof(xVisualType); } } } connSetupPrefix.success = xTrue; connSetupPrefix.length = lenofblock / 4; connSetupPrefix.majorVersion = X_PROTOCOL; connSetupPrefix.minorVersion = X_PROTOCOL_REVISION; return TRUE; } int ProcBadRequest(ClientPtr client) { return BadRequest; } int ProcCreateWindow(ClientPtr client) { WindowPtr pParent, pWin; REQUEST(xCreateWindowReq); int len, rc; REQUEST_AT_LEAST_SIZE(xCreateWindowReq); LEGAL_NEW_RESOURCE(stuff->wid, client); rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); if (rc != Success) return rc; len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq)); if (Ones(stuff->mask) != len) return BadLength; if (!stuff->width || !stuff->height) { client->errorValue = 0; return BadValue; } pWin = CreateWindow(stuff->wid, pParent, stuff->x, stuff->y, stuff->width, stuff->height, stuff->borderWidth, stuff->class, stuff->mask, (XID *) &stuff[1], (int) stuff->depth, client, stuff->visual, &rc); if (pWin) { Mask mask = pWin->eventMask; pWin->eventMask = 0; /* subterfuge in case AddResource fails */ if (!AddResource(stuff->wid, RT_WINDOW, (void *) pWin)) return BadAlloc; pWin->eventMask = mask; } return rc; } int ProcChangeWindowAttributes(ClientPtr client) { WindowPtr pWin; REQUEST(xChangeWindowAttributesReq); int len, rc; Mask access_mode = 0; REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0; access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0; rc = dixLookupWindow(&pWin, stuff->window, client, access_mode); if (rc != Success) return rc; len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq)); if (len != Ones(stuff->valueMask)) return BadLength; return ChangeWindowAttributes(pWin, stuff->valueMask, (XID *) &stuff[1], client); } int ProcGetWindowAttributes(ClientPtr client) { WindowPtr pWin; REQUEST(xResourceReq); xGetWindowAttributesReply wa; int rc; REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); if (rc != Success) return rc; memset(&wa, 0, sizeof(xGetWindowAttributesReply)); GetWindowAttributes(pWin, client, &wa); WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa); return Success; } int ProcDestroyWindow(ClientPtr client) { WindowPtr pWin; REQUEST(xResourceReq); int rc; REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess); if (rc != Success) return rc; if (pWin->parent) { rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client, DixRemoveAccess); if (rc != Success) return rc; FreeResource(stuff->id, RT_NONE); } return Success; } int ProcDestroySubwindows(ClientPtr client) { WindowPtr pWin; REQUEST(xResourceReq); int rc; REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess); if (rc != Success) return rc; DestroySubwindows(pWin, client); return Success; } int ProcChangeSaveSet(ClientPtr client) { WindowPtr pWin; REQUEST(xChangeSaveSetReq); int rc; REQUEST_SIZE_MATCH(xChangeSaveSetReq); rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); if (rc != Success) return rc; if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id))) return BadMatch; if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete)) return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE); client->errorValue = stuff->mode; return BadValue; } int ProcReparentWindow(ClientPtr client) { WindowPtr pWin, pParent; REQUEST(xReparentWindowReq); int rc; REQUEST_SIZE_MATCH(xReparentWindowReq); rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); if (rc != Success) return rc; rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); if (rc != Success) return rc; if (!SAME_SCREENS(pWin->drawable, pParent->drawable)) return BadMatch; if ((pWin->backgroundState == ParentRelative) && (pParent->drawable.depth != pWin->drawable.depth)) return BadMatch; if ((pWin->drawable.class != InputOnly) && (pParent->drawable.class == InputOnly)) return BadMatch; return ReparentWindow(pWin, pParent, (short) stuff->x, (short) stuff->y, client); } int ProcMapWindow(ClientPtr client) { WindowPtr pWin; REQUEST(xResourceReq); int rc; REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess); if (rc != Success) return rc; MapWindow(pWin, client); /* update cache to say it is mapped */ return Success; } int ProcMapSubwindows(ClientPtr client) { WindowPtr pWin; REQUEST(xResourceReq); int rc; REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); if (rc != Success) return rc; MapSubwindows(pWin, client); /* update cache to say it is mapped */ return Success; } int ProcUnmapWindow(ClientPtr client) { WindowPtr pWin; REQUEST(xResourceReq); int rc; REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess); if (rc != Success) return rc; UnmapWindow(pWin, FALSE); /* update cache to say it is mapped */ return Success; } int ProcUnmapSubwindows(ClientPtr client) { WindowPtr pWin; REQUEST(xResourceReq); int rc; REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); if (rc != Success) return rc; UnmapSubwindows(pWin); return Success; } int ProcConfigureWindow(ClientPtr client) { WindowPtr pWin; REQUEST(xConfigureWindowReq); int len, rc; REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess | DixSetAttrAccess); if (rc != Success) return rc; len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq)); if (Ones((Mask) stuff->mask) != len) return BadLength; return ConfigureWindow(pWin, (Mask) stuff->mask, (XID *) &stuff[1], client); } int ProcCirculateWindow(ClientPtr client) { WindowPtr pWin; REQUEST(xCirculateWindowReq); int rc; REQUEST_SIZE_MATCH(xCirculateWindowReq); if ((stuff->direction != RaiseLowest) && (stuff->direction != LowerHighest)) { client->errorValue = stuff->direction; return BadValue; } rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); if (rc != Success) return rc; CirculateWindow(pWin, (int) stuff->direction, client); return Success; } static int GetGeometry(ClientPtr client, xGetGeometryReply * rep) { DrawablePtr pDraw; int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess); if (rc != Success) return rc; rep->type = X_Reply; rep->length = 0; rep->sequenceNumber = client->sequence; rep->root = pDraw->pScreen->root->drawable.id; rep->depth = pDraw->depth; rep->width = pDraw->width; rep->height = pDraw->height; if (WindowDrawable(pDraw->type)) { WindowPtr pWin = (WindowPtr) pDraw; rep->x = pWin->origin.x - wBorderWidth(pWin); rep->y = pWin->origin.y - wBorderWidth(pWin); rep->borderWidth = pWin->borderWidth; } else { /* DRAWABLE_PIXMAP */ rep->x = rep->y = rep->borderWidth = 0; } return Success; } int ProcGetGeometry(ClientPtr client) { xGetGeometryReply rep = { .type = X_Reply }; int status; if ((status = GetGeometry(client, &rep)) != Success) return status; WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); return Success; } int ProcQueryTree(ClientPtr client) { xQueryTreeReply reply; int rc, numChildren = 0; WindowPtr pChild, pWin, pHead; Window *childIDs = (Window *) NULL; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); if (rc != Success) return rc; reply = (xQueryTreeReply) { .type = X_Reply, .sequenceNumber = client->sequence, .root = pWin->drawable.pScreen->root->drawable.id, .parent = (pWin->parent) ? pWin->parent->drawable.id : (Window) None }; pHead = RealChildHead(pWin); for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) numChildren++; if (numChildren) { int curChild = 0; childIDs = xallocarray(numChildren, sizeof(Window)); if (!childIDs) return BadAlloc; for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) childIDs[curChild++] = pChild->drawable.id; } reply.nChildren = numChildren; reply.length = bytes_to_int32(numChildren * sizeof(Window)); WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); if (numChildren) { client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs); free(childIDs); } return Success; } int ProcInternAtom(ClientPtr client) { Atom atom; char *tchar; REQUEST(xInternAtomReq); REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes); if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) { client->errorValue = stuff->onlyIfExists; return BadValue; } tchar = (char *) &stuff[1]; atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists); if (atom != BAD_RESOURCE) { xInternAtomReply reply = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .atom = atom }; WriteReplyToClient(client, sizeof(xInternAtomReply), &reply); return Success; } else return BadAlloc; } int ProcGetAtomName(ClientPtr client) { const char *str; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); if ((str = NameForAtom(stuff->id))) { int len = strlen(str); xGetAtomNameReply reply = { .type = X_Reply, .sequenceNumber = client->sequence, .length = bytes_to_int32(len), .nameLength = len }; WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); WriteToClient(client, len, str); return Success; } else { client->errorValue = stuff->id; return BadAtom; } } int ProcGrabServer(ClientPtr client) { int rc; REQUEST_SIZE_MATCH(xReq); if (grabState != GrabNone && client != grabClient) { ResetCurrentRequest(client); client->sequence--; BITSET(grabWaiters, client->index); IgnoreClient(client); return Success; } rc = OnlyListenToOneClient(client); if (rc != Success) return rc; grabState = GrabActive; grabClient = client; mark_client_grab(client); if (ServerGrabCallback) { ServerGrabInfoRec grabinfo; grabinfo.client = client; grabinfo.grabstate = SERVER_GRABBED; CallCallbacks(&ServerGrabCallback, (void *) &grabinfo); } return Success; } static void UngrabServer(ClientPtr client) { int i; grabState = GrabNone; ListenToAllClients(); mark_client_ungrab(); for (i = mskcnt; --i >= 0 && !grabWaiters[i];); if (i >= 0) { i <<= 5; while (!GETBIT(grabWaiters, i)) i++; BITCLEAR(grabWaiters, i); AttendClient(clients[i]); } if (ServerGrabCallback) { ServerGrabInfoRec grabinfo; grabinfo.client = client; grabinfo.grabstate = SERVER_UNGRABBED; CallCallbacks(&ServerGrabCallback, (void *) &grabinfo); } } int ProcUngrabServer(ClientPtr client) { REQUEST_SIZE_MATCH(xReq); UngrabServer(client); return Success; } int ProcTranslateCoords(ClientPtr client) { REQUEST(xTranslateCoordsReq); WindowPtr pWin, pDst; xTranslateCoordsReply rep; int rc; REQUEST_SIZE_MATCH(xTranslateCoordsReq); rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess); if (rc != Success) return rc; rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess); if (rc != Success) return rc; rep = (xTranslateCoordsReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0 }; if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) { rep.sameScreen = xFalse; rep.child = None; rep.dstX = rep.dstY = 0; } else { INT16 x, y; rep.sameScreen = xTrue; rep.child = None; /* computing absolute coordinates -- adjust to destination later */ x = pWin->drawable.x + stuff->srcX; y = pWin->drawable.y + stuff->srcY; pWin = pDst->firstChild; while (pWin) { BoxRec box; if ((pWin->mapped) && (x >= pWin->drawable.x - wBorderWidth(pWin)) && (x < pWin->drawable.x + (int) pWin->drawable.width + wBorderWidth(pWin)) && (y >= pWin->drawable.y - wBorderWidth(pWin)) && (y < pWin->drawable.y + (int) pWin->drawable.height + wBorderWidth(pWin)) /* When a window is shaped, a further check * is made to see if the point is inside * borderSize */ && (!wBoundingShape(pWin) || RegionContainsPoint(&pWin->borderSize, x, y, &box)) && (!wInputShape(pWin) || RegionContainsPoint(wInputShape(pWin), x - pWin->drawable.x, y - pWin->drawable.y, &box)) ) { rep.child = pWin->drawable.id; pWin = (WindowPtr) NULL; } else pWin = pWin->nextSib; } /* adjust to destination coordinates */ rep.dstX = x - pDst->drawable.x; rep.dstY = y - pDst->drawable.y; } WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); return Success; } int ProcOpenFont(ClientPtr client) { int err; REQUEST(xOpenFontReq); REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes); client->errorValue = stuff->fid; LEGAL_NEW_RESOURCE(stuff->fid, client); err = OpenFont(client, stuff->fid, (Mask) 0, stuff->nbytes, (char *) &stuff[1]); if (err == Success) { return Success; } else return err; } int ProcCloseFont(ClientPtr client) { FontPtr pFont; int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupResourceByType((void **) &pFont, stuff->id, RT_FONT, client, DixDestroyAccess); if (rc == Success) { FreeResource(stuff->id, RT_NONE); return Success; } else { client->errorValue = stuff->id; return rc; } } int ProcQueryFont(ClientPtr client) { xQueryFontReply *reply; FontPtr pFont; int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess); if (rc != Success) return rc; { xCharInfo *pmax = FONTINKMAX(pFont); xCharInfo *pmin = FONTINKMIN(pFont); int nprotoxcistructs; int rlength; nprotoxcistructs = (pmax->rightSideBearing == pmin->rightSideBearing && pmax->leftSideBearing == pmin->leftSideBearing && pmax->descent == pmin->descent && pmax->ascent == pmin->ascent && pmax->characterWidth == pmin->characterWidth) ? 0 : N2dChars(pFont); rlength = sizeof(xQueryFontReply) + FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) + nprotoxcistructs * sizeof(xCharInfo); reply = calloc(1, rlength); if (!reply) { return BadAlloc; } reply->type = X_Reply; reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); reply->sequenceNumber = client->sequence; QueryFont(pFont, reply, nprotoxcistructs); WriteReplyToClient(client, rlength, reply); free(reply); return Success; } } int ProcQueryTextExtents(ClientPtr client) { xQueryTextExtentsReply reply; FontPtr pFont; ExtentInfoRec info; unsigned long length; int rc; REQUEST(xQueryTextExtentsReq); REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq); rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess); if (rc != Success) return rc; length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq)); length = length << 1; if (stuff->oddLength) { if (length == 0) return BadLength; length--; } if (!xfont2_query_text_extents(pFont, length, (unsigned char *) &stuff[1], &info)) return BadAlloc; reply = (xQueryTextExtentsReply) { .type = X_Reply, .drawDirection = info.drawDirection, .sequenceNumber = client->sequence, .length = 0, .fontAscent = info.fontAscent, .fontDescent = info.fontDescent, .overallAscent = info.overallAscent, .overallDescent = info.overallDescent, .overallWidth = info.overallWidth, .overallLeft = info.overallLeft, .overallRight = info.overallRight }; WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply); return Success; } int ProcListFonts(ClientPtr client) { REQUEST(xListFontsReq); REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes); return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, stuff->maxNames); } int ProcListFontsWithInfo(ClientPtr client) { REQUEST(xListFontsWithInfoReq); REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes); return StartListFontsWithInfo(client, stuff->nbytes, (unsigned char *) &stuff[1], stuff->maxNames); } /** * * \param value must conform to DeleteType */ int dixDestroyPixmap(void *value, XID pid) { PixmapPtr pPixmap = (PixmapPtr) value; return (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap); } int ProcCreatePixmap(ClientPtr client) { PixmapPtr pMap; DrawablePtr pDraw; REQUEST(xCreatePixmapReq); DepthPtr pDepth; int i, rc; REQUEST_SIZE_MATCH(xCreatePixmapReq); client->errorValue = stuff->pid; LEGAL_NEW_RESOURCE(stuff->pid, client); rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, DixGetAttrAccess); if (rc != Success) return rc; if (!stuff->width || !stuff->height) { client->errorValue = 0; return BadValue; } if (stuff->width > 32767 || stuff->height > 32767) { /* It is allowed to try and allocate a pixmap which is larger than * 32767 in either dimension. However, all of the framebuffer code * is buggy and does not reliably draw to such big pixmaps, basically * because the Region data structure operates with signed shorts * for the rectangles in it. * * Furthermore, several places in the X server computes the * size in bytes of the pixmap and tries to store it in an * integer. This integer can overflow and cause the allocated size * to be much smaller. * * So, such big pixmaps are rejected here with a BadAlloc */ return BadAlloc; } if (stuff->depth != 1) { pDepth = pDraw->pScreen->allowedDepths; for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++) if (pDepth->depth == stuff->depth) goto CreatePmap; client->errorValue = stuff->depth; return BadValue; } CreatePmap: pMap = (PixmapPtr) (*pDraw->pScreen->CreatePixmap) (pDraw->pScreen, stuff->width, stuff->height, stuff->depth, 0); if (pMap) { pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; pMap->drawable.id = stuff->pid; /* security creation/labeling check */ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, pMap, RT_NONE, NULL, DixCreateAccess); if (rc != Success) { (*pDraw->pScreen->DestroyPixmap) (pMap); return rc; } if (AddResource(stuff->pid, RT_PIXMAP, (void *) pMap)) return Success; } return BadAlloc; } int ProcFreePixmap(ClientPtr client) { PixmapPtr pMap; int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupResourceByType((void **) &pMap, stuff->id, RT_PIXMAP, client, DixDestroyAccess); if (rc == Success) { FreeResource(stuff->id, RT_NONE); return Success; } else { client->errorValue = stuff->id; return rc; } } int ProcCreateGC(ClientPtr client) { int error, rc; GC *pGC; DrawablePtr pDraw; unsigned len; REQUEST(xCreateGCReq); REQUEST_AT_LEAST_SIZE(xCreateGCReq); client->errorValue = stuff->gc; LEGAL_NEW_RESOURCE(stuff->gc, client); rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixGetAttrAccess); if (rc != Success) return rc; len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq)); if (len != Ones(stuff->mask)) return BadLength; pGC = (GC *) CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error, stuff->gc, client); if (error != Success) return error; if (!AddResource(stuff->gc, RT_GC, (void *) pGC)) return BadAlloc; return Success; } int ProcChangeGC(ClientPtr client) { GC *pGC; int result; unsigned len; REQUEST(xChangeGCReq); REQUEST_AT_LEAST_SIZE(xChangeGCReq); result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); if (result != Success) return result; len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq)); if (len != Ones(stuff->mask)) return BadLength; return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]); } int ProcCopyGC(ClientPtr client) { GC *dstGC; GC *pGC; int result; REQUEST(xCopyGCReq); REQUEST_SIZE_MATCH(xCopyGCReq); result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess); if (result != Success) return result; result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess); if (result != Success) return result; if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth)) return BadMatch; if (stuff->mask & ~GCAllBits) { client->errorValue = stuff->mask; return BadValue; } return CopyGC(pGC, dstGC, stuff->mask); } int ProcSetDashes(ClientPtr client) { GC *pGC; int result; REQUEST(xSetDashesReq); REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); if (stuff->nDashes == 0) { client->errorValue = 0; return BadValue; } result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); if (result != Success) return result; /* If there's an error, either there's no sensible errorValue, * or there was a dash segment of 0. */ client->errorValue = 0; return SetDashes(pGC, stuff->dashOffset, stuff->nDashes, (unsigned char *) &stuff[1]); } int ProcSetClipRectangles(ClientPtr client) { int nr, result; GC *pGC; REQUEST(xSetClipRectanglesReq); REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) { client->errorValue = stuff->ordering; return BadValue; } result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); if (result != Success) return result; nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq); if (nr & 4) return BadLength; nr >>= 3; return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin, nr, (xRectangle *) &stuff[1], (int) stuff->ordering); } int ProcFreeGC(ClientPtr client) { GC *pGC; int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess); if (rc != Success) return rc; FreeResource(stuff->id, RT_NONE); return Success; } int ProcClearToBackground(ClientPtr client) { REQUEST(xClearAreaReq); WindowPtr pWin; int rc; REQUEST_SIZE_MATCH(xClearAreaReq); rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); if (rc != Success) return rc; if (pWin->drawable.class == InputOnly) { client->errorValue = stuff->window; return BadMatch; } if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) { client->errorValue = stuff->exposures; return BadValue; } (*pWin->drawable.pScreen->ClearToBackground) (pWin, stuff->x, stuff->y, stuff->width, stuff->height, (Bool) stuff->exposures); return Success; } /* send GraphicsExpose events, or a NoExpose event, based on the region */ void SendGraphicsExpose(ClientPtr client, RegionPtr pRgn, XID drawable, int major, int minor) { if (pRgn && !RegionNil(pRgn)) { xEvent *pEvent; xEvent *pe; BoxPtr pBox; int i; int numRects; numRects = RegionNumRects(pRgn); pBox = RegionRects(pRgn); if (!(pEvent = calloc(numRects, sizeof(xEvent)))) return; pe = pEvent; for (i = 1; i <= numRects; i++, pe++, pBox++) { pe->u.u.type = GraphicsExpose; pe->u.graphicsExposure.drawable = drawable; pe->u.graphicsExposure.x = pBox->x1; pe->u.graphicsExposure.y = pBox->y1; pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; pe->u.graphicsExposure.count = numRects - i; pe->u.graphicsExposure.majorEvent = major; pe->u.graphicsExposure.minorEvent = minor; } /* GraphicsExpose is a "critical event", which TryClientEvents * handles specially. */ TryClientEvents(client, NULL, pEvent, numRects, (Mask) 0, NoEventMask, NullGrab); free(pEvent); } else { xEvent event = { .u.noExposure.drawable = drawable, .u.noExposure.majorEvent = major, .u.noExposure.minorEvent = minor }; event.u.u.type = NoExpose; WriteEventsToClient(client, 1, &event); } } int ProcCopyArea(ClientPtr client) { DrawablePtr pDst; DrawablePtr pSrc; GC *pGC; REQUEST(xCopyAreaReq); RegionPtr pRgn; int rc; REQUEST_SIZE_MATCH(xCopyAreaReq); VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); if (stuff->dstDrawable != stuff->srcDrawable) { rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, DixReadAccess); if (rc != Success) return rc; if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) { client->errorValue = stuff->dstDrawable; return BadMatch; } } else pSrc = pDst; pRgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, stuff->srcX, stuff->srcY, stuff->width, stuff->height, stuff->dstX, stuff->dstY); if (pGC->graphicsExposures) { SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyArea, 0); if (pRgn) RegionDestroy(pRgn); } return Success; } int ProcCopyPlane(ClientPtr client) { DrawablePtr psrcDraw, pdstDraw; GC *pGC; REQUEST(xCopyPlaneReq); RegionPtr pRgn; int rc; REQUEST_SIZE_MATCH(xCopyPlaneReq); VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess); if (stuff->dstDrawable != stuff->srcDrawable) { rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, DixReadAccess); if (rc != Success) return rc; if (pdstDraw->pScreen != psrcDraw->pScreen) { client->errorValue = stuff->dstDrawable; return BadMatch; } } else psrcDraw = pdstDraw; /* Check to see if stuff->bitPlane has exactly ONE good bit set */ if (stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) { client->errorValue = stuff->bitPlane; return BadValue; } pRgn = (*pGC->ops->CopyPlane) (psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY, stuff->width, stuff->height, stuff->dstX, stuff->dstY, stuff->bitPlane); if (pGC->graphicsExposures) { SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); if (pRgn) RegionDestroy(pRgn); } return Success; } int ProcPolyPoint(ClientPtr client) { int npoint; GC *pGC; DrawablePtr pDraw; REQUEST(xPolyPointReq); REQUEST_AT_LEAST_SIZE(xPolyPointReq); if ((stuff->coordMode != CoordModeOrigin) && (stuff->coordMode != CoordModePrevious)) { client->errorValue = stuff->coordMode; return BadValue; } VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); if (npoint) (*pGC->ops->PolyPoint) (pDraw, pGC, stuff->coordMode, npoint, (xPoint *) &stuff[1]); return Success; } int ProcPolyLine(ClientPtr client) { int npoint; GC *pGC; DrawablePtr pDraw; REQUEST(xPolyLineReq); REQUEST_AT_LEAST_SIZE(xPolyLineReq); if ((stuff->coordMode != CoordModeOrigin) && (stuff->coordMode != CoordModePrevious)) { client->errorValue = stuff->coordMode; return BadValue; } VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); if (npoint > 1) (*pGC->ops->Polylines) (pDraw, pGC, stuff->coordMode, npoint, (DDXPointPtr) &stuff[1]); return Success; } int ProcPolySegment(ClientPtr client) { int nsegs; GC *pGC; DrawablePtr pDraw; REQUEST(xPolySegmentReq); REQUEST_AT_LEAST_SIZE(xPolySegmentReq); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); if (nsegs & 4) return BadLength; nsegs >>= 3; if (nsegs) (*pGC->ops->PolySegment) (pDraw, pGC, nsegs, (xSegment *) &stuff[1]); return Success; } int ProcPolyRectangle(ClientPtr client) { int nrects; GC *pGC; DrawablePtr pDraw; REQUEST(xPolyRectangleReq); REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); if (nrects & 4) return BadLength; nrects >>= 3; if (nrects) (*pGC->ops->PolyRectangle) (pDraw, pGC, nrects, (xRectangle *) &stuff[1]); return Success; } int ProcPolyArc(ClientPtr client) { int narcs; GC *pGC; DrawablePtr pDraw; REQUEST(xPolyArcReq); REQUEST_AT_LEAST_SIZE(xPolyArcReq); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); narcs = (client->req_len << 2) - sizeof(xPolyArcReq); if (narcs % sizeof(xArc)) return BadLength; narcs /= sizeof(xArc); if (narcs) (*pGC->ops->PolyArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); return Success; } int ProcFillPoly(ClientPtr client) { int things; GC *pGC; DrawablePtr pDraw; REQUEST(xFillPolyReq); REQUEST_AT_LEAST_SIZE(xFillPolyReq); if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) && (stuff->shape != Convex)) { client->errorValue = stuff->shape; return BadValue; } if ((stuff->coordMode != CoordModeOrigin) && (stuff->coordMode != CoordModePrevious)) { client->errorValue = stuff->coordMode; return BadValue; } VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); if (things) (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape, stuff->coordMode, things, (DDXPointPtr) &stuff[1]); return Success; } int ProcPolyFillRectangle(ClientPtr client) { int things; GC *pGC; DrawablePtr pDraw; REQUEST(xPolyFillRectangleReq); REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); if (things & 4) return BadLength; things >>= 3; if (things) (*pGC->ops->PolyFillRect) (pDraw, pGC, things, (xRectangle *) &stuff[1]); return Success; } int ProcPolyFillArc(ClientPtr client) { int narcs; GC *pGC; DrawablePtr pDraw; REQUEST(xPolyFillArcReq); REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); if (narcs % sizeof(xArc)) return BadLength; narcs /= sizeof(xArc); if (narcs) (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); return Success; } #ifdef MATCH_CLIENT_ENDIAN int ServerOrder(void) { int whichbyte = 1; if (*((char *) &whichbyte)) return LSBFirst; return MSBFirst; } #define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder()) void ReformatImage(char *base, int nbytes, int bpp, int order) { switch (bpp) { case 1: /* yuck */ if (BITMAP_BIT_ORDER != order) BitOrderInvert((unsigned char *) base, nbytes); #if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8 ReformatImage(base, nbytes, BITMAP_SCANLINE_UNIT, order); #endif break; case 4: break; /* yuck */ case 8: break; case 16: if (IMAGE_BYTE_ORDER != order) TwoByteSwap((unsigned char *) base, nbytes); break; case 32: if (IMAGE_BYTE_ORDER != order) FourByteSwap((unsigned char *) base, nbytes); break; } } #else #define ReformatImage(b,n,bpp,o) #endif /* 64-bit server notes: the protocol restricts padding of images to * 8-, 16-, or 32-bits. We would like to have 64-bits for the server * to use internally. Removes need for internal alignment checking. * All of the PutImage functions could be changed individually, but * as currently written, they call other routines which require things * to be 64-bit padded on scanlines, so we changed things here. * If an image would be padded differently for 64- versus 32-, then * copy each scanline to a 64-bit padded scanline. * Also, we need to make sure that the image is aligned on a 64-bit * boundary, even if the scanlines are padded to our satisfaction. */ int ProcPutImage(ClientPtr client) { GC *pGC; DrawablePtr pDraw; long length; /* length of scanline server padded */ long lengthProto; /* length of scanline protocol padded */ char *tmpImage; REQUEST(xPutImageReq); REQUEST_AT_LEAST_SIZE(xPutImageReq); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); if (stuff->format == XYBitmap) { if ((stuff->depth != 1) || (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad)) return BadMatch; length = BitmapBytePad(stuff->width + stuff->leftPad); } else if (stuff->format == XYPixmap) { if ((pDraw->depth != stuff->depth) || (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad)) return BadMatch; length = BitmapBytePad(stuff->width + stuff->leftPad); length *= stuff->depth; } else if (stuff->format == ZPixmap) { if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0)) return BadMatch; length = PixmapBytePad(stuff->width, stuff->depth); } else { client->errorValue = stuff->format; return BadValue; } tmpImage = (char *) &stuff[1]; lengthProto = length; if (stuff->height != 0 && lengthProto >= (INT32_MAX / stuff->height)) return BadLength; if ((bytes_to_int32(lengthProto * stuff->height) + bytes_to_int32(sizeof(xPutImageReq))) != client->req_len) return BadLength; ReformatImage(tmpImage, lengthProto * stuff->height, stuff->format == ZPixmap ? BitsPerPixel(stuff->depth) : 1, ClientOrder(client)); (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY, stuff->width, stuff->height, stuff->leftPad, stuff->format, tmpImage); return Success; } static int DoGetImage(ClientPtr client, int format, Drawable drawable, int x, int y, int width, int height, Mask planemask) { DrawablePtr pDraw, pBoundingDraw; int nlines, linesPerBuf, rc; int linesDone; /* coordinates relative to the bounding drawable */ int relx, rely; long widthBytesLine, length; Mask plane = 0; char *pBuf; xGetImageReply xgi; RegionPtr pVisibleRegion = NULL; if ((format != XYPixmap) && (format != ZPixmap)) { client->errorValue = format; return BadValue; } rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess); if (rc != Success) return rc; memset(&xgi, 0, sizeof(xGetImageReply)); relx = x; rely = y; if (pDraw->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr) pDraw; /* "If the drawable is a window, the window must be viewable ... or a * BadMatch error results" */ if (!pWin->viewable) return BadMatch; /* If the drawable is a window, the rectangle must be contained within * its bounds (including the border). */ if (x < -wBorderWidth(pWin) || x + width > wBorderWidth(pWin) + (int) pDraw->width || y < -wBorderWidth(pWin) || y + height > wBorderWidth(pWin) + (int) pDraw->height) return BadMatch; relx += pDraw->x; rely += pDraw->y; if (pDraw->pScreen->GetWindowPixmap) { PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin); pBoundingDraw = &pPix->drawable; #ifdef COMPOSITE relx -= pPix->screen_x; rely -= pPix->screen_y; #endif } else { pBoundingDraw = (DrawablePtr) pDraw->pScreen->root; } xgi.visual = wVisual(pWin); } else { pBoundingDraw = pDraw; xgi.visual = None; } /* "If the drawable is a pixmap, the given rectangle must be wholly * contained within the pixmap, or a BadMatch error results. If the * drawable is a window [...] it must be the case that if there were no * inferiors or overlapping windows, the specified rectangle of the window * would be fully visible on the screen and wholly contained within the * outside edges of the window, or a BadMatch error results." * * We relax the window case slightly to mean that the rectangle must exist * within the bounds of the window's backing pixmap. In particular, this * means that a GetImage request may succeed or fail with BadMatch depending * on whether any of its ancestor windows are redirected. */ if (relx < 0 || relx + width > (int) pBoundingDraw->width || rely < 0 || rely + height > (int) pBoundingDraw->height) return BadMatch; xgi.type = X_Reply; xgi.sequenceNumber = client->sequence; xgi.depth = pDraw->depth; if (format == ZPixmap) { widthBytesLine = PixmapBytePad(width, pDraw->depth); length = widthBytesLine * height; } else { widthBytesLine = BitmapBytePad(width); plane = ((Mask) 1) << (pDraw->depth - 1); /* only planes asked for */ length = widthBytesLine * height * Ones(planemask & (plane | (plane - 1))); } xgi.length = length; xgi.length = bytes_to_int32(xgi.length); if (widthBytesLine == 0 || height == 0) linesPerBuf = 0; else if (widthBytesLine >= IMAGE_BUFSIZE) linesPerBuf = 1; else { linesPerBuf = IMAGE_BUFSIZE / widthBytesLine; if (linesPerBuf > height) linesPerBuf = height; } length = linesPerBuf * widthBytesLine; if (linesPerBuf < height) { /* we have to make sure intermediate buffers don't need padding */ while ((linesPerBuf > 1) && (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1))) { linesPerBuf--; length -= widthBytesLine; } while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1)) { linesPerBuf++; length += widthBytesLine; } } if (!(pBuf = calloc(1, length))) return BadAlloc; WriteReplyToClient(client, sizeof(xGetImageReply), &xgi); if (pDraw->type == DRAWABLE_WINDOW) { pVisibleRegion = &((WindowPtr) pDraw)->borderClip; pDraw->pScreen->SourceValidate(pDraw, x, y, width, height, IncludeInferiors); } if (linesPerBuf == 0) { /* nothing to do */ } else if (format == ZPixmap) { linesDone = 0; while (height - linesDone > 0) { nlines = min(linesPerBuf, height - linesDone); (*pDraw->pScreen->GetImage) (pDraw, x, y + linesDone, width, nlines, format, planemask, (void *) pBuf); if (pVisibleRegion) XaceCensorImage(client, pVisibleRegion, widthBytesLine, pDraw, x, y + linesDone, width, nlines, format, pBuf); /* Note that this is NOT a call to WriteSwappedDataToClient, as we do NOT byte swap */ ReformatImage(pBuf, (int) (nlines * widthBytesLine), BitsPerPixel(pDraw->depth), ClientOrder(client)); WriteToClient(client, (int) (nlines * widthBytesLine), pBuf); linesDone += nlines; } } else { /* XYPixmap */ for (; plane; plane >>= 1) { if (planemask & plane) { linesDone = 0; while (height - linesDone > 0) { nlines = min(linesPerBuf, height - linesDone); (*pDraw->pScreen->GetImage) (pDraw, x, y + linesDone, width, nlines, format, plane, (void *) pBuf); if (pVisibleRegion) XaceCensorImage(client, pVisibleRegion, widthBytesLine, pDraw, x, y + linesDone, width, nlines, format, pBuf); /* Note: NOT a call to WriteSwappedDataToClient, as we do NOT byte swap */ ReformatImage(pBuf, (int) (nlines * widthBytesLine), 1, ClientOrder(client)); WriteToClient(client, (int)(nlines * widthBytesLine), pBuf); linesDone += nlines; } } } } free(pBuf); return Success; } int ProcGetImage(ClientPtr client) { REQUEST(xGetImageReq); REQUEST_SIZE_MATCH(xGetImageReq); return DoGetImage(client, stuff->format, stuff->drawable, stuff->x, stuff->y, (int) stuff->width, (int) stuff->height, stuff->planeMask); } int ProcPolyText(ClientPtr client) { int err; REQUEST(xPolyTextReq); DrawablePtr pDraw; GC *pGC; REQUEST_AT_LEAST_SIZE(xPolyTextReq); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); err = PolyText(client, pDraw, pGC, (unsigned char *) &stuff[1], ((unsigned char *) stuff) + (client->req_len << 2), stuff->x, stuff->y, stuff->reqType, stuff->drawable); if (err == Success) { return Success; } else return err; } int ProcImageText8(ClientPtr client) { int err; DrawablePtr pDraw; GC *pGC; REQUEST(xImageTextReq); REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); err = ImageText(client, pDraw, pGC, stuff->nChars, (unsigned char *) &stuff[1], stuff->x, stuff->y, stuff->reqType, stuff->drawable); if (err == Success) { return Success; } else return err; } int ProcImageText16(ClientPtr client) { int err; DrawablePtr pDraw; GC *pGC; REQUEST(xImageTextReq); REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); err = ImageText(client, pDraw, pGC, stuff->nChars, (unsigned char *) &stuff[1], stuff->x, stuff->y, stuff->reqType, stuff->drawable); if (err == Success) { return Success; } else return err; } int ProcCreateColormap(ClientPtr client) { VisualPtr pVisual; ColormapPtr pmap; Colormap mid; WindowPtr pWin; ScreenPtr pScreen; REQUEST(xCreateColormapReq); int i, result; REQUEST_SIZE_MATCH(xCreateColormapReq); if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) { client->errorValue = stuff->alloc; return BadValue; } mid = stuff->mid; LEGAL_NEW_RESOURCE(mid, client); result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (result != Success) return result; pScreen = pWin->drawable.pScreen; for (i = 0, pVisual = pScreen->visuals; i < pScreen->numVisuals; i++, pVisual++) { if (pVisual->vid != stuff->visual) continue; return CreateColormap(mid, pScreen, pVisual, &pmap, (int) stuff->alloc, client->index); } client->errorValue = stuff->visual; return BadMatch; } int ProcFreeColormap(ClientPtr client) { ColormapPtr pmap; int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupResourceByType((void **) &pmap, stuff->id, RT_COLORMAP, client, DixDestroyAccess); if (rc == Success) { /* Freeing a default colormap is a no-op */ if (!(pmap->flags & IsDefault)) FreeResource(stuff->id, RT_NONE); return Success; } else { client->errorValue = stuff->id; return rc; } } int ProcCopyColormapAndFree(ClientPtr client) { Colormap mid; ColormapPtr pSrcMap; REQUEST(xCopyColormapAndFreeReq); int rc; REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); mid = stuff->mid; LEGAL_NEW_RESOURCE(mid, client); rc = dixLookupResourceByType((void **) &pSrcMap, stuff->srcCmap, RT_COLORMAP, client, DixReadAccess | DixRemoveAccess); if (rc == Success) return CopyColormapAndFree(mid, pSrcMap, client->index); client->errorValue = stuff->srcCmap; return rc; } int ProcInstallColormap(ClientPtr client) { ColormapPtr pcmp; int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP, client, DixInstallAccess); if (rc != Success) goto out; rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); if (rc != Success) { if (rc == BadValue) rc = BadColor; goto out; } (*(pcmp->pScreen->InstallColormap)) (pcmp); return Success; out: client->errorValue = stuff->id; return rc; } int ProcUninstallColormap(ClientPtr client) { ColormapPtr pcmp; int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP, client, DixUninstallAccess); if (rc != Success) goto out; rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); if (rc != Success) { if (rc == BadValue) rc = BadColor; goto out; } if (pcmp->mid != pcmp->pScreen->defColormap) (*(pcmp->pScreen->UninstallColormap)) (pcmp); return Success; out: client->errorValue = stuff->id; return rc; } int ProcListInstalledColormaps(ClientPtr client) { xListInstalledColormapsReply *preply; int nummaps, rc; WindowPtr pWin; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); if (rc != Success) return rc; rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, DixGetAttrAccess); if (rc != Success) return rc; preply = malloc(sizeof(xListInstalledColormapsReply) + pWin->drawable.pScreen->maxInstalledCmaps * sizeof(Colormap)); if (!preply) return BadAlloc; preply->type = X_Reply; preply->sequenceNumber = client->sequence; nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) (pWin->drawable.pScreen, (Colormap *) &preply[1]); preply->nColormaps = nummaps; preply->length = nummaps; WriteReplyToClient(client, sizeof(xListInstalledColormapsReply), preply); client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]); free(preply); return Success; } int ProcAllocColor(ClientPtr client) { ColormapPtr pmap; int rc; REQUEST(xAllocColorReq); REQUEST_SIZE_MATCH(xAllocColorReq); rc = dixLookupResourceByType((void **) &pmap, stuff->cmap, RT_COLORMAP, client, DixAddAccess); if (rc == Success) { xAllocColorReply acr = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .red = stuff->red, .green = stuff->green, .blue = stuff->blue, .pixel = 0 }; if ((rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue, &acr.pixel, client->index))) return rc; #ifdef PANORAMIX if (noPanoramiXExtension || !pmap->pScreen->myNum) #endif WriteReplyToClient(client, sizeof(xAllocColorReply), &acr); return Success; } else { client->errorValue = stuff->cmap; return rc; } } int ProcAllocNamedColor(ClientPtr client) { ColormapPtr pcmp; int rc; REQUEST(xAllocNamedColorReq); REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, client, DixAddAccess); if (rc == Success) { xAllocNamedColorReply ancr = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0 }; if (OsLookupColor (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes, &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) { ancr.screenRed = ancr.exactRed; ancr.screenGreen = ancr.exactGreen; ancr.screenBlue = ancr.exactBlue; ancr.pixel = 0; if ((rc = AllocColor(pcmp, &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue, &ancr.pixel, client->index))) return rc; #ifdef PANORAMIX if (noPanoramiXExtension || !pcmp->pScreen->myNum) #endif WriteReplyToClient(client, sizeof(xAllocNamedColorReply), &ancr); return Success; } else return BadName; } else { client->errorValue = stuff->cmap; return rc; } } int ProcAllocColorCells(ClientPtr client) { ColormapPtr pcmp; int rc; REQUEST(xAllocColorCellsReq); REQUEST_SIZE_MATCH(xAllocColorCellsReq); rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, client, DixAddAccess); if (rc == Success) { int npixels, nmasks; long length; Pixel *ppixels, *pmasks; npixels = stuff->colors; if (!npixels) { client->errorValue = npixels; return BadValue; } if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) { client->errorValue = stuff->contiguous; return BadValue; } nmasks = stuff->planes; length = ((long) npixels + (long) nmasks) * sizeof(Pixel); ppixels = malloc(length); if (!ppixels) return BadAlloc; pmasks = ppixels + npixels; if ((rc = AllocColorCells(client->index, pcmp, npixels, nmasks, (Bool) stuff->contiguous, ppixels, pmasks))) { free(ppixels); return rc; } #ifdef PANORAMIX if (noPanoramiXExtension || !pcmp->pScreen->myNum) #endif { xAllocColorCellsReply accr = { .type = X_Reply, .sequenceNumber = client->sequence, .length = bytes_to_int32(length), .nPixels = npixels, .nMasks = nmasks }; WriteReplyToClient(client, sizeof(xAllocColorCellsReply), &accr); client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; WriteSwappedDataToClient(client, length, ppixels); } free(ppixels); return Success; } else { client->errorValue = stuff->cmap; return rc; } } int ProcAllocColorPlanes(ClientPtr client) { ColormapPtr pcmp; int rc; REQUEST(xAllocColorPlanesReq); REQUEST_SIZE_MATCH(xAllocColorPlanesReq); rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, client, DixAddAccess); if (rc == Success) { xAllocColorPlanesReply acpr; int npixels; long length; Pixel *ppixels; npixels = stuff->colors; if (!npixels) { client->errorValue = npixels; return BadValue; } if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) { client->errorValue = stuff->contiguous; return BadValue; } acpr = (xAllocColorPlanesReply) { .type = X_Reply, .sequenceNumber = client->sequence, .nPixels = npixels }; length = (long) npixels *sizeof(Pixel); ppixels = malloc(length); if (!ppixels) return BadAlloc; if ((rc = AllocColorPlanes(client->index, pcmp, npixels, (int) stuff->red, (int) stuff->green, (int) stuff->blue, (Bool) stuff->contiguous, ppixels, &acpr.redMask, &acpr.greenMask, &acpr.blueMask))) { free(ppixels); return rc; } acpr.length = bytes_to_int32(length); #ifdef PANORAMIX if (noPanoramiXExtension || !pcmp->pScreen->myNum) #endif { WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr); client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; WriteSwappedDataToClient(client, length, ppixels); } free(ppixels); return Success; } else { client->errorValue = stuff->cmap; return rc; } } int ProcFreeColors(ClientPtr client) { ColormapPtr pcmp; int rc; REQUEST(xFreeColorsReq); REQUEST_AT_LEAST_SIZE(xFreeColorsReq); rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, client, DixRemoveAccess); if (rc == Success) { int count; if (pcmp->flags & AllAllocated) return BadAccess; count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq)); return FreeColors(pcmp, client->index, count, (Pixel *) &stuff[1], (Pixel) stuff->planeMask); } else { client->errorValue = stuff->cmap; return rc; } } int ProcStoreColors(ClientPtr client) { ColormapPtr pcmp; int rc; REQUEST(xStoreColorsReq); REQUEST_AT_LEAST_SIZE(xStoreColorsReq); rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, client, DixWriteAccess); if (rc == Success) { int count; count = (client->req_len << 2) - sizeof(xStoreColorsReq); if (count % sizeof(xColorItem)) return BadLength; count /= sizeof(xColorItem); return StoreColors(pcmp, count, (xColorItem *) &stuff[1], client); } else { client->errorValue = stuff->cmap; return rc; } } int ProcStoreNamedColor(ClientPtr client) { ColormapPtr pcmp; int rc; REQUEST(xStoreNamedColorReq); REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, client, DixWriteAccess); if (rc == Success) { xColorItem def; if (OsLookupColor(pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes, &def.red, &def.green, &def.blue)) { def.flags = stuff->flags; def.pixel = stuff->pixel; return StoreColors(pcmp, 1, &def, client); } return BadName; } else { client->errorValue = stuff->cmap; return rc; } } int ProcQueryColors(ClientPtr client) { ColormapPtr pcmp; int rc; REQUEST(xQueryColorsReq); REQUEST_AT_LEAST_SIZE(xQueryColorsReq); rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, client, DixReadAccess); if (rc == Success) { int count; xrgb *prgbs; xQueryColorsReply qcr; count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq)); prgbs = calloc(count, sizeof(xrgb)); if (!prgbs && count) return BadAlloc; if ((rc = QueryColors(pcmp, count, (Pixel *) &stuff[1], prgbs, client))) { free(prgbs); return rc; } qcr = (xQueryColorsReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = bytes_to_int32(count * sizeof(xrgb)), .nColors = count }; WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); if (count) { client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend; WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs); } free(prgbs); return Success; } else { client->errorValue = stuff->cmap; return rc; } } int ProcLookupColor(ClientPtr client) { ColormapPtr pcmp; int rc; REQUEST(xLookupColorReq); REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes); rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, client, DixReadAccess); if (rc == Success) { CARD16 exactRed, exactGreen, exactBlue; if (OsLookupColor (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes, &exactRed, &exactGreen, &exactBlue)) { xLookupColorReply lcr = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .exactRed = exactRed, .exactGreen = exactGreen, .exactBlue = exactBlue, .screenRed = exactRed, .screenGreen = exactGreen, .screenBlue = exactBlue }; (*pcmp->pScreen->ResolveColor) (&lcr.screenRed, &lcr.screenGreen, &lcr.screenBlue, pcmp->pVisual); WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr); return Success; } return BadName; } else { client->errorValue = stuff->cmap; return rc; } } int ProcCreateCursor(ClientPtr client) { CursorPtr pCursor; PixmapPtr src; PixmapPtr msk; unsigned char *srcbits; unsigned char *mskbits; unsigned short width, height; long n; CursorMetricRec cm; int rc; REQUEST(xCreateCursorReq); REQUEST_SIZE_MATCH(xCreateCursorReq); LEGAL_NEW_RESOURCE(stuff->cid, client); rc = dixLookupResourceByType((void **) &src, stuff->source, RT_PIXMAP, client, DixReadAccess); if (rc != Success) { client->errorValue = stuff->source; return rc; } if (src->drawable.depth != 1) return (BadMatch); /* Find and validate cursor mask pixmap, if one is provided */ if (stuff->mask != None) { rc = dixLookupResourceByType((void **) &msk, stuff->mask, RT_PIXMAP, client, DixReadAccess); if (rc != Success) { client->errorValue = stuff->mask; return rc; } if (src->drawable.width != msk->drawable.width || src->drawable.height != msk->drawable.height || src->drawable.depth != 1 || msk->drawable.depth != 1) return BadMatch; } else msk = NULL; width = src->drawable.width; height = src->drawable.height; if (stuff->x > width || stuff->y > height) return BadMatch; srcbits = calloc(BitmapBytePad(width), height); if (!srcbits) return BadAlloc; n = BitmapBytePad(width) * height; mskbits = malloc(n); if (!mskbits) { free(srcbits); return BadAlloc; } (*src->drawable.pScreen->GetImage) ((DrawablePtr) src, 0, 0, width, height, XYPixmap, 1, (void *) srcbits); if (msk == (PixmapPtr) NULL) { unsigned char *bits = mskbits; while (--n >= 0) *bits++ = ~0; } else { /* zeroing the (pad) bits helps some ddx cursor handling */ memset((char *) mskbits, 0, n); (*msk->drawable.pScreen->GetImage) ((DrawablePtr) msk, 0, 0, width, height, XYPixmap, 1, (void *) mskbits); } cm.width = width; cm.height = height; cm.xhot = stuff->x; cm.yhot = stuff->y; rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm, stuff->foreRed, stuff->foreGreen, stuff->foreBlue, stuff->backRed, stuff->backGreen, stuff->backBlue, &pCursor, client, stuff->cid); if (rc != Success) goto bail; if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) { rc = BadAlloc; goto bail; } return Success; bail: free(srcbits); free(mskbits); return rc; } int ProcCreateGlyphCursor(ClientPtr client) { CursorPtr pCursor; int res; REQUEST(xCreateGlyphCursorReq); REQUEST_SIZE_MATCH(xCreateGlyphCursorReq); LEGAL_NEW_RESOURCE(stuff->cid, client); res = AllocGlyphCursor(stuff->source, stuff->sourceChar, stuff->mask, stuff->maskChar, stuff->foreRed, stuff->foreGreen, stuff->foreBlue, stuff->backRed, stuff->backGreen, stuff->backBlue, &pCursor, client, stuff->cid); if (res != Success) return res; if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) return Success; return BadAlloc; } int ProcFreeCursor(ClientPtr client) { CursorPtr pCursor; int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupResourceByType((void **) &pCursor, stuff->id, RT_CURSOR, client, DixDestroyAccess); if (rc == Success) { FreeResource(stuff->id, RT_NONE); return Success; } else { client->errorValue = stuff->id; return rc; } } int ProcQueryBestSize(ClientPtr client) { xQueryBestSizeReply reply; DrawablePtr pDraw; ScreenPtr pScreen; int rc; REQUEST(xQueryBestSizeReq); REQUEST_SIZE_MATCH(xQueryBestSizeReq); if ((stuff->class != CursorShape) && (stuff->class != TileShape) && (stuff->class != StippleShape)) { client->errorValue = stuff->class; return BadValue; } rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, DixGetAttrAccess); if (rc != Success) return rc; if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW) return BadMatch; pScreen = pDraw->pScreen; rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); if (rc != Success) return rc; (*pScreen->QueryBestSize) (stuff->class, &stuff->width, &stuff->height, pScreen); reply = (xQueryBestSizeReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .width = stuff->width, .height = stuff->height }; WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply); return Success; } int ProcSetScreenSaver(ClientPtr client) { int rc, i, blankingOption, exposureOption; REQUEST(xSetScreenSaverReq); REQUEST_SIZE_MATCH(xSetScreenSaverReq); for (i = 0; i < screenInfo.numScreens; i++) { rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], DixSetAttrAccess); if (rc != Success) return rc; } blankingOption = stuff->preferBlank; if ((blankingOption != DontPreferBlanking) && (blankingOption != PreferBlanking) && (blankingOption != DefaultBlanking)) { client->errorValue = blankingOption; return BadValue; } exposureOption = stuff->allowExpose; if ((exposureOption != DontAllowExposures) && (exposureOption != AllowExposures) && (exposureOption != DefaultExposures)) { client->errorValue = exposureOption; return BadValue; } if (stuff->timeout < -1) { client->errorValue = stuff->timeout; return BadValue; } if (stuff->interval < -1) { client->errorValue = stuff->interval; return BadValue; } if (blankingOption == DefaultBlanking) ScreenSaverBlanking = defaultScreenSaverBlanking; else ScreenSaverBlanking = blankingOption; if (exposureOption == DefaultExposures) ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; else ScreenSaverAllowExposures = exposureOption; if (stuff->timeout >= 0) ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND; else ScreenSaverTime = defaultScreenSaverTime; if (stuff->interval >= 0) ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND; else ScreenSaverInterval = defaultScreenSaverInterval; SetScreenSaverTimer(); return Success; } int ProcGetScreenSaver(ClientPtr client) { xGetScreenSaverReply rep; int rc, i; REQUEST_SIZE_MATCH(xReq); for (i = 0; i < screenInfo.numScreens; i++) { rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], DixGetAttrAccess); if (rc != Success) return rc; } rep = (xGetScreenSaverReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .timeout = ScreenSaverTime / MILLI_PER_SECOND, .interval = ScreenSaverInterval / MILLI_PER_SECOND, .preferBlanking = ScreenSaverBlanking, .allowExposures = ScreenSaverAllowExposures }; WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep); return Success; } int ProcChangeHosts(ClientPtr client) { REQUEST(xChangeHostsReq); REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength); if (stuff->mode == HostInsert) return AddHost(client, (int) stuff->hostFamily, stuff->hostLength, (void *) &stuff[1]); if (stuff->mode == HostDelete) return RemoveHost(client, (int) stuff->hostFamily, stuff->hostLength, (void *) &stuff[1]); client->errorValue = stuff->mode; return BadValue; } int ProcListHosts(ClientPtr client) { xListHostsReply reply; int len, nHosts, result; BOOL enabled; void *pdata; /* REQUEST(xListHostsReq); */ REQUEST_SIZE_MATCH(xListHostsReq); /* untrusted clients can't list hosts */ result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess); if (result != Success) return result; result = GetHosts(&pdata, &nHosts, &len, &enabled); if (result != Success) return result; reply = (xListHostsReply) { .type = X_Reply, .enabled = enabled, .sequenceNumber = client->sequence, .length = bytes_to_int32(len), .nHosts = nHosts }; WriteReplyToClient(client, sizeof(xListHostsReply), &reply); if (nHosts) { client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend; WriteSwappedDataToClient(client, len, pdata); } free(pdata); return Success; } int ProcChangeAccessControl(ClientPtr client) { REQUEST(xSetAccessControlReq); REQUEST_SIZE_MATCH(xSetAccessControlReq); if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) { client->errorValue = stuff->mode; return BadValue; } return ChangeAccessControl(client, stuff->mode == EnableAccess); } /********************* * CloseDownRetainedResources * * Find all clients that are gone and have terminated in RetainTemporary * and destroy their resources. *********************/ static void CloseDownRetainedResources(void) { int i; ClientPtr client; for (i = 1; i < currentMaxClients; i++) { client = clients[i]; if (client && (client->closeDownMode == RetainTemporary) && (client->clientGone)) CloseDownClient(client); } } int ProcKillClient(ClientPtr client) { REQUEST(xResourceReq); ClientPtr killclient; int rc; REQUEST_SIZE_MATCH(xResourceReq); if (stuff->id == AllTemporary) { CloseDownRetainedResources(); return Success; } rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess); if (rc == Success) { CloseDownClient(killclient); if (client == killclient) { /* force yield and return Success, so that Dispatch() * doesn't try to touch client */ isItTimeToYield = TRUE; } return Success; } else return rc; } int ProcSetFontPath(ClientPtr client) { unsigned char *ptr; unsigned long nbytes, total; long nfonts; int n; REQUEST(xSetFontPathReq); REQUEST_AT_LEAST_SIZE(xSetFontPathReq); nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq); total = nbytes; ptr = (unsigned char *) &stuff[1]; nfonts = stuff->nFonts; while (--nfonts >= 0) { if ((total == 0) || (total < (n = (*ptr + 1)))) return BadLength; total -= n; ptr += n; } if (total >= 4) return BadLength; return SetFontPath(client, stuff->nFonts, (unsigned char *) &stuff[1]); } int ProcGetFontPath(ClientPtr client) { xGetFontPathReply reply; int rc, stringLens, numpaths; unsigned char *bufferStart; /* REQUEST (xReq); */ REQUEST_SIZE_MATCH(xReq); rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart); if (rc != Success) return rc; reply = (xGetFontPathReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = bytes_to_int32(stringLens + numpaths), .nPaths = numpaths }; WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); if (stringLens || numpaths) WriteToClient(client, stringLens + numpaths, bufferStart); return Success; } int ProcChangeCloseDownMode(ClientPtr client) { int rc; REQUEST(xSetCloseDownModeReq); REQUEST_SIZE_MATCH(xSetCloseDownModeReq); rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess); if (rc != Success) return rc; if ((stuff->mode == AllTemporary) || (stuff->mode == RetainPermanent) || (stuff->mode == RetainTemporary)) { client->closeDownMode = stuff->mode; return Success; } else { client->errorValue = stuff->mode; return BadValue; } } int ProcForceScreenSaver(ClientPtr client) { int rc; REQUEST(xForceScreenSaverReq); REQUEST_SIZE_MATCH(xForceScreenSaverReq); if ((stuff->mode != ScreenSaverReset) && (stuff->mode != ScreenSaverActive)) { client->errorValue = stuff->mode; return BadValue; } rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int) stuff->mode); if (rc != Success) return rc; return Success; } int ProcNoOperation(ClientPtr client) { REQUEST_AT_LEAST_SIZE(xReq); /* noop -- don't do anything */ return Success; } /********************** * CloseDownClient * * Client can either mark his resources destroy or retain. If retained and * then killed again, the client is really destroyed. *********************/ char dispatchExceptionAtReset = DE_RESET; void CloseDownClient(ClientPtr client) { Bool really_close_down = client->clientGone || client->closeDownMode == DestroyAll; if (!client->clientGone) { /* ungrab server if grabbing client dies */ if (grabState != GrabNone && grabClient == client) { UngrabServer(client); } BITCLEAR(grabWaiters, client->index); DeleteClientFromAnySelections(client); ReleaseActiveGrabs(client); DeleteClientFontStuff(client); if (!really_close_down) { /* This frees resources that should never be retained * no matter what the close down mode is. Actually we * could do this unconditionally, but it's probably * better not to traverse all the client's resources * twice (once here, once a few lines down in * FreeClientResources) in the common case of * really_close_down == TRUE. */ FreeClientNeverRetainResources(client); client->clientState = ClientStateRetained; if (ClientStateCallback) { NewClientInfoRec clientinfo; clientinfo.client = client; clientinfo.prefix = (xConnSetupPrefix *) NULL; clientinfo.setup = (xConnSetup *) NULL; CallCallbacks((&ClientStateCallback), (void *) &clientinfo); } } client->clientGone = TRUE; /* so events aren't sent to client */ if (ClientIsAsleep(client)) ClientSignal(client); ProcessWorkQueueZombies(); CloseDownConnection(client); output_pending_clear(client); mark_client_not_ready(client); /* If the client made it to the Running stage, nClients has * been incremented on its behalf, so we need to decrement it * now. If it hasn't gotten to Running, nClients has *not* * been incremented, so *don't* decrement it. */ if (client->clientState != ClientStateInitial) { --nClients; } } if (really_close_down) { if (client->clientState == ClientStateRunning && nClients == 0) dispatchException |= dispatchExceptionAtReset; client->clientState = ClientStateGone; if (ClientStateCallback) { NewClientInfoRec clientinfo; clientinfo.client = client; clientinfo.prefix = (xConnSetupPrefix *) NULL; clientinfo.setup = (xConnSetup *) NULL; CallCallbacks((&ClientStateCallback), (void *) &clientinfo); } TouchListenerGone(client->clientAsMask); FreeClientResources(client); /* Disable client ID tracking. This must be done after * ClientStateCallback. */ ReleaseClientIds(client); #ifdef XSERVER_DTRACE XSERVER_CLIENT_DISCONNECT(client->index); #endif if (client->index < nextFreeClientID) nextFreeClientID = client->index; clients[client->index] = NullClient; SmartLastClient = NullClient; dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); while (!clients[currentMaxClients - 1]) currentMaxClients--; } } static void KillAllClients(void) { int i; for (i = 1; i < currentMaxClients; i++) if (clients[i]) { /* Make sure Retained clients are released. */ clients[i]->closeDownMode = DestroyAll; CloseDownClient(clients[i]); } } void InitClient(ClientPtr client, int i, void *ospriv) { client->index = i; xorg_list_init(&client->ready); xorg_list_init(&client->output_pending); client->clientAsMask = ((Mask) i) << CLIENTOFFSET; client->closeDownMode = i ? DestroyAll : RetainPermanent; client->requestVector = InitialVector; client->osPrivate = ospriv; QueryMinMaxKeyCodes(&client->minKC, &client->maxKC); client->smart_start_tick = SmartScheduleTime; client->smart_stop_tick = SmartScheduleTime; client->clientIds = NULL; } /************************ * int NextAvailableClient(ospriv) * * OS dependent portion can't assign client id's because of CloseDownModes. * Returns NULL if there are no free clients. *************************/ ClientPtr NextAvailableClient(void *ospriv) { int i; ClientPtr client; xReq data; i = nextFreeClientID; if (i == LimitClients) return (ClientPtr) NULL; clients[i] = client = dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT); if (!client) return (ClientPtr) NULL; InitClient(client, i, ospriv); if (!InitClientResources(client)) { dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); return (ClientPtr) NULL; } data.reqType = 1; data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix); if (!InsertFakeRequest(client, (char *) &data, sz_xReq)) { FreeClientResources(client); dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); return (ClientPtr) NULL; } if (i == currentMaxClients) currentMaxClients++; while ((nextFreeClientID < LimitClients) && clients[nextFreeClientID]) nextFreeClientID++; /* Enable client ID tracking. This must be done before * ClientStateCallback. */ ReserveClientIds(client); if (ClientStateCallback) { NewClientInfoRec clientinfo; clientinfo.client = client; clientinfo.prefix = (xConnSetupPrefix *) NULL; clientinfo.setup = (xConnSetup *) NULL; CallCallbacks((&ClientStateCallback), (void *) &clientinfo); } return client; } int ProcInitialConnection(ClientPtr client) { REQUEST(xReq); xConnClientPrefix *prefix; int whichbyte = 1; char order; prefix = (xConnClientPrefix *) ((char *)stuff + sz_xReq); order = prefix->byteOrder; if (order != 'l' && order != 'B' && order != 'r' && order != 'R') return client->noClientException = -1; if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) || (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) { client->swapped = TRUE; SwapConnClientPrefix(prefix); } stuff->reqType = 2; stuff->length += bytes_to_int32(prefix->nbytesAuthProto) + bytes_to_int32(prefix->nbytesAuthString); if (client->swapped) { swaps(&stuff->length); } if (order == 'r' || order == 'R') { client->local = FALSE; } ResetCurrentRequest(client); return Success; } static int SendConnSetup(ClientPtr client, const char *reason) { xWindowRoot *root; int i; int numScreens; char *lConnectionInfo; xConnSetupPrefix *lconnSetupPrefix; if (reason) { xConnSetupPrefix csp; csp.success = xFalse; csp.lengthReason = strlen(reason); csp.length = bytes_to_int32(csp.lengthReason); csp.majorVersion = X_PROTOCOL; csp.minorVersion = X_PROTOCOL_REVISION; if (client->swapped) WriteSConnSetupPrefix(client, &csp); else WriteToClient(client, sz_xConnSetupPrefix, &csp); WriteToClient(client, (int) csp.lengthReason, reason); return client->noClientException = -1; } numScreens = screenInfo.numScreens; lConnectionInfo = ConnectionInfo; lconnSetupPrefix = &connSetupPrefix; /* We're about to start speaking X protocol back to the client by * sending the connection setup info. This means the authorization * step is complete, and we can count the client as an * authorized one. */ nClients++; client->requestVector = client->swapped ? SwappedProcVector : ProcVector; client->sequence = 0; ((xConnSetup *) lConnectionInfo)->ridBase = client->clientAsMask; ((xConnSetup *) lConnectionInfo)->ridMask = RESOURCE_ID_MASK; #ifdef MATCH_CLIENT_ENDIAN ((xConnSetup *) lConnectionInfo)->imageByteOrder = ClientOrder(client); ((xConnSetup *) lConnectionInfo)->bitmapBitOrder = ClientOrder(client); #endif /* fill in the "currentInputMask" */ root = (xWindowRoot *) (lConnectionInfo + connBlockScreenStart); #ifdef PANORAMIX if (noPanoramiXExtension) numScreens = screenInfo.numScreens; else numScreens = ((xConnSetup *) ConnectionInfo)->numRoots; #endif for (i = 0; i < numScreens; i++) { unsigned int j; xDepth *pDepth; WindowPtr pRoot = screenInfo.screens[i]->root; root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot); pDepth = (xDepth *) (root + 1); for (j = 0; j < root->nDepths; j++) { pDepth = (xDepth *) (((char *) (pDepth + 1)) + pDepth->nVisuals * sizeof(xVisualType)); } root = (xWindowRoot *) pDepth; } if (client->swapped) { WriteSConnSetupPrefix(client, lconnSetupPrefix); WriteSConnectionInfo(client, (unsigned long) (lconnSetupPrefix->length << 2), lConnectionInfo); } else { WriteToClient(client, sizeof(xConnSetupPrefix), lconnSetupPrefix); WriteToClient(client, (int) (lconnSetupPrefix->length << 2), lConnectionInfo); } client->clientState = ClientStateRunning; if (ClientStateCallback) { NewClientInfoRec clientinfo; clientinfo.client = client; clientinfo.prefix = lconnSetupPrefix; clientinfo.setup = (xConnSetup *) lConnectionInfo; CallCallbacks((&ClientStateCallback), (void *) &clientinfo); } return Success; } int ProcEstablishConnection(ClientPtr client) { const char *reason; char *auth_proto, *auth_string; xConnClientPrefix *prefix; REQUEST(xReq); prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq); auth_proto = (char *) prefix + sz_xConnClientPrefix; auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto); if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix + pad_to_int32(prefix->nbytesAuthProto) + pad_to_int32(prefix->nbytesAuthString)) reason = "Bad length"; else if ((prefix->majorVersion != X_PROTOCOL) || (prefix->minorVersion != X_PROTOCOL_REVISION)) reason = "Protocol version mismatch"; else reason = ClientAuthorized(client, (unsigned short) prefix->nbytesAuthProto, auth_proto, (unsigned short) prefix->nbytesAuthString, auth_string); return (SendConnSetup(client, reason)); } void SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, XID resId, int errorCode) { xError rep = { .type = X_Error, .errorCode = errorCode, .resourceID = resId, .minorCode = minorCode, .majorCode = majorCode }; WriteEventsToClient(client, 1, (xEvent *) &rep); } void MarkClientException(ClientPtr client) { client->noClientException = -1; } /* * This array encodes the answer to the question "what is the log base 2 * of the number of pixels that fit in a scanline pad unit?" * Note that ~0 is an invalid entry (mostly for the benefit of the reader). */ static int answer[6][4] = { /* pad pad pad pad */ /* 8 16 32 64 */ {3, 4, 5, 6}, /* 1 bit per pixel */ {1, 2, 3, 4}, /* 4 bits per pixel */ {0, 1, 2, 3}, /* 8 bits per pixel */ {~0, 0, 1, 2}, /* 16 bits per pixel */ {~0, ~0, 0, 1}, /* 24 bits per pixel */ {~0, ~0, 0, 1} /* 32 bits per pixel */ }; /* * This array gives the answer to the question "what is the first index for * the answer array above given the number of bits per pixel?" * Note that ~0 is an invalid entry (mostly for the benefit of the reader). */ static int indexForBitsPerPixel[33] = { ~0, 0, ~0, ~0, /* 1 bit per pixel */ 1, ~0, ~0, ~0, /* 4 bits per pixel */ 2, ~0, ~0, ~0, /* 8 bits per pixel */ ~0, ~0, ~0, ~0, 3, ~0, ~0, ~0, /* 16 bits per pixel */ ~0, ~0, ~0, ~0, 4, ~0, ~0, ~0, /* 24 bits per pixel */ ~0, ~0, ~0, ~0, 5 /* 32 bits per pixel */ }; /* * This array gives the bytesperPixel value for cases where the number * of bits per pixel is a multiple of 8 but not a power of 2. */ static int answerBytesPerPixel[33] = { ~0, 0, ~0, ~0, /* 1 bit per pixel */ 0, ~0, ~0, ~0, /* 4 bits per pixel */ 0, ~0, ~0, ~0, /* 8 bits per pixel */ ~0, ~0, ~0, ~0, 0, ~0, ~0, ~0, /* 16 bits per pixel */ ~0, ~0, ~0, ~0, 3, ~0, ~0, ~0, /* 24 bits per pixel */ ~0, ~0, ~0, ~0, 0 /* 32 bits per pixel */ }; /* * This array gives the answer to the question "what is the second index for * the answer array above given the number of bits per scanline pad unit?" * Note that ~0 is an invalid entry (mostly for the benefit of the reader). */ static int indexForScanlinePad[65] = { ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ ~0, ~0, ~0, ~0, 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 3 /* 64 bits per scanline pad unit */ }; /* grow the array of screenRecs if necessary. call the device-supplied initialization procedure with its screen number, a pointer to its ScreenRec, argc, and argv. return the number of successfully installed screens. */ static int init_screen(ScreenPtr pScreen, int i, Bool gpu) { int scanlinepad, format, depth, bitsPerPixel, j, k; dixInitScreenSpecificPrivates(pScreen); if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) { return -1; } pScreen->myNum = i; if (gpu) { pScreen->myNum += GPU_SCREEN_OFFSET; pScreen->isGPU = TRUE; } pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */ pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ pScreen->CreateScreenResources = 0; xorg_list_init(&pScreen->pixmap_dirty_list); xorg_list_init(&pScreen->slave_list); /* * This loop gets run once for every Screen that gets added, * but thats ok. If the ddx layer initializes the formats * one at a time calling AddScreen() after each, then each * iteration will make it a little more accurate. Worst case * we do this loop N * numPixmapFormats where N is # of screens. * Anyway, this must be called after InitOutput and before the * screen init routine is called. */ for (format = 0; format < screenInfo.numPixmapFormats; format++) { depth = screenInfo.formats[format].depth; bitsPerPixel = screenInfo.formats[format].bitsPerPixel; scanlinepad = screenInfo.formats[format].scanlinePad; j = indexForBitsPerPixel[bitsPerPixel]; k = indexForScanlinePad[scanlinepad]; PixmapWidthPaddingInfo[depth].padPixelsLog2 = answer[j][k]; PixmapWidthPaddingInfo[depth].padRoundUp = (scanlinepad / bitsPerPixel) - 1; j = indexForBitsPerPixel[8]; /* bits per byte */ PixmapWidthPaddingInfo[depth].padBytesLog2 = answer[j][k]; PixmapWidthPaddingInfo[depth].bitsPerPixel = bitsPerPixel; if (answerBytesPerPixel[bitsPerPixel]) { PixmapWidthPaddingInfo[depth].notPower2 = 1; PixmapWidthPaddingInfo[depth].bytesPerPixel = answerBytesPerPixel[bitsPerPixel]; } else { PixmapWidthPaddingInfo[depth].notPower2 = 0; } } return 0; } int AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , int /*argc */ , char ** /*argv */ ), int argc, char **argv) { int i; ScreenPtr pScreen; Bool ret; i = screenInfo.numScreens; if (i == MAXSCREENS) return -1; pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); if (!pScreen) return -1; ret = init_screen(pScreen, i, FALSE); if (ret != 0) { free(pScreen); return ret; } /* This is where screen specific stuff gets initialized. Load the screen structure, call the hardware, whatever. This is also where the default colormap should be allocated and also pixel values for blackPixel, whitePixel, and the cursor Note that InitScreen is NOT allowed to modify argc, argv, or any of the strings pointed to by argv. They may be passed to multiple screens. */ screenInfo.screens[i] = pScreen; screenInfo.numScreens++; if (!(*pfnInit) (pScreen, argc, argv)) { dixFreeScreenSpecificPrivates(pScreen); dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); free(pScreen); screenInfo.numScreens--; return -1; } update_desktop_dimensions(); dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR, 0); return i; } int AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , int /*argc */ , char ** /*argv */ ), int argc, char **argv) { int i; ScreenPtr pScreen; Bool ret; i = screenInfo.numGPUScreens; if (i == MAXGPUSCREENS) return -1; pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); if (!pScreen) return -1; ret = init_screen(pScreen, i, TRUE); if (ret != 0) { free(pScreen); return ret; } /* This is where screen specific stuff gets initialized. Load the screen structure, call the hardware, whatever. This is also where the default colormap should be allocated and also pixel values for blackPixel, whitePixel, and the cursor Note that InitScreen is NOT allowed to modify argc, argv, or any of the strings pointed to by argv. They may be passed to multiple screens. */ screenInfo.gpuscreens[i] = pScreen; screenInfo.numGPUScreens++; if (!(*pfnInit) (pScreen, argc, argv)) { dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); free(pScreen); screenInfo.numGPUScreens--; return -1; } update_desktop_dimensions(); /* * We cannot register the Screen PRIVATE_CURSOR key if cursors are already * created, because dix/privates.c does not have relocation code for * PRIVATE_CURSOR. Once this is fixed the if() can be removed and we can * register the Screen PRIVATE_CURSOR key unconditionally. */ if (!dixPrivatesCreated(PRIVATE_CURSOR)) dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR, 0); return i; } void RemoveGPUScreen(ScreenPtr pScreen) { int idx, j; if (!pScreen->isGPU) return; idx = pScreen->myNum - GPU_SCREEN_OFFSET; for (j = idx; j < screenInfo.numGPUScreens - 1; j++) { screenInfo.gpuscreens[j] = screenInfo.gpuscreens[j + 1]; screenInfo.gpuscreens[j]->myNum = j + GPU_SCREEN_OFFSET; } screenInfo.numGPUScreens--; /* this gets freed later in the resource list, but without * the screen existing it causes crashes - so remove it here */ if (pScreen->defColormap) FreeResource(pScreen->defColormap, RT_COLORMAP); free(pScreen); } void AttachUnboundGPU(ScreenPtr pScreen, ScreenPtr new) { assert(new->isGPU); assert(!new->current_master); xorg_list_add(&new->slave_head, &pScreen->slave_list); new->current_master = pScreen; } void DetachUnboundGPU(ScreenPtr slave) { assert(slave->isGPU); assert(!slave->is_output_slave); assert(!slave->is_offload_slave); xorg_list_del(&slave->slave_head); slave->current_master = NULL; } void AttachOutputGPU(ScreenPtr pScreen, ScreenPtr new) { assert(new->isGPU); assert(!new->is_output_slave); assert(new->current_master == pScreen); new->is_output_slave = TRUE; new->current_master->output_slaves++; } void DetachOutputGPU(ScreenPtr slave) { assert(slave->isGPU); assert(slave->is_output_slave); slave->current_master->output_slaves--; slave->is_output_slave = FALSE; } void AttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new) { assert(new->isGPU); assert(!new->is_offload_slave); assert(new->current_master == pScreen); new->is_offload_slave = TRUE; } void DetachOffloadGPU(ScreenPtr slave) { assert(slave->isGPU); assert(slave->is_offload_slave); slave->is_offload_slave = FALSE; } xorg-server-1.20.13/dix/dispatch.h0000644000175000017500000001467714100573755013644 00000000000000/************************************************************ Copyright 1996 by Thomas E. Dickey All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the above listed copyright holder(s) not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ********************************************************/ /* * This prototypes the dispatch.c module (except for functions declared in * global headers), plus related dispatch procedures from devices.c, events.c, * extension.c, property.c. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef DISPATCH_H #define DISPATCH_H 1 int ProcAllocColor(ClientPtr /* client */ ); int ProcAllocColorCells(ClientPtr /* client */ ); int ProcAllocColorPlanes(ClientPtr /* client */ ); int ProcAllocNamedColor(ClientPtr /* client */ ); int ProcBell(ClientPtr /* client */ ); int ProcChangeAccessControl(ClientPtr /* client */ ); int ProcChangeCloseDownMode(ClientPtr /* client */ ); int ProcChangeGC(ClientPtr /* client */ ); int ProcChangeHosts(ClientPtr /* client */ ); int ProcChangeKeyboardControl(ClientPtr /* client */ ); int ProcChangeKeyboardMapping(ClientPtr /* client */ ); int ProcChangePointerControl(ClientPtr /* client */ ); int ProcChangeProperty(ClientPtr /* client */ ); int ProcChangeSaveSet(ClientPtr /* client */ ); int ProcChangeWindowAttributes(ClientPtr /* client */ ); int ProcCirculateWindow(ClientPtr /* client */ ); int ProcClearToBackground(ClientPtr /* client */ ); int ProcCloseFont(ClientPtr /* client */ ); int ProcConfigureWindow(ClientPtr /* client */ ); int ProcConvertSelection(ClientPtr /* client */ ); int ProcCopyArea(ClientPtr /* client */ ); int ProcCopyColormapAndFree(ClientPtr /* client */ ); int ProcCopyGC(ClientPtr /* client */ ); int ProcCopyPlane(ClientPtr /* client */ ); int ProcCreateColormap(ClientPtr /* client */ ); int ProcCreateCursor(ClientPtr /* client */ ); int ProcCreateGC(ClientPtr /* client */ ); int ProcCreateGlyphCursor(ClientPtr /* client */ ); int ProcCreatePixmap(ClientPtr /* client */ ); int ProcCreateWindow(ClientPtr /* client */ ); int ProcDeleteProperty(ClientPtr /* client */ ); int ProcDestroySubwindows(ClientPtr /* client */ ); int ProcDestroyWindow(ClientPtr /* client */ ); int ProcEstablishConnection(ClientPtr /* client */ ); int ProcFillPoly(ClientPtr /* client */ ); int ProcForceScreenSaver(ClientPtr /* client */ ); int ProcFreeColormap(ClientPtr /* client */ ); int ProcFreeColors(ClientPtr /* client */ ); int ProcFreeCursor(ClientPtr /* client */ ); int ProcFreeGC(ClientPtr /* client */ ); int ProcFreePixmap(ClientPtr /* client */ ); int ProcGetAtomName(ClientPtr /* client */ ); int ProcGetFontPath(ClientPtr /* client */ ); int ProcGetGeometry(ClientPtr /* client */ ); int ProcGetImage(ClientPtr /* client */ ); int ProcGetKeyboardControl(ClientPtr /* client */ ); int ProcGetKeyboardMapping(ClientPtr /* client */ ); int ProcGetModifierMapping(ClientPtr /* client */ ); int ProcGetMotionEvents(ClientPtr /* client */ ); int ProcGetPointerControl(ClientPtr /* client */ ); int ProcGetPointerMapping(ClientPtr /* client */ ); int ProcGetProperty(ClientPtr /* client */ ); int ProcGetScreenSaver(ClientPtr /* client */ ); int ProcGetSelectionOwner(ClientPtr /* client */ ); int ProcGetWindowAttributes(ClientPtr /* client */ ); int ProcGrabServer(ClientPtr /* client */ ); int ProcImageText16(ClientPtr /* client */ ); int ProcImageText8(ClientPtr /* client */ ); int ProcInitialConnection(ClientPtr /* client */ ); int ProcInstallColormap(ClientPtr /* client */ ); int ProcInternAtom(ClientPtr /* client */ ); int ProcKillClient(ClientPtr /* client */ ); int ProcListExtensions(ClientPtr /* client */ ); int ProcListFonts(ClientPtr /* client */ ); int ProcListFontsWithInfo(ClientPtr /* client */ ); int ProcListHosts(ClientPtr /* client */ ); int ProcListInstalledColormaps(ClientPtr /* client */ ); int ProcListProperties(ClientPtr /* client */ ); int ProcLookupColor(ClientPtr /* client */ ); int ProcMapSubwindows(ClientPtr /* client */ ); int ProcMapWindow(ClientPtr /* client */ ); int ProcNoOperation(ClientPtr /* client */ ); int ProcOpenFont(ClientPtr /* client */ ); int ProcPolyArc(ClientPtr /* client */ ); int ProcPolyFillArc(ClientPtr /* client */ ); int ProcPolyFillRectangle(ClientPtr /* client */ ); int ProcPolyLine(ClientPtr /* client */ ); int ProcPolyPoint(ClientPtr /* client */ ); int ProcPolyRectangle(ClientPtr /* client */ ); int ProcPolySegment(ClientPtr /* client */ ); int ProcPolyText(ClientPtr /* client */ ); int ProcPutImage(ClientPtr /* client */ ); int ProcQueryBestSize(ClientPtr /* client */ ); int ProcQueryColors(ClientPtr /* client */ ); int ProcQueryExtension(ClientPtr /* client */ ); int ProcQueryFont(ClientPtr /* client */ ); int ProcQueryKeymap(ClientPtr /* client */ ); int ProcQueryTextExtents(ClientPtr /* client */ ); int ProcQueryTree(ClientPtr /* client */ ); int ProcReparentWindow(ClientPtr /* client */ ); int ProcRotateProperties(ClientPtr /* client */ ); int ProcSetClipRectangles(ClientPtr /* client */ ); int ProcSetDashes(ClientPtr /* client */ ); int ProcSetFontPath(ClientPtr /* client */ ); int ProcSetModifierMapping(ClientPtr /* client */ ); int ProcSetPointerMapping(ClientPtr /* client */ ); int ProcSetScreenSaver(ClientPtr /* client */ ); int ProcSetSelectionOwner(ClientPtr /* client */ ); int ProcStoreColors(ClientPtr /* client */ ); int ProcStoreNamedColor(ClientPtr /* client */ ); int ProcTranslateCoords(ClientPtr /* client */ ); int ProcUngrabServer(ClientPtr /* client */ ); int ProcUninstallColormap(ClientPtr /* client */ ); int ProcUnmapSubwindows(ClientPtr /* client */ ); int ProcUnmapWindow(ClientPtr /* client */ ); #endif /* DISPATCH_H */ xorg-server-1.20.13/dix/dixfonts.c0000644000175000017500000017721214100573755013671 00000000000000/************************************************************************ Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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. ************************************************************************/ /* The panoramix components contained the following notice */ /* Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Digital Equipment Corporation shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Digital Equipment Corporation. ******************************************************************/ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include "scrnintstr.h" #include "resource.h" #include "dixstruct.h" #include "cursorstr.h" #include "misc.h" #include "opaque.h" #include "dixfontstr.h" #include "closestr.h" #include "dixfont.h" #include "xace.h" #include #ifdef XF86BIGFONT #include "xf86bigfontsrv.h" #endif extern void *fosNaturalParams; extern FontPtr defaultFont; static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0; static int num_fpes = 0; static xfont2_fpe_funcs_rec const **fpe_functions; static int num_fpe_types = 0; static unsigned char *font_path_string; static int num_slept_fpes = 0; static int size_slept_fpes = 0; static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0; static xfont2_pattern_cache_ptr patternCache; static int FontToXError(int err) { switch (err) { case Successful: return Success; case AllocError: return BadAlloc; case BadFontName: return BadName; case BadFontPath: case BadFontFormat: /* is there something better? */ case BadCharRange: return BadValue; default: return err; } } static int LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data) { if (fpe_functions[pfont->fpe->type]->load_glyphs) return (*fpe_functions[pfont->fpe->type]->load_glyphs) (client, pfont, 0, nchars, item_size, data); else return Successful; } void GetGlyphs(FontPtr font, unsigned long count, unsigned char *chars, FontEncoding fontEncoding, unsigned long *glyphcount, /* RETURN */ CharInfoPtr *glyphs) /* RETURN */ { (*font->get_glyphs) (font, count, chars, fontEncoding, glyphcount, glyphs); } /* * adding RT_FONT prevents conflict with default cursor font */ Bool SetDefaultFont(const char *defaultfontname) { int err; FontPtr pf; XID fid; fid = FakeClientID(0); err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync, (unsigned) strlen(defaultfontname), defaultfontname); if (err != Success) return FALSE; err = dixLookupResourceByType((void **) &pf, fid, RT_FONT, serverClient, DixReadAccess); if (err != Success) return FALSE; defaultFont = pf; return TRUE; } /* * note that the font wakeup queue is not refcounted. this is because * an fpe needs to be added when it's inited, and removed when it's finally * freed, in order to handle any data that isn't requested, like FS events. * * since the only thing that should call these routines is the renderer's * init_fpe() and free_fpe(), there shouldn't be any problem in using * freed data. */ static void QueueFontWakeup(FontPathElementPtr fpe) { int i; FontPathElementPtr *new; for (i = 0; i < num_slept_fpes; i++) { if (slept_fpes[i] == fpe) { return; } } if (num_slept_fpes == size_slept_fpes) { new = reallocarray(slept_fpes, size_slept_fpes + 4, sizeof(FontPathElementPtr)); if (!new) return; slept_fpes = new; size_slept_fpes += 4; } slept_fpes[num_slept_fpes] = fpe; num_slept_fpes++; } static void RemoveFontWakeup(FontPathElementPtr fpe) { int i, j; for (i = 0; i < num_slept_fpes; i++) { if (slept_fpes[i] == fpe) { for (j = i; j < num_slept_fpes; j++) { slept_fpes[j] = slept_fpes[j + 1]; } num_slept_fpes--; return; } } } static void FontWakeup(void *data, int count) { int i; FontPathElementPtr fpe; if (count < 0) return; /* wake up any fpe's that may be waiting for information */ for (i = 0; i < num_slept_fpes; i++) { fpe = slept_fpes[i]; (void) (*fpe_functions[fpe->type]->wakeup_fpe) (fpe); } } /* XXX -- these two funcs may want to be broken into macros */ static void UseFPE(FontPathElementPtr fpe) { fpe->refcount++; } static void FreeFPE(FontPathElementPtr fpe) { fpe->refcount--; if (fpe->refcount == 0) { (*fpe_functions[fpe->type]->free_fpe) (fpe); free((void *) fpe->name); free(fpe); } } static Bool doOpenFont(ClientPtr client, OFclosurePtr c) { FontPtr pfont = NullFont; FontPathElementPtr fpe = NULL; ScreenPtr pScr; int err = Successful; int i; char *alias, *newname; int newlen; int aliascount = 20; /* * Decide at runtime what FontFormat to use. */ Mask FontFormat = ((screenInfo.imageByteOrder == LSBFirst) ? BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) | ((screenInfo.bitmapBitOrder == LSBFirst) ? BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) | BitmapFormatImageRectMin | #if GLYPHPADBYTES == 1 BitmapFormatScanlinePad8 | #endif #if GLYPHPADBYTES == 2 BitmapFormatScanlinePad16 | #endif #if GLYPHPADBYTES == 4 BitmapFormatScanlinePad32 | #endif #if GLYPHPADBYTES == 8 BitmapFormatScanlinePad64 | #endif BitmapFormatScanlineUnit8; if (client->clientGone) { if (c->current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current_fpe]; (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe); } err = Successful; goto bail; } while (c->current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current_fpe]; err = (*fpe_functions[fpe->type]->open_font) ((void *) client, fpe, c->flags, c->fontname, c->fnamelen, FontFormat, BitmapFormatMaskByte | BitmapFormatMaskBit | BitmapFormatMaskImageRectangle | BitmapFormatMaskScanLinePad | BitmapFormatMaskScanLineUnit, c->fontid, &pfont, &alias, c->non_cachable_font && c->non_cachable_font->fpe == fpe ? c->non_cachable_font : (FontPtr) 0); if (err == FontNameAlias && alias) { newlen = strlen(alias); newname = (char *) realloc((char *) c->fontname, newlen); if (!newname) { err = AllocError; break; } memmove(newname, alias, newlen); c->fontname = newname; c->fnamelen = newlen; c->current_fpe = 0; if (--aliascount <= 0) { /* We've tried resolving this alias 20 times, we're * probably stuck in an infinite loop of aliases pointing * to each other - time to take emergency exit! */ err = BadImplementation; break; } continue; } if (err == BadFontName) { c->current_fpe++; continue; } if (err == Suspended) { if (!ClientIsAsleep(client)) ClientSleep(client, (ClientSleepProcPtr) doOpenFont, c); return TRUE; } break; } if (err != Successful) goto bail; if (!pfont) { err = BadFontName; goto bail; } /* check values for firstCol, lastCol, firstRow, and lastRow */ if (pfont->info.firstCol > pfont->info.lastCol || pfont->info.firstRow > pfont->info.lastRow || pfont->info.lastCol - pfont->info.firstCol > 255) { err = AllocError; goto bail; } if (!pfont->fpe) pfont->fpe = fpe; pfont->refcnt++; if (pfont->refcnt == 1) { UseFPE(pfont->fpe); for (i = 0; i < screenInfo.numScreens; i++) { pScr = screenInfo.screens[i]; if (pScr->RealizeFont) { if (!(*pScr->RealizeFont) (pScr, pfont)) { CloseFont(pfont, (Font) 0); err = AllocError; goto bail; } } } } if (!AddResource(c->fontid, RT_FONT, (void *) pfont)) { err = AllocError; goto bail; } if (patternCache && pfont != c->non_cachable_font) xfont2_cache_font_pattern(patternCache, c->origFontName, c->origFontNameLen, pfont); bail: if (err != Successful && c->client != serverClient) { SendErrorToClient(c->client, X_OpenFont, 0, c->fontid, FontToXError(err)); } ClientWakeup(c->client); for (i = 0; i < c->num_fpes; i++) { FreeFPE(c->fpe_list[i]); } free(c->fpe_list); free((void *) c->fontname); free(c); return TRUE; } int OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, const char *pfontname) { OFclosurePtr c; int i; FontPtr cached = (FontPtr) 0; if (!lenfname || lenfname > XLFDMAXFONTNAMELEN) return BadName; if (patternCache) { /* ** Check name cache. If we find a cached version of this font that ** is cachable, immediately satisfy the request with it. If we find ** a cached version of this font that is non-cachable, we do not ** satisfy the request with it. Instead, we pass the FontPtr to the ** FPE's open_font code (the fontfile FPE in turn passes the ** information to the rasterizer; the fserve FPE ignores it). ** ** Presumably, the font is marked non-cachable because the FPE has ** put some licensing restrictions on it. If the FPE, using ** whatever logic it relies on, determines that it is willing to ** share this existing font with the client, then it has the option ** to return the FontPtr we passed it as the newly-opened font. ** This allows the FPE to exercise its licensing logic without ** having to create another instance of a font that already exists. */ cached = xfont2_find_cached_font_pattern(patternCache, pfontname, lenfname); if (cached && cached->info.cachable) { if (!AddResource(fid, RT_FONT, (void *) cached)) return BadAlloc; cached->refcnt++; return Success; } } c = malloc(sizeof(OFclosureRec)); if (!c) return BadAlloc; c->fontname = malloc(lenfname); c->origFontName = pfontname; c->origFontNameLen = lenfname; if (!c->fontname) { free(c); return BadAlloc; } /* * copy the current FPE list, so that if it gets changed by another client * while we're blocking, the request still appears atomic */ c->fpe_list = xallocarray(num_fpes, sizeof(FontPathElementPtr)); if (!c->fpe_list) { free((void *) c->fontname); free(c); return BadAlloc; } memmove(c->fontname, pfontname, lenfname); for (i = 0; i < num_fpes; i++) { c->fpe_list[i] = font_path_elements[i]; UseFPE(c->fpe_list[i]); } c->client = client; c->fontid = fid; c->current_fpe = 0; c->num_fpes = num_fpes; c->fnamelen = lenfname; c->flags = flags; c->non_cachable_font = cached; (void) doOpenFont(client, c); return Success; } /** * Decrement font's ref count, and free storage if ref count equals zero * * \param value must conform to DeleteType */ int CloseFont(void *value, XID fid) { int nscr; ScreenPtr pscr; FontPathElementPtr fpe; FontPtr pfont = (FontPtr) value; if (pfont == NullFont) return Success; if (--pfont->refcnt == 0) { if (patternCache) xfont2_remove_cached_font_pattern(patternCache, pfont); /* * since the last reference is gone, ask each screen to free any * storage it may have allocated locally for it. */ for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { pscr = screenInfo.screens[nscr]; if (pscr->UnrealizeFont) (*pscr->UnrealizeFont) (pscr, pfont); } if (pfont == defaultFont) defaultFont = NULL; #ifdef XF86BIGFONT XF86BigfontFreeFontShm(pfont); #endif fpe = pfont->fpe; (*fpe_functions[fpe->type]->close_font) (fpe, pfont); FreeFPE(fpe); } return Success; } /***====================================================================***/ /** * Sets up pReply as the correct QueryFontReply for pFont with the first * nProtoCCIStructs char infos. * * \param pReply caller must allocate this storage */ void QueryFont(FontPtr pFont, xQueryFontReply * pReply, int nProtoCCIStructs) { FontPropPtr pFP; int r, c, i; xFontProp *prFP; xCharInfo *prCI; xCharInfo *charInfos[256]; unsigned char chars[512]; int ninfos; unsigned long ncols; unsigned long count; /* pr->length set in dispatch */ pReply->minCharOrByte2 = pFont->info.firstCol; pReply->defaultChar = pFont->info.defaultCh; pReply->maxCharOrByte2 = pFont->info.lastCol; pReply->drawDirection = pFont->info.drawDirection; pReply->allCharsExist = pFont->info.allExist; pReply->minByte1 = pFont->info.firstRow; pReply->maxByte1 = pFont->info.lastRow; pReply->fontAscent = pFont->info.fontAscent; pReply->fontDescent = pFont->info.fontDescent; pReply->minBounds = pFont->info.ink_minbounds; pReply->maxBounds = pFont->info.ink_maxbounds; pReply->nFontProps = pFont->info.nprops; pReply->nCharInfos = nProtoCCIStructs; for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]); i < pFont->info.nprops; i++, pFP++, prFP++) { prFP->name = pFP->name; prFP->value = pFP->value; } ninfos = 0; ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1); prCI = (xCharInfo *) (prFP); for (r = pFont->info.firstRow; ninfos < nProtoCCIStructs && r <= (int) pFont->info.lastRow; r++) { i = 0; for (c = pFont->info.firstCol; c <= (int) pFont->info.lastCol; c++) { chars[i++] = r; chars[i++] = c; } (*pFont->get_metrics) (pFont, ncols, chars, TwoD16Bit, &count, charInfos); i = 0; for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) { *prCI = *charInfos[i]; prCI++; ninfos++; } } return; } static Bool doListFontsAndAliases(ClientPtr client, LFclosurePtr c) { FontPathElementPtr fpe; int err = Successful; FontNamesPtr names = NULL; char *name, *resolved = NULL; int namelen, resolvedlen; int nnames; int stringLens; int i; xListFontsReply reply; char *bufptr; char *bufferStart; int aliascount = 0; if (client->clientGone) { if (c->current.current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current.current_fpe]; (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe); } err = Successful; goto bail; } if (!c->current.patlen) goto finish; while (c->current.current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current.current_fpe]; err = Successful; if (!fpe_functions[fpe->type]->start_list_fonts_and_aliases) { /* This FPE doesn't support/require list_fonts_and_aliases */ err = (*fpe_functions[fpe->type]->list_fonts) ((void *) c->client, fpe, c->current.pattern, c->current.patlen, c->current.max_names - c->names->nnames, c->names); if (err == Suspended) { if (!ClientIsAsleep(client)) ClientSleep(client, (ClientSleepProcPtr) doListFontsAndAliases, c); return TRUE; } err = BadFontName; } else { /* Start of list_fonts_and_aliases functionality. Modeled after list_fonts_with_info in that it resolves aliases, except that the information collected from FPEs is just names, not font info. Each list_next_font_or_alias() returns either a name into name/namelen or an alias into name/namelen and its target name into resolved/resolvedlen. The code at this level then resolves the alias by polling the FPEs. */ if (!c->current.list_started) { err = (*fpe_functions[fpe->type]->start_list_fonts_and_aliases) ((void *) c->client, fpe, c->current.pattern, c->current.patlen, c->current.max_names - c->names->nnames, &c->current.private); if (err == Suspended) { if (!ClientIsAsleep(client)) ClientSleep(client, (ClientSleepProcPtr) doListFontsAndAliases, c); return TRUE; } if (err == Successful) c->current.list_started = TRUE; } if (err == Successful) { char *tmpname; name = 0; err = (*fpe_functions[fpe->type]->list_next_font_or_alias) ((void *) c->client, fpe, &name, &namelen, &tmpname, &resolvedlen, c->current.private); if (err == Suspended) { if (!ClientIsAsleep(client)) ClientSleep(client, (ClientSleepProcPtr) doListFontsAndAliases, c); return TRUE; } if (err == FontNameAlias) { free(resolved); resolved = malloc(resolvedlen + 1); if (resolved) memmove(resolved, tmpname, resolvedlen + 1); } } if (err == Successful) { if (c->haveSaved) { if (c->savedName) (void) xfont2_add_font_names_name(c->names, c->savedName, c->savedNameLen); } else (void) xfont2_add_font_names_name(c->names, name, namelen); } /* * When we get an alias back, save our state and reset back to * the start of the FPE looking for the specified name. As * soon as a real font is found for the alias, pop back to the * old state */ else if (err == FontNameAlias) { char tmp_pattern[XLFDMAXFONTNAMELEN]; /* * when an alias recurses, we need to give * the last FPE a chance to clean up; so we call * it again, and assume that the error returned * is BadFontName, indicating the alias resolution * is complete. */ memmove(tmp_pattern, resolved, resolvedlen); if (c->haveSaved) { char *tmpname; int tmpnamelen; tmpname = 0; (void) (*fpe_functions[fpe->type]->list_next_font_or_alias) ((void *) c->client, fpe, &tmpname, &tmpnamelen, &tmpname, &tmpnamelen, c->current.private); if (--aliascount <= 0) { err = BadFontName; goto ContBadFontName; } } else { c->saved = c->current; c->haveSaved = TRUE; free(c->savedName); c->savedName = malloc(namelen + 1); if (c->savedName) memmove(c->savedName, name, namelen + 1); c->savedNameLen = namelen; aliascount = 20; } memmove(c->current.pattern, tmp_pattern, resolvedlen); c->current.patlen = resolvedlen; c->current.max_names = c->names->nnames + 1; c->current.current_fpe = -1; c->current.private = 0; err = BadFontName; } } /* * At the end of this FPE, step to the next. If we've finished * processing an alias, pop state back. If we've collected enough * font names, quit. */ if (err == BadFontName) { ContBadFontName:; c->current.list_started = FALSE; c->current.current_fpe++; err = Successful; if (c->haveSaved) { if (c->names->nnames == c->current.max_names || c->current.current_fpe == c->num_fpes) { c->haveSaved = FALSE; c->current = c->saved; /* Give the saved namelist a chance to clean itself up */ continue; } } if (c->names->nnames == c->current.max_names) break; } } /* * send the reply */ if (err != Successful) { SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err)); goto bail; } finish: names = c->names; nnames = names->nnames; client = c->client; stringLens = 0; for (i = 0; i < nnames; i++) stringLens += (names->length[i] <= 255) ? names->length[i] : 0; reply = (xListFontsReply) { .type = X_Reply, .length = bytes_to_int32(stringLens + nnames), .nFonts = nnames, .sequenceNumber = client->sequence }; bufptr = bufferStart = malloc(reply.length << 2); if (!bufptr && reply.length) { SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc); goto bail; } /* * since WriteToClient long word aligns things, copy to temp buffer and * write all at once */ for (i = 0; i < nnames; i++) { if (names->length[i] > 255) reply.nFonts--; else { *bufptr++ = names->length[i]; memmove(bufptr, names->names[i], names->length[i]); bufptr += names->length[i]; } } nnames = reply.nFonts; reply.length = bytes_to_int32(stringLens + nnames); client->pSwapReplyFunc = ReplySwapVector[X_ListFonts]; WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply); WriteToClient(client, stringLens + nnames, bufferStart); free(bufferStart); bail: ClientWakeup(client); for (i = 0; i < c->num_fpes; i++) FreeFPE(c->fpe_list[i]); free(c->fpe_list); free(c->savedName); xfont2_free_font_names(names); free(c); free(resolved); return TRUE; } int ListFonts(ClientPtr client, unsigned char *pattern, unsigned length, unsigned max_names) { int i; LFclosurePtr c; /* * The right error to return here would be BadName, however the * specification does not allow for a Name error on this request. * Perhaps a better solution would be to return a nil list, i.e. * a list containing zero fontnames. */ if (length > XLFDMAXFONTNAMELEN) return BadAlloc; i = XaceHook(XACE_SERVER_ACCESS, client, DixGetAttrAccess); if (i != Success) return i; if (!(c = malloc(sizeof *c))) return BadAlloc; c->fpe_list = xallocarray(num_fpes, sizeof(FontPathElementPtr)); if (!c->fpe_list) { free(c); return BadAlloc; } c->names = xfont2_make_font_names_record(max_names < 100 ? max_names : 100); if (!c->names) { free(c->fpe_list); free(c); return BadAlloc; } memmove(c->current.pattern, pattern, length); for (i = 0; i < num_fpes; i++) { c->fpe_list[i] = font_path_elements[i]; UseFPE(c->fpe_list[i]); } c->client = client; c->num_fpes = num_fpes; c->current.patlen = length; c->current.current_fpe = 0; c->current.max_names = max_names; c->current.list_started = FALSE; c->current.private = 0; c->haveSaved = FALSE; c->savedName = 0; doListFontsAndAliases(client, c); return Success; } static int doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) { FontPathElementPtr fpe; int err = Successful; char *name; int namelen; int numFonts; FontInfoRec fontInfo, *pFontInfo; xListFontsWithInfoReply *reply; int length; xFontProp *pFP; int i; int aliascount = 0; xListFontsWithInfoReply finalReply; if (client->clientGone) { if (c->current.current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current.current_fpe]; (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe); } err = Successful; goto bail; } client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo]; if (!c->current.patlen) goto finish; while (c->current.current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current.current_fpe]; err = Successful; if (!c->current.list_started) { err = (*fpe_functions[fpe->type]->start_list_fonts_with_info) (client, fpe, c->current.pattern, c->current.patlen, c->current.max_names, &c->current.private); if (err == Suspended) { if (!ClientIsAsleep(client)) ClientSleep(client, (ClientSleepProcPtr) doListFontsWithInfo, c); return TRUE; } if (err == Successful) c->current.list_started = TRUE; } if (err == Successful) { name = 0; pFontInfo = &fontInfo; err = (*fpe_functions[fpe->type]->list_next_font_with_info) (client, fpe, &name, &namelen, &pFontInfo, &numFonts, c->current.private); if (err == Suspended) { if (!ClientIsAsleep(client)) ClientSleep(client, (ClientSleepProcPtr) doListFontsWithInfo, c); return TRUE; } } /* * When we get an alias back, save our state and reset back to the * start of the FPE looking for the specified name. As soon as a real * font is found for the alias, pop back to the old state */ if (err == FontNameAlias) { /* * when an alias recurses, we need to give * the last FPE a chance to clean up; so we call * it again, and assume that the error returned * is BadFontName, indicating the alias resolution * is complete. */ if (c->haveSaved) { char *tmpname; int tmpnamelen; FontInfoPtr tmpFontInfo; tmpname = 0; tmpFontInfo = &fontInfo; (void) (*fpe_functions[fpe->type]->list_next_font_with_info) (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo, &numFonts, c->current.private); if (--aliascount <= 0) { err = BadFontName; goto ContBadFontName; } } else { c->saved = c->current; c->haveSaved = TRUE; c->savedNumFonts = numFonts; free(c->savedName); c->savedName = malloc(namelen + 1); if (c->savedName) memmove(c->savedName, name, namelen + 1); aliascount = 20; } memmove(c->current.pattern, name, namelen); c->current.patlen = namelen; c->current.max_names = 1; c->current.current_fpe = 0; c->current.private = 0; c->current.list_started = FALSE; } /* * At the end of this FPE, step to the next. If we've finished * processing an alias, pop state back. If we've sent enough font * names, quit. Always wait for BadFontName to let the FPE * have a chance to clean up. */ else if (err == BadFontName) { ContBadFontName:; c->current.list_started = FALSE; c->current.current_fpe++; err = Successful; if (c->haveSaved) { if (c->current.max_names == 0 || c->current.current_fpe == c->num_fpes) { c->haveSaved = FALSE; c->saved.max_names -= (1 - c->current.max_names); c->current = c->saved; } } else if (c->current.max_names == 0) break; } else if (err == Successful) { length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp); reply = c->reply; if (c->length < length) { reply = (xListFontsWithInfoReply *) realloc(c->reply, length); if (!reply) { err = AllocError; break; } memset((char *) reply + c->length, 0, length - c->length); c->reply = reply; c->length = length; } if (c->haveSaved) { numFonts = c->savedNumFonts; name = c->savedName; namelen = strlen(name); } reply->type = X_Reply; reply->length = bytes_to_int32(sizeof *reply - sizeof(xGenericReply) + pFontInfo->nprops * sizeof(xFontProp) + namelen); reply->sequenceNumber = client->sequence; reply->nameLength = namelen; reply->minBounds = pFontInfo->ink_minbounds; reply->maxBounds = pFontInfo->ink_maxbounds; reply->minCharOrByte2 = pFontInfo->firstCol; reply->maxCharOrByte2 = pFontInfo->lastCol; reply->defaultChar = pFontInfo->defaultCh; reply->nFontProps = pFontInfo->nprops; reply->drawDirection = pFontInfo->drawDirection; reply->minByte1 = pFontInfo->firstRow; reply->maxByte1 = pFontInfo->lastRow; reply->allCharsExist = pFontInfo->allExist; reply->fontAscent = pFontInfo->fontAscent; reply->fontDescent = pFontInfo->fontDescent; reply->nReplies = numFonts; pFP = (xFontProp *) (reply + 1); for (i = 0; i < pFontInfo->nprops; i++) { pFP->name = pFontInfo->props[i].name; pFP->value = pFontInfo->props[i].value; pFP++; } WriteSwappedDataToClient(client, length, reply); WriteToClient(client, namelen, name); if (pFontInfo == &fontInfo) { free(fontInfo.props); free(fontInfo.isStringProp); } --c->current.max_names; } } finish: length = sizeof(xListFontsWithInfoReply); finalReply = (xListFontsWithInfoReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = bytes_to_int32(sizeof(xListFontsWithInfoReply) - sizeof(xGenericReply)) }; WriteSwappedDataToClient(client, length, &finalReply); bail: ClientWakeup(client); for (i = 0; i < c->num_fpes; i++) FreeFPE(c->fpe_list[i]); free(c->reply); free(c->fpe_list); free(c->savedName); free(c); return TRUE; } int StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern, int max_names) { int i; LFWIclosurePtr c; /* * The right error to return here would be BadName, however the * specification does not allow for a Name error on this request. * Perhaps a better solution would be to return a nil list, i.e. * a list containing zero fontnames. */ if (length > XLFDMAXFONTNAMELEN) return BadAlloc; i = XaceHook(XACE_SERVER_ACCESS, client, DixGetAttrAccess); if (i != Success) return i; if (!(c = malloc(sizeof *c))) goto badAlloc; c->fpe_list = xallocarray(num_fpes, sizeof(FontPathElementPtr)); if (!c->fpe_list) { free(c); goto badAlloc; } memmove(c->current.pattern, pattern, length); for (i = 0; i < num_fpes; i++) { c->fpe_list[i] = font_path_elements[i]; UseFPE(c->fpe_list[i]); } c->client = client; c->num_fpes = num_fpes; c->reply = 0; c->length = 0; c->current.patlen = length; c->current.current_fpe = 0; c->current.max_names = max_names; c->current.list_started = FALSE; c->current.private = 0; c->savedNumFonts = 0; c->haveSaved = FALSE; c->savedName = 0; doListFontsWithInfo(client, c); return Success; badAlloc: return BadAlloc; } #define TextEltHeader 2 #define FontShiftSize 5 static ChangeGCVal clearGC[] = { {.ptr = NullPixmap} }; #define clearGCmask (GCClipMask) static int doPolyText(ClientPtr client, PTclosurePtr c) { FontPtr pFont = c->pGC->font, oldpFont; int err = Success, lgerr; /* err is in X error, not font error, space */ enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT; FontPathElementPtr fpe; GC *origGC = NULL; int itemSize = c->reqType == X_PolyText8 ? 1 : 2; if (client->clientGone) { fpe = c->pGC->font->fpe; (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe); if (ClientIsAsleep(client)) { /* Client has died, but we cannot bail out right now. We need to clean up after the work we did when going to sleep. Setting the drawable poiner to 0 makes this happen without any attempts to render or perform other unnecessary activities. */ c->pDraw = (DrawablePtr) 0; } else { err = Success; goto bail; } } /* Make sure our drawable hasn't disappeared while we slept. */ if (ClientIsAsleep(client) && c->pDraw) { DrawablePtr pDraw; dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess); if (c->pDraw != pDraw) { /* Our drawable has disappeared. Treat like client died... ask the FPE code to clean up after client and avoid further rendering while we clean up after ourself. */ fpe = c->pGC->font->fpe; (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe); c->pDraw = (DrawablePtr) 0; } } client_state = ClientIsAsleep(client) ? SLEEPING : NEVER_SLEPT; while (c->endReq - c->pElt > TextEltHeader) { if (*c->pElt == FontChange) { Font fid; if (c->endReq - c->pElt < FontShiftSize) { err = BadLength; goto bail; } oldpFont = pFont; fid = ((Font) *(c->pElt + 4)) /* big-endian */ |((Font) *(c->pElt + 3)) << 8 | ((Font) *(c->pElt + 2)) << 16 | ((Font) *(c->pElt + 1)) << 24; err = dixLookupResourceByType((void **) &pFont, fid, RT_FONT, client, DixUseAccess); if (err != Success) { /* restore pFont for step 4 (described below) */ pFont = oldpFont; /* If we're in START_SLEEP mode, the following step shortens the request... in the unlikely event that the fid somehow becomes valid before we come through again to actually execute the polytext, which would then mess up our refcounting scheme badly. */ c->err = err; c->endReq = c->pElt; goto bail; } /* Step 3 (described below) on our new font */ if (client_state == START_SLEEP) pFont->refcnt++; else { if (pFont != c->pGC->font && c->pDraw) { ChangeGCVal val; val.ptr = pFont; ChangeGC(NullClient, c->pGC, GCFont, &val); ValidateGC(c->pDraw, c->pGC); } /* Undo the refcnt++ we performed when going to sleep */ if (client_state == SLEEPING) (void) CloseFont(c->pGC->font, (Font) 0); } c->pElt += FontShiftSize; } else { /* print a string */ unsigned char *pNextElt; pNextElt = c->pElt + TextEltHeader + (*c->pElt) * itemSize; if (pNextElt > c->endReq) { err = BadLength; goto bail; } if (client_state == START_SLEEP) { c->pElt = pNextElt; continue; } if (c->pDraw) { lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, itemSize, c->pElt + TextEltHeader); } else lgerr = Successful; if (lgerr == Suspended) { if (!ClientIsAsleep(client)) { int len; GC *pGC; PTclosurePtr new_closure; /* We're putting the client to sleep. We need to do a few things to ensure successful and atomic-appearing execution of the remainder of the request. First, copy the remainder of the request into a safe malloc'd area. Second, create a scratch GC to use for the remainder of the request. Third, mark all fonts referenced in the remainder of the request to prevent their deallocation. Fourth, make the original GC look like the request has completed... set its font to the final font value from this request. These GC manipulations are for the unlikely (but possible) event that some other client is using the GC. Steps 3 and 4 are performed by running this procedure through the remainder of the request in a special no-render mode indicated by client_state = START_SLEEP. */ /* Step 1 */ /* Allocate a malloc'd closure structure to replace the local one we were passed */ new_closure = malloc(sizeof(PTclosureRec)); if (!new_closure) { err = BadAlloc; goto bail; } *new_closure = *c; len = new_closure->endReq - new_closure->pElt; new_closure->data = malloc(len); if (!new_closure->data) { free(new_closure); err = BadAlloc; goto bail; } memmove(new_closure->data, new_closure->pElt, len); new_closure->pElt = new_closure->data; new_closure->endReq = new_closure->pElt + len; /* Step 2 */ pGC = GetScratchGC(new_closure->pGC->depth, new_closure->pGC->pScreen); if (!pGC) { free(new_closure->data); free(new_closure); err = BadAlloc; goto bail; } if ((err = CopyGC(new_closure->pGC, pGC, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCFillStyle | GCTile | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin | GCFont | GCSubwindowMode | GCClipXOrigin | GCClipYOrigin | GCClipMask)) != Success) { FreeScratchGC(pGC); free(new_closure->data); free(new_closure); err = BadAlloc; goto bail; } c = new_closure; origGC = c->pGC; c->pGC = pGC; ValidateGC(c->pDraw, c->pGC); ClientSleep(client, (ClientSleepProcPtr) doPolyText, c); /* Set up to perform steps 3 and 4 */ client_state = START_SLEEP; continue; /* on to steps 3 and 4 */ } return TRUE; } else if (lgerr != Successful) { err = FontToXError(lgerr); goto bail; } if (c->pDraw) { c->xorg += *((INT8 *) (c->pElt + 1)); /* must be signed */ if (c->reqType == X_PolyText8) c->xorg = (*c->pGC->ops->PolyText8) (c->pDraw, c->pGC, c->xorg, c->yorg, *c->pElt, (char *) (c->pElt + TextEltHeader)); else c->xorg = (*c->pGC->ops->PolyText16) (c->pDraw, c->pGC, c->xorg, c->yorg, *c->pElt, (unsigned short *) (c-> pElt + TextEltHeader)); } c->pElt = pNextElt; } } bail: if (client_state == START_SLEEP) { /* Step 4 */ if (pFont != origGC->font) { ChangeGCVal val; val.ptr = pFont; ChangeGC(NullClient, origGC, GCFont, &val); ValidateGC(c->pDraw, origGC); } /* restore pElt pointer for execution of remainder of the request */ c->pElt = c->data; return TRUE; } if (c->err != Success) err = c->err; if (err != Success && c->client != serverClient) { #ifdef PANORAMIX if (noPanoramiXExtension || !c->pGC->pScreen->myNum) #endif SendErrorToClient(c->client, c->reqType, 0, 0, err); } if (ClientIsAsleep(client)) { ClientWakeup(c->client); ChangeGC(NullClient, c->pGC, clearGCmask, clearGC); /* Unreference the font from the scratch GC */ CloseFont(c->pGC->font, (Font) 0); c->pGC->font = NullFont; FreeScratchGC(c->pGC); free(c->data); free(c); } return TRUE; } int PolyText(ClientPtr client, DrawablePtr pDraw, GC * pGC, unsigned char *pElt, unsigned char *endReq, int xorg, int yorg, int reqType, XID did) { PTclosureRec local_closure; local_closure.pElt = pElt; local_closure.endReq = endReq; local_closure.client = client; local_closure.pDraw = pDraw; local_closure.xorg = xorg; local_closure.yorg = yorg; local_closure.reqType = reqType; local_closure.pGC = pGC; local_closure.did = did; local_closure.err = Success; (void) doPolyText(client, &local_closure); return Success; } #undef TextEltHeader #undef FontShiftSize static int doImageText(ClientPtr client, ITclosurePtr c) { int err = Success, lgerr; /* err is in X error, not font error, space */ FontPathElementPtr fpe; int itemSize = c->reqType == X_ImageText8 ? 1 : 2; if (client->clientGone) { fpe = c->pGC->font->fpe; (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe); err = Success; goto bail; } /* Make sure our drawable hasn't disappeared while we slept. */ if (ClientIsAsleep(client) && c->pDraw) { DrawablePtr pDraw; dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess); if (c->pDraw != pDraw) { /* Our drawable has disappeared. Treat like client died... ask the FPE code to clean up after client. */ fpe = c->pGC->font->fpe; (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe); err = Success; goto bail; } } lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, itemSize, c->data); if (lgerr == Suspended) { if (!ClientIsAsleep(client)) { GC *pGC; unsigned char *data; ITclosurePtr new_closure; ITclosurePtr old_closure; /* We're putting the client to sleep. We need to save some state. Similar problem to that handled in doPolyText, but much simpler because the request structure is much simpler. */ new_closure = malloc(sizeof(ITclosureRec)); if (!new_closure) { err = BadAlloc; goto bail; } old_closure = c; *new_closure = *c; c = new_closure; data = xallocarray(c->nChars, itemSize); if (!data) { free(c); c = old_closure; err = BadAlloc; goto bail; } memmove(data, c->data, c->nChars * itemSize); c->data = data; pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen); if (!pGC) { free(c->data); free(c); c = old_closure; err = BadAlloc; goto bail; } if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCFillStyle | GCTile | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin | GCFont | GCSubwindowMode | GCClipXOrigin | GCClipYOrigin | GCClipMask)) != Success) { FreeScratchGC(pGC); free(c->data); free(c); c = old_closure; err = BadAlloc; goto bail; } c->pGC = pGC; ValidateGC(c->pDraw, c->pGC); ClientSleep(client, (ClientSleepProcPtr) doImageText, c); } return TRUE; } else if (lgerr != Successful) { err = FontToXError(lgerr); goto bail; } if (c->pDraw) { if (c->reqType == X_ImageText8) (*c->pGC->ops->ImageText8) (c->pDraw, c->pGC, c->xorg, c->yorg, c->nChars, (char *) c->data); else (*c->pGC->ops->ImageText16) (c->pDraw, c->pGC, c->xorg, c->yorg, c->nChars, (unsigned short *) c->data); } bail: if (err != Success && c->client != serverClient) { SendErrorToClient(c->client, c->reqType, 0, 0, err); } if (ClientIsAsleep(client)) { ClientWakeup(c->client); ChangeGC(NullClient, c->pGC, clearGCmask, clearGC); /* Unreference the font from the scratch GC */ CloseFont(c->pGC->font, (Font) 0); c->pGC->font = NullFont; FreeScratchGC(c->pGC); free(c->data); free(c); } return TRUE; } int ImageText(ClientPtr client, DrawablePtr pDraw, GC * pGC, int nChars, unsigned char *data, int xorg, int yorg, int reqType, XID did) { ITclosureRec local_closure; local_closure.client = client; local_closure.pDraw = pDraw; local_closure.pGC = pGC; local_closure.nChars = nChars; local_closure.data = data; local_closure.xorg = xorg; local_closure.yorg = yorg; local_closure.reqType = reqType; local_closure.did = did; (void) doImageText(client, &local_closure); return Success; } /* does the necessary magic to figure out the fpe type */ static int DetermineFPEType(const char *pathname) { int i; for (i = 0; i < num_fpe_types; i++) { if ((*fpe_functions[i]->name_check) (pathname)) return i; } return -1; } static void FreeFontPath(FontPathElementPtr * list, int n, Bool force) { int i; for (i = 0; i < n; i++) { if (force) { /* Sanity check that all refcounts will be 0 by the time we get to the end of the list. */ int found = 1; /* the first reference is us */ int j; for (j = i + 1; j < n; j++) { if (list[j] == list[i]) found++; } if (list[i]->refcount != found) { list[i]->refcount = found; /* ensure it will get freed */ } } FreeFPE(list[i]); } free(list); } static FontPathElementPtr find_existing_fpe(FontPathElementPtr * list, int num, unsigned char *name, int len) { FontPathElementPtr fpe; int i; for (i = 0; i < num; i++) { fpe = list[i]; if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0) return fpe; } return (FontPathElementPtr) 0; } static int SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist) { int i, err = 0; int valid_paths = 0; unsigned int len; unsigned char *cp = paths; FontPathElementPtr fpe = NULL, *fplist; fplist = xallocarray(npaths, sizeof(FontPathElementPtr)); if (!fplist) { *bad = 0; return BadAlloc; } for (i = 0; i < num_fpe_types; i++) { if (fpe_functions[i]->set_path_hook) (*fpe_functions[i]->set_path_hook) (); } for (i = 0; i < npaths; i++) { len = (unsigned int) (*cp++); if (len == 0) { if (persist) ErrorF ("[dix] Removing empty element from the valid list of fontpaths\n"); err = BadValue; } else { /* if it's already in our active list, just reset it */ /* * note that this can miss FPE's in limbo -- may be worth catching * them, though it'd muck up refcounting */ fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len); if (fpe) { err = (*fpe_functions[fpe->type]->reset_fpe) (fpe); if (err == Successful) { UseFPE(fpe); /* since it'll be decref'd later when freed * from the old list */ } else fpe = 0; } /* if error or can't do it, act like it's a new one */ if (!fpe) { char *name; fpe = malloc(sizeof(FontPathElementRec)); if (!fpe) { err = BadAlloc; goto bail; } name = malloc(len + 1); if (!name) { free(fpe); err = BadAlloc; goto bail; } fpe->refcount = 1; strncpy(name, (char *) cp, (int) len); name[len] = '\0'; fpe->name = name; fpe->name_length = len; fpe->type = DetermineFPEType(fpe->name); if (fpe->type == -1) err = BadValue; else err = (*fpe_functions[fpe->type]->init_fpe) (fpe); if (err != Successful) { if (persist) { DebugF ("[dix] Could not init font path element %s, removing from list!\n", fpe->name); } free((void *) fpe->name); free(fpe); } } } if (err != Successful) { if (!persist) goto bail; } else { fplist[valid_paths++] = fpe; } cp += len; } FreeFontPath(font_path_elements, num_fpes, FALSE); font_path_elements = fplist; if (patternCache) xfont2_empty_font_pattern_cache(patternCache); num_fpes = valid_paths; return Success; bail: *bad = i; while (--valid_paths >= 0) FreeFPE(fplist[valid_paths]); free(fplist); return FontToXError(err); } int SetFontPath(ClientPtr client, int npaths, unsigned char *paths) { int err = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess); if (err != Success) return err; if (npaths == 0) { if (SetDefaultFontPath(defaultFontPath) != Success) return BadValue; } else { int bad; err = SetFontPathElements(npaths, paths, &bad, FALSE); client->errorValue = bad; } return err; } int SetDefaultFontPath(const char *path) { const char *start, *end; char *temp_path; unsigned char *cp, *pp, *nump, *newpath; int num = 1, len, err, size = 0, bad; /* ensure temp_path contains "built-ins" */ start = path; while (1) { start = strstr(start, "built-ins"); if (start == NULL) break; end = start + strlen("built-ins"); if ((start == path || start[-1] == ',') && (!*end || *end == ',')) break; start = end; } if (!start) { if (asprintf(&temp_path, "%s%sbuilt-ins", path, *path ? "," : "") == -1) temp_path = NULL; } else { temp_path = strdup(path); } if (!temp_path) return BadAlloc; /* get enough for string, plus values -- use up commas */ len = strlen(temp_path) + 1; nump = cp = newpath = malloc(len); if (!newpath) { free(temp_path); return BadAlloc; } pp = (unsigned char *) temp_path; cp++; while (*pp) { if (*pp == ',') { *nump = (unsigned char) size; nump = cp++; pp++; num++; size = 0; } else { *cp++ = *pp++; size++; } } *nump = (unsigned char) size; err = SetFontPathElements(num, newpath, &bad, TRUE); free(newpath); free(temp_path); return err; } int GetFontPath(ClientPtr client, int *count, int *length, unsigned char **result) { int i; unsigned char *c; int len; FontPathElementPtr fpe; i = XaceHook(XACE_SERVER_ACCESS, client, DixGetAttrAccess); if (i != Success) return i; len = 0; for (i = 0; i < num_fpes; i++) { fpe = font_path_elements[i]; len += fpe->name_length + 1; } c = realloc(font_path_string, len); if (c == NULL) { free(font_path_string); font_path_string = NULL; return BadAlloc; } font_path_string = c; *length = 0; for (i = 0; i < num_fpes; i++) { fpe = font_path_elements[i]; *c = fpe->name_length; *length += *c++; memmove(c, fpe->name, fpe->name_length); c += fpe->name_length; } *count = num_fpes; *result = font_path_string; return Success; } void DeleteClientFontStuff(ClientPtr client) { int i; FontPathElementPtr fpe; for (i = 0; i < num_fpes; i++) { fpe = font_path_elements[i]; if (fpe_functions[fpe->type]->client_died) (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe); } } static int register_fpe_funcs(const xfont2_fpe_funcs_rec *funcs) { xfont2_fpe_funcs_rec const **new; /* grow the list */ new = reallocarray(fpe_functions, num_fpe_types + 1, sizeof(xfont2_fpe_funcs_ptr)); if (!new) return -1; fpe_functions = new; fpe_functions[num_fpe_types] = funcs; return num_fpe_types++; } static unsigned long get_server_generation(void) { return serverGeneration; } static void * get_server_client(void) { return serverClient; } static int get_default_point_size(void) { return 120; } static FontResolutionPtr get_client_resolutions(int *num) { static struct _FontResolution res; ScreenPtr pScreen; pScreen = screenInfo.screens[0]; res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth; /* * XXX - we'll want this as long as bitmap instances are prevalent so that we can match them from scalable fonts */ if (res.x_resolution < 88) res.x_resolution = 75; else res.x_resolution = 100; res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight; if (res.y_resolution < 88) res.y_resolution = 75; else res.y_resolution = 100; res.point_size = 120; *num = 1; return &res; } void FreeFonts(void) { if (patternCache) { xfont2_free_font_pattern_cache(patternCache); patternCache = 0; } FreeFontPath(font_path_elements, num_fpes, TRUE); font_path_elements = 0; num_fpes = 0; free(fpe_functions); num_fpe_types = 0; fpe_functions = NULL; } /* convenience functions for FS interface */ static FontPtr find_old_font(XID id) { void *pFont; dixLookupResourceByType(&pFont, id, RT_NONE, serverClient, DixReadAccess); return (FontPtr) pFont; } static Font get_new_font_client_id(void) { return FakeClientID(0); } static int store_font_Client_font(FontPtr pfont, Font id) { return AddResource(id, RT_NONE, (void *) pfont); } static void delete_font_client_id(Font id) { FreeResource(id, RT_NONE); } static int _client_auth_generation(ClientPtr client) { return 0; } static int fs_handlers_installed = 0; static unsigned int last_server_gen; static void fs_block_handler(void *blockData, void *timeout) { FontBlockHandlerProcPtr block_handler = blockData; (*block_handler)(timeout); } struct fs_fd_entry { struct xorg_list entry; int fd; void *data; FontFdHandlerProcPtr handler; }; static void fs_fd_handler(int fd, int ready, void *data) { struct fs_fd_entry *entry = data; entry->handler(fd, entry->data); } static struct xorg_list fs_fd_list; static int add_fs_fd(int fd, FontFdHandlerProcPtr handler, void *data) { struct fs_fd_entry *entry = calloc(1, sizeof (struct fs_fd_entry)); if (!entry) return FALSE; entry->fd = fd; entry->data = data; entry->handler = handler; if (!SetNotifyFd(fd, fs_fd_handler, X_NOTIFY_READ, entry)) { free(entry); return FALSE; } xorg_list_add(&entry->entry, &fs_fd_list); return TRUE; } static void remove_fs_fd(int fd) { struct fs_fd_entry *entry, *temp; xorg_list_for_each_entry_safe(entry, temp, &fs_fd_list, entry) { if (entry->fd == fd) { xorg_list_del(&entry->entry); free(entry); break; } } RemoveNotifyFd(fd); } static void adjust_fs_wait_for_delay(void *wt, unsigned long newdelay) { AdjustWaitForDelay(wt, newdelay); } static int _init_fs_handlers(FontPathElementPtr fpe, FontBlockHandlerProcPtr block_handler) { /* if server has reset, make sure the b&w handlers are reinstalled */ if (last_server_gen < serverGeneration) { last_server_gen = serverGeneration; fs_handlers_installed = 0; } if (fs_handlers_installed == 0) { if (!RegisterBlockAndWakeupHandlers(fs_block_handler, FontWakeup, (void *) block_handler)) return AllocError; xorg_list_init(&fs_fd_list); fs_handlers_installed++; } QueueFontWakeup(fpe); return Successful; } static void _remove_fs_handlers(FontPathElementPtr fpe, FontBlockHandlerProcPtr block_handler, Bool all) { if (all) { /* remove the handlers if no one else is using them */ if (--fs_handlers_installed == 0) { RemoveBlockAndWakeupHandlers(fs_block_handler, FontWakeup, (void *) block_handler); } } RemoveFontWakeup(fpe); } static uint32_t wrap_time_in_millis(void) { return GetTimeInMillis(); } static const xfont2_client_funcs_rec xfont2_client_funcs = { .version = XFONT2_CLIENT_FUNCS_VERSION, .client_auth_generation = _client_auth_generation, .client_signal = ClientSignal, .delete_font_client_id = delete_font_client_id, .verrorf = VErrorF, .find_old_font = find_old_font, .get_client_resolutions = get_client_resolutions, .get_default_point_size = get_default_point_size, .get_new_font_client_id = get_new_font_client_id, .get_time_in_millis = wrap_time_in_millis, .init_fs_handlers = _init_fs_handlers, .register_fpe_funcs = register_fpe_funcs, .remove_fs_handlers = _remove_fs_handlers, .get_server_client = get_server_client, .set_font_authorizations = set_font_authorizations, .store_font_client_font = store_font_Client_font, .make_atom = MakeAtom, .valid_atom = ValidAtom, .name_for_atom = NameForAtom, .get_server_generation = get_server_generation, .add_fs_fd = add_fs_fd, .remove_fs_fd = remove_fs_fd, .adjust_fs_wait_for_delay = adjust_fs_wait_for_delay, }; xfont2_pattern_cache_ptr fontPatternCache; void InitFonts(void) { if (fontPatternCache) xfont2_free_font_pattern_cache(fontPatternCache); fontPatternCache = xfont2_make_font_pattern_cache(); xfont2_init(&xfont2_client_funcs); } xorg-server-1.20.13/dix/main.c0000644000175000017500000002757414100573755012764 00000000000000/*********************************************************** Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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. ******************************************************************/ /* The panoramix components contained the following notice */ /***************************************************************** Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Digital Equipment Corporation shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Digital Equipment Corporation. ******************************************************************/ #ifdef HAVE_DIX_CONFIG_H #include #include #endif #include #include /* for unistd.h */ #include #include #include "scrnintstr.h" #include "misc.h" #include "os.h" #include "windowstr.h" #include "resource.h" #include "dixstruct.h" #include "gcstruct.h" #include "extension.h" #include "colormap.h" #include "colormapst.h" #include "cursorstr.h" #include "selection.h" #include #include #include #include "opaque.h" #include "servermd.h" #include "hotplug.h" #include "site.h" #include "dixfont.h" #include "extnsionst.h" #include "privates.h" #include "registry.h" #include "client.h" #include "exevents.h" #ifdef PANORAMIX #include "panoramiXsrv.h" #else #include "dixevents.h" /* InitEvents() */ #endif #ifdef DPMSExtension #include #include "dpmsproc.h" #endif extern void Dispatch(void); CallbackListPtr RootWindowFinalizeCallback = NULL; int dix_main(int argc, char *argv[], char *envp[]) { int i; HWEventQueueType alwaysCheckForInput[2]; display = "0"; InitRegions(); CheckUserParameters(argc, argv, envp); CheckUserAuthorization(); InitConnectionLimits(); ProcessCommandLine(argc, argv); alwaysCheckForInput[0] = 0; alwaysCheckForInput[1] = 1; while (1) { serverGeneration++; ScreenSaverTime = defaultScreenSaverTime; ScreenSaverInterval = defaultScreenSaverInterval; ScreenSaverBlanking = defaultScreenSaverBlanking; ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; InitBlockAndWakeupHandlers(); /* Perform any operating system dependent initializations you'd like */ OsInit(); if (serverGeneration == 1) { CreateWellKnownSockets(); for (i = 1; i < LimitClients; i++) clients[i] = NullClient; serverClient = calloc(sizeof(ClientRec), 1); if (!serverClient) FatalError("couldn't create server client"); InitClient(serverClient, 0, (void *) NULL); } else ResetWellKnownSockets(); clients[0] = serverClient; currentMaxClients = 1; /* clear any existing selections */ InitSelections(); /* Initialize privates before first allocation */ dixResetPrivates(); /* Initialize server client devPrivates, to be reallocated as * more client privates are registered */ if (!dixAllocatePrivates(&serverClient->devPrivates, PRIVATE_CLIENT)) FatalError("failed to create server client privates"); if (!InitClientResources(serverClient)) /* for root resources */ FatalError("couldn't init server resources"); SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]); screenInfo.numScreens = 0; InitAtoms(); InitEvents(); xfont2_init_glyph_caching(); dixResetRegistry(); InitFonts(); InitCallbackManager(); InitOutput(&screenInfo, argc, argv); if (screenInfo.numScreens < 1) FatalError("no screens found"); InitExtensions(argc, argv); for (i = 0; i < screenInfo.numGPUScreens; i++) { ScreenPtr pScreen = screenInfo.gpuscreens[i]; if (!CreateScratchPixmapsForScreen(pScreen)) FatalError("failed to create scratch pixmaps"); if (pScreen->CreateScreenResources && !(*pScreen->CreateScreenResources) (pScreen)) FatalError("failed to create screen resources"); } for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr pScreen = screenInfo.screens[i]; if (!CreateScratchPixmapsForScreen(pScreen)) FatalError("failed to create scratch pixmaps"); if (pScreen->CreateScreenResources && !(*pScreen->CreateScreenResources) (pScreen)) FatalError("failed to create screen resources"); if (!CreateGCperDepth(i)) FatalError("failed to create scratch GCs"); if (!CreateDefaultStipple(i)) FatalError("failed to create default stipple"); if (!CreateRootWindow(pScreen)) FatalError("failed to create root window"); CallCallbacks(&RootWindowFinalizeCallback, pScreen); } if (SetDefaultFontPath(defaultFontPath) != Success) { ErrorF("[dix] failed to set default font path '%s'", defaultFontPath); } if (!SetDefaultFont(defaultTextFont)) { FatalError("could not open default font '%s'", defaultTextFont); } if (!(rootCursor = CreateRootCursor(NULL, 0))) { FatalError("could not open default cursor font '%s'", defaultCursorFont); } #ifdef PANORAMIX /* * Consolidate window and colourmap information for each screen */ if (!noPanoramiXExtension) PanoramiXConsolidate(); #endif for (i = 0; i < screenInfo.numScreens; i++) InitRootWindow(screenInfo.screens[i]->root); InitCoreDevices(); InitInput(argc, argv); InitAndStartDevices(); ReserveClientIds(serverClient); dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); dixCloseRegistry(); #ifdef PANORAMIX if (!noPanoramiXExtension) { if (!PanoramiXCreateConnectionBlock()) { FatalError("could not create connection block info"); } } else #endif { if (!CreateConnectionBlock()) { FatalError("could not create connection block info"); } } NotifyParentProcess(); InputThreadInit(); Dispatch(); UndisplayDevices(); DisableAllDevices(); /* Now free up whatever must be freed */ if (screenIsSaved == SCREEN_SAVER_ON) dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset); FreeScreenSaverTimer(); CloseDownExtensions(); #ifdef PANORAMIX { Bool remember_it = noPanoramiXExtension; noPanoramiXExtension = TRUE; FreeAllResources(); noPanoramiXExtension = remember_it; } #else FreeAllResources(); #endif CloseInput(); InputThreadFini(); for (i = 0; i < screenInfo.numScreens; i++) screenInfo.screens[i]->root = NullWindow; CloseDownDevices(); CloseDownEvents(); for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) { ScreenPtr pScreen = screenInfo.gpuscreens[i]; FreeScratchPixmapsForScreen(pScreen); dixFreeScreenSpecificPrivates(pScreen); (*pScreen->CloseScreen) (pScreen); dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); free(pScreen); screenInfo.numGPUScreens = i; } for (i = screenInfo.numScreens - 1; i >= 0; i--) { FreeScratchPixmapsForScreen(screenInfo.screens[i]); FreeGCperDepth(i); FreeDefaultStipple(i); dixFreeScreenSpecificPrivates(screenInfo.screens[i]); (*screenInfo.screens[i]->CloseScreen) (screenInfo.screens[i]); dixFreePrivates(screenInfo.screens[i]->devPrivates, PRIVATE_SCREEN); free(screenInfo.screens[i]); screenInfo.numScreens = i; } ReleaseClientIds(serverClient); dixFreePrivates(serverClient->devPrivates, PRIVATE_CLIENT); serverClient->devPrivates = NULL; dixFreeRegistry(); FreeFonts(); FreeAllAtoms(); FreeAuditTimer(); DeleteCallbackManager(); ClearWorkQueue(); if (dispatchException & DE_TERMINATE) { CloseWellKnownConnections(); } OsCleanup((dispatchException & DE_TERMINATE) != 0); if (dispatchException & DE_TERMINATE) { ddxGiveUp(EXIT_NO_ERROR); break; } free(ConnectionInfo); ConnectionInfo = NULL; } return 0; } xorg-server-1.20.13/dix/dixutils.c0000644000175000017500000006155614100573755013703 00000000000000/*********************************************************** Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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. ******************************************************************/ /* (c)Copyright 1988,1991 Adobe Systems Incorporated. All rights reserved. Permission to use, copy, modify, distribute, and sublicense this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notices appear in all copies and that both those copyright notices and this permission notice appear in supporting documentation and that the name of Adobe Systems Incorporated not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. No trademark license to use the Adobe trademarks is hereby granted. If the Adobe trademark "Display PostScript"(tm) is used to describe this software, its functionality or for any other purpose, such use shall be limited to a statement that this software works in conjunction with the Display PostScript system. Proper trademark attribution to reflect Adobe's ownership of the trademark shall be given whenever any such reference to the Display PostScript system is made. ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE. Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems Incorporated which may be registered in certain jurisdictions. Author: Adobe Systems Incorporated */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include "misc.h" #include "windowstr.h" #include "dixstruct.h" #include "pixmapstr.h" #include "gcstruct.h" #include "scrnintstr.h" #define XK_LATIN1 #include #include "xace.h" /* * CompareTimeStamps returns -1, 0, or +1 depending on if the first * argument is less than, equal to or greater than the second argument. */ int CompareTimeStamps(TimeStamp a, TimeStamp b) { if (a.months < b.months) return EARLIER; if (a.months > b.months) return LATER; if (a.milliseconds < b.milliseconds) return EARLIER; if (a.milliseconds > b.milliseconds) return LATER; return SAMETIME; } /* * convert client times to server TimeStamps */ #define HALFMONTH ((unsigned long) 1<<31) TimeStamp ClientTimeToServerTime(CARD32 c) { TimeStamp ts; if (c == CurrentTime) return currentTime; ts.months = currentTime.months; ts.milliseconds = c; if (c > currentTime.milliseconds) { if (((unsigned long) c - currentTime.milliseconds) > HALFMONTH) ts.months -= 1; } else if (c < currentTime.milliseconds) { if (((unsigned long) currentTime.milliseconds - c) > HALFMONTH) ts.months += 1; } return ts; } /* * ISO Latin-1 case conversion routine * * this routine always null-terminates the result, so * beware of too-small buffers */ static unsigned char ISOLatin1ToLower(unsigned char source) { unsigned char dest; if ((source >= XK_A) && (source <= XK_Z)) dest = source + (XK_a - XK_A); else if ((source >= XK_Agrave) && (source <= XK_Odiaeresis)) dest = source + (XK_agrave - XK_Agrave); else if ((source >= XK_Ooblique) && (source <= XK_Thorn)) dest = source + (XK_oslash - XK_Ooblique); else dest = source; return dest; } int CompareISOLatin1Lowered(const unsigned char *s1, int s1len, const unsigned char *s2, int s2len) { unsigned char c1, c2; for (;;) { /* note -- compare against zero so that -1 ignores len */ c1 = s1len-- ? *s1++ : '\0'; c2 = s2len-- ? *s2++ : '\0'; if (!c1 || (c1 != c2 && (c1 = ISOLatin1ToLower(c1)) != (c2 = ISOLatin1ToLower(c2)))) break; } return (int) c1 - (int) c2; } /* * dixLookupWindow and dixLookupDrawable: * Look up the window/drawable taking into account the client doing the * lookup, the type of drawable desired, and the type of access desired. * Return Success with *pDraw set if the window/drawable exists and the client * is allowed access, else return an error code with *pDraw set to NULL. The * access mask values are defined in resource.h. The type mask values are * defined in pixmap.h, with zero equivalent to M_DRAWABLE. */ int dixLookupDrawable(DrawablePtr *pDraw, XID id, ClientPtr client, Mask type, Mask access) { DrawablePtr pTmp; int rc; *pDraw = NULL; rc = dixLookupResourceByClass((void **) &pTmp, id, RC_DRAWABLE, client, access); if (rc != Success) client->errorValue = id; if (rc == BadValue) return BadDrawable; if (rc != Success) return rc; if (!((1 << pTmp->type) & (type ? type : M_DRAWABLE))) return BadMatch; *pDraw = pTmp; return Success; } int dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access) { int rc; rc = dixLookupDrawable((DrawablePtr *) pWin, id, client, M_WINDOW, access); /* dixLookupDrawable returns BadMatch iff id is a valid Drawable but is not a Window. Users of dixLookupWindow expect a BadWindow error in this case; they don't care that it's a valid non-Window XID */ if (rc == BadMatch) rc = BadWindow; /* Similarly, users of dixLookupWindow don't want BadDrawable. */ if (rc == BadDrawable) rc = BadWindow; return rc; } int dixLookupGC(GCPtr *pGC, XID id, ClientPtr client, Mask access) { return dixLookupResourceByType((void **) pGC, id, RT_GC, client, access); } int dixLookupFontable(FontPtr *pFont, XID id, ClientPtr client, Mask access) { int rc; GC *pGC; client->errorValue = id; /* EITHER font or gc */ rc = dixLookupResourceByType((void **) pFont, id, RT_FONT, client, access); if (rc != BadFont) return rc; rc = dixLookupResourceByType((void **) &pGC, id, RT_GC, client, access); if (rc == BadGC) return BadFont; if (rc == Success) *pFont = pGC->font; return rc; } int dixLookupClient(ClientPtr *pClient, XID rid, ClientPtr client, Mask access) { void *pRes; int rc = BadValue, clientIndex = CLIENT_ID(rid); if (!clientIndex || !clients[clientIndex] || (rid & SERVER_BIT)) goto bad; rc = dixLookupResourceByClass(&pRes, rid, RC_ANY, client, DixGetAttrAccess); if (rc != Success) goto bad; rc = XaceHook(XACE_CLIENT_ACCESS, client, clients[clientIndex], access); if (rc != Success) goto bad; *pClient = clients[clientIndex]; return Success; bad: if (client) client->errorValue = rid; *pClient = NULL; return rc; } int AlterSaveSetForClient(ClientPtr client, WindowPtr pWin, unsigned mode, Bool toRoot, Bool map) { int numnow; SaveSetElt *pTmp = NULL; int j; numnow = client->numSaved; j = 0; if (numnow) { pTmp = client->saveSet; while ((j < numnow) && (SaveSetWindow(pTmp[j]) != (void *) pWin)) j++; } if (mode == SetModeInsert) { if (j < numnow) /* duplicate */ return Success; numnow++; pTmp = (SaveSetElt *) realloc(client->saveSet, sizeof(*pTmp) * numnow); if (!pTmp) return BadAlloc; client->saveSet = pTmp; client->numSaved = numnow; SaveSetAssignWindow(client->saveSet[numnow - 1], pWin); SaveSetAssignToRoot(client->saveSet[numnow - 1], toRoot); SaveSetAssignMap(client->saveSet[numnow - 1], map); return Success; } else if ((mode == SetModeDelete) && (j < numnow)) { while (j < numnow - 1) { pTmp[j] = pTmp[j + 1]; j++; } numnow--; if (numnow) { pTmp = (SaveSetElt *) realloc(client->saveSet, sizeof(*pTmp) * numnow); if (pTmp) client->saveSet = pTmp; } else { free(client->saveSet); client->saveSet = (SaveSetElt *) NULL; } client->numSaved = numnow; return Success; } return Success; } void DeleteWindowFromAnySaveSet(WindowPtr pWin) { int i; ClientPtr client; for (i = 0; i < currentMaxClients; i++) { client = clients[i]; if (client && client->numSaved) (void) AlterSaveSetForClient(client, pWin, SetModeDelete, FALSE, TRUE); } } /* No-op Don't Do Anything : sometimes we need to be able to call a procedure * that doesn't do anything. For example, on screen with only static * colormaps, if someone calls install colormap, it's easier to have a dummy * procedure to call than to check if there's a procedure */ void NoopDDA(void) { } typedef struct _BlockHandler { ServerBlockHandlerProcPtr BlockHandler; ServerWakeupHandlerProcPtr WakeupHandler; void *blockData; Bool deleted; } BlockHandlerRec, *BlockHandlerPtr; static BlockHandlerPtr handlers; static int numHandlers; static int sizeHandlers; static Bool inHandler; static Bool handlerDeleted; /** * * \param pTimeout DIX doesn't want to know how OS represents time * \param pReadMask nor how it represents the det of descriptors */ void BlockHandler(void *pTimeout) { int i, j; ++inHandler; for (i = 0; i < numHandlers; i++) if (!handlers[i].deleted) (*handlers[i].BlockHandler) (handlers[i].blockData, pTimeout); for (i = 0; i < screenInfo.numGPUScreens; i++) (*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i], pTimeout); for (i = 0; i < screenInfo.numScreens; i++) (*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i], pTimeout); if (handlerDeleted) { for (i = 0; i < numHandlers;) if (handlers[i].deleted) { for (j = i; j < numHandlers - 1; j++) handlers[j] = handlers[j + 1]; numHandlers--; } else i++; handlerDeleted = FALSE; } --inHandler; } /** * * \param result 32 bits of undefined result from the wait * \param pReadmask the resulting descriptor mask */ void WakeupHandler(int result) { int i, j; ++inHandler; for (i = 0; i < screenInfo.numScreens; i++) (*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i], result); for (i = 0; i < screenInfo.numGPUScreens; i++) (*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i], result); for (i = numHandlers - 1; i >= 0; i--) if (!handlers[i].deleted) (*handlers[i].WakeupHandler) (handlers[i].blockData, result); if (handlerDeleted) { for (i = 0; i < numHandlers;) if (handlers[i].deleted) { for (j = i; j < numHandlers - 1; j++) handlers[j] = handlers[j + 1]; numHandlers--; } else i++; handlerDeleted = FALSE; } --inHandler; } /** * Reentrant with BlockHandler and WakeupHandler, except wakeup won't * get called until next time */ Bool RegisterBlockAndWakeupHandlers(ServerBlockHandlerProcPtr blockHandler, ServerWakeupHandlerProcPtr wakeupHandler, void *blockData) { BlockHandlerPtr new; if (numHandlers >= sizeHandlers) { new = (BlockHandlerPtr) realloc(handlers, (numHandlers + 1) * sizeof(BlockHandlerRec)); if (!new) return FALSE; handlers = new; sizeHandlers = numHandlers + 1; } handlers[numHandlers].BlockHandler = blockHandler; handlers[numHandlers].WakeupHandler = wakeupHandler; handlers[numHandlers].blockData = blockData; handlers[numHandlers].deleted = FALSE; numHandlers = numHandlers + 1; return TRUE; } void RemoveBlockAndWakeupHandlers(ServerBlockHandlerProcPtr blockHandler, ServerWakeupHandlerProcPtr wakeupHandler, void *blockData) { int i; for (i = 0; i < numHandlers; i++) if (handlers[i].BlockHandler == blockHandler && handlers[i].WakeupHandler == wakeupHandler && handlers[i].blockData == blockData) { if (inHandler) { handlerDeleted = TRUE; handlers[i].deleted = TRUE; } else { for (; i < numHandlers - 1; i++) handlers[i] = handlers[i + 1]; numHandlers--; } break; } } void InitBlockAndWakeupHandlers(void) { free(handlers); handlers = (BlockHandlerPtr) 0; numHandlers = 0; sizeHandlers = 0; } /* * A general work queue. Perform some task before the server * sleeps for input. */ WorkQueuePtr workQueue; static WorkQueuePtr *workQueueLast = &workQueue; void ClearWorkQueue(void) { WorkQueuePtr q, *p; p = &workQueue; while ((q = *p)) { *p = q->next; free(q); } workQueueLast = p; } void ProcessWorkQueue(void) { WorkQueuePtr q, *p; p = &workQueue; /* * Scan the work queue once, calling each function. Those * which return TRUE are removed from the queue, otherwise * they will be called again. This must be reentrant with * QueueWorkProc. */ while ((q = *p)) { if ((*q->function) (q->client, q->closure)) { /* remove q from the list */ *p = q->next; /* don't fetch until after func called */ free(q); } else { p = &q->next; /* don't fetch until after func called */ } } workQueueLast = p; } void ProcessWorkQueueZombies(void) { WorkQueuePtr q, *p; p = &workQueue; while ((q = *p)) { if (q->client && q->client->clientGone) { (void) (*q->function) (q->client, q->closure); /* remove q from the list */ *p = q->next; /* don't fetch until after func called */ free(q); } else { p = &q->next; /* don't fetch until after func called */ } } workQueueLast = p; } Bool QueueWorkProc(Bool (*function) (ClientPtr pClient, void *closure), ClientPtr client, void *closure) { WorkQueuePtr q; q = malloc(sizeof *q); if (!q) return FALSE; q->function = function; q->client = client; q->closure = closure; q->next = NULL; *workQueueLast = q; workQueueLast = &q->next; return TRUE; } /* * Manage a queue of sleeping clients, awakening them * when requested, by using the OS functions IgnoreClient * and AttendClient. Note that this *ignores* the troubles * with request data interleaving itself with events, but * we'll leave that until a later time. */ typedef struct _SleepQueue { struct _SleepQueue *next; ClientPtr client; ClientSleepProcPtr function; void *closure; } SleepQueueRec, *SleepQueuePtr; static SleepQueuePtr sleepQueue = NULL; Bool ClientSleep(ClientPtr client, ClientSleepProcPtr function, void *closure) { SleepQueuePtr q; q = malloc(sizeof *q); if (!q) return FALSE; IgnoreClient(client); q->next = sleepQueue; q->client = client; q->function = function; q->closure = closure; sleepQueue = q; return TRUE; } Bool ClientSignal(ClientPtr client) { SleepQueuePtr q; for (q = sleepQueue; q; q = q->next) if (q->client == client) { return QueueWorkProc(q->function, q->client, q->closure); } return FALSE; } int ClientSignalAll(ClientPtr client, ClientSleepProcPtr function, void *closure) { SleepQueuePtr q; int count = 0; for (q = sleepQueue; q; q = q->next) { if (!(client == CLIENT_SIGNAL_ANY || q->client == client)) continue; if (!(function == CLIENT_SIGNAL_ANY || q->function == function)) continue; if (!(closure == CLIENT_SIGNAL_ANY || q->closure == closure)) continue; count += QueueWorkProc(q->function, q->client, q->closure); } return count; } void ClientWakeup(ClientPtr client) { SleepQueuePtr q, *prev; prev = &sleepQueue; while ((q = *prev)) { if (q->client == client) { *prev = q->next; free(q); AttendClient(client); break; } prev = &q->next; } } Bool ClientIsAsleep(ClientPtr client) { SleepQueuePtr q; for (q = sleepQueue; q; q = q->next) if (q->client == client) return TRUE; return FALSE; } /* * Generic Callback Manager */ /* ===== Private Procedures ===== */ static int numCallbackListsToCleanup = 0; static CallbackListPtr **listsToCleanup = NULL; static Bool _AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void *data) { CallbackPtr cbr; cbr = malloc(sizeof(CallbackRec)); if (!cbr) return FALSE; cbr->proc = callback; cbr->data = data; cbr->next = (*pcbl)->list; cbr->deleted = FALSE; (*pcbl)->list = cbr; return TRUE; } static Bool _DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void *data) { CallbackListPtr cbl = *pcbl; CallbackPtr cbr, pcbr; for (pcbr = NULL, cbr = cbl->list; cbr != NULL; pcbr = cbr, cbr = cbr->next) { if ((cbr->proc == callback) && (cbr->data == data)) break; } if (cbr != NULL) { if (cbl->inCallback) { ++(cbl->numDeleted); cbr->deleted = TRUE; } else { if (pcbr == NULL) cbl->list = cbr->next; else pcbr->next = cbr->next; free(cbr); } return TRUE; } return FALSE; } void _CallCallbacks(CallbackListPtr *pcbl, void *call_data) { CallbackListPtr cbl = *pcbl; CallbackPtr cbr, pcbr; ++(cbl->inCallback); for (cbr = cbl->list; cbr != NULL; cbr = cbr->next) { (*(cbr->proc)) (pcbl, cbr->data, call_data); } --(cbl->inCallback); if (cbl->inCallback) return; /* Was the entire list marked for deletion? */ if (cbl->deleted) { DeleteCallbackList(pcbl); return; } /* Were some individual callbacks on the list marked for deletion? * If so, do the deletions. */ if (cbl->numDeleted) { for (pcbr = NULL, cbr = cbl->list; (cbr != NULL) && cbl->numDeleted;) { if (cbr->deleted) { if (pcbr) { cbr = cbr->next; free(pcbr->next); pcbr->next = cbr; } else { cbr = cbr->next; free(cbl->list); cbl->list = cbr; } cbl->numDeleted--; } else { /* this one wasn't deleted */ pcbr = cbr; cbr = cbr->next; } } } } static void _DeleteCallbackList(CallbackListPtr *pcbl) { CallbackListPtr cbl = *pcbl; CallbackPtr cbr, nextcbr; int i; if (cbl->inCallback) { cbl->deleted = TRUE; return; } for (i = 0; i < numCallbackListsToCleanup; i++) { if (listsToCleanup[i] == pcbl) { listsToCleanup[i] = NULL; break; } } for (cbr = cbl->list; cbr != NULL; cbr = nextcbr) { nextcbr = cbr->next; free(cbr); } free(cbl); *pcbl = NULL; } static Bool CreateCallbackList(CallbackListPtr *pcbl) { CallbackListPtr cbl; int i; if (!pcbl) return FALSE; cbl = malloc(sizeof(CallbackListRec)); if (!cbl) return FALSE; cbl->inCallback = 0; cbl->deleted = FALSE; cbl->numDeleted = 0; cbl->list = NULL; *pcbl = cbl; for (i = 0; i < numCallbackListsToCleanup; i++) { if (!listsToCleanup[i]) { listsToCleanup[i] = pcbl; return TRUE; } } listsToCleanup = (CallbackListPtr **) xnfrealloc(listsToCleanup, sizeof(CallbackListPtr *) * (numCallbackListsToCleanup + 1)); listsToCleanup[numCallbackListsToCleanup] = pcbl; numCallbackListsToCleanup++; return TRUE; } /* ===== Public Procedures ===== */ Bool AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void *data) { if (!pcbl) return FALSE; if (!*pcbl) { /* list hasn't been created yet; go create it */ if (!CreateCallbackList(pcbl)) return FALSE; } return _AddCallback(pcbl, callback, data); } Bool DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void *data) { if (!pcbl || !*pcbl) return FALSE; return _DeleteCallback(pcbl, callback, data); } void DeleteCallbackList(CallbackListPtr *pcbl) { if (!pcbl || !*pcbl) return; _DeleteCallbackList(pcbl); } void DeleteCallbackManager(void) { int i; for (i = 0; i < numCallbackListsToCleanup; i++) { DeleteCallbackList(listsToCleanup[i]); } free(listsToCleanup); numCallbackListsToCleanup = 0; listsToCleanup = NULL; } void InitCallbackManager(void) { DeleteCallbackManager(); } /** * Coordinates the global GL context used by modules in the X Server * doing rendering with OpenGL. * * When setting a GL context (glXMakeCurrent() or eglMakeCurrent()), * there is an expensive implied glFlush() required by the GLX and EGL * APIs, so modules don't want to have to do it on every request. But * the individual modules using GL also don't know about each other, * so they have to coordinate who owns the current context. * * When you're about to do a MakeCurrent, you should set this variable * to your context's address, and you can skip MakeCurrent if it's * already set to yours. * * When you're about to do a DestroyContext, you should set this to * NULL if it's set to your context. * * When you're about to do an unbindContext on a DRI driver, you * should set this to NULL. Despite the unbindContext interface * sounding like it only unbinds the passed in context, it actually * unconditionally clears the dispatch table even if the given * context wasn't current. */ void *lastGLContext = NULL; xorg-server-1.20.13/dix/enterleave.c0000644000175000017500000014613514100573755014165 00000000000000/* * Copyright © 2008 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: Peter Hutterer * */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include "inputstr.h" #include "windowstr.h" #include "scrnintstr.h" #include "exglobals.h" #include "enterleave.h" #include "eventconvert.h" #include "xkbsrv.h" #include "inpututils.h" /** * @file * This file describes the model for sending core enter/leave events and * focus in/out in the case of multiple pointers/keyboard foci. * * Since we can't send more than one Enter or Leave/Focus in or out event per * window to a core client without confusing it, this is a rather complicated * approach. * * For a full description of the enter/leave model from a window's * perspective, see * http://lists.freedesktop.org/archives/xorg/2008-August/037606.html * * For a full description of the focus in/out model from a window's * perspective, see * http://lists.freedesktop.org/archives/xorg/2008-December/041740.html * * Additional notes: * - The core protocol spec says that "In a LeaveNotify event, if a child of the * event window contains the initial position of the pointer, then the child * component is set to that child. Otherwise, it is None. For an EnterNotify * event, if a child of the event window contains the final pointer position, * then the child component is set to that child. Otherwise, it is None." * * By inference, this means that only NotifyVirtual or NotifyNonlinearVirtual * events may have a subwindow set to other than None. * * - NotifyPointer events may be sent if the focus changes from window A to * B. The assumption used in this model is that NotifyPointer events are only * sent for the pointer paired with the keyboard that is involved in the focus * events. For example, if F(W) changes because of keyboard 2, then * NotifyPointer events are only sent for pointer 2. */ static WindowPtr PointerWindows[MAXDEVICES]; static WindowPtr FocusWindows[MAXDEVICES]; /** * Return TRUE if 'win' has a pointer within its boundaries, excluding child * window. */ static BOOL HasPointer(DeviceIntPtr dev, WindowPtr win) { int i; /* FIXME: The enter/leave model does not cater for grabbed devices. For * now, a quickfix: if the device about to send an enter/leave event to * a window is grabbed, assume there is no pointer in that window. * Fixes fdo 27804. * There isn't enough beer in my fridge to fix this properly. */ if (dev->deviceGrab.grab) return FALSE; for (i = 0; i < MAXDEVICES; i++) if (PointerWindows[i] == win) return TRUE; return FALSE; } /** * Return TRUE if at least one keyboard focus is set to 'win' (excluding * descendants of win). */ static BOOL HasFocus(WindowPtr win) { int i; for (i = 0; i < MAXDEVICES; i++) if (FocusWindows[i] == win) return TRUE; return FALSE; } /** * Return the window the device dev is currently on. */ static WindowPtr PointerWin(DeviceIntPtr dev) { return PointerWindows[dev->id]; } /** * Search for the first window below 'win' that has a pointer directly within * it's boundaries (excluding boundaries of its own descendants). * * @return The child window that has the pointer within its boundaries or * NULL. */ static WindowPtr FirstPointerChild(WindowPtr win) { int i; for (i = 0; i < MAXDEVICES; i++) { if (PointerWindows[i] && IsParent(win, PointerWindows[i])) return PointerWindows[i]; } return NULL; } /** * Search for the first window below 'win' that has a focus directly within * it's boundaries (excluding boundaries of its own descendants). * * @return The child window that has the pointer within its boundaries or * NULL. */ static WindowPtr FirstFocusChild(WindowPtr win) { int i; for (i = 0; i < MAXDEVICES; i++) { if (FocusWindows[i] && FocusWindows[i] != PointerRootWin && IsParent(win, FocusWindows[i])) return FocusWindows[i]; } return NULL; } /** * Set the presence flag for dev to mark that it is now in 'win'. */ void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode) { PointerWindows[dev->id] = win; } /** * Unset the presence flag for dev to mark that it is not in 'win' anymore. */ void LeaveWindow(DeviceIntPtr dev) { PointerWindows[dev->id] = NULL; } /** * Set the presence flag for dev to mark that it is now in 'win'. */ void SetFocusIn(DeviceIntPtr dev, WindowPtr win) { FocusWindows[dev->id] = win; } /** * Unset the presence flag for dev to mark that it is not in 'win' anymore. */ void SetFocusOut(DeviceIntPtr dev) { FocusWindows[dev->id] = NULL; } /** * Return the common ancestor of 'a' and 'b' (if one exists). * @param a A window with the same ancestor as b. * @param b A window with the same ancestor as a. * @return The window that is the first ancestor of both 'a' and 'b', or the * NullWindow if they do not have a common ancestor. */ static WindowPtr CommonAncestor(WindowPtr a, WindowPtr b) { for (b = b->parent; b; b = b->parent) if (IsParent(b, a)) return b; return NullWindow; } /** * Send enter notifies to all windows between 'ancestor' and 'child' (excluding * both). Events are sent running up the window hierarchy. This function * recurses. */ static void DeviceEnterNotifies(DeviceIntPtr dev, int sourceid, WindowPtr ancestor, WindowPtr child, int mode, int detail) { WindowPtr parent = child->parent; if (ancestor == parent) return; DeviceEnterNotifies(dev, sourceid, ancestor, parent, mode, detail); DeviceEnterLeaveEvent(dev, sourceid, XI_Enter, mode, detail, parent, child->drawable.id); } /** * Send enter notifies to all windows between 'ancestor' and 'child' (excluding * both). Events are sent running down the window hierarchy. This function * recurses. */ static void CoreEnterNotifies(DeviceIntPtr dev, WindowPtr ancestor, WindowPtr child, int mode, int detail) { WindowPtr parent = child->parent; if (ancestor == parent) return; CoreEnterNotifies(dev, ancestor, parent, mode, detail); /* Case 3: A is above W, B is a descendant Classically: The move generates an EnterNotify on W with a detail of Virtual or NonlinearVirtual MPX: Case 3A: There is at least one other pointer on W itself P(W) doesn't change, so the event should be suppressed Case 3B: Otherwise, if there is at least one other pointer in a descendant P(W) stays on the same descendant, or changes to a different descendant. The event should be suppressed. Case 3C: Otherwise: P(W) moves from a window above W to a descendant. The subwindow field is set to the child containing the descendant. The detail may need to be changed from Virtual to NonlinearVirtual depending on the previous P(W). */ if (!HasPointer(dev, parent) && !FirstPointerChild(parent)) CoreEnterLeaveEvent(dev, EnterNotify, mode, detail, parent, child->drawable.id); } static void CoreLeaveNotifies(DeviceIntPtr dev, WindowPtr child, WindowPtr ancestor, int mode, int detail) { WindowPtr win; if (ancestor == child) return; for (win = child->parent; win != ancestor; win = win->parent) { /*Case 7: A is a descendant of W, B is above W Classically: A LeaveNotify is generated on W with a detail of Virtual or NonlinearVirtual. MPX: Case 3A: There is at least one other pointer on W itself P(W) doesn't change, the event should be suppressed. Case 3B: Otherwise, if there is at least one other pointer in a descendant P(W) stays on the same descendant, or changes to a different descendant. The event should be suppressed. Case 3C: Otherwise: P(W) changes from the descendant of W to a window above W. The detail may need to be changed from Virtual to NonlinearVirtual or vice-versa depending on the new P(W). */ /* If one window has a pointer or a child with a pointer, skip some * work and exit. */ if (HasPointer(dev, win) || FirstPointerChild(win)) return; CoreEnterLeaveEvent(dev, LeaveNotify, mode, detail, win, child->drawable.id); child = win; } } /** * Send leave notifies to all windows between 'child' and 'ancestor'. * Events are sent running up the hierarchy. */ static void DeviceLeaveNotifies(DeviceIntPtr dev, int sourceid, WindowPtr child, WindowPtr ancestor, int mode, int detail) { WindowPtr win; if (ancestor == child) return; for (win = child->parent; win != ancestor; win = win->parent) { DeviceEnterLeaveEvent(dev, sourceid, XI_Leave, mode, detail, win, child->drawable.id); child = win; } } /** * Pointer dev moves from A to B and A neither a descendant of B nor is * B a descendant of A. */ static void CoreEnterLeaveNonLinear(DeviceIntPtr dev, WindowPtr A, WindowPtr B, int mode) { WindowPtr X = CommonAncestor(A, B); /* Case 4: A is W, B is above W Classically: The move generates a LeaveNotify on W with a detail of Ancestor or Nonlinear MPX: Case 3A: There is at least one other pointer on W itself P(W) doesn't change, the event should be suppressed Case 3B: Otherwise, if there is at least one other pointer in a descendant of W P(W) changes from W to a descendant of W. The subwindow field is set to the child containing the new P(W), the detail field is set to Inferior Case 3C: Otherwise: The pointer window moves from W to a window above W. The detail may need to be changed from Ancestor to Nonlinear or vice versa depending on the the new P(W) */ if (!HasPointer(dev, A)) { WindowPtr child = FirstPointerChild(A); if (child) CoreEnterLeaveEvent(dev, LeaveNotify, mode, NotifyInferior, A, None); else CoreEnterLeaveEvent(dev, LeaveNotify, mode, NotifyNonlinear, A, None); } CoreLeaveNotifies(dev, A, X, mode, NotifyNonlinearVirtual); /* Case 9: A is a descendant of W, B is a descendant of W Classically: No events are generated on W MPX: The pointer window stays the same or moves to a different descendant of W. No events should be generated on W. Therefore, no event to X. */ CoreEnterNotifies(dev, X, B, mode, NotifyNonlinearVirtual); /* Case 2: A is above W, B=W Classically: The move generates an EnterNotify on W with a detail of Ancestor or Nonlinear MPX: Case 2A: There is at least one other pointer on W itself P(W) doesn't change, so the event should be suppressed Case 2B: Otherwise, if there is at least one other pointer in a descendant P(W) moves from a descendant to W. detail is changed to Inferior, subwindow is set to the child containing the previous P(W) Case 2C: Otherwise: P(W) changes from a window above W to W itself. The detail may need to be changed from Ancestor to Nonlinear or vice-versa depending on the previous P(W). */ if (!HasPointer(dev, B)) { WindowPtr child = FirstPointerChild(B); if (child) CoreEnterLeaveEvent(dev, EnterNotify, mode, NotifyInferior, B, None); else CoreEnterLeaveEvent(dev, EnterNotify, mode, NotifyNonlinear, B, None); } } /** * Pointer dev moves from A to B and A is a descendant of B. */ static void CoreEnterLeaveToAncestor(DeviceIntPtr dev, WindowPtr A, WindowPtr B, int mode) { /* Case 4: A is W, B is above W Classically: The move generates a LeaveNotify on W with a detail of Ancestor or Nonlinear MPX: Case 3A: There is at least one other pointer on W itself P(W) doesn't change, the event should be suppressed Case 3B: Otherwise, if there is at least one other pointer in a descendant of W P(W) changes from W to a descendant of W. The subwindow field is set to the child containing the new P(W), the detail field is set to Inferior Case 3C: Otherwise: The pointer window moves from W to a window above W. The detail may need to be changed from Ancestor to Nonlinear or vice versa depending on the the new P(W) */ if (!HasPointer(dev, A)) { WindowPtr child = FirstPointerChild(A); if (child) CoreEnterLeaveEvent(dev, LeaveNotify, mode, NotifyInferior, A, None); else CoreEnterLeaveEvent(dev, LeaveNotify, mode, NotifyAncestor, A, None); } CoreLeaveNotifies(dev, A, B, mode, NotifyVirtual); /* Case 8: A is a descendant of W, B is W Classically: A EnterNotify is generated on W with a detail of NotifyInferior MPX: Case 3A: There is at least one other pointer on W itself P(W) doesn't change, the event should be suppressed Case 3B: Otherwise: P(W) changes from a descendant to W itself. The subwindow field should be set to the child containing the old P(W) <<< WRONG */ if (!HasPointer(dev, B)) CoreEnterLeaveEvent(dev, EnterNotify, mode, NotifyInferior, B, None); } /** * Pointer dev moves from A to B and B is a descendant of A. */ static void CoreEnterLeaveToDescendant(DeviceIntPtr dev, WindowPtr A, WindowPtr B, int mode) { /* Case 6: A is W, B is a descendant of W Classically: A LeaveNotify is generated on W with a detail of NotifyInferior MPX: Case 3A: There is at least one other pointer on W itself P(W) doesn't change, the event should be suppressed Case 3B: Otherwise: P(W) changes from W to a descendant of W. The subwindow field is set to the child containing the new P(W) <<< THIS IS WRONG */ if (!HasPointer(dev, A)) CoreEnterLeaveEvent(dev, LeaveNotify, mode, NotifyInferior, A, None); CoreEnterNotifies(dev, A, B, mode, NotifyVirtual); /* Case 2: A is above W, B=W Classically: The move generates an EnterNotify on W with a detail of Ancestor or Nonlinear MPX: Case 2A: There is at least one other pointer on W itself P(W) doesn't change, so the event should be suppressed Case 2B: Otherwise, if there is at least one other pointer in a descendant P(W) moves from a descendant to W. detail is changed to Inferior, subwindow is set to the child containing the previous P(W) Case 2C: Otherwise: P(W) changes from a window above W to W itself. The detail may need to be changed from Ancestor to Nonlinear or vice-versa depending on the previous P(W). */ if (!HasPointer(dev, B)) { WindowPtr child = FirstPointerChild(B); if (child) CoreEnterLeaveEvent(dev, EnterNotify, mode, NotifyInferior, B, None); else CoreEnterLeaveEvent(dev, EnterNotify, mode, NotifyAncestor, B, None); } } static void CoreEnterLeaveEvents(DeviceIntPtr dev, WindowPtr from, WindowPtr to, int mode) { if (!IsMaster(dev)) return; LeaveWindow(dev); if (IsParent(from, to)) CoreEnterLeaveToDescendant(dev, from, to, mode); else if (IsParent(to, from)) CoreEnterLeaveToAncestor(dev, from, to, mode); else CoreEnterLeaveNonLinear(dev, from, to, mode); EnterWindow(dev, to, mode); } static void DeviceEnterLeaveEvents(DeviceIntPtr dev, int sourceid, WindowPtr from, WindowPtr to, int mode) { if (IsParent(from, to)) { DeviceEnterLeaveEvent(dev, sourceid, XI_Leave, mode, NotifyInferior, from, None); DeviceEnterNotifies(dev, sourceid, from, to, mode, NotifyVirtual); DeviceEnterLeaveEvent(dev, sourceid, XI_Enter, mode, NotifyAncestor, to, None); } else if (IsParent(to, from)) { DeviceEnterLeaveEvent(dev, sourceid, XI_Leave, mode, NotifyAncestor, from, None); DeviceLeaveNotifies(dev, sourceid, from, to, mode, NotifyVirtual); DeviceEnterLeaveEvent(dev, sourceid, XI_Enter, mode, NotifyInferior, to, None); } else { /* neither from nor to is descendent of the other */ WindowPtr common = CommonAncestor(to, from); /* common == NullWindow ==> different screens */ DeviceEnterLeaveEvent(dev, sourceid, XI_Leave, mode, NotifyNonlinear, from, None); DeviceLeaveNotifies(dev, sourceid, from, common, mode, NotifyNonlinearVirtual); DeviceEnterNotifies(dev, sourceid, common, to, mode, NotifyNonlinearVirtual); DeviceEnterLeaveEvent(dev, sourceid, XI_Enter, mode, NotifyNonlinear, to, None); } } /** * Figure out if enter/leave events are necessary and send them to the * appropriate windows. * * @param fromWin Window the sprite moved out of. * @param toWin Window the sprite moved into. */ void DoEnterLeaveEvents(DeviceIntPtr pDev, int sourceid, WindowPtr fromWin, WindowPtr toWin, int mode) { if (!IsPointerDevice(pDev)) return; if (fromWin == toWin) return; if (mode != XINotifyPassiveGrab && mode != XINotifyPassiveUngrab) CoreEnterLeaveEvents(pDev, fromWin, toWin, mode); DeviceEnterLeaveEvents(pDev, sourceid, fromWin, toWin, mode); } static void FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, int first) { int nval = v->numAxes - first; ev->type = DeviceValuator; ev->deviceid = dev->id; ev->num_valuators = nval < 3 ? nval : 3; ev->first_valuator = first; switch (ev->num_valuators) { case 3: ev->valuator2 = v->axisVal[first + 2]; case 2: ev->valuator1 = v->axisVal[first + 1]; case 1: ev->valuator0 = v->axisVal[first]; break; } first += ev->num_valuators; } static void FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, ButtonClassPtr b, ValuatorClassPtr v, int first) { ev->type = DeviceStateNotify; ev->deviceid = dev->id; ev->time = currentTime.milliseconds; ev->classes_reported = 0; ev->num_keys = 0; ev->num_buttons = 0; ev->num_valuators = 0; if (b) { ev->classes_reported |= (1 << ButtonClass); ev->num_buttons = b->numButtons; memcpy((char *) ev->buttons, (char *) b->down, 4); } else if (k) { ev->classes_reported |= (1 << KeyClass); ev->num_keys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code; memmove((char *) &ev->keys[0], (char *) k->down, 4); } if (v) { int nval = v->numAxes - first; ev->classes_reported |= (1 << ValuatorClass); ev->classes_reported |= valuator_get_mode(dev, 0) << ModeBitsShift; ev->num_valuators = nval < 3 ? nval : 3; switch (ev->num_valuators) { case 3: ev->valuator2 = v->axisVal[first + 2]; case 2: ev->valuator1 = v->axisVal[first + 1]; case 1: ev->valuator0 = v->axisVal[first]; break; } } } static void DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) { int evcount = 1; deviceStateNotify *ev, *sev; deviceKeyStateNotify *kev; deviceButtonStateNotify *bev; KeyClassPtr k; ButtonClassPtr b; ValuatorClassPtr v; int nval = 0, nkeys = 0, nbuttons = 0, first = 0; if (!(wOtherInputMasks(win)) || !(wOtherInputMasks(win)->inputEvents[dev->id] & DeviceStateNotifyMask)) return; if ((b = dev->button) != NULL) { nbuttons = b->numButtons; if (nbuttons > 32) evcount++; } if ((k = dev->key) != NULL) { nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code; if (nkeys > 32) evcount++; if (nbuttons > 0) { evcount++; } } if ((v = dev->valuator) != NULL) { nval = v->numAxes; if (nval > 3) evcount++; if (nval > 6) { if (!(k && b)) evcount++; if (nval > 9) evcount += ((nval - 7) / 3); } } sev = ev = xallocarray(evcount, sizeof(xEvent)); FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); if (b != NULL) { FixDeviceStateNotify(dev, ev++, NULL, b, v, first); first += 3; nval -= 3; if (nbuttons > 32) { (ev - 1)->deviceid |= MORE_EVENTS; bev = (deviceButtonStateNotify *) ev++; bev->type = DeviceButtonStateNotify; bev->deviceid = dev->id; memcpy((char *) &bev->buttons[4], (char *) &b->down[4], DOWN_LENGTH - 4); } if (nval > 0) { (ev - 1)->deviceid |= MORE_EVENTS; FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); first += 3; nval -= 3; } } if (k != NULL) { FixDeviceStateNotify(dev, ev++, k, NULL, v, first); first += 3; nval -= 3; if (nkeys > 32) { (ev - 1)->deviceid |= MORE_EVENTS; kev = (deviceKeyStateNotify *) ev++; kev->type = DeviceKeyStateNotify; kev->deviceid = dev->id; memmove((char *) &kev->keys[0], (char *) &k->down[4], 28); } if (nval > 0) { (ev - 1)->deviceid |= MORE_EVENTS; FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); first += 3; nval -= 3; } } while (nval > 0) { FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); first += 3; nval -= 3; if (nval > 0) { (ev - 1)->deviceid |= MORE_EVENTS; FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); first += 3; nval -= 3; } } DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount, DeviceStateNotifyMask, NullGrab); free(sev); } void DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) { deviceFocus event; xXIFocusInEvent *xi2event; DeviceIntPtr mouse; int btlen, len, i; mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER); /* XI 2 event */ btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; btlen = bytes_to_int32(btlen); len = sizeof(xXIFocusInEvent) + btlen * 4; xi2event = calloc(1, len); xi2event->type = GenericEvent; xi2event->extension = IReqCode; xi2event->evtype = type; xi2event->length = bytes_to_int32(len - sizeof(xEvent)); xi2event->buttons_len = btlen; xi2event->detail = detail; xi2event->time = currentTime.milliseconds; xi2event->deviceid = dev->id; xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ xi2event->mode = mode; xi2event->root_x = double_to_fp1616(mouse->spriteInfo->sprite->hot.x); xi2event->root_y = double_to_fp1616(mouse->spriteInfo->sprite->hot.y); for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) if (BitIsOn(mouse->button->down, i)) SetBit(&xi2event[1], mouse->button->map[i]); if (dev->key) { xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; xi2event->group.base_group = dev->key->xkbInfo->state.base_group; xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; xi2event->group.effective_group = dev->key->xkbInfo->state.group; } FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent *) xi2event, pWin, None, FALSE); DeliverEventsToWindow(dev, pWin, (xEvent *) xi2event, 1, GetEventFilter(dev, (xEvent *) xi2event), NullGrab); free(xi2event); /* XI 1.x event */ event = (deviceFocus) { .deviceid = dev->id, .mode = mode, .type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut, .detail = detail, .window = pWin->drawable.id, .time = currentTime.milliseconds }; DeliverEventsToWindow(dev, pWin, (xEvent *) &event, 1, DeviceFocusChangeMask, NullGrab); if (event.type == DeviceFocusIn) DeliverStateNotifyEvent(dev, pWin); } /** * Send focus out events to all windows between 'child' and 'ancestor'. * Events are sent running up the hierarchy. */ static void DeviceFocusOutEvents(DeviceIntPtr dev, WindowPtr child, WindowPtr ancestor, int mode, int detail) { WindowPtr win; if (ancestor == child) return; for (win = child->parent; win != ancestor; win = win->parent) DeviceFocusEvent(dev, XI_FocusOut, mode, detail, win); } /** * Send enter notifies to all windows between 'ancestor' and 'child' (excluding * both). Events are sent running up the window hierarchy. This function * recurses. */ static void DeviceFocusInEvents(DeviceIntPtr dev, WindowPtr ancestor, WindowPtr child, int mode, int detail) { WindowPtr parent = child->parent; if (ancestor == parent || !parent) return; DeviceFocusInEvents(dev, ancestor, parent, mode, detail); DeviceFocusEvent(dev, XI_FocusIn, mode, detail, parent); } /** * Send FocusIn events to all windows between 'ancestor' and 'child' (excluding * both). Events are sent running down the window hierarchy. This function * recurses. */ static void CoreFocusInEvents(DeviceIntPtr dev, WindowPtr ancestor, WindowPtr child, int mode, int detail) { WindowPtr parent = child->parent; if (ancestor == parent) return; CoreFocusInEvents(dev, ancestor, parent, mode, detail); /* Case 3: A is above W, B is a descendant Classically: The move generates an FocusIn on W with a detail of Virtual or NonlinearVirtual MPX: Case 3A: There is at least one other focus on W itself F(W) doesn't change, so the event should be suppressed Case 3B: Otherwise, if there is at least one other focus in a descendant F(W) stays on the same descendant, or changes to a different descendant. The event should be suppressed. Case 3C: Otherwise: F(W) moves from a window above W to a descendant. The detail may need to be changed from Virtual to NonlinearVirtual depending on the previous F(W). */ if (!HasFocus(parent) && !FirstFocusChild(parent)) CoreFocusEvent(dev, FocusIn, mode, detail, parent); } static void CoreFocusOutEvents(DeviceIntPtr dev, WindowPtr child, WindowPtr ancestor, int mode, int detail) { WindowPtr win; if (ancestor == child) return; for (win = child->parent; win != ancestor; win = win->parent) { /*Case 7: A is a descendant of W, B is above W Classically: A FocusOut is generated on W with a detail of Virtual or NonlinearVirtual. MPX: Case 3A: There is at least one other focus on W itself F(W) doesn't change, the event should be suppressed. Case 3B: Otherwise, if there is at least one other focus in a descendant F(W) stays on the same descendant, or changes to a different descendant. The event should be suppressed. Case 3C: Otherwise: F(W) changes from the descendant of W to a window above W. The detail may need to be changed from Virtual to NonlinearVirtual or vice-versa depending on the new P(W). */ /* If one window has a focus or a child with a focuspointer, skip some * work and exit. */ if (HasFocus(win) || FirstFocusChild(win)) return; CoreFocusEvent(dev, FocusOut, mode, detail, win); } } /** * Send FocusOut(NotifyPointer) events from the current pointer window (which * is a descendant of pwin_parent) up to (excluding) pwin_parent. * * NotifyPointer events are only sent for the device paired with dev. * * If the current pointer window is a descendant of 'exclude' or an ancestor of * 'exclude', no events are sent. If the current pointer IS 'exclude', events * are sent! */ static void CoreFocusOutNotifyPointerEvents(DeviceIntPtr dev, WindowPtr pwin_parent, WindowPtr exclude, int mode, int inclusive) { WindowPtr P, stopAt; P = PointerWin(GetMaster(dev, POINTER_OR_FLOAT)); if (!P) return; if (!IsParent(pwin_parent, P)) if (!(pwin_parent == P && inclusive)) return; if (exclude != None && exclude != PointerRootWin && (IsParent(exclude, P) || IsParent(P, exclude))) return; stopAt = (inclusive) ? pwin_parent->parent : pwin_parent; for (; P && P != stopAt; P = P->parent) CoreFocusEvent(dev, FocusOut, mode, NotifyPointer, P); } /** * DO NOT CALL DIRECTLY. * Recursion helper for CoreFocusInNotifyPointerEvents. */ static void CoreFocusInRecurse(DeviceIntPtr dev, WindowPtr win, WindowPtr stopAt, int mode, int inclusive) { if ((!inclusive && win == stopAt) || !win) return; CoreFocusInRecurse(dev, win->parent, stopAt, mode, inclusive); CoreFocusEvent(dev, FocusIn, mode, NotifyPointer, win); } /** * Send FocusIn(NotifyPointer) events from pwin_parent down to * including the current pointer window (which is a descendant of pwin_parent). * * @param pwin The pointer window. * @param exclude If the pointer window is a child of 'exclude', no events are * sent. * @param inclusive If TRUE, pwin_parent will receive the event too. */ static void CoreFocusInNotifyPointerEvents(DeviceIntPtr dev, WindowPtr pwin_parent, WindowPtr exclude, int mode, int inclusive) { WindowPtr P; P = PointerWin(GetMaster(dev, POINTER_OR_FLOAT)); if (!P || P == exclude || (pwin_parent != P && !IsParent(pwin_parent, P))) return; if (exclude != None && (IsParent(exclude, P) || IsParent(P, exclude))) return; CoreFocusInRecurse(dev, P, pwin_parent, mode, inclusive); } /** * Focus of dev moves from A to B and A neither a descendant of B nor is * B a descendant of A. */ static void CoreFocusNonLinear(DeviceIntPtr dev, WindowPtr A, WindowPtr B, int mode) { WindowPtr X = CommonAncestor(A, B); /* Case 4: A is W, B is above W Classically: The change generates a FocusOut on W with a detail of Ancestor or Nonlinear MPX: Case 3A: There is at least one other focus on W itself F(W) doesn't change, the event should be suppressed Case 3B: Otherwise, if there is at least one other focus in a descendant of W F(W) changes from W to a descendant of W. The detail field is set to Inferior Case 3C: Otherwise: The focus window moves from W to a window above W. The detail may need to be changed from Ancestor to Nonlinear or vice versa depending on the the new F(W) */ if (!HasFocus(A)) { WindowPtr child = FirstFocusChild(A); if (child) { /* NotifyPointer P-A unless P is child or below */ CoreFocusOutNotifyPointerEvents(dev, A, child, mode, FALSE); CoreFocusEvent(dev, FocusOut, mode, NotifyInferior, A); } else { /* NotifyPointer P-A */ CoreFocusOutNotifyPointerEvents(dev, A, None, mode, FALSE); CoreFocusEvent(dev, FocusOut, mode, NotifyNonlinear, A); } } CoreFocusOutEvents(dev, A, X, mode, NotifyNonlinearVirtual); /* Case 9: A is a descendant of W, B is a descendant of W Classically: No events are generated on W MPX: The focus window stays the same or moves to a different descendant of W. No events should be generated on W. Therefore, no event to X. */ CoreFocusInEvents(dev, X, B, mode, NotifyNonlinearVirtual); /* Case 2: A is above W, B=W Classically: The move generates an EnterNotify on W with a detail of Ancestor or Nonlinear MPX: Case 2A: There is at least one other focus on W itself F(W) doesn't change, so the event should be suppressed Case 2B: Otherwise, if there is at least one other focus in a descendant F(W) moves from a descendant to W. detail is changed to Inferior. Case 2C: Otherwise: F(W) changes from a window above W to W itself. The detail may need to be changed from Ancestor to Nonlinear or vice-versa depending on the previous F(W). */ if (!HasFocus(B)) { WindowPtr child = FirstFocusChild(B); if (child) { CoreFocusEvent(dev, FocusIn, mode, NotifyInferior, B); /* NotifyPointer B-P unless P is child or below. */ CoreFocusInNotifyPointerEvents(dev, B, child, mode, FALSE); } else { CoreFocusEvent(dev, FocusIn, mode, NotifyNonlinear, B); /* NotifyPointer B-P unless P is child or below. */ CoreFocusInNotifyPointerEvents(dev, B, None, mode, FALSE); } } } /** * Focus of dev moves from A to B and A is a descendant of B. */ static void CoreFocusToAncestor(DeviceIntPtr dev, WindowPtr A, WindowPtr B, int mode) { /* Case 4: A is W, B is above W Classically: The change generates a FocusOut on W with a detail of Ancestor or Nonlinear MPX: Case 3A: There is at least one other focus on W itself F(W) doesn't change, the event should be suppressed Case 3B: Otherwise, if there is at least one other focus in a descendant of W F(W) changes from W to a descendant of W. The detail field is set to Inferior Case 3C: Otherwise: The focus window moves from W to a window above W. The detail may need to be changed from Ancestor to Nonlinear or vice versa depending on the the new F(W) */ if (!HasFocus(A)) { WindowPtr child = FirstFocusChild(A); if (child) { /* NotifyPointer P-A unless P is child or below */ CoreFocusOutNotifyPointerEvents(dev, A, child, mode, FALSE); CoreFocusEvent(dev, FocusOut, mode, NotifyInferior, A); } else CoreFocusEvent(dev, FocusOut, mode, NotifyAncestor, A); } CoreFocusOutEvents(dev, A, B, mode, NotifyVirtual); /* Case 8: A is a descendant of W, B is W Classically: A FocusOut is generated on W with a detail of NotifyInferior MPX: Case 3A: There is at least one other focus on W itself F(W) doesn't change, the event should be suppressed Case 3B: Otherwise: F(W) changes from a descendant to W itself. */ if (!HasFocus(B)) { CoreFocusEvent(dev, FocusIn, mode, NotifyInferior, B); /* NotifyPointer B-P unless P is A or below. */ CoreFocusInNotifyPointerEvents(dev, B, A, mode, FALSE); } } /** * Focus of dev moves from A to B and B is a descendant of A. */ static void CoreFocusToDescendant(DeviceIntPtr dev, WindowPtr A, WindowPtr B, int mode) { /* Case 6: A is W, B is a descendant of W Classically: A FocusOut is generated on W with a detail of NotifyInferior MPX: Case 3A: There is at least one other focus on W itself F(W) doesn't change, the event should be suppressed Case 3B: Otherwise: F(W) changes from W to a descendant of W. */ if (!HasFocus(A)) { /* NotifyPointer P-A unless P is B or below */ CoreFocusOutNotifyPointerEvents(dev, A, B, mode, FALSE); CoreFocusEvent(dev, FocusOut, mode, NotifyInferior, A); } CoreFocusInEvents(dev, A, B, mode, NotifyVirtual); /* Case 2: A is above W, B=W Classically: The move generates an FocusIn on W with a detail of Ancestor or Nonlinear MPX: Case 2A: There is at least one other focus on W itself F(W) doesn't change, so the event should be suppressed Case 2B: Otherwise, if there is at least one other focus in a descendant F(W) moves from a descendant to W. detail is changed to Inferior. Case 2C: Otherwise: F(W) changes from a window above W to W itself. The detail may need to be changed from Ancestor to Nonlinear or vice-versa depending on the previous F(W). */ if (!HasFocus(B)) { WindowPtr child = FirstFocusChild(B); if (child) { CoreFocusEvent(dev, FocusIn, mode, NotifyInferior, B); /* NotifyPointer B-P unless P is child or below. */ CoreFocusInNotifyPointerEvents(dev, B, child, mode, FALSE); } else CoreFocusEvent(dev, FocusIn, mode, NotifyAncestor, B); } } static BOOL HasOtherPointer(WindowPtr win, DeviceIntPtr exclude) { int i; for (i = 0; i < MAXDEVICES; i++) if (i != exclude->id && PointerWindows[i] == win) return TRUE; return FALSE; } /** * Focus moves from PointerRoot to None or from None to PointerRoot. * Assumption: Neither A nor B are valid windows. */ static void CoreFocusPointerRootNoneSwitch(DeviceIntPtr dev, WindowPtr A, /* PointerRootWin or NoneWin */ WindowPtr B, /* NoneWin or PointerRootWin */ int mode) { WindowPtr root; int i; int nscreens = screenInfo.numScreens; #ifdef PANORAMIX if (!noPanoramiXExtension) nscreens = 1; #endif for (i = 0; i < nscreens; i++) { root = screenInfo.screens[i]->root; if (!HasOtherPointer(root, GetMaster(dev, POINTER_OR_FLOAT)) && !FirstFocusChild(root)) { /* If pointer was on PointerRootWin and changes to NoneWin, and * the pointer paired with dev is below the current root window, * do a NotifyPointer run. */ if (dev->focus && dev->focus->win == PointerRootWin && B != PointerRootWin) { WindowPtr ptrwin = PointerWin(GetMaster(dev, POINTER_OR_FLOAT)); if (ptrwin && IsParent(root, ptrwin)) CoreFocusOutNotifyPointerEvents(dev, root, None, mode, TRUE); } CoreFocusEvent(dev, FocusOut, mode, A ? NotifyPointerRoot : NotifyDetailNone, root); CoreFocusEvent(dev, FocusIn, mode, B ? NotifyPointerRoot : NotifyDetailNone, root); if (B == PointerRootWin) CoreFocusInNotifyPointerEvents(dev, root, None, mode, TRUE); } } } /** * Focus moves from window A to PointerRoot or to None. * Assumption: A is a valid window and not PointerRoot or None. */ static void CoreFocusToPointerRootOrNone(DeviceIntPtr dev, WindowPtr A, WindowPtr B, /* PointerRootWin or NoneWin */ int mode) { WindowPtr root; int i; int nscreens = screenInfo.numScreens; #ifdef PANORAMIX if (!noPanoramiXExtension) nscreens = 1; #endif if (!HasFocus(A)) { WindowPtr child = FirstFocusChild(A); if (child) { /* NotifyPointer P-A unless P is B or below */ CoreFocusOutNotifyPointerEvents(dev, A, B, mode, FALSE); CoreFocusEvent(dev, FocusOut, mode, NotifyInferior, A); } else { /* NotifyPointer P-A */ CoreFocusOutNotifyPointerEvents(dev, A, None, mode, FALSE); CoreFocusEvent(dev, FocusOut, mode, NotifyNonlinear, A); } } /* NullWindow means we include the root window */ CoreFocusOutEvents(dev, A, NullWindow, mode, NotifyNonlinearVirtual); for (i = 0; i < nscreens; i++) { root = screenInfo.screens[i]->root; if (!HasFocus(root) && !FirstFocusChild(root)) { CoreFocusEvent(dev, FocusIn, mode, B ? NotifyPointerRoot : NotifyDetailNone, root); if (B == PointerRootWin) CoreFocusInNotifyPointerEvents(dev, root, None, mode, TRUE); } } } /** * Focus moves from PointerRoot or None to a window B. * Assumption: B is a valid window and not PointerRoot or None. */ static void CoreFocusFromPointerRootOrNone(DeviceIntPtr dev, WindowPtr A, /* PointerRootWin or NoneWin */ WindowPtr B, int mode) { WindowPtr root; int i; int nscreens = screenInfo.numScreens; #ifdef PANORAMIX if (!noPanoramiXExtension) nscreens = 1; #endif for (i = 0; i < nscreens; i++) { root = screenInfo.screens[i]->root; if (!HasFocus(root) && !FirstFocusChild(root)) { /* If pointer was on PointerRootWin and changes to NoneWin, and * the pointer paired with dev is below the current root window, * do a NotifyPointer run. */ if (dev->focus && dev->focus->win == PointerRootWin && B != PointerRootWin) { WindowPtr ptrwin = PointerWin(GetMaster(dev, POINTER_OR_FLOAT)); if (ptrwin) CoreFocusOutNotifyPointerEvents(dev, root, None, mode, TRUE); } CoreFocusEvent(dev, FocusOut, mode, A ? NotifyPointerRoot : NotifyDetailNone, root); } } root = B; /* get B's root window */ while (root->parent) root = root->parent; if (B != root) { CoreFocusEvent(dev, FocusIn, mode, NotifyNonlinearVirtual, root); CoreFocusInEvents(dev, root, B, mode, NotifyNonlinearVirtual); } if (!HasFocus(B)) { WindowPtr child = FirstFocusChild(B); if (child) { CoreFocusEvent(dev, FocusIn, mode, NotifyInferior, B); /* NotifyPointer B-P unless P is child or below. */ CoreFocusInNotifyPointerEvents(dev, B, child, mode, FALSE); } else { CoreFocusEvent(dev, FocusIn, mode, NotifyNonlinear, B); /* NotifyPointer B-P unless P is child or below. */ CoreFocusInNotifyPointerEvents(dev, B, None, mode, FALSE); } } } static void CoreFocusEvents(DeviceIntPtr dev, WindowPtr from, WindowPtr to, int mode) { if (!IsMaster(dev)) return; SetFocusOut(dev); if (((to == NullWindow) || (to == PointerRootWin)) && ((from == NullWindow) || (from == PointerRootWin))) CoreFocusPointerRootNoneSwitch(dev, from, to, mode); else if ((to == NullWindow) || (to == PointerRootWin)) CoreFocusToPointerRootOrNone(dev, from, to, mode); else if ((from == NullWindow) || (from == PointerRootWin)) CoreFocusFromPointerRootOrNone(dev, from, to, mode); else if (IsParent(from, to)) CoreFocusToDescendant(dev, from, to, mode); else if (IsParent(to, from)) CoreFocusToAncestor(dev, from, to, mode); else CoreFocusNonLinear(dev, from, to, mode); SetFocusIn(dev, to); } static void DeviceFocusEvents(DeviceIntPtr dev, WindowPtr from, WindowPtr to, int mode) { int out, in; /* for holding details for to/from PointerRoot/None */ int i; int nscreens = screenInfo.numScreens; SpritePtr sprite = dev->spriteInfo->sprite; if (from == to) return; out = (from == NoneWin) ? NotifyDetailNone : NotifyPointerRoot; in = (to == NoneWin) ? NotifyDetailNone : NotifyPointerRoot; /* wrong values if neither, but then not referenced */ #ifdef PANORAMIX if (!noPanoramiXExtension) nscreens = 1; #endif if ((to == NullWindow) || (to == PointerRootWin)) { if ((from == NullWindow) || (from == PointerRootWin)) { if (from == PointerRootWin) { DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyPointer, sprite->win); DeviceFocusOutEvents(dev, sprite->win, GetCurrentRootWindow(dev), mode, NotifyPointer); } /* Notify all the roots */ for (i = 0; i < nscreens; i++) DeviceFocusEvent(dev, XI_FocusOut, mode, out, screenInfo.screens[i]->root); } else { if (IsParent(from, sprite->win)) { DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyPointer, sprite->win); DeviceFocusOutEvents(dev, sprite->win, from, mode, NotifyPointer); } DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from); /* next call catches the root too, if the screen changed */ DeviceFocusOutEvents(dev, from, NullWindow, mode, NotifyNonlinearVirtual); } /* Notify all the roots */ for (i = 0; i < nscreens; i++) DeviceFocusEvent(dev, XI_FocusIn, mode, in, screenInfo.screens[i]->root); if (to == PointerRootWin) { DeviceFocusInEvents(dev, GetCurrentRootWindow(dev), sprite->win, mode, NotifyPointer); DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyPointer, sprite->win); } } else { if ((from == NullWindow) || (from == PointerRootWin)) { if (from == PointerRootWin) { DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyPointer, sprite->win); DeviceFocusOutEvents(dev, sprite->win, GetCurrentRootWindow(dev), mode, NotifyPointer); } for (i = 0; i < nscreens; i++) DeviceFocusEvent(dev, XI_FocusOut, mode, out, screenInfo.screens[i]->root); if (to->parent != NullWindow) DeviceFocusInEvents(dev, GetCurrentRootWindow(dev), to, mode, NotifyNonlinearVirtual); DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyNonlinear, to); if (IsParent(to, sprite->win)) DeviceFocusInEvents(dev, to, sprite->win, mode, NotifyPointer); } else { if (IsParent(to, from)) { DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyAncestor, from); DeviceFocusOutEvents(dev, from, to, mode, NotifyVirtual); DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyInferior, to); if ((IsParent(to, sprite->win)) && (sprite->win != from) && (!IsParent(from, sprite->win)) && (!IsParent(sprite->win, from))) DeviceFocusInEvents(dev, to, sprite->win, mode, NotifyPointer); } else if (IsParent(from, to)) { if ((IsParent(from, sprite->win)) && (sprite->win != from) && (!IsParent(to, sprite->win)) && (!IsParent(sprite->win, to))) { DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyPointer, sprite->win); DeviceFocusOutEvents(dev, sprite->win, from, mode, NotifyPointer); } DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyInferior, from); DeviceFocusInEvents(dev, from, to, mode, NotifyVirtual); DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyAncestor, to); } else { /* neither from or to is child of other */ WindowPtr common = CommonAncestor(to, from); /* common == NullWindow ==> different screens */ if (IsParent(from, sprite->win)) DeviceFocusOutEvents(dev, sprite->win, from, mode, NotifyPointer); DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from); if (from->parent != NullWindow) DeviceFocusOutEvents(dev, from, common, mode, NotifyNonlinearVirtual); if (to->parent != NullWindow) DeviceFocusInEvents(dev, common, to, mode, NotifyNonlinearVirtual); DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyNonlinear, to); if (IsParent(to, sprite->win)) DeviceFocusInEvents(dev, to, sprite->win, mode, NotifyPointer); } } } } /** * Figure out if focus events are necessary and send them to the * appropriate windows. * * @param from Window the focus moved out of. * @param to Window the focus moved into. */ void DoFocusEvents(DeviceIntPtr pDev, WindowPtr from, WindowPtr to, int mode) { if (!IsKeyboardDevice(pDev)) return; if (from == to && mode != NotifyGrab && mode != NotifyUngrab) return; CoreFocusEvents(pDev, from, to, mode); DeviceFocusEvents(pDev, from, to, mode); } xorg-server-1.20.13/dix/enterleave.h0000644000175000017500000000527514100573755014171 00000000000000/* * Copyright © 2008 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: Peter Hutterer * */ #ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef ENTERLEAVE_H #define ENTERLEAVE_H #include /* DoFocusEvents() */ extern void DoEnterLeaveEvents(DeviceIntPtr pDev, int sourceid, WindowPtr fromWin, WindowPtr toWin, int mode); extern void EnterLeaveEvent(DeviceIntPtr mouse, int type, int mode, int detail, WindowPtr pWin, Window child); extern void CoreEnterLeaveEvent(DeviceIntPtr mouse, int type, int mode, int detail, WindowPtr pWin, Window child); extern void DeviceEnterLeaveEvent(DeviceIntPtr mouse, int sourceid, int type, int mode, int detail, WindowPtr pWin, Window child); extern void DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail , WindowPtr pWin); extern void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode); extern void LeaveWindow(DeviceIntPtr dev); extern void CoreFocusEvent(DeviceIntPtr kbd, int type, int mode, int detail, WindowPtr pWin); extern void SetFocusIn(DeviceIntPtr kbd, WindowPtr win); extern void SetFocusOut(DeviceIntPtr dev); #endif /* _ENTERLEAVE_H_ */ xorg-server-1.20.13/dix/events.c0000644000175000017500000057624314100573755013346 00000000000000/************************************************************ Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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. ********************************************************/ /* The panoramix components contained the following notice */ /***************************************************************** Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Digital Equipment Corporation shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Digital Equipment Corporation. ******************************************************************/ /* * Copyright (c) 2003-2005, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /** @file events.c * This file handles event delivery and a big part of the server-side protocol * handling (the parts for input devices). */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "misc.h" #include "resource.h" #include #include "windowstr.h" #include "inputstr.h" #include "inpututils.h" #include "scrnintstr.h" #include "cursorstr.h" #include "dixstruct.h" #ifdef PANORAMIX #include "panoramiX.h" #include "panoramiXsrv.h" #endif #include "globals.h" #include #include "xkbsrv.h" #include "xace.h" #include "probes.h" #include #include #include #include #include "exglobals.h" #include "exevents.h" #include "extnsionst.h" #include "dixevents.h" #include "dixgrabs.h" #include "dispatch.h" #include #include "geext.h" #include "geint.h" #include "eventstr.h" #include "enterleave.h" #include "eventconvert.h" #include "mi.h" /* Extension events type numbering starts at EXTENSION_EVENT_BASE. */ #define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */ #define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask ) #define AllButtonsMask ( \ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) #define MotionMask ( \ PointerMotionMask | Button1MotionMask | \ Button2MotionMask | Button3MotionMask | Button4MotionMask | \ Button5MotionMask | ButtonMotionMask ) #define PropagateMask ( \ KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \ MotionMask ) #define PointerGrabMask ( \ ButtonPressMask | ButtonReleaseMask | \ EnterWindowMask | LeaveWindowMask | \ PointerMotionHintMask | KeymapStateMask | \ MotionMask ) #define AllModifiersMask ( \ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ Mod3Mask | Mod4Mask | Mod5Mask ) #define LastEventMask OwnerGrabButtonMask #define AllEventMasks (LastEventMask|(LastEventMask-1)) /* @return the core event type or 0 if the event is not a core event */ static inline int core_get_type(const xEvent *event) { int type = event->u.u.type; return ((type & EXTENSION_EVENT_BASE) || type == GenericEvent) ? 0 : type; } /* @return the XI2 event type or 0 if the event is not a XI2 event */ static inline int xi2_get_type(const xEvent *event) { const xGenericEvent *e = (const xGenericEvent *) event; return (e->type != GenericEvent || e->extension != IReqCode) ? 0 : e->evtype; } /** * Used to indicate a implicit passive grab created by a ButtonPress event. * See DeliverEventsToWindow(). */ #define ImplicitGrabMask (1 << 7) #define WID(w) ((w) ? ((w)->drawable.id) : 0) #define XE_KBPTR (xE->u.keyButtonPointer) CallbackListPtr EventCallback; CallbackListPtr DeviceEventCallback; #define DNPMCOUNT 8 Mask DontPropagateMasks[DNPMCOUNT]; static int DontPropagateRefCnts[DNPMCOUNT]; static void CheckVirtualMotion(DeviceIntPtr pDev, QdEventPtr qe, WindowPtr pWin); static void CheckPhysLimits(DeviceIntPtr pDev, CursorPtr cursor, Bool generateEvents, Bool confineToScreen, ScreenPtr pScreen); static Bool IsWrongPointerBarrierClient(ClientPtr client, DeviceIntPtr dev, xEvent *event); /** Key repeat hack. Do not use but in TryClientEvents */ extern BOOL EventIsKeyRepeat(xEvent *event); /** * Main input device struct. * inputInfo.pointer * is the core pointer. Referred to as "virtual core pointer", "VCP", * "core pointer" or inputInfo.pointer. The VCP is the first master * pointer device and cannot be deleted. * * inputInfo.keyboard * is the core keyboard ("virtual core keyboard", "VCK", "core keyboard"). * See inputInfo.pointer. * * inputInfo.devices * linked list containing all devices including VCP and VCK. * * inputInfo.off_devices * Devices that have not been initialized and are thus turned off. * * inputInfo.numDevices * Total number of devices. * * inputInfo.all_devices * Virtual device used for XIAllDevices passive grabs. This device is * not part of the inputInfo.devices list and mostly unset except for * the deviceid. It exists because passivegrabs need a valid device * reference. * * inputInfo.all_master_devices * Virtual device used for XIAllMasterDevices passive grabs. This device * is not part of the inputInfo.devices list and mostly unset except for * the deviceid. It exists because passivegrabs need a valid device * reference. */ InputInfo inputInfo; EventSyncInfoRec syncEvents; static struct DeviceEventTime { Bool reset; TimeStamp time; } lastDeviceEventTime[MAXDEVICES]; /** * The root window the given device is currently on. */ #define RootWindow(sprite) sprite->spriteTrace[0] static xEvent *swapEvent = NULL; static int swapEventLen = 0; void NotImplemented(xEvent *from, xEvent *to) { FatalError("Not implemented"); } /** * Convert the given event type from an XI event to a core event. * @param[in] The XI 1.x event type. * @return The matching core event type or 0 if there is none. */ int XItoCoreType(int xitype) { int coretype = 0; if (xitype == DeviceMotionNotify) coretype = MotionNotify; else if (xitype == DeviceButtonPress) coretype = ButtonPress; else if (xitype == DeviceButtonRelease) coretype = ButtonRelease; else if (xitype == DeviceKeyPress) coretype = KeyPress; else if (xitype == DeviceKeyRelease) coretype = KeyRelease; return coretype; } /** * @return true if the device owns a cursor, false if device shares a cursor * sprite with another device. */ Bool DevHasCursor(DeviceIntPtr pDev) { return pDev->spriteInfo->spriteOwner; } /* * @return true if a device is a pointer, check is the same as used by XI to * fill the 'use' field. */ Bool IsPointerDevice(DeviceIntPtr dev) { return (dev->type == MASTER_POINTER) || (dev->valuator && dev->button) || (dev->valuator && !dev->key); } /* * @return true if a device is a keyboard, check is the same as used by XI to * fill the 'use' field. * * Some pointer devices have keys as well (e.g. multimedia keys). Try to not * count them as keyboard devices. */ Bool IsKeyboardDevice(DeviceIntPtr dev) { return (dev->type == MASTER_KEYBOARD) || ((dev->key && dev->kbdfeed) && !IsPointerDevice(dev)); } Bool IsMaster(DeviceIntPtr dev) { return dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD; } Bool IsFloating(DeviceIntPtr dev) { return !IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == NULL; } /** * Max event opcode. */ extern int lastEvent; #define CantBeFiltered NoEventMask /** * Event masks for each event type. * * One set of filters for each device, initialized by memcpy of * default_filter in InitEvents. * * Filters are used whether a given event may be delivered to a client, * usually in the form of if (window-event-mask & filter); then deliver event. * * One notable filter is for PointerMotion/DevicePointerMotion events. Each * time a button is pressed, the filter is modified to also contain the * matching ButtonXMotion mask. */ Mask event_filters[MAXDEVICES][MAXEVENTS]; static const Mask default_filter[MAXEVENTS] = { NoSuchEvent, /* 0 */ NoSuchEvent, /* 1 */ KeyPressMask, /* KeyPress */ KeyReleaseMask, /* KeyRelease */ ButtonPressMask, /* ButtonPress */ ButtonReleaseMask, /* ButtonRelease */ PointerMotionMask, /* MotionNotify (initial state) */ EnterWindowMask, /* EnterNotify */ LeaveWindowMask, /* LeaveNotify */ FocusChangeMask, /* FocusIn */ FocusChangeMask, /* FocusOut */ KeymapStateMask, /* KeymapNotify */ ExposureMask, /* Expose */ CantBeFiltered, /* GraphicsExpose */ CantBeFiltered, /* NoExpose */ VisibilityChangeMask, /* VisibilityNotify */ SubstructureNotifyMask, /* CreateNotify */ StructureAndSubMask, /* DestroyNotify */ StructureAndSubMask, /* UnmapNotify */ StructureAndSubMask, /* MapNotify */ SubstructureRedirectMask, /* MapRequest */ StructureAndSubMask, /* ReparentNotify */ StructureAndSubMask, /* ConfigureNotify */ SubstructureRedirectMask, /* ConfigureRequest */ StructureAndSubMask, /* GravityNotify */ ResizeRedirectMask, /* ResizeRequest */ StructureAndSubMask, /* CirculateNotify */ SubstructureRedirectMask, /* CirculateRequest */ PropertyChangeMask, /* PropertyNotify */ CantBeFiltered, /* SelectionClear */ CantBeFiltered, /* SelectionRequest */ CantBeFiltered, /* SelectionNotify */ ColormapChangeMask, /* ColormapNotify */ CantBeFiltered, /* ClientMessage */ CantBeFiltered /* MappingNotify */ }; /** * For the given event, return the matching event filter. This filter may then * be AND'ed with the selected event mask. * * For XI2 events, the returned filter is simply the byte containing the event * mask we're interested in. E.g. for a mask of (1 << 13), this would be * byte[1]. * * @param[in] dev The device the event belongs to, may be NULL. * @param[in] event The event to get the filter for. Only the type of the * event matters, or the extension + evtype for GenericEvents. * @return The filter mask for the given event. * * @see GetEventMask */ Mask GetEventFilter(DeviceIntPtr dev, xEvent *event) { int evtype = 0; if (event->u.u.type != GenericEvent) return event_get_filter_from_type(dev, event->u.u.type); else if ((evtype = xi2_get_type(event))) return event_get_filter_from_xi2type(evtype); ErrorF("[dix] Unknown event type %d. No filter\n", event->u.u.type); return 0; } /** * Return the single byte of the device's XI2 mask that contains the mask * for the event_type. */ int GetXI2MaskByte(XI2Mask *mask, DeviceIntPtr dev, int event_type) { /* we just return the matching filter because that's the only use * for this mask anyway. */ if (xi2mask_isset(mask, dev, event_type)) return event_get_filter_from_xi2type(event_type); else return 0; } /** * @return TRUE if the mask is set for this event from this device on the * window, or FALSE otherwise. */ Bool WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev) { OtherInputMasks *inputMasks = wOtherInputMasks(win); int evtype; if (!inputMasks || xi2_get_type(ev) == 0) return 0; evtype = ((xGenericEvent *) ev)->evtype; return xi2mask_isset(inputMasks->xi2mask, dev, evtype); } Mask GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients * other) { int evtype; /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */ if ((evtype = xi2_get_type(event))) { return GetXI2MaskByte(other->xi2mask, dev, evtype); } else if (core_get_type(event) != 0) return other->mask[XIAllDevices]; else return other->mask[dev->id]; } static CARD8 criticalEvents[32] = { 0x7c, 0x30, 0x40 /* key, button, expose, and configure events */ }; static void SyntheticMotion(DeviceIntPtr dev, int x, int y) { int screenno = 0; #ifdef PANORAMIX if (!noPanoramiXExtension) screenno = dev->spriteInfo->sprite->screen->myNum; #endif PostSyntheticMotion(dev, x, y, screenno, (syncEvents.playingEvents) ? syncEvents.time. milliseconds : currentTime.milliseconds); } #ifdef PANORAMIX static void PostNewCursor(DeviceIntPtr pDev); static Bool XineramaSetCursorPosition(DeviceIntPtr pDev, int x, int y, Bool generateEvent) { ScreenPtr pScreen; int i; SpritePtr pSprite = pDev->spriteInfo->sprite; /* x,y are in Screen 0 coordinates. We need to decide what Screen to send the message too and what the coordinates relative to that screen are. */ pScreen = pSprite->screen; x += screenInfo.screens[0]->x; y += screenInfo.screens[0]->y; if (!point_on_screen(pScreen, x, y)) { FOR_NSCREENS(i) { if (i == pScreen->myNum) continue; if (point_on_screen(screenInfo.screens[i], x, y)) { pScreen = screenInfo.screens[i]; break; } } } pSprite->screen = pScreen; pSprite->hotPhys.x = x - screenInfo.screens[0]->x; pSprite->hotPhys.y = y - screenInfo.screens[0]->y; x -= pScreen->x; y -= pScreen->y; return (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent); } static void XineramaConstrainCursor(DeviceIntPtr pDev) { SpritePtr pSprite = pDev->spriteInfo->sprite; ScreenPtr pScreen; BoxRec newBox; pScreen = pSprite->screen; newBox = pSprite->physLimits; /* Translate the constraining box to the screen the sprite is actually on */ newBox.x1 += screenInfo.screens[0]->x - pScreen->x; newBox.x2 += screenInfo.screens[0]->x - pScreen->x; newBox.y1 += screenInfo.screens[0]->y - pScreen->y; newBox.y2 += screenInfo.screens[0]->y - pScreen->y; (*pScreen->ConstrainCursor) (pDev, pScreen, &newBox); } static Bool XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin) { SpritePtr pSprite = pDev->spriteInfo->sprite; if (pWin == screenInfo.screens[0]->root) { int i; FOR_NSCREENS(i) pSprite->windows[i] = screenInfo.screens[i]->root; } else { PanoramiXRes *win; int rc, i; rc = dixLookupResourceByType((void **) &win, pWin->drawable.id, XRT_WINDOW, serverClient, DixReadAccess); if (rc != Success) return FALSE; FOR_NSCREENS(i) { rc = dixLookupWindow(pSprite->windows + i, win->info[i].id, serverClient, DixReadAccess); if (rc != Success) /* window is being unmapped */ return FALSE; } } return TRUE; } static void XineramaConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents) { SpritePtr pSprite = pDev->spriteInfo->sprite; int x, y, off_x, off_y, i; assert(!noPanoramiXExtension); if (!XineramaSetWindowPntrs(pDev, pWin)) return; i = PanoramiXNumScreens - 1; RegionCopy(&pSprite->Reg1, &pSprite->windows[i]->borderSize); off_x = screenInfo.screens[i]->x; off_y = screenInfo.screens[i]->y; while (i--) { x = off_x - screenInfo.screens[i]->x; y = off_y - screenInfo.screens[i]->y; if (x || y) RegionTranslate(&pSprite->Reg1, x, y); RegionUnion(&pSprite->Reg1, &pSprite->Reg1, &pSprite->windows[i]->borderSize); off_x = screenInfo.screens[i]->x; off_y = screenInfo.screens[i]->y; } pSprite->hotLimits = *RegionExtents(&pSprite->Reg1); if (RegionNumRects(&pSprite->Reg1) > 1) pSprite->hotShape = &pSprite->Reg1; else pSprite->hotShape = NullRegion; pSprite->confined = FALSE; pSprite->confineWin = (pWin == screenInfo.screens[0]->root) ? NullWindow : pWin; CheckPhysLimits(pDev, pSprite->current, generateEvents, FALSE, NULL); } #endif /* PANORAMIX */ /** * Modifies the filter for the given protocol event type to the given masks. * * There's only two callers: UpdateDeviceState() and XI's SetMaskForExtEvent(). * The latter initialises masks for the matching XI events, it's a once-off * setting. * UDS however changes the mask for MotionNotify and DeviceMotionNotify each * time a button is pressed to include the matching ButtonXMotion mask in the * filter. * * @param[in] deviceid The device to modify the filter for. * @param[in] mask The new filter mask. * @param[in] event Protocol event type. */ void SetMaskForEvent(int deviceid, Mask mask, int event) { if (deviceid < 0 || deviceid >= MAXDEVICES) FatalError("SetMaskForEvent: bogus device id"); event_filters[deviceid][event] = mask; } void SetCriticalEvent(int event) { if (event >= MAXEVENTS) FatalError("SetCriticalEvent: bogus event number"); criticalEvents[event >> 3] |= 1 << (event & 7); } void ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py) { BoxRec box; int x = *px, y = *py; int incx = 1, incy = 1; if (RegionContainsPoint(shape, x, y, &box)) return; box = *RegionExtents(shape); /* this is rather crude */ do { x += incx; if (x >= box.x2) { incx = -1; x = *px - 1; } else if (x < box.x1) { incx = 1; x = *px; y += incy; if (y >= box.y2) { incy = -1; y = *py - 1; } else if (y < box.y1) return; /* should never get here! */ } } while (!RegionContainsPoint(shape, x, y, &box)); *px = x; *py = y; } static void CheckPhysLimits(DeviceIntPtr pDev, CursorPtr cursor, Bool generateEvents, Bool confineToScreen, /* unused if PanoramiX on */ ScreenPtr pScreen) /* unused if PanoramiX on */ { HotSpot new; SpritePtr pSprite = pDev->spriteInfo->sprite; if (!cursor) return; new = pSprite->hotPhys; #ifdef PANORAMIX if (!noPanoramiXExtension) /* I don't care what the DDX has to say about it */ pSprite->physLimits = pSprite->hotLimits; else #endif { if (pScreen) new.pScreen = pScreen; else pScreen = new.pScreen; (*pScreen->CursorLimits) (pDev, pScreen, cursor, &pSprite->hotLimits, &pSprite->physLimits); pSprite->confined = confineToScreen; (*pScreen->ConstrainCursor) (pDev, pScreen, &pSprite->physLimits); } /* constrain the pointer to those limits */ if (new.x < pSprite->physLimits.x1) new.x = pSprite->physLimits.x1; else if (new.x >= pSprite->physLimits.x2) new.x = pSprite->physLimits.x2 - 1; if (new.y < pSprite->physLimits.y1) new.y = pSprite->physLimits.y1; else if (new.y >= pSprite->physLimits.y2) new.y = pSprite->physLimits.y2 - 1; if (pSprite->hotShape) ConfineToShape(pDev, pSprite->hotShape, &new.x, &new.y); if (( #ifdef PANORAMIX noPanoramiXExtension && #endif (pScreen != pSprite->hotPhys.pScreen)) || (new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y)) { #ifdef PANORAMIX if (!noPanoramiXExtension) XineramaSetCursorPosition(pDev, new.x, new.y, generateEvents); else #endif { if (pScreen != pSprite->hotPhys.pScreen) pSprite->hotPhys = new; (*pScreen->SetCursorPosition) (pDev, pScreen, new.x, new.y, generateEvents); } if (!generateEvents) SyntheticMotion(pDev, new.x, new.y); } #ifdef PANORAMIX /* Tell DDX what the limits are */ if (!noPanoramiXExtension) XineramaConstrainCursor(pDev); #endif } static void CheckVirtualMotion(DeviceIntPtr pDev, QdEventPtr qe, WindowPtr pWin) { SpritePtr pSprite = pDev->spriteInfo->sprite; RegionPtr reg = NULL; DeviceEvent *ev = NULL; if (qe) { ev = &qe->event->device_event; switch (ev->type) { case ET_Motion: case ET_ButtonPress: case ET_ButtonRelease: case ET_KeyPress: case ET_KeyRelease: case ET_ProximityIn: case ET_ProximityOut: pSprite->hot.pScreen = qe->pScreen; pSprite->hot.x = ev->root_x; pSprite->hot.y = ev->root_y; pWin = pDev->deviceGrab.grab ? pDev->deviceGrab.grab-> confineTo : NullWindow; break; default: break; } } if (pWin) { BoxRec lims; #ifdef PANORAMIX if (!noPanoramiXExtension) { int x, y, off_x, off_y, i; if (!XineramaSetWindowPntrs(pDev, pWin)) return; i = PanoramiXNumScreens - 1; RegionCopy(&pSprite->Reg2, &pSprite->windows[i]->borderSize); off_x = screenInfo.screens[i]->x; off_y = screenInfo.screens[i]->y; while (i--) { x = off_x - screenInfo.screens[i]->x; y = off_y - screenInfo.screens[i]->y; if (x || y) RegionTranslate(&pSprite->Reg2, x, y); RegionUnion(&pSprite->Reg2, &pSprite->Reg2, &pSprite->windows[i]->borderSize); off_x = screenInfo.screens[i]->x; off_y = screenInfo.screens[i]->y; } } else #endif { if (pSprite->hot.pScreen != pWin->drawable.pScreen) { pSprite->hot.pScreen = pWin->drawable.pScreen; pSprite->hot.x = pSprite->hot.y = 0; } } lims = *RegionExtents(&pWin->borderSize); if (pSprite->hot.x < lims.x1) pSprite->hot.x = lims.x1; else if (pSprite->hot.x >= lims.x2) pSprite->hot.x = lims.x2 - 1; if (pSprite->hot.y < lims.y1) pSprite->hot.y = lims.y1; else if (pSprite->hot.y >= lims.y2) pSprite->hot.y = lims.y2 - 1; #ifdef PANORAMIX if (!noPanoramiXExtension) { if (RegionNumRects(&pSprite->Reg2) > 1) reg = &pSprite->Reg2; } else #endif { if (wBoundingShape(pWin)) reg = &pWin->borderSize; } if (reg) ConfineToShape(pDev, reg, &pSprite->hot.x, &pSprite->hot.y); if (qe && ev) { qe->pScreen = pSprite->hot.pScreen; ev->root_x = pSprite->hot.x; ev->root_y = pSprite->hot.y; } } #ifdef PANORAMIX if (noPanoramiXExtension) /* No typo. Only set the root win if disabled */ #endif RootWindow(pDev->spriteInfo->sprite) = pSprite->hot.pScreen->root; } static void ConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents, Bool confineToScreen) { SpritePtr pSprite = pDev->spriteInfo->sprite; if (syncEvents.playingEvents) { CheckVirtualMotion(pDev, (QdEventPtr) NULL, pWin); SyntheticMotion(pDev, pSprite->hot.x, pSprite->hot.y); } else { ScreenPtr pScreen = pWin->drawable.pScreen; #ifdef PANORAMIX if (!noPanoramiXExtension) { XineramaConfineCursorToWindow(pDev, pWin, generateEvents); return; } #endif pSprite->hotLimits = *RegionExtents(&pWin->borderSize); pSprite->hotShape = wBoundingShape(pWin) ? &pWin->borderSize : NullRegion; CheckPhysLimits(pDev, pSprite->current, generateEvents, confineToScreen, pWin->drawable.pScreen); if (*pScreen->CursorConfinedTo) (*pScreen->CursorConfinedTo) (pDev, pScreen, pWin); } } Bool PointerConfinedToScreen(DeviceIntPtr pDev) { return pDev->spriteInfo->sprite->confined; } /** * Update the sprite cursor to the given cursor. * * ChangeToCursor() will display the new cursor and free the old cursor (if * applicable). If the provided cursor is already the updated cursor, nothing * happens. */ static void ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor) { SpritePtr pSprite = pDev->spriteInfo->sprite; ScreenPtr pScreen; if (cursor != pSprite->current) { if ((pSprite->current->bits->xhot != cursor->bits->xhot) || (pSprite->current->bits->yhot != cursor->bits->yhot)) CheckPhysLimits(pDev, cursor, FALSE, pSprite->confined, (ScreenPtr) NULL); #ifdef PANORAMIX /* XXX: is this really necessary?? (whot) */ if (!noPanoramiXExtension) pScreen = pSprite->screen; else #endif pScreen = pSprite->hotPhys.pScreen; (*pScreen->DisplayCursor) (pDev, pScreen, cursor); FreeCursor(pSprite->current, (Cursor) 0); pSprite->current = RefCursor(cursor); } } /** * @returns true if b is a descendent of a */ Bool IsParent(WindowPtr a, WindowPtr b) { for (b = b->parent; b; b = b->parent) if (b == a) return TRUE; return FALSE; } /** * Update the cursor displayed on the screen. * * Called whenever a cursor may have changed shape or position. */ static void PostNewCursor(DeviceIntPtr pDev) { WindowPtr win; GrabPtr grab = pDev->deviceGrab.grab; SpritePtr pSprite = pDev->spriteInfo->sprite; CursorPtr pCursor; if (syncEvents.playingEvents) return; if (grab) { if (grab->cursor) { ChangeToCursor(pDev, grab->cursor); return; } if (IsParent(grab->window, pSprite->win)) win = pSprite->win; else win = grab->window; } else win = pSprite->win; for (; win; win = win->parent) { if (win->optional) { pCursor = WindowGetDeviceCursor(win, pDev); if (!pCursor && win->optional->cursor != NullCursor) pCursor = win->optional->cursor; if (pCursor) { ChangeToCursor(pDev, pCursor); return; } } } } /** * @param dev device which you want to know its current root window * @return root window where dev's sprite is located */ WindowPtr GetCurrentRootWindow(DeviceIntPtr dev) { return RootWindow(dev->spriteInfo->sprite); } /** * @return window underneath the cursor sprite. */ WindowPtr GetSpriteWindow(DeviceIntPtr pDev) { return pDev->spriteInfo->sprite->win; } /** * @return current sprite cursor. */ CursorPtr GetSpriteCursor(DeviceIntPtr pDev) { return pDev->spriteInfo->sprite->current; } /** * Set x/y current sprite position in screen coordinates. */ void GetSpritePosition(DeviceIntPtr pDev, int *px, int *py) { SpritePtr pSprite = pDev->spriteInfo->sprite; *px = pSprite->hotPhys.x; *py = pSprite->hotPhys.y; } #ifdef PANORAMIX int XineramaGetCursorScreen(DeviceIntPtr pDev) { if (!noPanoramiXExtension) { return pDev->spriteInfo->sprite->screen->myNum; } else { return 0; } } #endif /* PANORAMIX */ #define TIMESLOP (5 * 60 * 1000) /* 5 minutes */ static void MonthChangedOrBadTime(CARD32 *ms) { /* If the ddx/OS is careless about not processing timestamped events from * different sources in sorted order, then it's possible for time to go * backwards when it should not. Here we ensure a decent time. */ if ((currentTime.milliseconds - *ms) > TIMESLOP) currentTime.months++; else *ms = currentTime.milliseconds; } void NoticeTime(const DeviceIntPtr dev, TimeStamp time) { currentTime = time; lastDeviceEventTime[XIAllDevices].time = currentTime; lastDeviceEventTime[dev->id].time = currentTime; LastEventTimeToggleResetFlag(dev->id, TRUE); LastEventTimeToggleResetFlag(XIAllDevices, TRUE); } static void NoticeTimeMillis(const DeviceIntPtr dev, CARD32 *ms) { TimeStamp time; if (*ms < currentTime.milliseconds) MonthChangedOrBadTime(ms); time.months = currentTime.months; time.milliseconds = *ms; NoticeTime(dev, time); } void NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev) { if (!syncEvents.playingEvents) NoticeTimeMillis(dev, &ev->any.time); } TimeStamp LastEventTime(int deviceid) { return lastDeviceEventTime[deviceid].time; } Bool LastEventTimeWasReset(int deviceid) { return lastDeviceEventTime[deviceid].reset; } void LastEventTimeToggleResetFlag(int deviceid, Bool state) { lastDeviceEventTime[deviceid].reset = state; } void LastEventTimeToggleResetAll(Bool state) { DeviceIntPtr dev; nt_list_for_each_entry(dev, inputInfo.devices, next) { LastEventTimeToggleResetFlag(dev->id, FALSE); } LastEventTimeToggleResetFlag(XIAllDevices, FALSE); LastEventTimeToggleResetFlag(XIAllMasterDevices, FALSE); } /************************************************************************** * The following procedures deal with synchronous events * **************************************************************************/ /** * EnqueueEvent is a device's processInputProc if a device is frozen. * Instead of delivering the events to the client, the event is tacked onto a * linked list for later delivery. */ void EnqueueEvent(InternalEvent *ev, DeviceIntPtr device) { QdEventPtr tail = NULL; QdEventPtr qe; SpritePtr pSprite = device->spriteInfo->sprite; int eventlen; DeviceEvent *event = &ev->device_event; if (!xorg_list_is_empty(&syncEvents.pending)) tail = xorg_list_last_entry(&syncEvents.pending, QdEventRec, next); NoticeTimeMillis(device, &ev->any.time); /* Fix for key repeating bug. */ if (device->key != NULL && device->key->xkbInfo != NULL && event->type == ET_KeyRelease) AccessXCancelRepeatKey(device->key->xkbInfo, event->detail.key); if (DeviceEventCallback) { DeviceEventInfoRec eventinfo; /* The RECORD spec says that the root window field of motion events * must be valid. At this point, it hasn't been filled in yet, so * we do it here. The long expression below is necessary to get * the current root window; the apparently reasonable alternative * GetCurrentRootWindow()->drawable.id doesn't give you the right * answer on the first motion event after a screen change because * the data that GetCurrentRootWindow relies on hasn't been * updated yet. */ if (ev->any.type == ET_Motion) ev->device_event.root = pSprite->hotPhys.pScreen->root->drawable.id; eventinfo.event = ev; eventinfo.device = device; CallCallbacks(&DeviceEventCallback, (void *) &eventinfo); } if (event->type == ET_Motion) { #ifdef PANORAMIX if (!noPanoramiXExtension) { event->root_x += pSprite->screen->x - screenInfo.screens[0]->x; event->root_y += pSprite->screen->y - screenInfo.screens[0]->y; } #endif pSprite->hotPhys.x = event->root_x; pSprite->hotPhys.y = event->root_y; /* do motion compression, but not if from different devices */ if (tail && (tail->event->any.type == ET_Motion) && (tail->device == device) && (tail->pScreen == pSprite->hotPhys.pScreen)) { DeviceEvent *tailev = &tail->event->device_event; tailev->root_x = pSprite->hotPhys.x; tailev->root_y = pSprite->hotPhys.y; tailev->time = event->time; tail->months = currentTime.months; return; } } eventlen = event->length; qe = malloc(sizeof(QdEventRec) + eventlen); if (!qe) return; xorg_list_init(&qe->next); qe->device = device; qe->pScreen = pSprite->hotPhys.pScreen; qe->months = currentTime.months; qe->event = (InternalEvent *) (qe + 1); memcpy(qe->event, event, eventlen); xorg_list_append(&qe->next, &syncEvents.pending); } /** * Run through the list of events queued up in syncEvents. * For each event do: * If the device for this event is not frozen anymore, take it and process it * as usually. * After that, check if there's any devices in the list that are not frozen. * If there is none, we're done. If there is at least one device that is not * frozen, then re-run from the beginning of the event queue. */ void PlayReleasedEvents(void) { QdEventPtr tmp; QdEventPtr qe; DeviceIntPtr dev; DeviceIntPtr pDev; restart: xorg_list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next) { if (!qe->device->deviceGrab.sync.frozen) { xorg_list_del(&qe->next); pDev = qe->device; if (qe->event->any.type == ET_Motion) CheckVirtualMotion(pDev, qe, NullWindow); syncEvents.time.months = qe->months; syncEvents.time.milliseconds = qe->event->any.time; #ifdef PANORAMIX /* Translate back to the sprite screen since processInputProc will translate from sprite screen to screen 0 upon reentry to the DIX layer */ if (!noPanoramiXExtension) { DeviceEvent *ev = &qe->event->device_event; switch (ev->type) { case ET_Motion: case ET_ButtonPress: case ET_ButtonRelease: case ET_KeyPress: case ET_KeyRelease: case ET_ProximityIn: case ET_ProximityOut: case ET_TouchBegin: case ET_TouchUpdate: case ET_TouchEnd: ev->root_x += screenInfo.screens[0]->x - pDev->spriteInfo->sprite->screen->x; ev->root_y += screenInfo.screens[0]->y - pDev->spriteInfo->sprite->screen->y; break; default: break; } } #endif (*qe->device->public.processInputProc) (qe->event, qe->device); free(qe); for (dev = inputInfo.devices; dev && dev->deviceGrab.sync.frozen; dev = dev->next); if (!dev) break; /* Playing the event may have unfrozen another device. */ /* So to play it safe, restart at the head of the queue */ goto restart; } } } /** * Freeze or thaw the given devices. The device's processing proc is * switched to either the real processing proc (in case of thawing) or an * enqueuing processing proc (usually EnqueueEvent()). * * @param dev The device to freeze/thaw * @param frozen True to freeze or false to thaw. */ static void FreezeThaw(DeviceIntPtr dev, Bool frozen) { dev->deviceGrab.sync.frozen = frozen; if (frozen) dev->public.processInputProc = dev->public.enqueueInputProc; else dev->public.processInputProc = dev->public.realInputProc; } /** * Unfreeze devices and replay all events to the respective clients. * * ComputeFreezes takes the first event in the device's frozen event queue. It * runs up the sprite tree (spriteTrace) and searches for the window to replay * the events from. If it is found, it checks for passive grabs one down from * the window or delivers the events. */ static void ComputeFreezes(void) { DeviceIntPtr replayDev = syncEvents.replayDev; WindowPtr w; GrabPtr grab; DeviceIntPtr dev; for (dev = inputInfo.devices; dev; dev = dev->next) FreezeThaw(dev, dev->deviceGrab.sync.other || (dev->deviceGrab.sync.state >= FROZEN)); if (syncEvents.playingEvents || (!replayDev && xorg_list_is_empty(&syncEvents.pending))) return; syncEvents.playingEvents = TRUE; if (replayDev) { DeviceEvent *event = replayDev->deviceGrab.sync.event; syncEvents.replayDev = (DeviceIntPtr) NULL; w = XYToWindow(replayDev->spriteInfo->sprite, event->root_x, event->root_y); if (!CheckDeviceGrabs(replayDev, event, syncEvents.replayWin)) { if (IsTouchEvent((InternalEvent *) event)) { TouchPointInfoPtr ti = TouchFindByClientID(replayDev, event->touchid); BUG_WARN(!ti); TouchListenerAcceptReject(replayDev, ti, 0, XIRejectTouch); } else if (replayDev->focus && !IsPointerEvent((InternalEvent *) event)) DeliverFocusedEvent(replayDev, (InternalEvent *) event, w); else DeliverDeviceEvents(w, (InternalEvent *) event, NullGrab, NullWindow, replayDev); } } for (dev = inputInfo.devices; dev; dev = dev->next) { if (!dev->deviceGrab.sync.frozen) { PlayReleasedEvents(); break; } } syncEvents.playingEvents = FALSE; for (dev = inputInfo.devices; dev; dev = dev->next) { if (DevHasCursor(dev)) { /* the following may have been skipped during replay, so do it now */ if ((grab = dev->deviceGrab.grab) && grab->confineTo) { if (grab->confineTo->drawable.pScreen != dev->spriteInfo->sprite->hotPhys.pScreen) dev->spriteInfo->sprite->hotPhys.x = dev->spriteInfo->sprite->hotPhys.y = 0; ConfineCursorToWindow(dev, grab->confineTo, TRUE, TRUE); } else ConfineCursorToWindow(dev, dev->spriteInfo->sprite->hotPhys.pScreen-> root, TRUE, FALSE); PostNewCursor(dev); } } } #ifdef RANDR void ScreenRestructured(ScreenPtr pScreen) { GrabPtr grab; DeviceIntPtr pDev; for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { if (!IsFloating(pDev) && !DevHasCursor(pDev)) continue; /* GrabDevice doesn't have a confineTo field, so we don't need to * worry about it. */ if ((grab = pDev->deviceGrab.grab) && grab->confineTo) { if (grab->confineTo->drawable.pScreen != pDev->spriteInfo->sprite->hotPhys.pScreen) pDev->spriteInfo->sprite->hotPhys.x = pDev->spriteInfo->sprite->hotPhys.y = 0; ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE); } else ConfineCursorToWindow(pDev, pDev->spriteInfo->sprite->hotPhys.pScreen-> root, TRUE, FALSE); } } #endif static void CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode) { GrabPtr grab = thisDev->deviceGrab.grab; DeviceIntPtr dev; if (thisMode == GrabModeSync) thisDev->deviceGrab.sync.state = FROZEN_NO_EVENT; else { /* free both if same client owns both */ thisDev->deviceGrab.sync.state = THAWED; if (thisDev->deviceGrab.sync.other && (CLIENT_BITS(thisDev->deviceGrab.sync.other->resource) == CLIENT_BITS(grab->resource))) thisDev->deviceGrab.sync.other = NullGrab; } if (IsMaster(thisDev)) { dev = GetPairedDevice(thisDev); if (otherMode == GrabModeSync) dev->deviceGrab.sync.other = grab; else { /* free both if same client owns both */ if (dev->deviceGrab.sync.other && (CLIENT_BITS(dev->deviceGrab.sync.other->resource) == CLIENT_BITS(grab->resource))) dev->deviceGrab.sync.other = NullGrab; } } ComputeFreezes(); } /** * Save the device's master device id. This needs to be done * if a client directly grabs a slave device that is attached to a master. For * the duration of the grab, the device is detached, ungrabbing re-attaches it * though. * * We store the ID of the master device only in case the master disappears * while the device has a grab. */ static void DetachFromMaster(DeviceIntPtr dev) { if (IsFloating(dev)) return; dev->saved_master_id = GetMaster(dev, MASTER_ATTACHED)->id; AttachDevice(NULL, dev, NULL); } static void ReattachToOldMaster(DeviceIntPtr dev) { DeviceIntPtr master = NULL; if (IsMaster(dev)) return; dixLookupDevice(&master, dev->saved_master_id, serverClient, DixUseAccess); if (master) { AttachDevice(serverClient, dev, master); dev->saved_master_id = 0; } } /** * Update touch records when an explicit grab is activated. Any touches owned by * the grabbing client are updated so the listener state reflects the new grab. */ static void UpdateTouchesForGrab(DeviceIntPtr mouse) { int i; if (!mouse->touch || mouse->deviceGrab.fromPassiveGrab) return; for (i = 0; i < mouse->touch->num_touches; i++) { TouchPointInfoPtr ti = mouse->touch->touches + i; TouchListener *listener = &ti->listeners[0]; GrabPtr grab = mouse->deviceGrab.grab; if (ti->active && CLIENT_BITS(listener->listener) == grab->resource) { listener->listener = grab->resource; listener->level = grab->grabtype; listener->state = LISTENER_IS_OWNER; listener->window = grab->window; if (grab->grabtype == CORE || grab->grabtype == XI || !xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin)) listener->type = LISTENER_POINTER_GRAB; else listener->type = LISTENER_GRAB; if (listener->grab) FreeGrab(listener->grab); listener->grab = AllocGrab(grab); } } } /** * Activate a pointer grab on the given device. A pointer grab will cause all * core pointer events of this device to be delivered to the grabbing client only. * No other device will send core events to the grab client while the grab is * on, but core events will be sent to other clients. * Can cause the cursor to change if a grab cursor is set. * * Note that parameter autoGrab may be (True & ImplicitGrabMask) if the grab * is an implicit grab caused by a ButtonPress event. * * @param mouse The device to grab. * @param grab The grab structure, needs to be setup. * @param autoGrab True if the grab was caused by a button down event and not * explicitely by a client. */ void ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, TimeStamp time, Bool autoGrab) { GrabInfoPtr grabinfo = &mouse->deviceGrab; GrabPtr oldgrab = grabinfo->grab; WindowPtr oldWin = (grabinfo->grab) ? grabinfo->grab->window : mouse->spriteInfo->sprite->win; Bool isPassive = autoGrab & ~ImplicitGrabMask; /* slave devices need to float for the duration of the grab. */ if (grab->grabtype == XI2 && !(autoGrab & ImplicitGrabMask) && !IsMaster(mouse)) DetachFromMaster(mouse); if (grab->confineTo) { if (grab->confineTo->drawable.pScreen != mouse->spriteInfo->sprite->hotPhys.pScreen) mouse->spriteInfo->sprite->hotPhys.x = mouse->spriteInfo->sprite->hotPhys.y = 0; ConfineCursorToWindow(mouse, grab->confineTo, FALSE, TRUE); } if (! (grabinfo->grab && oldWin == grabinfo->grab->window && oldWin == grab->window)) DoEnterLeaveEvents(mouse, mouse->id, oldWin, grab->window, NotifyGrab); mouse->valuator->motionHintWindow = NullWindow; if (syncEvents.playingEvents) grabinfo->grabTime = syncEvents.time; else grabinfo->grabTime = time; grabinfo->grab = AllocGrab(grab); grabinfo->fromPassiveGrab = isPassive; grabinfo->implicitGrab = autoGrab & ImplicitGrabMask; PostNewCursor(mouse); UpdateTouchesForGrab(mouse); CheckGrabForSyncs(mouse, (Bool) grab->pointerMode, (Bool) grab->keyboardMode); if (oldgrab) FreeGrab(oldgrab); } /** * Delete grab on given device, update the sprite. * * Extension devices are set up for ActivateKeyboardGrab(). */ void DeactivatePointerGrab(DeviceIntPtr mouse) { GrabPtr grab = mouse->deviceGrab.grab; DeviceIntPtr dev; Bool wasPassive = mouse->deviceGrab.fromPassiveGrab; Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab && mouse->deviceGrab.implicitGrab); XID grab_resource = grab->resource; int i; /* If an explicit grab was deactivated, we must remove it from the head of * all the touches' listener lists. */ for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) { TouchPointInfoPtr ti = mouse->touch->touches + i; if (ti->active && TouchResourceIsOwner(ti, grab_resource)) { int mode = XIRejectTouch; /* Rejecting will generate a TouchEnd, but we must not emulate a ButtonRelease here. So pretend the listener already has the end event */ if (grab->grabtype == CORE || grab->grabtype == XI || !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin)) { mode = XIAcceptTouch; /* NOTE: we set the state here, but * ProcessTouchOwnershipEvent() will still call * TouchEmitTouchEnd for this listener. The other half of * this hack is in DeliverTouchEndEvent */ ti->listeners[0].state = LISTENER_HAS_END; } TouchListenerAcceptReject(mouse, ti, 0, mode); } } TouchRemovePointerGrab(mouse); mouse->valuator->motionHintWindow = NullWindow; mouse->deviceGrab.grab = NullGrab; mouse->deviceGrab.sync.state = NOT_GRABBED; mouse->deviceGrab.fromPassiveGrab = FALSE; for (dev = inputInfo.devices; dev; dev = dev->next) { if (dev->deviceGrab.sync.other == grab) dev->deviceGrab.sync.other = NullGrab; } DoEnterLeaveEvents(mouse, mouse->id, grab->window, mouse->spriteInfo->sprite->win, NotifyUngrab); if (grab->confineTo) ConfineCursorToWindow(mouse, GetCurrentRootWindow(mouse), FALSE, FALSE); PostNewCursor(mouse); if (!wasImplicit && grab->grabtype == XI2) ReattachToOldMaster(mouse); ComputeFreezes(); FreeGrab(grab); } /** * Activate a keyboard grab on the given device. * * Extension devices have ActivateKeyboardGrab() set as their grabbing proc. */ void ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive) { GrabInfoPtr grabinfo = &keybd->deviceGrab; GrabPtr oldgrab = grabinfo->grab; WindowPtr oldWin; /* slave devices need to float for the duration of the grab. */ if (grab->grabtype == XI2 && keybd->enabled && !(passive & ImplicitGrabMask) && !IsMaster(keybd)) DetachFromMaster(keybd); if (!keybd->enabled) oldWin = NULL; else if (grabinfo->grab) oldWin = grabinfo->grab->window; else if (keybd->focus) oldWin = keybd->focus->win; else oldWin = keybd->spriteInfo->sprite->win; if (oldWin == FollowKeyboardWin) oldWin = keybd->focus->win; if (keybd->valuator) keybd->valuator->motionHintWindow = NullWindow; if (oldWin && ! (grabinfo->grab && oldWin == grabinfo->grab->window && oldWin == grab->window)) DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab); if (syncEvents.playingEvents) grabinfo->grabTime = syncEvents.time; else grabinfo->grabTime = time; grabinfo->grab = AllocGrab(grab); grabinfo->fromPassiveGrab = passive; grabinfo->implicitGrab = passive & ImplicitGrabMask; CheckGrabForSyncs(keybd, (Bool) grab->keyboardMode, (Bool) grab->pointerMode); if (oldgrab) FreeGrab(oldgrab); } /** * Delete keyboard grab for the given device. */ void DeactivateKeyboardGrab(DeviceIntPtr keybd) { GrabPtr grab = keybd->deviceGrab.grab; DeviceIntPtr dev; WindowPtr focusWin; Bool wasImplicit = (keybd->deviceGrab.fromPassiveGrab && keybd->deviceGrab.implicitGrab); if (keybd->valuator) keybd->valuator->motionHintWindow = NullWindow; keybd->deviceGrab.grab = NullGrab; keybd->deviceGrab.sync.state = NOT_GRABBED; keybd->deviceGrab.fromPassiveGrab = FALSE; for (dev = inputInfo.devices; dev; dev = dev->next) { if (dev->deviceGrab.sync.other == grab) dev->deviceGrab.sync.other = NullGrab; } if (keybd->focus) focusWin = keybd->focus->win; else if (keybd->spriteInfo->sprite) focusWin = keybd->spriteInfo->sprite->win; else focusWin = NullWindow; if (focusWin == FollowKeyboardWin) focusWin = inputInfo.keyboard->focus->win; DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab); if (!wasImplicit && grab->grabtype == XI2) ReattachToOldMaster(keybd); ComputeFreezes(); FreeGrab(grab); } void AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState) { Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced; TimeStamp grabTime; DeviceIntPtr dev; GrabInfoPtr devgrabinfo, grabinfo = &thisDev->deviceGrab; thisGrabbed = grabinfo->grab && SameClient(grabinfo->grab, client); thisSynced = FALSE; otherGrabbed = FALSE; othersFrozen = FALSE; grabTime = grabinfo->grabTime; for (dev = inputInfo.devices; dev; dev = dev->next) { devgrabinfo = &dev->deviceGrab; if (dev == thisDev) continue; if (devgrabinfo->grab && SameClient(devgrabinfo->grab, client)) { if (!(thisGrabbed || otherGrabbed) || (CompareTimeStamps(devgrabinfo->grabTime, grabTime) == LATER)) grabTime = devgrabinfo->grabTime; otherGrabbed = TRUE; if (grabinfo->sync.other == devgrabinfo->grab) thisSynced = TRUE; if (devgrabinfo->sync.state >= FROZEN) othersFrozen = TRUE; } } if (!((thisGrabbed && grabinfo->sync.state >= FROZEN) || thisSynced)) return; if ((CompareTimeStamps(time, currentTime) == LATER) || (CompareTimeStamps(time, grabTime) == EARLIER)) return; switch (newState) { case THAWED: /* Async */ if (thisGrabbed) grabinfo->sync.state = THAWED; if (thisSynced) grabinfo->sync.other = NullGrab; ComputeFreezes(); break; case FREEZE_NEXT_EVENT: /* Sync */ if (thisGrabbed) { grabinfo->sync.state = FREEZE_NEXT_EVENT; if (thisSynced) grabinfo->sync.other = NullGrab; ComputeFreezes(); } break; case THAWED_BOTH: /* AsyncBoth */ if (othersFrozen) { for (dev = inputInfo.devices; dev; dev = dev->next) { devgrabinfo = &dev->deviceGrab; if (devgrabinfo->grab && SameClient(devgrabinfo->grab, client)) devgrabinfo->sync.state = THAWED; if (devgrabinfo->sync.other && SameClient(devgrabinfo->sync.other, client)) devgrabinfo->sync.other = NullGrab; } ComputeFreezes(); } break; case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */ if (othersFrozen) { for (dev = inputInfo.devices; dev; dev = dev->next) { devgrabinfo = &dev->deviceGrab; if (devgrabinfo->grab && SameClient(devgrabinfo->grab, client)) devgrabinfo->sync.state = FREEZE_BOTH_NEXT_EVENT; if (devgrabinfo->sync.other && SameClient(devgrabinfo->sync.other, client)) devgrabinfo->sync.other = NullGrab; } ComputeFreezes(); } break; case NOT_GRABBED: /* Replay */ if (thisGrabbed && grabinfo->sync.state == FROZEN_WITH_EVENT) { if (thisSynced) grabinfo->sync.other = NullGrab; syncEvents.replayDev = thisDev; syncEvents.replayWin = grabinfo->grab->window; (*grabinfo->DeactivateGrab) (thisDev); syncEvents.replayDev = (DeviceIntPtr) NULL; } break; case THAW_OTHERS: /* AsyncOthers */ if (othersFrozen) { for (dev = inputInfo.devices; dev; dev = dev->next) { if (dev == thisDev) continue; devgrabinfo = &dev->deviceGrab; if (devgrabinfo->grab && SameClient(devgrabinfo->grab, client)) devgrabinfo->sync.state = THAWED; if (devgrabinfo->sync.other && SameClient(devgrabinfo->sync.other, client)) devgrabinfo->sync.other = NullGrab; } ComputeFreezes(); } break; } /* We've unfrozen the grab. If the grab was a touch grab, we're now the * owner and expected to accept/reject it. Reject == ReplayPointer which * we've handled in ComputeFreezes() (during DeactivateGrab) above, * anything else is accept. */ if (newState != NOT_GRABBED /* Replay */ && IsTouchEvent((InternalEvent*)grabinfo->sync.event)) { TouchAcceptAndEnd(thisDev, grabinfo->sync.event->touchid); } } /** * Server-side protocol handling for AllowEvents request. * * Release some events from a frozen device. */ int ProcAllowEvents(ClientPtr client) { TimeStamp time; DeviceIntPtr mouse = NULL; DeviceIntPtr keybd = NULL; REQUEST(xAllowEventsReq); REQUEST_SIZE_MATCH(xAllowEventsReq); UpdateCurrentTime(); time = ClientTimeToServerTime(stuff->time); mouse = PickPointer(client); keybd = PickKeyboard(client); switch (stuff->mode) { case ReplayPointer: AllowSome(client, time, mouse, NOT_GRABBED); break; case SyncPointer: AllowSome(client, time, mouse, FREEZE_NEXT_EVENT); break; case AsyncPointer: AllowSome(client, time, mouse, THAWED); break; case ReplayKeyboard: AllowSome(client, time, keybd, NOT_GRABBED); break; case SyncKeyboard: AllowSome(client, time, keybd, FREEZE_NEXT_EVENT); break; case AsyncKeyboard: AllowSome(client, time, keybd, THAWED); break; case SyncBoth: AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT); break; case AsyncBoth: AllowSome(client, time, keybd, THAWED_BOTH); break; default: client->errorValue = stuff->mode; return BadValue; } return Success; } /** * Deactivate grabs from any device that has been grabbed by the client. */ void ReleaseActiveGrabs(ClientPtr client) { DeviceIntPtr dev; Bool done; /* XXX CloseDownClient should remove passive grabs before * releasing active grabs. */ do { done = TRUE; for (dev = inputInfo.devices; dev; dev = dev->next) { if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client)) { (*dev->deviceGrab.DeactivateGrab) (dev); done = FALSE; } } } while (!done); } /************************************************************************** * The following procedures deal with delivering events * **************************************************************************/ /** * Deliver the given events to the given client. * * More than one event may be delivered at a time. This is the case with * DeviceMotionNotifies which may be followed by DeviceValuator events. * * TryClientEvents() is the last station before actually writing the events to * the socket. Anything that is not filtered here, will get delivered to the * client. * An event is only delivered if * - mask and filter match up. * - no other client has a grab on the device that caused the event. * * * @param client The target client to deliver to. * @param dev The device the event came from. May be NULL. * @param pEvents The events to be delivered. * @param count Number of elements in pEvents. * @param mask Event mask as set by the window. * @param filter Mask based on event type. * @param grab Possible grab on the device that caused the event. * * @return 1 if event was delivered, 0 if not or -1 if grab was not set by the * client. */ int TryClientEvents(ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, int count, Mask mask, Mask filter, GrabPtr grab) { int type; #ifdef DEBUG_EVENTS ErrorF("[dix] Event([%d, %d], mask=0x%lx), client=%d%s", pEvents->u.u.type, pEvents->u.u.detail, mask, client ? client->index : -1, (client && client->clientGone) ? " (gone)" : ""); #endif if (!client || client == serverClient || client->clientGone) { #ifdef DEBUG_EVENTS ErrorF(" not delivered to fake/dead client\n"); #endif return 0; } if (filter != CantBeFiltered && !(mask & filter)) { #ifdef DEBUG_EVENTS ErrorF(" filtered\n"); #endif return 0; } if (grab && !SameClient(grab, client)) { #ifdef DEBUG_EVENTS ErrorF(" not delivered due to grab\n"); #endif return -1; /* don't send, but notify caller */ } type = pEvents->u.u.type; if (type == MotionNotify) { if (mask & PointerMotionHintMask) { if (WID(dev->valuator->motionHintWindow) == pEvents->u.keyButtonPointer.event) { #ifdef DEBUG_EVENTS ErrorF("[dix] \n"); ErrorF("[dix] motionHintWindow == keyButtonPointer.event\n"); #endif return 1; /* don't send, but pretend we did */ } pEvents->u.u.detail = NotifyHint; } else { pEvents->u.u.detail = NotifyNormal; } } else if (type == DeviceMotionNotify) { if (MaybeSendDeviceMotionNotifyHint((deviceKeyButtonPointer *) pEvents, mask) != 0) return 1; } else if (type == KeyPress) { if (EventIsKeyRepeat(pEvents)) { if (!_XkbWantsDetectableAutoRepeat(client)) { xEvent release = *pEvents; release.u.u.type = KeyRelease; WriteEventsToClient(client, 1, &release); #ifdef DEBUG_EVENTS ErrorF(" (plus fake core release for repeat)"); #endif } else { #ifdef DEBUG_EVENTS ErrorF(" (detectable autorepeat for core)"); #endif } } } else if (type == DeviceKeyPress) { if (EventIsKeyRepeat(pEvents)) { if (!_XkbWantsDetectableAutoRepeat(client)) { deviceKeyButtonPointer release = *(deviceKeyButtonPointer *) pEvents; release.type = DeviceKeyRelease; #ifdef DEBUG_EVENTS ErrorF(" (plus fake xi1 release for repeat)"); #endif WriteEventsToClient(client, 1, (xEvent *) &release); } else { #ifdef DEBUG_EVENTS ErrorF(" (detectable autorepeat for core)"); #endif } } } if (BitIsOn(criticalEvents, type)) { if (client->smart_priority < SMART_MAX_PRIORITY) client->smart_priority++; SetCriticalOutputPending(); } WriteEventsToClient(client, count, pEvents); #ifdef DEBUG_EVENTS ErrorF("[dix] delivered\n"); #endif return 1; } static BOOL ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win, xEvent *event, Mask deliveryMask) { GrabPtr tempGrab; OtherInputMasks *inputMasks; CARD8 type = event->u.u.type; enum InputLevel grabtype; if (type == ButtonPress) grabtype = CORE; else if (type == DeviceButtonPress) grabtype = XI; else if ((type = xi2_get_type(event)) == XI_ButtonPress) grabtype = XI2; else return FALSE; tempGrab = AllocGrab(NULL); if (!tempGrab) return FALSE; tempGrab->next = NULL; tempGrab->device = dev; tempGrab->resource = client->clientAsMask; tempGrab->window = win; tempGrab->ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE; tempGrab->eventMask = deliveryMask; tempGrab->keyboardMode = GrabModeAsync; tempGrab->pointerMode = GrabModeAsync; tempGrab->confineTo = NullWindow; tempGrab->cursor = NullCursor; tempGrab->type = type; tempGrab->grabtype = grabtype; /* get the XI and XI2 device mask */ inputMasks = wOtherInputMasks(win); tempGrab->deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id] : 0; if (inputMasks) xi2mask_merge(tempGrab->xi2mask, inputMasks->xi2mask); (*dev->deviceGrab.ActivateGrab) (dev, tempGrab, currentTime, TRUE | ImplicitGrabMask); FreeGrab(tempGrab); return TRUE; } /** * Attempt event delivery to the client owning the window. */ static enum EventDeliveryState DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win, xEvent *events, int count, Mask filter, GrabPtr grab) { /* if nobody ever wants to see this event, skip some work */ if (filter != CantBeFiltered && !((wOtherEventMasks(win) | win->eventMask) & filter)) return EVENT_SKIP; if (IsInterferingGrab(wClient(win), dev, events)) return EVENT_SKIP; if (!XaceHook(XACE_RECEIVE_ACCESS, wClient(win), win, events, count)) { int attempt = TryClientEvents(wClient(win), dev, events, count, win->eventMask, filter, grab); if (attempt > 0) return EVENT_DELIVERED; if (attempt < 0) return EVENT_REJECTED; } return EVENT_NOT_DELIVERED; } /** * Get the list of clients that should be tried for event delivery on the * given window. * * @return 1 if the client list should be traversed, zero if the event * should be skipped. */ static Bool GetClientsForDelivery(DeviceIntPtr dev, WindowPtr win, xEvent *events, Mask filter, InputClients ** iclients) { int rc = 0; if (core_get_type(events) != 0) *iclients = (InputClients *) wOtherClients(win); else if (xi2_get_type(events) != 0) { OtherInputMasks *inputMasks = wOtherInputMasks(win); /* Has any client selected for the event? */ if (!WindowXI2MaskIsset(dev, win, events)) goto out; *iclients = inputMasks->inputClients; } else { OtherInputMasks *inputMasks = wOtherInputMasks(win); /* Has any client selected for the event? */ if (!inputMasks || !(inputMasks->inputEvents[dev->id] & filter)) goto out; *iclients = inputMasks->inputClients; } rc = 1; out: return rc; } /** * Try delivery on each client in inputclients, provided the event mask * accepts it and there is no interfering core grab.. */ static enum EventDeliveryState DeliverEventToInputClients(DeviceIntPtr dev, InputClients * inputclients, WindowPtr win, xEvent *events, int count, Mask filter, GrabPtr grab, ClientPtr *client_return, Mask *mask_return) { int attempt; enum EventDeliveryState rc = EVENT_NOT_DELIVERED; Bool have_device_button_grab_class_client = FALSE; for (; inputclients; inputclients = inputclients->next) { Mask mask; ClientPtr client = rClient(inputclients); if (IsInterferingGrab(client, dev, events)) continue; if (IsWrongPointerBarrierClient(client, dev, events)) continue; mask = GetEventMask(dev, events, inputclients); if (XaceHook(XACE_RECEIVE_ACCESS, client, win, events, count)) /* do nothing */ ; else if ((attempt = TryClientEvents(client, dev, events, count, mask, filter, grab))) { if (attempt > 0) { /* * The order of clients is arbitrary therefore if one * client belongs to DeviceButtonGrabClass make sure to * catch it. */ if (!have_device_button_grab_class_client) { rc = EVENT_DELIVERED; *client_return = client; *mask_return = mask; /* Success overrides non-success, so if we've been * successful on one client, return that */ if (mask & DeviceButtonGrabMask) have_device_button_grab_class_client = TRUE; } } else if (rc == EVENT_NOT_DELIVERED) rc = EVENT_REJECTED; } } return rc; } /** * Deliver events to clients registered on the window. * * @param client_return On successful delivery, set to the recipient. * @param mask_return On successful delivery, set to the recipient's event * mask for this event. */ static enum EventDeliveryState DeliverEventToWindowMask(DeviceIntPtr dev, WindowPtr win, xEvent *events, int count, Mask filter, GrabPtr grab, ClientPtr *client_return, Mask *mask_return) { InputClients *iclients; if (!GetClientsForDelivery(dev, win, events, filter, &iclients)) return EVENT_SKIP; return DeliverEventToInputClients(dev, iclients, win, events, count, filter, grab, client_return, mask_return); } /** * Deliver events to a window. At this point, we do not yet know if the event * actually needs to be delivered. May activate a grab if the event is a * button press. * * Core events are always delivered to the window owner. If the filter is * something other than CantBeFiltered, the event is also delivered to other * clients with the matching mask on the window. * * More than one event may be delivered at a time. This is the case with * DeviceMotionNotifies which may be followed by DeviceValuator events. * * @param pWin The window that would get the event. * @param pEvents The events to be delivered. * @param count Number of elements in pEvents. * @param filter Mask based on event type. * @param grab Possible grab on the device that caused the event. * * @return a positive number if at least one successful delivery has been * made, 0 if no events were delivered, or a negative number if the event * has not been delivered _and_ rejected by at least one client. */ int DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent *pEvents, int count, Mask filter, GrabPtr grab) { int deliveries = 0, nondeliveries = 0; ClientPtr client = NullClient; Mask deliveryMask = 0; /* If a grab occurs due to a button press, then this mask is the mask of the grab. */ int type = pEvents->u.u.type; /* Deliver to window owner */ if ((filter == CantBeFiltered) || core_get_type(pEvents) != 0) { enum EventDeliveryState rc; rc = DeliverToWindowOwner(pDev, pWin, pEvents, count, filter, grab); switch (rc) { case EVENT_SKIP: return 0; case EVENT_REJECTED: nondeliveries--; break; case EVENT_DELIVERED: /* We delivered to the owner, with our event mask */ deliveries++; client = wClient(pWin); deliveryMask = pWin->eventMask; break; case EVENT_NOT_DELIVERED: break; } } /* CantBeFiltered means only window owner gets the event */ if (filter != CantBeFiltered) { enum EventDeliveryState rc; rc = DeliverEventToWindowMask(pDev, pWin, pEvents, count, filter, grab, &client, &deliveryMask); switch (rc) { case EVENT_SKIP: return 0; case EVENT_REJECTED: nondeliveries--; break; case EVENT_DELIVERED: deliveries++; break; case EVENT_NOT_DELIVERED: break; } } if (deliveries) { /* * Note that since core events are delivered first, an implicit grab may * be activated on a core grab, stopping the XI events. */ if (!grab && ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask)) /* grab activated */ ; else if (type == MotionNotify) pDev->valuator->motionHintWindow = pWin; else if (type == DeviceMotionNotify || type == DeviceButtonPress) CheckDeviceGrabAndHintWindow(pWin, type, (deviceKeyButtonPointer *) pEvents, grab, client, deliveryMask); return deliveries; } return nondeliveries; } /** * Filter out raw events for XI 2.0 and XI 2.1 clients. * * If there is a grab on the device, 2.0 clients only get raw events if they * have the grab. 2.1+ clients get raw events in all cases. * * @return TRUE if the event should be discarded, FALSE otherwise. */ static BOOL FilterRawEvents(const ClientPtr client, const GrabPtr grab, WindowPtr root) { XIClientPtr client_xi_version; int cmp; /* device not grabbed -> don't filter */ if (!grab) return FALSE; client_xi_version = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); cmp = version_compare(client_xi_version->major_version, client_xi_version->minor_version, 2, 0); /* XI 2.0: if device is grabbed, skip XI 2.1: if device is grabbed by us, skip, we've already delivered */ if (cmp == 0) return TRUE; return (grab->window != root) ? FALSE : SameClient(grab, client); } /** * Deliver a raw event to the grab owner (if any) and to all root windows. * * Raw event delivery differs between XI 2.0 and XI 2.1. * XI 2.0: events delivered to the grabbing client (if any) OR to all root * windows * XI 2.1: events delivered to all root windows, regardless of grabbing * state. */ void DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) { GrabPtr grab = device->deviceGrab.grab; xEvent *xi; int i, rc; int filter; rc = EventToXI2((InternalEvent *) ev, (xEvent **) &xi); if (rc != Success) { ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n", __func__, device->name, rc); return; } if (grab) DeliverGrabbedEvent((InternalEvent *) ev, device, FALSE); filter = GetEventFilter(device, xi); for (i = 0; i < screenInfo.numScreens; i++) { WindowPtr root; InputClients *inputclients; root = screenInfo.screens[i]->root; if (!GetClientsForDelivery(device, root, xi, filter, &inputclients)) continue; for (; inputclients; inputclients = inputclients->next) { ClientPtr c; /* unused */ Mask m; /* unused */ InputClients ic = *inputclients; /* Because we run through the list manually, copy the actual * list, shorten the copy to only have one client and then pass * that down to DeliverEventToInputClients. This way we avoid * double events on XI 2.1 clients that have a grab on the * device. */ ic.next = NULL; if (!FilterRawEvents(rClient(&ic), grab, root)) DeliverEventToInputClients(device, &ic, root, xi, 1, filter, NULL, &c, &m); } } free(xi); } /* If the event goes to dontClient, don't send it and return 0. if send works, return 1 or if send didn't work, return 2. Only works for core events. */ #ifdef PANORAMIX static int XineramaTryClientEventsResult(ClientPtr client, GrabPtr grab, Mask mask, Mask filter) { if ((client) && (client != serverClient) && (!client->clientGone) && ((filter == CantBeFiltered) || (mask & filter))) { if (grab && !SameClient(grab, client)) return -1; else return 1; } return 0; } #endif /** * Try to deliver events to the interested parties. * * @param pWin The window that would get the event. * @param pEvents The events to be delivered. * @param count Number of elements in pEvents. * @param filter Mask based on event type. * @param dontClient Don't deliver to the dontClient. */ int MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents, int count, Mask filter, ClientPtr dontClient) { OtherClients *other; if (pWin->eventMask & filter) { if (wClient(pWin) == dontClient) return 0; #ifdef PANORAMIX if (!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return XineramaTryClientEventsResult(wClient(pWin), NullGrab, pWin->eventMask, filter); #endif if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count)) return 1; /* don't send, but pretend we did */ return TryClientEvents(wClient(pWin), NULL, pEvents, count, pWin->eventMask, filter, NullGrab); } for (other = wOtherClients(pWin); other; other = other->next) { if (other->mask & filter) { if (SameClient(other, dontClient)) return 0; #ifdef PANORAMIX if (!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return XineramaTryClientEventsResult(rClient(other), NullGrab, other->mask, filter); #endif if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, pEvents, count)) return 1; /* don't send, but pretend we did */ return TryClientEvents(rClient(other), NULL, pEvents, count, other->mask, filter, NullGrab); } } return 2; } static Window FindChildForEvent(SpritePtr pSprite, WindowPtr event) { WindowPtr w = DeepestSpriteWin(pSprite); Window child = None; /* If the search ends up past the root should the child field be set to none or should the value in the argument be passed through. It probably doesn't matter since everyone calls this function with child == None anyway. */ while (w) { /* If the source window is same as event window, child should be none. Don't bother going all all the way back to the root. */ if (w == event) { child = None; break; } if (w->parent == event) { child = w->drawable.id; break; } w = w->parent; } return child; } /** * Adjust event fields to comply with the window properties. * * @param xE Event to be modified in place * @param pWin The window to get the information from. * @param child Child window setting for event (if applicable) * @param calcChild If True, calculate the child window. */ void FixUpEventFromWindow(SpritePtr pSprite, xEvent *xE, WindowPtr pWin, Window child, Bool calcChild) { int evtype; if (calcChild) child = FindChildForEvent(pSprite, pWin); if ((evtype = xi2_get_type(xE))) { xXIDeviceEvent *event = (xXIDeviceEvent *) xE; switch (evtype) { case XI_RawKeyPress: case XI_RawKeyRelease: case XI_RawButtonPress: case XI_RawButtonRelease: case XI_RawMotion: case XI_RawTouchBegin: case XI_RawTouchUpdate: case XI_RawTouchEnd: case XI_DeviceChanged: case XI_HierarchyChanged: case XI_PropertyEvent: case XI_BarrierHit: case XI_BarrierLeave: return; default: break; } event->root = RootWindow(pSprite)->drawable.id; event->event = pWin->drawable.id; if (evtype == XI_TouchOwnership) { event->child = child; return; } if (pSprite->hot.pScreen == pWin->drawable.pScreen) { event->event_x = event->root_x - double_to_fp1616(pWin->drawable.x); event->event_y = event->root_y - double_to_fp1616(pWin->drawable.y); event->child = child; } else { event->event_x = 0; event->event_y = 0; event->child = None; } if (event->evtype == XI_Enter || event->evtype == XI_Leave || event->evtype == XI_FocusIn || event->evtype == XI_FocusOut) ((xXIEnterEvent *) event)->same_screen = (pSprite->hot.pScreen == pWin->drawable.pScreen); } else { XE_KBPTR.root = RootWindow(pSprite)->drawable.id; XE_KBPTR.event = pWin->drawable.id; if (pSprite->hot.pScreen == pWin->drawable.pScreen) { XE_KBPTR.sameScreen = xTrue; XE_KBPTR.child = child; XE_KBPTR.eventX = XE_KBPTR.rootX - pWin->drawable.x; XE_KBPTR.eventY = XE_KBPTR.rootY - pWin->drawable.y; } else { XE_KBPTR.sameScreen = xFalse; XE_KBPTR.child = None; XE_KBPTR.eventX = 0; XE_KBPTR.eventY = 0; } } } /** * Check if a given event is deliverable at all on a given window. * * This function only checks if any client wants it, not for a specific * client. * * @param[in] dev The device this event is being sent for. * @param[in] evtype The event type of the event that is to be sent. * @param[in] win The current event window. * * @return Bitmask of ::EVENT_XI2_MASK, ::EVENT_XI1_MASK, ::EVENT_CORE_MASK, and * ::EVENT_DONT_PROPAGATE_MASK. */ int EventIsDeliverable(DeviceIntPtr dev, int evtype, WindowPtr win) { int rc = 0; int filter = 0; int type; OtherInputMasks *inputMasks = wOtherInputMasks(win); if ((type = GetXI2Type(evtype)) != 0) { if (inputMasks && xi2mask_isset(inputMasks->xi2mask, dev, type)) rc |= EVENT_XI2_MASK; } if ((type = GetXIType(evtype)) != 0) { filter = event_get_filter_from_type(dev, type); /* Check for XI mask */ if (inputMasks && (inputMasks->deliverableEvents[dev->id] & filter) && (inputMasks->inputEvents[dev->id] & filter)) rc |= EVENT_XI1_MASK; /* Check for XI DontPropagate mask */ if (inputMasks && (inputMasks->dontPropagateMask[dev->id] & filter)) rc |= EVENT_DONT_PROPAGATE_MASK; } if ((type = GetCoreType(evtype)) != 0) { filter = event_get_filter_from_type(dev, type); /* Check for core mask */ if ((win->deliverableEvents & filter) && ((wOtherEventMasks(win) | win->eventMask) & filter)) rc |= EVENT_CORE_MASK; /* Check for core DontPropagate mask */ if (filter & wDontPropagateMask(win)) rc |= EVENT_DONT_PROPAGATE_MASK; } return rc; } static int DeliverEvent(DeviceIntPtr dev, xEvent *xE, int count, WindowPtr win, Window child, GrabPtr grab) { SpritePtr pSprite = dev->spriteInfo->sprite; Mask filter; int deliveries = 0; if (XaceHook(XACE_SEND_ACCESS, NULL, dev, win, xE, count) == Success) { filter = GetEventFilter(dev, xE); FixUpEventFromWindow(pSprite, xE, win, child, FALSE); deliveries = DeliverEventsToWindow(dev, win, xE, count, filter, grab); } return deliveries; } static int DeliverOneEvent(InternalEvent *event, DeviceIntPtr dev, enum InputLevel level, WindowPtr win, Window child, GrabPtr grab) { xEvent *xE = NULL; int count = 0; int deliveries = 0; int rc; switch (level) { case XI2: rc = EventToXI2(event, &xE); count = 1; break; case XI: rc = EventToXI(event, &xE, &count); break; case CORE: rc = EventToCore(event, &xE, &count); break; default: rc = BadImplementation; break; } if (rc == Success) { deliveries = DeliverEvent(dev, xE, count, win, child, grab); free(xE); } else BUG_WARN_MSG(rc != BadMatch, "%s: conversion to level %d failed with rc %d\n", dev->name, level, rc); return deliveries; } /** * Deliver events caused by input devices. * * For events from a non-grabbed, non-focus device, DeliverDeviceEvents is * called directly from the processInputProc. * For grabbed devices, DeliverGrabbedEvent is called first, and _may_ call * DeliverDeviceEvents. * For focused events, DeliverFocusedEvent is called first, and _may_ call * DeliverDeviceEvents. * * @param pWin Window to deliver event to. * @param event The events to deliver, not yet in wire format. * @param grab Possible grab on a device. * @param stopAt Don't recurse up to the root window. * @param dev The device that is responsible for the event. * * @see DeliverGrabbedEvent * @see DeliverFocusedEvent */ int DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, WindowPtr stopAt, DeviceIntPtr dev) { Window child = None; int deliveries = 0; int mask; verify_internal_event(event); while (pWin) { if ((mask = EventIsDeliverable(dev, event->any.type, pWin))) { /* XI2 events first */ if (mask & EVENT_XI2_MASK) { deliveries = DeliverOneEvent(event, dev, XI2, pWin, child, grab); if (deliveries > 0) break; } /* XI events */ if (mask & EVENT_XI1_MASK) { deliveries = DeliverOneEvent(event, dev, XI, pWin, child, grab); if (deliveries > 0) break; } /* Core event */ if ((mask & EVENT_CORE_MASK) && IsMaster(dev) && dev->coreEvents) { deliveries = DeliverOneEvent(event, dev, CORE, pWin, child, grab); if (deliveries > 0) break; } } if ((deliveries < 0) || (pWin == stopAt) || (mask & EVENT_DONT_PROPAGATE_MASK)) { deliveries = 0; break; } child = pWin->drawable.id; pWin = pWin->parent; } return deliveries; } /** * Deliver event to a window and it's immediate parent. Used for most window * events (CreateNotify, ConfigureNotify, etc.). Not useful for events that * propagate up the tree or extension events * * In case of a ReparentNotify event, the event will be delivered to the * otherParent as well. * * @param pWin Window to deliver events to. * @param xE Events to deliver. * @param count number of events in xE. * @param otherParent Used for ReparentNotify events. */ int DeliverEvents(WindowPtr pWin, xEvent *xE, int count, WindowPtr otherParent) { DeviceIntRec dummy; int deliveries; #ifdef PANORAMIX if (!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return count; #endif if (!count) return 0; dummy.id = XIAllDevices; switch (xE->u.u.type) { case DestroyNotify: case UnmapNotify: case MapNotify: case MapRequest: case ReparentNotify: case ConfigureNotify: case ConfigureRequest: case GravityNotify: case CirculateNotify: case CirculateRequest: xE->u.destroyNotify.event = pWin->drawable.id; break; } switch (xE->u.u.type) { case DestroyNotify: case UnmapNotify: case MapNotify: case ReparentNotify: case ConfigureNotify: case GravityNotify: case CirculateNotify: break; default: { Mask filter; filter = GetEventFilter(&dummy, xE); return DeliverEventsToWindow(&dummy, pWin, xE, count, filter, NullGrab); } } deliveries = DeliverEventsToWindow(&dummy, pWin, xE, count, StructureNotifyMask, NullGrab); if (pWin->parent) { xE->u.destroyNotify.event = pWin->parent->drawable.id; deliveries += DeliverEventsToWindow(&dummy, pWin->parent, xE, count, SubstructureNotifyMask, NullGrab); if (xE->u.u.type == ReparentNotify) { xE->u.destroyNotify.event = otherParent->drawable.id; deliveries += DeliverEventsToWindow(&dummy, otherParent, xE, count, SubstructureNotifyMask, NullGrab); } } return deliveries; } Bool PointInBorderSize(WindowPtr pWin, int x, int y) { BoxRec box; if (RegionContainsPoint(&pWin->borderSize, x, y, &box)) return TRUE; #ifdef PANORAMIX if (!noPanoramiXExtension && XineramaSetWindowPntrs(inputInfo.pointer, pWin)) { SpritePtr pSprite = inputInfo.pointer->spriteInfo->sprite; int i; FOR_NSCREENS_FORWARD_SKIP(i) { if (RegionContainsPoint(&pSprite->windows[i]->borderSize, x + screenInfo.screens[0]->x - screenInfo.screens[i]->x, y + screenInfo.screens[0]->y - screenInfo.screens[i]->y, &box)) return TRUE; } } #endif return FALSE; } /** * Traversed from the root window to the window at the position x/y. While * traversing, it sets up the traversal history in the spriteTrace array. * After completing, the spriteTrace history is set in the following way: * spriteTrace[0] ... root window * spriteTrace[1] ... top level window that encloses x/y * ... * spriteTrace[spriteTraceGood - 1] ... window at x/y * * @returns the window at the given coordinates. */ WindowPtr XYToWindow(SpritePtr pSprite, int x, int y) { ScreenPtr pScreen = RootWindow(pSprite)->drawable.pScreen; return (*pScreen->XYToWindow)(pScreen, pSprite, x, y); } /** * Ungrab a currently FocusIn grabbed device and grab the device on the * given window. If the win given is the NoneWin, the device is ungrabbed if * applicable and FALSE is returned. * * @returns TRUE if the device has been grabbed, or FALSE otherwise. */ BOOL ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) { BOOL rc = FALSE; DeviceEvent event; if (dev->deviceGrab.grab) { if (!dev->deviceGrab.fromPassiveGrab || dev->deviceGrab.grab->type != XI_FocusIn || dev->deviceGrab.grab->window == win || IsParent(dev->deviceGrab.grab->window, win)) return FALSE; DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); (*dev->deviceGrab.DeactivateGrab) (dev); } if (win == NoneWin || win == PointerRootWin) return FALSE; event = (DeviceEvent) { .header = ET_Internal, .type = ET_FocusIn, .length = sizeof(DeviceEvent), .time = GetTimeInMillis(), .deviceid = dev->id, .sourceid = dev->id, .detail.button = 0 }; rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE, TRUE) != NULL); if (rc) DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab); return rc; } /** * Ungrab a currently Enter grabbed device and grab the device for the given * window. * * @returns TRUE if the device has been grabbed, or FALSE otherwise. */ static BOOL ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) { BOOL rc = FALSE; DeviceEvent event; if (dev->deviceGrab.grab) { if (!dev->deviceGrab.fromPassiveGrab || dev->deviceGrab.grab->type != XI_Enter || dev->deviceGrab.grab->window == win || IsParent(dev->deviceGrab.grab->window, win)) return FALSE; DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); (*dev->deviceGrab.DeactivateGrab) (dev); } event = (DeviceEvent) { .header = ET_Internal, .type = ET_Enter, .length = sizeof(DeviceEvent), .time = GetTimeInMillis(), .deviceid = dev->id, .sourceid = dev->id, .detail.button = 0 }; rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE, TRUE) != NULL); if (rc) DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab); return rc; } /** * Update the sprite coordinates based on the event. Update the cursor * position, then update the event with the new coordinates that may have been * changed. If the window underneath the sprite has changed, change to new * cursor and send enter/leave events. * * CheckMotion() will not do anything and return FALSE if the event is not a * pointer event. * * @return TRUE if the sprite has moved or FALSE otherwise. */ Bool CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev) { WindowPtr prevSpriteWin, newSpriteWin; SpritePtr pSprite = pDev->spriteInfo->sprite; verify_internal_event((InternalEvent *) ev); prevSpriteWin = pSprite->win; if (ev && !syncEvents.playingEvents) { /* GetPointerEvents() guarantees that pointer events have the correct rootX/Y set already. */ switch (ev->type) { case ET_ButtonPress: case ET_ButtonRelease: case ET_Motion: case ET_TouchBegin: case ET_TouchUpdate: case ET_TouchEnd: break; default: /* all other events return FALSE */ return FALSE; } #ifdef PANORAMIX if (!noPanoramiXExtension) { /* Motion events entering DIX get translated to Screen 0 coordinates. Replayed events have already been translated since they've entered DIX before */ ev->root_x += pSprite->screen->x - screenInfo.screens[0]->x; ev->root_y += pSprite->screen->y - screenInfo.screens[0]->y; } else #endif { if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen) { pSprite->hot.pScreen = pSprite->hotPhys.pScreen; RootWindow(pDev->spriteInfo->sprite) = pSprite->hot.pScreen->root; } } pSprite->hot.x = ev->root_x; pSprite->hot.y = ev->root_y; if (pSprite->hot.x < pSprite->physLimits.x1) pSprite->hot.x = pSprite->physLimits.x1; else if (pSprite->hot.x >= pSprite->physLimits.x2) pSprite->hot.x = pSprite->physLimits.x2 - 1; if (pSprite->hot.y < pSprite->physLimits.y1) pSprite->hot.y = pSprite->physLimits.y1; else if (pSprite->hot.y >= pSprite->physLimits.y2) pSprite->hot.y = pSprite->physLimits.y2 - 1; if (pSprite->hotShape) ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y); pSprite->hotPhys = pSprite->hot; if ((pSprite->hotPhys.x != ev->root_x) || (pSprite->hotPhys.y != ev->root_y)) { #ifdef PANORAMIX if (!noPanoramiXExtension) { XineramaSetCursorPosition(pDev, pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); } else #endif { (*pSprite->hotPhys.pScreen->SetCursorPosition) (pDev, pSprite-> hotPhys.pScreen, pSprite-> hotPhys.x, pSprite-> hotPhys.y, FALSE); } } ev->root_x = pSprite->hot.x; ev->root_y = pSprite->hot.y; } newSpriteWin = XYToWindow(pSprite, pSprite->hot.x, pSprite->hot.y); if (newSpriteWin != prevSpriteWin) { int sourceid; if (!ev) { UpdateCurrentTimeIf(); sourceid = pDev->id; /* when from WindowsRestructured */ } else sourceid = ev->sourceid; if (prevSpriteWin != NullWindow) { if (!ActivateEnterGrab(pDev, prevSpriteWin, newSpriteWin)) DoEnterLeaveEvents(pDev, sourceid, prevSpriteWin, newSpriteWin, NotifyNormal); } /* set pSprite->win after ActivateEnterGrab, otherwise sprite window == grab_window and no enter/leave events are sent. */ pSprite->win = newSpriteWin; PostNewCursor(pDev); return FALSE; } return TRUE; } /** * Windows have restructured, we need to update the sprite position and the * sprite's cursor. */ void WindowsRestructured(void) { DeviceIntPtr pDev = inputInfo.devices; while (pDev) { if (IsMaster(pDev) || IsFloating(pDev)) CheckMotion(NULL, pDev); pDev = pDev->next; } } #ifdef PANORAMIX /* This was added to support reconfiguration under Xdmx. The problem is * that if the 0th screen (i.e., screenInfo.screens[0]) is moved to an origin * other than 0,0, the information in the private sprite structure must * be updated accordingly, or XYToWindow (and other routines) will not * compute correctly. */ void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff) { GrabPtr grab; DeviceIntPtr pDev; SpritePtr pSprite; if (noPanoramiXExtension) return; pDev = inputInfo.devices; while (pDev) { if (DevHasCursor(pDev)) { pSprite = pDev->spriteInfo->sprite; pSprite->hot.x -= xoff; pSprite->hot.y -= yoff; pSprite->hotPhys.x -= xoff; pSprite->hotPhys.y -= yoff; pSprite->hotLimits.x1 -= xoff; pSprite->hotLimits.y1 -= yoff; pSprite->hotLimits.x2 -= xoff; pSprite->hotLimits.y2 -= yoff; if (RegionNotEmpty(&pSprite->Reg1)) RegionTranslate(&pSprite->Reg1, xoff, yoff); if (RegionNotEmpty(&pSprite->Reg2)) RegionTranslate(&pSprite->Reg2, xoff, yoff); /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */ if ((grab = pDev->deviceGrab.grab) && grab->confineTo) { if (grab->confineTo->drawable.pScreen != pSprite->hotPhys.pScreen) pSprite->hotPhys.x = pSprite->hotPhys.y = 0; ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE); } else ConfineCursorToWindow(pDev, pSprite->hotPhys.pScreen->root, TRUE, FALSE); } pDev = pDev->next; } } #endif /** * Initialize a sprite for the given device and set it to some sane values. If * the device already has a sprite alloc'd, don't realloc but just reset to * default values. * If a window is supplied, the sprite will be initialized with the window's * cursor and positioned in the center of the window's screen. The root window * is a good choice to pass in here. * * It's a good idea to call it only for pointer devices, unless you have a * really talented keyboard. * * @param pDev The device to initialize. * @param pWin The window where to generate the sprite in. * */ void InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin) { SpritePtr pSprite; ScreenPtr pScreen; CursorPtr pCursor; if (!pDev->spriteInfo->sprite) { DeviceIntPtr it; pDev->spriteInfo->sprite = (SpritePtr) calloc(1, sizeof(SpriteRec)); if (!pDev->spriteInfo->sprite) FatalError("InitializeSprite: failed to allocate sprite struct"); /* We may have paired another device with this device before our * device had a actual sprite. We need to check for this and reset the * sprite field for all paired devices. * * The VCK is always paired with the VCP before the VCP has a sprite. */ for (it = inputInfo.devices; it; it = it->next) { if (it->spriteInfo->paired == pDev) it->spriteInfo->sprite = pDev->spriteInfo->sprite; } if (inputInfo.keyboard->spriteInfo->paired == pDev) inputInfo.keyboard->spriteInfo->sprite = pDev->spriteInfo->sprite; } pSprite = pDev->spriteInfo->sprite; pDev->spriteInfo->spriteOwner = TRUE; pScreen = (pWin) ? pWin->drawable.pScreen : (ScreenPtr) NULL; pSprite->hot.pScreen = pScreen; pSprite->hotPhys.pScreen = pScreen; if (pScreen) { pSprite->hotPhys.x = pScreen->width / 2; pSprite->hotPhys.y = pScreen->height / 2; pSprite->hotLimits.x2 = pScreen->width; pSprite->hotLimits.y2 = pScreen->height; } pSprite->hot = pSprite->hotPhys; pSprite->win = pWin; if (pWin) { pCursor = wCursor(pWin); pSprite->spriteTrace = (WindowPtr *) calloc(1, 32 * sizeof(WindowPtr)); if (!pSprite->spriteTrace) FatalError("Failed to allocate spriteTrace"); pSprite->spriteTraceSize = 32; RootWindow(pDev->spriteInfo->sprite) = pWin; pSprite->spriteTraceGood = 1; pSprite->pEnqueueScreen = pScreen; pSprite->pDequeueScreen = pSprite->pEnqueueScreen; } else { pCursor = NullCursor; pSprite->spriteTrace = NULL; pSprite->spriteTraceSize = 0; pSprite->spriteTraceGood = 0; pSprite->pEnqueueScreen = screenInfo.screens[0]; pSprite->pDequeueScreen = pSprite->pEnqueueScreen; } pCursor = RefCursor(pCursor); if (pSprite->current) FreeCursor(pSprite->current, None); pSprite->current = pCursor; if (pScreen) { (*pScreen->RealizeCursor) (pDev, pScreen, pSprite->current); (*pScreen->CursorLimits) (pDev, pScreen, pSprite->current, &pSprite->hotLimits, &pSprite->physLimits); pSprite->confined = FALSE; (*pScreen->ConstrainCursor) (pDev, pScreen, &pSprite->physLimits); (*pScreen->SetCursorPosition) (pDev, pScreen, pSprite->hot.x, pSprite->hot.y, FALSE); (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->current); } #ifdef PANORAMIX if (!noPanoramiXExtension) { pSprite->hotLimits.x1 = -screenInfo.screens[0]->x; pSprite->hotLimits.y1 = -screenInfo.screens[0]->y; pSprite->hotLimits.x2 = PanoramiXPixWidth - screenInfo.screens[0]->x; pSprite->hotLimits.y2 = PanoramiXPixHeight - screenInfo.screens[0]->y; pSprite->physLimits = pSprite->hotLimits; pSprite->confineWin = NullWindow; pSprite->hotShape = NullRegion; pSprite->screen = pScreen; /* gotta UNINIT these someplace */ RegionNull(&pSprite->Reg1); RegionNull(&pSprite->Reg2); } #endif } void FreeSprite(DeviceIntPtr dev) { if (DevHasCursor(dev) && dev->spriteInfo->sprite) { if (dev->spriteInfo->sprite->current) FreeCursor(dev->spriteInfo->sprite->current, None); free(dev->spriteInfo->sprite->spriteTrace); free(dev->spriteInfo->sprite); } dev->spriteInfo->sprite = NULL; } /** * Update the mouse sprite info when the server switches from a pScreen to another. * Otherwise, the pScreen of the mouse sprite is never updated when we switch * from a pScreen to another. Never updating the pScreen of the mouse sprite * implies that windows that are in pScreen whose pScreen->myNum >0 will never * get pointer events. This is because in CheckMotion(), sprite.hotPhys.pScreen * always points to the first pScreen it has been set by * DefineInitialRootWindow(). * * Calling this function is useful for use cases where the server * has more than one pScreen. * This function is similar to DefineInitialRootWindow() but it does not * reset the mouse pointer position. * @param win must be the new pScreen we are switching to. */ void UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen) { SpritePtr pSprite = NULL; WindowPtr win = NULL; CursorPtr pCursor; if (!pScreen) return; if (!pDev->spriteInfo->sprite) return; pSprite = pDev->spriteInfo->sprite; win = pScreen->root; pSprite->hotPhys.pScreen = pScreen; pSprite->hot = pSprite->hotPhys; pSprite->hotLimits.x2 = pScreen->width; pSprite->hotLimits.y2 = pScreen->height; pSprite->win = win; pCursor = RefCursor(wCursor(win)); if (pSprite->current) FreeCursor(pSprite->current, 0); pSprite->current = pCursor; pSprite->spriteTraceGood = 1; pSprite->spriteTrace[0] = win; (*pScreen->CursorLimits) (pDev, pScreen, pSprite->current, &pSprite->hotLimits, &pSprite->physLimits); pSprite->confined = FALSE; (*pScreen->ConstrainCursor) (pDev, pScreen, &pSprite->physLimits); (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->current); #ifdef PANORAMIX if (!noPanoramiXExtension) { pSprite->hotLimits.x1 = -screenInfo.screens[0]->x; pSprite->hotLimits.y1 = -screenInfo.screens[0]->y; pSprite->hotLimits.x2 = PanoramiXPixWidth - screenInfo.screens[0]->x; pSprite->hotLimits.y2 = PanoramiXPixHeight - screenInfo.screens[0]->y; pSprite->physLimits = pSprite->hotLimits; pSprite->screen = pScreen; } #endif } /* * This does not take any shortcuts, and even ignores its argument, since * it does not happen very often, and one has to walk up the tree since * this might be a newly instantiated cursor for an intermediate window * between the one the pointer is in and the one that the last cursor was * instantiated from. */ void WindowHasNewCursor(WindowPtr pWin) { DeviceIntPtr pDev; for (pDev = inputInfo.devices; pDev; pDev = pDev->next) if (DevHasCursor(pDev)) PostNewCursor(pDev); } void NewCurrentScreen(DeviceIntPtr pDev, ScreenPtr newScreen, int x, int y) { DeviceIntPtr ptr; SpritePtr pSprite; ptr = IsFloating(pDev) ? pDev : GetXTestDevice(GetMaster(pDev, MASTER_POINTER)); pSprite = ptr->spriteInfo->sprite; pSprite->hotPhys.x = x; pSprite->hotPhys.y = y; #ifdef PANORAMIX if (!noPanoramiXExtension) { pSprite->hotPhys.x += newScreen->x - screenInfo.screens[0]->x; pSprite->hotPhys.y += newScreen->y - screenInfo.screens[0]->y; if (newScreen != pSprite->screen) { pSprite->screen = newScreen; /* Make sure we tell the DDX to update its copy of the screen */ if (pSprite->confineWin) XineramaConfineCursorToWindow(ptr, pSprite->confineWin, TRUE); else XineramaConfineCursorToWindow(ptr, screenInfo.screens[0]->root, TRUE); /* if the pointer wasn't confined, the DDX won't get told of the pointer warp so we reposition it here */ if (!syncEvents.playingEvents) (*pSprite->screen->SetCursorPosition) (ptr, pSprite->screen, pSprite->hotPhys.x + screenInfo.screens[0]-> x - pSprite->screen->x, pSprite->hotPhys.y + screenInfo.screens[0]-> y - pSprite->screen->y, FALSE); } } else #endif if (newScreen != pSprite->hotPhys.pScreen) ConfineCursorToWindow(ptr, newScreen->root, TRUE, FALSE); } #ifdef PANORAMIX static Bool XineramaPointInWindowIsVisible(WindowPtr pWin, int x, int y) { BoxRec box; int i, xoff, yoff; if (!pWin->realized) return FALSE; if (RegionContainsPoint(&pWin->borderClip, x, y, &box)) return TRUE; if (!XineramaSetWindowPntrs(inputInfo.pointer, pWin)) return FALSE; xoff = x + screenInfo.screens[0]->x; yoff = y + screenInfo.screens[0]->y; FOR_NSCREENS_FORWARD_SKIP(i) { pWin = inputInfo.pointer->spriteInfo->sprite->windows[i]; x = xoff - screenInfo.screens[i]->x; y = yoff - screenInfo.screens[i]->y; if (RegionContainsPoint(&pWin->borderClip, x, y, &box) && (!wInputShape(pWin) || RegionContainsPoint(wInputShape(pWin), x - pWin->drawable.x, y - pWin->drawable.y, &box))) return TRUE; } return FALSE; } static int XineramaWarpPointer(ClientPtr client) { WindowPtr dest = NULL; int x, y, rc; SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; REQUEST(xWarpPointerReq); if (stuff->dstWid != None) { rc = dixLookupWindow(&dest, stuff->dstWid, client, DixReadAccess); if (rc != Success) return rc; } x = pSprite->hotPhys.x; y = pSprite->hotPhys.y; if (stuff->srcWid != None) { int winX, winY; XID winID = stuff->srcWid; WindowPtr source; rc = dixLookupWindow(&source, winID, client, DixReadAccess); if (rc != Success) return rc; winX = source->drawable.x; winY = source->drawable.y; if (source == screenInfo.screens[0]->root) { winX -= screenInfo.screens[0]->x; winY -= screenInfo.screens[0]->y; } if (x < winX + stuff->srcX || y < winY + stuff->srcY || (stuff->srcWidth != 0 && winX + stuff->srcX + (int) stuff->srcWidth < x) || (stuff->srcHeight != 0 && winY + stuff->srcY + (int) stuff->srcHeight < y) || !XineramaPointInWindowIsVisible(source, x, y)) return Success; } if (dest) { x = dest->drawable.x; y = dest->drawable.y; if (dest == screenInfo.screens[0]->root) { x -= screenInfo.screens[0]->x; y -= screenInfo.screens[0]->y; } } x += stuff->dstX; y += stuff->dstY; if (x < pSprite->physLimits.x1) x = pSprite->physLimits.x1; else if (x >= pSprite->physLimits.x2) x = pSprite->physLimits.x2 - 1; if (y < pSprite->physLimits.y1) y = pSprite->physLimits.y1; else if (y >= pSprite->physLimits.y2) y = pSprite->physLimits.y2 - 1; if (pSprite->hotShape) ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y); XineramaSetCursorPosition(PickPointer(client), x, y, TRUE); return Success; } #endif /** * Server-side protocol handling for WarpPointer request. * Warps the cursor position to the coordinates given in the request. */ int ProcWarpPointer(ClientPtr client) { WindowPtr dest = NULL; int x, y, rc; ScreenPtr newScreen; DeviceIntPtr dev, tmp; SpritePtr pSprite; REQUEST(xWarpPointerReq); REQUEST_SIZE_MATCH(xWarpPointerReq); dev = PickPointer(client); for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { if (GetMaster(tmp, MASTER_ATTACHED) == dev) { rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixWriteAccess); if (rc != Success) return rc; } } if (dev->lastSlave) dev = dev->lastSlave; pSprite = dev->spriteInfo->sprite; #ifdef PANORAMIX if (!noPanoramiXExtension) return XineramaWarpPointer(client); #endif if (stuff->dstWid != None) { rc = dixLookupWindow(&dest, stuff->dstWid, client, DixGetAttrAccess); if (rc != Success) return rc; } x = pSprite->hotPhys.x; y = pSprite->hotPhys.y; if (stuff->srcWid != None) { int winX, winY; XID winID = stuff->srcWid; WindowPtr source; rc = dixLookupWindow(&source, winID, client, DixGetAttrAccess); if (rc != Success) return rc; winX = source->drawable.x; winY = source->drawable.y; if (source->drawable.pScreen != pSprite->hotPhys.pScreen || x < winX + stuff->srcX || y < winY + stuff->srcY || (stuff->srcWidth != 0 && winX + stuff->srcX + (int) stuff->srcWidth < x) || (stuff->srcHeight != 0 && winY + stuff->srcY + (int) stuff->srcHeight < y) || (source->parent && !PointInWindowIsVisible(source, x, y))) return Success; } if (dest) { x = dest->drawable.x; y = dest->drawable.y; newScreen = dest->drawable.pScreen; } else newScreen = pSprite->hotPhys.pScreen; x += stuff->dstX; y += stuff->dstY; if (x < 0) x = 0; else if (x >= newScreen->width) x = newScreen->width - 1; if (y < 0) y = 0; else if (y >= newScreen->height) y = newScreen->height - 1; if (newScreen == pSprite->hotPhys.pScreen) { if (x < pSprite->physLimits.x1) x = pSprite->physLimits.x1; else if (x >= pSprite->physLimits.x2) x = pSprite->physLimits.x2 - 1; if (y < pSprite->physLimits.y1) y = pSprite->physLimits.y1; else if (y >= pSprite->physLimits.y2) y = pSprite->physLimits.y2 - 1; if (pSprite->hotShape) ConfineToShape(dev, pSprite->hotShape, &x, &y); (*newScreen->SetCursorPosition) (dev, newScreen, x, y, TRUE); } else if (!PointerConfinedToScreen(dev)) { NewCurrentScreen(dev, newScreen, x, y); } if (*newScreen->CursorWarpedTo) (*newScreen->CursorWarpedTo) (dev, newScreen, client, dest, pSprite, x, y); return Success; } static Bool BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin) { if (RegionNotEmpty(&pWin->borderSize)) return TRUE; #ifdef PANORAMIX if (!noPanoramiXExtension && XineramaSetWindowPntrs(pDev, pWin)) { int i; FOR_NSCREENS_FORWARD_SKIP(i) { if (RegionNotEmpty (&pDev->spriteInfo->sprite->windows[i]->borderSize)) return TRUE; } } #endif return FALSE; } /** * Activate the given passive grab. If the grab is activated successfully, the * event has been delivered to the client. * * @param device The device of the event to check. * @param grab The grab to check. * @param event The current device event. * @param real_event The original event, in case of touch emulation. The * real event is the one stored in the sync queue. * * @return Whether the grab has been activated. */ Bool ActivatePassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event, InternalEvent *real_event) { SpritePtr pSprite = device->spriteInfo->sprite; GrabInfoPtr grabinfo = &device->deviceGrab; xEvent *xE = NULL; int count; int rc; /* The only consumers of corestate are Xi 1.x and core events, which * are guaranteed to come from DeviceEvents. */ if (grab->grabtype == XI || grab->grabtype == CORE) { DeviceIntPtr gdev; event->device_event.corestate &= 0x1f00; if (grab->grabtype == CORE) gdev = GetMaster(device, KEYBOARD_OR_FLOAT); else gdev = grab->modifierDevice; if (gdev && gdev->key && gdev->key->xkbInfo) event->device_event.corestate |= gdev->key->xkbInfo->state.grab_mods & (~0x1f00); } if (grab->grabtype == CORE) { rc = EventToCore(event, &xE, &count); if (rc != Success) { BUG_WARN_MSG(rc != BadMatch, "[dix] %s: core conversion failed" "(%d, %d).\n", device->name, event->any.type, rc); return FALSE; } } else if (grab->grabtype == XI2) { rc = EventToXI2(event, &xE); if (rc != Success) { if (rc != BadMatch) BUG_WARN_MSG(rc != BadMatch, "[dix] %s: XI2 conversion failed" "(%d, %d).\n", device->name, event->any.type, rc); return FALSE; } count = 1; } else { rc = EventToXI(event, &xE, &count); if (rc != Success) { if (rc != BadMatch) BUG_WARN_MSG(rc != BadMatch, "[dix] %s: XI conversion failed" "(%d, %d).\n", device->name, event->any.type, rc); return FALSE; } } (*grabinfo->ActivateGrab) (device, grab, ClientTimeToServerTime(event->any.time), TRUE); if (xE) { FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE); /* XXX: XACE? */ TryClientEvents(rClient(grab), device, xE, count, GetEventFilter(device, xE), GetEventFilter(device, xE), grab); } if (grabinfo->sync.state == FROZEN_NO_EVENT) grabinfo->sync.state = FROZEN_WITH_EVENT; *grabinfo->sync.event = real_event->device_event; free(xE); return TRUE; } static BOOL CoreGrabInterferes(DeviceIntPtr device, GrabPtr grab) { DeviceIntPtr other; BOOL interfering = FALSE; for (other = inputInfo.devices; other; other = other->next) { GrabPtr othergrab = other->deviceGrab.grab; if (othergrab && othergrab->grabtype == CORE && SameClient(grab, rClient(othergrab)) && ((IsPointerDevice(grab->device) && IsPointerDevice(othergrab->device)) || (IsKeyboardDevice(grab->device) && IsKeyboardDevice(othergrab->device)))) { interfering = TRUE; break; } } return interfering; } enum MatchFlags { NO_MATCH = 0x0, CORE_MATCH = 0x1, XI_MATCH = 0x2, XI2_MATCH = 0x4, }; /** * Match the grab against the temporary grab on the given input level. * Modifies the temporary grab pointer. * * @param grab The grab to match against * @param tmp The temporary grab to use for matching * @param level The input level we want to match on * @param event_type Wire protocol event type * * @return The respective matched flag or 0 for no match */ static enum MatchFlags MatchForType(const GrabPtr grab, GrabPtr tmp, enum InputLevel level, int event_type) { enum MatchFlags match; BOOL ignore_device = FALSE; int grabtype; int evtype; switch (level) { case XI2: grabtype = XI2; evtype = GetXI2Type(event_type); BUG_WARN(!evtype); match = XI2_MATCH; break; case XI: grabtype = XI; evtype = GetXIType(event_type); match = XI_MATCH; break; case CORE: grabtype = CORE; evtype = GetCoreType(event_type); match = CORE_MATCH; ignore_device = TRUE; break; default: return NO_MATCH; } tmp->grabtype = grabtype; tmp->type = evtype; if (tmp->type && GrabMatchesSecond(tmp, grab, ignore_device)) return match; return NO_MATCH; } /** * Check an individual grab against an event to determine if a passive grab * should be activated. * * @param device The device of the event to check. * @param grab The grab to check. * @param event The current device event. * @param checkCore Check for core grabs too. * @param tempGrab A pre-allocated temporary grab record for matching. This * must have the window and device values filled in. * * @return Whether the grab matches the event. */ static Bool CheckPassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event, Bool checkCore, GrabPtr tempGrab) { DeviceIntPtr gdev; XkbSrvInfoPtr xkbi = NULL; enum MatchFlags match = 0; int emulated_type = 0; gdev = grab->modifierDevice; if (grab->grabtype == CORE) { gdev = GetMaster(device, KEYBOARD_OR_FLOAT); } else if (grab->grabtype == XI2) { /* if the device is an attached slave device, gdev must be the * attached master keyboard. Since the slave may have been * reattached after the grab, the modifier device may not be the * same. */ if (!IsMaster(grab->device) && !IsFloating(device)) gdev = GetMaster(device, MASTER_KEYBOARD); } if (gdev && gdev->key) xkbi = gdev->key->xkbInfo; tempGrab->modifierDevice = grab->modifierDevice; tempGrab->modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0; /* Check for XI2 and XI grabs first */ match = MatchForType(grab, tempGrab, XI2, event->any.type); if (!match && IsTouchEvent(event) && (event->device_event.flags & TOUCH_POINTER_EMULATED)) { emulated_type = TouchGetPointerEventType(event); match = MatchForType(grab, tempGrab, XI2, emulated_type); } if (!match) match = MatchForType(grab, tempGrab, XI, event->any.type); if (!match && emulated_type) match = MatchForType(grab, tempGrab, XI, emulated_type); if (!match && checkCore) { match = MatchForType(grab, tempGrab, CORE, event->any.type); if (!match && emulated_type) match = MatchForType(grab, tempGrab, CORE, emulated_type); } if (!match || (grab->confineTo && (!grab->confineTo->realized || !BorderSizeNotEmpty(device, grab->confineTo)))) return FALSE; /* In some cases a passive core grab may exist, but the client * already has a core grab on some other device. In this case we * must not get the grab, otherwise we may never ungrab the * device. */ if (grab->grabtype == CORE) { /* A passive grab may have been created for a different device than it is assigned to at this point in time. Update the grab's device and modifier device to reflect the current state. Since XGrabDeviceButton requires to specify the modifierDevice explicitly, we don't override this choice. */ if (grab->type < GenericEvent) { grab->device = device; grab->modifierDevice = GetMaster(device, MASTER_KEYBOARD); } if (CoreGrabInterferes(device, grab)) return FALSE; } return TRUE; } /** * "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a * passive grab set on the window to be activated. * If activate is true and a passive grab is found, it will be activated, * and the event will be delivered to the client. * * @param pWin The window that may be subject to a passive grab. * @param device Device that caused the event. * @param event The current device event. * @param checkCore Check for core grabs too. * @param activate If a grab is found, activate it and deliver the event. */ GrabPtr CheckPassiveGrabsOnWindow(WindowPtr pWin, DeviceIntPtr device, InternalEvent *event, BOOL checkCore, BOOL activate) { GrabPtr grab = wPassiveGrabs(pWin); GrabPtr tempGrab; if (!grab) return NULL; tempGrab = AllocGrab(NULL); if (tempGrab == NULL) return NULL; /* Fill out the grab details, but leave the type for later before * comparing */ switch (event->any.type) { case ET_KeyPress: case ET_KeyRelease: tempGrab->detail.exact = event->device_event.detail.key; break; case ET_ButtonPress: case ET_ButtonRelease: case ET_TouchBegin: case ET_TouchEnd: tempGrab->detail.exact = event->device_event.detail.button; break; default: tempGrab->detail.exact = 0; break; } tempGrab->window = pWin; tempGrab->device = device; tempGrab->detail.pMask = NULL; tempGrab->modifiersDetail.pMask = NULL; tempGrab->next = NULL; for (; grab; grab = grab->next) { if (!CheckPassiveGrab(device, grab, event, checkCore, tempGrab)) continue; if (activate && !ActivatePassiveGrab(device, grab, event, event)) continue; break; } FreeGrab(tempGrab); return grab; } /** * CheckDeviceGrabs handles both keyboard and pointer events that may cause * a passive grab to be activated. * * If the event is a keyboard event, the ancestors of the focus window are * traced down and tried to see if they have any passive grabs to be * activated. If the focus window itself is reached and it's descendants * contain the pointer, the ancestors of the window that the pointer is in * are then traced down starting at the focus window, otherwise no grabs are * activated. * If the event is a pointer event, the ancestors of the window that the * pointer is in are traced down starting at the root until CheckPassiveGrabs * causes a passive grab to activate or all the windows are * tried. PRH * * If a grab is activated, the event has been sent to the client already! * * The event we pass in must always be an XI event. From this, we then emulate * the core event and then check for grabs. * * @param device The device that caused the event. * @param xE The event to handle (Device{Button|Key}Press). * @param count Number of events in list. * @return TRUE if a grab has been activated or false otherwise. */ Bool CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor) { int i; WindowPtr pWin = NULL; FocusClassPtr focus = IsPointerEvent((InternalEvent *) event) ? NULL : device->focus; BOOL sendCore = (IsMaster(device) && device->coreEvents); Bool ret = FALSE; if (event->type != ET_ButtonPress && event->type != ET_KeyPress) return FALSE; if (event->type == ET_ButtonPress && (device->button->buttonsDown != 1)) return FALSE; if (device->deviceGrab.grab) return FALSE; i = 0; if (ancestor) { while (i < device->spriteInfo->sprite->spriteTraceGood) if (device->spriteInfo->sprite->spriteTrace[i++] == ancestor) break; if (i == device->spriteInfo->sprite->spriteTraceGood) goto out; } if (focus) { for (; i < focus->traceGood; i++) { pWin = focus->trace[i]; if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event, sendCore, TRUE)) { ret = TRUE; goto out; } } if ((focus->win == NoneWin) || (i >= device->spriteInfo->sprite->spriteTraceGood) || (pWin && pWin != device->spriteInfo->sprite->spriteTrace[i - 1])) goto out; } for (; i < device->spriteInfo->sprite->spriteTraceGood; i++) { pWin = device->spriteInfo->sprite->spriteTrace[i]; if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event, sendCore, TRUE)) { ret = TRUE; goto out; } } out: if (ret == TRUE && event->type == ET_KeyPress) device->deviceGrab.activatingKey = event->detail.key; return ret; } /** * Called for keyboard events to deliver event to whatever client owns the * focus. * * The event is delivered to the keyboard's focus window, the root window or * to the window owning the input focus. * * @param keybd The keyboard originating the event. * @param event The event, not yet in wire format. * @param window Window underneath the sprite. */ void DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window) { DeviceIntPtr ptr; WindowPtr focus = keybd->focus->win; BOOL sendCore = (IsMaster(keybd) && keybd->coreEvents); xEvent *core = NULL, *xE = NULL, *xi2 = NULL; int count, rc; int deliveries = 0; if (focus == FollowKeyboardWin) focus = inputInfo.keyboard->focus->win; if (!focus) return; if (focus == PointerRootWin) { DeliverDeviceEvents(window, event, NullGrab, NullWindow, keybd); return; } if ((focus == window) || IsParent(focus, window)) { if (DeliverDeviceEvents(window, event, NullGrab, focus, keybd)) return; } /* just deliver it to the focus window */ ptr = GetMaster(keybd, POINTER_OR_FLOAT); rc = EventToXI2(event, &xi2); if (rc == Success) { /* XXX: XACE */ int filter = GetEventFilter(keybd, xi2); FixUpEventFromWindow(ptr->spriteInfo->sprite, xi2, focus, None, FALSE); deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1, filter, NullGrab); if (deliveries > 0) goto unwind; } else if (rc != BadMatch) ErrorF ("[dix] %s: XI2 conversion failed in DFE (%d, %d). Skipping delivery.\n", keybd->name, event->any.type, rc); rc = EventToXI(event, &xE, &count); if (rc == Success && XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count) == Success) { FixUpEventFromWindow(ptr->spriteInfo->sprite, xE, focus, None, FALSE); deliveries = DeliverEventsToWindow(keybd, focus, xE, count, GetEventFilter(keybd, xE), NullGrab); if (deliveries > 0) goto unwind; } else if (rc != BadMatch) ErrorF ("[dix] %s: XI conversion failed in DFE (%d, %d). Skipping delivery.\n", keybd->name, event->any.type, rc); if (sendCore) { rc = EventToCore(event, &core, &count); if (rc == Success) { if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, core, count) == Success) { FixUpEventFromWindow(keybd->spriteInfo->sprite, core, focus, None, FALSE); deliveries = DeliverEventsToWindow(keybd, focus, core, count, GetEventFilter(keybd, core), NullGrab); } } else if (rc != BadMatch) ErrorF ("[dix] %s: core conversion failed DFE (%d, %d). Skipping delivery.\n", keybd->name, event->any.type, rc); } unwind: free(core); free(xE); free(xi2); return; } int DeliverOneGrabbedEvent(InternalEvent *event, DeviceIntPtr dev, enum InputLevel level) { SpritePtr pSprite = dev->spriteInfo->sprite; int rc; xEvent *xE = NULL; int count = 0; int deliveries = 0; Mask mask; GrabInfoPtr grabinfo = &dev->deviceGrab; GrabPtr grab = grabinfo->grab; Mask filter; if (grab->grabtype != level) return 0; switch (level) { case XI2: rc = EventToXI2(event, &xE); count = 1; if (rc == Success) { int evtype = xi2_get_type(xE); mask = GetXI2MaskByte(grab->xi2mask, dev, evtype); filter = GetEventFilter(dev, xE); } break; case XI: if (grabinfo->fromPassiveGrab && grabinfo->implicitGrab) mask = grab->deviceMask; else mask = grab->eventMask; rc = EventToXI(event, &xE, &count); if (rc == Success) filter = GetEventFilter(dev, xE); break; case CORE: rc = EventToCore(event, &xE, &count); mask = grab->eventMask; if (rc == Success) filter = GetEventFilter(dev, xE); break; default: BUG_WARN_MSG(1, "Invalid input level %d\n", level); return 0; } if (rc == Success) { FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE); if (XaceHook(XACE_SEND_ACCESS, 0, dev, grab->window, xE, count) || XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), grab->window, xE, count)) deliveries = 1; /* don't send, but pretend we did */ else if (level != CORE || !IsInterferingGrab(rClient(grab), dev, xE)) { deliveries = TryClientEvents(rClient(grab), dev, xE, count, mask, filter, grab); } } else BUG_WARN_MSG(rc != BadMatch, "%s: conversion to mode %d failed on %d with %d\n", dev->name, level, event->any.type, rc); free(xE); return deliveries; } /** * Deliver an event from a device that is currently grabbed. Uses * DeliverDeviceEvents() for further delivery if a ownerEvents is set on the * grab. If not, TryClientEvents() is used. * * @param deactivateGrab True if the device's grab should be deactivated. * * @return The number of events delivered. */ int DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, Bool deactivateGrab) { GrabPtr grab; GrabInfoPtr grabinfo; int deliveries = 0; DeviceIntPtr dev; SpritePtr pSprite = thisDev->spriteInfo->sprite; BOOL sendCore = FALSE; grabinfo = &thisDev->deviceGrab; grab = grabinfo->grab; if (grab->ownerEvents) { WindowPtr focus; /* Hack: Some pointer device have a focus class. So we need to check * for the type of event, to see if we really want to deliver it to * the focus window. For pointer events, the answer is no. */ if (IsPointerEvent(event)) focus = PointerRootWin; else if (thisDev->focus) { focus = thisDev->focus->win; if (focus == FollowKeyboardWin) focus = inputInfo.keyboard->focus->win; } else focus = PointerRootWin; if (focus == PointerRootWin) deliveries = DeliverDeviceEvents(pSprite->win, event, grab, NullWindow, thisDev); else if (focus && (focus == pSprite->win || IsParent(focus, pSprite->win))) deliveries = DeliverDeviceEvents(pSprite->win, event, grab, focus, thisDev); else if (focus) deliveries = DeliverDeviceEvents(focus, event, grab, focus, thisDev); } if (!deliveries) { sendCore = (IsMaster(thisDev) && thisDev->coreEvents); /* try core event */ if ((sendCore && grab->grabtype == CORE) || grab->grabtype != CORE) deliveries = DeliverOneGrabbedEvent(event, thisDev, grab->grabtype); if (deliveries && (event->any.type == ET_Motion)) thisDev->valuator->motionHintWindow = grab->window; } if (deliveries && !deactivateGrab && (event->any.type == ET_KeyPress || event->any.type == ET_KeyRelease || event->any.type == ET_ButtonPress || event->any.type == ET_ButtonRelease)) { switch (grabinfo->sync.state) { case FREEZE_BOTH_NEXT_EVENT: dev = GetPairedDevice(thisDev); if (dev) { FreezeThaw(dev, TRUE); if ((dev->deviceGrab.sync.state == FREEZE_BOTH_NEXT_EVENT) && (CLIENT_BITS(grab->resource) == CLIENT_BITS(dev->deviceGrab.grab->resource))) dev->deviceGrab.sync.state = FROZEN_NO_EVENT; else dev->deviceGrab.sync.other = grab; } /* fall through */ case FREEZE_NEXT_EVENT: grabinfo->sync.state = FROZEN_WITH_EVENT; FreezeThaw(thisDev, TRUE); *grabinfo->sync.event = event->device_event; break; } } return deliveries; } /* This function is used to set the key pressed or key released state - this is only used when the pressing of keys does not cause the device's processInputProc to be called, as in for example Mouse Keys. */ void FixKeyState(DeviceEvent *event, DeviceIntPtr keybd) { int key = event->detail.key; if (event->type == ET_KeyPress) { DebugF("FixKeyState: Key %d %s\n", key, ((event->type == ET_KeyPress) ? "down" : "up")); } if (event->type == ET_KeyPress) set_key_down(keybd, key, KEY_PROCESSED); else if (event->type == ET_KeyRelease) set_key_up(keybd, key, KEY_PROCESSED); else FatalError("Impossible keyboard event"); } #define AtMostOneClient \ (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask) #define ManagerMask \ (SubstructureRedirectMask | ResizeRedirectMask) /** * Recalculate which events may be deliverable for the given window. * Recalculated mask is used for quicker determination which events may be * delivered to a window. * * The otherEventMasks on a WindowOptional is the combination of all event * masks set by all clients on the window. * deliverableEventMask is the combination of the eventMask and the * otherEventMask plus the events that may be propagated to the parent. * * Traverses to siblings and parents of the window. */ void RecalculateDeliverableEvents(WindowPtr pWin) { OtherClients *others; WindowPtr pChild; pChild = pWin; while (1) { if (pChild->optional) { pChild->optional->otherEventMasks = 0; for (others = wOtherClients(pChild); others; others = others->next) { pChild->optional->otherEventMasks |= others->mask; } } pChild->deliverableEvents = pChild->eventMask | wOtherEventMasks(pChild); if (pChild->parent) pChild->deliverableEvents |= (pChild->parent->deliverableEvents & ~wDontPropagateMask(pChild) & PropagateMask); if (pChild->firstChild) { pChild = pChild->firstChild; continue; } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) break; pChild = pChild->nextSib; } } /** * * \param value must conform to DeleteType */ int OtherClientGone(void *value, XID id) { OtherClientsPtr other, prev; WindowPtr pWin = (WindowPtr) value; prev = 0; for (other = wOtherClients(pWin); other; other = other->next) { if (other->resource == id) { if (prev) prev->next = other->next; else { if (!(pWin->optional->otherClients = other->next)) CheckWindowOptionalNeed(pWin); } free(other); RecalculateDeliverableEvents(pWin); return Success; } prev = other; } FatalError("client not on event list"); } int EventSelectForWindow(WindowPtr pWin, ClientPtr client, Mask mask) { Mask check; OtherClients *others; DeviceIntPtr dev; int rc; if (mask & ~AllEventMasks) { client->errorValue = mask; return BadValue; } check = (mask & ManagerMask); if (check) { rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, RT_WINDOW, pWin, RT_NONE, NULL, DixManageAccess); if (rc != Success) return rc; } check = (mask & AtMostOneClient); if (check & (pWin->eventMask | wOtherEventMasks(pWin))) { /* It is illegal for two different clients to select on any of the events for AtMostOneClient. However, it is OK, for some client to continue selecting on one of those events. */ if ((wClient(pWin) != client) && (check & pWin->eventMask)) return BadAccess; for (others = wOtherClients(pWin); others; others = others->next) { if (!SameClient(others, client) && (check & others->mask)) return BadAccess; } } if (wClient(pWin) == client) { check = pWin->eventMask; pWin->eventMask = mask; } else { for (others = wOtherClients(pWin); others; others = others->next) { if (SameClient(others, client)) { check = others->mask; if (mask == 0) { FreeResource(others->resource, RT_NONE); return Success; } else others->mask = mask; goto maskSet; } } check = 0; if (!pWin->optional && !MakeWindowOptional(pWin)) return BadAlloc; others = malloc(sizeof(OtherClients)); if (!others) return BadAlloc; others->mask = mask; others->resource = FakeClientID(client->index); others->next = pWin->optional->otherClients; pWin->optional->otherClients = others; if (!AddResource(others->resource, RT_OTHERCLIENT, (void *) pWin)) return BadAlloc; } maskSet: if ((mask & PointerMotionHintMask) && !(check & PointerMotionHintMask)) { for (dev = inputInfo.devices; dev; dev = dev->next) { if (dev->valuator && dev->valuator->motionHintWindow == pWin) dev->valuator->motionHintWindow = NullWindow; } } RecalculateDeliverableEvents(pWin); return Success; } int EventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, Bool *checkOptional) { int i, freed; if (mask & ~PropagateMask) { client->errorValue = mask; return BadValue; } if (pWin->dontPropagate) DontPropagateRefCnts[pWin->dontPropagate]--; if (!mask) i = 0; else { for (i = DNPMCOUNT, freed = 0; --i > 0;) { if (!DontPropagateRefCnts[i]) freed = i; else if (mask == DontPropagateMasks[i]) break; } if (!i && freed) { i = freed; DontPropagateMasks[i] = mask; } } if (i || !mask) { pWin->dontPropagate = i; if (i) DontPropagateRefCnts[i]++; if (pWin->optional) { pWin->optional->dontPropagateMask = mask; *checkOptional = TRUE; } } else { if (!pWin->optional && !MakeWindowOptional(pWin)) { if (pWin->dontPropagate) DontPropagateRefCnts[pWin->dontPropagate]++; return BadAlloc; } pWin->dontPropagate = 0; pWin->optional->dontPropagateMask = mask; } RecalculateDeliverableEvents(pWin); return Success; } /** * Assembles an EnterNotify or LeaveNotify and sends it event to the client. * Uses the paired keyboard to get some additional information. */ void CoreEnterLeaveEvent(DeviceIntPtr mouse, int type, int mode, int detail, WindowPtr pWin, Window child) { xEvent event = { .u.u.type = type, .u.u.detail = detail }; WindowPtr focus; DeviceIntPtr keybd; GrabPtr grab = mouse->deviceGrab.grab; Mask mask; keybd = GetMaster(mouse, KEYBOARD_OR_FLOAT); if ((pWin == mouse->valuator->motionHintWindow) && (detail != NotifyInferior)) mouse->valuator->motionHintWindow = NullWindow; if (grab) { mask = (pWin == grab->window) ? grab->eventMask : 0; if (grab->ownerEvents) mask |= EventMaskForClient(pWin, rClient(grab)); } else { mask = pWin->eventMask | wOtherEventMasks(pWin); } event.u.enterLeave.time = currentTime.milliseconds; event.u.enterLeave.rootX = mouse->spriteInfo->sprite->hot.x; event.u.enterLeave.rootY = mouse->spriteInfo->sprite->hot.y; /* Counts on the same initial structure of crossing & button events! */ FixUpEventFromWindow(mouse->spriteInfo->sprite, &event, pWin, None, FALSE); /* Enter/Leave events always set child */ event.u.enterLeave.child = child; event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ? ELFlagSameScreen : 0; event.u.enterLeave.state = mouse->button ? (mouse->button->state & 0x1f00) : 0; if (keybd) event.u.enterLeave.state |= XkbGrabStateFromRec(&keybd->key->xkbInfo->state); event.u.enterLeave.mode = mode; focus = (keybd) ? keybd->focus->win : None; if ((focus != NoneWin) && ((pWin == focus) || (focus == PointerRootWin) || IsParent(focus, pWin))) event.u.enterLeave.flags |= ELFlagFocus; if ((mask & GetEventFilter(mouse, &event))) { if (grab) TryClientEvents(rClient(grab), mouse, &event, 1, mask, GetEventFilter(mouse, &event), grab); else DeliverEventsToWindow(mouse, pWin, &event, 1, GetEventFilter(mouse, &event), NullGrab); } if ((type == EnterNotify) && (mask & KeymapStateMask)) { xKeymapEvent ke = { .type = KeymapNotify }; ClientPtr client = grab ? rClient(grab) : wClient(pWin); int rc; rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess); if (rc == Success) memcpy((char *) &ke.map[0], (char *) &keybd->key->down[1], 31); if (grab) TryClientEvents(rClient(grab), keybd, (xEvent *) &ke, 1, mask, KeymapStateMask, grab); else DeliverEventsToWindow(mouse, pWin, (xEvent *) &ke, 1, KeymapStateMask, NullGrab); } } void DeviceEnterLeaveEvent(DeviceIntPtr mouse, int sourceid, int type, int mode, int detail, WindowPtr pWin, Window child) { GrabPtr grab = mouse->deviceGrab.grab; xXIEnterEvent *event; WindowPtr focus; int filter; int btlen, len, i; DeviceIntPtr kbd; if ((mode == XINotifyPassiveGrab && type == XI_Leave) || (mode == XINotifyPassiveUngrab && type == XI_Enter)) return; btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; btlen = bytes_to_int32(btlen); len = sizeof(xXIEnterEvent) + btlen * 4; event = calloc(1, len); event->type = GenericEvent; event->extension = IReqCode; event->evtype = type; event->length = (len - sizeof(xEvent)) / 4; event->buttons_len = btlen; event->detail = detail; event->time = currentTime.milliseconds; event->deviceid = mouse->id; event->sourceid = sourceid; event->mode = mode; event->root_x = double_to_fp1616(mouse->spriteInfo->sprite->hot.x); event->root_y = double_to_fp1616(mouse->spriteInfo->sprite->hot.y); for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) if (BitIsOn(mouse->button->down, i)) SetBit(&event[1], i); kbd = GetMaster(mouse, MASTER_KEYBOARD); if (kbd && kbd->key) { event->mods.base_mods = kbd->key->xkbInfo->state.base_mods; event->mods.latched_mods = kbd->key->xkbInfo->state.latched_mods; event->mods.locked_mods = kbd->key->xkbInfo->state.locked_mods; event->group.base_group = kbd->key->xkbInfo->state.base_group; event->group.latched_group = kbd->key->xkbInfo->state.latched_group; event->group.locked_group = kbd->key->xkbInfo->state.locked_group; } focus = (kbd) ? kbd->focus->win : None; if ((focus != NoneWin) && ((pWin == focus) || (focus == PointerRootWin) || IsParent(focus, pWin))) event->focus = TRUE; FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent *) event, pWin, None, FALSE); filter = GetEventFilter(mouse, (xEvent *) event); if (grab && grab->grabtype == XI2) { Mask mask; mask = xi2mask_isset(grab->xi2mask, mouse, type); TryClientEvents(rClient(grab), mouse, (xEvent *) event, 1, mask, 1, grab); } else { if (!WindowXI2MaskIsset(mouse, pWin, (xEvent *) event)) goto out; DeliverEventsToWindow(mouse, pWin, (xEvent *) event, 1, filter, NullGrab); } out: free(event); } void CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) { xEvent event = { .u.u.type = type, .u.u.detail = detail }; event.u.focus.mode = mode; event.u.focus.window = pWin->drawable.id; DeliverEventsToWindow(dev, pWin, &event, 1, GetEventFilter(dev, &event), NullGrab); if ((type == FocusIn) && ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask)) { xKeymapEvent ke = { .type = KeymapNotify }; ClientPtr client = wClient(pWin); int rc; rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess); if (rc == Success) memcpy((char *) &ke.map[0], (char *) &dev->key->down[1], 31); DeliverEventsToWindow(dev, pWin, (xEvent *) &ke, 1, KeymapStateMask, NullGrab); } } /** * Set the input focus to the given window. Subsequent keyboard events will be * delivered to the given window. * * Usually called from ProcSetInputFocus as result of a client request. If so, * the device is the inputInfo.keyboard. * If called from ProcXSetInputFocus as result of a client xinput request, the * device is set to the device specified by the client. * * @param client Client that requested input focus change. * @param dev Focus device. * @param focusID The window to obtain the focus. Can be PointerRoot or None. * @param revertTo Specifies where the focus reverts to when window becomes * unviewable. * @param ctime Specifies the time. * @param followOK True if pointer is allowed to follow the keyboard. */ int SetInputFocus(ClientPtr client, DeviceIntPtr dev, Window focusID, CARD8 revertTo, Time ctime, Bool followOK) { FocusClassPtr focus; WindowPtr focusWin; int mode, rc; TimeStamp time; DeviceIntPtr keybd; /* used for FollowKeyboard or FollowKeyboardWin */ UpdateCurrentTime(); if ((revertTo != RevertToParent) && (revertTo != RevertToPointerRoot) && (revertTo != RevertToNone) && ((revertTo != RevertToFollowKeyboard) || !followOK)) { client->errorValue = revertTo; return BadValue; } time = ClientTimeToServerTime(ctime); keybd = GetMaster(dev, KEYBOARD_OR_FLOAT); if ((focusID == None) || (focusID == PointerRoot)) focusWin = (WindowPtr) (long) focusID; else if ((focusID == FollowKeyboard) && followOK) { focusWin = keybd->focus->win; } else { rc = dixLookupWindow(&focusWin, focusID, client, DixSetAttrAccess); if (rc != Success) return rc; /* It is a match error to try to set the input focus to an unviewable window. */ if (!focusWin->realized) return BadMatch; } rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixSetFocusAccess); if (rc != Success) return Success; focus = dev->focus; if ((CompareTimeStamps(time, currentTime) == LATER) || (CompareTimeStamps(time, focus->time) == EARLIER)) return Success; mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal; if (focus->win == FollowKeyboardWin) { if (!ActivateFocusInGrab(dev, keybd->focus->win, focusWin)) DoFocusEvents(dev, keybd->focus->win, focusWin, mode); } else { if (!ActivateFocusInGrab(dev, focus->win, focusWin)) DoFocusEvents(dev, focus->win, focusWin, mode); } focus->time = time; focus->revert = revertTo; if (focusID == FollowKeyboard) focus->win = FollowKeyboardWin; else focus->win = focusWin; if ((focusWin == NoneWin) || (focusWin == PointerRootWin)) focus->traceGood = 0; else { int depth = 0; WindowPtr pWin; for (pWin = focusWin; pWin; pWin = pWin->parent) depth++; if (depth > focus->traceSize) { focus->traceSize = depth + 1; focus->trace = reallocarray(focus->trace, focus->traceSize, sizeof(WindowPtr)); } focus->traceGood = depth; for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) focus->trace[depth] = pWin; } return Success; } /** * Server-side protocol handling for SetInputFocus request. * * Sets the input focus for the virtual core keyboard. */ int ProcSetInputFocus(ClientPtr client) { DeviceIntPtr kbd = PickKeyboard(client); REQUEST(xSetInputFocusReq); REQUEST_SIZE_MATCH(xSetInputFocusReq); return SetInputFocus(client, kbd, stuff->focus, stuff->revertTo, stuff->time, FALSE); } /** * Server-side protocol handling for GetInputFocus request. * * Sends the current input focus for the client's keyboard back to the * client. */ int ProcGetInputFocus(ClientPtr client) { DeviceIntPtr kbd = PickKeyboard(client); xGetInputFocusReply rep; FocusClassPtr focus = kbd->focus; int rc; /* REQUEST(xReq); */ REQUEST_SIZE_MATCH(xReq); rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetFocusAccess); if (rc != Success) return rc; rep = (xGetInputFocusReply) { .type = X_Reply, .length = 0, .sequenceNumber = client->sequence, .revertTo = focus->revert }; if (focus->win == NoneWin) rep.focus = None; else if (focus->win == PointerRootWin) rep.focus = PointerRoot; else rep.focus = focus->win->drawable.id; WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep); return Success; } /** * Server-side protocol handling for GrabPointer request. * * Sets an active grab on the client's ClientPointer and returns success * status to client. */ int ProcGrabPointer(ClientPtr client) { xGrabPointerReply rep; DeviceIntPtr device = PickPointer(client); GrabPtr grab; GrabMask mask; WindowPtr confineTo; BYTE status; REQUEST(xGrabPointerReq); int rc; REQUEST_SIZE_MATCH(xGrabPointerReq); UpdateCurrentTime(); if (stuff->eventMask & ~PointerGrabMask) { client->errorValue = stuff->eventMask; return BadValue; } if (stuff->confineTo == None) confineTo = NullWindow; else { rc = dixLookupWindow(&confineTo, stuff->confineTo, client, DixSetAttrAccess); if (rc != Success) return rc; } grab = device->deviceGrab.grab; if (grab && grab->confineTo && !confineTo) ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE, FALSE); mask.core = stuff->eventMask; rc = GrabDevice(client, device, stuff->pointerMode, stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents, stuff->time, &mask, CORE, stuff->cursor, stuff->confineTo, &status); if (rc != Success) return rc; rep = (xGrabPointerReply) { .type = X_Reply, .status = status, .sequenceNumber = client->sequence, .length = 0 }; WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep); return Success; } /** * Server-side protocol handling for ChangeActivePointerGrab request. * * Changes properties of the grab hold by the client. If the client does not * hold an active grab on the device, nothing happens. */ int ProcChangeActivePointerGrab(ClientPtr client) { DeviceIntPtr device; GrabPtr grab; CursorPtr newCursor, oldCursor; REQUEST(xChangeActivePointerGrabReq); TimeStamp time; REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq); if (stuff->eventMask & ~PointerGrabMask) { client->errorValue = stuff->eventMask; return BadValue; } if (stuff->cursor == None) newCursor = NullCursor; else { int rc = dixLookupResourceByType((void **) &newCursor, stuff->cursor, RT_CURSOR, client, DixUseAccess); if (rc != Success) { client->errorValue = stuff->cursor; return rc; } } device = PickPointer(client); grab = device->deviceGrab.grab; if (!grab) return Success; if (!SameClient(grab, client)) return Success; UpdateCurrentTime(); time = ClientTimeToServerTime(stuff->time); if ((CompareTimeStamps(time, currentTime) == LATER) || (CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER)) return Success; oldCursor = grab->cursor; grab->cursor = RefCursor(newCursor); PostNewCursor(device); if (oldCursor) FreeCursor(oldCursor, (Cursor) 0); grab->eventMask = stuff->eventMask; return Success; } /** * Server-side protocol handling for UngrabPointer request. * * Deletes a pointer grab on a device the client has grabbed. */ int ProcUngrabPointer(ClientPtr client) { DeviceIntPtr device = PickPointer(client); GrabPtr grab; TimeStamp time; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); UpdateCurrentTime(); grab = device->deviceGrab.grab; time = ClientTimeToServerTime(stuff->id); if ((CompareTimeStamps(time, currentTime) != LATER) && (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) && (grab) && SameClient(grab, client)) (*device->deviceGrab.DeactivateGrab) (device); return Success; } /** * Sets a grab on the given device. * * Called from ProcGrabKeyboard to work on the client's keyboard. * Called from ProcXGrabDevice to work on the device specified by the client. * * The parameters this_mode and other_mode represent the keyboard_mode and * pointer_mode parameters of XGrabKeyboard(). * See man page for details on all the parameters * * @param client Client that owns the grab. * @param dev The device to grab. * @param this_mode GrabModeSync or GrabModeAsync * @param other_mode GrabModeSync or GrabModeAsync * @param status Return code to be returned to the caller. * * @returns Success or BadValue or BadAlloc. */ int GrabDevice(ClientPtr client, DeviceIntPtr dev, unsigned pointer_mode, unsigned keyboard_mode, Window grabWindow, unsigned ownerEvents, Time ctime, GrabMask *mask, int grabtype, Cursor curs, Window confineToWin, CARD8 *status) { WindowPtr pWin, confineTo; GrabPtr grab; TimeStamp time; Mask access_mode = DixGrabAccess; int rc; GrabInfoPtr grabInfo = &dev->deviceGrab; CursorPtr cursor; UpdateCurrentTime(); if ((keyboard_mode != GrabModeSync) && (keyboard_mode != GrabModeAsync)) { client->errorValue = keyboard_mode; return BadValue; } if ((pointer_mode != GrabModeSync) && (pointer_mode != GrabModeAsync)) { client->errorValue = pointer_mode; return BadValue; } if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) { client->errorValue = ownerEvents; return BadValue; } rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess); if (rc != Success) return rc; if (confineToWin == None) confineTo = NullWindow; else { rc = dixLookupWindow(&confineTo, confineToWin, client, DixSetAttrAccess); if (rc != Success) return rc; } if (curs == None) cursor = NullCursor; else { rc = dixLookupResourceByType((void **) &cursor, curs, RT_CURSOR, client, DixUseAccess); if (rc != Success) { client->errorValue = curs; return rc; } access_mode |= DixForceAccess; } if (keyboard_mode == GrabModeSync || pointer_mode == GrabModeSync) access_mode |= DixFreezeAccess; rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); if (rc != Success) return rc; time = ClientTimeToServerTime(ctime); grab = grabInfo->grab; if (grab && grab->grabtype != grabtype) *status = AlreadyGrabbed; else if (grab && !SameClient(grab, client)) *status = AlreadyGrabbed; else if ((!pWin->realized) || (confineTo && !(confineTo->realized && BorderSizeNotEmpty(dev, confineTo)))) *status = GrabNotViewable; else if ((CompareTimeStamps(time, currentTime) == LATER) || (CompareTimeStamps(time, grabInfo->grabTime) == EARLIER)) *status = GrabInvalidTime; else if (grabInfo->sync.frozen && grabInfo->sync.other && !SameClient(grabInfo->sync.other, client)) *status = GrabFrozen; else { GrabPtr tempGrab; tempGrab = AllocGrab(NULL); if (tempGrab == NULL) return BadAlloc; tempGrab->next = NULL; tempGrab->window = pWin; tempGrab->resource = client->clientAsMask; tempGrab->ownerEvents = ownerEvents; tempGrab->keyboardMode = keyboard_mode; tempGrab->pointerMode = pointer_mode; if (grabtype == CORE) tempGrab->eventMask = mask->core; else if (grabtype == XI) tempGrab->eventMask = mask->xi; else xi2mask_merge(tempGrab->xi2mask, mask->xi2mask); tempGrab->device = dev; tempGrab->cursor = RefCursor(cursor); tempGrab->confineTo = confineTo; tempGrab->grabtype = grabtype; (*grabInfo->ActivateGrab) (dev, tempGrab, time, FALSE); *status = GrabSuccess; FreeGrab(tempGrab); } return Success; } /** * Server-side protocol handling for GrabKeyboard request. * * Grabs the client's keyboard and returns success status to client. */ int ProcGrabKeyboard(ClientPtr client) { xGrabKeyboardReply rep; BYTE status; REQUEST(xGrabKeyboardReq); int result; DeviceIntPtr keyboard = PickKeyboard(client); GrabMask mask; REQUEST_SIZE_MATCH(xGrabKeyboardReq); UpdateCurrentTime(); mask.core = KeyPressMask | KeyReleaseMask; result = GrabDevice(client, keyboard, stuff->pointerMode, stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents, stuff->time, &mask, CORE, None, None, &status); if (result != Success) return result; rep = (xGrabKeyboardReply) { .type = X_Reply, .status = status, .sequenceNumber = client->sequence, .length = 0 }; WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep); return Success; } /** * Server-side protocol handling for UngrabKeyboard request. * * Deletes a possible grab on the client's keyboard. */ int ProcUngrabKeyboard(ClientPtr client) { DeviceIntPtr device = PickKeyboard(client); GrabPtr grab; TimeStamp time; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); UpdateCurrentTime(); grab = device->deviceGrab.grab; time = ClientTimeToServerTime(stuff->id); if ((CompareTimeStamps(time, currentTime) != LATER) && (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) && (grab) && SameClient(grab, client) && grab->grabtype == CORE) (*device->deviceGrab.DeactivateGrab) (device); return Success; } /** * Server-side protocol handling for QueryPointer request. * * Returns the current state and position of the client's ClientPointer to the * client. */ int ProcQueryPointer(ClientPtr client) { xQueryPointerReply rep; WindowPtr pWin, t; DeviceIntPtr mouse = PickPointer(client); DeviceIntPtr keyboard; SpritePtr pSprite; int rc; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); if (rc != Success) return rc; rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess); if (rc != Success && rc != BadAccess) return rc; keyboard = GetMaster(mouse, MASTER_KEYBOARD); pSprite = mouse->spriteInfo->sprite; if (mouse->valuator->motionHintWindow) MaybeStopHint(mouse, client); rep = (xQueryPointerReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .mask = event_get_corestate(mouse, keyboard), .root = (GetCurrentRootWindow(mouse))->drawable.id, .rootX = pSprite->hot.x, .rootY = pSprite->hot.y, .child = None }; if (pSprite->hot.pScreen == pWin->drawable.pScreen) { rep.sameScreen = xTrue; rep.winX = pSprite->hot.x - pWin->drawable.x; rep.winY = pSprite->hot.y - pWin->drawable.y; for (t = pSprite->win; t; t = t->parent) if (t->parent == pWin) { rep.child = t->drawable.id; break; } } else { rep.sameScreen = xFalse; rep.winX = 0; rep.winY = 0; } #ifdef PANORAMIX if (!noPanoramiXExtension) { rep.rootX += screenInfo.screens[0]->x; rep.rootY += screenInfo.screens[0]->y; if (stuff->id == rep.root) { rep.winX += screenInfo.screens[0]->x; rep.winY += screenInfo.screens[0]->y; } } #endif if (rc == BadAccess) { rep.mask = 0; rep.child = None; rep.rootX = 0; rep.rootY = 0; rep.winX = 0; rep.winY = 0; } WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep); return Success; } /** * Initializes the device list and the DIX sprite to sane values. Allocates * trace memory used for quick window traversal. */ void InitEvents(void) { int i; QdEventPtr qe, tmp; inputInfo.numDevices = 0; inputInfo.devices = (DeviceIntPtr) NULL; inputInfo.off_devices = (DeviceIntPtr) NULL; inputInfo.keyboard = (DeviceIntPtr) NULL; inputInfo.pointer = (DeviceIntPtr) NULL; for (i = 0; i < MAXDEVICES; i++) { DeviceIntRec dummy; memcpy(&event_filters[i], default_filter, sizeof(default_filter)); dummy.id = i; NoticeTime(&dummy, currentTime); LastEventTimeToggleResetFlag(i, FALSE); } syncEvents.replayDev = (DeviceIntPtr) NULL; syncEvents.replayWin = NullWindow; if (syncEvents.pending.next) xorg_list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next) free(qe); xorg_list_init(&syncEvents.pending); syncEvents.playingEvents = FALSE; syncEvents.time.months = 0; syncEvents.time.milliseconds = 0; /* hardly matters */ currentTime.months = 0; currentTime.milliseconds = GetTimeInMillis(); for (i = 0; i < DNPMCOUNT; i++) { DontPropagateMasks[i] = 0; DontPropagateRefCnts[i] = 0; } InputEventList = InitEventList(GetMaximumEventsNum()); if (!InputEventList) FatalError("[dix] Failed to allocate input event list.\n"); } void CloseDownEvents(void) { FreeEventList(InputEventList, GetMaximumEventsNum()); InputEventList = NULL; } #define SEND_EVENT_BIT 0x80 /** * Server-side protocol handling for SendEvent request. * * Locates the window to send the event to and forwards the event. */ int ProcSendEvent(ClientPtr client) { WindowPtr pWin; WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ DeviceIntPtr dev = PickPointer(client); DeviceIntPtr keybd = GetMaster(dev, MASTER_KEYBOARD); SpritePtr pSprite = dev->spriteInfo->sprite; REQUEST(xSendEventReq); REQUEST_SIZE_MATCH(xSendEventReq); /* libXext and other extension libraries may set the bit indicating * that this event came from a SendEvent request so remove it * since otherwise the event type may fail the range checks * and cause an invalid BadValue error to be returned. * * This is safe to do since we later add the SendEvent bit (0x80) * back in once we send the event to the client */ stuff->event.u.u.type &= ~(SEND_EVENT_BIT); /* The client's event type must be a core event type or one defined by an extension. */ if (!((stuff->event.u.u.type > X_Reply && stuff->event.u.u.type < LASTEvent) || (stuff->event.u.u.type >= EXTENSION_EVENT_BASE && stuff->event.u.u.type < (unsigned) lastEvent))) { client->errorValue = stuff->event.u.u.type; return BadValue; } /* Generic events can have variable size, but SendEvent request holds exactly 32B of event data. */ if (stuff->event.u.u.type == GenericEvent) { client->errorValue = stuff->event.u.u.type; return BadValue; } if (stuff->event.u.u.type == ClientMessage && stuff->event.u.u.detail != 8 && stuff->event.u.u.detail != 16 && stuff->event.u.u.detail != 32) { client->errorValue = stuff->event.u.u.detail; return BadValue; } if (stuff->eventMask & ~AllEventMasks) { client->errorValue = stuff->eventMask; return BadValue; } if (stuff->destination == PointerWindow) pWin = pSprite->win; else if (stuff->destination == InputFocus) { WindowPtr inputFocus = (keybd) ? keybd->focus->win : NoneWin; if (inputFocus == NoneWin) return Success; /* If the input focus is PointerRootWin, send the event to where the pointer is if possible, then perhaps propogate up to root. */ if (inputFocus == PointerRootWin) inputFocus = GetCurrentRootWindow(dev); if (IsParent(inputFocus, pSprite->win)) { effectiveFocus = inputFocus; pWin = pSprite->win; } else effectiveFocus = pWin = inputFocus; } else dixLookupWindow(&pWin, stuff->destination, client, DixSendAccess); if (!pWin) return BadWindow; if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue)) { client->errorValue = stuff->propagate; return BadValue; } stuff->event.u.u.type |= SEND_EVENT_BIT; if (stuff->propagate) { for (; pWin; pWin = pWin->parent) { if (XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, &stuff->event, 1)) return Success; if (DeliverEventsToWindow(dev, pWin, &stuff->event, 1, stuff->eventMask, NullGrab)) return Success; if (pWin == effectiveFocus) return Success; stuff->eventMask &= ~wDontPropagateMask(pWin); if (!stuff->eventMask) break; } } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, &stuff->event, 1)) DeliverEventsToWindow(dev, pWin, &stuff->event, 1, stuff->eventMask, NullGrab); return Success; } /** * Server-side protocol handling for UngrabKey request. * * Deletes a passive grab for the given key. Works on the * client's keyboard. */ int ProcUngrabKey(ClientPtr client) { REQUEST(xUngrabKeyReq); WindowPtr pWin; GrabPtr tempGrab; DeviceIntPtr keybd = PickKeyboard(client); int rc; REQUEST_SIZE_MATCH(xUngrabKeyReq); rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixGetAttrAccess); if (rc != Success) return rc; if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) || (stuff->key < keybd->key->xkbInfo->desc->min_key_code)) && (stuff->key != AnyKey)) { client->errorValue = stuff->key; return BadValue; } if ((stuff->modifiers != AnyModifier) && (stuff->modifiers & ~AllModifiersMask)) { client->errorValue = stuff->modifiers; return BadValue; } tempGrab = AllocGrab(NULL); if (!tempGrab) return BadAlloc; tempGrab->resource = client->clientAsMask; tempGrab->device = keybd; tempGrab->window = pWin; tempGrab->modifiersDetail.exact = stuff->modifiers; tempGrab->modifiersDetail.pMask = NULL; tempGrab->modifierDevice = keybd; tempGrab->type = KeyPress; tempGrab->grabtype = CORE; tempGrab->detail.exact = stuff->key; tempGrab->detail.pMask = NULL; tempGrab->next = NULL; if (!DeletePassiveGrabFromList(tempGrab)) rc = BadAlloc; FreeGrab(tempGrab); return rc; } /** * Server-side protocol handling for GrabKey request. * * Creates a grab for the client's keyboard and adds it to the list of passive * grabs. */ int ProcGrabKey(ClientPtr client) { WindowPtr pWin; REQUEST(xGrabKeyReq); GrabPtr grab; DeviceIntPtr keybd = PickKeyboard(client); int rc; GrabParameters param; GrabMask mask; REQUEST_SIZE_MATCH(xGrabKeyReq); param = (GrabParameters) { .grabtype = CORE, .ownerEvents = stuff->ownerEvents, .this_device_mode = stuff->keyboardMode, .other_devices_mode = stuff->pointerMode, .modifiers = stuff->modifiers }; rc = CheckGrabValues(client, ¶m); if (rc != Success) return rc; if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) || (stuff->key < keybd->key->xkbInfo->desc->min_key_code)) && (stuff->key != AnyKey)) { client->errorValue = stuff->key; return BadValue; } rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess); if (rc != Success) return rc; mask.core = (KeyPressMask | KeyReleaseMask); grab = CreateGrab(client->index, keybd, keybd, pWin, CORE, &mask, ¶m, KeyPress, stuff->key, NullWindow, NullCursor); if (!grab) return BadAlloc; return AddPassiveGrabToList(client, grab); } /** * Server-side protocol handling for GrabButton request. * * Creates a grab for the client's ClientPointer and adds it as a passive grab * to the list. */ int ProcGrabButton(ClientPtr client) { WindowPtr pWin, confineTo; REQUEST(xGrabButtonReq); CursorPtr cursor; GrabPtr grab; DeviceIntPtr ptr, modifierDevice; Mask access_mode = DixGrabAccess; GrabMask mask; GrabParameters param; int rc; REQUEST_SIZE_MATCH(xGrabButtonReq); UpdateCurrentTime(); if ((stuff->pointerMode != GrabModeSync) && (stuff->pointerMode != GrabModeAsync)) { client->errorValue = stuff->pointerMode; return BadValue; } if ((stuff->keyboardMode != GrabModeSync) && (stuff->keyboardMode != GrabModeAsync)) { client->errorValue = stuff->keyboardMode; return BadValue; } if ((stuff->modifiers != AnyModifier) && (stuff->modifiers & ~AllModifiersMask)) { client->errorValue = stuff->modifiers; return BadValue; } if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue)) { client->errorValue = stuff->ownerEvents; return BadValue; } if (stuff->eventMask & ~PointerGrabMask) { client->errorValue = stuff->eventMask; return BadValue; } rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess); if (rc != Success) return rc; if (stuff->confineTo == None) confineTo = NullWindow; else { rc = dixLookupWindow(&confineTo, stuff->confineTo, client, DixSetAttrAccess); if (rc != Success) return rc; } if (stuff->cursor == None) cursor = NullCursor; else { rc = dixLookupResourceByType((void **) &cursor, stuff->cursor, RT_CURSOR, client, DixUseAccess); if (rc != Success) { client->errorValue = stuff->cursor; return rc; } access_mode |= DixForceAccess; } ptr = PickPointer(client); modifierDevice = GetMaster(ptr, MASTER_KEYBOARD); if (stuff->pointerMode == GrabModeSync || stuff->keyboardMode == GrabModeSync) access_mode |= DixFreezeAccess; rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, access_mode); if (rc != Success) return rc; param = (GrabParameters) { .grabtype = CORE, .ownerEvents = stuff->ownerEvents, .this_device_mode = stuff->keyboardMode, .other_devices_mode = stuff->pointerMode, .modifiers = stuff->modifiers }; mask.core = stuff->eventMask; grab = CreateGrab(client->index, ptr, modifierDevice, pWin, CORE, &mask, ¶m, ButtonPress, stuff->button, confineTo, cursor); if (!grab) return BadAlloc; return AddPassiveGrabToList(client, grab); } /** * Server-side protocol handling for UngrabButton request. * * Deletes a passive grab on the client's ClientPointer from the list. */ int ProcUngrabButton(ClientPtr client) { REQUEST(xUngrabButtonReq); WindowPtr pWin; GrabPtr tempGrab; int rc; DeviceIntPtr ptr; REQUEST_SIZE_MATCH(xUngrabButtonReq); UpdateCurrentTime(); if ((stuff->modifiers != AnyModifier) && (stuff->modifiers & ~AllModifiersMask)) { client->errorValue = stuff->modifiers; return BadValue; } rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixReadAccess); if (rc != Success) return rc; ptr = PickPointer(client); tempGrab = AllocGrab(NULL); if (!tempGrab) return BadAlloc; tempGrab->resource = client->clientAsMask; tempGrab->device = ptr; tempGrab->window = pWin; tempGrab->modifiersDetail.exact = stuff->modifiers; tempGrab->modifiersDetail.pMask = NULL; tempGrab->modifierDevice = GetMaster(ptr, MASTER_KEYBOARD); tempGrab->type = ButtonPress; tempGrab->detail.exact = stuff->button; tempGrab->grabtype = CORE; tempGrab->detail.pMask = NULL; tempGrab->next = NULL; if (!DeletePassiveGrabFromList(tempGrab)) rc = BadAlloc; FreeGrab(tempGrab); return rc; } /** * Deactivate any grab that may be on the window, remove the focus. * Delete any XInput extension events from the window too. Does not change the * window mask. Use just before the window is deleted. * * If freeResources is set, passive grabs on the window are deleted. * * @param pWin The window to delete events from. * @param freeResources True if resources associated with the window should be * deleted. */ void DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) { WindowPtr parent; DeviceIntPtr mouse = inputInfo.pointer; DeviceIntPtr keybd = inputInfo.keyboard; FocusClassPtr focus; OtherClientsPtr oc; GrabPtr passive; GrabPtr grab; /* Deactivate any grabs performed on this window, before making any input focus changes. */ grab = mouse->deviceGrab.grab; if (grab && ((grab->window == pWin) || (grab->confineTo == pWin))) (*mouse->deviceGrab.DeactivateGrab) (mouse); /* Deactivating a keyboard grab should cause focus events. */ grab = keybd->deviceGrab.grab; if (grab && (grab->window == pWin)) (*keybd->deviceGrab.DeactivateGrab) (keybd); /* And now the real devices */ for (mouse = inputInfo.devices; mouse; mouse = mouse->next) { grab = mouse->deviceGrab.grab; if (grab && ((grab->window == pWin) || (grab->confineTo == pWin))) (*mouse->deviceGrab.DeactivateGrab) (mouse); } for (keybd = inputInfo.devices; keybd; keybd = keybd->next) { if (IsKeyboardDevice(keybd)) { focus = keybd->focus; /* If the focus window is a root window (ie. has no parent) then don't delete the focus from it. */ if ((pWin == focus->win) && (pWin->parent != NullWindow)) { int focusEventMode = NotifyNormal; /* If a grab is in progress, then alter the mode of focus events. */ if (keybd->deviceGrab.grab) focusEventMode = NotifyWhileGrabbed; switch (focus->revert) { case RevertToNone: DoFocusEvents(keybd, pWin, NoneWin, focusEventMode); focus->win = NoneWin; focus->traceGood = 0; break; case RevertToParent: parent = pWin; do { parent = parent->parent; focus->traceGood--; } while (!parent->realized /* This would be a good protocol change -- windows being reparented during SaveSet processing would cause the focus to revert to the nearest enclosing window which will survive the death of the exiting client, instead of ending up reverting to a dying window and thence to None */ #ifdef NOTDEF || wClient(parent)->clientGone #endif ); if (!ActivateFocusInGrab(keybd, pWin, parent)) DoFocusEvents(keybd, pWin, parent, focusEventMode); focus->win = parent; focus->revert = RevertToNone; break; case RevertToPointerRoot: if (!ActivateFocusInGrab(keybd, pWin, PointerRootWin)) DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode); focus->win = PointerRootWin; focus->traceGood = 0; break; } } } if (IsPointerDevice(keybd)) { if (keybd->valuator->motionHintWindow == pWin) keybd->valuator->motionHintWindow = NullWindow; } } if (freeResources) { if (pWin->dontPropagate) DontPropagateRefCnts[pWin->dontPropagate]--; while ((oc = wOtherClients(pWin))) FreeResource(oc->resource, RT_NONE); while ((passive = wPassiveGrabs(pWin))) FreeResource(passive->resource, RT_NONE); } DeleteWindowFromAnyExtEvents(pWin, freeResources); } /** * Call this whenever some window at or below pWin has changed geometry. If * there is a grab on the window, the cursor will be re-confined into the * window. */ void CheckCursorConfinement(WindowPtr pWin) { GrabPtr grab; WindowPtr confineTo; DeviceIntPtr pDev; #ifdef PANORAMIX if (!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return; #endif for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { if (DevHasCursor(pDev)) { grab = pDev->deviceGrab.grab; if (grab && (confineTo = grab->confineTo)) { if (!BorderSizeNotEmpty(pDev, confineTo)) (*pDev->deviceGrab.DeactivateGrab) (pDev); else if ((pWin == confineTo) || IsParent(pWin, confineTo)) ConfineCursorToWindow(pDev, confineTo, TRUE, TRUE); } } } } Mask EventMaskForClient(WindowPtr pWin, ClientPtr client) { OtherClientsPtr other; if (wClient(pWin) == client) return pWin->eventMask; for (other = wOtherClients(pWin); other; other = other->next) { if (SameClient(other, client)) return other->mask; } return 0; } /** * Server-side protocol handling for RecolorCursor request. */ int ProcRecolorCursor(ClientPtr client) { CursorPtr pCursor; int rc, nscr; ScreenPtr pscr; Bool displayed; SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; REQUEST(xRecolorCursorReq); REQUEST_SIZE_MATCH(xRecolorCursorReq); rc = dixLookupResourceByType((void **) &pCursor, stuff->cursor, RT_CURSOR, client, DixWriteAccess); if (rc != Success) { client->errorValue = stuff->cursor; return rc; } pCursor->foreRed = stuff->foreRed; pCursor->foreGreen = stuff->foreGreen; pCursor->foreBlue = stuff->foreBlue; pCursor->backRed = stuff->backRed; pCursor->backGreen = stuff->backGreen; pCursor->backBlue = stuff->backBlue; for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { pscr = screenInfo.screens[nscr]; #ifdef PANORAMIX if (!noPanoramiXExtension) displayed = (pscr == pSprite->screen); else #endif displayed = (pscr == pSprite->hotPhys.pScreen); (*pscr->RecolorCursor) (PickPointer(client), pscr, pCursor, (pCursor == pSprite->current) && displayed); } return Success; } /** * Write the given events to a client, swapping the byte order if necessary. * To swap the byte ordering, a callback is called that has to be set up for * the given event type. * * In the case of DeviceMotionNotify trailed by DeviceValuators, the events * can be more than one. Usually it's just one event. * * Do not modify the event structure passed in. See comment below. * * @param pClient Client to send events to. * @param count Number of events. * @param events The event list. */ void WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) { #ifdef PANORAMIX xEvent eventCopy; #endif xEvent *eventTo, *eventFrom; int i, eventlength = sizeof(xEvent); if (!pClient || pClient == serverClient || pClient->clientGone) return; for (i = 0; i < count; i++) if ((events[i].u.u.type & 0x7f) != KeymapNotify) events[i].u.u.sequenceNumber = pClient->sequence; /* Let XKB rewrite the state, as it depends on client preferences. */ XkbFilterEvents(pClient, count, events); #ifdef PANORAMIX if (!noPanoramiXExtension && (screenInfo.screens[0]->x || screenInfo.screens[0]->y)) { switch (events->u.u.type) { case MotionNotify: case ButtonPress: case ButtonRelease: case KeyPress: case KeyRelease: case EnterNotify: case LeaveNotify: /* When multiple clients want the same event DeliverEventsToWindow passes the same event structure multiple times so we can't modify the one passed to us */ count = 1; /* should always be 1 */ memcpy(&eventCopy, events, sizeof(xEvent)); eventCopy.u.keyButtonPointer.rootX += screenInfo.screens[0]->x; eventCopy.u.keyButtonPointer.rootY += screenInfo.screens[0]->y; if (eventCopy.u.keyButtonPointer.event == eventCopy.u.keyButtonPointer.root) { eventCopy.u.keyButtonPointer.eventX += screenInfo.screens[0]->x; eventCopy.u.keyButtonPointer.eventY += screenInfo.screens[0]->y; } events = &eventCopy; break; default: break; } } #endif if (EventCallback) { EventInfoRec eventinfo; eventinfo.client = pClient; eventinfo.events = events; eventinfo.count = count; CallCallbacks(&EventCallback, (void *) &eventinfo); } #ifdef XSERVER_DTRACE if (XSERVER_SEND_EVENT_ENABLED()) { for (i = 0; i < count; i++) { XSERVER_SEND_EVENT(pClient->index, events[i].u.u.type, &events[i]); } } #endif /* Just a safety check to make sure we only have one GenericEvent, it just * makes things easier for me right now. (whot) */ for (i = 1; i < count; i++) { if (events[i].u.u.type == GenericEvent) { ErrorF("[dix] TryClientEvents: Only one GenericEvent at a time.\n"); return; } } if (events->u.u.type == GenericEvent) { eventlength += ((xGenericEvent *) events)->length * 4; } if (pClient->swapped) { if (eventlength > swapEventLen) { swapEventLen = eventlength; swapEvent = realloc(swapEvent, swapEventLen); if (!swapEvent) { FatalError("WriteEventsToClient: Out of memory.\n"); return; } } for (i = 0; i < count; i++) { eventFrom = &events[i]; eventTo = swapEvent; /* Remember to strip off the leading bit of type in case this event was sent with "SendEvent." */ (*EventSwapVector[eventFrom->u.u.type & 0177]) (eventFrom, eventTo); WriteToClient(pClient, eventlength, eventTo); } } else { /* only one GenericEvent, remember? that means either count is 1 and * eventlength is arbitrary or eventlength is 32 and count doesn't * matter. And we're all set. Woohoo. */ WriteToClient(pClient, count * eventlength, events); } } /* * Set the client pointer for the given client. * * A client can have exactly one ClientPointer. Each time a * request/reply/event is processed and the choice of devices is ambiguous * (e.g. QueryPointer request), the server will pick the ClientPointer (see * PickPointer()). * If a keyboard is needed, the first keyboard paired with the CP is used. */ int SetClientPointer(ClientPtr client, DeviceIntPtr device) { int rc = XaceHook(XACE_DEVICE_ACCESS, client, device, DixUseAccess); if (rc != Success) return rc; if (!IsMaster(device)) { ErrorF("[dix] Need master device for ClientPointer. This is a bug.\n"); return BadDevice; } else if (!device->spriteInfo->spriteOwner) { ErrorF("[dix] Device %d does not have a sprite. " "Cannot be ClientPointer\n", device->id); return BadDevice; } client->clientPtr = device; return Success; } /* PickPointer will pick an appropriate pointer for the given client. * * An "appropriate device" is (in order of priority): * 1) A device the given client has a core grab on. * 2) A device set as ClientPointer for the given client. * 3) The first master device. */ DeviceIntPtr PickPointer(ClientPtr client) { DeviceIntPtr it = inputInfo.devices; /* First, check if the client currently has a grab on a device. Even * keyboards count. */ for (it = inputInfo.devices; it; it = it->next) { GrabPtr grab = it->deviceGrab.grab; if (grab && grab->grabtype == CORE && SameClient(grab, client)) { it = GetMaster(it, MASTER_POINTER); return it; /* Always return a core grabbed device */ } } if (!client->clientPtr) { it = inputInfo.devices; while (it) { if (IsMaster(it) && it->spriteInfo->spriteOwner) { client->clientPtr = it; break; } it = it->next; } } return client->clientPtr; } /* PickKeyboard will pick an appropriate keyboard for the given client by * searching the list of devices for the keyboard device that is paired with * the client's pointer. */ DeviceIntPtr PickKeyboard(ClientPtr client) { DeviceIntPtr ptr = PickPointer(client); DeviceIntPtr kbd = GetMaster(ptr, MASTER_KEYBOARD); if (!kbd) { ErrorF("[dix] ClientPointer not paired with a keyboard. This " "is a bug.\n"); } return kbd; } /* A client that has one or more core grabs does not get core events from * devices it does not have a grab on. Legacy applications behave bad * otherwise because they are not used to it and the events interfere. * Only applies for core events. * * Return true if a core event from the device would interfere and should not * be delivered. */ Bool IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent *event) { DeviceIntPtr it = inputInfo.devices; switch (event->u.u.type) { case KeyPress: case KeyRelease: case ButtonPress: case ButtonRelease: case MotionNotify: case EnterNotify: case LeaveNotify: break; default: return FALSE; } if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client)) return FALSE; while (it) { if (it != dev) { if (it->deviceGrab.grab && SameClient(it->deviceGrab.grab, client) && !it->deviceGrab.fromPassiveGrab) { if ((IsPointerDevice(it) && IsPointerDevice(dev)) || (IsKeyboardDevice(it) && IsKeyboardDevice(dev))) return TRUE; } } it = it->next; } return FALSE; } /* PointerBarrier events are only delivered to the client that created that * barrier */ static Bool IsWrongPointerBarrierClient(ClientPtr client, DeviceIntPtr dev, xEvent *event) { xXIBarrierEvent *ev = (xXIBarrierEvent*)event; if (ev->type != GenericEvent || ev->extension != IReqCode) return FALSE; if (ev->evtype != XI_BarrierHit && ev->evtype != XI_BarrierLeave) return FALSE; return client->index != CLIENT_ID(ev->barrier); } xorg-server-1.20.13/dix/eventconvert.c0000644000175000017500000006571414100573755014560 00000000000000/* * Copyright © 2009 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * */ /** * @file eventconvert.c * This file contains event conversion routines from InternalEvent to the * matching protocol events. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include #include #include "dix.h" #include "inputstr.h" #include "misc.h" #include "eventstr.h" #include "exevents.h" #include "exglobals.h" #include "eventconvert.h" #include "inpututils.h" #include "xiquerydevice.h" #include "xkbsrv.h" #include "inpututils.h" static int countValuators(DeviceEvent *ev, int *first); static int getValuatorEvents(DeviceEvent *ev, deviceValuator * xv); static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count); static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce); static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi); static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi); static int eventToBarrierEvent(BarrierEvent *ev, xEvent **xi); static int eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi); /* Do not use, read comments below */ BOOL EventIsKeyRepeat(xEvent *event); /** * Hack to allow detectable autorepeat for core and XI1 events. * The sequence number is unused until we send to the client and can be * misused to store data. More or less, anyway. * * Do not use this. It may change any time without warning, eat your babies * and piss on your cat. */ static void EventSetKeyRepeatFlag(xEvent *event, BOOL on) { event->u.u.sequenceNumber = on; } /** * Check if the event was marked as a repeat event before. * NOTE: This is a nasty hack and should NOT be used by anyone else but * TryClientEvents. */ BOOL EventIsKeyRepeat(xEvent *event) { return ! !event->u.u.sequenceNumber; } /** * Convert the given event to the respective core event. * * Return values: * Success ... core contains the matching core event. * BadValue .. One or more values in the internal event are invalid. * BadMatch .. The event has no core equivalent. * * @param[in] event The event to convert into a core event. * @param[in] core The memory location to store the core event at. * @return Success or the matching error code. */ int EventToCore(InternalEvent *event, xEvent **core_out, int *count_out) { xEvent *core = NULL; int count = 0; int ret = BadImplementation; switch (event->any.type) { case ET_Motion: { DeviceEvent *e = &event->device_event; /* Don't create core motion event if neither x nor y are * present */ if (!BitIsOn(e->valuators.mask, 0) && !BitIsOn(e->valuators.mask, 1)) { ret = BadMatch; goto out; } } /* fallthrough */ case ET_ButtonPress: case ET_ButtonRelease: case ET_KeyPress: case ET_KeyRelease: { DeviceEvent *e = &event->device_event; if (e->detail.key > 0xFF) { ret = BadMatch; goto out; } core = calloc(1, sizeof(*core)); if (!core) return BadAlloc; count = 1; core->u.u.type = e->type - ET_KeyPress + KeyPress; core->u.u.detail = e->detail.key & 0xFF; core->u.keyButtonPointer.time = e->time; core->u.keyButtonPointer.rootX = e->root_x; core->u.keyButtonPointer.rootY = e->root_y; core->u.keyButtonPointer.state = e->corestate; core->u.keyButtonPointer.root = e->root; EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat)); ret = Success; } break; case ET_ProximityIn: case ET_ProximityOut: case ET_RawKeyPress: case ET_RawKeyRelease: case ET_RawButtonPress: case ET_RawButtonRelease: case ET_RawMotion: case ET_RawTouchBegin: case ET_RawTouchUpdate: case ET_RawTouchEnd: case ET_TouchBegin: case ET_TouchUpdate: case ET_TouchEnd: case ET_TouchOwnership: case ET_BarrierHit: case ET_BarrierLeave: ret = BadMatch; break; default: /* XXX: */ ErrorF("[dix] EventToCore: Not implemented yet \n"); ret = BadImplementation; } out: *core_out = core; *count_out = count; return ret; } /** * Convert the given event to the respective XI 1.x event and store it in * xi. xi is allocated on demand and must be freed by the caller. * count returns the number of events in xi. If count is 1, and the type of * xi is GenericEvent, then xi may be larger than 32 bytes. * * Return values: * Success ... core contains the matching core event. * BadValue .. One or more values in the internal event are invalid. * BadMatch .. The event has no XI equivalent. * * @param[in] ev The event to convert into an XI 1 event. * @param[out] xi Future memory location for the XI event. * @param[out] count Number of elements in xi. * * @return Success or the error code. */ int EventToXI(InternalEvent *ev, xEvent **xi, int *count) { switch (ev->any.type) { case ET_Motion: case ET_ButtonPress: case ET_ButtonRelease: case ET_KeyPress: case ET_KeyRelease: case ET_ProximityIn: case ET_ProximityOut: return eventToKeyButtonPointer(&ev->device_event, xi, count); case ET_DeviceChanged: case ET_RawKeyPress: case ET_RawKeyRelease: case ET_RawButtonPress: case ET_RawButtonRelease: case ET_RawMotion: case ET_RawTouchBegin: case ET_RawTouchUpdate: case ET_RawTouchEnd: case ET_TouchBegin: case ET_TouchUpdate: case ET_TouchEnd: case ET_TouchOwnership: case ET_BarrierHit: case ET_BarrierLeave: *count = 0; *xi = NULL; return BadMatch; default: break; } ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type); return BadImplementation; } /** * Convert the given event to the respective XI 2.x event and store it in xi. * xi is allocated on demand and must be freed by the caller. * * Return values: * Success ... core contains the matching core event. * BadValue .. One or more values in the internal event are invalid. * BadMatch .. The event has no XI2 equivalent. * * @param[in] ev The event to convert into an XI2 event * @param[out] xi Future memory location for the XI2 event. * * @return Success or the error code. */ int EventToXI2(InternalEvent *ev, xEvent **xi) { switch (ev->any.type) { /* Enter/FocusIn are for grabs. We don't need an actual event, since * the real events delivered are triggered elsewhere */ case ET_Enter: case ET_FocusIn: *xi = NULL; return Success; case ET_Motion: case ET_ButtonPress: case ET_ButtonRelease: case ET_KeyPress: case ET_KeyRelease: case ET_TouchBegin: case ET_TouchUpdate: case ET_TouchEnd: return eventToDeviceEvent(&ev->device_event, xi); case ET_TouchOwnership: return eventToTouchOwnershipEvent(&ev->touch_ownership_event, xi); case ET_ProximityIn: case ET_ProximityOut: *xi = NULL; return BadMatch; case ET_DeviceChanged: return eventToDeviceChanged(&ev->changed_event, xi); case ET_RawKeyPress: case ET_RawKeyRelease: case ET_RawButtonPress: case ET_RawButtonRelease: case ET_RawMotion: case ET_RawTouchBegin: case ET_RawTouchUpdate: case ET_RawTouchEnd: return eventToRawEvent(&ev->raw_event, xi); case ET_BarrierHit: case ET_BarrierLeave: return eventToBarrierEvent(&ev->barrier_event, xi); default: break; } ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type); return BadImplementation; } static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count) { int num_events; int first; /* dummy */ deviceKeyButtonPointer *kbp; /* Sorry, XI 1.x protocol restrictions. */ if (ev->detail.button > 0xFF || ev->deviceid >= 0x80) { *count = 0; return Success; } num_events = (countValuators(ev, &first) + 5) / 6; /* valuator ev */ if (num_events <= 0) { switch (ev->type) { case ET_KeyPress: case ET_KeyRelease: case ET_ButtonPress: case ET_ButtonRelease: /* no axes is ok */ break; case ET_Motion: case ET_ProximityIn: case ET_ProximityOut: *count = 0; return BadMatch; default: *count = 0; return BadImplementation; } } num_events++; /* the actual event event */ *xi = calloc(num_events, sizeof(xEvent)); if (!(*xi)) { return BadAlloc; } kbp = (deviceKeyButtonPointer *) (*xi); kbp->detail = ev->detail.button; kbp->time = ev->time; kbp->root = ev->root; kbp->root_x = ev->root_x; kbp->root_y = ev->root_y; kbp->deviceid = ev->deviceid; kbp->state = ev->corestate; EventSetKeyRepeatFlag((xEvent *) kbp, (ev->type == ET_KeyPress && ev->key_repeat)); if (num_events > 1) kbp->deviceid |= MORE_EVENTS; switch (ev->type) { case ET_Motion: kbp->type = DeviceMotionNotify; break; case ET_ButtonPress: kbp->type = DeviceButtonPress; break; case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break; case ET_KeyPress: kbp->type = DeviceKeyPress; break; case ET_KeyRelease: kbp->type = DeviceKeyRelease; break; case ET_ProximityIn: kbp->type = ProximityIn; break; case ET_ProximityOut: kbp->type = ProximityOut; break; default: break; } if (num_events > 1) { getValuatorEvents(ev, (deviceValuator *) (kbp + 1)); } *count = num_events; return Success; } /** * Set first to the first valuator in the event ev and return the number of * valuators from first to the last set valuator. */ static int countValuators(DeviceEvent *ev, int *first) { int first_valuator = -1, last_valuator = -1, num_valuators = 0; int i; for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) { if (BitIsOn(ev->valuators.mask, i)) { if (first_valuator == -1) first_valuator = i; last_valuator = i; } } if (first_valuator != -1) { num_valuators = last_valuator - first_valuator + 1; *first = first_valuator; } return num_valuators; } static int getValuatorEvents(DeviceEvent *ev, deviceValuator * xv) { int i; int state = 0; int first_valuator, num_valuators; num_valuators = countValuators(ev, &first_valuator); if (num_valuators > 0) { DeviceIntPtr dev = NULL; dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess); /* State needs to be assembled BEFORE the device is updated. */ state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo-> state) : 0; state |= (dev && dev->button) ? (dev->button->state) : 0; } for (i = 0; i < num_valuators; i += 6, xv++) { INT32 *valuators = &xv->valuator0; // Treat all 6 vals as an array int j; xv->type = DeviceValuator; xv->first_valuator = first_valuator + i; xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i); xv->deviceid = ev->deviceid; xv->device_state = state; /* Unset valuators in masked valuator events have the proper data values * in the case of an absolute axis in between two set valuators. */ for (j = 0; j < xv->num_valuators; j++) valuators[j] = ev->valuators.data[xv->first_valuator + j]; if (i + 6 < num_valuators) xv->deviceid |= MORE_EVENTS; } return (num_valuators + 5) / 6; } static int appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo * info) { uint32_t *kc; int i; info->type = XIKeyClass; info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1; info->length = sizeof(xXIKeyInfo) / 4 + info->num_keycodes; info->sourceid = dce->sourceid; kc = (uint32_t *) &info[1]; for (i = 0; i < info->num_keycodes; i++) *kc++ = i + dce->keys.min_keycode; return info->length * 4; } static int appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo * info) { unsigned char *bits; int mask_len; mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons)); info->type = XIButtonClass; info->num_buttons = dce->buttons.num_buttons; info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + info->num_buttons + mask_len; info->sourceid = dce->sourceid; bits = (unsigned char *) &info[1]; memset(bits, 0, mask_len * 4); /* FIXME: is_down? */ bits += mask_len * 4; memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom)); return info->length * 4; } static int appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo * info, int axisnumber) { info->type = XIValuatorClass; info->length = sizeof(xXIValuatorInfo) / 4; info->label = dce->valuators[axisnumber].name; info->min.integral = dce->valuators[axisnumber].min; info->min.frac = 0; info->max.integral = dce->valuators[axisnumber].max; info->max.frac = 0; info->value = double_to_fp3232(dce->valuators[axisnumber].value); info->resolution = dce->valuators[axisnumber].resolution; info->number = axisnumber; info->mode = dce->valuators[axisnumber].mode; info->sourceid = dce->sourceid; return info->length * 4; } static int appendScrollInfo(DeviceChangedEvent *dce, xXIScrollInfo * info, int axisnumber) { if (dce->valuators[axisnumber].scroll.type == SCROLL_TYPE_NONE) return 0; info->type = XIScrollClass; info->length = sizeof(xXIScrollInfo) / 4; info->number = axisnumber; switch (dce->valuators[axisnumber].scroll.type) { case SCROLL_TYPE_VERTICAL: info->scroll_type = XIScrollTypeVertical; break; case SCROLL_TYPE_HORIZONTAL: info->scroll_type = XIScrollTypeHorizontal; break; default: ErrorF("[Xi] Unknown scroll type %d. This is a bug.\n", dce->valuators[axisnumber].scroll.type); break; } info->increment = double_to_fp3232(dce->valuators[axisnumber].scroll.increment); info->sourceid = dce->sourceid; info->flags = 0; if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_DONT_EMULATE) info->flags |= XIScrollFlagNoEmulation; if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_PREFERRED) info->flags |= XIScrollFlagPreferred; return info->length * 4; } static int eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi) { xXIDeviceChangedEvent *dcce; int len = sizeof(xXIDeviceChangedEvent); int nkeys; char *ptr; if (dce->buttons.num_buttons) { len += sizeof(xXIButtonInfo); len += dce->buttons.num_buttons * sizeof(Atom); /* button names */ len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons)); } if (dce->num_valuators) { int i; len += sizeof(xXIValuatorInfo) * dce->num_valuators; for (i = 0; i < dce->num_valuators; i++) if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE) len += sizeof(xXIScrollInfo); } nkeys = (dce->keys.max_keycode > 0) ? dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0; if (nkeys > 0) { len += sizeof(xXIKeyInfo); len += sizeof(CARD32) * nkeys; /* keycodes */ } dcce = calloc(1, len); if (!dcce) { ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n"); return BadAlloc; } dcce->type = GenericEvent; dcce->extension = IReqCode; dcce->evtype = XI_DeviceChanged; dcce->time = dce->time; dcce->deviceid = dce->deviceid; dcce->sourceid = dce->sourceid; dcce->reason = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch; dcce->num_classes = 0; dcce->length = bytes_to_int32(len - sizeof(xEvent)); ptr = (char *) &dcce[1]; if (dce->buttons.num_buttons) { dcce->num_classes++; ptr += appendButtonInfo(dce, (xXIButtonInfo *) ptr); } if (nkeys) { dcce->num_classes++; ptr += appendKeyInfo(dce, (xXIKeyInfo *) ptr); } if (dce->num_valuators) { int i; dcce->num_classes += dce->num_valuators; for (i = 0; i < dce->num_valuators; i++) ptr += appendValuatorInfo(dce, (xXIValuatorInfo *) ptr, i); for (i = 0; i < dce->num_valuators; i++) { if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE) { dcce->num_classes++; ptr += appendScrollInfo(dce, (xXIScrollInfo *) ptr, i); } } } *xi = (xEvent *) dcce; return Success; } static int count_bits(unsigned char *ptr, int len) { int bits = 0; unsigned int i; unsigned char x; for (i = 0; i < len; i++) { x = ptr[i]; while (x > 0) { bits += (x & 0x1); x >>= 1; } } return bits; } static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi) { int len = sizeof(xXIDeviceEvent); xXIDeviceEvent *xde; int i, btlen, vallen; char *ptr; FP3232 *axisval; /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same * with MAX_VALUATORS below */ /* btlen is in 4 byte units */ btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS)); len += btlen * 4; /* buttonmask len */ vallen = count_bits(ev->valuators.mask, ARRAY_SIZE(ev->valuators.mask)); len += vallen * 2 * sizeof(uint32_t); /* axisvalues */ vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); len += vallen * 4; /* valuators mask */ *xi = calloc(1, len); xde = (xXIDeviceEvent *) * xi; xde->type = GenericEvent; xde->extension = IReqCode; xde->evtype = GetXI2Type(ev->type); xde->time = ev->time; xde->length = bytes_to_int32(len - sizeof(xEvent)); if (IsTouchEvent((InternalEvent *) ev)) xde->detail = ev->touchid; else xde->detail = ev->detail.button; xde->root = ev->root; xde->buttons_len = btlen; xde->valuators_len = vallen; xde->deviceid = ev->deviceid; xde->sourceid = ev->sourceid; xde->root_x = double_to_fp1616(ev->root_x + ev->root_x_frac); xde->root_y = double_to_fp1616(ev->root_y + ev->root_y_frac); if (IsTouchEvent((InternalEvent *)ev)) { if (ev->type == ET_TouchUpdate) xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0; if (ev->flags & TOUCH_POINTER_EMULATED) xde->flags |= XITouchEmulatingPointer; } else { xde->flags = ev->flags; if (ev->key_repeat) xde->flags |= XIKeyRepeat; } xde->mods.base_mods = ev->mods.base; xde->mods.latched_mods = ev->mods.latched; xde->mods.locked_mods = ev->mods.locked; xde->mods.effective_mods = ev->mods.effective; xde->group.base_group = ev->group.base; xde->group.latched_group = ev->group.latched; xde->group.locked_group = ev->group.locked; xde->group.effective_group = ev->group.effective; ptr = (char *) &xde[1]; for (i = 0; i < sizeof(ev->buttons) * 8; i++) { if (BitIsOn(ev->buttons, i)) SetBit(ptr, i); } ptr += xde->buttons_len * 4; axisval = (FP3232 *) (ptr + xde->valuators_len * 4); for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) { if (BitIsOn(ev->valuators.mask, i)) { SetBit(ptr, i); *axisval = double_to_fp3232(ev->valuators.data[i]); axisval++; } } return Success; } static int eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi) { int len = sizeof(xXITouchOwnershipEvent); xXITouchOwnershipEvent *xtoe; *xi = calloc(1, len); xtoe = (xXITouchOwnershipEvent *) * xi; xtoe->type = GenericEvent; xtoe->extension = IReqCode; xtoe->length = bytes_to_int32(len - sizeof(xEvent)); xtoe->evtype = GetXI2Type(ev->type); xtoe->deviceid = ev->deviceid; xtoe->time = ev->time; xtoe->sourceid = ev->sourceid; xtoe->touchid = ev->touchid; xtoe->flags = 0; /* we don't have wire flags for ownership yet */ return Success; } static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi) { xXIRawEvent *raw; int vallen, nvals; int i, len = sizeof(xXIRawEvent); char *ptr; FP3232 *axisval, *axisval_raw; nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)); len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once raw, once processed */ vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); len += vallen * 4; /* valuators mask */ *xi = calloc(1, len); raw = (xXIRawEvent *) * xi; raw->type = GenericEvent; raw->extension = IReqCode; raw->evtype = GetXI2Type(ev->type); raw->time = ev->time; raw->length = bytes_to_int32(len - sizeof(xEvent)); raw->detail = ev->detail.button; raw->deviceid = ev->deviceid; raw->sourceid = ev->sourceid; raw->valuators_len = vallen; raw->flags = ev->flags; ptr = (char *) &raw[1]; axisval = (FP3232 *) (ptr + raw->valuators_len * 4); axisval_raw = axisval + nvals; for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) { if (BitIsOn(ev->valuators.mask, i)) { SetBit(ptr, i); *axisval = double_to_fp3232(ev->valuators.data[i]); *axisval_raw = double_to_fp3232(ev->valuators.data_raw[i]); axisval++; axisval_raw++; } } return Success; } static int eventToBarrierEvent(BarrierEvent *ev, xEvent **xi) { xXIBarrierEvent *barrier; int len = sizeof(xXIBarrierEvent); *xi = calloc(1, len); barrier = (xXIBarrierEvent*) *xi; barrier->type = GenericEvent; barrier->extension = IReqCode; barrier->evtype = GetXI2Type(ev->type); barrier->length = bytes_to_int32(len - sizeof(xEvent)); barrier->deviceid = ev->deviceid; barrier->sourceid = ev->sourceid; barrier->time = ev->time; barrier->event = ev->window; barrier->root = ev->root; barrier->dx = double_to_fp3232(ev->dx); barrier->dy = double_to_fp3232(ev->dy); barrier->dtime = ev->dt; barrier->flags = ev->flags; barrier->eventid = ev->event_id; barrier->barrier = ev->barrierid; barrier->root_x = double_to_fp1616(ev->root_x); barrier->root_y = double_to_fp1616(ev->root_y); return Success; } /** * Return the corresponding core type for the given event or 0 if no core * equivalent exists. */ int GetCoreType(enum EventType type) { int coretype = 0; switch (type) { case ET_Motion: coretype = MotionNotify; break; case ET_ButtonPress: coretype = ButtonPress; break; case ET_ButtonRelease: coretype = ButtonRelease; break; case ET_KeyPress: coretype = KeyPress; break; case ET_KeyRelease: coretype = KeyRelease; break; default: break; } return coretype; } /** * Return the corresponding XI 1.x type for the given event or 0 if no * equivalent exists. */ int GetXIType(enum EventType type) { int xitype = 0; switch (type) { case ET_Motion: xitype = DeviceMotionNotify; break; case ET_ButtonPress: xitype = DeviceButtonPress; break; case ET_ButtonRelease: xitype = DeviceButtonRelease; break; case ET_KeyPress: xitype = DeviceKeyPress; break; case ET_KeyRelease: xitype = DeviceKeyRelease; break; case ET_ProximityIn: xitype = ProximityIn; break; case ET_ProximityOut: xitype = ProximityOut; break; default: break; } return xitype; } /** * Return the corresponding XI 2.x type for the given event or 0 if no * equivalent exists. */ int GetXI2Type(enum EventType type) { int xi2type = 0; switch (type) { case ET_Motion: xi2type = XI_Motion; break; case ET_ButtonPress: xi2type = XI_ButtonPress; break; case ET_ButtonRelease: xi2type = XI_ButtonRelease; break; case ET_KeyPress: xi2type = XI_KeyPress; break; case ET_KeyRelease: xi2type = XI_KeyRelease; break; case ET_Enter: xi2type = XI_Enter; break; case ET_Leave: xi2type = XI_Leave; break; case ET_Hierarchy: xi2type = XI_HierarchyChanged; break; case ET_DeviceChanged: xi2type = XI_DeviceChanged; break; case ET_RawKeyPress: xi2type = XI_RawKeyPress; break; case ET_RawKeyRelease: xi2type = XI_RawKeyRelease; break; case ET_RawButtonPress: xi2type = XI_RawButtonPress; break; case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break; case ET_RawMotion: xi2type = XI_RawMotion; break; case ET_RawTouchBegin: xi2type = XI_RawTouchBegin; break; case ET_RawTouchUpdate: xi2type = XI_RawTouchUpdate; break; case ET_RawTouchEnd: xi2type = XI_RawTouchEnd; break; case ET_FocusIn: xi2type = XI_FocusIn; break; case ET_FocusOut: xi2type = XI_FocusOut; break; case ET_TouchBegin: xi2type = XI_TouchBegin; break; case ET_TouchEnd: xi2type = XI_TouchEnd; break; case ET_TouchUpdate: xi2type = XI_TouchUpdate; break; case ET_TouchOwnership: xi2type = XI_TouchOwnership; break; case ET_BarrierHit: xi2type = XI_BarrierHit; break; case ET_BarrierLeave: xi2type = XI_BarrierLeave; break; default: break; } return xi2type; } xorg-server-1.20.13/dix/extension.c0000644000175000017500000002136414100573755014043 00000000000000/*********************************************************** Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include #include "misc.h" #include "dixstruct.h" #include "extnsionst.h" #include "gcstruct.h" #include "scrnintstr.h" #include "dispatch.h" #include "privates.h" #include "registry.h" #include "xace.h" #define LAST_ERROR 255 static ExtensionEntry **extensions = (ExtensionEntry **) NULL; int lastEvent = EXTENSION_EVENT_BASE; static int lastError = FirstExtensionError; static unsigned int NumExtensions = 0; ExtensionEntry * AddExtension(const char *name, int NumEvents, int NumErrors, int (*MainProc) (ClientPtr c1), int (*SwappedMainProc) (ClientPtr c2), void (*CloseDownProc) (ExtensionEntry * e), unsigned short (*MinorOpcodeProc) (ClientPtr c3)) { int i; ExtensionEntry *ext, **newexts; if (!MainProc || !SwappedMainProc || !MinorOpcodeProc) return ((ExtensionEntry *) NULL); if ((lastEvent + NumEvents > MAXEVENTS) || (unsigned) (lastError + NumErrors > LAST_ERROR)) { LogMessage(X_ERROR, "Not enabling extension %s: maximum number of " "events or errors exceeded.\n", name); return ((ExtensionEntry *) NULL); } ext = calloc(sizeof(ExtensionEntry), 1); if (!ext) return NULL; if (!dixAllocatePrivates(&ext->devPrivates, PRIVATE_EXTENSION)) { free(ext); return NULL; } ext->name = strdup(name); if (!ext->name) { dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION); free(ext); return ((ExtensionEntry *) NULL); } i = NumExtensions; newexts = reallocarray(extensions, i + 1, sizeof(ExtensionEntry *)); if (!newexts) { free((void *) ext->name); dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION); free(ext); return ((ExtensionEntry *) NULL); } NumExtensions++; extensions = newexts; extensions[i] = ext; ext->index = i; ext->base = i + EXTENSION_BASE; ext->CloseDown = CloseDownProc; ext->MinorOpcode = MinorOpcodeProc; ProcVector[i + EXTENSION_BASE] = MainProc; SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc; if (NumEvents) { ext->eventBase = lastEvent; ext->eventLast = lastEvent + NumEvents; lastEvent += NumEvents; } else { ext->eventBase = 0; ext->eventLast = 0; } if (NumErrors) { ext->errorBase = lastError; ext->errorLast = lastError + NumErrors; lastError += NumErrors; } else { ext->errorBase = 0; ext->errorLast = 0; } #ifdef X_REGISTRY_REQUEST RegisterExtensionNames(ext); #endif return ext; } static int FindExtension(const char *extname, int len) { int i; for (i = 0; i < NumExtensions; i++) { if ((strlen(extensions[i]->name) == len) && !strncmp(extname, extensions[i]->name, len)) break; } return ((i == NumExtensions) ? -1 : i); } /* * CheckExtension returns the extensions[] entry for the requested * extension name. Maybe this could just return a Bool instead? */ ExtensionEntry * CheckExtension(const char *extname) { int n; n = FindExtension(extname, strlen(extname)); if (n != -1) return extensions[n]; else return NULL; } /* * Added as part of Xace. */ ExtensionEntry * GetExtensionEntry(int major) { if (major < EXTENSION_BASE) return NULL; major -= EXTENSION_BASE; if (major >= NumExtensions) return NULL; return extensions[major]; } unsigned short StandardMinorOpcode(ClientPtr client) { return ((xReq *) client->requestBuffer)->data; } void CloseDownExtensions(void) { int i; for (i = NumExtensions - 1; i >= 0; i--) { if (extensions[i]->CloseDown) extensions[i]->CloseDown(extensions[i]); NumExtensions = i; free((void *) extensions[i]->name); dixFreePrivates(extensions[i]->devPrivates, PRIVATE_EXTENSION); free(extensions[i]); } free(extensions); extensions = (ExtensionEntry **) NULL; lastEvent = EXTENSION_EVENT_BASE; lastError = FirstExtensionError; } static Bool ExtensionAvailable(ClientPtr client, ExtensionEntry *ext) { if (XaceHook(XACE_EXT_ACCESS, client, ext) != Success) return FALSE; if (!ext->base) return FALSE; return TRUE; } int ProcQueryExtension(ClientPtr client) { xQueryExtensionReply reply; int i; REQUEST(xQueryExtensionReq); REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes); reply = (xQueryExtensionReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .major_opcode = 0 }; if (!NumExtensions) reply.present = xFalse; else { i = FindExtension((char *) &stuff[1], stuff->nbytes); if (i < 0 || !ExtensionAvailable(client, extensions[i])) reply.present = xFalse; else { reply.present = xTrue; reply.major_opcode = extensions[i]->base; reply.first_event = extensions[i]->eventBase; reply.first_error = extensions[i]->errorBase; } } WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply); return Success; } int ProcListExtensions(ClientPtr client) { xListExtensionsReply reply; char *bufptr, *buffer; int total_length = 0; REQUEST_SIZE_MATCH(xReq); reply = (xListExtensionsReply) { .type = X_Reply, .nExtensions = 0, .sequenceNumber = client->sequence, .length = 0 }; buffer = NULL; if (NumExtensions) { int i; for (i = 0; i < NumExtensions; i++) { /* call callbacks to find out whether to show extension */ if (!ExtensionAvailable(client, extensions[i])) continue; total_length += strlen(extensions[i]->name) + 1; reply.nExtensions += 1; } reply.length = bytes_to_int32(total_length); buffer = bufptr = malloc(total_length); if (!buffer) return BadAlloc; for (i = 0; i < NumExtensions; i++) { int len; if (!ExtensionAvailable(client, extensions[i])) continue; *bufptr++ = len = strlen(extensions[i]->name); memmove(bufptr, extensions[i]->name, len); bufptr += len; } } WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply); if (reply.length) WriteToClient(client, total_length, buffer); free(buffer); return Success; } xorg-server-1.20.13/dix/gc.c0000644000175000017500000007565214100573755012431 00000000000000/*********************************************************** Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include #include #include "misc.h" #include "resource.h" #include "gcstruct.h" #include "pixmapstr.h" #include "dixfontstr.h" #include "scrnintstr.h" #include "region.h" #include "dixstruct.h" #include "privates.h" #include "dix.h" #include "xace.h" #include extern FontPtr defaultFont; static Bool CreateDefaultTile(GCPtr pGC); static unsigned char DefaultDash[2] = { 4, 4 }; void ValidateGC(DrawablePtr pDraw, GC * pGC) { (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw); pGC->stateChanges = 0; pGC->serialNumber = pDraw->serialNumber; } /* * ChangeGC/ChangeGCXIDs: * * The client performing the gc change must be passed so that access * checks can be performed on any tiles, stipples, or fonts that are * specified. ddxen can call this too; they should normally pass * NullClient for the client since any access checking should have * already been done at a higher level. * * If you have any XIDs, you must use ChangeGCXIDs: * * CARD32 v[2]; * v[0] = FillTiled; * v[1] = pid; * ChangeGCXIDs(client, pGC, GCFillStyle|GCTile, v); * * However, if you need to pass a pointer to a pixmap or font, you must * use ChangeGC: * * ChangeGCVal v[2]; * v[0].val = FillTiled; * v[1].ptr = pPixmap; * ChangeGC(client, pGC, GCFillStyle|GCTile, v); * * If you have neither XIDs nor pointers, you can use either function, * but ChangeGC will do less work. * * ChangeGCVal v[2]; * v[0].val = foreground; * v[1].val = background; * ChangeGC(client, pGC, GCForeground|GCBackground, v); */ #define NEXTVAL(_type, _var) { \ _var = (_type)(pUnion->val); pUnion++; \ } #define NEXT_PTR(_type, _var) { \ _var = (_type)pUnion->ptr; pUnion++; } int ChangeGC(ClientPtr client, GC * pGC, BITS32 mask, ChangeGCValPtr pUnion) { BITS32 index2; int error = 0; PixmapPtr pPixmap; BITS32 maskQ; assert(pUnion); pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; maskQ = mask; /* save these for when we walk the GCque */ while (mask && !error) { index2 = (BITS32) lowbit(mask); mask &= ~index2; pGC->stateChanges |= index2; switch (index2) { case GCFunction: { CARD8 newalu; NEXTVAL(CARD8, newalu); if (newalu <= GXset) pGC->alu = newalu; else { if (client) client->errorValue = newalu; error = BadValue; } break; } case GCPlaneMask: NEXTVAL(unsigned long, pGC->planemask); break; case GCForeground: NEXTVAL(unsigned long, pGC->fgPixel); /* * this is for CreateGC */ if (!pGC->tileIsPixel && !pGC->tile.pixmap) { pGC->tileIsPixel = TRUE; pGC->tile.pixel = pGC->fgPixel; } break; case GCBackground: NEXTVAL(unsigned long, pGC->bgPixel); break; case GCLineWidth: /* ??? line width is a CARD16 */ NEXTVAL(CARD16, pGC->lineWidth); break; case GCLineStyle: { unsigned int newlinestyle; NEXTVAL(unsigned int, newlinestyle); if (newlinestyle <= LineDoubleDash) pGC->lineStyle = newlinestyle; else { if (client) client->errorValue = newlinestyle; error = BadValue; } break; } case GCCapStyle: { unsigned int newcapstyle; NEXTVAL(unsigned int, newcapstyle); if (newcapstyle <= CapProjecting) pGC->capStyle = newcapstyle; else { if (client) client->errorValue = newcapstyle; error = BadValue; } break; } case GCJoinStyle: { unsigned int newjoinstyle; NEXTVAL(unsigned int, newjoinstyle); if (newjoinstyle <= JoinBevel) pGC->joinStyle = newjoinstyle; else { if (client) client->errorValue = newjoinstyle; error = BadValue; } break; } case GCFillStyle: { unsigned int newfillstyle; NEXTVAL(unsigned int, newfillstyle); if (newfillstyle <= FillOpaqueStippled) pGC->fillStyle = newfillstyle; else { if (client) client->errorValue = newfillstyle; error = BadValue; } break; } case GCFillRule: { unsigned int newfillrule; NEXTVAL(unsigned int, newfillrule); if (newfillrule <= WindingRule) pGC->fillRule = newfillrule; else { if (client) client->errorValue = newfillrule; error = BadValue; } break; } case GCTile: NEXT_PTR(PixmapPtr, pPixmap); if ((pPixmap->drawable.depth != pGC->depth) || (pPixmap->drawable.pScreen != pGC->pScreen)) { error = BadMatch; } else { pPixmap->refcnt++; if (!pGC->tileIsPixel) (*pGC->pScreen->DestroyPixmap) (pGC->tile.pixmap); pGC->tileIsPixel = FALSE; pGC->tile.pixmap = pPixmap; } break; case GCStipple: NEXT_PTR(PixmapPtr, pPixmap); if (pPixmap && ((pPixmap->drawable.depth != 1) || (pPixmap->drawable.pScreen != pGC->pScreen))) { error = BadMatch; } else { if (pPixmap) pPixmap->refcnt++; if (pGC->stipple) (*pGC->pScreen->DestroyPixmap) (pGC->stipple); pGC->stipple = pPixmap; } break; case GCTileStipXOrigin: NEXTVAL(INT16, pGC->patOrg.x); break; case GCTileStipYOrigin: NEXTVAL(INT16, pGC->patOrg.y); break; case GCFont: { FontPtr pFont; NEXT_PTR(FontPtr, pFont); pFont->refcnt++; if (pGC->font) CloseFont(pGC->font, (Font) 0); pGC->font = pFont; break; } case GCSubwindowMode: { unsigned int newclipmode; NEXTVAL(unsigned int, newclipmode); if (newclipmode <= IncludeInferiors) pGC->subWindowMode = newclipmode; else { if (client) client->errorValue = newclipmode; error = BadValue; } break; } case GCGraphicsExposures: { unsigned int newge; NEXTVAL(unsigned int, newge); if (newge <= xTrue) pGC->graphicsExposures = newge; else { if (client) client->errorValue = newge; error = BadValue; } break; } case GCClipXOrigin: NEXTVAL(INT16, pGC->clipOrg.x); break; case GCClipYOrigin: NEXTVAL(INT16, pGC->clipOrg.y); break; case GCClipMask: NEXT_PTR(PixmapPtr, pPixmap); if (pPixmap) { if ((pPixmap->drawable.depth != 1) || (pPixmap->drawable.pScreen != pGC->pScreen)) { error = BadMatch; break; } pPixmap->refcnt++; } (*pGC->funcs->ChangeClip) (pGC, pPixmap ? CT_PIXMAP : CT_NONE, (void *) pPixmap, 0); break; case GCDashOffset: NEXTVAL(INT16, pGC->dashOffset); break; case GCDashList: { CARD8 newdash; NEXTVAL(CARD8, newdash); if (newdash == 4) { if (pGC->dash != DefaultDash) { free(pGC->dash); pGC->numInDashList = 2; pGC->dash = DefaultDash; } } else if (newdash != 0) { unsigned char *dash; dash = malloc(2 * sizeof(unsigned char)); if (dash) { if (pGC->dash != DefaultDash) free(pGC->dash); pGC->numInDashList = 2; pGC->dash = dash; dash[0] = newdash; dash[1] = newdash; } else error = BadAlloc; } else { if (client) client->errorValue = newdash; error = BadValue; } break; } case GCArcMode: { unsigned int newarcmode; NEXTVAL(unsigned int, newarcmode); if (newarcmode <= ArcPieSlice) pGC->arcMode = newarcmode; else { if (client) client->errorValue = newarcmode; error = BadValue; } break; } default: if (client) client->errorValue = maskQ; error = BadValue; break; } } /* end while mask && !error */ if (pGC->fillStyle == FillTiled && pGC->tileIsPixel) { if (!CreateDefaultTile(pGC)) { pGC->fillStyle = FillSolid; error = BadAlloc; } } (*pGC->funcs->ChangeGC) (pGC, maskQ); return error; } #undef NEXTVAL #undef NEXT_PTR static const struct { BITS32 mask; RESTYPE type; Mask access_mode; } xidfields[] = { {GCTile, RT_PIXMAP, DixReadAccess}, {GCStipple, RT_PIXMAP, DixReadAccess}, {GCFont, RT_FONT, DixUseAccess}, {GCClipMask, RT_PIXMAP, DixReadAccess}, }; int ChangeGCXIDs(ClientPtr client, GC * pGC, BITS32 mask, CARD32 *pC32) { ChangeGCVal vals[GCLastBit + 1]; int i; if (mask & ~GCAllBits) { client->errorValue = mask; return BadValue; } for (i = Ones(mask); i--;) vals[i].val = pC32[i]; for (i = 0; i < ARRAY_SIZE(xidfields); ++i) { int offset, rc; if (!(mask & xidfields[i].mask)) continue; offset = Ones(mask & (xidfields[i].mask - 1)); if (xidfields[i].mask == GCClipMask && vals[offset].val == None) { vals[offset].ptr = NullPixmap; continue; } rc = dixLookupResourceByType(&vals[offset].ptr, vals[offset].val, xidfields[i].type, client, xidfields[i].access_mode); if (rc != Success) { client->errorValue = vals[offset].val; return rc; } } return ChangeGC(client, pGC, mask, vals); } static GCPtr NewGCObject(ScreenPtr pScreen, int depth) { GCPtr pGC; pGC = dixAllocateScreenObjectWithPrivates(pScreen, GC, PRIVATE_GC); if (!pGC) { return (GCPtr) NULL; } pGC->pScreen = pScreen; pGC->depth = depth; pGC->alu = GXcopy; /* dst <- src */ pGC->planemask = ~0; pGC->serialNumber = 0; pGC->funcs = 0; pGC->fgPixel = 0; pGC->bgPixel = 1; pGC->lineWidth = 0; pGC->lineStyle = LineSolid; pGC->capStyle = CapButt; pGC->joinStyle = JoinMiter; pGC->fillStyle = FillSolid; pGC->fillRule = EvenOddRule; pGC->arcMode = ArcPieSlice; pGC->tile.pixel = 0; pGC->tile.pixmap = NullPixmap; pGC->tileIsPixel = TRUE; pGC->patOrg.x = 0; pGC->patOrg.y = 0; pGC->subWindowMode = ClipByChildren; pGC->graphicsExposures = TRUE; pGC->clipOrg.x = 0; pGC->clipOrg.y = 0; pGC->clientClip = (void *) NULL; pGC->numInDashList = 2; pGC->dash = DefaultDash; pGC->dashOffset = 0; /* use the default font and stipple */ pGC->font = defaultFont; if (pGC->font) /* necessary, because open of default font could fail */ pGC->font->refcnt++; pGC->stipple = pGC->pScreen->defaultStipple; if (pGC->stipple) pGC->stipple->refcnt++; /* this is not a scratch GC */ pGC->scratch_inuse = FALSE; return pGC; } /* CreateGC(pDrawable, mask, pval, pStatus) creates a default GC for the given drawable, using mask to fill in any non-default values. Returns a pointer to the new GC on success, NULL otherwise. returns status of non-default fields in pStatus BUG: should check for failure to create default tile */ GCPtr CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus, XID gcid, ClientPtr client) { GCPtr pGC; pGC = NewGCObject(pDrawable->pScreen, pDrawable->depth); if (!pGC) { *pStatus = BadAlloc; return (GCPtr) NULL; } pGC->serialNumber = GC_CHANGE_SERIAL_BIT; if (mask & GCForeground) { /* * magic special case -- ChangeGC checks for this condition * and snags the Foreground value to create a pseudo default-tile */ pGC->tileIsPixel = FALSE; } else { pGC->tileIsPixel = TRUE; } /* security creation/labeling check */ *pStatus = XaceHook(XACE_RESOURCE_ACCESS, client, gcid, RT_GC, pGC, RT_NONE, NULL, DixCreateAccess | DixSetAttrAccess); if (*pStatus != Success) goto out; pGC->stateChanges = GCAllBits; if (!(*pGC->pScreen->CreateGC) (pGC)) *pStatus = BadAlloc; else if (mask) *pStatus = ChangeGCXIDs(client, pGC, mask, pval); else *pStatus = Success; out: if (*pStatus != Success) { if (!pGC->tileIsPixel && !pGC->tile.pixmap) pGC->tileIsPixel = TRUE; /* undo special case */ FreeGC(pGC, (XID) 0); pGC = (GCPtr) NULL; } return pGC; } static Bool CreateDefaultTile(GCPtr pGC) { ChangeGCVal tmpval[3]; PixmapPtr pTile; GCPtr pgcScratch; xRectangle rect; CARD16 w, h; w = 1; h = 1; (*pGC->pScreen->QueryBestSize) (TileShape, &w, &h, pGC->pScreen); pTile = (PixmapPtr) (*pGC->pScreen->CreatePixmap) (pGC->pScreen, w, h, pGC->depth, 0); pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen); if (!pTile || !pgcScratch) { if (pTile) (*pTile->drawable.pScreen->DestroyPixmap) (pTile); if (pgcScratch) FreeScratchGC(pgcScratch); return FALSE; } tmpval[0].val = GXcopy; tmpval[1].val = pGC->tile.pixel; tmpval[2].val = FillSolid; (void) ChangeGC(NullClient, pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval); ValidateGC((DrawablePtr) pTile, pgcScratch); rect.x = 0; rect.y = 0; rect.width = w; rect.height = h; (*pgcScratch->ops->PolyFillRect) ((DrawablePtr) pTile, pgcScratch, 1, &rect); /* Always remember to free the scratch graphics context after use. */ FreeScratchGC(pgcScratch); pGC->tileIsPixel = FALSE; pGC->tile.pixmap = pTile; return TRUE; } int CopyGC(GC * pgcSrc, GC * pgcDst, BITS32 mask) { BITS32 index2; BITS32 maskQ; int error = 0; if (pgcSrc == pgcDst) return Success; pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT; pgcDst->stateChanges |= mask; maskQ = mask; while (mask) { index2 = (BITS32) lowbit(mask); mask &= ~index2; switch (index2) { case GCFunction: pgcDst->alu = pgcSrc->alu; break; case GCPlaneMask: pgcDst->planemask = pgcSrc->planemask; break; case GCForeground: pgcDst->fgPixel = pgcSrc->fgPixel; break; case GCBackground: pgcDst->bgPixel = pgcSrc->bgPixel; break; case GCLineWidth: pgcDst->lineWidth = pgcSrc->lineWidth; break; case GCLineStyle: pgcDst->lineStyle = pgcSrc->lineStyle; break; case GCCapStyle: pgcDst->capStyle = pgcSrc->capStyle; break; case GCJoinStyle: pgcDst->joinStyle = pgcSrc->joinStyle; break; case GCFillStyle: pgcDst->fillStyle = pgcSrc->fillStyle; break; case GCFillRule: pgcDst->fillRule = pgcSrc->fillRule; break; case GCTile: { if (EqualPixUnion(pgcDst->tileIsPixel, pgcDst->tile, pgcSrc->tileIsPixel, pgcSrc->tile)) { break; } if (!pgcDst->tileIsPixel) (*pgcDst->pScreen->DestroyPixmap) (pgcDst->tile.pixmap); pgcDst->tileIsPixel = pgcSrc->tileIsPixel; pgcDst->tile = pgcSrc->tile; if (!pgcDst->tileIsPixel) pgcDst->tile.pixmap->refcnt++; break; } case GCStipple: { if (pgcDst->stipple == pgcSrc->stipple) break; if (pgcDst->stipple) (*pgcDst->pScreen->DestroyPixmap) (pgcDst->stipple); pgcDst->stipple = pgcSrc->stipple; if (pgcDst->stipple) pgcDst->stipple->refcnt++; break; } case GCTileStipXOrigin: pgcDst->patOrg.x = pgcSrc->patOrg.x; break; case GCTileStipYOrigin: pgcDst->patOrg.y = pgcSrc->patOrg.y; break; case GCFont: if (pgcDst->font == pgcSrc->font) break; if (pgcDst->font) CloseFont(pgcDst->font, (Font) 0); if ((pgcDst->font = pgcSrc->font) != NullFont) (pgcDst->font)->refcnt++; break; case GCSubwindowMode: pgcDst->subWindowMode = pgcSrc->subWindowMode; break; case GCGraphicsExposures: pgcDst->graphicsExposures = pgcSrc->graphicsExposures; break; case GCClipXOrigin: pgcDst->clipOrg.x = pgcSrc->clipOrg.x; break; case GCClipYOrigin: pgcDst->clipOrg.y = pgcSrc->clipOrg.y; break; case GCClipMask: (*pgcDst->funcs->CopyClip) (pgcDst, pgcSrc); break; case GCDashOffset: pgcDst->dashOffset = pgcSrc->dashOffset; break; case GCDashList: if (pgcSrc->dash == DefaultDash) { if (pgcDst->dash != DefaultDash) { free(pgcDst->dash); pgcDst->numInDashList = pgcSrc->numInDashList; pgcDst->dash = pgcSrc->dash; } } else { unsigned char *dash; unsigned int i; dash = malloc(pgcSrc->numInDashList * sizeof(unsigned char)); if (dash) { if (pgcDst->dash != DefaultDash) free(pgcDst->dash); pgcDst->numInDashList = pgcSrc->numInDashList; pgcDst->dash = dash; for (i = 0; i < pgcSrc->numInDashList; i++) dash[i] = pgcSrc->dash[i]; } else error = BadAlloc; } break; case GCArcMode: pgcDst->arcMode = pgcSrc->arcMode; break; default: FatalError("CopyGC: Unhandled mask!\n"); } } if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel) { if (!CreateDefaultTile(pgcDst)) { pgcDst->fillStyle = FillSolid; error = BadAlloc; } } (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst); return error; } /** * does the diX part of freeing the characteristics in the GC. * * \param value must conform to DeleteType */ int FreeGC(void *value, XID gid) { GCPtr pGC = (GCPtr) value; CloseFont(pGC->font, (Font) 0); (*pGC->funcs->DestroyClip) (pGC); if (!pGC->tileIsPixel) (*pGC->pScreen->DestroyPixmap) (pGC->tile.pixmap); if (pGC->stipple) (*pGC->pScreen->DestroyPixmap) (pGC->stipple); (*pGC->funcs->DestroyGC) (pGC); if (pGC->dash != DefaultDash) free(pGC->dash); dixFreeObjectWithPrivates(pGC, PRIVATE_GC); return Success; } /* CreateScratchGC(pScreen, depth) like CreateGC, but doesn't do the default tile or stipple, since we can't create them without already having a GC. any code using the tile or stipple has to set them explicitly anyway, since the state of the scratch gc is unknown. This is OK because ChangeGC() has to be able to deal with NULL tiles and stipples anyway (in case the CreateGC() call has provided a value for them -- we can't set the default tile until the client-supplied attributes are installed, since the fgPixel is what fills the default tile. (maybe this comment should go with CreateGC() or ChangeGC().) */ static GCPtr CreateScratchGC(ScreenPtr pScreen, unsigned depth) { GCPtr pGC; pGC = NewGCObject(pScreen, depth); if (!pGC) return (GCPtr) NULL; pGC->stateChanges = GCAllBits; if (!(*pScreen->CreateGC) (pGC)) { FreeGC(pGC, (XID) 0); pGC = (GCPtr) NULL; } pGC->graphicsExposures = FALSE; return pGC; } void FreeGCperDepth(int screenNum) { int i; ScreenPtr pScreen; GCPtr *ppGC; pScreen = screenInfo.screens[screenNum]; ppGC = pScreen->GCperDepth; for (i = 0; i <= pScreen->numDepths; i++) { (void) FreeGC(ppGC[i], (XID) 0); ppGC[i] = NULL; } } Bool CreateGCperDepth(int screenNum) { int i; ScreenPtr pScreen; DepthPtr pDepth; GCPtr *ppGC; pScreen = screenInfo.screens[screenNum]; ppGC = pScreen->GCperDepth; /* do depth 1 separately because it's not included in list */ if (!(ppGC[0] = CreateScratchGC(pScreen, 1))) return FALSE; /* Make sure we don't overflow GCperDepth[] */ if (pScreen->numDepths > MAXFORMATS) return FALSE; pDepth = pScreen->allowedDepths; for (i = 0; i < pScreen->numDepths; i++, pDepth++) { if (!(ppGC[i + 1] = CreateScratchGC(pScreen, pDepth->depth))) { for (; i >= 0; i--) (void) FreeGC(ppGC[i], (XID) 0); return FALSE; } } return TRUE; } Bool CreateDefaultStipple(int screenNum) { ScreenPtr pScreen; ChangeGCVal tmpval[3]; xRectangle rect; CARD16 w, h; GCPtr pgcScratch; pScreen = screenInfo.screens[screenNum]; w = 16; h = 16; (*pScreen->QueryBestSize) (StippleShape, &w, &h, pScreen); if (!(pScreen->defaultStipple = pScreen->CreatePixmap(pScreen, w, h, 1, 0))) return FALSE; /* fill stipple with 1 */ tmpval[0].val = GXcopy; tmpval[1].val = 1; tmpval[2].val = FillSolid; pgcScratch = GetScratchGC(1, pScreen); if (!pgcScratch) { (*pScreen->DestroyPixmap) (pScreen->defaultStipple); return FALSE; } (void) ChangeGC(NullClient, pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval); ValidateGC((DrawablePtr) pScreen->defaultStipple, pgcScratch); rect.x = 0; rect.y = 0; rect.width = w; rect.height = h; (*pgcScratch->ops->PolyFillRect) ((DrawablePtr) pScreen->defaultStipple, pgcScratch, 1, &rect); FreeScratchGC(pgcScratch); return TRUE; } void FreeDefaultStipple(int screenNum) { ScreenPtr pScreen = screenInfo.screens[screenNum]; (*pScreen->DestroyPixmap) (pScreen->defaultStipple); } int SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash) { long i; unsigned char *p, *indash; BITS32 maskQ = 0; i = ndash; p = pdash; while (i--) { if (!*p++) { /* dash segment must be > 0 */ return BadValue; } } if (ndash & 1) p = malloc(2 * ndash * sizeof(unsigned char)); else p = malloc(ndash * sizeof(unsigned char)); if (!p) return BadAlloc; pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; if (offset != pGC->dashOffset) { pGC->dashOffset = offset; pGC->stateChanges |= GCDashOffset; maskQ |= GCDashOffset; } if (pGC->dash != DefaultDash) free(pGC->dash); pGC->numInDashList = ndash; pGC->dash = p; if (ndash & 1) { pGC->numInDashList += ndash; indash = pdash; i = ndash; while (i--) *p++ = *indash++; } while (ndash--) *p++ = *pdash++; pGC->stateChanges |= GCDashList; maskQ |= GCDashList; if (pGC->funcs->ChangeGC) (*pGC->funcs->ChangeGC) (pGC, maskQ); return Success; } int VerifyRectOrder(int nrects, xRectangle *prects, int ordering) { xRectangle *prectP, *prectN; int i; switch (ordering) { case Unsorted: return CT_UNSORTED; case YSorted: if (nrects > 1) { for (i = 1, prectP = prects, prectN = prects + 1; i < nrects; i++, prectP++, prectN++) if (prectN->y < prectP->y) return -1; } return CT_YSORTED; case YXSorted: if (nrects > 1) { for (i = 1, prectP = prects, prectN = prects + 1; i < nrects; i++, prectP++, prectN++) if ((prectN->y < prectP->y) || ((prectN->y == prectP->y) && (prectN->x < prectP->x))) return -1; } return CT_YXSORTED; case YXBanded: if (nrects > 1) { for (i = 1, prectP = prects, prectN = prects + 1; i < nrects; i++, prectP++, prectN++) if ((prectN->y != prectP->y && prectN->y < prectP->y + (int) prectP->height) || ((prectN->y == prectP->y) && (prectN->height != prectP->height || prectN->x < prectP->x + (int) prectP->width))) return -1; } return CT_YXBANDED; } return -1; } int SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects, xRectangle *prects, int ordering) { int newct, size; xRectangle *prectsNew; newct = VerifyRectOrder(nrects, prects, ordering); if (newct < 0) return BadMatch; size = nrects * sizeof(xRectangle); prectsNew = malloc(size); if (!prectsNew && size) return BadAlloc; pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; pGC->clipOrg.x = xOrigin; pGC->stateChanges |= GCClipXOrigin; pGC->clipOrg.y = yOrigin; pGC->stateChanges |= GCClipYOrigin; if (size) memmove((char *) prectsNew, (char *) prects, size); (*pGC->funcs->ChangeClip) (pGC, newct, (void *) prectsNew, nrects); if (pGC->funcs->ChangeGC) (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin | GCClipYOrigin | GCClipMask); return Success; } /* sets reasonable defaults if we can get a pre-allocated one, use it and mark it as used. if we can't, create one out of whole cloth (The Velveteen GC -- if you use it often enough it will become real.) */ GCPtr GetScratchGC(unsigned depth, ScreenPtr pScreen) { int i; GCPtr pGC; for (i = 0; i <= pScreen->numDepths; i++) { pGC = pScreen->GCperDepth[i]; if (pGC && pGC->depth == depth && !pGC->scratch_inuse) { pGC->scratch_inuse = TRUE; pGC->alu = GXcopy; pGC->planemask = ~0; pGC->serialNumber = 0; pGC->fgPixel = 0; pGC->bgPixel = 1; pGC->lineWidth = 0; pGC->lineStyle = LineSolid; pGC->capStyle = CapButt; pGC->joinStyle = JoinMiter; pGC->fillStyle = FillSolid; pGC->fillRule = EvenOddRule; pGC->arcMode = ArcChord; pGC->patOrg.x = 0; pGC->patOrg.y = 0; pGC->subWindowMode = ClipByChildren; pGC->graphicsExposures = FALSE; pGC->clipOrg.x = 0; pGC->clipOrg.y = 0; if (pGC->clientClip) (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0); pGC->stateChanges = GCAllBits; return pGC; } } /* if we make it this far, need to roll our own */ return CreateScratchGC(pScreen, depth); } /* if the gc to free is in the table of pre-existing ones, mark it as available. if not, free it for real */ void FreeScratchGC(GCPtr pGC) { if (pGC->scratch_inuse) pGC->scratch_inuse = FALSE; else FreeGC(pGC, (GContext) 0); } xorg-server-1.20.13/dix/getevents.c0000644000175000017500000020164214100573755014032 00000000000000/* * Copyright © 2006 Nokia Corporation * Copyright © 2006-2007 Daniel Stone * Copyright © 2008 Red Hat, Inc. * Copyright © 2011 The Chromium Authors * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: Daniel Stone * Peter Hutterer */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include #include "misc.h" #include "resource.h" #include "inputstr.h" #include "scrnintstr.h" #include "cursorstr.h" #include "dixstruct.h" #include "globals.h" #include "dixevents.h" #include "mipointer.h" #include "eventstr.h" #include "eventconvert.h" #include "inpututils.h" #include "mi.h" #include "windowstr.h" #include #include "xkbsrv.h" #ifdef PANORAMIX #include "panoramiX.h" #include "panoramiXsrv.h" #endif #include #include #include #include #include "exglobals.h" #include "exevents.h" #include "extnsionst.h" #include "listdev.h" /* for sizing up DeviceClassesChangedEvent */ #include "probes.h" /* Number of motion history events to store. */ #define MOTION_HISTORY_SIZE 256 /** * InputEventList is the storage for input events generated by * QueuePointerEvents, QueueKeyboardEvents, and QueueProximityEvents. * This list is allocated on startup by the DIX. */ InternalEvent *InputEventList = NULL; /** * Pick some arbitrary size for Xi motion history. */ int GetMotionHistorySize(void) { return MOTION_HISTORY_SIZE; } void set_button_down(DeviceIntPtr pDev, int button, int type) { if (type == BUTTON_PROCESSED) SetBit(pDev->button->down, button); else SetBit(pDev->button->postdown, button); } void set_button_up(DeviceIntPtr pDev, int button, int type) { if (type == BUTTON_PROCESSED) ClearBit(pDev->button->down, button); else ClearBit(pDev->button->postdown, button); } Bool button_is_down(DeviceIntPtr pDev, int button, int type) { Bool ret = FALSE; if (type & BUTTON_PROCESSED) ret = ret || BitIsOn(pDev->button->down, button); if (type & BUTTON_POSTED) ret = ret || BitIsOn(pDev->button->postdown, button); return ret; } void set_key_down(DeviceIntPtr pDev, int key_code, int type) { if (type == KEY_PROCESSED) SetBit(pDev->key->down, key_code); else SetBit(pDev->key->postdown, key_code); } void set_key_up(DeviceIntPtr pDev, int key_code, int type) { if (type == KEY_PROCESSED) ClearBit(pDev->key->down, key_code); else ClearBit(pDev->key->postdown, key_code); } Bool key_is_down(DeviceIntPtr pDev, int key_code, int type) { Bool ret = FALSE; if (type & KEY_PROCESSED) ret = ret || BitIsOn(pDev->key->down, key_code); if (type & KEY_POSTED) ret = ret || BitIsOn(pDev->key->postdown, key_code); return ret; } static Bool key_autorepeats(DeviceIntPtr pDev, int key_code) { return ! !(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] & (1 << (key_code & 7))); } static void init_touch_ownership(DeviceIntPtr dev, TouchOwnershipEvent *event, Time ms) { memset(event, 0, sizeof(TouchOwnershipEvent)); event->header = ET_Internal; event->type = ET_TouchOwnership; event->length = sizeof(TouchOwnershipEvent); event->time = ms; event->deviceid = dev->id; } static void init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail) { memset(event, 0, sizeof(RawDeviceEvent)); event->header = ET_Internal; event->length = sizeof(RawDeviceEvent); switch (type) { case MotionNotify: event->type = ET_RawMotion; break; case ButtonPress: event->type = ET_RawButtonPress; break; case ButtonRelease: event->type = ET_RawButtonRelease; break; case KeyPress: event->type = ET_RawKeyPress; break; case KeyRelease: event->type = ET_RawKeyRelease; break; case XI_TouchBegin: event->type = ET_RawTouchBegin; break; case XI_TouchUpdate: event->type = ET_RawTouchUpdate; break; case XI_TouchEnd: event->type = ET_RawTouchEnd; break; } event->time = ms; event->deviceid = dev->id; event->sourceid = dev->id; event->detail.button = detail; } static void set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, BOOL use_unaccel, double *data) { int i; use_unaccel = use_unaccel && valuator_mask_has_unaccelerated(mask); for (i = 0; i < valuator_mask_size(mask); i++) { if (valuator_mask_isset(mask, i)) { double v; SetBit(event->valuators.mask, i); if (use_unaccel) v = valuator_mask_get_unaccelerated(mask, i); else v = valuator_mask_get_double(mask, i); data[i] = v; } } } static void set_valuators(DeviceIntPtr dev, DeviceEvent *event, ValuatorMask *mask) { int i; /* Set the data to the previous value for unset absolute axes. The values * may be used when sent as part of an XI 1.x valuator event. */ for (i = 0; i < valuator_mask_size(mask); i++) { if (valuator_mask_isset(mask, i)) { SetBit(event->valuators.mask, i); if (valuator_get_mode(dev, i) == Absolute) SetBit(event->valuators.mode, i); event->valuators.data[i] = valuator_mask_get_double(mask, i); } else event->valuators.data[i] = dev->valuator->axisVal[i]; } } void CreateClassesChangedEvent(InternalEvent *event, DeviceIntPtr master, DeviceIntPtr slave, int flags) { int i; DeviceChangedEvent *dce; CARD32 ms = GetTimeInMillis(); dce = &event->changed_event; memset(dce, 0, sizeof(DeviceChangedEvent)); dce->deviceid = slave->id; dce->masterid = master ? master->id : 0; dce->header = ET_Internal; dce->length = sizeof(DeviceChangedEvent); dce->type = ET_DeviceChanged; dce->time = ms; dce->flags = flags; dce->sourceid = slave->id; if (slave->button) { dce->buttons.num_buttons = slave->button->numButtons; for (i = 0; i < dce->buttons.num_buttons; i++) dce->buttons.names[i] = slave->button->labels[i]; } if (slave->valuator) { dce->num_valuators = slave->valuator->numAxes; for (i = 0; i < dce->num_valuators; i++) { dce->valuators[i].min = slave->valuator->axes[i].min_value; dce->valuators[i].max = slave->valuator->axes[i].max_value; dce->valuators[i].resolution = slave->valuator->axes[i].resolution; dce->valuators[i].mode = slave->valuator->axes[i].mode; dce->valuators[i].name = slave->valuator->axes[i].label; dce->valuators[i].scroll = slave->valuator->axes[i].scroll; dce->valuators[i].value = slave->valuator->axisVal[i]; } } if (slave->key) { dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code; dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code; } } /** * Rescale the coord between the two axis ranges. */ static double rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to, double defmin, double defmax) { double fmin = defmin, fmax = defmax; double tmin = defmin, tmax = defmax; if (from && from->min_value < from->max_value) { fmin = from->min_value; fmax = from->max_value + 1; } if (to && to->min_value < to->max_value) { tmin = to->min_value; tmax = to->max_value + 1; } if (fmin == tmin && fmax == tmax) return coord; if (fmax == fmin) /* avoid division by 0 */ return 0.0; return (coord - fmin) * (tmax - tmin) / (fmax - fmin) + tmin; } /** * Update all coordinates when changing to a different SD * to ensure that relative reporting will work as expected * without loss of precision. * * pDev->last.valuators will be in absolute device coordinates after this * function. */ static void updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev) { /* master->last.valuators[0]/[1] is in desktop-wide coords and the actual * position of the pointer */ pDev->last.valuators[0] = master->last.valuators[0]; pDev->last.valuators[1] = master->last.valuators[1]; if (!pDev->valuator) return; /* scale back to device coordinates */ if (pDev->valuator->numAxes > 0) { pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], NULL, pDev->valuator->axes + 0, screenInfo.x, screenInfo.width); } if (pDev->valuator->numAxes > 1) { pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], NULL, pDev->valuator->axes + 1, screenInfo.y, screenInfo.height); } /* other axes are left as-is */ } /** * Allocate the motion history buffer. */ void AllocateMotionHistory(DeviceIntPtr pDev) { int size; free(pDev->valuator->motion); if (pDev->valuator->numMotionEvents < 1) return; /* An MD must have a motion history size large enough to keep all * potential valuators, plus the respective range of the valuators. * 3 * INT32 for (min_val, max_val, curr_val)) */ if (IsMaster(pDev)) size = sizeof(INT32) * 3 * MAX_VALUATORS; else { ValuatorClassPtr v = pDev->valuator; int numAxes; /* XI1 doesn't understand mixed mode devices */ for (numAxes = 0; numAxes < v->numAxes; numAxes++) if (valuator_get_mode(pDev, numAxes) != valuator_get_mode(pDev, 0)) break; size = sizeof(INT32) * numAxes; } size += sizeof(Time); pDev->valuator->motion = calloc(pDev->valuator->numMotionEvents, size); pDev->valuator->first_motion = 0; pDev->valuator->last_motion = 0; if (!pDev->valuator->motion) ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n", pDev->name, size * pDev->valuator->numMotionEvents); } /** * Dump the motion history between start and stop into the supplied buffer. * Only records the event for a given screen in theory, but in practice, we * sort of ignore this. * * If core is set, we only generate x/y, in INT16, scaled to screen coords. */ int GetMotionHistory(DeviceIntPtr pDev, xTimecoord ** buff, unsigned long start, unsigned long stop, ScreenPtr pScreen, BOOL core) { char *ibuff = NULL, *obuff; int i = 0, ret = 0; int j, coord; Time current; /* The size of a single motion event. */ int size; AxisInfo from, *to; /* for scaling */ INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */ INT16 *corebuf; AxisInfo core_axis = { 0 }; if (!pDev->valuator || !pDev->valuator->numMotionEvents) return 0; if (core && !pScreen) return 0; if (IsMaster(pDev)) size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time); else size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time); *buff = malloc(size * pDev->valuator->numMotionEvents); if (!(*buff)) return 0; obuff = (char *) *buff; for (i = pDev->valuator->first_motion; i != pDev->valuator->last_motion; i = (i + 1) % pDev->valuator->numMotionEvents) { /* We index the input buffer by which element we're accessing, which * is not monotonic, and the output buffer by how many events we've * written so far. */ ibuff = (char *) pDev->valuator->motion + (i * size); memcpy(¤t, ibuff, sizeof(Time)); if (current > stop) { return ret; } else if (current >= start) { if (core) { memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */ icbuf = (INT32 *) (ibuff + sizeof(Time)); corebuf = (INT16 *) (obuff + sizeof(Time)); /* fetch x coordinate + range */ memcpy(&from.min_value, icbuf++, sizeof(INT32)); memcpy(&from.max_value, icbuf++, sizeof(INT32)); memcpy(&coord, icbuf++, sizeof(INT32)); /* scale to screen coords */ to = &core_axis; to->max_value = pScreen->width; coord = rescaleValuatorAxis(coord, &from, to, 0, pScreen->width); memcpy(corebuf, &coord, sizeof(INT16)); corebuf++; /* fetch y coordinate + range */ memcpy(&from.min_value, icbuf++, sizeof(INT32)); memcpy(&from.max_value, icbuf++, sizeof(INT32)); memcpy(&coord, icbuf++, sizeof(INT32)); to->max_value = pScreen->height; coord = rescaleValuatorAxis(coord, &from, to, 0, pScreen->height); memcpy(corebuf, &coord, sizeof(INT16)); } else if (IsMaster(pDev)) { memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */ ocbuf = (INT32 *) (obuff + sizeof(Time)); icbuf = (INT32 *) (ibuff + sizeof(Time)); for (j = 0; j < MAX_VALUATORS; j++) { if (j >= pDev->valuator->numAxes) break; /* fetch min/max/coordinate */ memcpy(&from.min_value, icbuf++, sizeof(INT32)); memcpy(&from.max_value, icbuf++, sizeof(INT32)); memcpy(&coord, icbuf++, sizeof(INT32)); to = (j < pDev->valuator->numAxes) ? &pDev->valuator-> axes[j] : NULL; /* x/y scaled to screen if no range is present */ if (j == 0 && (from.max_value < from.min_value)) from.max_value = pScreen->width; else if (j == 1 && (from.max_value < from.min_value)) from.max_value = pScreen->height; /* scale from stored range into current range */ coord = rescaleValuatorAxis(coord, &from, to, 0, 0); memcpy(ocbuf, &coord, sizeof(INT32)); ocbuf++; } } else memcpy(obuff, ibuff, size); /* don't advance by size here. size may be different to the * actually written size if the MD has less valuators than MAX */ if (core) obuff += sizeof(INT32) + sizeof(Time); else obuff += (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time); ret++; } } return ret; } /** * Update the motion history for a specific device, with the list of * valuators. * * Layout of the history buffer: * for SDs: [time] [val0] [val1] ... [valn] * for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn] * * For events that have some valuators unset: * min_val == max_val == val == 0. */ static void updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask, double *valuators) { char *buff = (char *) pDev->valuator->motion; ValuatorClassPtr v; int i; if (!pDev->valuator->numMotionEvents) return; v = pDev->valuator; if (IsMaster(pDev)) { buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) * v->last_motion; memcpy(buff, &ms, sizeof(Time)); buff += sizeof(Time); memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS); for (i = 0; i < v->numAxes; i++) { int val; /* XI1 doesn't support mixed mode devices */ if (valuator_get_mode(pDev, i) != valuator_get_mode(pDev, 0)) break; if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i)) { buff += 3 * sizeof(INT32); continue; } memcpy(buff, &v->axes[i].min_value, sizeof(INT32)); buff += sizeof(INT32); memcpy(buff, &v->axes[i].max_value, sizeof(INT32)); buff += sizeof(INT32); val = valuators[i]; memcpy(buff, &val, sizeof(INT32)); buff += sizeof(INT32); } } else { buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) * pDev->valuator->last_motion; memcpy(buff, &ms, sizeof(Time)); buff += sizeof(Time); memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes); for (i = 0; i < MAX_VALUATORS; i++) { int val; if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i)) { buff += sizeof(INT32); continue; } val = valuators[i]; memcpy(buff, &val, sizeof(INT32)); buff += sizeof(INT32); } } pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) % pDev->valuator->numMotionEvents; /* If we're wrapping around, just keep the circular buffer going. */ if (pDev->valuator->first_motion == pDev->valuator->last_motion) pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) % pDev->valuator->numMotionEvents; return; } /** * Returns the maximum number of events GetKeyboardEvents * and GetPointerEvents will ever return. * * This MUST be absolutely constant, from init until exit. */ int GetMaximumEventsNum(void) { /* One raw event * One device event * One possible device changed event * Lots of possible separate button scroll events (horiz + vert) * Lots of possible separate raw button scroll events (horiz + vert) */ return 100; } /** * Clip an axis to its bounds, which are declared in the call to * InitValuatorAxisClassStruct. */ static void clipAxis(DeviceIntPtr pDev, int axisNum, double *val) { AxisInfoPtr axis; if (axisNum >= pDev->valuator->numAxes) return; axis = pDev->valuator->axes + axisNum; /* If a value range is defined, clip. If not, do nothing */ if (axis->max_value <= axis->min_value) return; if (*val < axis->min_value) *val = axis->min_value; if (*val > axis->max_value) *val = axis->max_value; } /** * Clip every axis in the list of valuators to its bounds. */ static void clipValuators(DeviceIntPtr pDev, ValuatorMask *mask) { int i; for (i = 0; i < valuator_mask_size(mask); i++) if (valuator_mask_isset(mask, i)) { double val = valuator_mask_get_double(mask, i); clipAxis(pDev, i, &val); valuator_mask_set_double(mask, i, val); } } /** * Create the DCCE event (does not update the master's device state yet, this * is done in the event processing). * Pull in the coordinates from the MD if necessary. * * @param events Pointer to a pre-allocated event array. * @param dev The slave device that generated an event. * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT * @param num_events The current number of events, returns the number of * events if a DCCE was generated. * @return The updated @events pointer. */ InternalEvent * UpdateFromMaster(InternalEvent *events, DeviceIntPtr dev, int type, int *num_events) { DeviceIntPtr master; master = GetMaster(dev, (type & DEVCHANGE_POINTER_EVENT) ? MASTER_POINTER : MASTER_KEYBOARD); if (master && master->last.slave != dev) { CreateClassesChangedEvent(events, master, dev, type | DEVCHANGE_SLAVE_SWITCH); if (IsPointerDevice(master)) { updateSlaveDeviceCoords(master, dev); master->last.numValuators = dev->last.numValuators; } master->last.slave = dev; (*num_events)++; events++; } return events; } /** * Move the device's pointer to the position given in the valuators. * * @param dev The device whose pointer is to be moved. * @param mask Valuator data for this event. */ static void clipAbsolute(DeviceIntPtr dev, ValuatorMask *mask) { int i; for (i = 0; i < valuator_mask_size(mask); i++) { double val; if (!valuator_mask_isset(mask, i)) continue; val = valuator_mask_get_double(mask, i); clipAxis(dev, i, &val); valuator_mask_set_double(mask, i, val); } } static void add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, double value) { double v; if (!valuator_mask_fetch_double(mask, valuator, &v)) return; /* protect against scrolling overflow. INT_MAX for double, because * we'll eventually write this as 32.32 fixed point */ if ((value > 0 && v > INT_MAX - value) || (value < 0 && v < INT_MIN - value)) { v = 0; /* reset last.scroll to avoid a button storm */ valuator_mask_set_double(dev->last.scroll, valuator, 0); } else v += value; valuator_mask_set_double(mask, valuator, v); } static void scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask) { double y; ValuatorClassPtr v = dev->valuator; int xrange = v->axes[0].max_value - v->axes[0].min_value + 1; int yrange = v->axes[1].max_value - v->axes[1].min_value + 1; double screen_ratio = 1.0 * screenInfo.width/screenInfo.height; double device_ratio = 1.0 * xrange/yrange; double resolution_ratio = 1.0; double ratio; if (!valuator_mask_fetch_double(mask, 1, &y)) return; if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0) resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution; ratio = device_ratio/resolution_ratio/screen_ratio; valuator_mask_set_double(mask, 1, y / ratio); } /** * Move the device's pointer by the values given in @valuators. * * @param dev The device whose pointer is to be moved. * @param[in,out] mask Valuator data for this event, modified in-place. */ static void moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask) { int i; Bool clip_xy = IsMaster(dev) || !IsFloating(dev); ValuatorClassPtr v = dev->valuator; /* for abs devices in relative mode, we've just scaled wrong, since we mapped the device's shape into the screen shape. Undo this. */ if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 && v->axes[0].min_value < v->axes[0].max_value && v->axes[1].min_value < v->axes[1].max_value) { scale_for_device_resolution(dev, mask); } /* calc other axes, clip, drop back into valuators */ for (i = 0; i < valuator_mask_size(mask); i++) { double val = dev->last.valuators[i]; if (!valuator_mask_isset(mask, i)) continue; add_to_scroll_valuator(dev, mask, i, val); /* x & y need to go over the limits to cross screens if the SD * isn't currently attached; otherwise, clip to screen bounds. */ if (valuator_get_mode(dev, i) == Absolute && ((i != 0 && i != 1) || clip_xy)) { val = valuator_mask_get_double(mask, i); clipAxis(dev, i, &val); valuator_mask_set_double(mask, i, val); } } } /** * Accelerate the data in valuators based on the device's acceleration scheme. * * @param dev The device which's pointer is to be moved. * @param valuators Valuator mask * @param ms Current time. */ static void accelPointer(DeviceIntPtr dev, ValuatorMask *valuators, CARD32 ms) { if (dev->valuator->accelScheme.AccelSchemeProc) dev->valuator->accelScheme.AccelSchemeProc(dev, valuators, ms); } /** * Scale from absolute screen coordinates to absolute coordinates in the * device's coordinate range. * * @param dev The device to scale for. * @param[in, out] mask The mask in desktop/screen coordinates, modified in place * to contain device coordinate range. * @param flags If POINTER_SCREEN is set, mask is in per-screen coordinates. * Otherwise, mask is in desktop coords. */ static void scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask, int flags) { double scaled; ScreenPtr scr = miPointerGetScreen(dev); if (valuator_mask_isset(mask, 0)) { scaled = valuator_mask_get_double(mask, 0); if (flags & POINTER_SCREEN) scaled += scr->x; scaled = rescaleValuatorAxis(scaled, NULL, dev->valuator->axes + 0, screenInfo.x, screenInfo.width); valuator_mask_set_double(mask, 0, scaled); } if (valuator_mask_isset(mask, 1)) { scaled = valuator_mask_get_double(mask, 1); if (flags & POINTER_SCREEN) scaled += scr->y; scaled = rescaleValuatorAxis(scaled, NULL, dev->valuator->axes + 1, screenInfo.y, screenInfo.height); valuator_mask_set_double(mask, 1, scaled); } } /** * Scale from (absolute) device to screen coordinates here, * * The coordinates provided are always absolute. see fill_pointer_events for * information on coordinate systems. * * @param dev The device to be moved. * @param mask Mask of axis values for this event * @param[out] devx x desktop-wide coordinate in device coordinate system * @param[out] devy y desktop-wide coordinate in device coordinate system * @param[out] screenx x coordinate in desktop coordinate system * @param[out] screeny y coordinate in desktop coordinate system */ static ScreenPtr scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask, double *devx, double *devy, double *screenx, double *screeny) { ScreenPtr scr = miPointerGetScreen(dev); double x, y; BUG_WARN(dev->valuator && dev->valuator->numAxes < 2); if (!dev->valuator || dev->valuator->numAxes < 2) { /* if we have no axes, last.valuators must be in screen coords * anyway */ *devx = *screenx = dev->last.valuators[0]; *devy = *screeny = dev->last.valuators[1]; return scr; } if (valuator_mask_isset(mask, 0)) x = valuator_mask_get_double(mask, 0); else x = dev->last.valuators[0]; if (valuator_mask_isset(mask, 1)) y = valuator_mask_get_double(mask, 1); else y = dev->last.valuators[1]; /* scale x&y to desktop coordinates */ *screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL, screenInfo.x, screenInfo.width); *screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL, screenInfo.y, screenInfo.height); *devx = x; *devy = y; return scr; } /** * If we have HW cursors, this actually moves the visible sprite. If not, we * just do all the screen crossing, etc. * * We use the screen coordinates here, call miPointerSetPosition() and then * scale back into device coordinates (if needed). miPSP will change x/y if * the screen was crossed. * * The coordinates provided are always absolute. The parameter mode * specifies whether it was relative or absolute movement that landed us at * those coordinates. see fill_pointer_events for information on coordinate * systems. * * @param dev The device to be moved. * @param mode Movement mode (Absolute or Relative) * @param[out] mask Mask of axis values for this event, returns the * per-screen device coordinates after confinement * @param[in,out] devx x desktop-wide coordinate in device coordinate system * @param[in,out] devy y desktop-wide coordinate in device coordinate system * @param[in,out] screenx x coordinate in desktop coordinate system * @param[in,out] screeny y coordinate in desktop coordinate system * @param[out] nevents Number of barrier events added to events * @param[in,out] events List of events barrier events are added to */ static ScreenPtr positionSprite(DeviceIntPtr dev, int mode, ValuatorMask *mask, double *devx, double *devy, double *screenx, double *screeny, int *nevents, InternalEvent* events) { ScreenPtr scr = miPointerGetScreen(dev); double tmpx, tmpy; if (!dev->valuator || dev->valuator->numAxes < 2) return scr; tmpx = *screenx; tmpy = *screeny; /* miPointerSetPosition takes care of crossing screens for us, as well as * clipping to the current screen. Coordinates returned are in desktop * coord system */ scr = miPointerSetPosition(dev, mode, screenx, screeny, nevents, events); /* If we were constrained, rescale x/y from the screen coordinates so * the device valuators reflect the correct position. For screen * crossing this doesn't matter much, the coords would be 0 or max. */ if (tmpx != *screenx) *devx = rescaleValuatorAxis(*screenx, NULL, dev->valuator->axes + 0, screenInfo.x, screenInfo.width); if (tmpy != *screeny) *devy = rescaleValuatorAxis(*screeny, NULL, dev->valuator->axes + 1, screenInfo.y, screenInfo.height); /* Recalculate the per-screen device coordinates */ if (valuator_mask_isset(mask, 0)) { double x; x = rescaleValuatorAxis(*screenx - scr->x, NULL, dev->valuator->axes + 0, 0, scr->width); valuator_mask_set_double(mask, 0, x); } if (valuator_mask_isset(mask, 1)) { double y; y = rescaleValuatorAxis(*screeny - scr->y, NULL, dev->valuator->axes + 1, 0, scr->height); valuator_mask_set_double(mask, 1, y); } return scr; } /** * Update the motion history for the device and (if appropriate) for its * master device. * @param dev Slave device to update. * @param mask Bit mask of valid valuators to append to history. * @param num Total number of valuators to append to history. * @param ms Current time */ static void updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms) { if (!dev->valuator) return; updateMotionHistory(dev, ms, mask, dev->last.valuators); if (!IsMaster(dev) && !IsFloating(dev)) { DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); updateMotionHistory(master, ms, mask, dev->last.valuators); } } static void queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents) { int i; for (i = 0; i < nevents; i++) mieqEnqueue(device, &events[i]); } static void event_set_root_coordinates(DeviceEvent *event, double x, double y) { event->root_x = trunc(x); event->root_y = trunc(y); event->root_x_frac = x - trunc(x); event->root_y_frac = y - trunc(y); } /** * Generate internal events representing this keyboard event and enqueue * them on the event queue. * * This function is not reentrant. Disable signals before calling. * * @param device The device to generate the event for * @param type Event type, one of KeyPress or KeyRelease * @param keycode Key code of the pressed/released key * */ void QueueKeyboardEvents(DeviceIntPtr device, int type, int keycode) { int nevents; nevents = GetKeyboardEvents(InputEventList, device, type, keycode); queueEventList(device, InputEventList, nevents); } /** * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally * also with valuator events. * * The DDX is responsible for allocating the event list in the first * place via InitEventList(), and for freeing it. * * @return the number of events written into events. */ int GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int key_code) { int num_events = 0; CARD32 ms = 0; DeviceEvent *event; RawDeviceEvent *raw; enum DeviceEventSource source_type = EVENT_SOURCE_NORMAL; #if XSERVER_DTRACE if (XSERVER_INPUT_EVENT_ENABLED()) { XSERVER_INPUT_EVENT(pDev->id, type, key_code, 0, 0, NULL, NULL); } #endif if (type == EnterNotify) { source_type = EVENT_SOURCE_FOCUS; type = KeyPress; } else if (type == LeaveNotify) { source_type = EVENT_SOURCE_FOCUS; type = KeyRelease; } /* refuse events from disabled devices */ if (!pDev->enabled) return 0; if (!events || !pDev->key || !pDev->focus || !pDev->kbdfeed || (type != KeyPress && type != KeyRelease) || (key_code < 8 || key_code > 255)) return 0; num_events = 1; events = UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events); /* Handle core repeating, via press/release/press/release. */ if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) { /* If autorepeating is disabled either globally or just for that key, * or we have a modifier, don't generate a repeat event. */ if (!pDev->kbdfeed->ctrl.autoRepeat || !key_autorepeats(pDev, key_code) || pDev->key->xkbInfo->desc->map->modmap[key_code]) return 0; } ms = GetTimeInMillis(); if (source_type == EVENT_SOURCE_NORMAL) { raw = &events->raw_event; init_raw(pDev, raw, ms, type, key_code); events++; num_events++; } event = &events->device_event; init_device_event(event, pDev, ms, source_type); event->detail.key = key_code; if (type == KeyPress) { event->type = ET_KeyPress; set_key_down(pDev, key_code, KEY_POSTED); } else if (type == KeyRelease) { event->type = ET_KeyRelease; set_key_up(pDev, key_code, KEY_POSTED); } return num_events; } /** * Initialize an event array large enough for num_events arrays. * This event list is to be passed into GetPointerEvents() and * GetKeyboardEvents(). * * @param num_events Number of elements in list. */ InternalEvent * InitEventList(int num_events) { InternalEvent *events = calloc(num_events, sizeof(InternalEvent)); return events; } /** * Free an event list. * * @param list The list to be freed. * @param num_events Number of elements in list. */ void FreeEventList(InternalEvent *list, int num_events) { free(list); } /** * Transform vector x/y according to matrix m and drop the rounded coords * back into x/y. */ static void transform(struct pixman_f_transform *m, double *x, double *y) { struct pixman_f_vector p = {.v = {*x, *y, 1} }; pixman_f_transform_point(m, &p); *x = p.v[0]; *y = p.v[1]; } static void transformRelative(DeviceIntPtr dev, ValuatorMask *mask) { double x = 0, y = 0; valuator_mask_fetch_double(mask, 0, &x); valuator_mask_fetch_double(mask, 1, &y); transform(&dev->relative_transform, &x, &y); if (x) valuator_mask_set_double(mask, 0, x); else valuator_mask_unset(mask, 0); if (y) valuator_mask_set_double(mask, 1, y); else valuator_mask_unset(mask, 1); } /** * Apply the device's transformation matrix to the valuator mask and replace * the scaled values in mask. This transformation only applies to valuators * 0 and 1, others will be untouched. * * @param dev The device the valuators came from * @param[in,out] mask The valuator mask. */ static void transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask) { double x, y, ox = 0.0, oy = 0.0; int has_x, has_y; has_x = valuator_mask_isset(mask, 0); has_y = valuator_mask_isset(mask, 1); if (!has_x && !has_y) return; if (!has_x || !has_y) { struct pixman_f_transform invert; /* undo transformation from last event */ ox = dev->last.valuators[0]; oy = dev->last.valuators[1]; pixman_f_transform_invert(&invert, &dev->scale_and_transform); transform(&invert, &ox, &oy); } if (has_x) ox = valuator_mask_get_double(mask, 0); if (has_y) oy = valuator_mask_get_double(mask, 1); x = ox; y = oy; transform(&dev->scale_and_transform, &x, &y); if (has_x || ox != x) valuator_mask_set_double(mask, 0, x); if (has_y || oy != y) valuator_mask_set_double(mask, 1, y); } static void storeLastValuators(DeviceIntPtr dev, ValuatorMask *mask, int xaxis, int yaxis, double devx, double devy) { int i; /* store desktop-wide in last.valuators */ if (valuator_mask_isset(mask, xaxis)) dev->last.valuators[0] = devx; if (valuator_mask_isset(mask, yaxis)) dev->last.valuators[1] = devy; for (i = 0; i < valuator_mask_size(mask); i++) { if (i == xaxis || i == yaxis) continue; if (valuator_mask_isset(mask, i)) dev->last.valuators[i] = valuator_mask_get_double(mask, i); } } /** * Generate internal events representing this pointer event and enqueue them * on the event queue. * * This function is not reentrant. Disable signals before calling. * * @param device The device to generate the event for * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify * @param buttons Button number of the buttons modified. Must be 0 for * MotionNotify * @param flags Event modification flags * @param mask Valuator mask for valuators present for this event. */ void QueuePointerEvents(DeviceIntPtr device, int type, int buttons, int flags, const ValuatorMask *mask) { int nevents; nevents = GetPointerEvents(InputEventList, device, type, buttons, flags, mask); queueEventList(device, InputEventList, nevents); } /** * Helper function for GetPointerEvents, which only generates motion and * raw motion events for the slave device: does not update the master device. * * Should not be called by anyone other than GetPointerEvents. * * We use several different coordinate systems and need to switch between * the three in fill_pointer_events, positionSprite and * miPointerSetPosition. "desktop" refers to the width/height of all * screenInfo.screens[n]->width/height added up. "screen" is ScreenRec, not * output. * * Coordinate systems: * - relative events have a mask_in in relative coordinates, mapped to * pixels. These events are mapped to the current position±delta. * - absolute events have a mask_in in absolute device coordinates in * device-specific range. This range is mapped to the desktop. * - POINTER_SCREEN absolute events (x86WarpCursor) are in screen-relative * screen coordinate range. * - rootx/rooty in events must be be relative to the current screen's * origin (screen coordinate system) * - XI2 valuators must be relative to the current screen's origin. On * the protocol the device min/max range maps to the current screen. * * For screen switching we need to get the desktop coordinates for each * event, then map that to the respective position on each screen and * position the cursor there. * The device's last.valuator[] stores the last position in desktop-wide * coordinates (in device range for slave devices, desktop range for master * devices). * * screen-relative device coordinates requires scaling: A device coordinate * x/y of range [n..m] that maps to positions Sx/Sy on Screen S must be * rescaled to match Sx/Sy for [n..m]. In the simplest example, x of (m/2-1) * is the last coordinate on the first screen and must be rescaled for the * event to be m. XI2 clients that do their own coordinate mapping would * otherwise interpret the position of the device elsewere to the cursor. * However, this scaling leads to losses: * if we have two ScreenRecs we scale from e.g. [0..44704] (Wacom I4) to * [0..2048[. that gives us 2047.954 as desktop coord, or the per-screen * coordinate 1023.954. Scaling that back into the device coordinate range * gives us 44703. So off by one device unit. It's a bug, but we'll have to * live with it because with all this scaling, we just cannot win. * * @return the number of events written into events. */ static int fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons, CARD32 ms, int flags, const ValuatorMask *mask_in) { int num_events = 1; DeviceEvent *event; RawDeviceEvent *raw = NULL; double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */ double devx = 0.0, devy = 0.0; /* desktop-wide in device coords */ int sx = 0, sy = 0; /* for POINTER_SCREEN */ ValuatorMask mask; ScreenPtr scr; int num_barrier_events = 0; switch (type) { case MotionNotify: if (!pDev->valuator) { ErrorF("[dix] motion events from device %d without valuators\n", pDev->id); return 0; } if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0) return 0; break; case ButtonPress: case ButtonRelease: if (!pDev->button || !buttons) return 0; if (mask_in && valuator_mask_size(mask_in) > 0 && !pDev->valuator) { ErrorF ("[dix] button event with valuator from device %d without valuators\n", pDev->id); return 0; } break; default: return 0; } valuator_mask_copy(&mask, mask_in); if ((flags & POINTER_NORAW) == 0) { raw = &events->raw_event; events++; num_events++; init_raw(pDev, raw, ms, type, buttons); set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw); } valuator_mask_drop_unaccelerated(&mask); /* valuators are in driver-native format (rel or abs) */ if (flags & POINTER_ABSOLUTE) { if (flags & (POINTER_SCREEN | POINTER_DESKTOP)) { /* valuators are in screen/desktop coords */ sx = valuator_mask_get(&mask, 0); sy = valuator_mask_get(&mask, 1); scale_from_screen(pDev, &mask, flags); } transformAbsolute(pDev, &mask); clipAbsolute(pDev, &mask); if ((flags & POINTER_NORAW) == 0 && raw) set_raw_valuators(raw, &mask, FALSE, raw->valuators.data); } else { transformRelative(pDev, &mask); if (flags & POINTER_ACCELERATE) accelPointer(pDev, &mask, ms); if ((flags & POINTER_NORAW) == 0 && raw) set_raw_valuators(raw, &mask, FALSE, raw->valuators.data); moveRelative(pDev, flags, &mask); } /* valuators are in device coordinate system in absolute coordinates */ scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny); /* #53037 XWarpPointer's scaling back and forth between screen and device may leave us with rounding errors. End result is that the pointer doesn't end up on the pixel it should. Avoid this by forcing screenx/screeny back to what the input coordinates were. */ if (flags & POINTER_SCREEN) { scr = miPointerGetScreen(pDev); screenx = sx + scr->x; screeny = sy + scr->y; } scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative, &mask, &devx, &devy, &screenx, &screeny, &num_barrier_events, events); num_events += num_barrier_events; events += num_barrier_events; /* screenx, screeny are in desktop coordinates, mask is in device coordinates per-screen (the event data) devx/devy is in device coordinate desktop-wide */ updateHistory(pDev, &mask, ms); clipValuators(pDev, &mask); storeLastValuators(pDev, &mask, 0, 1, devx, devy); /* Update the MD's co-ordinates, which are always in desktop space. */ if (!IsMaster(pDev) && !IsFloating(pDev)) { DeviceIntPtr master = GetMaster(pDev, MASTER_POINTER); master->last.valuators[0] = screenx; master->last.valuators[1] = screeny; } event = &events->device_event; init_device_event(event, pDev, ms, EVENT_SOURCE_NORMAL); if (type == MotionNotify) { event->type = ET_Motion; event->detail.button = 0; } else { if (type == ButtonPress) { event->type = ET_ButtonPress; set_button_down(pDev, buttons, BUTTON_POSTED); } else if (type == ButtonRelease) { event->type = ET_ButtonRelease; set_button_up(pDev, buttons, BUTTON_POSTED); } event->detail.button = buttons; } /* root_x and root_y must be in per-screen co-ordinates */ event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y); if (flags & POINTER_EMULATED) { if (raw) raw->flags = XIPointerEmulated; event->flags = XIPointerEmulated; } set_valuators(pDev, event, &mask); return num_events; } /** * Generate events for each scroll axis that changed between before/after * for the device. * * @param events The pointer to the event list to fill the events * @param dev The device to generate the events for * @param type The real type of the event * @param axis The axis number to generate events for * @param mask State before this event in absolute coords * @param[in,out] last Last scroll state posted in absolute coords (modified * in-place) * @param ms Current time in ms * @param max_events Max number of events to be generated * @return The number of events generated */ static int emulate_scroll_button_events(InternalEvent *events, DeviceIntPtr dev, int type, int axis, const ValuatorMask *mask, ValuatorMask *last, CARD32 ms, int max_events) { AxisInfoPtr ax; double delta; double incr; int num_events = 0; double total; int b; int flags = 0; if (dev->valuator->axes[axis].scroll.type == SCROLL_TYPE_NONE) return 0; if (!valuator_mask_isset(mask, axis)) return 0; ax = &dev->valuator->axes[axis]; incr = ax->scroll.increment; BUG_WARN_MSG(incr == 0, "for device %s\n", dev->name); if (incr == 0) return 0; if (type != ButtonPress && type != ButtonRelease) flags |= POINTER_EMULATED; if (!valuator_mask_isset(last, axis)) valuator_mask_set_double(last, axis, 0); delta = valuator_mask_get_double(mask, axis) - valuator_mask_get_double(last, axis); total = delta; b = (ax->scroll.type == SCROLL_TYPE_VERTICAL) ? 5 : 7; if ((incr > 0 && delta < 0) || (incr < 0 && delta > 0)) b--; /* we're scrolling up or left → button 4 or 6 */ while (fabs(delta) >= fabs(incr)) { int nev_tmp; if (delta > 0) delta -= fabs(incr); else if (delta < 0) delta += fabs(incr); /* fill_pointer_events() generates four events: one normal and one raw * event for button press and button release. * We may get a bigger scroll delta than we can generate events * for. In that case, we keep decreasing delta, but skip events. */ if (num_events + 4 < max_events) { if (type != ButtonRelease) { nev_tmp = fill_pointer_events(events, dev, ButtonPress, b, ms, flags, NULL); events += nev_tmp; num_events += nev_tmp; } if (type != ButtonPress) { nev_tmp = fill_pointer_events(events, dev, ButtonRelease, b, ms, flags, NULL); events += nev_tmp; num_events += nev_tmp; } } } /* We emulated, update last.scroll */ if (total != delta) { total -= delta; valuator_mask_set_double(last, axis, valuator_mask_get_double(last, axis) + total); } return num_events; } /** * Generate a complete series of InternalEvents (filled into the EventList) * representing pointer motion, or button presses. If the device is a slave * device, also potentially generate a DeviceClassesChangedEvent to update * the master device. * * events is not NULL-terminated; the return value is the number of events. * The DDX is responsible for allocating the event structure in the first * place via InitEventList() and GetMaximumEventsNum(), and for freeing it. * * In the generated events rootX/Y will be in absolute screen coords and * the valuator information in the absolute or relative device coords. * * last.valuators[x] of the device is always in absolute device coords. * last.valuators[x] of the master device is in absolute screen coords. * * master->last.valuators[x] for x > 2 is undefined. */ int GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons, int flags, const ValuatorMask *mask_in) { CARD32 ms = GetTimeInMillis(); int num_events = 0, nev_tmp; ValuatorMask mask; ValuatorMask scroll; int i; int realtype = type; #if XSERVER_DTRACE if (XSERVER_INPUT_EVENT_ENABLED()) { XSERVER_INPUT_EVENT(pDev->id, type, buttons, flags, mask_in ? mask_in->last_bit + 1 : 0, mask_in ? mask_in->mask : NULL, mask_in ? mask_in->valuators : NULL); } #endif BUG_RETURN_VAL(buttons >= MAX_BUTTONS, 0); /* refuse events from disabled devices */ if (!pDev->enabled) return 0; if (!miPointerGetScreen(pDev)) return 0; events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); valuator_mask_copy(&mask, mask_in); /* Turn a scroll button press into a smooth-scrolling event if * necessary. This only needs to cater for the XIScrollFlagPreferred * axis (if more than one scrolling axis is present) */ if (type == ButtonPress) { double adj; int axis; int h_scroll_axis = -1; int v_scroll_axis = -1; if (pDev->valuator) { h_scroll_axis = pDev->valuator->h_scroll_axis; v_scroll_axis = pDev->valuator->v_scroll_axis; } /* Up is negative on valuators, down positive */ switch (buttons) { case 4: adj = -1.0; axis = v_scroll_axis; break; case 5: adj = 1.0; axis = v_scroll_axis; break; case 6: adj = -1.0; axis = h_scroll_axis; break; case 7: adj = 1.0; axis = h_scroll_axis; break; default: adj = 0.0; axis = -1; break; } if (adj != 0.0 && axis != -1) { adj *= pDev->valuator->axes[axis].scroll.increment; if (!valuator_mask_isset(&mask, axis)) valuator_mask_set(&mask, axis, 0); add_to_scroll_valuator(pDev, &mask, axis, adj); type = MotionNotify; buttons = 0; flags |= POINTER_EMULATED; } } /* First fill out the original event set, with smooth-scrolling axes. */ nev_tmp = fill_pointer_events(events, pDev, type, buttons, ms, flags, &mask); events += nev_tmp; num_events += nev_tmp; valuator_mask_zero(&scroll); /* Now turn the smooth-scrolling axes back into emulated button presses * for legacy clients, based on the integer delta between before and now */ for (i = 0; i < valuator_mask_size(&mask); i++) { if ( !pDev->valuator || (i >= pDev->valuator->numAxes)) break; if (!valuator_mask_isset(&mask, i)) continue; valuator_mask_set_double(&scroll, i, pDev->last.valuators[i]); nev_tmp = emulate_scroll_button_events(events, pDev, realtype, i, &scroll, pDev->last.scroll, ms, GetMaximumEventsNum() - num_events); events += nev_tmp; num_events += nev_tmp; } return num_events; } /** * Generate internal events representing this proximity event and enqueue * them on the event queue. * * This function is not reentrant. Disable signals before calling. * * @param device The device to generate the event for * @param type Event type, one of ProximityIn or ProximityOut * @param keycode Key code of the pressed/released key * @param mask Valuator mask for valuators present for this event. * */ void QueueProximityEvents(DeviceIntPtr device, int type, const ValuatorMask *mask) { int nevents; nevents = GetProximityEvents(InputEventList, device, type, mask); queueEventList(device, InputEventList, nevents); } /** * Generate ProximityIn/ProximityOut InternalEvents, accompanied by * valuators. * * The DDX is responsible for allocating the events in the first place via * InitEventList(), and for freeing it. * * @return the number of events written into events. */ int GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in) { int num_events = 1, i; DeviceEvent *event; ValuatorMask mask; #if XSERVER_DTRACE if (XSERVER_INPUT_EVENT_ENABLED()) { XSERVER_INPUT_EVENT(pDev->id, type, 0, 0, mask_in ? mask_in->last_bit + 1 : 0, mask_in ? mask_in->mask : NULL, mask_in ? mask_in->valuators : NULL); } #endif /* refuse events from disabled devices */ if (!pDev->enabled) return 0; /* Sanity checks. */ if ((type != ProximityIn && type != ProximityOut) || !mask_in) return 0; if (!pDev->valuator || !pDev->proximity) return 0; valuator_mask_copy(&mask, mask_in); /* ignore relative axes for proximity. */ for (i = 0; i < valuator_mask_size(&mask); i++) { if (valuator_mask_isset(&mask, i) && valuator_get_mode(pDev, i) == Relative) valuator_mask_unset(&mask, i); } /* FIXME: posting proximity events with relative valuators only results * in an empty event, EventToXI() will fail to convert → no event sent * to client. */ events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); event = &events->device_event; init_device_event(event, pDev, GetTimeInMillis(), EVENT_SOURCE_NORMAL); event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut; clipValuators(pDev, &mask); set_valuators(pDev, event, &mask); return num_events; } int GetTouchOwnershipEvents(InternalEvent *events, DeviceIntPtr pDev, TouchPointInfoPtr ti, uint8_t reason, XID resource, uint32_t flags) { TouchClassPtr t = pDev->touch; TouchOwnershipEvent *event; CARD32 ms = GetTimeInMillis(); if (!pDev->enabled || !t || !ti) return 0; event = &events->touch_ownership_event; init_touch_ownership(pDev, event, ms); event->touchid = ti->client_id; event->sourceid = ti->sourceid; event->resource = resource; event->flags = flags; event->reason = reason; return 1; } /** * Generate internal events representing this touch event and enqueue them * on the event queue. * * This function is not reentrant. Disable signals before calling. * * @param device The device to generate the event for * @param type Event type, one of XI_TouchBegin, XI_TouchUpdate, XI_TouchEnd * @param touchid Touch point ID * @param flags Event modification flags * @param mask Valuator mask for valuators present for this event. */ void QueueTouchEvents(DeviceIntPtr device, int type, uint32_t ddx_touchid, int flags, const ValuatorMask *mask) { int nevents; nevents = GetTouchEvents(InputEventList, device, ddx_touchid, type, flags, mask); queueEventList(device, InputEventList, nevents); } /** * Get events for a touch. Generates a TouchBegin event if end is not set and * the touch id is not active. Generates a TouchUpdate event if end is not set * and the touch id is active. Generates a TouchEnd event if end is set and the * touch id is active. * * events is not NULL-terminated; the return value is the number of events. * The DDX is responsible for allocating the event structure in the first * place via GetMaximumEventsNum(), and for freeing it. * * @param[out] events The list of events generated * @param dev The device to generate the events for * @param ddx_touchid The touch ID as assigned by the DDX * @param type XI_TouchBegin, XI_TouchUpdate or XI_TouchEnd * @param flags Event flags * @param mask_in Valuator information for this event */ int GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid, uint16_t type, uint32_t flags, const ValuatorMask *mask_in) { ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen; TouchClassPtr t = dev->touch; ValuatorClassPtr v = dev->valuator; DeviceEvent *event; CARD32 ms = GetTimeInMillis(); ValuatorMask mask; double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */ double devx = 0.0, devy = 0.0; /* desktop-wide in device coords */ int i; int num_events = 0; RawDeviceEvent *raw; DDXTouchPointInfoPtr ti; int need_rawevent = TRUE; Bool emulate_pointer = FALSE; int client_id = 0; #if XSERVER_DTRACE if (XSERVER_INPUT_EVENT_ENABLED()) { XSERVER_INPUT_EVENT(dev->id, type, ddx_touchid, flags, mask_in ? mask_in->last_bit + 1 : 0, mask_in ? mask_in->mask : NULL, mask_in ? mask_in->valuators : NULL); } #endif if (!dev->enabled || !t || !v) return 0; /* Find and/or create the DDX touch info */ ti = TouchFindByDDXID(dev, ddx_touchid, (type == XI_TouchBegin)); if (!ti) { ErrorFSigSafe("[dix] %s: unable to %s touch point %u\n", dev->name, type == XI_TouchBegin ? "begin" : "find", ddx_touchid); return 0; } client_id = ti->client_id; emulate_pointer = ti->emulate_pointer; if (!IsMaster(dev)) events = UpdateFromMaster(events, dev, DEVCHANGE_POINTER_EVENT, &num_events); valuator_mask_copy(&mask, mask_in); if (need_rawevent) { raw = &events->raw_event; events++; num_events++; init_raw(dev, raw, ms, type, client_id); set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw); } event = &events->device_event; num_events++; init_device_event(event, dev, ms, EVENT_SOURCE_NORMAL); switch (type) { case XI_TouchBegin: event->type = ET_TouchBegin; /* If we're starting a touch, we must have x & y co-ordinates. */ if (!mask_in || !valuator_mask_isset(mask_in, 0) || !valuator_mask_isset(mask_in, 1)) { ErrorFSigSafe("%s: Attempted to start touch without x/y " "(driver bug)\n", dev->name); return 0; } break; case XI_TouchUpdate: event->type = ET_TouchUpdate; if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0) { ErrorFSigSafe("%s: TouchUpdate with no valuators? Driver bug\n", dev->name); } break; case XI_TouchEnd: event->type = ET_TouchEnd; /* We can end the DDX touch here, since we don't use the active * field below */ TouchEndDDXTouch(dev, ti); break; default: return 0; } /* Get our screen event co-ordinates (root_x/root_y/event_x/event_y): * these come from the touchpoint in Absolute mode, or the sprite in * Relative. */ if (t->mode == XIDirectTouch) { for (i = 0; i < max(valuator_mask_size(&mask), 2); i++) { double val; if (valuator_mask_fetch_double(&mask, i, &val)) valuator_mask_set_double(ti->valuators, i, val); /* If the device doesn't post new X and Y axis values, * use the last values posted. */ else if (i < 2 && valuator_mask_fetch_double(ti->valuators, i, &val)) valuator_mask_set_double(&mask, i, val); } transformAbsolute(dev, &mask); clipAbsolute(dev, &mask); } else { screenx = dev->spriteInfo->sprite->hotPhys.x; screeny = dev->spriteInfo->sprite->hotPhys.y; } if (need_rawevent) set_raw_valuators(raw, &mask, FALSE, raw->valuators.data); /* Indirect device touch coordinates are not used for cursor positioning. * They are merely informational, and are provided in device coordinates. * The device sprite is used for positioning instead, and it is already * scaled. */ if (t->mode == XIDirectTouch) scr = scale_to_desktop(dev, &mask, &devx, &devy, &screenx, &screeny); if (emulate_pointer) scr = positionSprite(dev, Absolute, &mask, &devx, &devy, &screenx, &screeny, NULL, NULL); /* see fill_pointer_events for coordinate systems */ if (emulate_pointer) updateHistory(dev, &mask, ms); clipValuators(dev, &mask); if (emulate_pointer) storeLastValuators(dev, &mask, 0, 1, devx, devy); /* Update the MD's co-ordinates, which are always in desktop space. */ if (emulate_pointer && !IsMaster(dev) && !IsFloating(dev)) { DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); master->last.valuators[0] = screenx; master->last.valuators[1] = screeny; } event->root = scr->root->drawable.id; event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y); event->touchid = client_id; event->flags = flags; if (emulate_pointer) { event->flags |= TOUCH_POINTER_EMULATED; event->detail.button = 1; } set_valuators(dev, event, &mask); for (i = 0; i < v->numAxes; i++) { if (valuator_mask_isset(&mask, i)) v->axisVal[i] = valuator_mask_get(&mask, i); } return num_events; } void GetDixTouchEnd(InternalEvent *ievent, DeviceIntPtr dev, TouchPointInfoPtr ti, uint32_t flags) { ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen; DeviceEvent *event = &ievent->device_event; CARD32 ms = GetTimeInMillis(); BUG_WARN(!dev->enabled); init_device_event(event, dev, ms, EVENT_SOURCE_NORMAL); event->sourceid = ti->sourceid; event->type = ET_TouchEnd; event->root = scr->root->drawable.id; /* Get screen event coordinates from the sprite. Is this really the best * we can do? */ event_set_root_coordinates(event, dev->last.valuators[0] - scr->x, dev->last.valuators[1] - scr->y); event->touchid = ti->client_id; event->flags = flags; if (flags & TOUCH_POINTER_EMULATED) { event->flags |= TOUCH_POINTER_EMULATED; event->detail.button = 1; } } /** * Synthesize a single motion event for the core pointer. * * Used in cursor functions, e.g. when cursor confinement changes, and we need * to shift the pointer to get it inside the new bounds. */ void PostSyntheticMotion(DeviceIntPtr pDev, int x, int y, int screen, unsigned long time) { DeviceEvent ev; #ifdef PANORAMIX /* Translate back to the sprite screen since processInputProc will translate from sprite screen to screen 0 upon reentry to the DIX layer. */ if (!noPanoramiXExtension) { x += screenInfo.screens[0]->x - screenInfo.screens[screen]->x; y += screenInfo.screens[0]->y - screenInfo.screens[screen]->y; } #endif memset(&ev, 0, sizeof(DeviceEvent)); init_device_event(&ev, pDev, time, EVENT_SOURCE_NORMAL); ev.root_x = x; ev.root_y = y; ev.type = ET_Motion; ev.time = time; /* FIXME: MD/SD considerations? */ (*pDev->public.processInputProc) ((InternalEvent *) &ev, pDev); } xorg-server-1.20.13/dix/globals.c0000644000175000017500000001023014100573755013440 00000000000000/************************************************************ Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include #include "misc.h" #include "windowstr.h" #include "scrnintstr.h" #include "input.h" #include "dixfont.h" #include "site.h" #include "dixstruct.h" #include "os.h" ScreenInfo screenInfo; KeybdCtrl defaultKeyboardControl = { DEFAULT_KEYBOARD_CLICK, DEFAULT_BELL, DEFAULT_BELL_PITCH, DEFAULT_BELL_DURATION, DEFAULT_AUTOREPEAT, DEFAULT_AUTOREPEATS, DEFAULT_LEDS, 0 }; PtrCtrl defaultPointerControl = { DEFAULT_PTR_NUMERATOR, DEFAULT_PTR_DENOMINATOR, DEFAULT_PTR_THRESHOLD, 0 }; ClientPtr clients[MAXCLIENTS]; ClientPtr serverClient; int currentMaxClients; /* current size of clients array */ long maxBigRequestSize = MAX_BIG_REQUEST_SIZE; unsigned long globalSerialNumber = 0; unsigned long serverGeneration = 0; /* these next four are initialized in main.c */ CARD32 ScreenSaverTime; CARD32 ScreenSaverInterval; int ScreenSaverBlanking; int ScreenSaverAllowExposures; CARD32 defaultScreenSaverTime = DEFAULT_SCREEN_SAVER_TIME; CARD32 defaultScreenSaverInterval = DEFAULT_SCREEN_SAVER_INTERVAL; int defaultScreenSaverBlanking = DEFAULT_SCREEN_SAVER_BLANKING; int defaultScreenSaverAllowExposures = DEFAULT_SCREEN_SAVER_EXPOSURES; #ifdef SCREENSAVER Bool screenSaverSuspended = FALSE; #endif const char *defaultFontPath = COMPILEDDEFAULTFONTPATH; const char *defaultTextFont = COMPILEDDEFAULTFONT; const char *defaultCursorFont = COMPILEDCURSORFONT; FontPtr defaultFont; /* not declared in dix.h to avoid including font.h in every compilation of dix code */ CursorPtr rootCursor; Bool party_like_its_1989 = FALSE; Bool whiteRoot = FALSE; TimeStamp currentTime; int defaultColorVisualClass = -1; int monitorResolution = 0; const char *display; int displayfd = -1; Bool explicit_display = FALSE; char *ConnectionInfo; CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND; xorg-server-1.20.13/dix/glyphcurs.c0000644000175000017500000001423514100573755014046 00000000000000/************************************************************************ Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include "misc.h" #include #include "dixfontstr.h" #include "scrnintstr.h" #include "gcstruct.h" #include "resource.h" #include "dix.h" #include "cursorstr.h" #include "opaque.h" #include "servermd.h" /* get the bits out of the font in a portable way. to avoid dealing with padding and such-like, we draw the glyph into a bitmap, then read the bits out with GetImage, which uses server-natural format. since all screens return the same bitmap format, we'll just use the first one we find. the character origin lines up with the hotspot in the cursor metrics. */ int ServerBitsFromGlyph(FontPtr pfont, unsigned ch, CursorMetricPtr cm, unsigned char **ppbits) { ScreenPtr pScreen; GCPtr pGC; xRectangle rect; PixmapPtr ppix; char *pbits; ChangeGCVal gcval[3]; unsigned char char2b[2]; /* turn glyph index into a protocol-format char2b */ char2b[0] = (unsigned char) (ch >> 8); char2b[1] = (unsigned char) (ch & 0xff); pScreen = screenInfo.screens[0]; pbits = calloc(BitmapBytePad(cm->width), cm->height); if (!pbits) return BadAlloc; ppix = (PixmapPtr) (*pScreen->CreatePixmap) (pScreen, cm->width, cm->height, 1, CREATE_PIXMAP_USAGE_SCRATCH); pGC = GetScratchGC(1, pScreen); if (!ppix || !pGC) { if (ppix) (*pScreen->DestroyPixmap) (ppix); if (pGC) FreeScratchGC(pGC); free(pbits); return BadAlloc; } rect.x = 0; rect.y = 0; rect.width = cm->width; rect.height = cm->height; /* fill the pixmap with 0 */ gcval[0].val = GXcopy; gcval[1].val = 0; gcval[2].ptr = (void *) pfont; ChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFont, gcval); ValidateGC((DrawablePtr) ppix, pGC); (*pGC->ops->PolyFillRect) ((DrawablePtr) ppix, pGC, 1, &rect); /* draw the glyph */ gcval[0].val = 1; ChangeGC(NullClient, pGC, GCForeground, gcval); ValidateGC((DrawablePtr) ppix, pGC); (*pGC->ops->PolyText16) ((DrawablePtr) ppix, pGC, cm->xhot, cm->yhot, 1, (unsigned short *) char2b); (*pScreen->GetImage) ((DrawablePtr) ppix, 0, 0, cm->width, cm->height, XYPixmap, 1, pbits); *ppbits = (unsigned char *) pbits; FreeScratchGC(pGC); (*pScreen->DestroyPixmap) (ppix); return Success; } Bool CursorMetricsFromGlyph(FontPtr pfont, unsigned ch, CursorMetricPtr cm) { CharInfoPtr pci; unsigned long nglyphs; CARD8 chs[2]; FontEncoding encoding; chs[0] = ch >> 8; chs[1] = ch; encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit; if (encoding == Linear16Bit) { if (ch < pfont->info.firstCol || pfont->info.lastCol < ch) return FALSE; } else { if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0]) return FALSE; if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1]) return FALSE; } (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci); if (nglyphs == 0) return FALSE; cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing; cm->height = pci->metrics.descent + pci->metrics.ascent; if (pci->metrics.leftSideBearing > 0) { cm->width += pci->metrics.leftSideBearing; cm->xhot = 0; } else { cm->xhot = -pci->metrics.leftSideBearing; if (pci->metrics.rightSideBearing < 0) cm->width -= pci->metrics.rightSideBearing; } if (pci->metrics.ascent < 0) { cm->height -= pci->metrics.ascent; cm->yhot = 0; } else { cm->yhot = pci->metrics.ascent; if (pci->metrics.descent < 0) cm->height -= pci->metrics.descent; } return TRUE; } xorg-server-1.20.13/dix/grabs.c0000644000175000017500000005470014100573755013125 00000000000000/* Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include "misc.h" #include #include #include "windowstr.h" #include "inputstr.h" #include "cursorstr.h" #include "dixgrabs.h" #include "xace.h" #include "exevents.h" #include "exglobals.h" #include "inpututils.h" #include "client.h" #define BITMASK(i) (((Mask)1) << ((i) & 31)) #define MASKIDX(i) ((i) >> 5) #define MASKWORD(buf, i) buf[MASKIDX(i)] #define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i) #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) void PrintDeviceGrabInfo(DeviceIntPtr dev) { ClientPtr client; LocalClientCredRec *lcc; int i, j; GrabInfoPtr devGrab = &dev->deviceGrab; GrabPtr grab = devGrab->grab; Bool clientIdPrinted = FALSE; ErrorF("Active grab 0x%lx (%s) on device '%s' (%d):\n", (unsigned long) grab->resource, (grab->grabtype == XI2) ? "xi2" : ((grab->grabtype == CORE) ? "core" : "xi1"), dev->name, dev->id); client = clients[CLIENT_ID(grab->resource)]; if (client) { pid_t clientpid = GetClientPid(client); const char *cmdname = GetClientCmdName(client); const char *cmdargs = GetClientCmdArgs(client); if ((clientpid > 0) && (cmdname != NULL)) { ErrorF(" client pid %ld %s %s\n", (long) clientpid, cmdname, cmdargs ? cmdargs : ""); clientIdPrinted = TRUE; } else if (GetLocalClientCreds(client, &lcc) != -1) { ErrorF(" client pid %ld uid %ld gid %ld\n", (lcc->fieldsSet & LCC_PID_SET) ? (long) lcc->pid : 0, (lcc->fieldsSet & LCC_UID_SET) ? (long) lcc->euid : 0, (lcc->fieldsSet & LCC_GID_SET) ? (long) lcc->egid : 0); FreeLocalClientCreds(lcc); clientIdPrinted = TRUE; } } if (!clientIdPrinted) { ErrorF(" (no client information available for client %d)\n", CLIENT_ID(grab->resource)); } /* XXX is this even correct? */ if (devGrab->sync.other) ErrorF(" grab ID 0x%lx from paired device\n", (unsigned long) devGrab->sync.other->resource); ErrorF(" at %ld (from %s grab)%s (device %s, state %d)\n", (unsigned long) devGrab->grabTime.milliseconds, devGrab->fromPassiveGrab ? "passive" : "active", devGrab->implicitGrab ? " (implicit)" : "", devGrab->sync.frozen ? "frozen" : "thawed", devGrab->sync.state); if (grab->grabtype == CORE) { ErrorF(" core event mask 0x%lx\n", (unsigned long) grab->eventMask); } else if (grab->grabtype == XI) { ErrorF(" xi1 event mask 0x%lx\n", devGrab->implicitGrab ? (unsigned long) grab->deviceMask : (unsigned long) grab->eventMask); } else if (grab->grabtype == XI2) { for (i = 0; i < xi2mask_num_masks(grab->xi2mask); i++) { const unsigned char *mask; int print; print = 0; for (j = 0; j < XI2MASKSIZE; j++) { mask = xi2mask_get_one_mask(grab->xi2mask, i); if (mask[j]) { print = 1; break; } } if (!print) continue; ErrorF(" xi2 event mask for device %d: 0x", dev->id); for (j = 0; j < xi2mask_mask_size(grab->xi2mask); j++) ErrorF("%x", mask[j]); ErrorF("\n"); } } if (devGrab->fromPassiveGrab) { ErrorF(" passive grab type %d, detail 0x%x, " "activating key %d\n", grab->type, grab->detail.exact, devGrab->activatingKey); } ErrorF(" owner-events %s, kb %d ptr %d, confine %lx, cursor 0x%lx\n", grab->ownerEvents ? "true" : "false", grab->keyboardMode, grab->pointerMode, grab->confineTo ? (unsigned long) grab->confineTo->drawable.id : 0, grab->cursor ? (unsigned long) grab->cursor->id : 0); } void UngrabAllDevices(Bool kill_client) { DeviceIntPtr dev; ClientPtr client; ErrorF("Ungrabbing all devices%s; grabs listed below:\n", kill_client ? " and killing their owners" : ""); for (dev = inputInfo.devices; dev; dev = dev->next) { if (!dev->deviceGrab.grab) continue; PrintDeviceGrabInfo(dev); client = clients[CLIENT_ID(dev->deviceGrab.grab->resource)]; if (!kill_client || !client || client->clientGone) dev->deviceGrab.DeactivateGrab(dev); if (kill_client) CloseDownClient(client); } ErrorF("End list of ungrabbed devices\n"); } GrabPtr AllocGrab(const GrabPtr src) { GrabPtr grab = calloc(1, sizeof(GrabRec)); if (grab) { grab->xi2mask = xi2mask_new(); if (!grab->xi2mask) { free(grab); grab = NULL; } else if (src && !CopyGrab(grab, src)) { free(grab->xi2mask); free(grab); grab = NULL; } } return grab; } GrabPtr CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice, WindowPtr window, enum InputLevel grabtype, GrabMask *mask, GrabParameters *param, int type, KeyCode keybut, /* key or button */ WindowPtr confineTo, CursorPtr cursor) { GrabPtr grab; grab = AllocGrab(NULL); if (!grab) return (GrabPtr) NULL; grab->resource = FakeClientID(client); grab->device = device; grab->window = window; if (grabtype == CORE || grabtype == XI) grab->eventMask = mask->core; /* same for XI */ else grab->eventMask = 0; grab->deviceMask = 0; grab->ownerEvents = param->ownerEvents; grab->keyboardMode = param->this_device_mode; grab->pointerMode = param->other_devices_mode; grab->modifiersDetail.exact = param->modifiers; grab->modifiersDetail.pMask = NULL; grab->modifierDevice = modDevice; grab->type = type; grab->grabtype = grabtype; grab->detail.exact = keybut; grab->detail.pMask = NULL; grab->confineTo = confineTo; grab->cursor = RefCursor(cursor); grab->next = NULL; if (grabtype == XI2) xi2mask_merge(grab->xi2mask, mask->xi2mask); return grab; } void FreeGrab(GrabPtr pGrab) { BUG_RETURN(!pGrab); free(pGrab->modifiersDetail.pMask); free(pGrab->detail.pMask); if (pGrab->cursor) FreeCursor(pGrab->cursor, (Cursor) 0); xi2mask_free(&pGrab->xi2mask); free(pGrab); } Bool CopyGrab(GrabPtr dst, const GrabPtr src) { Mask *mdetails_mask = NULL; Mask *details_mask = NULL; XI2Mask *xi2mask; if (src->modifiersDetail.pMask) { int len = MasksPerDetailMask * sizeof(Mask); mdetails_mask = malloc(len); if (!mdetails_mask) return FALSE; memcpy(mdetails_mask, src->modifiersDetail.pMask, len); } if (src->detail.pMask) { int len = MasksPerDetailMask * sizeof(Mask); details_mask = malloc(len); if (!details_mask) { free(mdetails_mask); return FALSE; } memcpy(details_mask, src->detail.pMask, len); } if (!dst->xi2mask) { xi2mask = xi2mask_new(); if (!xi2mask) { free(mdetails_mask); free(details_mask); return FALSE; } } else { xi2mask = dst->xi2mask; xi2mask_zero(xi2mask, -1); } *dst = *src; dst->modifiersDetail.pMask = mdetails_mask; dst->detail.pMask = details_mask; dst->xi2mask = xi2mask; dst->cursor = RefCursor(src->cursor); xi2mask_merge(dst->xi2mask, src->xi2mask); return TRUE; } int DeletePassiveGrab(void *value, XID id) { GrabPtr g, prev; GrabPtr pGrab = (GrabPtr) value; /* it is OK if the grab isn't found */ prev = 0; for (g = (wPassiveGrabs(pGrab->window)); g; g = g->next) { if (pGrab == g) { if (prev) prev->next = g->next; else if (!(pGrab->window->optional->passiveGrabs = g->next)) CheckWindowOptionalNeed(pGrab->window); break; } prev = g; } FreeGrab(pGrab); return Success; } static Mask * DeleteDetailFromMask(Mask *pDetailMask, unsigned int detail) { Mask *mask; int i; mask = malloc(sizeof(Mask) * MasksPerDetailMask); if (mask) { if (pDetailMask) for (i = 0; i < MasksPerDetailMask; i++) mask[i] = pDetailMask[i]; else for (i = 0; i < MasksPerDetailMask; i++) mask[i] = ~0L; BITCLEAR(mask, detail); } return mask; } static Bool IsInGrabMask(DetailRec firstDetail, DetailRec secondDetail, unsigned int exception) { if (firstDetail.exact == exception) { if (firstDetail.pMask == NULL) return TRUE; /* (at present) never called with two non-null pMasks */ if (secondDetail.exact == exception) return FALSE; if (GETBIT(firstDetail.pMask, secondDetail.exact)) return TRUE; } return FALSE; } static Bool IdenticalExactDetails(unsigned int firstExact, unsigned int secondExact, unsigned int exception) { if ((firstExact == exception) || (secondExact == exception)) return FALSE; if (firstExact == secondExact) return TRUE; return FALSE; } static Bool DetailSupersedesSecond(DetailRec firstDetail, DetailRec secondDetail, unsigned int exception) { if (IsInGrabMask(firstDetail, secondDetail, exception)) return TRUE; if (IdenticalExactDetails(firstDetail.exact, secondDetail.exact, exception)) return TRUE; return FALSE; } static Bool GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab) { unsigned int any_modifier = (pFirstGrab->grabtype == XI2) ? (unsigned int) XIAnyModifier : (unsigned int) AnyModifier; if (!DetailSupersedesSecond(pFirstGrab->modifiersDetail, pSecondGrab->modifiersDetail, any_modifier)) return FALSE; if (DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail, (unsigned int) AnyKey)) return TRUE; return FALSE; } /** * Compares two grabs and returns TRUE if the first grab matches the second * grab. * * A match is when * - the devices set for the grab are equal (this is optional). * - the event types for both grabs are equal. * - XXX * * @param ignoreDevice TRUE if the device settings on the grabs are to be * ignored. * @return TRUE if the grabs match or FALSE otherwise. */ Bool GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice) { unsigned int any_modifier = (pFirstGrab->grabtype == XI2) ? (unsigned int) XIAnyModifier : (unsigned int) AnyModifier; if (pFirstGrab->grabtype != pSecondGrab->grabtype) return FALSE; if (pFirstGrab->grabtype == XI2) { if (pFirstGrab->device == inputInfo.all_devices || pSecondGrab->device == inputInfo.all_devices) { /* do nothing */ } else if (pFirstGrab->device == inputInfo.all_master_devices) { if (pSecondGrab->device != inputInfo.all_master_devices && !IsMaster(pSecondGrab->device)) return FALSE; } else if (pSecondGrab->device == inputInfo.all_master_devices) { if (pFirstGrab->device != inputInfo.all_master_devices && !IsMaster(pFirstGrab->device)) return FALSE; } else if (pSecondGrab->device != pFirstGrab->device) return FALSE; } else if (!ignoreDevice && ((pFirstGrab->device != pSecondGrab->device) || (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice))) return FALSE; if (pFirstGrab->type != pSecondGrab->type) return FALSE; if (GrabSupersedesSecond(pFirstGrab, pSecondGrab) || GrabSupersedesSecond(pSecondGrab, pFirstGrab)) return TRUE; if (DetailSupersedesSecond(pSecondGrab->detail, pFirstGrab->detail, (unsigned int) AnyKey) && DetailSupersedesSecond(pFirstGrab->modifiersDetail, pSecondGrab->modifiersDetail, any_modifier)) return TRUE; if (DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail, (unsigned int) AnyKey) && DetailSupersedesSecond(pSecondGrab->modifiersDetail, pFirstGrab->modifiersDetail, any_modifier)) return TRUE; return FALSE; } static Bool GrabsAreIdentical(GrabPtr pFirstGrab, GrabPtr pSecondGrab) { unsigned int any_modifier = (pFirstGrab->grabtype == XI2) ? (unsigned int) XIAnyModifier : (unsigned int) AnyModifier; if (pFirstGrab->grabtype != pSecondGrab->grabtype) return FALSE; if (pFirstGrab->device != pSecondGrab->device || (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice) || (pFirstGrab->type != pSecondGrab->type)) return FALSE; if (!(DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail, (unsigned int) AnyKey) && DetailSupersedesSecond(pSecondGrab->detail, pFirstGrab->detail, (unsigned int) AnyKey))) return FALSE; if (!(DetailSupersedesSecond(pFirstGrab->modifiersDetail, pSecondGrab->modifiersDetail, any_modifier) && DetailSupersedesSecond(pSecondGrab->modifiersDetail, pFirstGrab->modifiersDetail, any_modifier))) return FALSE; return TRUE; } /** * Prepend the new grab to the list of passive grabs on the window. * Any previously existing grab that matches the new grab will be removed. * Adding a new grab that would override another client's grab will result in * a BadAccess. * * @return Success or X error code on failure. */ int AddPassiveGrabToList(ClientPtr client, GrabPtr pGrab) { GrabPtr grab; Mask access_mode = DixGrabAccess; int rc; for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next) { if (GrabMatchesSecond(pGrab, grab, (pGrab->grabtype == CORE))) { if (CLIENT_BITS(pGrab->resource) != CLIENT_BITS(grab->resource)) { FreeGrab(pGrab); return BadAccess; } } } if (pGrab->keyboardMode == GrabModeSync || pGrab->pointerMode == GrabModeSync) access_mode |= DixFreezeAccess; rc = XaceHook(XACE_DEVICE_ACCESS, client, pGrab->device, access_mode); if (rc != Success) return rc; /* Remove all grabs that match the new one exactly */ for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next) { if (GrabsAreIdentical(pGrab, grab)) { DeletePassiveGrabFromList(grab); break; } } if (!pGrab->window->optional && !MakeWindowOptional(pGrab->window)) { FreeGrab(pGrab); return BadAlloc; } pGrab->next = pGrab->window->optional->passiveGrabs; pGrab->window->optional->passiveGrabs = pGrab; if (AddResource(pGrab->resource, RT_PASSIVEGRAB, (void *) pGrab)) return Success; return BadAlloc; } /* the following is kinda complicated, because we need to be able to back out * if any allocation fails */ Bool DeletePassiveGrabFromList(GrabPtr pMinuendGrab) { GrabPtr grab; GrabPtr *deletes, *adds; Mask ***updates, **details; int i, ndels, nadds, nups; Bool ok; unsigned int any_modifier; unsigned int any_key; #define UPDATE(mask,exact) \ if (!(details[nups] = DeleteDetailFromMask(mask, exact))) \ ok = FALSE; \ else \ updates[nups++] = &(mask) i = 0; for (grab = wPassiveGrabs(pMinuendGrab->window); grab; grab = grab->next) i++; if (!i) return TRUE; deletes = xallocarray(i, sizeof(GrabPtr)); adds = xallocarray(i, sizeof(GrabPtr)); updates = xallocarray(i, sizeof(Mask **)); details = xallocarray(i, sizeof(Mask *)); if (!deletes || !adds || !updates || !details) { free(details); free(updates); free(adds); free(deletes); return FALSE; } any_modifier = (pMinuendGrab->grabtype == XI2) ? (unsigned int) XIAnyModifier : (unsigned int) AnyModifier; any_key = (pMinuendGrab->grabtype == XI2) ? (unsigned int) XIAnyKeycode : (unsigned int) AnyKey; ndels = nadds = nups = 0; ok = TRUE; for (grab = wPassiveGrabs(pMinuendGrab->window); grab && ok; grab = grab->next) { if ((CLIENT_BITS(grab->resource) != CLIENT_BITS(pMinuendGrab->resource)) || !GrabMatchesSecond(grab, pMinuendGrab, (grab->grabtype == CORE))) continue; if (GrabSupersedesSecond(pMinuendGrab, grab)) { deletes[ndels++] = grab; } else if ((grab->detail.exact == any_key) && (grab->modifiersDetail.exact != any_modifier)) { UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); } else if ((grab->modifiersDetail.exact == any_modifier) && (grab->detail.exact != any_key)) { UPDATE(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail.exact); } else if ((pMinuendGrab->detail.exact != any_key) && (pMinuendGrab->modifiersDetail.exact != any_modifier)) { GrabPtr pNewGrab; GrabParameters param; UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); memset(¶m, 0, sizeof(param)); param.ownerEvents = grab->ownerEvents; param.this_device_mode = grab->keyboardMode; param.other_devices_mode = grab->pointerMode; param.modifiers = any_modifier; pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device, grab->modifierDevice, grab->window, grab->grabtype, (GrabMask *) &grab->eventMask, ¶m, (int) grab->type, pMinuendGrab->detail.exact, grab->confineTo, grab->cursor); if (!pNewGrab) ok = FALSE; else if (!(pNewGrab->modifiersDetail.pMask = DeleteDetailFromMask(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail. exact)) || (!pNewGrab->window->optional && !MakeWindowOptional(pNewGrab->window))) { FreeGrab(pNewGrab); ok = FALSE; } else if (!AddResource(pNewGrab->resource, RT_PASSIVEGRAB, (void *) pNewGrab)) ok = FALSE; else adds[nadds++] = pNewGrab; } else if (pMinuendGrab->detail.exact == any_key) { UPDATE(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail.exact); } else { UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); } } if (!ok) { for (i = 0; i < nadds; i++) FreeResource(adds[i]->resource, RT_NONE); for (i = 0; i < nups; i++) free(details[i]); } else { for (i = 0; i < ndels; i++) FreeResource(deletes[i]->resource, RT_NONE); for (i = 0; i < nadds; i++) { grab = adds[i]; grab->next = grab->window->optional->passiveGrabs; grab->window->optional->passiveGrabs = grab; } for (i = 0; i < nups; i++) { free(*updates[i]); *updates[i] = details[i]; } } free(details); free(updates); free(adds); free(deletes); return ok; #undef UPDATE } Bool GrabIsPointerGrab(GrabPtr grab) { return (grab->type == ButtonPress || grab->type == DeviceButtonPress || grab->type == XI_ButtonPress); } Bool GrabIsKeyboardGrab(GrabPtr grab) { return (grab->type == KeyPress || grab->type == DeviceKeyPress || grab->type == XI_KeyPress); } xorg-server-1.20.13/dix/initatoms.c0000644000175000017500000001261214100573755014032 00000000000000/* THIS IS A GENERATED FILE * * Do not change! Changing this file implies a protocol change! */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include "misc.h" #include "dix.h" void MakePredeclaredAtoms(void) { if (MakeAtom("PRIMARY", 7, 1) != XA_PRIMARY) AtomError(); if (MakeAtom("SECONDARY", 9, 1) != XA_SECONDARY) AtomError(); if (MakeAtom("ARC", 3, 1) != XA_ARC) AtomError(); if (MakeAtom("ATOM", 4, 1) != XA_ATOM) AtomError(); if (MakeAtom("BITMAP", 6, 1) != XA_BITMAP) AtomError(); if (MakeAtom("CARDINAL", 8, 1) != XA_CARDINAL) AtomError(); if (MakeAtom("COLORMAP", 8, 1) != XA_COLORMAP) AtomError(); if (MakeAtom("CURSOR", 6, 1) != XA_CURSOR) AtomError(); if (MakeAtom("CUT_BUFFER0", 11, 1) != XA_CUT_BUFFER0) AtomError(); if (MakeAtom("CUT_BUFFER1", 11, 1) != XA_CUT_BUFFER1) AtomError(); if (MakeAtom("CUT_BUFFER2", 11, 1) != XA_CUT_BUFFER2) AtomError(); if (MakeAtom("CUT_BUFFER3", 11, 1) != XA_CUT_BUFFER3) AtomError(); if (MakeAtom("CUT_BUFFER4", 11, 1) != XA_CUT_BUFFER4) AtomError(); if (MakeAtom("CUT_BUFFER5", 11, 1) != XA_CUT_BUFFER5) AtomError(); if (MakeAtom("CUT_BUFFER6", 11, 1) != XA_CUT_BUFFER6) AtomError(); if (MakeAtom("CUT_BUFFER7", 11, 1) != XA_CUT_BUFFER7) AtomError(); if (MakeAtom("DRAWABLE", 8, 1) != XA_DRAWABLE) AtomError(); if (MakeAtom("FONT", 4, 1) != XA_FONT) AtomError(); if (MakeAtom("INTEGER", 7, 1) != XA_INTEGER) AtomError(); if (MakeAtom("PIXMAP", 6, 1) != XA_PIXMAP) AtomError(); if (MakeAtom("POINT", 5, 1) != XA_POINT) AtomError(); if (MakeAtom("RECTANGLE", 9, 1) != XA_RECTANGLE) AtomError(); if (MakeAtom("RESOURCE_MANAGER", 16, 1) != XA_RESOURCE_MANAGER) AtomError(); if (MakeAtom("RGB_COLOR_MAP", 13, 1) != XA_RGB_COLOR_MAP) AtomError(); if (MakeAtom("RGB_BEST_MAP", 12, 1) != XA_RGB_BEST_MAP) AtomError(); if (MakeAtom("RGB_BLUE_MAP", 12, 1) != XA_RGB_BLUE_MAP) AtomError(); if (MakeAtom("RGB_DEFAULT_MAP", 15, 1) != XA_RGB_DEFAULT_MAP) AtomError(); if (MakeAtom("RGB_GRAY_MAP", 12, 1) != XA_RGB_GRAY_MAP) AtomError(); if (MakeAtom("RGB_GREEN_MAP", 13, 1) != XA_RGB_GREEN_MAP) AtomError(); if (MakeAtom("RGB_RED_MAP", 11, 1) != XA_RGB_RED_MAP) AtomError(); if (MakeAtom("STRING", 6, 1) != XA_STRING) AtomError(); if (MakeAtom("VISUALID", 8, 1) != XA_VISUALID) AtomError(); if (MakeAtom("WINDOW", 6, 1) != XA_WINDOW) AtomError(); if (MakeAtom("WM_COMMAND", 10, 1) != XA_WM_COMMAND) AtomError(); if (MakeAtom("WM_HINTS", 8, 1) != XA_WM_HINTS) AtomError(); if (MakeAtom("WM_CLIENT_MACHINE", 17, 1) != XA_WM_CLIENT_MACHINE) AtomError(); if (MakeAtom("WM_ICON_NAME", 12, 1) != XA_WM_ICON_NAME) AtomError(); if (MakeAtom("WM_ICON_SIZE", 12, 1) != XA_WM_ICON_SIZE) AtomError(); if (MakeAtom("WM_NAME", 7, 1) != XA_WM_NAME) AtomError(); if (MakeAtom("WM_NORMAL_HINTS", 15, 1) != XA_WM_NORMAL_HINTS) AtomError(); if (MakeAtom("WM_SIZE_HINTS", 13, 1) != XA_WM_SIZE_HINTS) AtomError(); if (MakeAtom("WM_ZOOM_HINTS", 13, 1) != XA_WM_ZOOM_HINTS) AtomError(); if (MakeAtom("MIN_SPACE", 9, 1) != XA_MIN_SPACE) AtomError(); if (MakeAtom("NORM_SPACE", 10, 1) != XA_NORM_SPACE) AtomError(); if (MakeAtom("MAX_SPACE", 9, 1) != XA_MAX_SPACE) AtomError(); if (MakeAtom("END_SPACE", 9, 1) != XA_END_SPACE) AtomError(); if (MakeAtom("SUPERSCRIPT_X", 13, 1) != XA_SUPERSCRIPT_X) AtomError(); if (MakeAtom("SUPERSCRIPT_Y", 13, 1) != XA_SUPERSCRIPT_Y) AtomError(); if (MakeAtom("SUBSCRIPT_X", 11, 1) != XA_SUBSCRIPT_X) AtomError(); if (MakeAtom("SUBSCRIPT_Y", 11, 1) != XA_SUBSCRIPT_Y) AtomError(); if (MakeAtom("UNDERLINE_POSITION", 18, 1) != XA_UNDERLINE_POSITION) AtomError(); if (MakeAtom("UNDERLINE_THICKNESS", 19, 1) != XA_UNDERLINE_THICKNESS) AtomError(); if (MakeAtom("STRIKEOUT_ASCENT", 16, 1) != XA_STRIKEOUT_ASCENT) AtomError(); if (MakeAtom("STRIKEOUT_DESCENT", 17, 1) != XA_STRIKEOUT_DESCENT) AtomError(); if (MakeAtom("ITALIC_ANGLE", 12, 1) != XA_ITALIC_ANGLE) AtomError(); if (MakeAtom("X_HEIGHT", 8, 1) != XA_X_HEIGHT) AtomError(); if (MakeAtom("QUAD_WIDTH", 10, 1) != XA_QUAD_WIDTH) AtomError(); if (MakeAtom("WEIGHT", 6, 1) != XA_WEIGHT) AtomError(); if (MakeAtom("POINT_SIZE", 10, 1) != XA_POINT_SIZE) AtomError(); if (MakeAtom("RESOLUTION", 10, 1) != XA_RESOLUTION) AtomError(); if (MakeAtom("COPYRIGHT", 9, 1) != XA_COPYRIGHT) AtomError(); if (MakeAtom("NOTICE", 6, 1) != XA_NOTICE) AtomError(); if (MakeAtom("FONT_NAME", 9, 1) != XA_FONT_NAME) AtomError(); if (MakeAtom("FAMILY_NAME", 11, 1) != XA_FAMILY_NAME) AtomError(); if (MakeAtom("FULL_NAME", 9, 1) != XA_FULL_NAME) AtomError(); if (MakeAtom("CAP_HEIGHT", 10, 1) != XA_CAP_HEIGHT) AtomError(); if (MakeAtom("WM_CLASS", 8, 1) != XA_WM_CLASS) AtomError(); if (MakeAtom("WM_TRANSIENT_FOR", 16, 1) != XA_WM_TRANSIENT_FOR) AtomError(); } xorg-server-1.20.13/dix/inpututils.c0000644000175000017500000007566414100573755014263 00000000000000/* * Copyright © 2008 Daniel Stone * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Daniel Stone */ #ifdef HAVE_DIX_CONFIG_H #include "dix-config.h" #endif #include "exevents.h" #include "exglobals.h" #include "misc.h" #include "input.h" #include "inputstr.h" #include "xace.h" #include "xkbsrv.h" #include "xkbstr.h" #include "inpututils.h" #include "eventstr.h" #include "scrnintstr.h" #include "optionstr.h" /* Check if a button map change is okay with the device. * Returns -1 for BadValue, as it collides with MappingBusy. */ static int check_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, CARD32 *errval_out, ClientPtr client) { int i, ret; if (!dev || !dev->button) { client->errorValue = (dev) ? dev->id : 0; return BadDevice; } ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); if (ret != Success) { client->errorValue = dev->id; return ret; } for (i = 0; i < len; i++) { if (dev->button->map[i + 1] != map[i] && button_is_down(dev, i + 1, BUTTON_PROCESSED)) return MappingBusy; } return Success; } static void do_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) { int i; xEvent core_mn = { .u.u.type = MappingNotify }; deviceMappingNotify xi_mn; /* The map in ButtonClassRec refers to button numbers, whereas the * protocol is zero-indexed. Sigh. */ memcpy(&(dev->button->map[1]), map, len); core_mn.u.mappingNotify.request = MappingPointer; /* 0 is the server client. */ for (i = 1; i < currentMaxClients; i++) { /* Don't send irrelevant events to naïve clients. */ if (!clients[i] || clients[i]->clientState != ClientStateRunning) continue; if (!XIShouldNotify(clients[i], dev)) continue; WriteEventsToClient(clients[i], 1, &core_mn); } xi_mn = (deviceMappingNotify) { .type = DeviceMappingNotify, .request = MappingPointer, .deviceid = dev->id, .time = GetTimeInMillis() }; SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1); } /* * Does what it says on the box, both for core and Xi. * * Faithfully reports any errors encountered while trying to apply the map * to the requested device, faithfully ignores any errors encountered while * trying to apply the map to its master/slaves. */ int ApplyPointerMapping(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) { int ret; /* If we can't perform the change on the requested device, bail out. */ ret = check_butmap_change(dev, map, len, &client->errorValue, client); if (ret != Success) return ret; do_butmap_change(dev, map, len, client); return Success; } /* Check if a modifier map change is okay with the device. * Returns -1 for BadValue, as it collides with MappingBusy; this particular * caveat can be removed with LegalModifier, as we have no other reason to * set MappingFailed. Sigh. */ static int check_modmap_change(ClientPtr client, DeviceIntPtr dev, KeyCode *modmap) { int ret, i; XkbDescPtr xkb; ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); if (ret != Success) return ret; if (!dev->key) return BadMatch; xkb = dev->key->xkbInfo->desc; for (i = 0; i < MAP_LENGTH; i++) { if (!modmap[i]) continue; /* Check that all the new modifiers fall within the advertised * keycode range. */ if (i < xkb->min_key_code || i > xkb->max_key_code) { client->errorValue = i; return -1; } /* Make sure the mapping is okay with the DDX. */ if (!LegalModifier(i, dev)) { client->errorValue = i; return MappingFailed; } /* None of the new modifiers may be down while we change the * map. */ if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) { client->errorValue = i; return MappingBusy; } } /* None of the old modifiers may be down while we change the map, * either. */ for (i = xkb->min_key_code; i < xkb->max_key_code; i++) { if (!xkb->map->modmap[i]) continue; if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) { client->errorValue = i; return MappingBusy; } } return Success; } static int check_modmap_change_slave(ClientPtr client, DeviceIntPtr master, DeviceIntPtr slave, CARD8 *modmap) { XkbDescPtr master_xkb, slave_xkb; int i, j; if (!slave->key || !master->key) return 0; master_xkb = master->key->xkbInfo->desc; slave_xkb = slave->key->xkbInfo->desc; /* Ignore devices with a clearly different keymap. */ if (slave_xkb->min_key_code != master_xkb->min_key_code || slave_xkb->max_key_code != master_xkb->max_key_code) return 0; for (i = 0; i < MAP_LENGTH; i++) { if (!modmap[i]) continue; /* If we have different symbols for any modifier on an * extended keyboard, ignore the whole remap request. */ for (j = 0; j < XkbKeyNumSyms(slave_xkb, i) && j < XkbKeyNumSyms(master_xkb, i); j++) if (XkbKeySymsPtr(slave_xkb, i)[j] != XkbKeySymsPtr(master_xkb, i)[j]) return 0; } if (check_modmap_change(client, slave, modmap) != Success) return 0; return 1; } /* Actually change the modifier map, and send notifications. Cannot fail. */ static void do_modmap_change(ClientPtr client, DeviceIntPtr dev, CARD8 *modmap) { XkbApplyMappingChange(dev, NULL, 0, 0, modmap, serverClient); } /* Rebuild modmap (key -> mod) from map (mod -> key). */ static int build_modmap_from_modkeymap(CARD8 *modmap, KeyCode *modkeymap, int max_keys_per_mod) { int i, len = max_keys_per_mod * 8; memset(modmap, 0, MAP_LENGTH); for (i = 0; i < len; i++) { if (!modkeymap[i]) continue; #if MAP_LENGTH < 256 if (modkeymap[i] >= MAP_LENGTH) return BadValue; #endif if (modmap[modkeymap[i]]) return BadValue; modmap[modkeymap[i]] = 1 << (i / max_keys_per_mod); } return Success; } int change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap, int max_keys_per_mod) { int ret; CARD8 modmap[MAP_LENGTH]; DeviceIntPtr tmp; ret = build_modmap_from_modkeymap(modmap, modkeymap, max_keys_per_mod); if (ret != Success) return ret; /* If we can't perform the change on the requested device, bail out. */ ret = check_modmap_change(client, dev, modmap); if (ret != Success) return ret; do_modmap_change(client, dev, modmap); /* Change any attached masters/slaves. */ if (IsMaster(dev)) { for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { if (!IsMaster(tmp) && GetMaster(tmp, MASTER_KEYBOARD) == dev) if (check_modmap_change_slave(client, dev, tmp, modmap)) do_modmap_change(client, tmp, modmap); } } else if (!IsFloating(dev) && GetMaster(dev, MASTER_KEYBOARD)->lastSlave == dev) { /* If this fails, expect the results to be weird. */ if (check_modmap_change(client, dev->master, modmap) == Success) do_modmap_change(client, dev->master, modmap); } return Success; } int generate_modkeymap(ClientPtr client, DeviceIntPtr dev, KeyCode **modkeymap_out, int *max_keys_per_mod_out) { CARD8 keys_per_mod[8]; int max_keys_per_mod; KeyCode *modkeymap = NULL; int i, j, ret; ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess); if (ret != Success) return ret; if (!dev->key) return BadMatch; /* Count the number of keys per modifier to determine how wide we * should make the map. */ max_keys_per_mod = 0; for (i = 0; i < 8; i++) keys_per_mod[i] = 0; for (i = 8; i < MAP_LENGTH; i++) { for (j = 0; j < 8; j++) { if (dev->key->xkbInfo->desc->map->modmap[i] & (1 << j)) { if (++keys_per_mod[j] > max_keys_per_mod) max_keys_per_mod = keys_per_mod[j]; } } } if (max_keys_per_mod != 0) { modkeymap = calloc(max_keys_per_mod * 8, sizeof(KeyCode)); if (!modkeymap) return BadAlloc; for (i = 0; i < 8; i++) keys_per_mod[i] = 0; for (i = 8; i < MAP_LENGTH; i++) { for (j = 0; j < 8; j++) { if (dev->key->xkbInfo->desc->map->modmap[i] & (1 << j)) { modkeymap[(j * max_keys_per_mod) + keys_per_mod[j]] = i; keys_per_mod[j]++; } } } } *max_keys_per_mod_out = max_keys_per_mod; *modkeymap_out = modkeymap; return Success; } /** * Duplicate the InputAttributes in the most obvious way. * No special memory handling is used to give drivers the maximum * flexibility with the data. Drivers should be able to call realloc on the * product string if needed and perform similar operations. */ InputAttributes * DuplicateInputAttributes(InputAttributes * attrs) { InputAttributes *new_attr; int ntags = 0; char **tags, **new_tags; if (!attrs) return NULL; if (!(new_attr = calloc(1, sizeof(InputAttributes)))) goto unwind; if (attrs->product && !(new_attr->product = strdup(attrs->product))) goto unwind; if (attrs->vendor && !(new_attr->vendor = strdup(attrs->vendor))) goto unwind; if (attrs->device && !(new_attr->device = strdup(attrs->device))) goto unwind; if (attrs->pnp_id && !(new_attr->pnp_id = strdup(attrs->pnp_id))) goto unwind; if (attrs->usb_id && !(new_attr->usb_id = strdup(attrs->usb_id))) goto unwind; new_attr->flags = attrs->flags; if ((tags = attrs->tags)) { while (*tags++) ntags++; new_attr->tags = calloc(ntags + 1, sizeof(char *)); if (!new_attr->tags) goto unwind; tags = attrs->tags; new_tags = new_attr->tags; while (*tags) { *new_tags = strdup(*tags); if (!*new_tags) goto unwind; tags++; new_tags++; } } return new_attr; unwind: FreeInputAttributes(new_attr); return NULL; } void FreeInputAttributes(InputAttributes * attrs) { char **tags; if (!attrs) return; free(attrs->product); free(attrs->vendor); free(attrs->device); free(attrs->pnp_id); free(attrs->usb_id); if ((tags = attrs->tags)) while (*tags) free(*tags++); free(attrs->tags); free(attrs); } /** * Alloc a valuator mask large enough for num_valuators. */ ValuatorMask * valuator_mask_new(int num_valuators) { /* alloc a fixed size mask for now and ignore num_valuators. in the * flying-car future, when we can dynamically alloc the masks and are * not constrained by signals, we can start using num_valuators */ ValuatorMask *mask = calloc(1, sizeof(ValuatorMask)); if (mask == NULL) return NULL; mask->last_bit = -1; return mask; } void valuator_mask_free(ValuatorMask **mask) { free(*mask); *mask = NULL; } /** * Sets a range of valuators between first_valuator and num_valuators with * the data in the valuators array. All other values are set to 0. */ void valuator_mask_set_range(ValuatorMask *mask, int first_valuator, int num_valuators, const int *valuators) { int i; valuator_mask_zero(mask); for (i = first_valuator; i < min(first_valuator + num_valuators, MAX_VALUATORS); i++) valuator_mask_set(mask, i, valuators[i - first_valuator]); } /** * Reset mask to zero. */ void valuator_mask_zero(ValuatorMask *mask) { memset(mask, 0, sizeof(*mask)); mask->last_bit = -1; } /** * Returns the current size of the mask (i.e. the highest number of * valuators currently set + 1). */ int valuator_mask_size(const ValuatorMask *mask) { return mask->last_bit + 1; } /** * Returns the number of valuators set in the given mask. */ int valuator_mask_num_valuators(const ValuatorMask *mask) { return CountBits(mask->mask, min(mask->last_bit + 1, MAX_VALUATORS)); } /** * Return true if the valuator is set in the mask, or false otherwise. */ int valuator_mask_isset(const ValuatorMask *mask, int valuator) { return mask->last_bit >= valuator && BitIsOn(mask->mask, valuator); } static inline void _valuator_mask_set_double(ValuatorMask *mask, int valuator, double data) { mask->last_bit = max(valuator, mask->last_bit); SetBit(mask->mask, valuator); mask->valuators[valuator] = data; } /** * Set the valuator to the given floating-point data. */ void valuator_mask_set_double(ValuatorMask *mask, int valuator, double data) { BUG_WARN_MSG(mask->has_unaccelerated, "Do not mix valuator types, zero mask first\n"); _valuator_mask_set_double(mask, valuator, data); } /** * Set the valuator to the given integer data. */ void valuator_mask_set(ValuatorMask *mask, int valuator, int data) { valuator_mask_set_double(mask, valuator, data); } /** * Return the requested valuator value as a double. If the mask bit is not * set for the given valuator, the returned value is undefined. */ double valuator_mask_get_double(const ValuatorMask *mask, int valuator) { return mask->valuators[valuator]; } /** * Return the requested valuator value as an integer, rounding towards zero. * If the mask bit is not set for the given valuator, the returned value is * undefined. */ int valuator_mask_get(const ValuatorMask *mask, int valuator) { return trunc(valuator_mask_get_double(mask, valuator)); } /** * Set value to the requested valuator. If the mask bit is set for this * valuator, value contains the requested valuator value and TRUE is * returned. * If the mask bit is not set for this valuator, value is unchanged and * FALSE is returned. */ Bool valuator_mask_fetch_double(const ValuatorMask *mask, int valuator, double *value) { if (valuator_mask_isset(mask, valuator)) { *value = valuator_mask_get_double(mask, valuator); return TRUE; } else return FALSE; } /** * Set value to the requested valuator. If the mask bit is set for this * valuator, value contains the requested valuator value and TRUE is * returned. * If the mask bit is not set for this valuator, value is unchanged and * FALSE is returned. */ Bool valuator_mask_fetch(const ValuatorMask *mask, int valuator, int *value) { if (valuator_mask_isset(mask, valuator)) { *value = valuator_mask_get(mask, valuator); return TRUE; } else return FALSE; } /** * Remove the valuator from the mask. */ void valuator_mask_unset(ValuatorMask *mask, int valuator) { if (mask->last_bit >= valuator) { int i, lastbit = -1; ClearBit(mask->mask, valuator); mask->valuators[valuator] = 0.0; mask->unaccelerated[valuator] = 0.0; for (i = 0; i <= mask->last_bit; i++) if (valuator_mask_isset(mask, i)) lastbit = max(lastbit, i); mask->last_bit = lastbit; if (mask->last_bit == -1) mask->has_unaccelerated = FALSE; } } void valuator_mask_copy(ValuatorMask *dest, const ValuatorMask *src) { if (src) memcpy(dest, src, sizeof(*dest)); else valuator_mask_zero(dest); } Bool valuator_mask_has_unaccelerated(const ValuatorMask *mask) { return mask->has_unaccelerated; } void valuator_mask_drop_unaccelerated(ValuatorMask *mask) { memset(mask->unaccelerated, 0, sizeof(mask->unaccelerated)); mask->has_unaccelerated = FALSE; } void valuator_mask_set_absolute_unaccelerated(ValuatorMask *mask, int valuator, int absolute, double unaccel) { BUG_WARN_MSG(mask->last_bit != -1 && !mask->has_unaccelerated, "Do not mix valuator types, zero mask first\n"); _valuator_mask_set_double(mask, valuator, absolute); mask->has_unaccelerated = TRUE; mask->unaccelerated[valuator] = unaccel; } /** * Set both accelerated and unaccelerated value for this mask. */ void valuator_mask_set_unaccelerated(ValuatorMask *mask, int valuator, double accel, double unaccel) { BUG_WARN_MSG(mask->last_bit != -1 && !mask->has_unaccelerated, "Do not mix valuator types, zero mask first\n"); _valuator_mask_set_double(mask, valuator, accel); mask->has_unaccelerated = TRUE; mask->unaccelerated[valuator] = unaccel; } double valuator_mask_get_accelerated(const ValuatorMask *mask, int valuator) { return valuator_mask_get_double(mask, valuator); } double valuator_mask_get_unaccelerated(const ValuatorMask *mask, int valuator) { return mask->unaccelerated[valuator]; } Bool valuator_mask_fetch_unaccelerated(const ValuatorMask *mask, int valuator, double *accel, double *unaccel) { if (valuator_mask_isset(mask, valuator)) { if (accel) *accel = valuator_mask_get_accelerated(mask, valuator); if (unaccel) *unaccel = valuator_mask_get_unaccelerated(mask, valuator); return TRUE; } else return FALSE; } int CountBits(const uint8_t * mask, int len) { int i; int ret = 0; for (i = 0; i < len; i++) if (BitIsOn(mask, i)) ret++; return ret; } /** * Verifies sanity of the event. If the event is not an internal event, * memdumps the first 32 bytes of event to the log, a backtrace, then kill * the server. */ void verify_internal_event(const InternalEvent *ev) { if (ev && ev->any.header != ET_Internal) { int i; const unsigned char *data = (const unsigned char *) ev; ErrorF("dix: invalid event type %d\n", ev->any.header); for (i = 0; i < sizeof(xEvent); i++, data++) { ErrorF("%02hhx ", *data); if ((i % 8) == 7) ErrorF("\n"); } xorg_backtrace(); FatalError("Wrong event type %d. Aborting server\n", ev->any.header); } } /** * Initializes the given event to zero (or default values), for the given * device. */ void init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms, enum DeviceEventSource source_type) { memset(event, 0, sizeof(DeviceEvent)); event->header = ET_Internal; event->length = sizeof(DeviceEvent); event->time = ms; event->deviceid = dev->id; event->sourceid = dev->id; event->source_type = source_type; } int event_get_corestate(DeviceIntPtr mouse, DeviceIntPtr kbd) { int corestate; /* core state needs to be assembled BEFORE the device is updated. */ corestate = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo-> state) : 0; corestate |= (mouse && mouse->button) ? (mouse->button->state) : 0; corestate |= (mouse && mouse->touch) ? (mouse->touch->state) : 0; return corestate; } void event_set_state(DeviceIntPtr mouse, DeviceIntPtr kbd, DeviceEvent *event) { int i; for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) if (BitIsOn(mouse->button->down, i)) SetBit(event->buttons, mouse->button->map[i]); if (mouse && mouse->touch && mouse->touch->buttonsDown > 0) SetBit(event->buttons, mouse->button->map[1]); if (kbd && kbd->key) { XkbStatePtr state; /* we need the state before the event happens */ if (event->type == ET_KeyPress || event->type == ET_KeyRelease) state = &kbd->key->xkbInfo->prev_state; else state = &kbd->key->xkbInfo->state; event->mods.base = state->base_mods; event->mods.latched = state->latched_mods; event->mods.locked = state->locked_mods; event->mods.effective = state->mods; event->group.base = state->base_group; event->group.latched = state->latched_group; event->group.locked = state->locked_group; event->group.effective = state->group; } } /** * Return the event filter mask for the given device and the given core or * XI1 protocol type. */ Mask event_get_filter_from_type(DeviceIntPtr dev, int evtype) { return event_filters[dev ? dev->id : 0][evtype]; } /** * Return the event filter mask for the given device and the given core or * XI2 protocol type. */ Mask event_get_filter_from_xi2type(int evtype) { return (1 << (evtype % 8)); } Bool point_on_screen(ScreenPtr pScreen, int x, int y) { return x >= pScreen->x && x < pScreen->x + pScreen->width && y >= pScreen->y && y < pScreen->y + pScreen->height; } /** * Update desktop dimensions on the screenInfo struct. */ void update_desktop_dimensions(void) { int i; int x1 = INT_MAX, y1 = INT_MAX; /* top-left */ int x2 = INT_MIN, y2 = INT_MIN; /* bottom-right */ for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr screen = screenInfo.screens[i]; x1 = min(x1, screen->x); y1 = min(y1, screen->y); x2 = max(x2, screen->x + screen->width); y2 = max(y2, screen->y + screen->height); } screenInfo.x = x1; screenInfo.y = y1; screenInfo.width = x2 - x1; screenInfo.height = y2 - y1; } /* * Delete the element with the key from the list, freeing all memory * associated with the element.. */ static void input_option_free(InputOption *o) { free(o->opt_name); free(o->opt_val); free(o->opt_comment); free(o); } /* * Create a new InputOption with the key/value pair provided. * If a list is provided, the new options is added to the list and the list * is returned. * * If a new option is added to a list that already contains that option, the * previous option is overwritten. * * @param list The list to add to. * @param key Option key, will be copied. * @param value Option value, will be copied. * * @return If list is not NULL, the list with the new option added. If list * is NULL, a new option list with one element. On failure, NULL is * returned. */ InputOption * input_option_new(InputOption *list, const char *key, const char *value) { InputOption *opt = NULL; if (!key) return NULL; if (list) { nt_list_for_each_entry(opt, list, list.next) { if (strcmp(input_option_get_key(opt), key) == 0) { input_option_set_value(opt, value); return list; } } } opt = calloc(1, sizeof(InputOption)); if (!opt) return NULL; nt_list_init(opt, list.next); input_option_set_key(opt, key); input_option_set_value(opt, value); if (list) { nt_list_append(opt, list, InputOption, list.next); return list; } else return opt; } InputOption * input_option_free_element(InputOption *list, const char *key) { InputOption *element; nt_list_for_each_entry(element, list, list.next) { if (strcmp(input_option_get_key(element), key) == 0) { nt_list_del(element, list, InputOption, list.next); input_option_free(element); break; } } return list; } /** * Free the list pointed at by opt. */ void input_option_free_list(InputOption **opt) { InputOption *element, *tmp; nt_list_for_each_entry_safe(element, tmp, *opt, list.next) { nt_list_del(element, *opt, InputOption, list.next); input_option_free(element); } *opt = NULL; } /** * Find the InputOption with the given option name. * * @return The InputOption or NULL if not present. */ InputOption * input_option_find(InputOption *list, const char *key) { InputOption *element; nt_list_for_each_entry(element, list, list.next) { if (strcmp(input_option_get_key(element), key) == 0) return element; } return NULL; } const char * input_option_get_key(const InputOption *opt) { return opt->opt_name; } const char * input_option_get_value(const InputOption *opt) { return opt->opt_val; } void input_option_set_key(InputOption *opt, const char *key) { free(opt->opt_name); if (key) opt->opt_name = strdup(key); } void input_option_set_value(InputOption *opt, const char *value) { free(opt->opt_val); if (value) opt->opt_val = strdup(value); } /* FP1616/FP3232 conversion functions. * Fixed point types are encoded as signed integral and unsigned frac. So any * negative number -n.m is encoded as floor(n) + (1 - 0.m). */ double fp1616_to_double(FP1616 in) { return pixman_fixed_to_double(in); } double fp3232_to_double(FP3232 in) { double ret; ret = (double) in.integral; ret += (double) in.frac * (1.0 / (1ULL << 32)); /* Optimized: ldexp((double)in.frac, -32); */ return ret; } FP1616 double_to_fp1616(double in) { return pixman_double_to_fixed(in); } FP3232 double_to_fp3232(double in) { FP3232 ret; int32_t integral; double tmp; uint32_t frac_d; tmp = floor(in); integral = (int32_t) tmp; tmp = (in - integral) * (1ULL << 32); /* Optimized: ldexp(in - integral, 32) */ frac_d = (uint32_t) tmp; ret.integral = integral; ret.frac = frac_d; return ret; } /** * DO NOT USE THIS FUNCTION. It only exists for the test cases. Use * xi2mask_new() instead to get the standard sized masks. * * @param nmasks The number of masks (== number of devices) * @param size The size of the masks in bytes * @return The new mask or NULL on allocation error. */ XI2Mask * xi2mask_new_with_size(size_t nmasks, size_t size) { int i; int alloc_size; unsigned char *cursor; XI2Mask *mask; alloc_size = sizeof(struct _XI2Mask) + nmasks * sizeof(unsigned char *) + nmasks * size; mask = calloc(1, alloc_size); if (!mask) return NULL; mask->nmasks = nmasks; mask->mask_size = size; mask->masks = (unsigned char **)(mask + 1); cursor = (unsigned char *)(mask + 1) + nmasks * sizeof(unsigned char *); for (i = 0; i < nmasks; i++) { mask->masks[i] = cursor; cursor += size; } return mask; } /** * Create a new XI2 mask of the standard size, i.e. for all devices + fake * devices and for the highest supported XI2 event type. * * @return The new mask or NULL on allocation error. */ XI2Mask * xi2mask_new(void) { return xi2mask_new_with_size(EMASKSIZE, XI2MASKSIZE); } /** * Frees memory associated with mask and resets mask to NULL. */ void xi2mask_free(XI2Mask **mask) { if (!(*mask)) return; free((*mask)); *mask = NULL; } /** * Test if the bit for event type is set for this device only. * * @return TRUE if the bit is set, FALSE otherwise */ Bool xi2mask_isset_for_device(XI2Mask *mask, const DeviceIntPtr dev, int event_type) { BUG_WARN(dev->id < 0); BUG_WARN(dev->id >= mask->nmasks); BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size); return BitIsOn(mask->masks[dev->id], event_type); } /** * Test if the bit for event type is set for this device, or the * XIAllDevices/XIAllMasterDevices (if applicable) is set. * * @return TRUE if the bit is set, FALSE otherwise */ Bool xi2mask_isset(XI2Mask *mask, const DeviceIntPtr dev, int event_type) { int set = 0; if (xi2mask_isset_for_device(mask, inputInfo.all_devices, event_type)) set = 1; else if (xi2mask_isset_for_device(mask, dev, event_type)) set = 1; else if (IsMaster(dev) && xi2mask_isset_for_device(mask, inputInfo.all_master_devices, event_type)) set = 1; return set; } /** * Set the mask bit for this event type for this device. */ void xi2mask_set(XI2Mask *mask, int deviceid, int event_type) { BUG_WARN(deviceid < 0); BUG_WARN(deviceid >= mask->nmasks); BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size); SetBit(mask->masks[deviceid], event_type); } /** * Zero out the xi2mask, for the deviceid given. If the deviceid is < 0, all * masks are zeroed. */ void xi2mask_zero(XI2Mask *mask, int deviceid) { int i; BUG_WARN(deviceid > 0 && deviceid >= mask->nmasks); if (deviceid >= 0) memset(mask->masks[deviceid], 0, mask->mask_size); else for (i = 0; i < mask->nmasks; i++) memset(mask->masks[i], 0, mask->mask_size); } /** * Merge source into dest, i.e. dest |= source. * If the masks are of different size, only the overlapping section is merged. */ void xi2mask_merge(XI2Mask *dest, const XI2Mask *source) { int i, j; for (i = 0; i < min(dest->nmasks, source->nmasks); i++) for (j = 0; j < min(dest->mask_size, source->mask_size); j++) dest->masks[i][j] |= source->masks[i][j]; } /** * @return The number of masks in mask */ size_t xi2mask_num_masks(const XI2Mask *mask) { return mask->nmasks; } /** * @return The size of each mask in bytes */ size_t xi2mask_mask_size(const XI2Mask *mask) { return mask->mask_size; } /** * Set the mask for the given deviceid to the source mask. * If the mask given is larger than the target memory, only the overlapping * parts are copied. */ void xi2mask_set_one_mask(XI2Mask *xi2mask, int deviceid, const unsigned char *mask, size_t mask_size) { BUG_WARN(deviceid < 0); BUG_WARN(deviceid >= xi2mask->nmasks); memcpy(xi2mask->masks[deviceid], mask, min(xi2mask->mask_size, mask_size)); } /** * Get a reference to the XI2mask for this particular device. */ const unsigned char * xi2mask_get_one_mask(const XI2Mask *mask, int deviceid) { BUG_WARN(deviceid < 0); BUG_WARN(deviceid >= mask->nmasks); return mask->masks[deviceid]; } xorg-server-1.20.13/dix/pixmap.c0000644000175000017500000002745614100573756013336 00000000000000/* Copyright 1993, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "scrnintstr.h" #include "mi.h" #include "misc.h" #include "os.h" #include "windowstr.h" #include "resource.h" #include "dixstruct.h" #include "gcstruct.h" #include "servermd.h" #include "site.h" #include "X11/extensions/render.h" #include "picturestr.h" #include "randrstr.h" /* * Scratch pixmap management and device independent pixmap allocation * function. */ /* callable by ddx */ PixmapPtr GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth, int bitsPerPixel, int devKind, void *pPixData) { PixmapPtr pPixmap = pScreen->pScratchPixmap; if (pPixmap) pScreen->pScratchPixmap = NULL; else /* width and height of 0 means don't allocate any pixmap data */ pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, 0); if (pPixmap) { if ((*pScreen->ModifyPixmapHeader) (pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData)) return pPixmap; (*pScreen->DestroyPixmap) (pPixmap); } return NullPixmap; } /* callable by ddx */ void FreeScratchPixmapHeader(PixmapPtr pPixmap) { if (pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; pPixmap->devPrivate.ptr = NULL; /* lest ddx chases bad ptr */ if (pScreen->pScratchPixmap) (*pScreen->DestroyPixmap) (pPixmap); else pScreen->pScratchPixmap = pPixmap; } } Bool CreateScratchPixmapsForScreen(ScreenPtr pScreen) { unsigned int pixmap_size; pixmap_size = sizeof(PixmapRec) + dixScreenSpecificPrivatesSize(pScreen, PRIVATE_PIXMAP); pScreen->totalPixmapSize = BitmapBytePad(pixmap_size * 8); /* let it be created on first use */ pScreen->pScratchPixmap = NULL; return TRUE; } void FreeScratchPixmapsForScreen(ScreenPtr pScreen) { FreeScratchPixmapHeader(pScreen->pScratchPixmap); } /* callable by ddx */ PixmapPtr AllocatePixmap(ScreenPtr pScreen, int pixDataSize) { PixmapPtr pPixmap; assert(pScreen->totalPixmapSize > 0); if (pScreen->totalPixmapSize > ((size_t) - 1) - pixDataSize) return NullPixmap; pPixmap = calloc(1, pScreen->totalPixmapSize + pixDataSize); if (!pPixmap) return NullPixmap; dixInitScreenPrivates(pScreen, pPixmap, pPixmap + 1, PRIVATE_PIXMAP); return pPixmap; } /* callable by ddx */ void FreePixmap(PixmapPtr pPixmap) { dixFiniPrivates(pPixmap, PRIVATE_PIXMAP); free(pPixmap); } void PixmapUnshareSlavePixmap(PixmapPtr slave_pixmap) { int ihandle = -1; ScreenPtr pScreen = slave_pixmap->drawable.pScreen; pScreen->SetSharedPixmapBacking(slave_pixmap, ((void *)(long)ihandle)); } PixmapPtr PixmapShareToSlave(PixmapPtr pixmap, ScreenPtr slave) { PixmapPtr spix; int ret; void *handle; ScreenPtr master = pixmap->drawable.pScreen; int depth = pixmap->drawable.depth; ret = master->SharePixmapBacking(pixmap, slave, &handle); if (ret == FALSE) return NULL; spix = slave->CreatePixmap(slave, 0, 0, depth, CREATE_PIXMAP_USAGE_SHARED); slave->ModifyPixmapHeader(spix, pixmap->drawable.width, pixmap->drawable.height, depth, 0, pixmap->devKind, NULL); /* have the slave pixmap take a reference on the master pixmap later we destroy them both at the same time */ pixmap->refcnt++; spix->master_pixmap = pixmap; ret = slave->SetSharedPixmapBacking(spix, handle); if (ret == FALSE) { slave->DestroyPixmap(spix); return NULL; } return spix; } static void PixmapDirtyDamageDestroy(DamagePtr damage, void *closure) { PixmapDirtyUpdatePtr dirty = closure; dirty->damage = NULL; } Bool PixmapStartDirtyTracking(DrawablePtr src, PixmapPtr slave_dst, int x, int y, int dst_x, int dst_y, Rotation rotation) { ScreenPtr screen = src->pScreen; PixmapDirtyUpdatePtr dirty_update; RegionPtr damageregion; RegionRec dstregion; BoxRec box; dirty_update = calloc(1, sizeof(PixmapDirtyUpdateRec)); if (!dirty_update) return FALSE; dirty_update->src = src; dirty_update->slave_dst = slave_dst; dirty_update->x = x; dirty_update->y = y; dirty_update->dst_x = dst_x; dirty_update->dst_y = dst_y; dirty_update->rotation = rotation; dirty_update->damage = DamageCreate(NULL, PixmapDirtyDamageDestroy, DamageReportNone, TRUE, screen, dirty_update); if (rotation != RR_Rotate_0) { RRTransformCompute(x, y, slave_dst->drawable.width, slave_dst->drawable.height, rotation, NULL, &dirty_update->transform, &dirty_update->f_transform, &dirty_update->f_inverse); } if (!dirty_update->damage) { free(dirty_update); return FALSE; } /* Damage destination rectangle so that the destination pixmap contents * will get fully initialized */ box.x1 = dirty_update->x; box.y1 = dirty_update->y; if (dirty_update->rotation == RR_Rotate_90 || dirty_update->rotation == RR_Rotate_270) { box.x2 = dirty_update->x + slave_dst->drawable.height; box.y2 = dirty_update->y + slave_dst->drawable.width; } else { box.x2 = dirty_update->x + slave_dst->drawable.width; box.y2 = dirty_update->y + slave_dst->drawable.height; } RegionInit(&dstregion, &box, 1); damageregion = DamageRegion(dirty_update->damage); RegionUnion(damageregion, damageregion, &dstregion); RegionUninit(&dstregion); DamageRegister(src, dirty_update->damage); xorg_list_add(&dirty_update->ent, &screen->pixmap_dirty_list); return TRUE; } Bool PixmapStopDirtyTracking(DrawablePtr src, PixmapPtr slave_dst) { ScreenPtr screen = src->pScreen; PixmapDirtyUpdatePtr ent, safe; xorg_list_for_each_entry_safe(ent, safe, &screen->pixmap_dirty_list, ent) { if (ent->src == src && ent->slave_dst == slave_dst) { if (ent->damage) DamageDestroy(ent->damage); xorg_list_del(&ent->ent); free(ent); } } return TRUE; } static void PixmapDirtyCopyArea(PixmapPtr dst, PixmapDirtyUpdatePtr dirty, RegionPtr dirty_region) { DrawablePtr src = dirty->src; ScreenPtr pScreen = src->pScreen; int n; BoxPtr b; GCPtr pGC; n = RegionNumRects(dirty_region); b = RegionRects(dirty_region); pGC = GetScratchGC(src->depth, pScreen); if (pScreen->root) { ChangeGCVal subWindowMode; subWindowMode.val = IncludeInferiors; ChangeGC(NullClient, pGC, GCSubwindowMode, &subWindowMode); } ValidateGC(&dst->drawable, pGC); while (n--) { BoxRec dst_box; int w, h; dst_box = *b; w = dst_box.x2 - dst_box.x1; h = dst_box.y2 - dst_box.y1; pGC->ops->CopyArea(src, &dst->drawable, pGC, dirty->x + dst_box.x1, dirty->y + dst_box.y1, w, h, dirty->dst_x + dst_box.x1, dirty->dst_y + dst_box.y1); b++; } FreeScratchGC(pGC); } static void PixmapDirtyCompositeRotate(PixmapPtr dst_pixmap, PixmapDirtyUpdatePtr dirty, RegionPtr dirty_region) { ScreenPtr pScreen = dirty->src->pScreen; PictFormatPtr format = PictureWindowFormat(pScreen->root); PicturePtr src, dst; XID include_inferiors = IncludeInferiors; int n = RegionNumRects(dirty_region); BoxPtr b = RegionRects(dirty_region); int error; src = CreatePicture(None, dirty->src, format, CPSubwindowMode, &include_inferiors, serverClient, &error); if (!src) return; dst = CreatePicture(None, &dst_pixmap->drawable, format, 0L, NULL, serverClient, &error); if (!dst) return; error = SetPictureTransform(src, &dirty->transform); if (error) return; while (n--) { BoxRec dst_box; dst_box = *b; dst_box.x1 += dirty->x; dst_box.x2 += dirty->x; dst_box.y1 += dirty->y; dst_box.y2 += dirty->y; pixman_f_transform_bounds(&dirty->f_inverse, &dst_box); CompositePicture(PictOpSrc, src, NULL, dst, dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1, dst_box.x2 - dst_box.x1, dst_box.y2 - dst_box.y1); b++; } FreePicture(src, None); FreePicture(dst, None); } /* * this function can possibly be improved and optimised, by clipping * instead of iterating * Drivers are free to implement their own version of this. */ Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty) { ScreenPtr pScreen = dirty->src->pScreen; RegionPtr region = DamageRegion(dirty->damage); PixmapPtr dst; SourceValidateProcPtr SourceValidate; RegionRec pixregion; BoxRec box; dst = dirty->slave_dst->master_pixmap; if (!dst) dst = dirty->slave_dst; box.x1 = 0; box.y1 = 0; if (dirty->rotation == RR_Rotate_90 || dirty->rotation == RR_Rotate_270) { box.x2 = dst->drawable.height; box.y2 = dst->drawable.width; } else { box.x2 = dst->drawable.width; box.y2 = dst->drawable.height; } RegionInit(&pixregion, &box, 1); /* * SourceValidate is used by the software cursor code * to pull the cursor off of the screen when reading * bits from the frame buffer. Bypassing this function * leaves the software cursor in place */ SourceValidate = pScreen->SourceValidate; pScreen->SourceValidate = miSourceValidate; RegionTranslate(&pixregion, dirty->x, dirty->y); RegionIntersect(&pixregion, &pixregion, region); if (RegionNil(&pixregion)) { RegionUninit(&pixregion); return FALSE; } RegionTranslate(&pixregion, -dirty->x, -dirty->y); if (!pScreen->root || dirty->rotation == RR_Rotate_0) PixmapDirtyCopyArea(dst, dirty, &pixregion); else PixmapDirtyCompositeRotate(dst, dirty, &pixregion); pScreen->SourceValidate = SourceValidate; return TRUE; } xorg-server-1.20.13/dix/privates.c0000644000175000017500000005452214100573756013667 00000000000000/* Copyright 1993, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ /* * Copyright © 2010, Keith Packard * Copyright © 2010, Jamey Sharp * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "windowstr.h" #include "resource.h" #include "privates.h" #include "gcstruct.h" #include "cursorstr.h" #include "colormapst.h" #include "inputstr.h" #include "scrnintstr.h" #include "extnsionst.h" #include "inputstr.h" static DevPrivateSetRec global_keys[PRIVATE_LAST]; static const Bool xselinux_private[PRIVATE_LAST] = { [PRIVATE_SCREEN] = TRUE, [PRIVATE_CLIENT] = TRUE, [PRIVATE_WINDOW] = TRUE, [PRIVATE_PIXMAP] = TRUE, [PRIVATE_GC] = TRUE, [PRIVATE_CURSOR] = TRUE, [PRIVATE_COLORMAP] = TRUE, [PRIVATE_DEVICE] = TRUE, [PRIVATE_EXTENSION] = TRUE, [PRIVATE_SELECTION] = TRUE, [PRIVATE_PROPERTY] = TRUE, [PRIVATE_PICTURE] = TRUE, [PRIVATE_GLYPHSET] = TRUE, }; static const char *key_names[PRIVATE_LAST] = { /* XSELinux uses the same private keys for numerous objects */ [PRIVATE_XSELINUX] = "XSELINUX", /* Otherwise, you get a private in just the requested structure */ /* These can have objects created before all of the keys are registered */ [PRIVATE_SCREEN] = "SCREEN", [PRIVATE_EXTENSION] = "EXTENSION", [PRIVATE_COLORMAP] = "COLORMAP", [PRIVATE_DEVICE] = "DEVICE", /* These cannot have any objects before all relevant keys are registered */ [PRIVATE_CLIENT] = "CLIENT", [PRIVATE_PROPERTY] = "PROPERTY", [PRIVATE_SELECTION] = "SELECTION", [PRIVATE_WINDOW] = "WINDOW", [PRIVATE_PIXMAP] = "PIXMAP", [PRIVATE_GC] = "GC", [PRIVATE_CURSOR] = "CURSOR", [PRIVATE_CURSOR_BITS] = "CURSOR_BITS", /* extension privates */ [PRIVATE_GLYPH] = "GLYPH", [PRIVATE_GLYPHSET] = "GLYPHSET", [PRIVATE_PICTURE] = "PICTURE", [PRIVATE_SYNC_FENCE] = "SYNC_FENCE", }; static const Bool screen_specific_private[PRIVATE_LAST] = { [PRIVATE_SCREEN] = FALSE, [PRIVATE_CLIENT] = FALSE, [PRIVATE_WINDOW] = TRUE, [PRIVATE_PIXMAP] = TRUE, [PRIVATE_GC] = TRUE, [PRIVATE_CURSOR] = FALSE, [PRIVATE_COLORMAP] = FALSE, [PRIVATE_DEVICE] = FALSE, [PRIVATE_EXTENSION] = FALSE, [PRIVATE_SELECTION] = FALSE, [PRIVATE_PROPERTY] = FALSE, [PRIVATE_PICTURE] = TRUE, [PRIVATE_GLYPHSET] = FALSE, }; typedef Bool (*FixupFunc) (PrivatePtr *privates, int offset, unsigned bytes); typedef enum { FixupMove, FixupRealloc } FixupType; static Bool dixReallocPrivates(PrivatePtr *privates, int old_offset, unsigned bytes) { void *new_privates; new_privates = realloc(*privates, old_offset + bytes); if (!new_privates) return FALSE; memset((char *) new_privates + old_offset, '\0', bytes); *privates = new_privates; return TRUE; } static Bool dixMovePrivates(PrivatePtr *privates, int new_offset, unsigned bytes) { memmove((char *) *privates + bytes, *privates, new_offset - bytes); memset(*privates, '\0', bytes); return TRUE; } static Bool fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes) { intptr_t dist; char *old; char *new; DevPrivateKey *keyp, key; DevPrivateType type; int size; old = (char *) pScreen->devPrivates; size = global_keys[PRIVATE_SCREEN].offset; if (!fixup (&pScreen->devPrivates, size, bytes)) return FALSE; /* Screen privates can contain screen-specific private keys * for other types. When they move, the linked list we use to * track them gets scrambled. Fix that by computing the change * in the location of each private adjusting our linked list * pointers to match */ new = (char *) pScreen->devPrivates; /* Moving means everyone shifts up in the privates by 'bytes' amount, * realloc means the base pointer moves */ if (fixup == dixMovePrivates) new += bytes; dist = new - old; if (dist) { for (type = PRIVATE_XSELINUX; type < PRIVATE_LAST; type++) /* Walk the privates list, being careful as the * pointers are scrambled before we patch them. */ for (keyp = &pScreen->screenSpecificPrivates[type].key; (key = *keyp) != NULL; keyp = &key->next) { /* Only mangle things if the private structure * is contained within the allocation. Privates * stored elsewhere will be left alone */ if (old <= (char *) key && (char *) key < old + size) { /* Compute new location of key */ key = (DevPrivateKey) ((char *) key + dist); /* Patch the list */ *keyp = key; } } } return TRUE; } static Bool fixupScreens(FixupFunc fixup, unsigned bytes) { int s; for (s = 0; s < screenInfo.numScreens; s++) if (!fixupOneScreen (screenInfo.screens[s], fixup, bytes)) return FALSE; for (s = 0; s < screenInfo.numGPUScreens; s++) if (!fixupOneScreen (screenInfo.gpuscreens[s], fixup, bytes)) return FALSE; return TRUE; } static Bool fixupServerClient(FixupFunc fixup, unsigned bytes) { if (serverClient) return fixup(&serverClient->devPrivates, global_keys[PRIVATE_CLIENT].offset, bytes); return TRUE; } static Bool fixupExtensions(FixupFunc fixup, unsigned bytes) { unsigned char major; ExtensionEntry *extension; for (major = EXTENSION_BASE; (extension = GetExtensionEntry(major)); major++) if (!fixup (&extension->devPrivates, global_keys[PRIVATE_EXTENSION].offset, bytes)) return FALSE; return TRUE; } static Bool fixupDefaultColormaps(FixupFunc fixup, unsigned bytes) { int s; for (s = 0; s < screenInfo.numScreens; s++) { ColormapPtr cmap; dixLookupResourceByType((void **) &cmap, screenInfo.screens[s]->defColormap, RT_COLORMAP, serverClient, DixCreateAccess); if (cmap && !fixup(&cmap->devPrivates, screenInfo.screens[s]->screenSpecificPrivates[PRIVATE_COLORMAP].offset, bytes)) return FALSE; } return TRUE; } static Bool fixupDeviceList(DeviceIntPtr device, FixupFunc fixup, unsigned bytes) { while (device) { if (!fixup(&device->devPrivates, global_keys[PRIVATE_DEVICE].offset, bytes)) return FALSE; device = device->next; } return TRUE; } static Bool fixupDevices(FixupFunc fixup, unsigned bytes) { return (fixupDeviceList(inputInfo.devices, fixup, bytes) && fixupDeviceList(inputInfo.off_devices, fixup, bytes)); } static Bool (*const allocated_early[PRIVATE_LAST]) (FixupFunc, unsigned) = { [PRIVATE_SCREEN] = fixupScreens, [PRIVATE_CLIENT] = fixupServerClient, [PRIVATE_EXTENSION] = fixupExtensions, [PRIVATE_COLORMAP] = fixupDefaultColormaps, [PRIVATE_DEVICE] = fixupDevices, }; static void grow_private_set(DevPrivateSetPtr set, unsigned bytes) { DevPrivateKey k; for (k = set->key; k; k = k->next) k->offset += bytes; set->offset += bytes; } static void grow_screen_specific_set(DevPrivateType type, unsigned bytes) { int s; /* Update offsets for all screen-specific keys */ for (s = 0; s < screenInfo.numScreens; s++) { ScreenPtr pScreen = screenInfo.screens[s]; grow_private_set(&pScreen->screenSpecificPrivates[type], bytes); } for (s = 0; s < screenInfo.numGPUScreens; s++) { ScreenPtr pScreen = screenInfo.gpuscreens[s]; grow_private_set(&pScreen->screenSpecificPrivates[type], bytes); } } /* * Register a private key. This takes the type of object the key will * be used with, which may be PRIVATE_ALL indicating that this key * will be used with all of the private objects. If 'size' is * non-zero, then the specified amount of space will be allocated in * the private storage. Otherwise, space for a single pointer will * be allocated which can be set with dixSetPrivate */ Bool dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size) { DevPrivateType t; int offset; unsigned bytes; if (key->initialized) { assert(size == key->size); return TRUE; } /* Compute required space */ bytes = size; if (size == 0) bytes = sizeof(void *); /* align to pointer size */ bytes = (bytes + sizeof(void *) - 1) & ~(sizeof(void *) - 1); /* Update offsets for all affected keys */ if (type == PRIVATE_XSELINUX) { /* Resize if we can, or make sure nothing's allocated if we can't */ for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) if (xselinux_private[t]) { if (!allocated_early[t]) assert(!global_keys[t].created); else if (!allocated_early[t] (dixReallocPrivates, bytes)) return FALSE; } /* Move all existing keys up in the privates space to make * room for this new global key */ for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { if (xselinux_private[t]) { grow_private_set(&global_keys[t], bytes); grow_screen_specific_set(t, bytes); if (allocated_early[t]) allocated_early[t] (dixMovePrivates, bytes); } } offset = 0; } else { /* Resize if we can, or make sure nothing's allocated if we can't */ if (!allocated_early[type]) assert(!global_keys[type].created); else if (!allocated_early[type] (dixReallocPrivates, bytes)) return FALSE; offset = global_keys[type].offset; global_keys[type].offset += bytes; grow_screen_specific_set(type, bytes); } /* Setup this key */ key->offset = offset; key->size = size; key->initialized = TRUE; key->type = type; key->allocated = FALSE; key->next = global_keys[type].key; global_keys[type].key = key; return TRUE; } Bool dixRegisterScreenPrivateKey(DevScreenPrivateKey screenKey, ScreenPtr pScreen, DevPrivateType type, unsigned size) { DevPrivateKey key; if (!dixRegisterPrivateKey(&screenKey->screenKey, PRIVATE_SCREEN, 0)) return FALSE; key = dixGetPrivate(&pScreen->devPrivates, &screenKey->screenKey); if (key != NULL) { assert(key->size == size); assert(key->type == type); return TRUE; } key = calloc(sizeof(DevPrivateKeyRec), 1); if (!key) return FALSE; if (!dixRegisterPrivateKey(key, type, size)) { free(key); return FALSE; } key->allocated = TRUE; dixSetPrivate(&pScreen->devPrivates, &screenKey->screenKey, key); return TRUE; } DevPrivateKey _dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen) { return dixGetPrivate(&pScreen->devPrivates, &key->screenKey); } /* * Initialize privates by zeroing them */ void _dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type) { assert (!screen_specific_private[type]); global_keys[type].created++; if (xselinux_private[type]) global_keys[PRIVATE_XSELINUX].created++; if (global_keys[type].offset == 0) addr = 0; *privates = addr; memset(addr, '\0', global_keys[type].offset); } /* * Clean up privates */ void _dixFiniPrivates(PrivatePtr privates, DevPrivateType type) { global_keys[type].created--; if (xselinux_private[type]) global_keys[PRIVATE_XSELINUX].created--; } /* * Allocate new object with privates. * * This is expected to be invoked from the * dixAllocateObjectWithPrivates macro */ void * _dixAllocateObjectWithPrivates(unsigned baseSize, unsigned clear, unsigned offset, DevPrivateType type) { unsigned totalSize; void *object; PrivatePtr privates; PrivatePtr *devPrivates; assert(type > PRIVATE_SCREEN && type < PRIVATE_LAST); assert(!screen_specific_private[type]); /* round up so that void * is aligned */ baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1); totalSize = baseSize + global_keys[type].offset; object = malloc(totalSize); if (!object) return NULL; memset(object, '\0', clear); privates = (PrivatePtr) (((char *) object) + baseSize); devPrivates = (PrivatePtr *) ((char *) object + offset); _dixInitPrivates(devPrivates, privates, type); return object; } /* * Allocate privates separately from containing object. * Used for clients and screens. */ Bool dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type) { unsigned size; PrivatePtr p; assert(type > PRIVATE_XSELINUX && type < PRIVATE_LAST); assert(!screen_specific_private[type]); size = global_keys[type].offset; if (!size) { p = NULL; } else { if (!(p = malloc(size))) return FALSE; } _dixInitPrivates(privates, p, type); ++global_keys[type].allocated; return TRUE; } /* * Free an object that has privates * * This is expected to be invoked from the * dixFreeObjectWithPrivates macro */ void _dixFreeObjectWithPrivates(void *object, PrivatePtr privates, DevPrivateType type) { _dixFiniPrivates(privates, type); free(object); } /* * Called to free screen or client privates */ void dixFreePrivates(PrivatePtr privates, DevPrivateType type) { _dixFiniPrivates(privates, type); --global_keys[type].allocated; free(privates); } /* * Return size of privates for the specified type */ extern _X_EXPORT int dixPrivatesSize(DevPrivateType type) { assert(type >= PRIVATE_SCREEN && type < PRIVATE_LAST); assert (!screen_specific_private[type]); return global_keys[type].offset; } /* Table of devPrivates offsets */ static const int offsets[] = { -1, /* RT_NONE */ offsetof(WindowRec, devPrivates), /* RT_WINDOW */ offsetof(PixmapRec, devPrivates), /* RT_PIXMAP */ offsetof(GC, devPrivates), /* RT_GC */ -1, /* RT_FONT */ offsetof(CursorRec, devPrivates), /* RT_CURSOR */ offsetof(ColormapRec, devPrivates), /* RT_COLORMAP */ }; int dixLookupPrivateOffset(RESTYPE type) { /* * Special kludge for DBE which registers a new resource type that * points at pixmaps (thanks, DBE) */ if (type & RC_DRAWABLE) { if (type == RT_WINDOW) return offsets[RT_WINDOW & TypeMask]; else return offsets[RT_PIXMAP & TypeMask]; } type = type & TypeMask; if (type < ARRAY_SIZE(offsets)) return offsets[type]; return -1; } /* * Screen-specific privates */ extern _X_EXPORT Bool dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key, DevPrivateType type, unsigned size) { int offset; unsigned bytes; if (!screen_specific_private[type]) FatalError("Attempt to allocate screen-specific private storage for type %s\n", key_names[type]); if (key->initialized) { assert(size == key->size); return TRUE; } /* Compute required space */ bytes = size; if (size == 0) bytes = sizeof(void *); /* align to void * size */ bytes = (bytes + sizeof(void *) - 1) & ~(sizeof(void *) - 1); assert (!allocated_early[type]); assert (!pScreen->screenSpecificPrivates[type].created); offset = pScreen->screenSpecificPrivates[type].offset; pScreen->screenSpecificPrivates[type].offset += bytes; /* Setup this key */ key->offset = offset; key->size = size; key->initialized = TRUE; key->type = type; key->allocated = FALSE; key->next = pScreen->screenSpecificPrivates[type].key; pScreen->screenSpecificPrivates[type].key = key; return TRUE; } /* Clean up screen-specific privates before CloseScreen */ void dixFreeScreenSpecificPrivates(ScreenPtr pScreen) { DevPrivateType t; for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { DevPrivateKey key; for (key = pScreen->screenSpecificPrivates[t].key; key; key = key->next) { key->initialized = FALSE; } } } /* Initialize screen-specific privates in AddScreen */ void dixInitScreenSpecificPrivates(ScreenPtr pScreen) { DevPrivateType t; for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) pScreen->screenSpecificPrivates[t].offset = global_keys[t].offset; } /* Initialize screen-specific privates in AddScreen */ void _dixInitScreenPrivates(ScreenPtr pScreen, PrivatePtr *privates, void *addr, DevPrivateType type) { int privates_size; assert (screen_specific_private[type]); if (pScreen) { privates_size = pScreen->screenSpecificPrivates[type].offset; pScreen->screenSpecificPrivates[type].created++; } else privates_size = global_keys[type].offset; global_keys[type].created++; if (xselinux_private[type]) global_keys[PRIVATE_XSELINUX].created++; if (privates_size == 0) addr = 0; *privates = addr; memset(addr, '\0', privates_size); } void * _dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen, unsigned baseSize, unsigned clear, unsigned offset, DevPrivateType type) { unsigned totalSize; void *object; PrivatePtr privates; PrivatePtr *devPrivates; int privates_size; assert(type > PRIVATE_SCREEN && type < PRIVATE_LAST); assert (screen_specific_private[type]); if (pScreen) privates_size = pScreen->screenSpecificPrivates[type].offset; else privates_size = global_keys[type].offset; /* round up so that pointer is aligned */ baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1); totalSize = baseSize + privates_size; object = malloc(totalSize); if (!object) return NULL; memset(object, '\0', clear); privates = (PrivatePtr) (((char *) object) + baseSize); devPrivates = (PrivatePtr *) ((char *) object + offset); _dixInitScreenPrivates(pScreen, devPrivates, privates, type); return object; } int dixScreenSpecificPrivatesSize(ScreenPtr pScreen, DevPrivateType type) { assert(type >= PRIVATE_SCREEN && type < PRIVATE_LAST); if (screen_specific_private[type]) return pScreen->screenSpecificPrivates[type].offset; else return global_keys[type].offset; } void dixPrivateUsage(void) { int objects = 0; int bytes = 0; int alloc = 0; DevPrivateType t; for (t = PRIVATE_XSELINUX + 1; t < PRIVATE_LAST; t++) { if (global_keys[t].offset) { ErrorF ("%s: %d objects of %d bytes = %d total bytes %d private allocs\n", key_names[t], global_keys[t].created, global_keys[t].offset, global_keys[t].created * global_keys[t].offset, global_keys[t].allocated); bytes += global_keys[t].created * global_keys[t].offset; objects += global_keys[t].created; alloc += global_keys[t].allocated; } } ErrorF("TOTAL: %d objects, %d bytes, %d allocs\n", objects, bytes, alloc); } void dixResetPrivates(void) { DevPrivateType t; for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { DevPrivateKey key, next; for (key = global_keys[t].key; key; key = next) { next = key->next; key->offset = 0; key->initialized = FALSE; key->size = 0; key->type = 0; if (key->allocated) free(key); } if (global_keys[t].created) { ErrorF("%d %ss still allocated at reset\n", global_keys[t].created, key_names[t]); dixPrivateUsage(); } global_keys[t].key = NULL; global_keys[t].offset = 0; global_keys[t].created = 0; global_keys[t].allocated = 0; } } Bool dixPrivatesCreated(DevPrivateType type) { if (global_keys[type].created) return TRUE; else return FALSE; } xorg-server-1.20.13/dix/property.c0000644000175000017500000004651214100573756013716 00000000000000/*********************************************************** Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include #include "windowstr.h" #include "propertyst.h" #include "dixstruct.h" #include "dispatch.h" #include "swaprep.h" #include "xace.h" /***************************************************************** * Property Stuff * * dixLookupProperty, dixChangeProperty, DeleteProperty * * Properties belong to windows. The list of properties should not be * traversed directly. Instead, use the three functions listed above. * *****************************************************************/ #ifdef notdef static void PrintPropertys(WindowPtr pWin) { PropertyPtr pProp; int j; pProp = pWin->userProps; while (pProp) { ErrorF("[dix] %x %x\n", pProp->propertyName, pProp->type); ErrorF("[dix] property format: %d\n", pProp->format); ErrorF("[dix] property data: \n"); for (j = 0; j < (pProp->format / 8) * pProp->size; j++) ErrorF("[dix] %c\n", pProp->data[j]); pProp = pProp->next; } } #endif int dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName, ClientPtr client, Mask access_mode) { PropertyPtr pProp; int rc = BadMatch; client->errorValue = propertyName; for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) if (pProp->propertyName == propertyName) break; if (pProp) rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode); *result = pProp; return rc; } CallbackListPtr PropertyStateCallback; static void deliverPropertyNotifyEvent(WindowPtr pWin, int state, PropertyPtr pProp) { xEvent event; PropertyStateRec rec = { .win = pWin, .prop = pProp, .state = state }; UpdateCurrentTimeIf(); event = (xEvent) { .u.property.window = pWin->drawable.id, .u.property.state = state, .u.property.atom = pProp->propertyName, .u.property.time = currentTime.milliseconds, }; event.u.u.type = PropertyNotify; CallCallbacks(&PropertyStateCallback, &rec); DeliverEvents(pWin, &event, 1, (WindowPtr) NULL); } int ProcRotateProperties(ClientPtr client) { int i, j, delta, rc; REQUEST(xRotatePropertiesReq); WindowPtr pWin; Atom *atoms; PropertyPtr *props; /* array of pointer */ PropertyPtr pProp, saved; REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2); UpdateCurrentTime(); rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); if (rc != Success || stuff->nAtoms <= 0) return rc; atoms = (Atom *) &stuff[1]; props = xallocarray(stuff->nAtoms, sizeof(PropertyPtr)); saved = xallocarray(stuff->nAtoms, sizeof(PropertyRec)); if (!props || !saved) { rc = BadAlloc; goto out; } for (i = 0; i < stuff->nAtoms; i++) { if (!ValidAtom(atoms[i])) { rc = BadAtom; client->errorValue = atoms[i]; goto out; } for (j = i + 1; j < stuff->nAtoms; j++) if (atoms[j] == atoms[i]) { rc = BadMatch; goto out; } rc = dixLookupProperty(&pProp, pWin, atoms[i], client, DixReadAccess | DixWriteAccess); if (rc != Success) goto out; props[i] = pProp; saved[i] = *pProp; } delta = stuff->nPositions; /* If the rotation is a complete 360 degrees, then moving the properties around and generating PropertyNotify events should be skipped. */ if (abs(delta) % stuff->nAtoms) { while (delta < 0) /* faster if abs value is small */ delta += stuff->nAtoms; for (i = 0; i < stuff->nAtoms; i++) { j = (i + delta) % stuff->nAtoms; deliverPropertyNotifyEvent(pWin, PropertyNewValue, props[i]); /* Preserve name and devPrivates */ props[j]->type = saved[i].type; props[j]->format = saved[i].format; props[j]->size = saved[i].size; props[j]->data = saved[i].data; } } out: free(saved); free(props); return rc; } int ProcChangeProperty(ClientPtr client) { WindowPtr pWin; char format, mode; unsigned long len; int sizeInBytes, totalSize, err; REQUEST(xChangePropertyReq); REQUEST_AT_LEAST_SIZE(xChangePropertyReq); UpdateCurrentTime(); format = stuff->format; mode = stuff->mode; if ((mode != PropModeReplace) && (mode != PropModeAppend) && (mode != PropModePrepend)) { client->errorValue = mode; return BadValue; } if ((format != 8) && (format != 16) && (format != 32)) { client->errorValue = format; return BadValue; } len = stuff->nUnits; if (len > bytes_to_int32(0xffffffff - sizeof(xChangePropertyReq))) return BadLength; sizeInBytes = format >> 3; totalSize = len * sizeInBytes; REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize); err = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); if (err != Success) return err; if (!ValidAtom(stuff->property)) { client->errorValue = stuff->property; return BadAtom; } if (!ValidAtom(stuff->type)) { client->errorValue = stuff->type; return BadAtom; } err = dixChangeWindowProperty(client, pWin, stuff->property, stuff->type, (int) format, (int) mode, len, &stuff[1], TRUE); if (err != Success) return err; else return Success; } int dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, Atom type, int format, int mode, unsigned long len, void *value, Bool sendevent) { PropertyPtr pProp; PropertyRec savedProp; int sizeInBytes, totalSize, rc; unsigned char *data; Mask access_mode; sizeInBytes = format >> 3; totalSize = len * sizeInBytes; access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess; /* first see if property already exists */ rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode); if (rc == BadMatch) { /* just add to list */ if (!pWin->optional && !MakeWindowOptional(pWin)) return BadAlloc; pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY); if (!pProp) return BadAlloc; data = malloc(totalSize); if (!data && len) { dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); return BadAlloc; } memcpy(data, value, totalSize); pProp->propertyName = property; pProp->type = type; pProp->format = format; pProp->data = data; pProp->size = len; rc = XaceHookPropertyAccess(pClient, pWin, &pProp, DixCreateAccess | DixWriteAccess); if (rc != Success) { free(data); dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); pClient->errorValue = property; return rc; } pProp->next = pWin->optional->userProps; pWin->optional->userProps = pProp; } else if (rc == Success) { /* To append or prepend to a property the request format and type must match those of the already defined property. The existing format and type are irrelevant when using the mode "PropModeReplace" since they will be written over. */ if ((format != pProp->format) && (mode != PropModeReplace)) return BadMatch; if ((pProp->type != type) && (mode != PropModeReplace)) return BadMatch; /* save the old values for later */ savedProp = *pProp; if (mode == PropModeReplace) { data = malloc(totalSize); if (!data && len) return BadAlloc; memcpy(data, value, totalSize); pProp->data = data; pProp->size = len; pProp->type = type; pProp->format = format; } else if (len == 0) { /* do nothing */ } else if (mode == PropModeAppend) { data = xallocarray(pProp->size + len, sizeInBytes); if (!data) return BadAlloc; memcpy(data, pProp->data, pProp->size * sizeInBytes); memcpy(data + pProp->size * sizeInBytes, value, totalSize); pProp->data = data; pProp->size += len; } else if (mode == PropModePrepend) { data = xallocarray(len + pProp->size, sizeInBytes); if (!data) return BadAlloc; memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes); memcpy(data, value, totalSize); pProp->data = data; pProp->size += len; } /* Allow security modules to check the new content */ access_mode |= DixPostAccess; rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode); if (rc == Success) { if (savedProp.data != pProp->data) free(savedProp.data); } else { if (savedProp.data != pProp->data) free(pProp->data); *pProp = savedProp; return rc; } } else return rc; if (sendevent) deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp); return Success; } int DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName) { PropertyPtr pProp, prevProp; int rc; rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess); if (rc == BadMatch) return Success; /* Succeed if property does not exist */ if (rc == Success) { if (pWin->optional->userProps == pProp) { /* Takes care of head */ if (!(pWin->optional->userProps = pProp->next)) CheckWindowOptionalNeed(pWin); } else { /* Need to traverse to find the previous element */ prevProp = pWin->optional->userProps; while (prevProp->next != pProp) prevProp = prevProp->next; prevProp->next = pProp->next; } deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp); free(pProp->data); dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); } return rc; } void DeleteAllWindowProperties(WindowPtr pWin) { PropertyPtr pProp, pNextProp; pProp = wUserProps(pWin); while (pProp) { deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp); pNextProp = pProp->next; free(pProp->data); dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); pProp = pNextProp; } if (pWin->optional) pWin->optional->userProps = NULL; } static int NullPropertyReply(ClientPtr client, ATOM propertyType, int format) { xGetPropertyReply reply = { .type = X_Reply, .format = format, .sequenceNumber = client->sequence, .length = 0, .propertyType = propertyType, .bytesAfter = 0, .nItems = 0 }; WriteReplyToClient(client, sizeof(xGenericReply), &reply); return Success; } /***************** * GetProperty * If type Any is specified, returns the property from the specified * window regardless of its type. If a type is specified, returns the * property only if its type equals the specified type. * If delete is True and a property is returned, the property is also * deleted from the window and a PropertyNotify event is generated on the * window. *****************/ int ProcGetProperty(ClientPtr client) { PropertyPtr pProp, prevProp; unsigned long n, len, ind; int rc; WindowPtr pWin; xGetPropertyReply reply; Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess; REQUEST(xGetPropertyReq); REQUEST_SIZE_MATCH(xGetPropertyReq); if (stuff->delete) { UpdateCurrentTime(); win_mode |= DixSetPropAccess; prop_mode |= DixDestroyAccess; } rc = dixLookupWindow(&pWin, stuff->window, client, win_mode); if (rc != Success) return rc; if (!ValidAtom(stuff->property)) { client->errorValue = stuff->property; return BadAtom; } if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) { client->errorValue = stuff->delete; return BadValue; } if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) { client->errorValue = stuff->type; return BadAtom; } rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode); if (rc == BadMatch) return NullPropertyReply(client, None, 0); else if (rc != Success) return rc; /* If the request type and actual type don't match. Return the property information, but not the data. */ if (((stuff->type != pProp->type) && (stuff->type != AnyPropertyType)) ) { reply = (xGetPropertyReply) { .type = X_Reply, .sequenceNumber = client->sequence, .bytesAfter = pProp->size, .format = pProp->format, .length = 0, .nItems = 0, .propertyType = pProp->type }; WriteReplyToClient(client, sizeof(xGenericReply), &reply); return Success; } /* * Return type, format, value to client */ n = (pProp->format / 8) * pProp->size; /* size (bytes) of prop */ ind = stuff->longOffset << 2; /* If longOffset is invalid such that it causes "len" to be negative, it's a value error. */ if (n < ind) { client->errorValue = stuff->longOffset; return BadValue; } len = min(n - ind, 4 * stuff->longLength); reply = (xGetPropertyReply) { .type = X_Reply, .sequenceNumber = client->sequence, .bytesAfter = n - (ind + len), .format = pProp->format, .length = bytes_to_int32(len), .nItems = len / (pProp->format / 8), .propertyType = pProp->type }; if (stuff->delete && (reply.bytesAfter == 0)) deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp); WriteReplyToClient(client, sizeof(xGenericReply), &reply); if (len) { switch (reply.format) { case 32: client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; break; case 16: client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write; break; default: client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient; break; } WriteSwappedDataToClient(client, len, (char *) pProp->data + ind); } if (stuff->delete && (reply.bytesAfter == 0)) { /* Delete the Property */ if (pWin->optional->userProps == pProp) { /* Takes care of head */ if (!(pWin->optional->userProps = pProp->next)) CheckWindowOptionalNeed(pWin); } else { /* Need to traverse to find the previous element */ prevProp = pWin->optional->userProps; while (prevProp->next != pProp) prevProp = prevProp->next; prevProp->next = pProp->next; } free(pProp->data); dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); } return Success; } int ProcListProperties(ClientPtr client) { Atom *pAtoms = NULL, *temppAtoms; xListPropertiesReply xlpr; int rc, numProps = 0; WindowPtr pWin; PropertyPtr pProp, realProp; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess); if (rc != Success) return rc; for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) numProps++; if (numProps && !(pAtoms = xallocarray(numProps, sizeof(Atom)))) return BadAlloc; numProps = 0; temppAtoms = pAtoms; for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { realProp = pProp; rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess); if (rc == Success && realProp == pProp) { *temppAtoms++ = pProp->propertyName; numProps++; } } xlpr = (xListPropertiesReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = bytes_to_int32(numProps * sizeof(Atom)), .nProperties = numProps }; WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); if (numProps) { client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); } free(pAtoms); return Success; } int ProcDeleteProperty(ClientPtr client) { WindowPtr pWin; REQUEST(xDeletePropertyReq); int result; REQUEST_SIZE_MATCH(xDeletePropertyReq); UpdateCurrentTime(); result = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); if (result != Success) return result; if (!ValidAtom(stuff->property)) { client->errorValue = stuff->property; return BadAtom; } return DeleteProperty(client, pWin, stuff->property); } xorg-server-1.20.13/dix/ptrveloc.c0000644000175000017500000010631714100573756013670 00000000000000/* * * Copyright © 2006-2009 Simon Thum simon dot thum at gmx dot de * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include #include /***************************************************************************** * Predictable pointer acceleration * * 2006-2009 by Simon Thum (simon [dot] thum [at] gmx de) * * Serves 3 complementary functions: * 1) provide a sophisticated ballistic velocity estimate to improve * the relation between velocity (of the device) and acceleration * 2) make arbitrary acceleration profiles possible * 3) decelerate by two means (constant and adaptive) if enabled * * Important concepts are the * * - Scheme * which selects the basic algorithm * (see devices.c/InitPointerAccelerationScheme) * - Profile * which returns an acceleration * for a given velocity * * The profile can be selected by the user at runtime. * The classic profile is intended to cleanly perform old-style * function selection (threshold =/!= 0) * ****************************************************************************/ /* fwds */ static double SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc); static PointerAccelerationProfileFunc GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); static BOOL InitializePredictableAccelerationProperties(DeviceIntPtr, DeviceVelocityPtr, PredictableAccelSchemePtr); static BOOL DeletePredictableAccelerationProperties(DeviceIntPtr, PredictableAccelSchemePtr); /*#define PTRACCEL_DEBUGGING*/ #ifdef PTRACCEL_DEBUGGING #define DebugAccelF(...) ErrorFSigSafe("dix/ptraccel: " __VA_ARGS__) #else #define DebugAccelF(...) /* */ #endif /******************************** * Init/Uninit *******************************/ /* some int which is not a profile number */ #define PROFILE_UNINITIALIZE (-100) /** * Init DeviceVelocity struct so it should match the average case */ void InitVelocityData(DeviceVelocityPtr vel) { memset(vel, 0, sizeof(DeviceVelocityRec)); vel->corr_mul = 10.0; /* dots per 10 milisecond should be usable */ vel->const_acceleration = 1.0; /* no acceleration/deceleration */ vel->reset_time = 300; vel->use_softening = 1; vel->min_acceleration = 1.0; /* don't decelerate */ vel->max_rel_diff = 0.2; vel->max_diff = 1.0; vel->initial_range = 2; vel->average_accel = TRUE; SetAccelerationProfile(vel, AccelProfileClassic); InitTrackers(vel, 16); } /** * Clean up DeviceVelocityRec */ void FreeVelocityData(DeviceVelocityPtr vel) { free(vel->tracker); SetAccelerationProfile(vel, PROFILE_UNINITIALIZE); } /** * Init predictable scheme */ Bool InitPredictableAccelerationScheme(DeviceIntPtr dev, ValuatorAccelerationPtr protoScheme) { DeviceVelocityPtr vel; ValuatorAccelerationRec scheme; PredictableAccelSchemePtr schemeData; scheme = *protoScheme; vel = calloc(1, sizeof(DeviceVelocityRec)); schemeData = calloc(1, sizeof(PredictableAccelSchemeRec)); if (!vel || !schemeData) { free(vel); free(schemeData); return FALSE; } InitVelocityData(vel); schemeData->vel = vel; scheme.accelData = schemeData; if (!InitializePredictableAccelerationProperties(dev, vel, schemeData)) { free(vel); free(schemeData); return FALSE; } /* all fine, assign scheme to device */ dev->valuator->accelScheme = scheme; return TRUE; } /** * Uninit scheme */ void AccelerationDefaultCleanup(DeviceIntPtr dev) { DeviceVelocityPtr vel = GetDevicePredictableAccelData(dev); if (vel) { /* the proper guarantee would be that we're not inside of * AccelSchemeProc(), but that seems impossible. Schemes don't get * switched often anyway. */ input_lock(); dev->valuator->accelScheme.AccelSchemeProc = NULL; FreeVelocityData(vel); free(vel); DeletePredictableAccelerationProperties(dev, (PredictableAccelSchemePtr) dev->valuator->accelScheme. accelData); free(dev->valuator->accelScheme.accelData); dev->valuator->accelScheme.accelData = NULL; input_unlock(); } } /************************* * Input property support ************************/ /** * choose profile */ static int AccelSetProfileProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkOnly) { DeviceVelocityPtr vel; int profile, *ptr = &profile; int rc; int nelem = 1; if (atom != XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER)) return Success; vel = GetDevicePredictableAccelData(dev); if (!vel) return BadValue; rc = XIPropToInt(val, &nelem, &ptr); if (checkOnly) { if (rc) return rc; if (GetAccelerationProfile(vel, profile) == NULL) return BadValue; } else SetAccelerationProfile(vel, profile); return Success; } static long AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) { int profile = vel->statistics.profile_number; Atom prop_profile_number = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER); XIChangeDeviceProperty(dev, prop_profile_number, XA_INTEGER, 32, PropModeReplace, 1, &profile, FALSE); XISetDevicePropertyDeletable(dev, prop_profile_number, FALSE); return XIRegisterPropertyHandler(dev, AccelSetProfileProperty, NULL, NULL); } /** * constant deceleration */ static int AccelSetDecelProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkOnly) { DeviceVelocityPtr vel; float v, *ptr = &v; int rc; int nelem = 1; if (atom != XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION)) return Success; vel = GetDevicePredictableAccelData(dev); if (!vel) return BadValue; rc = XIPropToFloat(val, &nelem, &ptr); if (checkOnly) { if (rc) return rc; return (v > 0) ? Success : BadValue; } vel->const_acceleration = 1 / v; return Success; } static long AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) { float fval = 1.0 / vel->const_acceleration; Atom prop_const_decel = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION); XIChangeDeviceProperty(dev, prop_const_decel, XIGetKnownProperty(XATOM_FLOAT), 32, PropModeReplace, 1, &fval, FALSE); XISetDevicePropertyDeletable(dev, prop_const_decel, FALSE); return XIRegisterPropertyHandler(dev, AccelSetDecelProperty, NULL, NULL); } /** * adaptive deceleration */ static int AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkOnly) { DeviceVelocityPtr veloc; float v, *ptr = &v; int rc; int nelem = 1; if (atom != XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION)) return Success; veloc = GetDevicePredictableAccelData(dev); if (!veloc) return BadValue; rc = XIPropToFloat(val, &nelem, &ptr); if (checkOnly) { if (rc) return rc; return (v >= 1.0f) ? Success : BadValue; } if (v >= 1.0f) veloc->min_acceleration = 1 / v; return Success; } static long AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) { float fval = 1.0 / vel->min_acceleration; Atom prop_adapt_decel = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION); XIChangeDeviceProperty(dev, prop_adapt_decel, XIGetKnownProperty(XATOM_FLOAT), 32, PropModeReplace, 1, &fval, FALSE); XISetDevicePropertyDeletable(dev, prop_adapt_decel, FALSE); return XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL, NULL); } /** * velocity scaling */ static int AccelSetScaleProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkOnly) { DeviceVelocityPtr vel; float v, *ptr = &v; int rc; int nelem = 1; if (atom != XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING)) return Success; vel = GetDevicePredictableAccelData(dev); if (!vel) return BadValue; rc = XIPropToFloat(val, &nelem, &ptr); if (checkOnly) { if (rc) return rc; return (v > 0) ? Success : BadValue; } if (v > 0) vel->corr_mul = v; return Success; } static long AccelInitScaleProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) { float fval = vel->corr_mul; Atom prop_velo_scale = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING); XIChangeDeviceProperty(dev, prop_velo_scale, XIGetKnownProperty(XATOM_FLOAT), 32, PropModeReplace, 1, &fval, FALSE); XISetDevicePropertyDeletable(dev, prop_velo_scale, FALSE); return XIRegisterPropertyHandler(dev, AccelSetScaleProperty, NULL, NULL); } static BOOL InitializePredictableAccelerationProperties(DeviceIntPtr dev, DeviceVelocityPtr vel, PredictableAccelSchemePtr schemeData) { int num_handlers = 4; if (!vel) return FALSE; schemeData->prop_handlers = calloc(num_handlers, sizeof(long)); if (!schemeData->prop_handlers) return FALSE; schemeData->num_prop_handlers = num_handlers; schemeData->prop_handlers[0] = AccelInitProfileProperty(dev, vel); schemeData->prop_handlers[1] = AccelInitDecelProperty(dev, vel); schemeData->prop_handlers[2] = AccelInitAdaptDecelProperty(dev, vel); schemeData->prop_handlers[3] = AccelInitScaleProperty(dev, vel); return TRUE; } BOOL DeletePredictableAccelerationProperties(DeviceIntPtr dev, PredictableAccelSchemePtr scheme) { DeviceVelocityPtr vel; Atom prop; int i; prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING); XIDeleteDeviceProperty(dev, prop, FALSE); prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION); XIDeleteDeviceProperty(dev, prop, FALSE); prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION); XIDeleteDeviceProperty(dev, prop, FALSE); prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER); XIDeleteDeviceProperty(dev, prop, FALSE); vel = GetDevicePredictableAccelData(dev); if (vel) { for (i = 0; i < scheme->num_prop_handlers; i++) if (scheme->prop_handlers[i]) XIUnregisterPropertyHandler(dev, scheme->prop_handlers[i]); } free(scheme->prop_handlers); scheme->prop_handlers = NULL; scheme->num_prop_handlers = 0; return TRUE; } /********************* * Tracking logic ********************/ void InitTrackers(DeviceVelocityPtr vel, int ntracker) { if (ntracker < 1) { ErrorF("invalid number of trackers\n"); return; } free(vel->tracker); vel->tracker = (MotionTrackerPtr) calloc(ntracker, sizeof(MotionTracker)); vel->num_tracker = ntracker; } enum directions { N = (1 << 0), NE = (1 << 1), E = (1 << 2), SE = (1 << 3), S = (1 << 4), SW = (1 << 5), W = (1 << 6), NW = (1 << 7), UNDEFINED = 0xFF }; /** * return a bit field of possible directions. * There's no reason against widening to more precise directions (<45 degrees), * should it not perform well. All this is needed for is sort out non-linear * motion, so precision isn't paramount. However, one should not flag direction * too narrow, since it would then cut the linear segment to zero size way too * often. * * @return A bitmask for N, NE, S, SE, etc. indicating the directions for * this movement. */ static int DoGetDirection(int dx, int dy) { int dir = 0; /* on insignificant mickeys, flag 135 degrees */ if (abs(dx) < 2 && abs(dy) < 2) { /* first check diagonal cases */ if (dx > 0 && dy > 0) dir = E | SE | S; else if (dx > 0 && dy < 0) dir = N | NE | E; else if (dx < 0 && dy < 0) dir = W | NW | N; else if (dx < 0 && dy > 0) dir = W | SW | S; /* check axis-aligned directions */ else if (dx > 0) dir = NE | E | SE; else if (dx < 0) dir = NW | W | SW; else if (dy > 0) dir = SE | S | SW; else if (dy < 0) dir = NE | N | NW; else dir = UNDEFINED; /* shouldn't happen */ } else { /* compute angle and set appropriate flags */ double r; int i1, i2; r = atan2(dy, dx); /* find direction. * * Add 360° to avoid r become negative since C has no well-defined * modulo for such cases. Then divide by 45° to get the octant * number, e.g. * 0 <= r <= 1 is [0-45]° * 1 <= r <= 2 is [45-90]° * etc. * But we add extra 90° to match up with our N, S, etc. defines up * there, rest stays the same. */ r = (r + (M_PI * 2.5)) / (M_PI / 4); /* this intends to flag 2 directions (45 degrees), * except on very well-aligned mickeys. */ i1 = (int) (r + 0.1) % 8; i2 = (int) (r + 0.9) % 8; if (i1 < 0 || i1 > 7 || i2 < 0 || i2 > 7) dir = UNDEFINED; /* shouldn't happen */ else dir = (1 << i1 | 1 << i2); } return dir; } #define DIRECTION_CACHE_RANGE 5 #define DIRECTION_CACHE_SIZE (DIRECTION_CACHE_RANGE*2+1) /* cache DoGetDirection(). * To avoid excessive use of direction calculation, cache the values for * [-5..5] for both x/y. Anything outside of that is calcualted on the fly. * * @return A bitmask for N, NE, S, SE, etc. indicating the directions for * this movement. */ static int GetDirection(int dx, int dy) { static int cache[DIRECTION_CACHE_SIZE][DIRECTION_CACHE_SIZE]; int dir; if (abs(dx) <= DIRECTION_CACHE_RANGE && abs(dy) <= DIRECTION_CACHE_RANGE) { /* cacheable */ dir = cache[DIRECTION_CACHE_RANGE + dx][DIRECTION_CACHE_RANGE + dy]; if (dir == 0) { dir = DoGetDirection(dx, dy); cache[DIRECTION_CACHE_RANGE + dx][DIRECTION_CACHE_RANGE + dy] = dir; } } else { /* non-cacheable */ dir = DoGetDirection(dx, dy); } return dir; } #undef DIRECTION_CACHE_RANGE #undef DIRECTION_CACHE_SIZE /* convert offset (age) to array index */ #define TRACKER_INDEX(s, d) (((s)->num_tracker + (s)->cur_tracker - (d)) % (s)->num_tracker) #define TRACKER(s, d) &(s)->tracker[TRACKER_INDEX(s,d)] /** * Add the delta motion to each tracker, then reset the latest tracker to * 0/0 and set it as the current one. */ static inline void FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t) { int n; for (n = 0; n < vel->num_tracker; n++) { vel->tracker[n].dx += dx; vel->tracker[n].dy += dy; } n = (vel->cur_tracker + 1) % vel->num_tracker; vel->tracker[n].dx = 0.0; vel->tracker[n].dy = 0.0; vel->tracker[n].time = cur_t; vel->tracker[n].dir = GetDirection(dx, dy); DebugAccelF("motion [dx: %f dy: %f dir:%d diff: %d]\n", dx, dy, vel->tracker[n].dir, cur_t - vel->tracker[vel->cur_tracker].time); vel->cur_tracker = n; } /** * calc velocity for given tracker, with * velocity scaling. * This assumes linear motion. */ static double CalcTracker(const MotionTracker * tracker, int cur_t) { double dist = sqrt(tracker->dx * tracker->dx + tracker->dy * tracker->dy); int dtime = cur_t - tracker->time; if (dtime > 0) return dist / dtime; else return 0; /* synonymous for NaN, since we're not C99 */ } /* find the most plausible velocity. That is, the most distant * (in time) tracker which isn't too old, the movement vector was * in the same octant, and where the velocity is within an * acceptable range to the inital velocity. * * @return The tracker's velocity or 0 if the above conditions are unmet */ static double QueryTrackers(DeviceVelocityPtr vel, int cur_t) { int offset, dir = UNDEFINED, used_offset = -1, age_ms; /* initial velocity: a low-offset, valid velocity */ double initial_velocity = 0, result = 0, velocity_diff; double velocity_factor = vel->corr_mul * vel->const_acceleration; /* premultiply */ /* loop from current to older data */ for (offset = 1; offset < vel->num_tracker; offset++) { MotionTracker *tracker = TRACKER(vel, offset); double tracker_velocity; age_ms = cur_t - tracker->time; /* bail out if data is too old and protect from overrun */ if (age_ms >= vel->reset_time || age_ms < 0) { DebugAccelF("query: tracker too old (reset after %d, age is %d)\n", vel->reset_time, age_ms); break; } /* * this heuristic avoids using the linear-motion velocity formula * in CalcTracker() on motion that isn't exactly linear. So to get * even more precision we could subdivide as a final step, so possible * non-linearities are accounted for. */ dir &= tracker->dir; if (dir == 0) { /* we've changed octant of movement (e.g. NE → NW) */ DebugAccelF("query: no longer linear\n"); /* instead of breaking it we might also inspect the partition after, * but actual improvement with this is probably rare. */ break; } tracker_velocity = CalcTracker(tracker, cur_t) * velocity_factor; if ((initial_velocity == 0 || offset <= vel->initial_range) && tracker_velocity != 0) { /* set initial velocity and result */ result = initial_velocity = tracker_velocity; used_offset = offset; } else if (initial_velocity != 0 && tracker_velocity != 0) { velocity_diff = fabs(initial_velocity - tracker_velocity); if (velocity_diff > vel->max_diff && velocity_diff / (initial_velocity + tracker_velocity) >= vel->max_rel_diff) { /* we're not in range, quit - it won't get better. */ DebugAccelF("query: tracker too different:" " old %2.2f initial %2.2f diff: %2.2f\n", tracker_velocity, initial_velocity, velocity_diff); break; } /* we're in range with the initial velocity, * so this result is likely better * (it contains more information). */ result = tracker_velocity; used_offset = offset; } } if (offset == vel->num_tracker) { DebugAccelF("query: last tracker in effect\n"); used_offset = vel->num_tracker - 1; } if (used_offset >= 0) { #ifdef PTRACCEL_DEBUGGING MotionTracker *tracker = TRACKER(vel, used_offset); DebugAccelF("result: offset %i [dx: %f dy: %f diff: %i]\n", used_offset, tracker->dx, tracker->dy, cur_t - tracker->time); #endif } return result; } #undef TRACKER_INDEX #undef TRACKER /** * Perform velocity approximation based on 2D 'mickeys' (mouse motion delta). * return true if non-visible state reset is suggested */ BOOL ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time) { double velocity; vel->last_velocity = vel->velocity; FeedTrackers(vel, dx, dy, time); velocity = QueryTrackers(vel, time); DebugAccelF("velocity is %f\n", velocity); vel->velocity = velocity; return velocity == 0; } /** * this flattens significant ( > 1) mickeys a little bit for more steady * constant-velocity response */ static inline double ApplySimpleSoftening(double prev_delta, double delta) { double result = delta; if (delta < -1.0 || delta > 1.0) { if (delta > prev_delta) result -= 0.5; else if (delta < prev_delta) result += 0.5; } return result; } /** * Soften the delta based on previous deltas stored in vel. * * @param[in,out] fdx Delta X, modified in-place. * @param[in,out] fdx Delta Y, modified in-place. */ static void ApplySoftening(DeviceVelocityPtr vel, double *fdx, double *fdy) { if (vel->use_softening) { *fdx = ApplySimpleSoftening(vel->last_dx, *fdx); *fdy = ApplySimpleSoftening(vel->last_dy, *fdy); } } static void ApplyConstantDeceleration(DeviceVelocityPtr vel, double *fdx, double *fdy) { *fdx *= vel->const_acceleration; *fdy *= vel->const_acceleration; } /* * compute the acceleration for given velocity and enforce min_acceleration */ double BasicComputeAcceleration(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc) { double result; result = vel->Profile(dev, vel, velocity, threshold, acc); /* enforce min_acceleration */ if (result < vel->min_acceleration) result = vel->min_acceleration; return result; } /** * Compute acceleration. Takes into account averaging, nv-reset, etc. * If the velocity has changed, an average is taken of 6 velocity factors: * current velocity, last velocity and 4 times the average between the two. */ static double ComputeAcceleration(DeviceIntPtr dev, DeviceVelocityPtr vel, double threshold, double acc) { double result; if (vel->velocity <= 0) { DebugAccelF("profile skipped\n"); /* * If we have no idea about device velocity, don't pretend it. */ return 1; } if (vel->average_accel && vel->velocity != vel->last_velocity) { /* use simpson's rule to average acceleration between * current and previous velocity. * Though being the more natural choice, it causes a minor delay * in comparison, so it can be disabled. */ result = BasicComputeAcceleration(dev, vel, vel->velocity, threshold, acc); result += BasicComputeAcceleration(dev, vel, vel->last_velocity, threshold, acc); result += 4.0 * BasicComputeAcceleration(dev, vel, (vel->last_velocity + vel->velocity) / 2, threshold, acc); result /= 6.0; DebugAccelF("profile average [%.2f ... %.2f] is %.3f\n", vel->velocity, vel->last_velocity, result); } else { result = BasicComputeAcceleration(dev, vel, vel->velocity, threshold, acc); DebugAccelF("profile sample [%.2f] is %.3f\n", vel->velocity, result); } return result; } /***************************************** * Acceleration functions and profiles ****************************************/ /** * Polynomial function similar previous one, but with f(1) = 1 */ static double PolynomialAccelerationProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double ignored, double acc) { return pow(velocity, (acc - 1.0) * 0.5); } /** * returns acceleration for velocity. * This profile selects the two functions like the old scheme did */ static double ClassicProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc) { if (threshold > 0) { return SimpleSmoothProfile(dev, vel, velocity, threshold, acc); } else { return PolynomialAccelerationProfile(dev, vel, velocity, 0, acc); } } /** * Power profile * This has a completely smooth transition curve, i.e. no jumps in the * derivatives. * * This has the expense of overall response dependency on min-acceleration. * In effect, min_acceleration mimics const_acceleration in this profile. */ static double PowerProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc) { double vel_dist; acc = (acc - 1.0) * 0.1 + 1.0; /* without this, acc of 2 is unuseable */ if (velocity <= threshold) return vel->min_acceleration; vel_dist = velocity - threshold; return (pow(acc, vel_dist)) * vel->min_acceleration; } /** * just a smooth function in [0..1] -> [0..1] * - point symmetry at 0.5 * - f'(0) = f'(1) = 0 * - starts faster than a sinoid * - smoothness C1 (Cinf if you dare to ignore endpoints) */ static inline double CalcPenumbralGradient(double x) { x *= 2.0; x -= 1.0; return 0.5 + (x * sqrt(1.0 - x * x) + asin(x)) / M_PI; } /** * acceleration function similar to classic accelerated/unaccelerated, * but with smooth transition in between (and towards zero for adaptive dec.). */ static double SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc) { if (velocity < 1.0f) return CalcPenumbralGradient(0.5 + velocity * 0.5) * 2.0f - 1.0f; if (threshold < 1.0f) threshold = 1.0f; if (velocity <= threshold) return 1; velocity /= threshold; if (velocity >= acc) return acc; else return 1.0f + (CalcPenumbralGradient(velocity / acc) * (acc - 1.0f)); } /** * This profile uses the first half of the penumbral gradient as a start * and then scales linearly. */ static double SmoothLinearProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc) { double res, nv; if (acc > 1.0) acc -= 1.0; /*this is so acc = 1 is no acceleration */ else return 1.0; nv = (velocity - threshold) * acc * 0.5; if (nv < 0) { res = 0; } else if (nv < 2) { res = CalcPenumbralGradient(nv * 0.25) * 2.0; } else { nv -= 2.0; res = nv * 2.0 / M_PI /* steepness of gradient at 0.5 */ + 1.0; /* gradient crosses 2|1 */ } res += vel->min_acceleration; return res; } /** * From 0 to threshold, the response graduates smoothly from min_accel to * acceleration. Beyond threshold it is exactly the specified acceleration. */ static double SmoothLimitedProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc) { double res; if (velocity >= threshold || threshold == 0.0) return acc; velocity /= threshold; /* should be [0..1[ now */ res = CalcPenumbralGradient(velocity) * (acc - vel->min_acceleration); return vel->min_acceleration + res; } static double LinearProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc) { return acc * velocity; } static double NoProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc) { return 1.0; } static PointerAccelerationProfileFunc GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num) { switch (profile_num) { case AccelProfileClassic: return ClassicProfile; case AccelProfileDeviceSpecific: return vel->deviceSpecificProfile; case AccelProfilePolynomial: return PolynomialAccelerationProfile; case AccelProfileSmoothLinear: return SmoothLinearProfile; case AccelProfileSimple: return SimpleSmoothProfile; case AccelProfilePower: return PowerProfile; case AccelProfileLinear: return LinearProfile; case AccelProfileSmoothLimited: return SmoothLimitedProfile; case AccelProfileNone: return NoProfile; default: return NULL; } } /** * Set the profile by number. * Intended to make profiles exchangeable at runtime. * If you created a profile, give it a number here and in the header to * make it selectable. In case some profile-specific init is needed, here * would be a good place, since FreeVelocityData() also calls this with * PROFILE_UNINITIALIZE. * * returns FALSE if profile number is unavailable, TRUE otherwise. */ int SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num) { PointerAccelerationProfileFunc profile; profile = GetAccelerationProfile(vel, profile_num); if (profile == NULL && profile_num != PROFILE_UNINITIALIZE) return FALSE; /* Here one could free old profile-private data */ free(vel->profile_private); vel->profile_private = NULL; /* Here one could init profile-private data */ vel->Profile = profile; vel->statistics.profile_number = profile_num; return TRUE; } /********************************************** * driver interaction **********************************************/ /** * device-specific profile * * The device-specific profile is intended as a hook for a driver * which may want to provide an own acceleration profile. * It should not rely on profile-private data, instead * it should do init/uninit in the driver (ie. with DEVICE_INIT and friends). * Users may override or choose it. */ void SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel, PointerAccelerationProfileFunc profile) { if (vel) vel->deviceSpecificProfile = profile; } /** * Use this function to obtain a DeviceVelocityPtr for a device. Will return NULL if * the predictable acceleration scheme is not in effect. */ DeviceVelocityPtr GetDevicePredictableAccelData(DeviceIntPtr dev) { BUG_RETURN_VAL(!dev, NULL); if (dev->valuator && dev->valuator->accelScheme.AccelSchemeProc == acceleratePointerPredictable && dev->valuator->accelScheme.accelData != NULL) { return ((PredictableAccelSchemePtr) dev->valuator->accelScheme.accelData)->vel; } return NULL; } /******************************** * acceleration schemes *******************************/ /** * Modifies valuators in-place. * This version employs a velocity approximation algorithm to * enable fine-grained predictable acceleration profiles. */ void acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime) { double dx = 0, dy = 0; DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev); Bool soften = TRUE; if (valuator_mask_num_valuators(val) == 0 || !velocitydata) return; if (velocitydata->statistics.profile_number == AccelProfileNone && velocitydata->const_acceleration == 1.0) { return; /*we're inactive anyway, so skip the whole thing. */ } if (valuator_mask_isset(val, 0)) { dx = valuator_mask_get_double(val, 0); } if (valuator_mask_isset(val, 1)) { dy = valuator_mask_get_double(val, 1); } if (dx != 0.0 || dy != 0.0) { /* reset non-visible state? */ if (ProcessVelocityData2D(velocitydata, dx, dy, evtime)) { soften = FALSE; } if (dev->ptrfeed && dev->ptrfeed->ctrl.num) { double mult; /* invoke acceleration profile to determine acceleration */ mult = ComputeAcceleration(dev, velocitydata, dev->ptrfeed->ctrl.threshold, (double) dev->ptrfeed->ctrl.num / (double) dev->ptrfeed->ctrl.den); DebugAccelF("mult is %f\n", mult); if (mult != 1.0 || velocitydata->const_acceleration != 1.0) { if (mult > 1.0 && soften) ApplySoftening(velocitydata, &dx, &dy); ApplyConstantDeceleration(velocitydata, &dx, &dy); if (dx != 0.0) valuator_mask_set_double(val, 0, mult * dx); if (dy != 0.0) valuator_mask_set_double(val, 1, mult * dy); DebugAccelF("delta x:%.3f y:%.3f\n", mult * dx, mult * dy); } } } /* remember last motion delta (for softening/slow movement treatment) */ velocitydata->last_dx = dx; velocitydata->last_dy = dy; } /** * Originally a part of xf86PostMotionEvent; modifies valuators * in-place. Retained mostly for embedded scenarios. */ void acceleratePointerLightweight(DeviceIntPtr dev, ValuatorMask *val, CARD32 ignored) { double mult = 0.0, tmpf; double dx = 0.0, dy = 0.0; if (valuator_mask_isset(val, 0)) { dx = valuator_mask_get(val, 0); } if (valuator_mask_isset(val, 1)) { dy = valuator_mask_get(val, 1); } if (valuator_mask_num_valuators(val) == 0) return; if (dev->ptrfeed && dev->ptrfeed->ctrl.num) { /* modeled from xf86Events.c */ if (dev->ptrfeed->ctrl.threshold) { if ((fabs(dx) + fabs(dy)) >= dev->ptrfeed->ctrl.threshold) { if (dx != 0.0) { tmpf = (dx * (double) (dev->ptrfeed->ctrl.num)) / (double) (dev->ptrfeed->ctrl.den); valuator_mask_set_double(val, 0, tmpf); } if (dy != 0.0) { tmpf = (dy * (double) (dev->ptrfeed->ctrl.num)) / (double) (dev->ptrfeed->ctrl.den); valuator_mask_set_double(val, 1, tmpf); } } } else { mult = pow(dx * dx + dy * dy, ((double) (dev->ptrfeed->ctrl.num) / (double) (dev->ptrfeed->ctrl.den) - 1.0) / 2.0) / 2.0; if (dx != 0.0) valuator_mask_set_double(val, 0, mult * dx); if (dy != 0.0) valuator_mask_set_double(val, 1, mult * dy); } } } xorg-server-1.20.13/dix/region.c0000644000175000017500000013131514100573756013311 00000000000000/*********************************************************** Copyright 1987, 1988, 1989, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987, 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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. ******************************************************************/ /* The panoramix components contained the following notice */ /***************************************************************** Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Digital Equipment Corporation shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Digital Equipment Corporation. ******************************************************************/ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "regionstr.h" #include #include #include "gc.h" #include #undef assert #ifdef REGION_DEBUG #define assert(expr) { \ CARD32 *foo = NULL; \ if (!(expr)) { \ ErrorF("Assertion failed file %s, line %d: %s\n", \ __FILE__, __LINE__, #expr); \ *foo = 0xdeadbeef; /* to get a backtrace */ \ } \ } #else #define assert(expr) #endif #define good(reg) assert(RegionIsValid(reg)) /* * The functions in this file implement the Region abstraction used extensively * throughout the X11 sample server. A Region is simply a set of disjoint * (non-overlapping) rectangles, plus an "extent" rectangle which is the * smallest single rectangle that contains all the non-overlapping rectangles. * * A Region is implemented as a "y-x-banded" array of rectangles. This array * imposes two degrees of order. First, all rectangles are sorted by top side * y coordinate first (y1), and then by left side x coordinate (x1). * * Furthermore, the rectangles are grouped into "bands". Each rectangle in a * band has the same top y coordinate (y1), and each has the same bottom y * coordinate (y2). Thus all rectangles in a band differ only in their left * and right side (x1 and x2). Bands are implicit in the array of rectangles: * there is no separate list of band start pointers. * * The y-x band representation does not minimize rectangles. In particular, * if a rectangle vertically crosses a band (the rectangle has scanlines in * the y1 to y2 area spanned by the band), then the rectangle may be broken * down into two or more smaller rectangles stacked one atop the other. * * ----------- ----------- * | | | | band 0 * | | -------- ----------- -------- * | | | | in y-x banded | | | | band 1 * | | | | form is | | | | * ----------- | | ----------- -------- * | | | | band 2 * -------- -------- * * An added constraint on the rectangles is that they must cover as much * horizontal area as possible: no two rectangles within a band are allowed * to touch. * * Whenever possible, bands will be merged together to cover a greater vertical * distance (and thus reduce the number of rectangles). Two bands can be merged * only if the bottom of one touches the top of the other and they have * rectangles in the same places (of the same width, of course). * * Adam de Boor wrote most of the original region code. Joel McCormack * substantially modified or rewrote most of the core arithmetic routines, * and added RegionValidate in order to support several speed improvements * to miValidateTree. Bob Scheifler changed the representation to be more * compact when empty or a single rectangle, and did a bunch of gratuitous * reformatting. */ /* true iff two Boxes overlap */ #define EXTENTCHECK(r1,r2) \ (!( ((r1)->x2 <= (r2)->x1) || \ ((r1)->x1 >= (r2)->x2) || \ ((r1)->y2 <= (r2)->y1) || \ ((r1)->y1 >= (r2)->y2) ) ) /* true iff (x,y) is in Box */ #define INBOX(r,x,y) \ ( ((r)->x2 > x) && \ ((r)->x1 <= x) && \ ((r)->y2 > y) && \ ((r)->y1 <= y) ) /* true iff Box r1 contains Box r2 */ #define SUBSUMES(r1,r2) \ ( ((r1)->x1 <= (r2)->x1) && \ ((r1)->x2 >= (r2)->x2) && \ ((r1)->y1 <= (r2)->y1) && \ ((r1)->y2 >= (r2)->y2) ) #define xfreeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data) #define RECTALLOC_BAIL(pReg,n,bail) \ if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \ if (!RegionRectAlloc(pReg, n)) { goto bail; } #define RECTALLOC(pReg,n) \ if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \ if (!RegionRectAlloc(pReg, n)) { return FALSE; } #define ADDRECT(pNextRect,nx1,ny1,nx2,ny2) \ { \ pNextRect->x1 = nx1; \ pNextRect->y1 = ny1; \ pNextRect->x2 = nx2; \ pNextRect->y2 = ny2; \ pNextRect++; \ } #define NEWRECT(pReg,pNextRect,nx1,ny1,nx2,ny2) \ { \ if (!(pReg)->data || ((pReg)->data->numRects == (pReg)->data->size))\ { \ if (!RegionRectAlloc(pReg, 1)) \ return FALSE; \ pNextRect = RegionTop(pReg); \ } \ ADDRECT(pNextRect,nx1,ny1,nx2,ny2); \ pReg->data->numRects++; \ assert(pReg->data->numRects<=pReg->data->size); \ } #define DOWNSIZE(reg,numRects) \ if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \ { \ size_t NewSize = RegionSizeof(numRects); \ RegDataPtr NewData = \ (NewSize > 0) ? realloc((reg)->data, NewSize) : NULL ; \ if (NewData) \ { \ NewData->size = (numRects); \ (reg)->data = NewData; \ } \ } BoxRec RegionEmptyBox = { 0, 0, 0, 0 }; RegDataRec RegionEmptyData = { 0, 0 }; RegDataRec RegionBrokenData = { 0, 0 }; static RegionRec RegionBrokenRegion = { {0, 0, 0, 0}, &RegionBrokenData }; void InitRegions(void) { pixman_region_set_static_pointers(&RegionEmptyBox, &RegionEmptyData, &RegionBrokenData); } /***************************************************************** * RegionCreate(rect, size) * This routine does a simple malloc to make a structure of * REGION of "size" number of rectangles. *****************************************************************/ RegionPtr RegionCreate(BoxPtr rect, int size) { RegionPtr pReg; pReg = (RegionPtr) malloc(sizeof(RegionRec)); if (!pReg) return &RegionBrokenRegion; RegionInit(pReg, rect, size); return pReg; } void RegionDestroy(RegionPtr pReg) { pixman_region_fini(pReg); if (pReg != &RegionBrokenRegion) free(pReg); } RegionPtr RegionDuplicate(RegionPtr pOld) { RegionPtr pNew; pNew = RegionCreate(&pOld->extents, 0); if (!pNew) return NULL; if (!RegionCopy(pNew, pOld)) { RegionDestroy(pNew); return NULL; } return pNew; } void RegionPrint(RegionPtr rgn) { int num, size; int i; BoxPtr rects; num = RegionNumRects(rgn); size = RegionSize(rgn); rects = RegionRects(rgn); ErrorF("[mi] num: %d size: %d\n", num, size); ErrorF("[mi] extents: %d %d %d %d\n", rgn->extents.x1, rgn->extents.y1, rgn->extents.x2, rgn->extents.y2); for (i = 0; i < num; i++) ErrorF("[mi] %d %d %d %d \n", rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2); ErrorF("[mi] \n"); } #ifdef DEBUG Bool RegionIsValid(RegionPtr reg) { int i, numRects; if ((reg->extents.x1 > reg->extents.x2) || (reg->extents.y1 > reg->extents.y2)) return FALSE; numRects = RegionNumRects(reg); if (!numRects) return ((reg->extents.x1 == reg->extents.x2) && (reg->extents.y1 == reg->extents.y2) && (reg->data->size || (reg->data == &RegionEmptyData))); else if (numRects == 1) return !reg->data; else { BoxPtr pboxP, pboxN; BoxRec box; pboxP = RegionRects(reg); box = *pboxP; box.y2 = pboxP[numRects - 1].y2; pboxN = pboxP + 1; for (i = numRects; --i > 0; pboxP++, pboxN++) { if ((pboxN->x1 >= pboxN->x2) || (pboxN->y1 >= pboxN->y2)) return FALSE; if (pboxN->x1 < box.x1) box.x1 = pboxN->x1; if (pboxN->x2 > box.x2) box.x2 = pboxN->x2; if ((pboxN->y1 < pboxP->y1) || ((pboxN->y1 == pboxP->y1) && ((pboxN->x1 < pboxP->x2) || (pboxN->y2 != pboxP->y2)))) return FALSE; } return ((box.x1 == reg->extents.x1) && (box.x2 == reg->extents.x2) && (box.y1 == reg->extents.y1) && (box.y2 == reg->extents.y2)); } } #endif /* DEBUG */ Bool RegionBreak(RegionPtr pReg) { xfreeData(pReg); pReg->extents = RegionEmptyBox; pReg->data = &RegionBrokenData; return FALSE; } Bool RegionRectAlloc(RegionPtr pRgn, int n) { RegDataPtr data; size_t rgnSize; if (!pRgn->data) { n++; rgnSize = RegionSizeof(n); pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL; if (!pRgn->data) return RegionBreak(pRgn); pRgn->data->numRects = 1; *RegionBoxptr(pRgn) = pRgn->extents; } else if (!pRgn->data->size) { rgnSize = RegionSizeof(n); pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL; if (!pRgn->data) return RegionBreak(pRgn); pRgn->data->numRects = 0; } else { if (n == 1) { n = pRgn->data->numRects; if (n > 500) /* XXX pick numbers out of a hat */ n = 250; } n += pRgn->data->numRects; rgnSize = RegionSizeof(n); data = (rgnSize > 0) ? realloc(pRgn->data, rgnSize) : NULL; if (!data) return RegionBreak(pRgn); pRgn->data = data; } pRgn->data->size = n; return TRUE; } /*====================================================================== * Generic Region Operator *====================================================================*/ /*- *----------------------------------------------------------------------- * RegionCoalesce -- * Attempt to merge the boxes in the current band with those in the * previous one. We are guaranteed that the current band extends to * the end of the rects array. Used only by RegionOp. * * Results: * The new index for the previous band. * * Side Effects: * If coalescing takes place: * - rectangles in the previous band will have their y2 fields * altered. * - pReg->data->numRects will be decreased. * *----------------------------------------------------------------------- */ _X_INLINE static int RegionCoalesce(RegionPtr pReg, /* Region to coalesce */ int prevStart, /* Index of start of previous band */ int curStart) { /* Index of start of current band */ BoxPtr pPrevBox; /* Current box in previous band */ BoxPtr pCurBox; /* Current box in current band */ int numRects; /* Number rectangles in both bands */ int y2; /* Bottom of current band */ /* * Figure out how many rectangles are in the band. */ numRects = curStart - prevStart; assert(numRects == pReg->data->numRects - curStart); if (!numRects) return curStart; /* * The bands may only be coalesced if the bottom of the previous * matches the top scanline of the current. */ pPrevBox = RegionBox(pReg, prevStart); pCurBox = RegionBox(pReg, curStart); if (pPrevBox->y2 != pCurBox->y1) return curStart; /* * Make sure the bands have boxes in the same places. This * assumes that boxes have been added in such a way that they * cover the most area possible. I.e. two boxes in a band must * have some horizontal space between them. */ y2 = pCurBox->y2; do { if ((pPrevBox->x1 != pCurBox->x1) || (pPrevBox->x2 != pCurBox->x2)) { return curStart; } pPrevBox++; pCurBox++; numRects--; } while (numRects); /* * The bands may be merged, so set the bottom y of each box * in the previous band to the bottom y of the current band. */ numRects = curStart - prevStart; pReg->data->numRects -= numRects; do { pPrevBox--; pPrevBox->y2 = y2; numRects--; } while (numRects); return prevStart; } /* Quicky macro to avoid trivial reject procedure calls to RegionCoalesce */ #define Coalesce(newReg, prevBand, curBand) \ if (curBand - prevBand == newReg->data->numRects - curBand) { \ prevBand = RegionCoalesce(newReg, prevBand, curBand); \ } else { \ prevBand = curBand; \ } /*- *----------------------------------------------------------------------- * RegionAppendNonO -- * Handle a non-overlapping band for the union and subtract operations. * Just adds the (top/bottom-clipped) rectangles into the region. * Doesn't have to check for subsumption or anything. * * Results: * None. * * Side Effects: * pReg->data->numRects is incremented and the rectangles overwritten * with the rectangles we're passed. * *----------------------------------------------------------------------- */ _X_INLINE static Bool RegionAppendNonO(RegionPtr pReg, BoxPtr r, BoxPtr rEnd, int y1, int y2) { BoxPtr pNextRect; int newRects; newRects = rEnd - r; assert(y1 < y2); assert(newRects != 0); /* Make sure we have enough space for all rectangles to be added */ RECTALLOC(pReg, newRects); pNextRect = RegionTop(pReg); pReg->data->numRects += newRects; do { assert(r->x1 < r->x2); ADDRECT(pNextRect, r->x1, y1, r->x2, y2); r++; } while (r != rEnd); return TRUE; } #define FindBand(r, rBandEnd, rEnd, ry1) \ { \ ry1 = r->y1; \ rBandEnd = r+1; \ while ((rBandEnd != rEnd) && (rBandEnd->y1 == ry1)) { \ rBandEnd++; \ } \ } #define AppendRegions(newReg, r, rEnd) \ { \ int newRects; \ if ((newRects = rEnd - r)) { \ RECTALLOC(newReg, newRects); \ memmove((char *)RegionTop(newReg),(char *)r, \ newRects * sizeof(BoxRec)); \ newReg->data->numRects += newRects; \ } \ } /*- *----------------------------------------------------------------------- * RegionOp -- * Apply an operation to two regions. Called by RegionUnion, RegionInverse, * RegionSubtract, RegionIntersect.... Both regions MUST have at least one * rectangle, and cannot be the same object. * * Results: * TRUE if successful. * * Side Effects: * The new region is overwritten. * pOverlap set to TRUE if overlapFunc ever returns TRUE. * * Notes: * The idea behind this function is to view the two regions as sets. * Together they cover a rectangle of area that this function divides * into horizontal bands where points are covered only by one region * or by both. For the first case, the nonOverlapFunc is called with * each the band and the band's upper and lower extents. For the * second, the overlapFunc is called to process the entire band. It * is responsible for clipping the rectangles in the band, though * this function provides the boundaries. * At the end of each band, the new region is coalesced, if possible, * to reduce the number of rectangles in the region. * *----------------------------------------------------------------------- */ typedef Bool (*OverlapProcPtr) (RegionPtr pReg, BoxPtr r1, BoxPtr r1End, BoxPtr r2, BoxPtr r2End, short y1, short y2, Bool *pOverlap); static Bool RegionOp(RegionPtr newReg, /* Place to store result */ RegionPtr reg1, /* First region in operation */ RegionPtr reg2, /* 2d region in operation */ OverlapProcPtr overlapFunc, /* Function to call for over- * lapping bands */ Bool appendNon1, /* Append non-overlapping bands */ /* in region 1 ? */ Bool appendNon2, /* Append non-overlapping bands */ /* in region 2 ? */ Bool *pOverlap) { BoxPtr r1; /* Pointer into first region */ BoxPtr r2; /* Pointer into 2d region */ BoxPtr r1End; /* End of 1st region */ BoxPtr r2End; /* End of 2d region */ short ybot; /* Bottom of intersection */ short ytop; /* Top of intersection */ RegDataPtr oldData; /* Old data for newReg */ int prevBand; /* Index of start of * previous band in newReg */ int curBand; /* Index of start of current * band in newReg */ BoxPtr r1BandEnd; /* End of current band in r1 */ BoxPtr r2BandEnd; /* End of current band in r2 */ short top; /* Top of non-overlapping band */ short bot; /* Bottom of non-overlapping band */ int r1y1; /* Temps for r1->y1 and r2->y1 */ int r2y1; int newSize; int numRects; /* * Break any region computed from a broken region */ if (RegionNar(reg1) || RegionNar(reg2)) return RegionBreak(newReg); /* * Initialization: * set r1, r2, r1End and r2End appropriately, save the rectangles * of the destination region until the end in case it's one of * the two source regions, then mark the "new" region empty, allocating * another array of rectangles for it to use. */ r1 = RegionRects(reg1); newSize = RegionNumRects(reg1); r1End = r1 + newSize; numRects = RegionNumRects(reg2); r2 = RegionRects(reg2); r2End = r2 + numRects; assert(r1 != r1End); assert(r2 != r2End); oldData = NULL; if (((newReg == reg1) && (newSize > 1)) || ((newReg == reg2) && (numRects > 1))) { oldData = newReg->data; newReg->data = &RegionEmptyData; } /* guess at new size */ if (numRects > newSize) newSize = numRects; newSize <<= 1; if (!newReg->data) newReg->data = &RegionEmptyData; else if (newReg->data->size) newReg->data->numRects = 0; if (newSize > newReg->data->size) if (!RegionRectAlloc(newReg, newSize)) return FALSE; /* * Initialize ybot. * In the upcoming loop, ybot and ytop serve different functions depending * on whether the band being handled is an overlapping or non-overlapping * band. * In the case of a non-overlapping band (only one of the regions * has points in the band), ybot is the bottom of the most recent * intersection and thus clips the top of the rectangles in that band. * ytop is the top of the next intersection between the two regions and * serves to clip the bottom of the rectangles in the current band. * For an overlapping band (where the two regions intersect), ytop clips * the top of the rectangles of both regions and ybot clips the bottoms. */ ybot = min(r1->y1, r2->y1); /* * prevBand serves to mark the start of the previous band so rectangles * can be coalesced into larger rectangles. qv. RegionCoalesce, above. * In the beginning, there is no previous band, so prevBand == curBand * (curBand is set later on, of course, but the first band will always * start at index 0). prevBand and curBand must be indices because of * the possible expansion, and resultant moving, of the new region's * array of rectangles. */ prevBand = 0; do { /* * This algorithm proceeds one source-band (as opposed to a * destination band, which is determined by where the two regions * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the * rectangle after the last one in the current band for their * respective regions. */ assert(r1 != r1End); assert(r2 != r2End); FindBand(r1, r1BandEnd, r1End, r1y1); FindBand(r2, r2BandEnd, r2End, r2y1); /* * First handle the band that doesn't intersect, if any. * * Note that attention is restricted to one band in the * non-intersecting region at once, so if a region has n * bands between the current position and the next place it overlaps * the other, this entire loop will be passed through n times. */ if (r1y1 < r2y1) { if (appendNon1) { top = max(r1y1, ybot); bot = min(r1->y2, r2y1); if (top != bot) { curBand = newReg->data->numRects; RegionAppendNonO(newReg, r1, r1BandEnd, top, bot); Coalesce(newReg, prevBand, curBand); } } ytop = r2y1; } else if (r2y1 < r1y1) { if (appendNon2) { top = max(r2y1, ybot); bot = min(r2->y2, r1y1); if (top != bot) { curBand = newReg->data->numRects; RegionAppendNonO(newReg, r2, r2BandEnd, top, bot); Coalesce(newReg, prevBand, curBand); } } ytop = r1y1; } else { ytop = r1y1; } /* * Now see if we've hit an intersecting band. The two bands only * intersect if ybot > ytop */ ybot = min(r1->y2, r2->y2); if (ybot > ytop) { curBand = newReg->data->numRects; (*overlapFunc) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot, pOverlap); Coalesce(newReg, prevBand, curBand); } /* * If we've finished with a band (y2 == ybot) we skip forward * in the region to the next band. */ if (r1->y2 == ybot) r1 = r1BandEnd; if (r2->y2 == ybot) r2 = r2BandEnd; } while (r1 != r1End && r2 != r2End); /* * Deal with whichever region (if any) still has rectangles left. * * We only need to worry about banding and coalescing for the very first * band left. After that, we can just group all remaining boxes, * regardless of how many bands, into one final append to the list. */ if ((r1 != r1End) && appendNon1) { /* Do first nonOverlap1Func call, which may be able to coalesce */ FindBand(r1, r1BandEnd, r1End, r1y1); curBand = newReg->data->numRects; RegionAppendNonO(newReg, r1, r1BandEnd, max(r1y1, ybot), r1->y2); Coalesce(newReg, prevBand, curBand); /* Just append the rest of the boxes */ AppendRegions(newReg, r1BandEnd, r1End); } else if ((r2 != r2End) && appendNon2) { /* Do first nonOverlap2Func call, which may be able to coalesce */ FindBand(r2, r2BandEnd, r2End, r2y1); curBand = newReg->data->numRects; RegionAppendNonO(newReg, r2, r2BandEnd, max(r2y1, ybot), r2->y2); Coalesce(newReg, prevBand, curBand); /* Append rest of boxes */ AppendRegions(newReg, r2BandEnd, r2End); } free(oldData); if (!(numRects = newReg->data->numRects)) { xfreeData(newReg); newReg->data = &RegionEmptyData; } else if (numRects == 1) { newReg->extents = *RegionBoxptr(newReg); xfreeData(newReg); newReg->data = NULL; } else { DOWNSIZE(newReg, numRects); } return TRUE; } /*- *----------------------------------------------------------------------- * RegionSetExtents -- * Reset the extents of a region to what they should be. Called by * Subtract and Intersect as they can't figure it out along the * way or do so easily, as Union can. * * Results: * None. * * Side Effects: * The region's 'extents' structure is overwritten. * *----------------------------------------------------------------------- */ static void RegionSetExtents(RegionPtr pReg) { BoxPtr pBox, pBoxEnd; if (!pReg->data) return; if (!pReg->data->size) { pReg->extents.x2 = pReg->extents.x1; pReg->extents.y2 = pReg->extents.y1; return; } pBox = RegionBoxptr(pReg); pBoxEnd = RegionEnd(pReg); /* * Since pBox is the first rectangle in the region, it must have the * smallest y1 and since pBoxEnd is the last rectangle in the region, * it must have the largest y2, because of banding. Initialize x1 and * x2 from pBox and pBoxEnd, resp., as good things to initialize them * to... */ pReg->extents.x1 = pBox->x1; pReg->extents.y1 = pBox->y1; pReg->extents.x2 = pBoxEnd->x2; pReg->extents.y2 = pBoxEnd->y2; assert(pReg->extents.y1 < pReg->extents.y2); while (pBox <= pBoxEnd) { if (pBox->x1 < pReg->extents.x1) pReg->extents.x1 = pBox->x1; if (pBox->x2 > pReg->extents.x2) pReg->extents.x2 = pBox->x2; pBox++; }; assert(pReg->extents.x1 < pReg->extents.x2); } /*====================================================================== * Region Intersection *====================================================================*/ /*- *----------------------------------------------------------------------- * RegionIntersectO -- * Handle an overlapping band for RegionIntersect. * * Results: * TRUE if successful. * * Side Effects: * Rectangles may be added to the region. * *----------------------------------------------------------------------- */ /*ARGSUSED*/ #define MERGERECT(r) \ { \ if (r->x1 <= x2) { \ /* Merge with current rectangle */ \ if (r->x1 < x2) *pOverlap = TRUE; \ if (x2 < r->x2) x2 = r->x2; \ } else { \ /* Add current rectangle, start new one */ \ NEWRECT(pReg, pNextRect, x1, y1, x2, y2); \ x1 = r->x1; \ x2 = r->x2; \ } \ r++; \ } /*====================================================================== * Region Union *====================================================================*/ /*- *----------------------------------------------------------------------- * RegionUnionO -- * Handle an overlapping band for the union operation. Picks the * left-most rectangle each time and merges it into the region. * * Results: * TRUE if successful. * * Side Effects: * pReg is overwritten. * pOverlap is set to TRUE if any boxes overlap. * *----------------------------------------------------------------------- */ static Bool RegionUnionO(RegionPtr pReg, BoxPtr r1, BoxPtr r1End, BoxPtr r2, BoxPtr r2End, short y1, short y2, Bool *pOverlap) { BoxPtr pNextRect; int x1; /* left and right side of current union */ int x2; assert(y1 < y2); assert(r1 != r1End && r2 != r2End); pNextRect = RegionTop(pReg); /* Start off current rectangle */ if (r1->x1 < r2->x1) { x1 = r1->x1; x2 = r1->x2; r1++; } else { x1 = r2->x1; x2 = r2->x2; r2++; } while (r1 != r1End && r2 != r2End) { if (r1->x1 < r2->x1) MERGERECT(r1) else MERGERECT(r2); } /* Finish off whoever (if any) is left */ if (r1 != r1End) { do { MERGERECT(r1); } while (r1 != r1End); } else if (r2 != r2End) { do { MERGERECT(r2); } while (r2 != r2End); } /* Add current rectangle */ NEWRECT(pReg, pNextRect, x1, y1, x2, y2); return TRUE; } /*====================================================================== * Batch Rectangle Union *====================================================================*/ /*- *----------------------------------------------------------------------- * RegionAppend -- * * "Append" the rgn rectangles onto the end of dstrgn, maintaining * knowledge of YX-banding when it's easy. Otherwise, dstrgn just * becomes a non-y-x-banded random collection of rectangles, and not * yet a true region. After a sequence of appends, the caller must * call RegionValidate to ensure that a valid region is constructed. * * Results: * TRUE if successful. * * Side Effects: * dstrgn is modified if rgn has rectangles. * */ Bool RegionAppend(RegionPtr dstrgn, RegionPtr rgn) { int numRects, dnumRects, size; BoxPtr new, old; Bool prepend; if (RegionNar(rgn)) return RegionBreak(dstrgn); if (!rgn->data && (dstrgn->data == &RegionEmptyData)) { dstrgn->extents = rgn->extents; dstrgn->data = NULL; return TRUE; } numRects = RegionNumRects(rgn); if (!numRects) return TRUE; prepend = FALSE; size = numRects; dnumRects = RegionNumRects(dstrgn); if (!dnumRects && (size < 200)) size = 200; /* XXX pick numbers out of a hat */ RECTALLOC(dstrgn, size); old = RegionRects(rgn); if (!dnumRects) dstrgn->extents = rgn->extents; else if (dstrgn->extents.x2 > dstrgn->extents.x1) { BoxPtr first, last; first = old; last = RegionBoxptr(dstrgn) + (dnumRects - 1); if ((first->y1 > last->y2) || ((first->y1 == last->y1) && (first->y2 == last->y2) && (first->x1 > last->x2))) { if (rgn->extents.x1 < dstrgn->extents.x1) dstrgn->extents.x1 = rgn->extents.x1; if (rgn->extents.x2 > dstrgn->extents.x2) dstrgn->extents.x2 = rgn->extents.x2; dstrgn->extents.y2 = rgn->extents.y2; } else { first = RegionBoxptr(dstrgn); last = old + (numRects - 1); if ((first->y1 > last->y2) || ((first->y1 == last->y1) && (first->y2 == last->y2) && (first->x1 > last->x2))) { prepend = TRUE; if (rgn->extents.x1 < dstrgn->extents.x1) dstrgn->extents.x1 = rgn->extents.x1; if (rgn->extents.x2 > dstrgn->extents.x2) dstrgn->extents.x2 = rgn->extents.x2; dstrgn->extents.y1 = rgn->extents.y1; } else dstrgn->extents.x2 = dstrgn->extents.x1; } } if (prepend) { new = RegionBox(dstrgn, numRects); if (dnumRects == 1) *new = *RegionBoxptr(dstrgn); else memmove((char *) new, (char *) RegionBoxptr(dstrgn), dnumRects * sizeof(BoxRec)); new = RegionBoxptr(dstrgn); } else new = RegionBoxptr(dstrgn) + dnumRects; if (numRects == 1) *new = *old; else memmove((char *) new, (char *) old, numRects * sizeof(BoxRec)); dstrgn->data->numRects += numRects; return TRUE; } #define ExchangeRects(a, b) \ { \ BoxRec t; \ t = rects[a]; \ rects[a] = rects[b]; \ rects[b] = t; \ } static void QuickSortRects(BoxRec rects[], int numRects) { int y1; int x1; int i, j; BoxPtr r; /* Always called with numRects > 1 */ do { if (numRects == 2) { if (rects[0].y1 > rects[1].y1 || (rects[0].y1 == rects[1].y1 && rects[0].x1 > rects[1].x1)) ExchangeRects(0, 1); return; } /* Choose partition element, stick in location 0 */ ExchangeRects(0, numRects >> 1); y1 = rects[0].y1; x1 = rects[0].x1; /* Partition array */ i = 0; j = numRects; do { r = &(rects[i]); do { r++; i++; } while (i != numRects && (r->y1 < y1 || (r->y1 == y1 && r->x1 < x1))); r = &(rects[j]); do { r--; j--; } while (y1 < r->y1 || (y1 == r->y1 && x1 < r->x1)); if (i < j) ExchangeRects(i, j); } while (i < j); /* Move partition element back to middle */ ExchangeRects(0, j); /* Recurse */ if (numRects - j - 1 > 1) QuickSortRects(&rects[j + 1], numRects - j - 1); numRects = j; } while (numRects > 1); } /*- *----------------------------------------------------------------------- * RegionValidate -- * * Take a ``region'' which is a non-y-x-banded random collection of * rectangles, and compute a nice region which is the union of all the * rectangles. * * Results: * TRUE if successful. * * Side Effects: * The passed-in ``region'' may be modified. * pOverlap set to TRUE if any retangles overlapped, else FALSE; * * Strategy: * Step 1. Sort the rectangles into ascending order with primary key y1 * and secondary key x1. * * Step 2. Split the rectangles into the minimum number of proper y-x * banded regions. This may require horizontally merging * rectangles, and vertically coalescing bands. With any luck, * this step in an identity tranformation (ala the Box widget), * or a coalescing into 1 box (ala Menus). * * Step 3. Merge the separate regions down to a single region by calling * Union. Maximize the work each Union call does by using * a binary merge. * *----------------------------------------------------------------------- */ Bool RegionValidate(RegionPtr badreg, Bool *pOverlap) { /* Descriptor for regions under construction in Step 2. */ typedef struct { RegionRec reg; int prevBand; int curBand; } RegionInfo; int numRects; /* Original numRects for badreg */ RegionInfo *ri; /* Array of current regions */ int numRI; /* Number of entries used in ri */ int sizeRI; /* Number of entries available in ri */ int i; /* Index into rects */ int j; /* Index into ri */ RegionInfo *rit; /* &ri[j] */ RegionPtr reg; /* ri[j].reg */ BoxPtr box; /* Current box in rects */ BoxPtr riBox; /* Last box in ri[j].reg */ RegionPtr hreg; /* ri[j_half].reg */ Bool ret = TRUE; *pOverlap = FALSE; if (!badreg->data) { good(badreg); return TRUE; } numRects = badreg->data->numRects; if (!numRects) { if (RegionNar(badreg)) return FALSE; good(badreg); return TRUE; } if (badreg->extents.x1 < badreg->extents.x2) { if ((numRects) == 1) { xfreeData(badreg); badreg->data = (RegDataPtr) NULL; } else { DOWNSIZE(badreg, numRects); } good(badreg); return TRUE; } /* Step 1: Sort the rects array into ascending (y1, x1) order */ QuickSortRects(RegionBoxptr(badreg), numRects); /* Step 2: Scatter the sorted array into the minimum number of regions */ /* Set up the first region to be the first rectangle in badreg */ /* Note that step 2 code will never overflow the ri[0].reg rects array */ ri = (RegionInfo *) malloc(4 * sizeof(RegionInfo)); if (!ri) return RegionBreak(badreg); sizeRI = 4; numRI = 1; ri[0].prevBand = 0; ri[0].curBand = 0; ri[0].reg = *badreg; box = RegionBoxptr(&ri[0].reg); ri[0].reg.extents = *box; ri[0].reg.data->numRects = 1; /* Now scatter rectangles into the minimum set of valid regions. If the next rectangle to be added to a region would force an existing rectangle in the region to be split up in order to maintain y-x banding, just forget it. Try the next region. If it doesn't fit cleanly into any region, make a new one. */ for (i = numRects; --i > 0;) { box++; /* Look for a region to append box to */ for (j = numRI, rit = ri; --j >= 0; rit++) { reg = &rit->reg; riBox = RegionEnd(reg); if (box->y1 == riBox->y1 && box->y2 == riBox->y2) { /* box is in same band as riBox. Merge or append it */ if (box->x1 <= riBox->x2) { /* Merge it with riBox */ if (box->x1 < riBox->x2) *pOverlap = TRUE; if (box->x2 > riBox->x2) riBox->x2 = box->x2; } else { RECTALLOC_BAIL(reg, 1, bail); *RegionTop(reg) = *box; reg->data->numRects++; } goto NextRect; /* So sue me */ } else if (box->y1 >= riBox->y2) { /* Put box into new band */ if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2; if (reg->extents.x1 > box->x1) reg->extents.x1 = box->x1; Coalesce(reg, rit->prevBand, rit->curBand); rit->curBand = reg->data->numRects; RECTALLOC_BAIL(reg, 1, bail); *RegionTop(reg) = *box; reg->data->numRects++; goto NextRect; } /* Well, this region was inappropriate. Try the next one. */ } /* for j */ /* Uh-oh. No regions were appropriate. Create a new one. */ if (sizeRI == numRI) { /* Oops, allocate space for new region information */ sizeRI <<= 1; rit = (RegionInfo *) reallocarray(ri, sizeRI, sizeof(RegionInfo)); if (!rit) goto bail; ri = rit; rit = &ri[numRI]; } numRI++; rit->prevBand = 0; rit->curBand = 0; rit->reg.extents = *box; rit->reg.data = NULL; if (!RegionRectAlloc(&rit->reg, (i + numRI) / numRI)) /* MUST force allocation */ goto bail; NextRect:; } /* for i */ /* Make a final pass over each region in order to Coalesce and set extents.x2 and extents.y2 */ for (j = numRI, rit = ri; --j >= 0; rit++) { reg = &rit->reg; riBox = RegionEnd(reg); reg->extents.y2 = riBox->y2; if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2; Coalesce(reg, rit->prevBand, rit->curBand); if (reg->data->numRects == 1) { /* keep unions happy below */ xfreeData(reg); reg->data = NULL; } } /* Step 3: Union all regions into a single region */ while (numRI > 1) { int half = numRI / 2; for (j = numRI & 1; j < (half + (numRI & 1)); j++) { reg = &ri[j].reg; hreg = &ri[j + half].reg; if (!RegionOp(reg, reg, hreg, RegionUnionO, TRUE, TRUE, pOverlap)) ret = FALSE; if (hreg->extents.x1 < reg->extents.x1) reg->extents.x1 = hreg->extents.x1; if (hreg->extents.y1 < reg->extents.y1) reg->extents.y1 = hreg->extents.y1; if (hreg->extents.x2 > reg->extents.x2) reg->extents.x2 = hreg->extents.x2; if (hreg->extents.y2 > reg->extents.y2) reg->extents.y2 = hreg->extents.y2; xfreeData(hreg); } numRI -= half; } *badreg = ri[0].reg; free(ri); good(badreg); return ret; bail: for (i = 0; i < numRI; i++) xfreeData(&ri[i].reg); free(ri); return RegionBreak(badreg); } RegionPtr RegionFromRects(int nrects, xRectangle *prect, int ctype) { RegionPtr pRgn; size_t rgnSize; RegDataPtr pData; BoxPtr pBox; int i; int x1, y1, x2, y2; pRgn = RegionCreate(NullBox, 0); if (RegionNar(pRgn)) return pRgn; if (!nrects) return pRgn; if (nrects == 1) { x1 = prect->x; y1 = prect->y; if ((x2 = x1 + (int) prect->width) > MAXSHORT) x2 = MAXSHORT; if ((y2 = y1 + (int) prect->height) > MAXSHORT) y2 = MAXSHORT; if (x1 != x2 && y1 != y2) { pRgn->extents.x1 = x1; pRgn->extents.y1 = y1; pRgn->extents.x2 = x2; pRgn->extents.y2 = y2; pRgn->data = NULL; } return pRgn; } rgnSize = RegionSizeof(nrects); pData = (rgnSize > 0) ? malloc(rgnSize) : NULL; if (!pData) { RegionBreak(pRgn); return pRgn; } pBox = (BoxPtr) (pData + 1); for (i = nrects; --i >= 0; prect++) { x1 = prect->x; y1 = prect->y; if ((x2 = x1 + (int) prect->width) > MAXSHORT) x2 = MAXSHORT; if ((y2 = y1 + (int) prect->height) > MAXSHORT) y2 = MAXSHORT; if (x1 != x2 && y1 != y2) { pBox->x1 = x1; pBox->y1 = y1; pBox->x2 = x2; pBox->y2 = y2; pBox++; } } if (pBox != (BoxPtr) (pData + 1)) { pData->size = nrects; pData->numRects = pBox - (BoxPtr) (pData + 1); pRgn->data = pData; if (ctype != CT_YXBANDED) { Bool overlap; /* result ignored */ pRgn->extents.x1 = pRgn->extents.x2 = 0; RegionValidate(pRgn, &overlap); } else RegionSetExtents(pRgn); good(pRgn); } else { free(pData); } return pRgn; } xorg-server-1.20.13/dix/registry.c0000644000175000017500000002121314100573756013671 00000000000000/************************************************************ Author: Eamon Walsh Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that this permission notice appear in supporting documentation. This permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ********************************************************/ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include "resource.h" #include "registry.h" #define BASE_SIZE 16 #ifdef X_REGISTRY_REQUEST #define CORE "X11" #define FILENAME SERVER_MISC_CONFIG_PATH "/protocol.txt" #define PROT_COMMENT '#' #define PROT_REQUEST 'R' #define PROT_EVENT 'V' #define PROT_ERROR 'E' static FILE *fh; static char ***requests, **events, **errors; static unsigned nmajor, *nminor, nevent, nerror; #endif #ifdef X_REGISTRY_RESOURCE static const char **resources; static unsigned nresource; #endif #if defined(X_REGISTRY_RESOURCE) || defined(X_REGISTRY_REQUEST) /* * File parsing routines */ static int double_size(void *p, unsigned n, unsigned size) { char **ptr = (char **) p; unsigned s, f; if (n) { s = n * size; n *= 2 * size; f = n; } else { s = 0; n = f = BASE_SIZE * size; } *ptr = realloc(*ptr, n); if (!*ptr) { dixResetRegistry(); return FALSE; } memset(*ptr + s, 0, f - s); return TRUE; } #endif #ifdef X_REGISTRY_REQUEST /* * Request/event/error registry functions */ static void RegisterRequestName(unsigned major, unsigned minor, char *name) { while (major >= nmajor) { if (!double_size(&requests, nmajor, sizeof(char **))) return; if (!double_size(&nminor, nmajor, sizeof(unsigned))) return; nmajor = nmajor ? nmajor * 2 : BASE_SIZE; } while (minor >= nminor[major]) { if (!double_size(requests + major, nminor[major], sizeof(char *))) return; nminor[major] = nminor[major] ? nminor[major] * 2 : BASE_SIZE; } free(requests[major][minor]); requests[major][minor] = name; } static void RegisterEventName(unsigned event, char *name) { while (event >= nevent) { if (!double_size(&events, nevent, sizeof(char *))) return; nevent = nevent ? nevent * 2 : BASE_SIZE; } free(events[event]); events[event] = name; } static void RegisterErrorName(unsigned error, char *name) { while (error >= nerror) { if (!double_size(&errors, nerror, sizeof(char *))) return; nerror = nerror ? nerror * 2 : BASE_SIZE; } free(errors[error]); errors[error] = name; } void RegisterExtensionNames(ExtensionEntry * extEntry) { char buf[256], *lineobj, *ptr; unsigned offset; if (fh == NULL) return; rewind(fh); while (fgets(buf, sizeof(buf), fh)) { lineobj = NULL; ptr = strchr(buf, '\n'); if (ptr) *ptr = 0; /* Check for comments or empty lines */ switch (buf[0]) { case PROT_REQUEST: case PROT_EVENT: case PROT_ERROR: break; case PROT_COMMENT: case '\0': continue; default: goto invalid; } /* Check for space character in the fifth position */ ptr = strchr(buf, ' '); if (!ptr || ptr != buf + 4) goto invalid; /* Duplicate the string after the space */ lineobj = strdup(ptr + 1); if (!lineobj) continue; /* Check for a colon somewhere on the line */ ptr = strchr(buf, ':'); if (!ptr) goto invalid; /* Compare the part before colon with the target extension name */ *ptr = 0; if (strcmp(buf + 5, extEntry->name)) goto skip; /* Get the opcode for the request, event, or error */ offset = strtol(buf + 1, &ptr, 10); if (offset == 0 && ptr == buf + 1) goto invalid; /* Save the strdup result in the registry */ switch (buf[0]) { case PROT_REQUEST: if (extEntry->base) RegisterRequestName(extEntry->base, offset, lineobj); else RegisterRequestName(offset, 0, lineobj); continue; case PROT_EVENT: RegisterEventName(extEntry->eventBase + offset, lineobj); continue; case PROT_ERROR: RegisterErrorName(extEntry->errorBase + offset, lineobj); continue; } invalid: LogMessage(X_WARNING, "Invalid line in " FILENAME ", skipping\n"); skip: free(lineobj); } } const char * LookupRequestName(int major, int minor) { if (major >= nmajor) return XREGISTRY_UNKNOWN; if (minor >= nminor[major]) return XREGISTRY_UNKNOWN; return requests[major][minor] ? requests[major][minor] : XREGISTRY_UNKNOWN; } const char * LookupMajorName(int major) { if (major < 128) { const char *retval; if (major >= nmajor) return XREGISTRY_UNKNOWN; if (0 >= nminor[major]) return XREGISTRY_UNKNOWN; retval = requests[major][0]; return retval ? retval + sizeof(CORE) : XREGISTRY_UNKNOWN; } else { ExtensionEntry *extEntry = GetExtensionEntry(major); return extEntry ? extEntry->name : XREGISTRY_UNKNOWN; } } const char * LookupEventName(int event) { event &= 127; if (event >= nevent) return XREGISTRY_UNKNOWN; return events[event] ? events[event] : XREGISTRY_UNKNOWN; } const char * LookupErrorName(int error) { if (error >= nerror) return XREGISTRY_UNKNOWN; return errors[error] ? errors[error] : XREGISTRY_UNKNOWN; } #endif /* X_REGISTRY_REQUEST */ #ifdef X_REGISTRY_RESOURCE /* * Resource registry functions */ void RegisterResourceName(RESTYPE resource, const char *name) { resource &= TypeMask; while (resource >= nresource) { if (!double_size(&resources, nresource, sizeof(char *))) return; nresource = nresource ? nresource * 2 : BASE_SIZE; } resources[resource] = name; } const char * LookupResourceName(RESTYPE resource) { resource &= TypeMask; if (resource >= nresource) return XREGISTRY_UNKNOWN; return resources[resource] ? resources[resource] : XREGISTRY_UNKNOWN; } #endif /* X_REGISTRY_RESOURCE */ void dixFreeRegistry(void) { #ifdef X_REGISTRY_REQUEST /* Free all memory */ while (nmajor--) { while (nminor[nmajor]) free(requests[nmajor][--nminor[nmajor]]); free(requests[nmajor]); } free(requests); free(nminor); while (nevent--) free(events[nevent]); free(events); while (nerror--) free(errors[nerror]); free(errors); requests = NULL; nminor = NULL; events = NULL; errors = NULL; nmajor = nevent = nerror = 0; #endif #ifdef X_REGISTRY_RESOURCE free(resources); resources = NULL; nresource = 0; #endif } void dixCloseRegistry(void) { #ifdef X_REGISTRY_REQUEST if (fh) { fclose(fh); fh = NULL; } #endif } /* * Setup and teardown */ void dixResetRegistry(void) { #ifdef X_REGISTRY_REQUEST ExtensionEntry extEntry = { .name = CORE }; #endif dixFreeRegistry(); #ifdef X_REGISTRY_REQUEST /* Open the protocol file */ fh = fopen(FILENAME, "r"); if (!fh) LogMessage(X_WARNING, "Failed to open protocol names file " FILENAME "\n"); /* Add the core protocol */ RegisterExtensionNames(&extEntry); #endif #ifdef X_REGISTRY_RESOURCE /* Add built-in resources */ RegisterResourceName(RT_NONE, "NONE"); RegisterResourceName(RT_WINDOW, "WINDOW"); RegisterResourceName(RT_PIXMAP, "PIXMAP"); RegisterResourceName(RT_GC, "GC"); RegisterResourceName(RT_FONT, "FONT"); RegisterResourceName(RT_CURSOR, "CURSOR"); RegisterResourceName(RT_COLORMAP, "COLORMAP"); RegisterResourceName(RT_CMAPENTRY, "COLORMAP ENTRY"); RegisterResourceName(RT_OTHERCLIENT, "OTHER CLIENT"); RegisterResourceName(RT_PASSIVEGRAB, "PASSIVE GRAB"); #endif } xorg-server-1.20.13/dix/resource.c0000644000175000017500000011520114100573756013651 00000000000000/************************************************************ Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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. ********************************************************/ /* The panoramix components contained the following notice */ /***************************************************************** Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Digital Equipment Corporation shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Digital Equipment Corporation. ******************************************************************/ /* XSERVER_DTRACE additions: * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* Routines to manage various kinds of resources: * * CreateNewResourceType, CreateNewResourceClass, InitClientResources, * FakeClientID, AddResource, FreeResource, FreeClientResources, * FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange */ /* * A resource ID is a 32 bit quantity, the upper 2 bits of which are * off-limits for client-visible resources. The next 8 bits are * used as client ID, and the low 22 bits come from the client. * A resource ID is "hashed" by extracting and xoring subfields * (varying with the size of the hash table). * * It is sometimes necessary for the server to create an ID that looks * like it belongs to a client. This ID, however, must not be one * the client actually can create, or we have the potential for conflict. * The 31st bit of the ID is reserved for the server's use for this * purpose. By setting CLIENT_ID(id) to the client, the SERVER_BIT to * 1, and an otherwise arbitrary ID in the low 22 bits, we can create a * resource "owned" by the client. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "misc.h" #include "os.h" #include "resource.h" #include "dixstruct.h" #include "opaque.h" #include "windowstr.h" #include "dixfont.h" #include "colormap.h" #include "inputstr.h" #include "dixevents.h" #include "dixgrabs.h" #include "cursor.h" #ifdef PANORAMIX #include "panoramiX.h" #include "panoramiXsrv.h" #endif #include "xace.h" #include #include "registry.h" #include "gcstruct.h" #ifdef XSERVER_DTRACE #include "probes.h" #define TypeNameString(t) LookupResourceName(t) #endif static void RebuildTable(int /*client */ ); #define SERVER_MINID 32 #define INITBUCKETS 64 #define INITHASHSIZE 6 #define MAXHASHSIZE 16 typedef struct _Resource { struct _Resource *next; XID id; RESTYPE type; void *value; } ResourceRec, *ResourcePtr; typedef struct _ClientResource { ResourcePtr *resources; int elements; int buckets; int hashsize; /* log(2)(buckets) */ XID fakeID; XID endFakeID; } ClientResourceRec; RESTYPE lastResourceType; static RESTYPE lastResourceClass; RESTYPE TypeMask; struct ResourceType { DeleteType deleteFunc; SizeType sizeFunc; FindTypeSubResources findSubResFunc; int errorValue; }; /** * Used by all resources that don't specify a function to calculate * resource size. Currently this is used for all resources with * insignificant memory usage. * * @see GetResourceTypeSizeFunc, SetResourceTypeSizeFunc * * @param[in] value Pointer to resource object. * * @param[in] id Resource ID for the object. * * @param[out] size Fill all fields to zero to indicate that size of * resource can't be determined. */ static void GetDefaultBytes(void *value, XID id, ResourceSizePtr size) { size->resourceSize = 0; size->pixmapRefSize = 0; size->refCnt = 1; } /** * Used by all resources that don't specify a function to iterate * through subresources. Currently this is used for all resources with * insignificant memory usage. * * @see FindSubResources, SetResourceTypeFindSubResFunc * * @param[in] value Pointer to resource object. * * @param[in] func Function to call for each subresource. * @param[out] cdata Pointer to opaque data. */ static void DefaultFindSubRes(void *value, FindAllRes func, void *cdata) { /* do nothing */ } /** * Calculate drawable size in bytes. Reference counting is not taken * into account. * * @param[in] drawable Pointer to a drawable. * * @return Estimate of total memory usage for the drawable. */ static unsigned long GetDrawableBytes(DrawablePtr drawable) { int bytes = 0; if (drawable) { int bytesPerPixel = drawable->bitsPerPixel >> 3; int numberOfPixels = drawable->width * drawable->height; bytes = numberOfPixels * bytesPerPixel; } return bytes; } /** * Calculate pixmap size in bytes. Reference counting is taken into * account. Any extra data attached by extensions and drivers is not * taken into account. The purpose of this function is to estimate * memory usage that can be attributed to single reference of the * pixmap. * * @param[in] value Pointer to a pixmap. * * @param[in] id Resource ID of pixmap. If the pixmap hasn't been * added as resource, just pass value->drawable.id. * * @param[out] size Estimate of memory usage attributed to a single * pixmap reference. */ static void GetPixmapBytes(void *value, XID id, ResourceSizePtr size) { PixmapPtr pixmap = value; size->resourceSize = 0; size->pixmapRefSize = 0; size->refCnt = pixmap->refcnt; if (pixmap && pixmap->refcnt) { DrawablePtr drawable = &pixmap->drawable; size->resourceSize = GetDrawableBytes(drawable); size->pixmapRefSize = size->resourceSize / pixmap->refcnt; } } /** * Calculate window size in bytes. The purpose of this function is to * estimate memory usage that can be attributed to all pixmap * references of the window. * * @param[in] value Pointer to a window. * * @param[in] id Resource ID of window. * * @param[out] size Estimate of memory usage attributed to a all * pixmap references of a window. */ static void GetWindowBytes(void *value, XID id, ResourceSizePtr size) { SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); ResourceSizeRec pixmapSize = { 0, 0, 0 }; WindowPtr window = value; /* Currently only pixmap bytes are reported to clients. */ size->resourceSize = 0; /* Calculate pixmap reference sizes. */ size->pixmapRefSize = 0; size->refCnt = 1; if (window->backgroundState == BackgroundPixmap) { PixmapPtr pixmap = window->background.pixmap; pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); size->pixmapRefSize += pixmapSize.pixmapRefSize; } if (window->border.pixmap && !window->borderIsPixel) { PixmapPtr pixmap = window->border.pixmap; pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); size->pixmapRefSize += pixmapSize.pixmapRefSize; } } /** * Iterate through subresources of a window. The purpose of this * function is to gather accurate information on what resources * a resource uses. * * @note Currently only sub-pixmaps are iterated * * @param[in] value Pointer to a window * * @param[in] func Function to call with each subresource * * @param[out] cdata Pointer to opaque data */ static void FindWindowSubRes(void *value, FindAllRes func, void *cdata) { WindowPtr window = value; /* Currently only pixmap subresources are reported to clients. */ if (window->backgroundState == BackgroundPixmap) { PixmapPtr pixmap = window->background.pixmap; func(window->background.pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); } if (window->border.pixmap && !window->borderIsPixel) { PixmapPtr pixmap = window->border.pixmap; func(window->background.pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); } } /** * Calculate graphics context size in bytes. The purpose of this * function is to estimate memory usage that can be attributed to all * pixmap references of the graphics context. * * @param[in] value Pointer to a graphics context. * * @param[in] id Resource ID of graphics context. * * @param[out] size Estimate of memory usage attributed to a all * pixmap references of a graphics context. */ static void GetGcBytes(void *value, XID id, ResourceSizePtr size) { SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); ResourceSizeRec pixmapSize = { 0, 0, 0 }; GCPtr gc = value; /* Currently only pixmap bytes are reported to clients. */ size->resourceSize = 0; /* Calculate pixmap reference sizes. */ size->pixmapRefSize = 0; size->refCnt = 1; if (gc->stipple) { PixmapPtr pixmap = gc->stipple; pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); size->pixmapRefSize += pixmapSize.pixmapRefSize; } if (gc->tile.pixmap && !gc->tileIsPixel) { PixmapPtr pixmap = gc->tile.pixmap; pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); size->pixmapRefSize += pixmapSize.pixmapRefSize; } } /** * Iterate through subresources of a graphics context. The purpose of * this function is to gather accurate information on what resources a * resource uses. * * @note Currently only sub-pixmaps are iterated * * @param[in] value Pointer to a window * * @param[in] func Function to call with each subresource * * @param[out] cdata Pointer to opaque data */ static void FindGCSubRes(void *value, FindAllRes func, void *cdata) { GCPtr gc = value; /* Currently only pixmap subresources are reported to clients. */ if (gc->stipple) { PixmapPtr pixmap = gc->stipple; func(pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); } if (gc->tile.pixmap && !gc->tileIsPixel) { PixmapPtr pixmap = gc->tile.pixmap; func(pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); } } static struct ResourceType *resourceTypes; static const struct ResourceType predefTypes[] = { [RT_NONE & (RC_LASTPREDEF - 1)] = { .deleteFunc = (DeleteType) NoopDDA, .sizeFunc = GetDefaultBytes, .findSubResFunc = DefaultFindSubRes, .errorValue = BadValue, }, [RT_WINDOW & (RC_LASTPREDEF - 1)] = { .deleteFunc = DeleteWindow, .sizeFunc = GetWindowBytes, .findSubResFunc = FindWindowSubRes, .errorValue = BadWindow, }, [RT_PIXMAP & (RC_LASTPREDEF - 1)] = { .deleteFunc = dixDestroyPixmap, .sizeFunc = GetPixmapBytes, .findSubResFunc = DefaultFindSubRes, .errorValue = BadPixmap, }, [RT_GC & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeGC, .sizeFunc = GetGcBytes, .findSubResFunc = FindGCSubRes, .errorValue = BadGC, }, [RT_FONT & (RC_LASTPREDEF - 1)] = { .deleteFunc = CloseFont, .sizeFunc = GetDefaultBytes, .findSubResFunc = DefaultFindSubRes, .errorValue = BadFont, }, [RT_CURSOR & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeCursor, .sizeFunc = GetDefaultBytes, .findSubResFunc = DefaultFindSubRes, .errorValue = BadCursor, }, [RT_COLORMAP & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeColormap, .sizeFunc = GetDefaultBytes, .findSubResFunc = DefaultFindSubRes, .errorValue = BadColor, }, [RT_CMAPENTRY & (RC_LASTPREDEF - 1)] = { .deleteFunc = FreeClientPixels, .sizeFunc = GetDefaultBytes, .findSubResFunc = DefaultFindSubRes, .errorValue = BadColor, }, [RT_OTHERCLIENT & (RC_LASTPREDEF - 1)] = { .deleteFunc = OtherClientGone, .sizeFunc = GetDefaultBytes, .findSubResFunc = DefaultFindSubRes, .errorValue = BadValue, }, [RT_PASSIVEGRAB & (RC_LASTPREDEF - 1)] = { .deleteFunc = DeletePassiveGrab, .sizeFunc = GetDefaultBytes, .findSubResFunc = DefaultFindSubRes, .errorValue = BadValue, }, }; CallbackListPtr ResourceStateCallback; static _X_INLINE void CallResourceStateCallback(ResourceState state, ResourceRec * res) { if (ResourceStateCallback) { ResourceStateInfoRec rsi = { state, res->id, res->type, res->value }; CallCallbacks(&ResourceStateCallback, &rsi); } } RESTYPE CreateNewResourceType(DeleteType deleteFunc, const char *name) { RESTYPE next = lastResourceType + 1; struct ResourceType *types; if (next & lastResourceClass) return 0; types = reallocarray(resourceTypes, next + 1, sizeof(*resourceTypes)); if (!types) return 0; lastResourceType = next; resourceTypes = types; resourceTypes[next].deleteFunc = deleteFunc; resourceTypes[next].sizeFunc = GetDefaultBytes; resourceTypes[next].findSubResFunc = DefaultFindSubRes; resourceTypes[next].errorValue = BadValue; #if X_REGISTRY_RESOURCE /* Called even if name is NULL, to remove any previous entry */ RegisterResourceName(next, name); #endif return next; } /** * Get the function used to calculate resource size. Extensions and * drivers need to be able to determine the current size calculation * function if they want to wrap or override it. * * @param[in] type Resource type used in size calculations. * * @return Function to calculate the size of a single * resource. */ SizeType GetResourceTypeSizeFunc(RESTYPE type) { return resourceTypes[type & TypeMask].sizeFunc; } /** * Override the default function that calculates resource size. For * example, video driver knows better how to calculate pixmap memory * usage and can therefore wrap or override size calculation for * RT_PIXMAP. * * @param[in] type Resource type used in size calculations. * * @param[in] sizeFunc Function to calculate the size of a single * resource. */ void SetResourceTypeSizeFunc(RESTYPE type, SizeType sizeFunc) { resourceTypes[type & TypeMask].sizeFunc = sizeFunc; } /** * Provide a function for iterating the subresources of a resource. * This allows for example more accurate accounting of the (memory) * resources consumed by a resource. * * @see FindSubResources * * @param[in] type Resource type used in size calculations. * * @param[in] sizeFunc Function to calculate the size of a single * resource. */ void SetResourceTypeFindSubResFunc(RESTYPE type, FindTypeSubResources findFunc) { resourceTypes[type & TypeMask].findSubResFunc = findFunc; } void SetResourceTypeErrorValue(RESTYPE type, int errorValue) { resourceTypes[type & TypeMask].errorValue = errorValue; } RESTYPE CreateNewResourceClass(void) { RESTYPE next = lastResourceClass >> 1; if (next & lastResourceType) return 0; lastResourceClass = next; TypeMask = next - 1; return next; } static ClientResourceRec clientTable[MAXCLIENTS]; static unsigned int ilog2(int val) { int bits; if (val <= 0) return 0; for (bits = 0; val != 0; bits++) val >>= 1; return bits - 1; } /***************** * ResourceClientBits * Returns the client bit offset in the client + resources ID field *****************/ unsigned int ResourceClientBits(void) { return (ilog2(LimitClients)); } /***************** * InitClientResources * When a new client is created, call this to allocate space * in resource table *****************/ Bool InitClientResources(ClientPtr client) { int i, j; if (client == serverClient) { lastResourceType = RT_LASTPREDEF; lastResourceClass = RC_LASTPREDEF; TypeMask = RC_LASTPREDEF - 1; free(resourceTypes); resourceTypes = malloc(sizeof(predefTypes)); if (!resourceTypes) return FALSE; memcpy(resourceTypes, predefTypes, sizeof(predefTypes)); } clientTable[i = client->index].resources = malloc(INITBUCKETS * sizeof(ResourcePtr)); if (!clientTable[i].resources) return FALSE; clientTable[i].buckets = INITBUCKETS; clientTable[i].elements = 0; clientTable[i].hashsize = INITHASHSIZE; /* Many IDs allocated from the server client are visible to clients, * so we don't use the SERVER_BIT for them, but we have to start * past the magic value constants used in the protocol. For normal * clients, we can start from zero, with SERVER_BIT set. */ clientTable[i].fakeID = client->clientAsMask | (client->index ? SERVER_BIT : SERVER_MINID); clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1; for (j = 0; j < INITBUCKETS; j++) { clientTable[i].resources[j] = NULL; } return TRUE; } int HashResourceID(XID id, int numBits) { static XID mask; if (!mask) mask = RESOURCE_ID_MASK; id &= mask; if (numBits < 9) return (id ^ (id >> numBits) ^ (id >> (numBits<<1))) & ~((~0) << numBits); return (id ^ (id >> numBits)) & ~((~0) << numBits); } static XID AvailableID(int client, XID id, XID maxid, XID goodid) { ResourcePtr res; if ((goodid >= id) && (goodid <= maxid)) return goodid; for (; id <= maxid; id++) { res = clientTable[client].resources[HashResourceID(id, clientTable[client].hashsize)]; while (res && (res->id != id)) res = res->next; if (!res) return id; } return 0; } void GetXIDRange(int client, Bool server, XID *minp, XID *maxp) { XID id, maxid; ResourcePtr *resp; ResourcePtr res; int i; XID goodid; id = (Mask) client << CLIENTOFFSET; if (server) id |= client ? SERVER_BIT : SERVER_MINID; maxid = id | RESOURCE_ID_MASK; goodid = 0; for (resp = clientTable[client].resources, i = clientTable[client].buckets; --i >= 0;) { for (res = *resp++; res; res = res->next) { if ((res->id < id) || (res->id > maxid)) continue; if (((res->id - id) >= (maxid - res->id)) ? (goodid = AvailableID(client, id, res->id - 1, goodid)) : !(goodid = AvailableID(client, res->id + 1, maxid, goodid))) maxid = res->id - 1; else id = res->id + 1; } } if (id > maxid) id = maxid = 0; *minp = id; *maxp = maxid; } /** * GetXIDList is called by the XC-MISC extension's MiscGetXIDList function. * This function tries to find count unused XIDs for the given client. It * puts the IDs in the array pids and returns the number found, which should * almost always be the number requested. * * The circumstances that lead to a call to this function are very rare. * Xlib must run out of IDs while trying to generate a request that wants * multiple ID's, like the Multi-buffering CreateImageBuffers request. * * No rocket science in the implementation; just iterate over all * possible IDs for the given client and pick the first count IDs * that aren't in use. A more efficient algorithm could probably be * invented, but this will be used so rarely that this should suffice. */ unsigned int GetXIDList(ClientPtr pClient, unsigned count, XID *pids) { unsigned int found = 0; XID rc, id = pClient->clientAsMask; XID maxid; void *val; maxid = id | RESOURCE_ID_MASK; while ((found < count) && (id <= maxid)) { rc = dixLookupResourceByClass(&val, id, RC_ANY, serverClient, DixGetAttrAccess); if (rc == BadValue) { pids[found++] = id; } id++; } return found; } /* * Return the next usable fake client ID. * * Normally this is just the next one in line, but if we've used the last * in the range, we need to find a new range of safe IDs to avoid * over-running another client. */ XID FakeClientID(int client) { XID id, maxid; id = clientTable[client].fakeID++; if (id != clientTable[client].endFakeID) return id; GetXIDRange(client, TRUE, &id, &maxid); if (!id) { if (!client) FatalError("FakeClientID: server internal ids exhausted\n"); MarkClientException(clients[client]); id = ((Mask) client << CLIENTOFFSET) | (SERVER_BIT * 3); maxid = id | RESOURCE_ID_MASK; } clientTable[client].fakeID = id + 1; clientTable[client].endFakeID = maxid + 1; return id; } Bool AddResource(XID id, RESTYPE type, void *value) { int client; ClientResourceRec *rrec; ResourcePtr res, *head; #ifdef XSERVER_DTRACE XSERVER_RESOURCE_ALLOC(id, type, value, TypeNameString(type)); #endif client = CLIENT_ID(id); rrec = &clientTable[client]; if (!rrec->buckets) { ErrorF("[dix] AddResource(%lx, %x, %lx), client=%d \n", (unsigned long) id, type, (unsigned long) value, client); FatalError("client not in use\n"); } if ((rrec->elements >= 4 * rrec->buckets) && (rrec->hashsize < MAXHASHSIZE)) RebuildTable(client); head = &rrec->resources[HashResourceID(id, clientTable[client].hashsize)]; res = malloc(sizeof(ResourceRec)); if (!res) { (*resourceTypes[type & TypeMask].deleteFunc) (value, id); return FALSE; } res->next = *head; res->id = id; res->type = type; res->value = value; *head = res; rrec->elements++; CallResourceStateCallback(ResourceStateAdding, res); return TRUE; } static void RebuildTable(int client) { int j; ResourcePtr res, next; ResourcePtr **tails, *resources; ResourcePtr **tptr, *rptr; /* * For now, preserve insertion order, since some ddx layers depend * on resources being free in the opposite order they are added. */ j = 2 * clientTable[client].buckets; tails = xallocarray(j, sizeof(ResourcePtr *)); if (!tails) return; resources = xallocarray(j, sizeof(ResourcePtr)); if (!resources) { free(tails); return; } for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++) { *rptr = NULL; *tptr = rptr; } clientTable[client].hashsize++; for (j = clientTable[client].buckets, rptr = clientTable[client].resources; --j >= 0; rptr++) { for (res = *rptr; res; res = next) { next = res->next; res->next = NULL; tptr = &tails[HashResourceID(res->id, clientTable[client].hashsize)]; **tptr = res; *tptr = &res->next; } } free(tails); clientTable[client].buckets *= 2; free(clientTable[client].resources); clientTable[client].resources = resources; } static void doFreeResource(ResourcePtr res, Bool skip) { CallResourceStateCallback(ResourceStateFreeing, res); if (!skip) resourceTypes[res->type & TypeMask].deleteFunc(res->value, res->id); free(res); } void FreeResource(XID id, RESTYPE skipDeleteFuncType) { int cid; ResourcePtr res; ResourcePtr *prev, *head; int *eltptr; int elements; if (((cid = CLIENT_ID(id)) < LimitClients) && clientTable[cid].buckets) { head = &clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; eltptr = &clientTable[cid].elements; prev = head; while ((res = *prev)) { if (res->id == id) { RESTYPE rtype = res->type; #ifdef XSERVER_DTRACE XSERVER_RESOURCE_FREE(res->id, res->type, res->value, TypeNameString(res->type)); #endif *prev = res->next; elements = --*eltptr; doFreeResource(res, rtype == skipDeleteFuncType); if (*eltptr != elements) prev = head; /* prev may no longer be valid */ } else prev = &res->next; } } } void FreeResourceByType(XID id, RESTYPE type, Bool skipFree) { int cid; ResourcePtr res; ResourcePtr *prev, *head; if (((cid = CLIENT_ID(id)) < LimitClients) && clientTable[cid].buckets) { head = &clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; prev = head; while ((res = *prev)) { if (res->id == id && res->type == type) { #ifdef XSERVER_DTRACE XSERVER_RESOURCE_FREE(res->id, res->type, res->value, TypeNameString(res->type)); #endif *prev = res->next; clientTable[cid].elements--; doFreeResource(res, skipFree); break; } else prev = &res->next; } } } /* * Change the value associated with a resource id. Caller * is responsible for "doing the right thing" with the old * data */ Bool ChangeResourceValue(XID id, RESTYPE rtype, void *value) { int cid; ResourcePtr res; if (((cid = CLIENT_ID(id)) < LimitClients) && clientTable[cid].buckets) { res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if ((res->id == id) && (res->type == rtype)) { res->value = value; return TRUE; } } return FALSE; } /* Note: if func adds or deletes resources, then func can get called * more than once for some resources. If func adds new resources, * func might or might not get called for them. func cannot both * add and delete an equal number of resources! */ void FindClientResourcesByType(ClientPtr client, RESTYPE type, FindResType func, void *cdata) { ResourcePtr *resources; ResourcePtr this, next; int i, elements; int *eltptr; if (!client) client = serverClient; resources = clientTable[client->index].resources; eltptr = &clientTable[client->index].elements; for (i = 0; i < clientTable[client->index].buckets; i++) { for (this = resources[i]; this; this = next) { next = this->next; if (!type || this->type == type) { elements = *eltptr; (*func) (this->value, this->id, cdata); if (*eltptr != elements) next = resources[i]; /* start over */ } } } } void FindSubResources(void *resource, RESTYPE type, FindAllRes func, void *cdata) { struct ResourceType rtype = resourceTypes[type & TypeMask]; rtype.findSubResFunc(resource, func, cdata); } void FindAllClientResources(ClientPtr client, FindAllRes func, void *cdata) { ResourcePtr *resources; ResourcePtr this, next; int i, elements; int *eltptr; if (!client) client = serverClient; resources = clientTable[client->index].resources; eltptr = &clientTable[client->index].elements; for (i = 0; i < clientTable[client->index].buckets; i++) { for (this = resources[i]; this; this = next) { next = this->next; elements = *eltptr; (*func) (this->value, this->id, this->type, cdata); if (*eltptr != elements) next = resources[i]; /* start over */ } } } void * LookupClientResourceComplex(ClientPtr client, RESTYPE type, FindComplexResType func, void *cdata) { ResourcePtr *resources; ResourcePtr this, next; void *value; int i; if (!client) client = serverClient; resources = clientTable[client->index].resources; for (i = 0; i < clientTable[client->index].buckets; i++) { for (this = resources[i]; this; this = next) { next = this->next; if (!type || this->type == type) { /* workaround func freeing the type as DRI1 does */ value = this->value; if ((*func) (value, this->id, cdata)) return value; } } } return NULL; } void FreeClientNeverRetainResources(ClientPtr client) { ResourcePtr *resources; ResourcePtr this; ResourcePtr *prev; int j, elements; int *eltptr; if (!client) return; resources = clientTable[client->index].resources; eltptr = &clientTable[client->index].elements; for (j = 0; j < clientTable[client->index].buckets; j++) { prev = &resources[j]; while ((this = *prev)) { RESTYPE rtype = this->type; if (rtype & RC_NEVERRETAIN) { #ifdef XSERVER_DTRACE XSERVER_RESOURCE_FREE(this->id, this->type, this->value, TypeNameString(this->type)); #endif *prev = this->next; clientTable[client->index].elements--; elements = *eltptr; doFreeResource(this, FALSE); if (*eltptr != elements) prev = &resources[j]; /* prev may no longer be valid */ } else prev = &this->next; } } } void FreeClientResources(ClientPtr client) { ResourcePtr *resources; ResourcePtr this; int j; /* This routine shouldn't be called with a null client, but just in case ... */ if (!client) return; HandleSaveSet(client); resources = clientTable[client->index].resources; for (j = 0; j < clientTable[client->index].buckets; j++) { /* It may seem silly to update the head of this resource list as we delete the members, since the entire list will be deleted any way, but there are some resource deletion functions "FreeClientPixels" for one which do a LookupID on another resource id (a Colormap id in this case), so the resource list must be kept valid up to the point that it is deleted, so every time we delete a resource, we must update the head, just like in FreeResource. I hope that this doesn't slow down mass deletion appreciably. PRH */ ResourcePtr *head; head = &resources[j]; for (this = *head; this; this = *head) { #ifdef XSERVER_DTRACE XSERVER_RESOURCE_FREE(this->id, this->type, this->value, TypeNameString(this->type)); #endif *head = this->next; clientTable[client->index].elements--; doFreeResource(this, FALSE); } } free(clientTable[client->index].resources); clientTable[client->index].resources = NULL; clientTable[client->index].buckets = 0; } void FreeAllResources(void) { int i; for (i = currentMaxClients; --i >= 0;) { if (clientTable[i].buckets) FreeClientResources(clients[i]); } } Bool LegalNewID(XID id, ClientPtr client) { void *val; int rc; #ifdef PANORAMIX XID minid, maxid; if (!noPanoramiXExtension) { minid = client->clientAsMask | (client->index ? SERVER_BIT : SERVER_MINID); maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1; if ((id >= minid) && (id <= maxid)) return TRUE; } #endif /* PANORAMIX */ if (client->clientAsMask == (id & ~RESOURCE_ID_MASK)) { rc = dixLookupResourceByClass(&val, id, RC_ANY, serverClient, DixGetAttrAccess); return rc == BadValue; } return FALSE; } int dixLookupResourceByType(void **result, XID id, RESTYPE rtype, ClientPtr client, Mask mode) { int cid = CLIENT_ID(id); ResourcePtr res = NULL; *result = NULL; if ((rtype & TypeMask) > lastResourceType) return BadImplementation; if ((cid < LimitClients) && clientTable[cid].buckets) { res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if (res->id == id && res->type == rtype) break; } if (client) { client->errorValue = id; } if (!res) return resourceTypes[rtype & TypeMask].errorValue; if (client) { cid = XaceHook(XACE_RESOURCE_ACCESS, client, id, res->type, res->value, RT_NONE, NULL, mode); if (cid == BadValue) return resourceTypes[rtype & TypeMask].errorValue; if (cid != Success) return cid; } *result = res->value; return Success; } int dixLookupResourceByClass(void **result, XID id, RESTYPE rclass, ClientPtr client, Mask mode) { int cid = CLIENT_ID(id); ResourcePtr res = NULL; *result = NULL; if ((cid < LimitClients) && clientTable[cid].buckets) { res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if (res->id == id && (res->type & rclass)) break; } if (client) { client->errorValue = id; } if (!res) return BadValue; if (client) { cid = XaceHook(XACE_RESOURCE_ACCESS, client, id, res->type, res->value, RT_NONE, NULL, mode); if (cid != Success) return cid; } *result = res->value; return Success; } xorg-server-1.20.13/dix/selection.c0000644000175000017500000002273414100573756014017 00000000000000/************************************************************ Copyright 1987, 1989, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include "windowstr.h" #include "dixstruct.h" #include "dispatch.h" #include "selection.h" #include "xace.h" /***************************************************************** * Selection Stuff * * dixLookupSelection * * Selections are global to the server. The list of selections should * not be traversed directly. Instead, use the functions listed above. * *****************************************************************/ Selection *CurrentSelections; CallbackListPtr SelectionCallback; int dixLookupSelection(Selection ** result, Atom selectionName, ClientPtr client, Mask access_mode) { Selection *pSel; int rc = BadMatch; client->errorValue = selectionName; for (pSel = CurrentSelections; pSel; pSel = pSel->next) if (pSel->selection == selectionName) break; if (pSel) rc = XaceHookSelectionAccess(client, &pSel, access_mode); *result = pSel; return rc; } void InitSelections(void) { Selection *pSel, *pNextSel; pSel = CurrentSelections; while (pSel) { pNextSel = pSel->next; dixFreeObjectWithPrivates(pSel, PRIVATE_SELECTION); pSel = pNextSel; } CurrentSelections = NULL; } static _X_INLINE void CallSelectionCallback(Selection * pSel, ClientPtr client, SelectionCallbackKind kind) { SelectionInfoRec info = { pSel, client, kind }; CallCallbacks(&SelectionCallback, &info); } void DeleteWindowFromAnySelections(WindowPtr pWin) { Selection *pSel; for (pSel = CurrentSelections; pSel; pSel = pSel->next) if (pSel->pWin == pWin) { CallSelectionCallback(pSel, NULL, SelectionWindowDestroy); pSel->pWin = (WindowPtr) NULL; pSel->window = None; pSel->client = NullClient; } } void DeleteClientFromAnySelections(ClientPtr client) { Selection *pSel; for (pSel = CurrentSelections; pSel; pSel = pSel->next) if (pSel->client == client) { CallSelectionCallback(pSel, NULL, SelectionClientClose); pSel->pWin = (WindowPtr) NULL; pSel->window = None; pSel->client = NullClient; } } int ProcSetSelectionOwner(ClientPtr client) { WindowPtr pWin = NULL; TimeStamp time; Selection *pSel; int rc; REQUEST(xSetSelectionOwnerReq); REQUEST_SIZE_MATCH(xSetSelectionOwnerReq); UpdateCurrentTime(); time = ClientTimeToServerTime(stuff->time); /* If the client's time stamp is in the future relative to the server's time stamp, do not set the selection, just return success. */ if (CompareTimeStamps(time, currentTime) == LATER) return Success; if (stuff->window != None) { rc = dixLookupWindow(&pWin, stuff->window, client, DixSetAttrAccess); if (rc != Success) return rc; } if (!ValidAtom(stuff->selection)) { client->errorValue = stuff->selection; return BadAtom; } /* * First, see if the selection is already set... */ rc = dixLookupSelection(&pSel, stuff->selection, client, DixSetAttrAccess); if (rc == Success) { /* If the timestamp in client's request is in the past relative to the time stamp indicating the last time the owner of the selection was set, do not set the selection, just return success. */ if (CompareTimeStamps(time, pSel->lastTimeChanged) == EARLIER) return Success; if (pSel->client && (!pWin || (pSel->client != client))) { xEvent event = { .u.selectionClear.time = time.milliseconds, .u.selectionClear.window = pSel->window, .u.selectionClear.atom = pSel->selection }; event.u.u.type = SelectionClear; WriteEventsToClient(pSel->client, 1, &event); } } else if (rc == BadMatch) { /* * It doesn't exist, so add it... */ pSel = dixAllocateObjectWithPrivates(Selection, PRIVATE_SELECTION); if (!pSel) return BadAlloc; pSel->selection = stuff->selection; /* security creation/labeling check */ rc = XaceHookSelectionAccess(client, &pSel, DixCreateAccess | DixSetAttrAccess); if (rc != Success) { free(pSel); return rc; } pSel->next = CurrentSelections; CurrentSelections = pSel; } else return rc; pSel->lastTimeChanged = time; pSel->window = stuff->window; pSel->pWin = pWin; pSel->client = (pWin ? client : NullClient); CallSelectionCallback(pSel, client, SelectionSetOwner); return Success; } int ProcGetSelectionOwner(ClientPtr client) { int rc; Selection *pSel; xGetSelectionOwnerReply reply; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); if (!ValidAtom(stuff->id)) { client->errorValue = stuff->id; return BadAtom; } reply = (xGetSelectionOwnerReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, }; rc = dixLookupSelection(&pSel, stuff->id, client, DixGetAttrAccess); if (rc == Success) reply.owner = pSel->window; else if (rc == BadMatch) reply.owner = None; else return rc; WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply); return Success; } int ProcConvertSelection(ClientPtr client) { Bool paramsOkay; xEvent event; WindowPtr pWin; Selection *pSel; int rc; REQUEST(xConvertSelectionReq); REQUEST_SIZE_MATCH(xConvertSelectionReq); rc = dixLookupWindow(&pWin, stuff->requestor, client, DixSetAttrAccess); if (rc != Success) return rc; paramsOkay = ValidAtom(stuff->selection) && ValidAtom(stuff->target); paramsOkay &= (stuff->property == None) || ValidAtom(stuff->property); if (!paramsOkay) { client->errorValue = stuff->property; return BadAtom; } if (stuff->time == CurrentTime) UpdateCurrentTime(); rc = dixLookupSelection(&pSel, stuff->selection, client, DixReadAccess); memset(&event, 0, sizeof(xEvent)); if (rc != Success && rc != BadMatch) return rc; else if (rc == Success && pSel->window != None) { event.u.u.type = SelectionRequest; event.u.selectionRequest.owner = pSel->window; event.u.selectionRequest.time = stuff->time; event.u.selectionRequest.requestor = stuff->requestor; event.u.selectionRequest.selection = stuff->selection; event.u.selectionRequest.target = stuff->target; event.u.selectionRequest.property = stuff->property; if (pSel->client && pSel->client != serverClient && !pSel->client->clientGone) { WriteEventsToClient(pSel->client, 1, &event); return Success; } } event.u.u.type = SelectionNotify; event.u.selectionNotify.time = stuff->time; event.u.selectionNotify.requestor = stuff->requestor; event.u.selectionNotify.selection = stuff->selection; event.u.selectionNotify.target = stuff->target; event.u.selectionNotify.property = None; WriteEventsToClient(client, 1, &event); return Success; } xorg-server-1.20.13/dix/swaprep.c0000644000175000017500000010723714100573756013515 00000000000000/************************************************************ Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include #include "misc.h" #include "dixstruct.h" #include #include "scrnintstr.h" #include "swaprep.h" #include "globals.h" static void SwapFontInfo(xQueryFontReply * pr); static void SwapCharInfo(xCharInfo * pInfo); static void SwapFont(xQueryFontReply * pr, Bool hasGlyphs); /** * Thanks to Jack Palevich for testing and subsequently rewriting all this * * \param size size in bytes */ void _X_COLD Swap32Write(ClientPtr pClient, int size, CARD32 *pbuf) { int i; size >>= 2; for (i = 0; i < size; i++) /* brackets are mandatory here, because "swapl" macro expands to several statements */ { swapl(&pbuf[i]); } WriteToClient(pClient, size << 2, pbuf); } /** * * \param size size in bytes */ void _X_COLD CopySwap32Write(ClientPtr pClient, int size, CARD32 *pbuf) { int bufsize = size; CARD32 *pbufT; CARD32 *from, *to, *fromLast, *toLast; CARD32 tmpbuf[1]; /* Allocate as big a buffer as we can... */ while (!(pbufT = malloc(bufsize))) { bufsize >>= 1; if (bufsize == 4) { pbufT = tmpbuf; break; } } /* convert lengths from # of bytes to # of longs */ size >>= 2; bufsize >>= 2; from = pbuf; fromLast = from + size; while (from < fromLast) { int nbytes; to = pbufT; toLast = to + min(bufsize, fromLast - from); nbytes = (toLast - to) << 2; while (to < toLast) { /* can't write "cpswapl(*from++, *to++)" because cpswapl is a macro that evaulates its args more than once */ cpswapl(*from, *to); from++; to++; } WriteToClient(pClient, nbytes, pbufT); } if (pbufT != tmpbuf) free(pbufT); } /** * * \param size size in bytes */ void _X_COLD CopySwap16Write(ClientPtr pClient, int size, short *pbuf) { int bufsize = size; short *pbufT; short *from, *to, *fromLast, *toLast; short tmpbuf[2]; /* Allocate as big a buffer as we can... */ while (!(pbufT = malloc(bufsize))) { bufsize >>= 1; if (bufsize == 4) { pbufT = tmpbuf; break; } } /* convert lengths from # of bytes to # of shorts */ size >>= 1; bufsize >>= 1; from = pbuf; fromLast = from + size; while (from < fromLast) { int nbytes; to = pbufT; toLast = to + min(bufsize, fromLast - from); nbytes = (toLast - to) << 1; while (to < toLast) { /* can't write "cpswaps(*from++, *to++)" because cpswaps is a macro that evaulates its args more than once */ cpswaps(*from, *to); from++; to++; } WriteToClient(pClient, nbytes, pbufT); } if (pbufT != tmpbuf) free(pbufT); } /* Extra-small reply */ void _X_COLD SGenericReply(ClientPtr pClient, int size, xGenericReply * pRep) { swaps(&pRep->sequenceNumber); WriteToClient(pClient, size, pRep); } /* Extra-large reply */ void _X_COLD SGetWindowAttributesReply(ClientPtr pClient, int size, xGetWindowAttributesReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swapl(&pRep->visualID); swaps(&pRep->class); swapl(&pRep->backingBitPlanes); swapl(&pRep->backingPixel); swapl(&pRep->colormap); swapl(&pRep->allEventMasks); swapl(&pRep->yourEventMask); swaps(&pRep->doNotPropagateMask); WriteToClient(pClient, size, pRep); } void _X_COLD SGetGeometryReply(ClientPtr pClient, int size, xGetGeometryReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->root); swaps(&pRep->x); swaps(&pRep->y); swaps(&pRep->width); swaps(&pRep->height); swaps(&pRep->borderWidth); WriteToClient(pClient, size, pRep); } void _X_COLD SQueryTreeReply(ClientPtr pClient, int size, xQueryTreeReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swapl(&pRep->root); swapl(&pRep->parent); swaps(&pRep->nChildren); WriteToClient(pClient, size, pRep); } void _X_COLD SInternAtomReply(ClientPtr pClient, int size, xInternAtomReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->atom); WriteToClient(pClient, size, pRep); } void _X_COLD SGetAtomNameReply(ClientPtr pClient, int size, xGetAtomNameReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nameLength); WriteToClient(pClient, size, pRep); } void _X_COLD SGetPropertyReply(ClientPtr pClient, int size, xGetPropertyReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swapl(&pRep->propertyType); swapl(&pRep->bytesAfter); swapl(&pRep->nItems); WriteToClient(pClient, size, pRep); } void _X_COLD SListPropertiesReply(ClientPtr pClient, int size, xListPropertiesReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nProperties); WriteToClient(pClient, size, pRep); } void _X_COLD SGetSelectionOwnerReply(ClientPtr pClient, int size, xGetSelectionOwnerReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->owner); WriteToClient(pClient, size, pRep); } void _X_COLD SQueryPointerReply(ClientPtr pClient, int size, xQueryPointerReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->root); swapl(&pRep->child); swaps(&pRep->rootX); swaps(&pRep->rootY); swaps(&pRep->winX); swaps(&pRep->winY); swaps(&pRep->mask); WriteToClient(pClient, size, pRep); } static void _X_COLD SwapTimecoord(xTimecoord * pCoord) { swapl(&pCoord->time); swaps(&pCoord->x); swaps(&pCoord->y); } void _X_COLD SwapTimeCoordWrite(ClientPtr pClient, int size, xTimecoord * pRep) { int i, n; xTimecoord *pRepT; n = size / sizeof(xTimecoord); pRepT = pRep; for (i = 0; i < n; i++) { SwapTimecoord(pRepT); pRepT++; } WriteToClient(pClient, size, pRep); } void _X_COLD SGetMotionEventsReply(ClientPtr pClient, int size, xGetMotionEventsReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swapl(&pRep->nEvents); WriteToClient(pClient, size, pRep); } void _X_COLD STranslateCoordsReply(ClientPtr pClient, int size, xTranslateCoordsReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->child); swaps(&pRep->dstX); swaps(&pRep->dstY); WriteToClient(pClient, size, pRep); } void _X_COLD SGetInputFocusReply(ClientPtr pClient, int size, xGetInputFocusReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->focus); WriteToClient(pClient, size, pRep); } /* extra long reply */ void _X_COLD SQueryKeymapReply(ClientPtr pClient, int size, xQueryKeymapReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); WriteToClient(pClient, size, pRep); } static void _X_COLD SwapCharInfo(xCharInfo * pInfo) { swaps(&pInfo->leftSideBearing); swaps(&pInfo->rightSideBearing); swaps(&pInfo->characterWidth); swaps(&pInfo->ascent); swaps(&pInfo->descent); swaps(&pInfo->attributes); } static void _X_COLD SwapFontInfo(xQueryFontReply * pr) { swaps(&pr->minCharOrByte2); swaps(&pr->maxCharOrByte2); swaps(&pr->defaultChar); swaps(&pr->nFontProps); swaps(&pr->fontAscent); swaps(&pr->fontDescent); SwapCharInfo(&pr->minBounds); SwapCharInfo(&pr->maxBounds); swapl(&pr->nCharInfos); } static void _X_COLD SwapFont(xQueryFontReply * pr, Bool hasGlyphs) { unsigned i; xCharInfo *pxci; unsigned nchars, nprops; char *pby; swaps(&pr->sequenceNumber); swapl(&pr->length); nchars = pr->nCharInfos; nprops = pr->nFontProps; SwapFontInfo(pr); pby = (char *) &pr[1]; /* Font properties are an atom and either an int32 or a CARD32, so * they are always 2 4 byte values */ for (i = 0; i < nprops; i++) { swapl((int *) pby); pby += 4; swapl((int *) pby); pby += 4; } if (hasGlyphs) { pxci = (xCharInfo *) pby; for (i = 0; i < nchars; i++, pxci++) SwapCharInfo(pxci); } } void _X_COLD SQueryFontReply(ClientPtr pClient, int size, xQueryFontReply * pRep) { SwapFont(pRep, TRUE); WriteToClient(pClient, size, pRep); } void _X_COLD SQueryTextExtentsReply(ClientPtr pClient, int size, xQueryTextExtentsReply * pRep) { swaps(&pRep->sequenceNumber); swaps(&pRep->fontAscent); swaps(&pRep->fontDescent); swaps(&pRep->overallAscent); swaps(&pRep->overallDescent); swapl(&pRep->overallWidth); swapl(&pRep->overallLeft); swapl(&pRep->overallRight); WriteToClient(pClient, size, pRep); } void _X_COLD SListFontsReply(ClientPtr pClient, int size, xListFontsReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nFonts); WriteToClient(pClient, size, pRep); } void _X_COLD SListFontsWithInfoReply(ClientPtr pClient, int size, xListFontsWithInfoReply * pRep) { SwapFont((xQueryFontReply *) pRep, FALSE); WriteToClient(pClient, size, pRep); } void _X_COLD SGetFontPathReply(ClientPtr pClient, int size, xGetFontPathReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nPaths); WriteToClient(pClient, size, pRep); } void _X_COLD SGetImageReply(ClientPtr pClient, int size, xGetImageReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swapl(&pRep->visual); WriteToClient(pClient, size, pRep); /* Fortunately, image doesn't need swapping */ } void _X_COLD SListInstalledColormapsReply(ClientPtr pClient, int size, xListInstalledColormapsReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nColormaps); WriteToClient(pClient, size, pRep); } void _X_COLD SAllocColorReply(ClientPtr pClient, int size, xAllocColorReply * pRep) { swaps(&pRep->sequenceNumber); swaps(&pRep->red); swaps(&pRep->green); swaps(&pRep->blue); swapl(&pRep->pixel); WriteToClient(pClient, size, pRep); } void _X_COLD SAllocNamedColorReply(ClientPtr pClient, int size, xAllocNamedColorReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->pixel); swaps(&pRep->exactRed); swaps(&pRep->exactGreen); swaps(&pRep->exactBlue); swaps(&pRep->screenRed); swaps(&pRep->screenGreen); swaps(&pRep->screenBlue); WriteToClient(pClient, size, pRep); } void _X_COLD SAllocColorCellsReply(ClientPtr pClient, int size, xAllocColorCellsReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nPixels); swaps(&pRep->nMasks); WriteToClient(pClient, size, pRep); } void _X_COLD SAllocColorPlanesReply(ClientPtr pClient, int size, xAllocColorPlanesReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nPixels); swapl(&pRep->redMask); swapl(&pRep->greenMask); swapl(&pRep->blueMask); WriteToClient(pClient, size, pRep); } static void _X_COLD SwapRGB(xrgb * prgb) { swaps(&prgb->red); swaps(&prgb->green); swaps(&prgb->blue); } void _X_COLD SQColorsExtend(ClientPtr pClient, int size, xrgb * prgb) { int i, n; xrgb *prgbT; n = size / sizeof(xrgb); prgbT = prgb; for (i = 0; i < n; i++) { SwapRGB(prgbT); prgbT++; } WriteToClient(pClient, size, prgb); } void _X_COLD SQueryColorsReply(ClientPtr pClient, int size, xQueryColorsReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nColors); WriteToClient(pClient, size, pRep); } void _X_COLD SLookupColorReply(ClientPtr pClient, int size, xLookupColorReply * pRep) { swaps(&pRep->sequenceNumber); swaps(&pRep->exactRed); swaps(&pRep->exactGreen); swaps(&pRep->exactBlue); swaps(&pRep->screenRed); swaps(&pRep->screenGreen); swaps(&pRep->screenBlue); WriteToClient(pClient, size, pRep); } void _X_COLD SQueryBestSizeReply(ClientPtr pClient, int size, xQueryBestSizeReply * pRep) { swaps(&pRep->sequenceNumber); swaps(&pRep->width); swaps(&pRep->height); WriteToClient(pClient, size, pRep); } void _X_COLD SListExtensionsReply(ClientPtr pClient, int size, xListExtensionsReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); WriteToClient(pClient, size, pRep); } void _X_COLD SGetKeyboardMappingReply(ClientPtr pClient, int size, xGetKeyboardMappingReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); WriteToClient(pClient, size, pRep); } void _X_COLD SGetPointerMappingReply(ClientPtr pClient, int size, xGetPointerMappingReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); WriteToClient(pClient, size, pRep); } void _X_COLD SGetModifierMappingReply(ClientPtr pClient, int size, xGetModifierMappingReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); WriteToClient(pClient, size, pRep); } void _X_COLD SGetKeyboardControlReply(ClientPtr pClient, int size, xGetKeyboardControlReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swapl(&pRep->ledMask); swaps(&pRep->bellPitch); swaps(&pRep->bellDuration); WriteToClient(pClient, size, pRep); } void _X_COLD SGetPointerControlReply(ClientPtr pClient, int size, xGetPointerControlReply * pRep) { swaps(&pRep->sequenceNumber); swaps(&pRep->accelNumerator); swaps(&pRep->accelDenominator); swaps(&pRep->threshold); WriteToClient(pClient, size, pRep); } void _X_COLD SGetScreenSaverReply(ClientPtr pClient, int size, xGetScreenSaverReply * pRep) { swaps(&pRep->sequenceNumber); swaps(&pRep->timeout); swaps(&pRep->interval); WriteToClient(pClient, size, pRep); } void _X_COLD SLHostsExtend(ClientPtr pClient, int size, char *buf) { char *bufT = buf; char *endbuf = buf + size; while (bufT < endbuf) { xHostEntry *host = (xHostEntry *) bufT; int len = host->length; swaps(&host->length); bufT += sizeof(xHostEntry) + pad_to_int32(len); } WriteToClient(pClient, size, buf); } void _X_COLD SListHostsReply(ClientPtr pClient, int size, xListHostsReply * pRep) { swaps(&pRep->sequenceNumber); swapl(&pRep->length); swaps(&pRep->nHosts); WriteToClient(pClient, size, pRep); } void _X_COLD SErrorEvent(xError * from, xError * to) { to->type = X_Error; to->errorCode = from->errorCode; cpswaps(from->sequenceNumber, to->sequenceNumber); cpswapl(from->resourceID, to->resourceID); cpswaps(from->minorCode, to->minorCode); to->majorCode = from->majorCode; } void _X_COLD SKeyButtonPtrEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; to->u.u.detail = from->u.u.detail; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.keyButtonPointer.time, to->u.keyButtonPointer.time); cpswapl(from->u.keyButtonPointer.root, to->u.keyButtonPointer.root); cpswapl(from->u.keyButtonPointer.event, to->u.keyButtonPointer.event); cpswapl(from->u.keyButtonPointer.child, to->u.keyButtonPointer.child); cpswaps(from->u.keyButtonPointer.rootX, to->u.keyButtonPointer.rootX); cpswaps(from->u.keyButtonPointer.rootY, to->u.keyButtonPointer.rootY); cpswaps(from->u.keyButtonPointer.eventX, to->u.keyButtonPointer.eventX); cpswaps(from->u.keyButtonPointer.eventY, to->u.keyButtonPointer.eventY); cpswaps(from->u.keyButtonPointer.state, to->u.keyButtonPointer.state); to->u.keyButtonPointer.sameScreen = from->u.keyButtonPointer.sameScreen; } void _X_COLD SEnterLeaveEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; to->u.u.detail = from->u.u.detail; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.enterLeave.time, to->u.enterLeave.time); cpswapl(from->u.enterLeave.root, to->u.enterLeave.root); cpswapl(from->u.enterLeave.event, to->u.enterLeave.event); cpswapl(from->u.enterLeave.child, to->u.enterLeave.child); cpswaps(from->u.enterLeave.rootX, to->u.enterLeave.rootX); cpswaps(from->u.enterLeave.rootY, to->u.enterLeave.rootY); cpswaps(from->u.enterLeave.eventX, to->u.enterLeave.eventX); cpswaps(from->u.enterLeave.eventY, to->u.enterLeave.eventY); cpswaps(from->u.enterLeave.state, to->u.enterLeave.state); to->u.enterLeave.mode = from->u.enterLeave.mode; to->u.enterLeave.flags = from->u.enterLeave.flags; } void _X_COLD SFocusEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; to->u.u.detail = from->u.u.detail; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.focus.window, to->u.focus.window); to->u.focus.mode = from->u.focus.mode; } void _X_COLD SExposeEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.expose.window, to->u.expose.window); cpswaps(from->u.expose.x, to->u.expose.x); cpswaps(from->u.expose.y, to->u.expose.y); cpswaps(from->u.expose.width, to->u.expose.width); cpswaps(from->u.expose.height, to->u.expose.height); cpswaps(from->u.expose.count, to->u.expose.count); } void _X_COLD SGraphicsExposureEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.graphicsExposure.drawable, to->u.graphicsExposure.drawable); cpswaps(from->u.graphicsExposure.x, to->u.graphicsExposure.x); cpswaps(from->u.graphicsExposure.y, to->u.graphicsExposure.y); cpswaps(from->u.graphicsExposure.width, to->u.graphicsExposure.width); cpswaps(from->u.graphicsExposure.height, to->u.graphicsExposure.height); cpswaps(from->u.graphicsExposure.minorEvent, to->u.graphicsExposure.minorEvent); cpswaps(from->u.graphicsExposure.count, to->u.graphicsExposure.count); to->u.graphicsExposure.majorEvent = from->u.graphicsExposure.majorEvent; } void _X_COLD SNoExposureEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.noExposure.drawable, to->u.noExposure.drawable); cpswaps(from->u.noExposure.minorEvent, to->u.noExposure.minorEvent); to->u.noExposure.majorEvent = from->u.noExposure.majorEvent; } void _X_COLD SVisibilityEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.visibility.window, to->u.visibility.window); to->u.visibility.state = from->u.visibility.state; } void _X_COLD SCreateNotifyEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.createNotify.window, to->u.createNotify.window); cpswapl(from->u.createNotify.parent, to->u.createNotify.parent); cpswaps(from->u.createNotify.x, to->u.createNotify.x); cpswaps(from->u.createNotify.y, to->u.createNotify.y); cpswaps(from->u.createNotify.width, to->u.createNotify.width); cpswaps(from->u.createNotify.height, to->u.createNotify.height); cpswaps(from->u.createNotify.borderWidth, to->u.createNotify.borderWidth); to->u.createNotify.override = from->u.createNotify.override; } void _X_COLD SDestroyNotifyEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.destroyNotify.event, to->u.destroyNotify.event); cpswapl(from->u.destroyNotify.window, to->u.destroyNotify.window); } void _X_COLD SUnmapNotifyEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.unmapNotify.event, to->u.unmapNotify.event); cpswapl(from->u.unmapNotify.window, to->u.unmapNotify.window); to->u.unmapNotify.fromConfigure = from->u.unmapNotify.fromConfigure; } void _X_COLD SMapNotifyEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.mapNotify.event, to->u.mapNotify.event); cpswapl(from->u.mapNotify.window, to->u.mapNotify.window); to->u.mapNotify.override = from->u.mapNotify.override; } void _X_COLD SMapRequestEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.mapRequest.parent, to->u.mapRequest.parent); cpswapl(from->u.mapRequest.window, to->u.mapRequest.window); } void _X_COLD SReparentEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.reparent.event, to->u.reparent.event); cpswapl(from->u.reparent.window, to->u.reparent.window); cpswapl(from->u.reparent.parent, to->u.reparent.parent); cpswaps(from->u.reparent.x, to->u.reparent.x); cpswaps(from->u.reparent.y, to->u.reparent.y); to->u.reparent.override = from->u.reparent.override; } void _X_COLD SConfigureNotifyEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.configureNotify.event, to->u.configureNotify.event); cpswapl(from->u.configureNotify.window, to->u.configureNotify.window); cpswapl(from->u.configureNotify.aboveSibling, to->u.configureNotify.aboveSibling); cpswaps(from->u.configureNotify.x, to->u.configureNotify.x); cpswaps(from->u.configureNotify.y, to->u.configureNotify.y); cpswaps(from->u.configureNotify.width, to->u.configureNotify.width); cpswaps(from->u.configureNotify.height, to->u.configureNotify.height); cpswaps(from->u.configureNotify.borderWidth, to->u.configureNotify.borderWidth); to->u.configureNotify.override = from->u.configureNotify.override; } void _X_COLD SConfigureRequestEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; to->u.u.detail = from->u.u.detail; /* actually stack-mode */ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.configureRequest.parent, to->u.configureRequest.parent); cpswapl(from->u.configureRequest.window, to->u.configureRequest.window); cpswapl(from->u.configureRequest.sibling, to->u.configureRequest.sibling); cpswaps(from->u.configureRequest.x, to->u.configureRequest.x); cpswaps(from->u.configureRequest.y, to->u.configureRequest.y); cpswaps(from->u.configureRequest.width, to->u.configureRequest.width); cpswaps(from->u.configureRequest.height, to->u.configureRequest.height); cpswaps(from->u.configureRequest.borderWidth, to->u.configureRequest.borderWidth); cpswaps(from->u.configureRequest.valueMask, to->u.configureRequest.valueMask); } void _X_COLD SGravityEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.gravity.event, to->u.gravity.event); cpswapl(from->u.gravity.window, to->u.gravity.window); cpswaps(from->u.gravity.x, to->u.gravity.x); cpswaps(from->u.gravity.y, to->u.gravity.y); } void _X_COLD SResizeRequestEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.resizeRequest.window, to->u.resizeRequest.window); cpswaps(from->u.resizeRequest.width, to->u.resizeRequest.width); cpswaps(from->u.resizeRequest.height, to->u.resizeRequest.height); } void _X_COLD SCirculateEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; to->u.u.detail = from->u.u.detail; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.circulate.event, to->u.circulate.event); cpswapl(from->u.circulate.window, to->u.circulate.window); cpswapl(from->u.circulate.parent, to->u.circulate.parent); to->u.circulate.place = from->u.circulate.place; } void _X_COLD SPropertyEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.property.window, to->u.property.window); cpswapl(from->u.property.atom, to->u.property.atom); cpswapl(from->u.property.time, to->u.property.time); to->u.property.state = from->u.property.state; } void _X_COLD SSelectionClearEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.selectionClear.time, to->u.selectionClear.time); cpswapl(from->u.selectionClear.window, to->u.selectionClear.window); cpswapl(from->u.selectionClear.atom, to->u.selectionClear.atom); } void _X_COLD SSelectionRequestEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.selectionRequest.time, to->u.selectionRequest.time); cpswapl(from->u.selectionRequest.owner, to->u.selectionRequest.owner); cpswapl(from->u.selectionRequest.requestor, to->u.selectionRequest.requestor); cpswapl(from->u.selectionRequest.selection, to->u.selectionRequest.selection); cpswapl(from->u.selectionRequest.target, to->u.selectionRequest.target); cpswapl(from->u.selectionRequest.property, to->u.selectionRequest.property); } void _X_COLD SSelectionNotifyEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.selectionNotify.time, to->u.selectionNotify.time); cpswapl(from->u.selectionNotify.requestor, to->u.selectionNotify.requestor); cpswapl(from->u.selectionNotify.selection, to->u.selectionNotify.selection); cpswapl(from->u.selectionNotify.target, to->u.selectionNotify.target); cpswapl(from->u.selectionNotify.property, to->u.selectionNotify.property); } void _X_COLD SColormapEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.colormap.window, to->u.colormap.window); cpswapl(from->u.colormap.colormap, to->u.colormap.colormap); to->u.colormap.new = from->u.colormap.new; to->u.colormap.state = from->u.colormap.state; } void _X_COLD SMappingEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); to->u.mappingNotify.request = from->u.mappingNotify.request; to->u.mappingNotify.firstKeyCode = from->u.mappingNotify.firstKeyCode; to->u.mappingNotify.count = from->u.mappingNotify.count; } void _X_COLD SClientMessageEvent(xEvent *from, xEvent *to) { to->u.u.type = from->u.u.type; to->u.u.detail = from->u.u.detail; /* actually format */ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber); cpswapl(from->u.clientMessage.window, to->u.clientMessage.window); cpswapl(from->u.clientMessage.u.l.type, to->u.clientMessage.u.l.type); switch (from->u.u.detail) { case 8: memmove(to->u.clientMessage.u.b.bytes, from->u.clientMessage.u.b.bytes, 20); break; case 16: cpswaps(from->u.clientMessage.u.s.shorts0, to->u.clientMessage.u.s.shorts0); cpswaps(from->u.clientMessage.u.s.shorts1, to->u.clientMessage.u.s.shorts1); cpswaps(from->u.clientMessage.u.s.shorts2, to->u.clientMessage.u.s.shorts2); cpswaps(from->u.clientMessage.u.s.shorts3, to->u.clientMessage.u.s.shorts3); cpswaps(from->u.clientMessage.u.s.shorts4, to->u.clientMessage.u.s.shorts4); cpswaps(from->u.clientMessage.u.s.shorts5, to->u.clientMessage.u.s.shorts5); cpswaps(from->u.clientMessage.u.s.shorts6, to->u.clientMessage.u.s.shorts6); cpswaps(from->u.clientMessage.u.s.shorts7, to->u.clientMessage.u.s.shorts7); cpswaps(from->u.clientMessage.u.s.shorts8, to->u.clientMessage.u.s.shorts8); cpswaps(from->u.clientMessage.u.s.shorts9, to->u.clientMessage.u.s.shorts9); break; case 32: cpswapl(from->u.clientMessage.u.l.longs0, to->u.clientMessage.u.l.longs0); cpswapl(from->u.clientMessage.u.l.longs1, to->u.clientMessage.u.l.longs1); cpswapl(from->u.clientMessage.u.l.longs2, to->u.clientMessage.u.l.longs2); cpswapl(from->u.clientMessage.u.l.longs3, to->u.clientMessage.u.l.longs3); cpswapl(from->u.clientMessage.u.l.longs4, to->u.clientMessage.u.l.longs4); break; } } void _X_COLD SKeymapNotifyEvent(xEvent *from, xEvent *to) { /* Keymap notify events are special; they have no sequence number field, and contain entirely 8-bit data */ *to = *from; } static void _X_COLD SwapConnSetup(xConnSetup * pConnSetup, xConnSetup * pConnSetupT) { cpswapl(pConnSetup->release, pConnSetupT->release); cpswapl(pConnSetup->ridBase, pConnSetupT->ridBase); cpswapl(pConnSetup->ridMask, pConnSetupT->ridMask); cpswapl(pConnSetup->motionBufferSize, pConnSetupT->motionBufferSize); cpswaps(pConnSetup->nbytesVendor, pConnSetupT->nbytesVendor); cpswaps(pConnSetup->maxRequestSize, pConnSetupT->maxRequestSize); pConnSetupT->minKeyCode = pConnSetup->minKeyCode; pConnSetupT->maxKeyCode = pConnSetup->maxKeyCode; pConnSetupT->numRoots = pConnSetup->numRoots; pConnSetupT->numFormats = pConnSetup->numFormats; pConnSetupT->imageByteOrder = pConnSetup->imageByteOrder; pConnSetupT->bitmapBitOrder = pConnSetup->bitmapBitOrder; pConnSetupT->bitmapScanlineUnit = pConnSetup->bitmapScanlineUnit; pConnSetupT->bitmapScanlinePad = pConnSetup->bitmapScanlinePad; } static void _X_COLD SwapWinRoot(xWindowRoot * pRoot, xWindowRoot * pRootT) { cpswapl(pRoot->windowId, pRootT->windowId); cpswapl(pRoot->defaultColormap, pRootT->defaultColormap); cpswapl(pRoot->whitePixel, pRootT->whitePixel); cpswapl(pRoot->blackPixel, pRootT->blackPixel); cpswapl(pRoot->currentInputMask, pRootT->currentInputMask); cpswaps(pRoot->pixWidth, pRootT->pixWidth); cpswaps(pRoot->pixHeight, pRootT->pixHeight); cpswaps(pRoot->mmWidth, pRootT->mmWidth); cpswaps(pRoot->mmHeight, pRootT->mmHeight); cpswaps(pRoot->minInstalledMaps, pRootT->minInstalledMaps); cpswaps(pRoot->maxInstalledMaps, pRootT->maxInstalledMaps); cpswapl(pRoot->rootVisualID, pRootT->rootVisualID); pRootT->backingStore = pRoot->backingStore; pRootT->saveUnders = pRoot->saveUnders; pRootT->rootDepth = pRoot->rootDepth; pRootT->nDepths = pRoot->nDepths; } static void _X_COLD SwapVisual(xVisualType * pVis, xVisualType * pVisT) { cpswapl(pVis->visualID, pVisT->visualID); pVisT->class = pVis->class; pVisT->bitsPerRGB = pVis->bitsPerRGB; cpswaps(pVis->colormapEntries, pVisT->colormapEntries); cpswapl(pVis->redMask, pVisT->redMask); cpswapl(pVis->greenMask, pVisT->greenMask); cpswapl(pVis->blueMask, pVisT->blueMask); } void _X_COLD SwapConnSetupInfo(char *pInfo, char *pInfoT) { int i, j, k; xConnSetup *pConnSetup = (xConnSetup *) pInfo; xDepth *depth; xWindowRoot *root; SwapConnSetup(pConnSetup, (xConnSetup *) pInfoT); pInfo += sizeof(xConnSetup); pInfoT += sizeof(xConnSetup); /* Copy the vendor string */ i = pad_to_int32(pConnSetup->nbytesVendor); memcpy(pInfoT, pInfo, i); pInfo += i; pInfoT += i; /* The Pixmap formats don't need to be swapped, just copied. */ i = sizeof(xPixmapFormat) * pConnSetup->numFormats; memcpy(pInfoT, pInfo, i); pInfo += i; pInfoT += i; for (i = 0; i < pConnSetup->numRoots; i++) { root = (xWindowRoot *) pInfo; SwapWinRoot(root, (xWindowRoot *) pInfoT); pInfo += sizeof(xWindowRoot); pInfoT += sizeof(xWindowRoot); for (j = 0; j < root->nDepths; j++) { depth = (xDepth *) pInfo; ((xDepth *) pInfoT)->depth = depth->depth; cpswaps(depth->nVisuals, ((xDepth *) pInfoT)->nVisuals); pInfo += sizeof(xDepth); pInfoT += sizeof(xDepth); for (k = 0; k < depth->nVisuals; k++) { SwapVisual((xVisualType *) pInfo, (xVisualType *) pInfoT); pInfo += sizeof(xVisualType); pInfoT += sizeof(xVisualType); } } } } void _X_COLD WriteSConnectionInfo(ClientPtr pClient, unsigned long size, char *pInfo) { char *pInfoTBase; pInfoTBase = malloc(size); if (!pInfoTBase) { pClient->noClientException = -1; return; } SwapConnSetupInfo(pInfo, pInfoTBase); WriteToClient(pClient, (int) size, pInfoTBase); free(pInfoTBase); } void _X_COLD SwapConnSetupPrefix(xConnSetupPrefix * pcspFrom, xConnSetupPrefix * pcspTo) { pcspTo->success = pcspFrom->success; pcspTo->lengthReason = pcspFrom->lengthReason; cpswaps(pcspFrom->majorVersion, pcspTo->majorVersion); cpswaps(pcspFrom->minorVersion, pcspTo->minorVersion); cpswaps(pcspFrom->length, pcspTo->length); } void _X_COLD WriteSConnSetupPrefix(ClientPtr pClient, xConnSetupPrefix * pcsp) { xConnSetupPrefix cspT; SwapConnSetupPrefix(pcsp, &cspT); WriteToClient(pClient, sizeof(cspT), &cspT); } /* * Dummy entry for ReplySwapVector[] */ void _X_COLD ReplyNotSwappd(ClientPtr pClient, int size, void *pbuf) { FatalError("Not implemented"); } xorg-server-1.20.13/dix/swapreq.c0000644000175000017500000006217714100573756013521 00000000000000/************************************************************ Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include #include #include "misc.h" #include "dixstruct.h" #include "extnsionst.h" /* for SendEvent */ #include "swapreq.h" /* Thanks to Jack Palevich for testing and subsequently rewriting all this */ /* Byte swap a list of longs */ void SwapLongs(CARD32 *list, unsigned long count) { while (count >= 8) { swapl(list + 0); swapl(list + 1); swapl(list + 2); swapl(list + 3); swapl(list + 4); swapl(list + 5); swapl(list + 6); swapl(list + 7); list += 8; count -= 8; } if (count != 0) { do { swapl(list); list++; } while (--count != 0); } } /* Byte swap a list of shorts */ void SwapShorts(short *list, unsigned long count) { while (count >= 16) { swaps(list + 0); swaps(list + 1); swaps(list + 2); swaps(list + 3); swaps(list + 4); swaps(list + 5); swaps(list + 6); swaps(list + 7); swaps(list + 8); swaps(list + 9); swaps(list + 10); swaps(list + 11); swaps(list + 12); swaps(list + 13); swaps(list + 14); swaps(list + 15); list += 16; count -= 16; } if (count != 0) { do { swaps(list); list++; } while (--count != 0); } } /* The following is used for all requests that have no fields to be swapped (except "length") */ int _X_COLD SProcSimpleReq(ClientPtr client) { REQUEST(xReq); swaps(&stuff->length); return (*ProcVector[stuff->reqType]) (client); } /* The following is used for all requests that have only a single 32-bit field to be swapped, coming right after the "length" field */ int _X_COLD SProcResourceReq(ClientPtr client) { REQUEST(xResourceReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xResourceReq); /* not EXACT */ swapl(&stuff->id); return (*ProcVector[stuff->reqType]) (client); } int _X_COLD SProcCreateWindow(ClientPtr client) { REQUEST(xCreateWindowReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xCreateWindowReq); swapl(&stuff->wid); swapl(&stuff->parent); swaps(&stuff->x); swaps(&stuff->y); swaps(&stuff->width); swaps(&stuff->height); swaps(&stuff->borderWidth); swaps(&stuff->class); swapl(&stuff->visual); swapl(&stuff->mask); SwapRestL(stuff); return ((*ProcVector[X_CreateWindow]) (client)); } int _X_COLD SProcChangeWindowAttributes(ClientPtr client) { REQUEST(xChangeWindowAttributesReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); swapl(&stuff->window); swapl(&stuff->valueMask); SwapRestL(stuff); return ((*ProcVector[X_ChangeWindowAttributes]) (client)); } int _X_COLD SProcReparentWindow(ClientPtr client) { REQUEST(xReparentWindowReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xReparentWindowReq); swapl(&stuff->window); swapl(&stuff->parent); swaps(&stuff->x); swaps(&stuff->y); return ((*ProcVector[X_ReparentWindow]) (client)); } int _X_COLD SProcConfigureWindow(ClientPtr client) { REQUEST(xConfigureWindowReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); swapl(&stuff->window); swaps(&stuff->mask); SwapRestL(stuff); return ((*ProcVector[X_ConfigureWindow]) (client)); } int _X_COLD SProcInternAtom(ClientPtr client) { REQUEST(xInternAtomReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xInternAtomReq); swaps(&stuff->nbytes); return ((*ProcVector[X_InternAtom]) (client)); } int _X_COLD SProcChangeProperty(ClientPtr client) { REQUEST(xChangePropertyReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xChangePropertyReq); swapl(&stuff->window); swapl(&stuff->property); swapl(&stuff->type); swapl(&stuff->nUnits); switch (stuff->format) { case 8: break; case 16: SwapRestS(stuff); break; case 32: SwapRestL(stuff); break; } return ((*ProcVector[X_ChangeProperty]) (client)); } int _X_COLD SProcDeleteProperty(ClientPtr client) { REQUEST(xDeletePropertyReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xDeletePropertyReq); swapl(&stuff->window); swapl(&stuff->property); return ((*ProcVector[X_DeleteProperty]) (client)); } int _X_COLD SProcGetProperty(ClientPtr client) { REQUEST(xGetPropertyReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xGetPropertyReq); swapl(&stuff->window); swapl(&stuff->property); swapl(&stuff->type); swapl(&stuff->longOffset); swapl(&stuff->longLength); return ((*ProcVector[X_GetProperty]) (client)); } int _X_COLD SProcSetSelectionOwner(ClientPtr client) { REQUEST(xSetSelectionOwnerReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xSetSelectionOwnerReq); swapl(&stuff->window); swapl(&stuff->selection); swapl(&stuff->time); return ((*ProcVector[X_SetSelectionOwner]) (client)); } int _X_COLD SProcConvertSelection(ClientPtr client) { REQUEST(xConvertSelectionReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xConvertSelectionReq); swapl(&stuff->requestor); swapl(&stuff->selection); swapl(&stuff->target); swapl(&stuff->property); swapl(&stuff->time); return ((*ProcVector[X_ConvertSelection]) (client)); } int _X_COLD SProcSendEvent(ClientPtr client) { xEvent eventT = { .u.u.type = 0 }; EventSwapPtr proc; REQUEST(xSendEventReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xSendEventReq); swapl(&stuff->destination); swapl(&stuff->eventMask); /* Generic events can have variable size, but SendEvent request holds exactly 32B of event data. */ if (stuff->event.u.u.type == GenericEvent) { client->errorValue = stuff->event.u.u.type; return BadValue; } /* Swap event */ proc = EventSwapVector[stuff->event.u.u.type & 0177]; if (!proc || proc == NotImplemented) /* no swapping proc; invalid event type? */ return BadValue; (*proc) (&stuff->event, &eventT); stuff->event = eventT; return ((*ProcVector[X_SendEvent]) (client)); } int _X_COLD SProcGrabPointer(ClientPtr client) { REQUEST(xGrabPointerReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xGrabPointerReq); swapl(&stuff->grabWindow); swaps(&stuff->eventMask); swapl(&stuff->confineTo); swapl(&stuff->cursor); swapl(&stuff->time); return ((*ProcVector[X_GrabPointer]) (client)); } int _X_COLD SProcGrabButton(ClientPtr client) { REQUEST(xGrabButtonReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xGrabButtonReq); swapl(&stuff->grabWindow); swaps(&stuff->eventMask); swapl(&stuff->confineTo); swapl(&stuff->cursor); swaps(&stuff->modifiers); return ((*ProcVector[X_GrabButton]) (client)); } int _X_COLD SProcUngrabButton(ClientPtr client) { REQUEST(xUngrabButtonReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xUngrabButtonReq); swapl(&stuff->grabWindow); swaps(&stuff->modifiers); return ((*ProcVector[X_UngrabButton]) (client)); } int _X_COLD SProcChangeActivePointerGrab(ClientPtr client) { REQUEST(xChangeActivePointerGrabReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq); swapl(&stuff->cursor); swapl(&stuff->time); swaps(&stuff->eventMask); return ((*ProcVector[X_ChangeActivePointerGrab]) (client)); } int _X_COLD SProcGrabKeyboard(ClientPtr client) { REQUEST(xGrabKeyboardReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xGrabKeyboardReq); swapl(&stuff->grabWindow); swapl(&stuff->time); return ((*ProcVector[X_GrabKeyboard]) (client)); } int _X_COLD SProcGrabKey(ClientPtr client) { REQUEST(xGrabKeyReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xGrabKeyReq); swapl(&stuff->grabWindow); swaps(&stuff->modifiers); return ((*ProcVector[X_GrabKey]) (client)); } int _X_COLD SProcUngrabKey(ClientPtr client) { REQUEST(xUngrabKeyReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xUngrabKeyReq); swapl(&stuff->grabWindow); swaps(&stuff->modifiers); return ((*ProcVector[X_UngrabKey]) (client)); } int _X_COLD SProcGetMotionEvents(ClientPtr client) { REQUEST(xGetMotionEventsReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xGetMotionEventsReq); swapl(&stuff->window); swapl(&stuff->start); swapl(&stuff->stop); return ((*ProcVector[X_GetMotionEvents]) (client)); } int _X_COLD SProcTranslateCoords(ClientPtr client) { REQUEST(xTranslateCoordsReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xTranslateCoordsReq); swapl(&stuff->srcWid); swapl(&stuff->dstWid); swaps(&stuff->srcX); swaps(&stuff->srcY); return ((*ProcVector[X_TranslateCoords]) (client)); } int _X_COLD SProcWarpPointer(ClientPtr client) { REQUEST(xWarpPointerReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xWarpPointerReq); swapl(&stuff->srcWid); swapl(&stuff->dstWid); swaps(&stuff->srcX); swaps(&stuff->srcY); swaps(&stuff->srcWidth); swaps(&stuff->srcHeight); swaps(&stuff->dstX); swaps(&stuff->dstY); return ((*ProcVector[X_WarpPointer]) (client)); } int _X_COLD SProcSetInputFocus(ClientPtr client) { REQUEST(xSetInputFocusReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xSetInputFocusReq); swapl(&stuff->focus); swapl(&stuff->time); return ((*ProcVector[X_SetInputFocus]) (client)); } int _X_COLD SProcOpenFont(ClientPtr client) { REQUEST(xOpenFontReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xOpenFontReq); swapl(&stuff->fid); swaps(&stuff->nbytes); return ((*ProcVector[X_OpenFont]) (client)); } int _X_COLD SProcListFonts(ClientPtr client) { REQUEST(xListFontsReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xListFontsReq); swaps(&stuff->maxNames); swaps(&stuff->nbytes); return ((*ProcVector[X_ListFonts]) (client)); } int _X_COLD SProcListFontsWithInfo(ClientPtr client) { REQUEST(xListFontsWithInfoReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xListFontsWithInfoReq); swaps(&stuff->maxNames); swaps(&stuff->nbytes); return ((*ProcVector[X_ListFontsWithInfo]) (client)); } int _X_COLD SProcSetFontPath(ClientPtr client) { REQUEST(xSetFontPathReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xSetFontPathReq); swaps(&stuff->nFonts); return ((*ProcVector[X_SetFontPath]) (client)); } int _X_COLD SProcCreatePixmap(ClientPtr client) { REQUEST(xCreatePixmapReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCreatePixmapReq); swapl(&stuff->pid); swapl(&stuff->drawable); swaps(&stuff->width); swaps(&stuff->height); return ((*ProcVector[X_CreatePixmap]) (client)); } int _X_COLD SProcCreateGC(ClientPtr client) { REQUEST(xCreateGCReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xCreateGCReq); swapl(&stuff->gc); swapl(&stuff->drawable); swapl(&stuff->mask); SwapRestL(stuff); return ((*ProcVector[X_CreateGC]) (client)); } int _X_COLD SProcChangeGC(ClientPtr client) { REQUEST(xChangeGCReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xChangeGCReq); swapl(&stuff->gc); swapl(&stuff->mask); SwapRestL(stuff); return ((*ProcVector[X_ChangeGC]) (client)); } int _X_COLD SProcCopyGC(ClientPtr client) { REQUEST(xCopyGCReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCopyGCReq); swapl(&stuff->srcGC); swapl(&stuff->dstGC); swapl(&stuff->mask); return ((*ProcVector[X_CopyGC]) (client)); } int _X_COLD SProcSetDashes(ClientPtr client) { REQUEST(xSetDashesReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xSetDashesReq); swapl(&stuff->gc); swaps(&stuff->dashOffset); swaps(&stuff->nDashes); return ((*ProcVector[X_SetDashes]) (client)); } int _X_COLD SProcSetClipRectangles(ClientPtr client) { REQUEST(xSetClipRectanglesReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); swapl(&stuff->gc); swaps(&stuff->xOrigin); swaps(&stuff->yOrigin); SwapRestS(stuff); return ((*ProcVector[X_SetClipRectangles]) (client)); } int _X_COLD SProcClearToBackground(ClientPtr client) { REQUEST(xClearAreaReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xClearAreaReq); swapl(&stuff->window); swaps(&stuff->x); swaps(&stuff->y); swaps(&stuff->width); swaps(&stuff->height); return ((*ProcVector[X_ClearArea]) (client)); } int _X_COLD SProcCopyArea(ClientPtr client) { REQUEST(xCopyAreaReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCopyAreaReq); swapl(&stuff->srcDrawable); swapl(&stuff->dstDrawable); swapl(&stuff->gc); swaps(&stuff->srcX); swaps(&stuff->srcY); swaps(&stuff->dstX); swaps(&stuff->dstY); swaps(&stuff->width); swaps(&stuff->height); return ((*ProcVector[X_CopyArea]) (client)); } int _X_COLD SProcCopyPlane(ClientPtr client) { REQUEST(xCopyPlaneReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCopyPlaneReq); swapl(&stuff->srcDrawable); swapl(&stuff->dstDrawable); swapl(&stuff->gc); swaps(&stuff->srcX); swaps(&stuff->srcY); swaps(&stuff->dstX); swaps(&stuff->dstY); swaps(&stuff->width); swaps(&stuff->height); swapl(&stuff->bitPlane); return ((*ProcVector[X_CopyPlane]) (client)); } /* The following routine is used for all Poly drawing requests (except FillPoly, which uses a different request format) */ int _X_COLD SProcPoly(ClientPtr client) { REQUEST(xPolyPointReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xPolyPointReq); swapl(&stuff->drawable); swapl(&stuff->gc); SwapRestS(stuff); return ((*ProcVector[stuff->reqType]) (client)); } /* cannot use SProcPoly for this one, because xFillPolyReq is longer than xPolyPointReq, and we don't want to swap the difference as shorts! */ int _X_COLD SProcFillPoly(ClientPtr client) { REQUEST(xFillPolyReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xFillPolyReq); swapl(&stuff->drawable); swapl(&stuff->gc); SwapRestS(stuff); return ((*ProcVector[X_FillPoly]) (client)); } int _X_COLD SProcPutImage(ClientPtr client) { REQUEST(xPutImageReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xPutImageReq); swapl(&stuff->drawable); swapl(&stuff->gc); swaps(&stuff->width); swaps(&stuff->height); swaps(&stuff->dstX); swaps(&stuff->dstY); /* Image should already be swapped */ return ((*ProcVector[X_PutImage]) (client)); } int _X_COLD SProcGetImage(ClientPtr client) { REQUEST(xGetImageReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xGetImageReq); swapl(&stuff->drawable); swaps(&stuff->x); swaps(&stuff->y); swaps(&stuff->width); swaps(&stuff->height); swapl(&stuff->planeMask); return ((*ProcVector[X_GetImage]) (client)); } /* ProcPolyText used for both PolyText8 and PolyText16 */ int _X_COLD SProcPolyText(ClientPtr client) { REQUEST(xPolyTextReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xPolyTextReq); swapl(&stuff->drawable); swapl(&stuff->gc); swaps(&stuff->x); swaps(&stuff->y); return ((*ProcVector[stuff->reqType]) (client)); } /* ProcImageText used for both ImageText8 and ImageText16 */ int _X_COLD SProcImageText(ClientPtr client) { REQUEST(xImageTextReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xImageTextReq); swapl(&stuff->drawable); swapl(&stuff->gc); swaps(&stuff->x); swaps(&stuff->y); return ((*ProcVector[stuff->reqType]) (client)); } int _X_COLD SProcCreateColormap(ClientPtr client) { REQUEST(xCreateColormapReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCreateColormapReq); swapl(&stuff->mid); swapl(&stuff->window); swapl(&stuff->visual); return ((*ProcVector[X_CreateColormap]) (client)); } int _X_COLD SProcCopyColormapAndFree(ClientPtr client) { REQUEST(xCopyColormapAndFreeReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); swapl(&stuff->mid); swapl(&stuff->srcCmap); return ((*ProcVector[X_CopyColormapAndFree]) (client)); } int _X_COLD SProcAllocColor(ClientPtr client) { REQUEST(xAllocColorReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xAllocColorReq); swapl(&stuff->cmap); swaps(&stuff->red); swaps(&stuff->green); swaps(&stuff->blue); return ((*ProcVector[X_AllocColor]) (client)); } int _X_COLD SProcAllocNamedColor(ClientPtr client) { REQUEST(xAllocNamedColorReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xAllocNamedColorReq); swapl(&stuff->cmap); swaps(&stuff->nbytes); return ((*ProcVector[X_AllocNamedColor]) (client)); } int _X_COLD SProcAllocColorCells(ClientPtr client) { REQUEST(xAllocColorCellsReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xAllocColorCellsReq); swapl(&stuff->cmap); swaps(&stuff->colors); swaps(&stuff->planes); return ((*ProcVector[X_AllocColorCells]) (client)); } int _X_COLD SProcAllocColorPlanes(ClientPtr client) { REQUEST(xAllocColorPlanesReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xAllocColorPlanesReq); swapl(&stuff->cmap); swaps(&stuff->colors); swaps(&stuff->red); swaps(&stuff->green); swaps(&stuff->blue); return ((*ProcVector[X_AllocColorPlanes]) (client)); } int _X_COLD SProcFreeColors(ClientPtr client) { REQUEST(xFreeColorsReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xFreeColorsReq); swapl(&stuff->cmap); swapl(&stuff->planeMask); SwapRestL(stuff); return ((*ProcVector[X_FreeColors]) (client)); } void _X_COLD SwapColorItem(xColorItem * pItem) { swapl(&pItem->pixel); swaps(&pItem->red); swaps(&pItem->green); swaps(&pItem->blue); } int _X_COLD SProcStoreColors(ClientPtr client) { long count; xColorItem *pItem; REQUEST(xStoreColorsReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xStoreColorsReq); swapl(&stuff->cmap); pItem = (xColorItem *) &stuff[1]; for (count = LengthRestB(stuff) / sizeof(xColorItem); --count >= 0;) SwapColorItem(pItem++); return ((*ProcVector[X_StoreColors]) (client)); } int _X_COLD SProcStoreNamedColor(ClientPtr client) { REQUEST(xStoreNamedColorReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xStoreNamedColorReq); swapl(&stuff->cmap); swapl(&stuff->pixel); swaps(&stuff->nbytes); return ((*ProcVector[X_StoreNamedColor]) (client)); } int _X_COLD SProcQueryColors(ClientPtr client) { REQUEST(xQueryColorsReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xQueryColorsReq); swapl(&stuff->cmap); SwapRestL(stuff); return ((*ProcVector[X_QueryColors]) (client)); } int _X_COLD SProcLookupColor(ClientPtr client) { REQUEST(xLookupColorReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xLookupColorReq); swapl(&stuff->cmap); swaps(&stuff->nbytes); return ((*ProcVector[X_LookupColor]) (client)); } int _X_COLD SProcCreateCursor(ClientPtr client) { REQUEST(xCreateCursorReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCreateCursorReq); swapl(&stuff->cid); swapl(&stuff->source); swapl(&stuff->mask); swaps(&stuff->foreRed); swaps(&stuff->foreGreen); swaps(&stuff->foreBlue); swaps(&stuff->backRed); swaps(&stuff->backGreen); swaps(&stuff->backBlue); swaps(&stuff->x); swaps(&stuff->y); return ((*ProcVector[X_CreateCursor]) (client)); } int _X_COLD SProcCreateGlyphCursor(ClientPtr client) { REQUEST(xCreateGlyphCursorReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xCreateGlyphCursorReq); swapl(&stuff->cid); swapl(&stuff->source); swapl(&stuff->mask); swaps(&stuff->sourceChar); swaps(&stuff->maskChar); swaps(&stuff->foreRed); swaps(&stuff->foreGreen); swaps(&stuff->foreBlue); swaps(&stuff->backRed); swaps(&stuff->backGreen); swaps(&stuff->backBlue); return ((*ProcVector[X_CreateGlyphCursor]) (client)); } int _X_COLD SProcRecolorCursor(ClientPtr client) { REQUEST(xRecolorCursorReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xRecolorCursorReq); swapl(&stuff->cursor); swaps(&stuff->foreRed); swaps(&stuff->foreGreen); swaps(&stuff->foreBlue); swaps(&stuff->backRed); swaps(&stuff->backGreen); swaps(&stuff->backBlue); return ((*ProcVector[X_RecolorCursor]) (client)); } int _X_COLD SProcQueryBestSize(ClientPtr client) { REQUEST(xQueryBestSizeReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xQueryBestSizeReq); swapl(&stuff->drawable); swaps(&stuff->width); swaps(&stuff->height); return ((*ProcVector[X_QueryBestSize]) (client)); } int _X_COLD SProcQueryExtension(ClientPtr client) { REQUEST(xQueryExtensionReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xQueryExtensionReq); swaps(&stuff->nbytes); return ((*ProcVector[X_QueryExtension]) (client)); } int _X_COLD SProcChangeKeyboardMapping(ClientPtr client) { REQUEST(xChangeKeyboardMappingReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq); SwapRestL(stuff); return ((*ProcVector[X_ChangeKeyboardMapping]) (client)); } int _X_COLD SProcChangeKeyboardControl(ClientPtr client) { REQUEST(xChangeKeyboardControlReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq); swapl(&stuff->mask); SwapRestL(stuff); return ((*ProcVector[X_ChangeKeyboardControl]) (client)); } int _X_COLD SProcChangePointerControl(ClientPtr client) { REQUEST(xChangePointerControlReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xChangePointerControlReq); swaps(&stuff->accelNum); swaps(&stuff->accelDenum); swaps(&stuff->threshold); return ((*ProcVector[X_ChangePointerControl]) (client)); } int _X_COLD SProcSetScreenSaver(ClientPtr client) { REQUEST(xSetScreenSaverReq); swaps(&stuff->length); REQUEST_SIZE_MATCH(xSetScreenSaverReq); swaps(&stuff->timeout); swaps(&stuff->interval); return ((*ProcVector[X_SetScreenSaver]) (client)); } int _X_COLD SProcChangeHosts(ClientPtr client) { REQUEST(xChangeHostsReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xChangeHostsReq); swaps(&stuff->hostLength); return ((*ProcVector[X_ChangeHosts]) (client)); } int _X_COLD SProcRotateProperties(ClientPtr client) { REQUEST(xRotatePropertiesReq); swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xRotatePropertiesReq); swapl(&stuff->window); swaps(&stuff->nAtoms); swaps(&stuff->nPositions); SwapRestL(stuff); return ((*ProcVector[X_RotateProperties]) (client)); } int _X_COLD SProcNoOperation(ClientPtr client) { REQUEST(xReq); swaps(&stuff->length); return ((*ProcVector[X_NoOperation]) (client)); } void _X_COLD SwapConnClientPrefix(xConnClientPrefix * pCCP) { swaps(&pCCP->majorVersion); swaps(&pCCP->minorVersion); swaps(&pCCP->nbytesAuthProto); swaps(&pCCP->nbytesAuthString); } xorg-server-1.20.13/dix/tables.c0000644000175000017500000006501314100573756013301 00000000000000/*********************************************************** Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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 #endif #include #include #include "windowstr.h" #include "extnsionst.h" #include "dixstruct.h" #include "dixevents.h" #include "dispatch.h" #include "swaprep.h" #include "swapreq.h" int (*InitialVector[3]) (ClientPtr /* client */) = { 0, ProcInitialConnection, ProcEstablishConnection }; int (*ProcVector[256]) (ClientPtr /* client */) = { ProcBadRequest, ProcCreateWindow, ProcChangeWindowAttributes, ProcGetWindowAttributes, ProcDestroyWindow, ProcDestroySubwindows, /* 5 */ ProcChangeSaveSet, ProcReparentWindow, ProcMapWindow, ProcMapSubwindows, ProcUnmapWindow, /* 10 */ ProcUnmapSubwindows, ProcConfigureWindow, ProcCirculateWindow, ProcGetGeometry, ProcQueryTree, /* 15 */ ProcInternAtom, ProcGetAtomName, ProcChangeProperty, ProcDeleteProperty, ProcGetProperty, /* 20 */ ProcListProperties, ProcSetSelectionOwner, ProcGetSelectionOwner, ProcConvertSelection, ProcSendEvent, /* 25 */ ProcGrabPointer, ProcUngrabPointer, ProcGrabButton, ProcUngrabButton, ProcChangeActivePointerGrab, /* 30 */ ProcGrabKeyboard, ProcUngrabKeyboard, ProcGrabKey, ProcUngrabKey, ProcAllowEvents, /* 35 */ ProcGrabServer, ProcUngrabServer, ProcQueryPointer, ProcGetMotionEvents, ProcTranslateCoords, /* 40 */ ProcWarpPointer, ProcSetInputFocus, ProcGetInputFocus, ProcQueryKeymap, ProcOpenFont, /* 45 */ ProcCloseFont, ProcQueryFont, ProcQueryTextExtents, ProcListFonts, ProcListFontsWithInfo, /* 50 */ ProcSetFontPath, ProcGetFontPath, ProcCreatePixmap, ProcFreePixmap, ProcCreateGC, /* 55 */ ProcChangeGC, ProcCopyGC, ProcSetDashes, ProcSetClipRectangles, ProcFreeGC, /* 60 */ ProcClearToBackground, ProcCopyArea, ProcCopyPlane, ProcPolyPoint, ProcPolyLine, /* 65 */ ProcPolySegment, ProcPolyRectangle, ProcPolyArc, ProcFillPoly, ProcPolyFillRectangle, /* 70 */ ProcPolyFillArc, ProcPutImage, ProcGetImage, ProcPolyText, ProcPolyText, /* 75 */ ProcImageText8, ProcImageText16, ProcCreateColormap, ProcFreeColormap, ProcCopyColormapAndFree, /* 80 */ ProcInstallColormap, ProcUninstallColormap, ProcListInstalledColormaps, ProcAllocColor, ProcAllocNamedColor, /* 85 */ ProcAllocColorCells, ProcAllocColorPlanes, ProcFreeColors, ProcStoreColors, ProcStoreNamedColor, /* 90 */ ProcQueryColors, ProcLookupColor, ProcCreateCursor, ProcCreateGlyphCursor, ProcFreeCursor, /* 95 */ ProcRecolorCursor, ProcQueryBestSize, ProcQueryExtension, ProcListExtensions, ProcChangeKeyboardMapping, /* 100 */ ProcGetKeyboardMapping, ProcChangeKeyboardControl, ProcGetKeyboardControl, ProcBell, ProcChangePointerControl, /* 105 */ ProcGetPointerControl, ProcSetScreenSaver, ProcGetScreenSaver, ProcChangeHosts, ProcListHosts, /* 110 */ ProcChangeAccessControl, ProcChangeCloseDownMode, ProcKillClient, ProcRotateProperties, ProcForceScreenSaver, /* 115 */ ProcSetPointerMapping, ProcGetPointerMapping, ProcSetModifierMapping, ProcGetModifierMapping, ProcBadRequest, /* 120 */ ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, /* 125 */ ProcBadRequest, ProcNoOperation, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest }; int (*SwappedProcVector[256]) (ClientPtr /* client */) = { ProcBadRequest, SProcCreateWindow, SProcChangeWindowAttributes, SProcResourceReq, /* GetWindowAttributes */ SProcResourceReq, /* DestroyWindow */ SProcResourceReq, /* 5 DestroySubwindows */ SProcResourceReq, /* SProcChangeSaveSet, */ SProcReparentWindow, SProcResourceReq, /* MapWindow */ SProcResourceReq, /* MapSubwindows */ SProcResourceReq, /* 10 UnmapWindow */ SProcResourceReq, /* UnmapSubwindows */ SProcConfigureWindow, SProcResourceReq, /* SProcCirculateWindow, */ SProcResourceReq, /* GetGeometry */ SProcResourceReq, /* 15 QueryTree */ SProcInternAtom, SProcResourceReq, /* SProcGetAtomName, */ SProcChangeProperty, SProcDeleteProperty, SProcGetProperty, /* 20 */ SProcResourceReq, /* SProcListProperties, */ SProcSetSelectionOwner, SProcResourceReq, /* SProcGetSelectionOwner, */ SProcConvertSelection, SProcSendEvent, /* 25 */ SProcGrabPointer, SProcResourceReq, /* SProcUngrabPointer, */ SProcGrabButton, SProcUngrabButton, SProcChangeActivePointerGrab, /* 30 */ SProcGrabKeyboard, SProcResourceReq, /* SProcUngrabKeyboard, */ SProcGrabKey, SProcUngrabKey, SProcResourceReq, /* 35 SProcAllowEvents, */ SProcSimpleReq, /* SProcGrabServer, */ SProcSimpleReq, /* SProcUngrabServer, */ SProcResourceReq, /* SProcQueryPointer, */ SProcGetMotionEvents, SProcTranslateCoords, /*40 */ SProcWarpPointer, SProcSetInputFocus, SProcSimpleReq, /* SProcGetInputFocus, */ SProcSimpleReq, /* QueryKeymap, */ SProcOpenFont, /* 45 */ SProcResourceReq, /* SProcCloseFont, */ SProcResourceReq, /* SProcQueryFont, */ SProcResourceReq, /* SProcQueryTextExtents, */ SProcListFonts, SProcListFontsWithInfo, /* 50 */ SProcSetFontPath, SProcSimpleReq, /* GetFontPath, */ SProcCreatePixmap, SProcResourceReq, /* SProcFreePixmap, */ SProcCreateGC, /* 55 */ SProcChangeGC, SProcCopyGC, SProcSetDashes, SProcSetClipRectangles, SProcResourceReq, /* 60 SProcFreeGC, */ SProcClearToBackground, SProcCopyArea, SProcCopyPlane, SProcPoly, /* PolyPoint, */ SProcPoly, /* 65 PolyLine */ SProcPoly, /* PolySegment, */ SProcPoly, /* PolyRectangle, */ SProcPoly, /* PolyArc, */ SProcFillPoly, SProcPoly, /* 70 PolyFillRectangle */ SProcPoly, /* PolyFillArc, */ SProcPutImage, SProcGetImage, SProcPolyText, SProcPolyText, /* 75 */ SProcImageText, SProcImageText, SProcCreateColormap, SProcResourceReq, /* SProcFreeColormap, */ SProcCopyColormapAndFree, /* 80 */ SProcResourceReq, /* SProcInstallColormap, */ SProcResourceReq, /* SProcUninstallColormap, */ SProcResourceReq, /* SProcListInstalledColormaps, */ SProcAllocColor, SProcAllocNamedColor, /* 85 */ SProcAllocColorCells, SProcAllocColorPlanes, SProcFreeColors, SProcStoreColors, SProcStoreNamedColor, /* 90 */ SProcQueryColors, SProcLookupColor, SProcCreateCursor, SProcCreateGlyphCursor, SProcResourceReq, /* 95 SProcFreeCursor, */ SProcRecolorCursor, SProcQueryBestSize, SProcQueryExtension, SProcSimpleReq, /* ListExtensions, */ SProcChangeKeyboardMapping, /* 100 */ SProcSimpleReq, /* GetKeyboardMapping, */ SProcChangeKeyboardControl, SProcSimpleReq, /* GetKeyboardControl, */ SProcSimpleReq, /* Bell, */ SProcChangePointerControl, /* 105 */ SProcSimpleReq, /* GetPointerControl, */ SProcSetScreenSaver, SProcSimpleReq, /* GetScreenSaver, */ SProcChangeHosts, SProcSimpleReq, /* 110 ListHosts, */ SProcSimpleReq, /* SProcChangeAccessControl, */ SProcSimpleReq, /* SProcChangeCloseDownMode, */ SProcResourceReq, /* SProcKillClient, */ SProcRotateProperties, SProcSimpleReq, /* 115 ForceScreenSaver */ SProcSimpleReq, /* SetPointerMapping, */ SProcSimpleReq, /* GetPointerMapping, */ SProcSimpleReq, /* SetModifierMapping, */ SProcSimpleReq, /* GetModifierMapping, */ ProcBadRequest, /* 120 */ ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, /* 125 */ ProcBadRequest, SProcNoOperation, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest, ProcBadRequest }; EventSwapPtr EventSwapVector[MAXEVENTS] = { (EventSwapPtr) SErrorEvent, NotImplemented, SKeyButtonPtrEvent, SKeyButtonPtrEvent, SKeyButtonPtrEvent, SKeyButtonPtrEvent, /* 5 */ SKeyButtonPtrEvent, SEnterLeaveEvent, SEnterLeaveEvent, SFocusEvent, SFocusEvent, /* 10 */ SKeymapNotifyEvent, SExposeEvent, SGraphicsExposureEvent, SNoExposureEvent, SVisibilityEvent, /* 15 */ SCreateNotifyEvent, SDestroyNotifyEvent, SUnmapNotifyEvent, SMapNotifyEvent, SMapRequestEvent, /* 20 */ SReparentEvent, SConfigureNotifyEvent, SConfigureRequestEvent, SGravityEvent, SResizeRequestEvent, /* 25 */ SCirculateEvent, SCirculateEvent, SPropertyEvent, SSelectionClearEvent, SSelectionRequestEvent, /* 30 */ SSelectionNotifyEvent, SColormapEvent, SClientMessageEvent, SMappingEvent, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented }; ReplySwapPtr ReplySwapVector[256] = { ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SGetWindowAttributesReply, ReplyNotSwappd, ReplyNotSwappd, /* 5 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 10 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SGetGeometryReply, (ReplySwapPtr) SQueryTreeReply, /* 15 */ (ReplySwapPtr) SInternAtomReply, (ReplySwapPtr) SGetAtomNameReply, ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SGetPropertyReply, /* 20 */ (ReplySwapPtr) SListPropertiesReply, ReplyNotSwappd, (ReplySwapPtr) SGetSelectionOwnerReply, ReplyNotSwappd, ReplyNotSwappd, /* 25 */ (ReplySwapPtr) SGenericReply, /* SGrabPointerReply, */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 30 */ (ReplySwapPtr) SGenericReply, /* SGrabKeyboardReply, */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 35 */ ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SQueryPointerReply, (ReplySwapPtr) SGetMotionEventsReply, (ReplySwapPtr) STranslateCoordsReply, /* 40 */ ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SGetInputFocusReply, (ReplySwapPtr) SQueryKeymapReply, ReplyNotSwappd, /* 45 */ ReplyNotSwappd, (ReplySwapPtr) SQueryFontReply, (ReplySwapPtr) SQueryTextExtentsReply, (ReplySwapPtr) SListFontsReply, (ReplySwapPtr) SListFontsWithInfoReply, /* 50 */ ReplyNotSwappd, (ReplySwapPtr) SGetFontPathReply, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 55 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 60 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 65 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 70 */ ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SGetImageReply, ReplyNotSwappd, ReplyNotSwappd, /* 75 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 80 */ ReplyNotSwappd, ReplyNotSwappd, (ReplySwapPtr) SListInstalledColormapsReply, (ReplySwapPtr) SAllocColorReply, (ReplySwapPtr) SAllocNamedColorReply, /* 85 */ (ReplySwapPtr) SAllocColorCellsReply, (ReplySwapPtr) SAllocColorPlanesReply, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 90 */ (ReplySwapPtr) SQueryColorsReply, (ReplySwapPtr) SLookupColorReply, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 95 */ ReplyNotSwappd, (ReplySwapPtr) SQueryBestSizeReply, (ReplySwapPtr) SGenericReply, /* SQueryExtensionReply, */ (ReplySwapPtr) SListExtensionsReply, ReplyNotSwappd, /* 100 */ (ReplySwapPtr) SGetKeyboardMappingReply, ReplyNotSwappd, (ReplySwapPtr) SGetKeyboardControlReply, ReplyNotSwappd, ReplyNotSwappd, /* 105 */ (ReplySwapPtr) SGetPointerControlReply, ReplyNotSwappd, (ReplySwapPtr) SGetScreenSaverReply, ReplyNotSwappd, (ReplySwapPtr) SListHostsReply, /* 110 */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, /* 115 */ (ReplySwapPtr) SGenericReply, /* SetPointerMapping */ (ReplySwapPtr) SGetPointerMappingReply, (ReplySwapPtr) SGenericReply, /* SetModifierMapping */ (ReplySwapPtr) SGetModifierMappingReply, /* 119 */ ReplyNotSwappd, /* 120 */ ReplyNotSwappd, /* 121 */ ReplyNotSwappd, /* 122 */ ReplyNotSwappd, /* 123 */ ReplyNotSwappd, /* 124 */ ReplyNotSwappd, /* 125 */ ReplyNotSwappd, /* 126 */ ReplyNotSwappd, /* NoOperation */ ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd, ReplyNotSwappd }; xorg-server-1.20.13/dix/touch.c0000644000175000017500000007711714100573756013161 00000000000000/* * Copyright © 2011 Collabra Ltd. * Copyright © 2011 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Daniel Stone */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "inputstr.h" #include "scrnintstr.h" #include "dixgrabs.h" #include "eventstr.h" #include "exevents.h" #include "exglobals.h" #include "inpututils.h" #include "eventconvert.h" #include "windowstr.h" #include "mi.h" #define TOUCH_HISTORY_SIZE 100 /** * Some documentation about touch points: * The driver submits touch events with it's own (unique) touch point ID. * The driver may re-use those IDs, the DDX doesn't care. It just passes on * the data to the DIX. In the server, the driver's ID is referred to as the * DDX id anyway. * * On a TouchBegin, we create a DDXTouchPointInfo that contains the DDX id * and the client ID that this touchpoint will have. The client ID is the * one visible on the protocol. * * TouchUpdate and TouchEnd will only be processed if there is an active * touchpoint with the same DDX id. * * The DDXTouchPointInfo struct is stored dev->last.touches. When the event * being processed, it becomes a TouchPointInfo in dev->touch-touches which * contains amongst other things the sprite trace and delivery information. */ /** * Check which devices need a bigger touch event queue and grow their * last.touches by half it's current size. * * @param client Always the serverClient * @param closure Always NULL * * @return Always True. If we fail to grow we probably will topple over soon * anyway and re-executing this won't help. */ static Bool TouchResizeQueue(DeviceIntPtr dev) { DDXTouchPointInfoPtr tmp; size_t size; /* Grow sufficiently so we don't need to do it often */ size = dev->last.num_touches + dev->last.num_touches / 2 + 1; tmp = reallocarray(dev->last.touches, size, sizeof(*dev->last.touches)); if (tmp) { int j; dev->last.touches = tmp; for (j = dev->last.num_touches; j < size; j++) TouchInitDDXTouchPoint(dev, &dev->last.touches[j]); dev->last.num_touches = size; return TRUE; } return FALSE; } /** * Given the DDX-facing ID (which is _not_ DeviceEvent::detail.touch), find the * associated DDXTouchPointInfoRec. * * @param dev The device to create the touch point for * @param ddx_id Touch id assigned by the driver/ddx * @param create Create the touchpoint if it cannot be found */ DDXTouchPointInfoPtr TouchFindByDDXID(DeviceIntPtr dev, uint32_t ddx_id, Bool create) { DDXTouchPointInfoPtr ti; int i; if (!dev->touch) return NULL; for (i = 0; i < dev->last.num_touches; i++) { ti = &dev->last.touches[i]; if (ti->active && ti->ddx_id == ddx_id) return ti; } return create ? TouchBeginDDXTouch(dev, ddx_id) : NULL; } /** * Given a unique DDX ID for a touchpoint, create a touchpoint record and * return it. * * If no other touch points are active, mark new touchpoint for pointer * emulation. * * Returns NULL on failure (i.e. if another touch with that ID is already active, * allocation failure). */ DDXTouchPointInfoPtr TouchBeginDDXTouch(DeviceIntPtr dev, uint32_t ddx_id) { static int next_client_id = 1; int i; TouchClassPtr t = dev->touch; DDXTouchPointInfoPtr ti = NULL; Bool emulate_pointer; if (!t) return NULL; emulate_pointer = (t->mode == XIDirectTouch); /* Look for another active touchpoint with the same DDX ID. DDX * touchpoints must be unique. */ if (TouchFindByDDXID(dev, ddx_id, FALSE)) return NULL; for (;;) { for (i = 0; i < dev->last.num_touches; i++) { /* Only emulate pointer events on the first touch */ if (dev->last.touches[i].active) emulate_pointer = FALSE; else if (!ti) /* ti is now first non-active touch rec */ ti = &dev->last.touches[i]; if (!emulate_pointer && ti) break; } if (ti) break; if (!TouchResizeQueue(dev)) break; } if (ti) { int client_id; ti->active = TRUE; ti->ddx_id = ddx_id; client_id = next_client_id; next_client_id++; if (next_client_id == 0) next_client_id = 1; ti->client_id = client_id; ti->emulate_pointer = emulate_pointer; } return ti; } void TouchEndDDXTouch(DeviceIntPtr dev, DDXTouchPointInfoPtr ti) { TouchClassPtr t = dev->touch; if (!t) return; ti->active = FALSE; } void TouchInitDDXTouchPoint(DeviceIntPtr dev, DDXTouchPointInfoPtr ddxtouch) { memset(ddxtouch, 0, sizeof(*ddxtouch)); ddxtouch->valuators = valuator_mask_new(dev->valuator->numAxes); } Bool TouchInitTouchPoint(TouchClassPtr t, ValuatorClassPtr v, int index) { TouchPointInfoPtr ti; if (index >= t->num_touches) return FALSE; ti = &t->touches[index]; memset(ti, 0, sizeof(*ti)); ti->valuators = valuator_mask_new(v->numAxes); if (!ti->valuators) return FALSE; ti->sprite.spriteTrace = calloc(32, sizeof(*ti->sprite.spriteTrace)); if (!ti->sprite.spriteTrace) { valuator_mask_free(&ti->valuators); return FALSE; } ti->sprite.spriteTraceSize = 32; ti->sprite.spriteTrace[0] = screenInfo.screens[0]->root; ti->sprite.hot.pScreen = screenInfo.screens[0]; ti->sprite.hotPhys.pScreen = screenInfo.screens[0]; ti->client_id = -1; return TRUE; } void TouchFreeTouchPoint(DeviceIntPtr device, int index) { TouchPointInfoPtr ti; int i; if (!device->touch || index >= device->touch->num_touches) return; ti = &device->touch->touches[index]; if (ti->active) TouchEndTouch(device, ti); for (i = 0; i < ti->num_listeners; i++) TouchRemoveListener(ti, ti->listeners[0].listener); valuator_mask_free(&ti->valuators); free(ti->sprite.spriteTrace); ti->sprite.spriteTrace = NULL; free(ti->listeners); ti->listeners = NULL; free(ti->history); ti->history = NULL; ti->history_size = 0; ti->history_elements = 0; } /** * Given a client-facing ID (e.g. DeviceEvent::detail.touch), find the * associated TouchPointInfoRec. */ TouchPointInfoPtr TouchFindByClientID(DeviceIntPtr dev, uint32_t client_id) { TouchClassPtr t = dev->touch; TouchPointInfoPtr ti; int i; if (!t) return NULL; for (i = 0; i < t->num_touches; i++) { ti = &t->touches[i]; if (ti->active && ti->client_id == client_id) return ti; } return NULL; } /** * Given a unique ID for a touchpoint, create a touchpoint record in the * server. * * Returns NULL on failure (i.e. if another touch with that ID is already active, * allocation failure). */ TouchPointInfoPtr TouchBeginTouch(DeviceIntPtr dev, int sourceid, uint32_t touchid, Bool emulate_pointer) { int i; TouchClassPtr t = dev->touch; TouchPointInfoPtr ti; void *tmp; if (!t) return NULL; /* Look for another active touchpoint with the same client ID. It's * technically legitimate for a touchpoint to still exist with the same * ID but only once the 32 bits wrap over and you've used up 4 billion * touch ids without lifting that one finger off once. In which case * you deserve a medal or something, but not error handling code. */ if (TouchFindByClientID(dev, touchid)) return NULL; try_find_touch: for (i = 0; i < t->num_touches; i++) { ti = &t->touches[i]; if (!ti->active) { ti->active = TRUE; ti->client_id = touchid; ti->sourceid = sourceid; ti->emulate_pointer = emulate_pointer; return ti; } } /* If we get here, then we've run out of touches: enlarge dev->touch and * try again. */ tmp = reallocarray(t->touches, t->num_touches + 1, sizeof(*ti)); if (tmp) { t->touches = tmp; t->num_touches++; if (TouchInitTouchPoint(t, dev->valuator, t->num_touches - 1)) goto try_find_touch; } return NULL; } /** * Releases a touchpoint for use: this must only be called after all events * related to that touchpoint have been sent and finalised. Called from * ProcessTouchEvent and friends. Not by you. */ void TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti) { int i; if (ti->emulate_pointer) { GrabPtr grab; if ((grab = dev->deviceGrab.grab)) { if (dev->deviceGrab.fromPassiveGrab && !dev->button->buttonsDown && !dev->touch->buttonsDown && GrabIsPointerGrab(grab)) (*dev->deviceGrab.DeactivateGrab) (dev); } } for (i = 0; i < ti->num_listeners; i++) TouchRemoveListener(ti, ti->listeners[0].listener); ti->active = FALSE; ti->pending_finish = FALSE; ti->sprite.spriteTraceGood = 0; free(ti->listeners); ti->listeners = NULL; ti->num_listeners = 0; ti->num_grabs = 0; ti->client_id = 0; TouchEventHistoryFree(ti); valuator_mask_zero(ti->valuators); } /** * Allocate the event history for this touch pointer. Calling this on a * touchpoint that already has an event history does nothing but counts as * as success. * * @return TRUE on success, FALSE on allocation errors */ Bool TouchEventHistoryAllocate(TouchPointInfoPtr ti) { if (ti->history) return TRUE; ti->history = calloc(TOUCH_HISTORY_SIZE, sizeof(*ti->history)); ti->history_elements = 0; if (ti->history) ti->history_size = TOUCH_HISTORY_SIZE; return ti->history != NULL; } void TouchEventHistoryFree(TouchPointInfoPtr ti) { free(ti->history); ti->history = NULL; ti->history_size = 0; ti->history_elements = 0; } /** * Store the given event on the event history (if one exists) * A touch event history consists of one TouchBegin and several TouchUpdate * events (if applicable) but no TouchEnd event. * If more than one TouchBegin is pushed onto the stack, the push is * ignored, calling this function multiple times for the TouchBegin is * valid. */ void TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev) { if (!ti->history) return; switch (ev->type) { case ET_TouchBegin: /* don't store the same touchbegin twice */ if (ti->history_elements > 0) return; break; case ET_TouchUpdate: break; case ET_TouchEnd: return; /* no TouchEnd events in the history */ default: return; } /* We only store real events in the history */ if (ev->flags & (TOUCH_CLIENT_ID | TOUCH_REPLAYING)) return; ti->history[ti->history_elements++] = *ev; /* FIXME: proper overflow fixes */ if (ti->history_elements > ti->history_size - 1) { ti->history_elements = ti->history_size - 1; DebugF("source device %d: history size %zu overflowing for touch %u\n", ti->sourceid, ti->history_size, ti->client_id); } } void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource) { int i; if (!ti->history) return; TouchDeliverDeviceClassesChangedEvent(ti, ti->history[0].time, resource); for (i = 0; i < ti->history_elements; i++) { DeviceEvent *ev = &ti->history[i]; ev->flags |= TOUCH_REPLAYING; ev->resource = resource; /* FIXME: We're replaying ti->history which contains the TouchBegin + all TouchUpdates for ti. This needs to be passed on to the next listener. If that is a touch listener, everything is dandy. If the TouchBegin however triggers a sync passive grab, the TouchUpdate events must be sent to EnqueueEvent so the events end up in syncEvents.pending to be forwarded correctly in a subsequent ComputeFreeze(). However, if we just send them to EnqueueEvent the sync'ing device prevents handling of touch events for ownership listeners who want the events right here, right now. */ dev->public.processInputProc((InternalEvent*)ev, dev); } } void TouchDeliverDeviceClassesChangedEvent(TouchPointInfoPtr ti, Time time, XID resource) { DeviceIntPtr dev; int num_events = 0; InternalEvent dcce; dixLookupDevice(&dev, ti->sourceid, serverClient, DixWriteAccess); if (!dev) return; /* UpdateFromMaster generates at most one event */ UpdateFromMaster(&dcce, dev, DEVCHANGE_POINTER_EVENT, &num_events); BUG_WARN(num_events > 1); if (num_events) { dcce.any.time = time; /* FIXME: This doesn't do anything */ dev->public.processInputProc(&dcce, dev); } } Bool TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite) { int i; TouchClassPtr t = dev->touch; WindowPtr *trace; SpritePtr srcsprite; /* All touches should have the same sprite trace, so find and reuse an * existing touch's sprite if possible, else use the device's sprite. */ for (i = 0; i < t->num_touches; i++) if (!t->touches[i].pending_finish && t->touches[i].sprite.spriteTraceGood > 0) break; if (i < t->num_touches) srcsprite = &t->touches[i].sprite; else if (dev->spriteInfo->sprite) srcsprite = dev->spriteInfo->sprite; else return FALSE; if (srcsprite->spriteTraceGood > sprite->spriteTraceSize) { trace = reallocarray(sprite->spriteTrace, srcsprite->spriteTraceSize, sizeof(*trace)); if (!trace) { sprite->spriteTraceGood = 0; return FALSE; } sprite->spriteTrace = trace; sprite->spriteTraceSize = srcsprite->spriteTraceGood; } memcpy(sprite->spriteTrace, srcsprite->spriteTrace, srcsprite->spriteTraceGood * sizeof(*trace)); sprite->spriteTraceGood = srcsprite->spriteTraceGood; return TRUE; } /** * Ensure a window trace is present in ti->sprite, constructing one for * TouchBegin events. */ Bool TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, InternalEvent *ev) { TouchClassPtr t = sourcedev->touch; SpritePtr sprite = &ti->sprite; if (t->mode == XIDirectTouch) { /* Focus immediately under the touchpoint in direct touch mode. * XXX: Do we need to handle crossing screens here? */ sprite->spriteTrace[0] = sourcedev->spriteInfo->sprite->hotPhys.pScreen->root; XYToWindow(sprite, ev->device_event.root_x, ev->device_event.root_y); } else if (!TouchBuildDependentSpriteTrace(sourcedev, sprite)) return FALSE; if (sprite->spriteTraceGood <= 0) return FALSE; /* Mark which grabs/event selections we're delivering to: max one grab per * window plus the bottom-most event selection, plus any active grab. */ ti->listeners = calloc(sprite->spriteTraceGood + 2, sizeof(*ti->listeners)); if (!ti->listeners) { sprite->spriteTraceGood = 0; return FALSE; } ti->num_listeners = 0; return TRUE; } /** * Copy the touch event into the pointer_event, switching the required * fields to make it a correct pointer event. * * @param event The original touch event * @param[in] motion_event The respective motion event * @param[in] button_event The respective button event (if any) * * @returns The number of converted events. * @retval 0 An error occured * @retval 1 only the motion event is valid * @retval 2 motion and button event are valid */ int TouchConvertToPointerEvent(const InternalEvent *event, InternalEvent *motion_event, InternalEvent *button_event) { int ptrtype; int nevents = 0; BUG_RETURN_VAL(!event, 0); BUG_RETURN_VAL(!motion_event, 0); switch (event->any.type) { case ET_TouchUpdate: nevents = 1; break; case ET_TouchBegin: nevents = 2; /* motion + press */ ptrtype = ET_ButtonPress; break; case ET_TouchEnd: nevents = 2; /* motion + release */ ptrtype = ET_ButtonRelease; break; default: BUG_WARN_MSG(1, "Invalid event type %d\n", event->any.type); return 0; } BUG_WARN_MSG(!(event->device_event.flags & TOUCH_POINTER_EMULATED), "Non-emulating touch event\n"); motion_event->device_event = event->device_event; motion_event->any.type = ET_Motion; motion_event->device_event.detail.button = 0; motion_event->device_event.flags = XIPointerEmulated; if (nevents > 1) { BUG_RETURN_VAL(!button_event, 0); button_event->device_event = event->device_event; button_event->any.type = ptrtype; button_event->device_event.flags = XIPointerEmulated; /* detail is already correct */ } return nevents; } /** * Return the corresponding pointer emulation internal event type for the given * touch event or 0 if no such event type exists. */ int TouchGetPointerEventType(const InternalEvent *event) { int type = 0; switch (event->any.type) { case ET_TouchBegin: type = ET_ButtonPress; break; case ET_TouchUpdate: type = ET_Motion; break; case ET_TouchEnd: type = ET_ButtonRelease; break; default: break; } return type; } /** * @returns TRUE if the specified grab or selection is the current owner of * the touch sequence. */ Bool TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource) { return (ti->listeners[0].listener == resource); } /** * Add the resource to this touch's listeners. */ void TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type, enum InputLevel level, enum TouchListenerType type, enum TouchListenerState state, WindowPtr window, const GrabPtr grab) { GrabPtr g = NULL; /* We need a copy of the grab, not the grab itself since that may be * deleted by a UngrabButton request and leaves us with a dangling * pointer */ if (grab) g = AllocGrab(grab); ti->listeners[ti->num_listeners].listener = resource; ti->listeners[ti->num_listeners].resource_type = resource_type; ti->listeners[ti->num_listeners].level = level; ti->listeners[ti->num_listeners].state = state; ti->listeners[ti->num_listeners].type = type; ti->listeners[ti->num_listeners].window = window; ti->listeners[ti->num_listeners].grab = g; if (grab) ti->num_grabs++; ti->num_listeners++; } /** * Remove the resource from this touch's listeners. * * @return TRUE if the resource was removed, FALSE if the resource was not * in the list */ Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource) { int i; for (i = 0; i < ti->num_listeners; i++) { int j; TouchListener *listener = &ti->listeners[i]; if (listener->listener != resource) continue; if (listener->grab) { FreeGrab(listener->grab); listener->grab = NULL; ti->num_grabs--; } for (j = i; j < ti->num_listeners - 1; j++) ti->listeners[j] = ti->listeners[j + 1]; ti->num_listeners--; ti->listeners[ti->num_listeners].listener = 0; ti->listeners[ti->num_listeners].state = LISTENER_AWAITING_BEGIN; return TRUE; } return FALSE; } static void TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev, GrabPtr grab) { enum TouchListenerType type = LISTENER_GRAB; /* FIXME: owner_events */ if (grab->grabtype == XI2) { if (!xi2mask_isset(grab->xi2mask, dev, XI_TouchOwnership)) TouchEventHistoryAllocate(ti); if (!xi2mask_isset(grab->xi2mask, dev, XI_TouchBegin)) type = LISTENER_POINTER_GRAB; } else if (grab->grabtype == XI || grab->grabtype == CORE) { TouchEventHistoryAllocate(ti); type = LISTENER_POINTER_GRAB; } /* grab listeners are always RT_NONE since we keep the grab pointer */ TouchAddListener(ti, grab->resource, RT_NONE, grab->grabtype, type, LISTENER_AWAITING_BEGIN, grab->window, grab); } /** * Add one listener if there is a grab on the given window. */ static void TouchAddPassiveGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti, WindowPtr win, InternalEvent *ev) { GrabPtr grab; Bool check_core = IsMaster(dev) && ti->emulate_pointer; /* FIXME: make CheckPassiveGrabsOnWindow only trigger on TouchBegin */ grab = CheckPassiveGrabsOnWindow(win, dev, ev, check_core, FALSE); if (!grab) return; TouchAddGrabListener(dev, ti, ev, grab); } static Bool TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, WindowPtr win, InternalEvent *ev) { InputClients *iclients = NULL; OtherInputMasks *inputMasks = NULL; uint16_t evtype = 0; /* may be event type or emulated event type */ enum TouchListenerType type = LISTENER_REGULAR; int mask; evtype = GetXI2Type(ev->any.type); mask = EventIsDeliverable(dev, ev->any.type, win); if (!mask && !ti->emulate_pointer) return FALSE; else if (!mask) { /* now try for pointer event */ mask = EventIsDeliverable(dev, TouchGetPointerEventType(ev), win); if (mask) { evtype = GetXI2Type(TouchGetPointerEventType(ev)); type = LISTENER_POINTER_REGULAR; } } if (!mask) return FALSE; inputMasks = wOtherInputMasks(win); if (mask & EVENT_XI2_MASK) { nt_list_for_each_entry(iclients, inputMasks->inputClients, next) { if (!xi2mask_isset(iclients->xi2mask, dev, evtype)) continue; if (!xi2mask_isset(iclients->xi2mask, dev, XI_TouchOwnership)) TouchEventHistoryAllocate(ti); TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI2, type, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; } } if (mask & EVENT_XI1_MASK) { int xitype = GetXIType(TouchGetPointerEventType(ev)); Mask xi_filter = event_get_filter_from_type(dev, xitype); nt_list_for_each_entry(iclients, inputMasks->inputClients, next) { if (!(iclients->mask[dev->id] & xi_filter)) continue; TouchEventHistoryAllocate(ti); TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI, LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; } } if (mask & EVENT_CORE_MASK) { int coretype = GetCoreType(TouchGetPointerEventType(ev)); Mask core_filter = event_get_filter_from_type(dev, coretype); OtherClients *oclients; /* window owner */ if (IsMaster(dev) && (win->eventMask & core_filter)) { TouchEventHistoryAllocate(ti); TouchAddListener(ti, win->drawable.id, RT_WINDOW, CORE, LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; } /* all others */ nt_list_for_each_entry(oclients, wOtherClients(win), next) { if (!(oclients->mask & core_filter)) continue; TouchEventHistoryAllocate(ti); TouchAddListener(ti, oclients->resource, RT_OTHERCLIENT, CORE, type, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; } } return FALSE; } static void TouchAddActiveGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev, GrabPtr grab) { if (!ti->emulate_pointer && (grab->grabtype == CORE || grab->grabtype == XI)) return; if (!ti->emulate_pointer && grab->grabtype == XI2 && !xi2mask_isset(grab->xi2mask, dev, XI_TouchBegin)) return; TouchAddGrabListener(dev, ti, ev, grab); } void TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev) { int i; SpritePtr sprite = &ti->sprite; WindowPtr win; if (dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab) TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab); /* We set up an active touch listener for existing touches, but not any * passive grab or regular listeners. */ if (ev->any.type != ET_TouchBegin) return; /* First, find all grabbing clients from the root window down * to the deepest child window. */ for (i = 0; i < sprite->spriteTraceGood; i++) { win = sprite->spriteTrace[i]; TouchAddPassiveGrabListener(dev, ti, win, ev); } /* Find the first client with an applicable event selection, * going from deepest child window back up to the root window. */ for (i = sprite->spriteTraceGood - 1; i >= 0; i--) { Bool delivered; win = sprite->spriteTrace[i]; delivered = TouchAddRegularListener(dev, ti, win, ev); if (delivered) return; } } /** * Remove the touch pointer grab from the device. Called from * DeactivatePointerGrab() */ void TouchRemovePointerGrab(DeviceIntPtr dev) { TouchPointInfoPtr ti; GrabPtr grab; DeviceEvent *ev; if (!dev->touch) return; grab = dev->deviceGrab.grab; if (!grab) return; ev = dev->deviceGrab.sync.event; if (!IsTouchEvent((InternalEvent *) ev)) return; ti = TouchFindByClientID(dev, ev->touchid); if (!ti) return; /* FIXME: missing a bit of code here... */ } /* As touch grabs don't turn into active grabs with their own resources, we * need to walk all the touches and remove this grab from any delivery * lists. */ void TouchListenerGone(XID resource) { TouchPointInfoPtr ti; DeviceIntPtr dev; InternalEvent *events = InitEventList(GetMaximumEventsNum()); int i, j, k, nev; if (!events) FatalError("TouchListenerGone: couldn't allocate events\n"); for (dev = inputInfo.devices; dev; dev = dev->next) { if (!dev->touch) continue; for (i = 0; i < dev->touch->num_touches; i++) { ti = &dev->touch->touches[i]; if (!ti->active) continue; for (j = 0; j < ti->num_listeners; j++) { if (CLIENT_BITS(ti->listeners[j].listener) != resource) continue; nev = GetTouchOwnershipEvents(events, dev, ti, XIRejectTouch, ti->listeners[j].listener, 0); for (k = 0; k < nev; k++) mieqProcessDeviceEvent(dev, events + k, NULL); break; } } } FreeEventList(events, GetMaximumEventsNum()); } int TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener, int mode) { InternalEvent *events; int nev; int i; BUG_RETURN_VAL(listener < 0, BadMatch); BUG_RETURN_VAL(listener >= ti->num_listeners, BadMatch); if (listener > 0) { if (mode == XIRejectTouch) TouchRejected(dev, ti, ti->listeners[listener].listener, NULL); else ti->listeners[listener].state = LISTENER_EARLY_ACCEPT; return Success; } events = InitEventList(GetMaximumEventsNum()); BUG_RETURN_VAL_MSG(!events, BadAlloc, "Failed to allocate touch ownership events\n"); nev = GetTouchOwnershipEvents(events, dev, ti, mode, ti->listeners[0].listener, 0); BUG_WARN_MSG(nev == 0, "Failed to get touch ownership events\n"); for (i = 0; i < nev; i++) mieqProcessDeviceEvent(dev, events + i, NULL); FreeEventList(events, GetMaximumEventsNum()); return nev ? Success : BadMatch; } int TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode, uint32_t touchid, Window grab_window, XID *error) { TouchPointInfoPtr ti; int i; if (!dev->touch) { *error = dev->id; return BadDevice; } ti = TouchFindByClientID(dev, touchid); if (!ti) { *error = touchid; return BadValue; } for (i = 0; i < ti->num_listeners; i++) { if (CLIENT_ID(ti->listeners[i].listener) == client->index && ti->listeners[i].window->drawable.id == grab_window) break; } if (i == ti->num_listeners) return BadAccess; return TouchListenerAcceptReject(dev, ti, i, mode); } /** * End physically active touches for a device. */ void TouchEndPhysicallyActiveTouches(DeviceIntPtr dev) { InternalEvent *eventlist = InitEventList(GetMaximumEventsNum()); int i; input_lock(); mieqProcessInputEvents(); for (i = 0; i < dev->last.num_touches; i++) { DDXTouchPointInfoPtr ddxti = dev->last.touches + i; if (ddxti->active) { int j; int nevents = GetTouchEvents(eventlist, dev, ddxti->ddx_id, XI_TouchEnd, 0, NULL); for (j = 0; j < nevents; j++) mieqProcessDeviceEvent(dev, eventlist + j, NULL); } } input_unlock(); FreeEventList(eventlist, GetMaximumEventsNum()); } /** * Generate and deliver a TouchEnd event. * * @param dev The device to deliver the event for. * @param ti The touch point record to deliver the event for. * @param flags Internal event flags. The called does not need to provide * TOUCH_CLIENT_ID and TOUCH_POINTER_EMULATED, this function will ensure * they are set appropriately. * @param resource The client resource to deliver to, or 0 for all clients. */ void TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource) { InternalEvent event; /* We're not processing a touch end for a frozen device */ if (dev->deviceGrab.sync.frozen) return; flags |= TOUCH_CLIENT_ID; if (ti->emulate_pointer) flags |= TOUCH_POINTER_EMULATED; TouchDeliverDeviceClassesChangedEvent(ti, GetTimeInMillis(), resource); GetDixTouchEnd(&event, dev, ti, flags); DeliverTouchEvents(dev, ti, &event, resource); if (ti->num_grabs == 0) UpdateDeviceState(dev, &event.device_event); } void TouchAcceptAndEnd(DeviceIntPtr dev, int touchid) { TouchPointInfoPtr ti = TouchFindByClientID(dev, touchid); if (!ti) return; TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch); if (ti->pending_finish) TouchEmitTouchEnd(dev, ti, 0, 0); if (ti->num_listeners <= 1) TouchEndTouch(dev, ti); } xorg-server-1.20.13/dix/window.c0000644000175000017500000034664714100573756013355 00000000000000/* Copyright (c) 2006, Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright 1987, 1998 The Open Group 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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, 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 Digital not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL 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. */ /* The panoramix components contained the following notice */ /***************************************************************** Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Digital Equipment Corporation shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Digital Equipment Corporation. ******************************************************************/ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "misc.h" #include "scrnintstr.h" #include "os.h" #include "regionstr.h" #include "validate.h" #include "windowstr.h" #include "propertyst.h" #include "input.h" #include "inputstr.h" #include "resource.h" #include "colormapst.h" #include "cursorstr.h" #include "dixstruct.h" #include "gcstruct.h" #include "servermd.h" #include "mivalidate.h" #ifdef PANORAMIX #include "panoramiX.h" #include "panoramiXsrv.h" #endif #include "dixevents.h" #include "globals.h" #include "mi.h" /* miPaintWindow */ #ifdef COMPOSITE #include "compint.h" #endif #include "selection.h" #include "inpututils.h" #include "privates.h" #include "xace.h" #include "exevents.h" #include /* must come after server includes */ /****** * Window stuff for server * * CreateRootWindow, CreateWindow, ChangeWindowAttributes, * GetWindowAttributes, DeleteWindow, DestroySubWindows, * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows, * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow, * ChangeWindowDeviceCursor ******/ Bool bgNoneRoot = FALSE; static unsigned char _back_lsb[4] = { 0x88, 0x22, 0x44, 0x11 }; static unsigned char _back_msb[4] = { 0x11, 0x44, 0x22, 0x88 }; static Bool WindowParentHasDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCurs); static Bool WindowSeekDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, DevCursNodePtr * pNode, DevCursNodePtr * pPrev); int screenIsSaved = SCREEN_SAVER_OFF; static Bool TileScreenSaver(ScreenPtr pScreen, int kind); #define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \ CWDontPropagate | CWOverrideRedirect | CWCursor ) #define BOXES_OVERLAP(b1, b2) \ (!( ((b1)->x2 <= (b2)->x1) || \ ( ((b1)->x1 >= (b2)->x2)) || \ ( ((b1)->y2 <= (b2)->y1)) || \ ( ((b1)->y1 >= (b2)->y2)) ) ) #define RedirectSend(pWin) \ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask) #define SubSend(pWin) \ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask) #define StrSend(pWin) \ ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask) #define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent)) #ifdef COMPOSITE static const char *overlay_win_name = ""; #endif static const char * get_window_name(WindowPtr pWin) { #define WINDOW_NAME_BUF_LEN 512 PropertyPtr prop; static char buf[WINDOW_NAME_BUF_LEN]; int len; #ifdef COMPOSITE CompScreenPtr comp_screen = GetCompScreen(pWin->drawable.pScreen); if (comp_screen && pWin == comp_screen->pOverlayWin) return overlay_win_name; #endif for (prop = wUserProps(pWin); prop; prop = prop->next) { if (prop->propertyName == XA_WM_NAME && prop->type == XA_STRING && prop->data) { len = min(prop->size, WINDOW_NAME_BUF_LEN - 1); memcpy(buf, prop->data, len); buf[len] = '\0'; return buf; } } return NULL; #undef WINDOW_NAME_BUF_LEN } static void log_window_info(WindowPtr pWin, int depth) { int i; const char *win_name, *visibility; BoxPtr rects; for (i = 0; i < (depth << 2); i++) ErrorF(" "); win_name = get_window_name(pWin); ErrorF("win 0x%.8x (%s), [%d, %d] to [%d, %d]", (unsigned) pWin->drawable.id, win_name ? win_name : "no name", pWin->drawable.x, pWin->drawable.y, pWin->drawable.x + pWin->drawable.width, pWin->drawable.y + pWin->drawable.height); if (pWin->overrideRedirect) ErrorF(" (override redirect)"); #ifdef COMPOSITE if (pWin->redirectDraw) ErrorF(" (%s compositing: pixmap %x)", (pWin->redirectDraw == RedirectDrawAutomatic) ? "automatic" : "manual", (unsigned) pWin->drawable.pScreen->GetWindowPixmap(pWin)->drawable.id); #endif switch (pWin->visibility) { case VisibilityUnobscured: visibility = "unobscured"; break; case VisibilityPartiallyObscured: visibility = "partially obscured"; break; case VisibilityFullyObscured: visibility = "fully obscured"; break; case VisibilityNotViewable: visibility = "unviewable"; break; } ErrorF(", %s", visibility); if (RegionNotEmpty(&pWin->clipList)) { ErrorF(", clip list:"); rects = RegionRects(&pWin->clipList); for (i = 0; i < RegionNumRects(&pWin->clipList); i++) ErrorF(" [(%d, %d) to (%d, %d)]", rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2); ErrorF("; extents [(%d, %d) to (%d, %d)]", pWin->clipList.extents.x1, pWin->clipList.extents.y1, pWin->clipList.extents.x2, pWin->clipList.extents.y2); } ErrorF("\n"); } static const char* grab_grabtype_to_text(GrabPtr pGrab) { switch (pGrab->grabtype) { case XI2: return "xi2"; case CORE: return "core"; default: return "xi1"; } } static const char* grab_type_to_text(GrabPtr pGrab) { switch (pGrab->type) { case ButtonPress: return "ButtonPress"; case KeyPress: return "KeyPress"; case XI_Enter: return "XI_Enter"; case XI_FocusIn: return "XI_FocusIn"; default: return "unknown?!"; } } static void log_grab_info(void *value, XID id, void *cdata) { int i, j; GrabPtr pGrab = (GrabPtr)value; ErrorF(" grab 0x%lx (%s), type '%s' on window 0x%lx\n", (unsigned long) pGrab->resource, grab_grabtype_to_text(pGrab), grab_type_to_text(pGrab), (unsigned long) pGrab->window->drawable.id); ErrorF(" detail %d (mask %lu), modifiersDetail %d (mask %lu)\n", pGrab->detail.exact, pGrab->detail.pMask ? (unsigned long) *(pGrab->detail.pMask) : 0, pGrab->modifiersDetail.exact, pGrab->modifiersDetail.pMask ? (unsigned long) *(pGrab->modifiersDetail.pMask) : (unsigned long) 0); ErrorF(" device '%s' (%d), modifierDevice '%s' (%d)\n", pGrab->device->name, pGrab->device->id, pGrab->modifierDevice->name, pGrab->modifierDevice->id); if (pGrab->grabtype == CORE) { ErrorF(" core event mask 0x%lx\n", (unsigned long) pGrab->eventMask); } else if (pGrab->grabtype == XI) { ErrorF(" xi1 event mask 0x%lx\n", (unsigned long) pGrab->eventMask); } else if (pGrab->grabtype == XI2) { for (i = 0; i < xi2mask_num_masks(pGrab->xi2mask); i++) { const unsigned char *mask; int print; print = 0; for (j = 0; j < XI2MASKSIZE; j++) { mask = xi2mask_get_one_mask(pGrab->xi2mask, i); if (mask[j]) { print = 1; break; } } if (!print) continue; ErrorF(" xi2 event mask 0x"); for (j = 0; j < xi2mask_mask_size(pGrab->xi2mask); j++) ErrorF("%x ", mask[j]); ErrorF("\n"); } } ErrorF(" owner-events %s, kb %d ptr %d, confine 0x%lx, cursor 0x%lx\n", pGrab->ownerEvents ? "true" : "false", pGrab->keyboardMode, pGrab->pointerMode, pGrab->confineTo ? (unsigned long) pGrab->confineTo->drawable.id : 0, pGrab->cursor ? (unsigned long) pGrab->cursor->id : 0); } void PrintPassiveGrabs(void) { int i; LocalClientCredRec *lcc; pid_t clientpid; const char *cmdname; const char *cmdargs; ErrorF("Printing all currently registered grabs\n"); for (i = 1; i < currentMaxClients; i++) { if (!clients[i] || clients[i]->clientState != ClientStateRunning) continue; clientpid = GetClientPid(clients[i]); cmdname = GetClientCmdName(clients[i]); cmdargs = GetClientCmdArgs(clients[i]); if ((clientpid > 0) && (cmdname != NULL)) { ErrorF(" Printing all registered grabs of client pid %ld %s %s\n", (long) clientpid, cmdname, cmdargs ? cmdargs : ""); } else { if (GetLocalClientCreds(clients[i], &lcc) == -1) { ErrorF(" GetLocalClientCreds() failed\n"); continue; } ErrorF(" Printing all registered grabs of client pid %ld uid %ld gid %ld\n", (lcc->fieldsSet & LCC_PID_SET) ? (long) lcc->pid : 0, (lcc->fieldsSet & LCC_UID_SET) ? (long) lcc->euid : 0, (lcc->fieldsSet & LCC_GID_SET) ? (long) lcc->egid : 0); FreeLocalClientCreds(lcc); } FindClientResourcesByType(clients[i], RT_PASSIVEGRAB, log_grab_info, NULL); } ErrorF("End list of registered passive grabs\n"); } void PrintWindowTree(void) { int scrnum, depth; ScreenPtr pScreen; WindowPtr pWin; for (scrnum = 0; scrnum < screenInfo.numScreens; scrnum++) { pScreen = screenInfo.screens[scrnum]; ErrorF("[dix] Dumping windows for screen %d (pixmap %x):\n", scrnum, (unsigned) pScreen->GetScreenPixmap(pScreen)->drawable.id); pWin = pScreen->root; depth = 1; while (pWin) { log_window_info(pWin, depth); if (pWin->firstChild) { pWin = pWin->firstChild; depth++; continue; } while (pWin && !pWin->nextSib) { pWin = pWin->parent; depth--; } if (!pWin) break; pWin = pWin->nextSib; } } } int TraverseTree(WindowPtr pWin, VisitWindowProcPtr func, void *data) { int result; WindowPtr pChild; if (!(pChild = pWin)) return WT_NOMATCH; while (1) { result = (*func) (pChild, data); if (result == WT_STOPWALKING) return WT_STOPWALKING; if ((result == WT_WALKCHILDREN) && pChild->firstChild) { pChild = pChild->firstChild; continue; } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) break; pChild = pChild->nextSib; } return WT_NOMATCH; } /***** * WalkTree * Walk the window tree, for SCREEN, performing FUNC(pWin, data) on * each window. If FUNC returns WT_WALKCHILDREN, traverse the children, * if it returns WT_DONTWALKCHILDREN, don't. If it returns WT_STOPWALKING, * exit WalkTree. Does depth-first traverse. *****/ int WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, void *data) { return (TraverseTree(pScreen->root, func, data)); } /* hack for forcing backing store on all windows */ int defaultBackingStore = NotUseful; /* hack to force no backing store */ Bool disableBackingStore = FALSE; Bool enableBackingStore = FALSE; static void SetWindowToDefaults(WindowPtr pWin) { pWin->prevSib = NullWindow; pWin->firstChild = NullWindow; pWin->lastChild = NullWindow; pWin->valdata = NULL; pWin->optional = NULL; pWin->cursorIsNone = TRUE; pWin->backingStore = NotUseful; pWin->backStorage = 0; pWin->mapped = FALSE; /* off */ pWin->realized = FALSE; /* off */ pWin->viewable = FALSE; pWin->visibility = VisibilityNotViewable; pWin->overrideRedirect = FALSE; pWin->saveUnder = FALSE; pWin->bitGravity = ForgetGravity; pWin->winGravity = NorthWestGravity; pWin->eventMask = 0; pWin->deliverableEvents = 0; pWin->dontPropagate = 0; pWin->forcedBS = FALSE; pWin->redirectDraw = RedirectDrawNone; pWin->forcedBG = FALSE; pWin->unhittable = FALSE; #ifdef COMPOSITE pWin->damagedDescendants = FALSE; #endif } static void MakeRootTile(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; GCPtr pGC; unsigned char back[128]; int len = BitmapBytePad(sizeof(long)); unsigned char *from, *to; int i, j; pWin->background.pixmap = (*pScreen->CreatePixmap) (pScreen, 4, 4, pScreen->rootDepth, 0); pWin->backgroundState = BackgroundPixmap; pGC = GetScratchGC(pScreen->rootDepth, pScreen); if (!pWin->background.pixmap || !pGC) FatalError("could not create root tile"); { ChangeGCVal attributes[2]; attributes[0].val = pScreen->whitePixel; attributes[1].val = pScreen->blackPixel; (void) ChangeGC(NullClient, pGC, GCForeground | GCBackground, attributes); } ValidateGC((DrawablePtr) pWin->background.pixmap, pGC); from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb; to = back; for (i = 4; i > 0; i--, from++) for (j = len; j > 0; j--) *to++ = *from; (*pGC->ops->PutImage) ((DrawablePtr) pWin->background.pixmap, pGC, 1, 0, 0, len, 4, 0, XYBitmap, (char *) back); FreeScratchGC(pGC); } /***** * CreateRootWindow * Makes a window at initialization time for specified screen *****/ Bool CreateRootWindow(ScreenPtr pScreen) { WindowPtr pWin; BoxRec box; PixmapFormatRec *format; pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW); if (!pWin) return FALSE; pScreen->screensaver.pWindow = NULL; pScreen->screensaver.wid = FakeClientID(0); pScreen->screensaver.ExternalScreenSaver = NULL; screenIsSaved = SCREEN_SAVER_OFF; pScreen->root = pWin; pWin->drawable.pScreen = pScreen; pWin->drawable.type = DRAWABLE_WINDOW; pWin->drawable.depth = pScreen->rootDepth; for (format = screenInfo.formats; format->depth != pScreen->rootDepth; format++); pWin->drawable.bitsPerPixel = format->bitsPerPixel; pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; pWin->parent = NullWindow; SetWindowToDefaults(pWin); pWin->optional = malloc(sizeof(WindowOptRec)); if (!pWin->optional) return FALSE; pWin->optional->dontPropagateMask = 0; pWin->optional->otherEventMasks = 0; pWin->optional->otherClients = NULL; pWin->optional->passiveGrabs = NULL; pWin->optional->userProps = NULL; pWin->optional->backingBitPlanes = ~0L; pWin->optional->backingPixel = 0; pWin->optional->boundingShape = NULL; pWin->optional->clipShape = NULL; pWin->optional->inputShape = NULL; pWin->optional->inputMasks = NULL; pWin->optional->deviceCursors = NULL; pWin->optional->colormap = pScreen->defColormap; pWin->optional->visual = pScreen->rootVisual; pWin->nextSib = NullWindow; pWin->drawable.id = FakeClientID(0); pWin->origin.x = pWin->origin.y = 0; pWin->drawable.height = pScreen->height; pWin->drawable.width = pScreen->width; pWin->drawable.x = pWin->drawable.y = 0; box.x1 = 0; box.y1 = 0; box.x2 = pScreen->width; box.y2 = pScreen->height; RegionInit(&pWin->clipList, &box, 1); RegionInit(&pWin->winSize, &box, 1); RegionInit(&pWin->borderSize, &box, 1); RegionInit(&pWin->borderClip, &box, 1); pWin->drawable.class = InputOutput; pWin->optional->visual = pScreen->rootVisual; pWin->backgroundState = BackgroundPixel; pWin->background.pixel = pScreen->whitePixel; pWin->borderIsPixel = TRUE; pWin->border.pixel = pScreen->blackPixel; pWin->borderWidth = 0; /* security creation/labeling check */ if (XaceHook(XACE_RESOURCE_ACCESS, serverClient, pWin->drawable.id, RT_WINDOW, pWin, RT_NONE, NULL, DixCreateAccess)) return FALSE; if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pWin)) return FALSE; if (disableBackingStore) pScreen->backingStoreSupport = NotUseful; if (enableBackingStore) pScreen->backingStoreSupport = WhenMapped; #ifdef COMPOSITE if (noCompositeExtension) pScreen->backingStoreSupport = NotUseful; #endif pScreen->saveUnderSupport = NotUseful; return TRUE; } void InitRootWindow(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; int backFlag = CWBorderPixel | CWCursor | CWBackingStore; if (!(*pScreen->CreateWindow) (pWin)) return; /* XXX */ (*pScreen->PositionWindow) (pWin, 0, 0); pWin->cursorIsNone = FALSE; pWin->optional->cursor = RefCursor(rootCursor); if (party_like_its_1989) { MakeRootTile(pWin); backFlag |= CWBackPixmap; } else if (pScreen->canDoBGNoneRoot && bgNoneRoot) { pWin->backgroundState = XaceBackgroundNoneState(pWin); pWin->background.pixel = pScreen->whitePixel; backFlag |= CWBackPixmap; } else { pWin->backgroundState = BackgroundPixel; if (whiteRoot) pWin->background.pixel = pScreen->whitePixel; else pWin->background.pixel = pScreen->blackPixel; backFlag |= CWBackPixel; } pWin->backingStore = defaultBackingStore; pWin->forcedBS = (defaultBackingStore != NotUseful); /* We SHOULD check for an error value here XXX */ (*pScreen->ChangeWindowAttributes) (pWin, backFlag); MapWindow(pWin, serverClient); } /* Set the region to the intersection of the rectangle and the * window's winSize. The window is typically the parent of the * window from which the region came. */ static void ClippedRegionFromBox(WindowPtr pWin, RegionPtr Rgn, int x, int y, int w, int h) { BoxRec box = *RegionExtents(&pWin->winSize); /* we do these calculations to avoid overflows */ if (x > box.x1) box.x1 = x; if (y > box.y1) box.y1 = y; x += w; if (x < box.x2) box.x2 = x; y += h; if (y < box.y2) box.y2 = y; if (box.x1 > box.x2) box.x2 = box.x1; if (box.y1 > box.y2) box.y2 = box.y1; RegionReset(Rgn, &box); RegionIntersect(Rgn, Rgn, &pWin->winSize); } static RealChildHeadProc realChildHeadProc = NULL; void RegisterRealChildHeadProc(RealChildHeadProc proc) { realChildHeadProc = proc; } WindowPtr RealChildHead(WindowPtr pWin) { if (realChildHeadProc) { return realChildHeadProc(pWin); } if (!pWin->parent && (screenIsSaved == SCREEN_SAVER_ON) && (HasSaverWindow(pWin->drawable.pScreen))) return pWin->firstChild; else return NullWindow; } /***** * CreateWindow * Makes a window in response to client request *****/ WindowPtr CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, unsigned h, unsigned bw, unsigned class, Mask vmask, XID *vlist, int depth, ClientPtr client, VisualID visual, int *error) { WindowPtr pWin; WindowPtr pHead; ScreenPtr pScreen; int idepth, ivisual; Bool fOK; DepthPtr pDepth; PixmapFormatRec *format; WindowOptPtr ancwopt; if (class == CopyFromParent) class = pParent->drawable.class; if ((class != InputOutput) && (class != InputOnly)) { *error = BadValue; client->errorValue = class; return NullWindow; } if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) { *error = BadMatch; return NullWindow; } if ((class == InputOnly) && ((bw != 0) || (depth != 0))) { *error = BadMatch; return NullWindow; } pScreen = pParent->drawable.pScreen; if ((class == InputOutput) && (depth == 0)) depth = pParent->drawable.depth; ancwopt = pParent->optional; if (!ancwopt) ancwopt = FindWindowWithOptional(pParent)->optional; if (visual == CopyFromParent) { visual = ancwopt->visual; } /* Find out if the depth and visual are acceptable for this Screen */ if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) { fOK = FALSE; for (idepth = 0; idepth < pScreen->numDepths; idepth++) { pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; if ((depth == pDepth->depth) || (depth == 0)) { for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) { if (visual == pDepth->vids[ivisual]) { fOK = TRUE; break; } } } } if (fOK == FALSE) { *error = BadMatch; return NullWindow; } } if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) && (class != InputOnly) && (depth != pParent->drawable.depth)) { *error = BadMatch; return NullWindow; } if (((vmask & CWColormap) == 0) && (class != InputOnly) && ((visual != ancwopt->visual) || (ancwopt->colormap == None))) { *error = BadMatch; return NullWindow; } pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW); if (!pWin) { *error = BadAlloc; return NullWindow; } pWin->drawable = pParent->drawable; pWin->drawable.depth = depth; if (depth == pParent->drawable.depth) pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel; else { for (format = screenInfo.formats; format->depth != depth; format++); pWin->drawable.bitsPerPixel = format->bitsPerPixel; } if (class == InputOnly) pWin->drawable.type = (short) UNDRAWABLE_WINDOW; pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; pWin->drawable.id = wid; pWin->drawable.class = class; pWin->parent = pParent; SetWindowToDefaults(pWin); if (visual != ancwopt->visual) { if (!MakeWindowOptional(pWin)) { dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); *error = BadAlloc; return NullWindow; } pWin->optional->visual = visual; pWin->optional->colormap = None; } pWin->borderWidth = bw; /* security creation/labeling check */ *error = XaceHook(XACE_RESOURCE_ACCESS, client, wid, RT_WINDOW, pWin, RT_WINDOW, pWin->parent, DixCreateAccess | DixSetAttrAccess); if (*error != Success) { dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); return NullWindow; } pWin->backgroundState = XaceBackgroundNoneState(pWin); pWin->background.pixel = pScreen->whitePixel; pWin->borderIsPixel = pParent->borderIsPixel; pWin->border = pParent->border; if (pWin->borderIsPixel == FALSE) pWin->border.pixmap->refcnt++; pWin->origin.x = x + (int) bw; pWin->origin.y = y + (int) bw; pWin->drawable.width = w; pWin->drawable.height = h; pWin->drawable.x = pParent->drawable.x + x + (int) bw; pWin->drawable.y = pParent->drawable.y + y + (int) bw; /* set up clip list correctly for unobscured WindowPtr */ RegionNull(&pWin->clipList); RegionNull(&pWin->borderClip); RegionNull(&pWin->winSize); RegionNull(&pWin->borderSize); pHead = RealChildHead(pParent); if (pHead) { pWin->nextSib = pHead->nextSib; if (pHead->nextSib) pHead->nextSib->prevSib = pWin; else pParent->lastChild = pWin; pHead->nextSib = pWin; pWin->prevSib = pHead; } else { pWin->nextSib = pParent->firstChild; if (pParent->firstChild) pParent->firstChild->prevSib = pWin; else pParent->lastChild = pWin; pParent->firstChild = pWin; } SetWinSize(pWin); SetBorderSize(pWin); /* We SHOULD check for an error value here XXX */ if (!(*pScreen->CreateWindow) (pWin)) { *error = BadAlloc; DeleteWindow(pWin, None); return NullWindow; } /* We SHOULD check for an error value here XXX */ (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y); if (!(vmask & CWEventMask)) RecalculateDeliverableEvents(pWin); if (vmask) *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient(pWin)); else *error = Success; if (*error != Success) { DeleteWindow(pWin, None); return NullWindow; } if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful)) { XID value = defaultBackingStore; (void) ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient(pWin)); pWin->forcedBS = TRUE; } if (SubSend(pParent)) { xEvent event = { .u.createNotify.window = wid, .u.createNotify.parent = pParent->drawable.id, .u.createNotify.x = x, .u.createNotify.y = y, .u.createNotify.width = w, .u.createNotify.height = h, .u.createNotify.borderWidth = bw, .u.createNotify.override = pWin->overrideRedirect }; event.u.u.type = CreateNotify; DeliverEvents(pParent, &event, 1, NullWindow); } return pWin; } static void DisposeWindowOptional(WindowPtr pWin) { if (!pWin->optional) return; /* * everything is peachy. Delete the optional record * and clean up */ if (pWin->optional->cursor) { FreeCursor(pWin->optional->cursor, (Cursor) 0); pWin->cursorIsNone = FALSE; } else pWin->cursorIsNone = TRUE; if (pWin->optional->deviceCursors) { DevCursorList pList; DevCursorList pPrev; pList = pWin->optional->deviceCursors; while (pList) { if (pList->cursor) FreeCursor(pList->cursor, (XID) 0); pPrev = pList; pList = pList->next; free(pPrev); } pWin->optional->deviceCursors = NULL; } free(pWin->optional); pWin->optional = NULL; } static void FreeWindowResources(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; DeleteWindowFromAnySaveSet(pWin); DeleteWindowFromAnySelections(pWin); DeleteWindowFromAnyEvents(pWin, TRUE); RegionUninit(&pWin->clipList); RegionUninit(&pWin->winSize); RegionUninit(&pWin->borderClip); RegionUninit(&pWin->borderSize); if (wBoundingShape(pWin)) RegionDestroy(wBoundingShape(pWin)); if (wClipShape(pWin)) RegionDestroy(wClipShape(pWin)); if (wInputShape(pWin)) RegionDestroy(wInputShape(pWin)); if (pWin->borderIsPixel == FALSE) (*pScreen->DestroyPixmap) (pWin->border.pixmap); if (pWin->backgroundState == BackgroundPixmap) (*pScreen->DestroyPixmap) (pWin->background.pixmap); DeleteAllWindowProperties(pWin); /* We SHOULD check for an error value here XXX */ (*pScreen->DestroyWindow) (pWin); DisposeWindowOptional(pWin); } static void CrushTree(WindowPtr pWin) { WindowPtr pChild, pSib, pParent; UnrealizeWindowProcPtr UnrealizeWindow; if (!(pChild = pWin->firstChild)) return; UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow; while (1) { if (pChild->firstChild) { pChild = pChild->firstChild; continue; } while (1) { pParent = pChild->parent; if (SubStrSend(pChild, pParent)) { xEvent event = { .u.u.type = DestroyNotify }; event.u.destroyNotify.window = pChild->drawable.id; DeliverEvents(pChild, &event, 1, NullWindow); } FreeResource(pChild->drawable.id, RT_WINDOW); pSib = pChild->nextSib; pChild->viewable = FALSE; if (pChild->realized) { pChild->realized = FALSE; (*UnrealizeWindow) (pChild); } FreeWindowResources(pChild); dixFreeObjectWithPrivates(pChild, PRIVATE_WINDOW); if ((pChild = pSib)) break; pChild = pParent; pChild->firstChild = NullWindow; pChild->lastChild = NullWindow; if (pChild == pWin) return; } } } /***** * DeleteWindow * Deletes child of window then window itself * If wid is None, don't send any events *****/ int DeleteWindow(void *value, XID wid) { WindowPtr pParent; WindowPtr pWin = (WindowPtr) value; UnmapWindow(pWin, FALSE); CrushTree(pWin); pParent = pWin->parent; if (wid && pParent && SubStrSend(pWin, pParent)) { xEvent event = { .u.u.type = DestroyNotify }; event.u.destroyNotify.window = pWin->drawable.id; DeliverEvents(pWin, &event, 1, NullWindow); } FreeWindowResources(pWin); if (pParent) { if (pParent->firstChild == pWin) pParent->firstChild = pWin->nextSib; if (pParent->lastChild == pWin) pParent->lastChild = pWin->prevSib; if (pWin->nextSib) pWin->nextSib->prevSib = pWin->prevSib; if (pWin->prevSib) pWin->prevSib->nextSib = pWin->nextSib; } else pWin->drawable.pScreen->root = NULL; dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); return Success; } int DestroySubwindows(WindowPtr pWin, ClientPtr client) { /* XXX * The protocol is quite clear that each window should be * destroyed in turn, however, unmapping all of the first * eliminates most of the calls to ValidateTree. So, * this implementation is incorrect in that all of the * UnmapNotifies occur before all of the DestroyNotifies. * If you care, simply delete the call to UnmapSubwindows. */ UnmapSubwindows(pWin); while (pWin->lastChild) { int rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->lastChild->drawable.id, RT_WINDOW, pWin->lastChild, RT_NONE, NULL, DixDestroyAccess); if (rc != Success) return rc; FreeResource(pWin->lastChild->drawable.id, RT_NONE); } return Success; } static void SetRootWindowBackground(WindowPtr pWin, ScreenPtr pScreen, Mask *index2) { /* following the protocol: "Changing the background of a root window to * None or ParentRelative restores the default background pixmap" */ if (bgNoneRoot) { pWin->backgroundState = XaceBackgroundNoneState(pWin); pWin->background.pixel = pScreen->whitePixel; } else if (party_like_its_1989) MakeRootTile(pWin); else { pWin->backgroundState = BackgroundPixel; if (whiteRoot) pWin->background.pixel = pScreen->whitePixel; else pWin->background.pixel = pScreen->blackPixel; *index2 = CWBackPixel; } } /***** * ChangeWindowAttributes * * The value-mask specifies which attributes are to be changed; the * value-list contains one value for each one bit in the mask, from least * to most significant bit in the mask. *****/ int ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) { XID *pVlist; PixmapPtr pPixmap; Pixmap pixID; CursorPtr pCursor, pOldCursor; Cursor cursorID; WindowPtr pChild; Colormap cmap; ColormapPtr pCmap; xEvent xE; int error, rc; ScreenPtr pScreen; Mask index2, tmask, vmaskCopy = 0; unsigned int val; Bool checkOptional = FALSE, borderRelative = FALSE; if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK))) return BadMatch; error = Success; pScreen = pWin->drawable.pScreen; pVlist = vlist; tmask = vmask; while (tmask) { index2 = (Mask) lowbit(tmask); tmask &= ~index2; switch (index2) { case CWBackPixmap: pixID = (Pixmap) * pVlist; pVlist++; if (pWin->backgroundState == ParentRelative) borderRelative = TRUE; if (pixID == None) { if (pWin->backgroundState == BackgroundPixmap) (*pScreen->DestroyPixmap) (pWin->background.pixmap); if (!pWin->parent) SetRootWindowBackground(pWin, pScreen, &index2); else { pWin->backgroundState = XaceBackgroundNoneState(pWin); pWin->background.pixel = pScreen->whitePixel; } } else if (pixID == ParentRelative) { if (pWin->parent && pWin->drawable.depth != pWin->parent->drawable.depth) { error = BadMatch; goto PatchUp; } if (pWin->backgroundState == BackgroundPixmap) (*pScreen->DestroyPixmap) (pWin->background.pixmap); if (!pWin->parent) SetRootWindowBackground(pWin, pScreen, &index2); else pWin->backgroundState = ParentRelative; borderRelative = TRUE; /* Note that the parent's backgroundTile's refcnt is NOT * incremented. */ } else { rc = dixLookupResourceByType((void **) &pPixmap, pixID, RT_PIXMAP, client, DixReadAccess); if (rc == Success) { if ((pPixmap->drawable.depth != pWin->drawable.depth) || (pPixmap->drawable.pScreen != pScreen)) { error = BadMatch; goto PatchUp; } if (pWin->backgroundState == BackgroundPixmap) (*pScreen->DestroyPixmap) (pWin->background.pixmap); pWin->backgroundState = BackgroundPixmap; pWin->background.pixmap = pPixmap; pPixmap->refcnt++; } else { error = rc; client->errorValue = pixID; goto PatchUp; } } break; case CWBackPixel: if (pWin->backgroundState == ParentRelative) borderRelative = TRUE; if (pWin->backgroundState == BackgroundPixmap) (*pScreen->DestroyPixmap) (pWin->background.pixmap); pWin->backgroundState = BackgroundPixel; pWin->background.pixel = (CARD32) *pVlist; /* background pixel overrides background pixmap, so don't let the ddx layer see both bits */ vmaskCopy &= ~CWBackPixmap; pVlist++; break; case CWBorderPixmap: pixID = (Pixmap) * pVlist; pVlist++; if (pixID == CopyFromParent) { if (!pWin->parent || (pWin->drawable.depth != pWin->parent->drawable.depth)) { error = BadMatch; goto PatchUp; } if (pWin->parent->borderIsPixel == TRUE) { if (pWin->borderIsPixel == FALSE) (*pScreen->DestroyPixmap) (pWin->border.pixmap); pWin->border = pWin->parent->border; pWin->borderIsPixel = TRUE; index2 = CWBorderPixel; break; } else { pixID = pWin->parent->border.pixmap->drawable.id; } } rc = dixLookupResourceByType((void **) &pPixmap, pixID, RT_PIXMAP, client, DixReadAccess); if (rc == Success) { if ((pPixmap->drawable.depth != pWin->drawable.depth) || (pPixmap->drawable.pScreen != pScreen)) { error = BadMatch; goto PatchUp; } if (pWin->borderIsPixel == FALSE) (*pScreen->DestroyPixmap) (pWin->border.pixmap); pWin->borderIsPixel = FALSE; pWin->border.pixmap = pPixmap; pPixmap->refcnt++; } else { error = rc; client->errorValue = pixID; goto PatchUp; } break; case CWBorderPixel: if (pWin->borderIsPixel == FALSE) (*pScreen->DestroyPixmap) (pWin->border.pixmap); pWin->borderIsPixel = TRUE; pWin->border.pixel = (CARD32) *pVlist; /* border pixel overrides border pixmap, so don't let the ddx layer see both bits */ vmaskCopy &= ~CWBorderPixmap; pVlist++; break; case CWBitGravity: val = (CARD8) *pVlist; pVlist++; if (val > StaticGravity) { error = BadValue; client->errorValue = val; goto PatchUp; } pWin->bitGravity = val; break; case CWWinGravity: val = (CARD8) *pVlist; pVlist++; if (val > StaticGravity) { error = BadValue; client->errorValue = val; goto PatchUp; } pWin->winGravity = val; break; case CWBackingStore: val = (CARD8) *pVlist; pVlist++; if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) { error = BadValue; client->errorValue = val; goto PatchUp; } pWin->backingStore = val; pWin->forcedBS = FALSE; break; case CWBackingPlanes: if (pWin->optional || ((CARD32) *pVlist != (CARD32) ~0L)) { if (!pWin->optional && !MakeWindowOptional(pWin)) { error = BadAlloc; goto PatchUp; } pWin->optional->backingBitPlanes = (CARD32) *pVlist; if ((CARD32) *pVlist == (CARD32) ~0L) checkOptional = TRUE; } pVlist++; break; case CWBackingPixel: if (pWin->optional || (CARD32) *pVlist) { if (!pWin->optional && !MakeWindowOptional(pWin)) { error = BadAlloc; goto PatchUp; } pWin->optional->backingPixel = (CARD32) *pVlist; if (!*pVlist) checkOptional = TRUE; } pVlist++; break; case CWSaveUnder: val = (BOOL) * pVlist; pVlist++; if ((val != xTrue) && (val != xFalse)) { error = BadValue; client->errorValue = val; goto PatchUp; } pWin->saveUnder = val; break; case CWEventMask: rc = EventSelectForWindow(pWin, client, (Mask) *pVlist); if (rc) { error = rc; goto PatchUp; } pVlist++; break; case CWDontPropagate: rc = EventSuppressForWindow(pWin, client, (Mask) *pVlist, &checkOptional); if (rc) { error = rc; goto PatchUp; } pVlist++; break; case CWOverrideRedirect: val = (BOOL) * pVlist; pVlist++; if ((val != xTrue) && (val != xFalse)) { error = BadValue; client->errorValue = val; goto PatchUp; } if (val == xTrue) { rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, RT_WINDOW, pWin, RT_NONE, NULL, DixGrabAccess); if (rc != Success) { error = rc; client->errorValue = pWin->drawable.id; goto PatchUp; } } pWin->overrideRedirect = val; break; case CWColormap: cmap = (Colormap) * pVlist; pVlist++; if (cmap == CopyFromParent) { if (pWin->parent && (!pWin->optional || pWin->optional->visual == wVisual(pWin->parent))) { cmap = wColormap(pWin->parent); } else cmap = None; } if (cmap == None) { error = BadMatch; goto PatchUp; } rc = dixLookupResourceByType((void **) &pCmap, cmap, RT_COLORMAP, client, DixUseAccess); if (rc != Success) { error = rc; client->errorValue = cmap; goto PatchUp; } if (pCmap->pVisual->vid != wVisual(pWin) || pCmap->pScreen != pScreen) { error = BadMatch; goto PatchUp; } if (cmap != wColormap(pWin)) { if (!pWin->optional) { if (!MakeWindowOptional(pWin)) { error = BadAlloc; goto PatchUp; } } else if (pWin->parent && cmap == wColormap(pWin->parent)) checkOptional = TRUE; /* * propagate the original colormap to any children * inheriting it */ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { if (!pChild->optional && !MakeWindowOptional(pChild)) { error = BadAlloc; goto PatchUp; } } pWin->optional->colormap = cmap; /* * check on any children now matching the new colormap */ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { if (pChild->optional->colormap == cmap) CheckWindowOptionalNeed(pChild); } xE = (xEvent) { .u.colormap.window = pWin->drawable.id, .u.colormap.colormap = cmap, .u.colormap.new = xTrue, .u.colormap.state = IsMapInstalled(cmap, pWin) }; xE.u.u.type = ColormapNotify; DeliverEvents(pWin, &xE, 1, NullWindow); } break; case CWCursor: cursorID = (Cursor) * pVlist; pVlist++; /* * install the new */ if (cursorID == None) { if (pWin == pWin->drawable.pScreen->root) pCursor = rootCursor; else pCursor = (CursorPtr) None; } else { rc = dixLookupResourceByType((void **) &pCursor, cursorID, RT_CURSOR, client, DixUseAccess); if (rc != Success) { error = rc; client->errorValue = cursorID; goto PatchUp; } } if (pCursor != wCursor(pWin)) { /* * patch up child windows so they don't lose cursors. */ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { if (!pChild->optional && !pChild->cursorIsNone && !MakeWindowOptional(pChild)) { error = BadAlloc; goto PatchUp; } } pOldCursor = 0; if (pCursor == (CursorPtr) None) { pWin->cursorIsNone = TRUE; if (pWin->optional) { pOldCursor = pWin->optional->cursor; pWin->optional->cursor = (CursorPtr) None; checkOptional = TRUE; } } else { if (!pWin->optional) { if (!MakeWindowOptional(pWin)) { error = BadAlloc; goto PatchUp; } } else if (pWin->parent && pCursor == wCursor(pWin->parent)) checkOptional = TRUE; pOldCursor = pWin->optional->cursor; pWin->optional->cursor = RefCursor(pCursor); pWin->cursorIsNone = FALSE; /* * check on any children now matching the new cursor */ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { if (pChild->optional && (pChild->optional->cursor == pCursor)) CheckWindowOptionalNeed(pChild); } } CursorVisible = TRUE; if (pWin->realized) WindowHasNewCursor(pWin); /* Can't free cursor until here - old cursor * is needed in WindowHasNewCursor */ if (pOldCursor) FreeCursor(pOldCursor, (Cursor) 0); } break; default: error = BadValue; client->errorValue = vmask; goto PatchUp; } vmaskCopy |= index2; } PatchUp: if (checkOptional) CheckWindowOptionalNeed(pWin); /* We SHOULD check for an error value here XXX */ (*pScreen->ChangeWindowAttributes) (pWin, vmaskCopy); /* If the border contents have changed, redraw the border. Note that this has to be done AFTER pScreen->ChangeWindowAttributes for the tile to be rotated, and the correct function selected. */ if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative) && pWin->viewable && HasBorder(pWin)) { RegionRec exposed; RegionNull(&exposed); RegionSubtract(&exposed, &pWin->borderClip, &pWin->winSize); pWin->drawable.pScreen->PaintWindow(pWin, &exposed, PW_BORDER); RegionUninit(&exposed); } return error; } /***** * GetWindowAttributes * Notice that this is different than ChangeWindowAttributes *****/ void GetWindowAttributes(WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply * wa) { wa->type = X_Reply; wa->bitGravity = pWin->bitGravity; wa->winGravity = pWin->winGravity; if (pWin->forcedBS && pWin->backingStore != Always) wa->backingStore = NotUseful; else wa->backingStore = pWin->backingStore; wa->length = bytes_to_int32(sizeof(xGetWindowAttributesReply) - sizeof(xGenericReply)); wa->sequenceNumber = client->sequence; wa->backingBitPlanes = wBackingBitPlanes(pWin); wa->backingPixel = wBackingPixel(pWin); wa->saveUnder = (BOOL) pWin->saveUnder; wa->override = pWin->overrideRedirect; if (!pWin->mapped) wa->mapState = IsUnmapped; else if (pWin->realized) wa->mapState = IsViewable; else wa->mapState = IsUnviewable; wa->colormap = wColormap(pWin); wa->mapInstalled = (wa->colormap == None) ? xFalse : IsMapInstalled(wa->colormap, pWin); wa->yourEventMask = EventMaskForClient(pWin, client); wa->allEventMasks = pWin->eventMask | wOtherEventMasks(pWin); wa->doNotPropagateMask = wDontPropagateMask(pWin); wa->class = pWin->drawable.class; wa->visualID = wVisual(pWin); } WindowPtr MoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib) { WindowPtr pParent = pWin->parent; WindowPtr pFirstChange = pWin; /* highest window where list changes */ if (pWin->nextSib != pNextSib) { WindowPtr pOldNextSib = pWin->nextSib; if (!pNextSib) { /* move to bottom */ if (pParent->firstChild == pWin) pParent->firstChild = pWin->nextSib; /* if (pWin->nextSib) *//* is always True: pNextSib == NULL * and pWin->nextSib != pNextSib * therefore pWin->nextSib != NULL */ pFirstChange = pWin->nextSib; pWin->nextSib->prevSib = pWin->prevSib; if (pWin->prevSib) pWin->prevSib->nextSib = pWin->nextSib; pParent->lastChild->nextSib = pWin; pWin->prevSib = pParent->lastChild; pWin->nextSib = NullWindow; pParent->lastChild = pWin; } else if (pParent->firstChild == pNextSib) { /* move to top */ pFirstChange = pWin; if (pParent->lastChild == pWin) pParent->lastChild = pWin->prevSib; if (pWin->nextSib) pWin->nextSib->prevSib = pWin->prevSib; if (pWin->prevSib) pWin->prevSib->nextSib = pWin->nextSib; pWin->nextSib = pParent->firstChild; pWin->prevSib = NULL; pNextSib->prevSib = pWin; pParent->firstChild = pWin; } else { /* move in middle of list */ WindowPtr pOldNext = pWin->nextSib; pFirstChange = NullWindow; if (pParent->firstChild == pWin) pFirstChange = pParent->firstChild = pWin->nextSib; if (pParent->lastChild == pWin) { pFirstChange = pWin; pParent->lastChild = pWin->prevSib; } if (pWin->nextSib) pWin->nextSib->prevSib = pWin->prevSib; if (pWin->prevSib) pWin->prevSib->nextSib = pWin->nextSib; pWin->nextSib = pNextSib; pWin->prevSib = pNextSib->prevSib; if (pNextSib->prevSib) pNextSib->prevSib->nextSib = pWin; pNextSib->prevSib = pWin; if (!pFirstChange) { /* do we know it yet? */ pFirstChange = pParent->firstChild; /* no, search from top */ while ((pFirstChange != pWin) && (pFirstChange != pOldNext)) pFirstChange = pFirstChange->nextSib; } } if (pWin->drawable.pScreen->RestackWindow) (*pWin->drawable.pScreen->RestackWindow) (pWin, pOldNextSib); } #ifdef ROOTLESS /* * In rootless mode we can't optimize away window restacks. * There may be non-X windows around, so even if the window * is in the correct position from X's point of view, * the underlying window system may want to reorder it. */ else if (pWin->drawable.pScreen->RestackWindow) (*pWin->drawable.pScreen->RestackWindow) (pWin, pWin->nextSib); #endif return pFirstChange; } void SetWinSize(WindowPtr pWin) { #ifdef COMPOSITE if (pWin->redirectDraw != RedirectDrawNone) { BoxRec box; /* * Redirected clients get clip list equal to their * own geometry, not clipped to their parent */ box.x1 = pWin->drawable.x; box.y1 = pWin->drawable.y; box.x2 = pWin->drawable.x + pWin->drawable.width; box.y2 = pWin->drawable.y + pWin->drawable.height; RegionReset(&pWin->winSize, &box); } else #endif ClippedRegionFromBox(pWin->parent, &pWin->winSize, pWin->drawable.x, pWin->drawable.y, (int) pWin->drawable.width, (int) pWin->drawable.height); if (wBoundingShape(pWin) || wClipShape(pWin)) { RegionTranslate(&pWin->winSize, -pWin->drawable.x, -pWin->drawable.y); if (wBoundingShape(pWin)) RegionIntersect(&pWin->winSize, &pWin->winSize, wBoundingShape(pWin)); if (wClipShape(pWin)) RegionIntersect(&pWin->winSize, &pWin->winSize, wClipShape(pWin)); RegionTranslate(&pWin->winSize, pWin->drawable.x, pWin->drawable.y); } } void SetBorderSize(WindowPtr pWin) { int bw; if (HasBorder(pWin)) { bw = wBorderWidth(pWin); #ifdef COMPOSITE if (pWin->redirectDraw != RedirectDrawNone) { BoxRec box; /* * Redirected clients get clip list equal to their * own geometry, not clipped to their parent */ box.x1 = pWin->drawable.x - bw; box.y1 = pWin->drawable.y - bw; box.x2 = pWin->drawable.x + pWin->drawable.width + bw; box.y2 = pWin->drawable.y + pWin->drawable.height + bw; RegionReset(&pWin->borderSize, &box); } else #endif ClippedRegionFromBox(pWin->parent, &pWin->borderSize, pWin->drawable.x - bw, pWin->drawable.y - bw, (int) (pWin->drawable.width + (bw << 1)), (int) (pWin->drawable.height + (bw << 1))); if (wBoundingShape(pWin)) { RegionTranslate(&pWin->borderSize, -pWin->drawable.x, -pWin->drawable.y); RegionIntersect(&pWin->borderSize, &pWin->borderSize, wBoundingShape(pWin)); RegionTranslate(&pWin->borderSize, pWin->drawable.x, pWin->drawable.y); RegionUnion(&pWin->borderSize, &pWin->borderSize, &pWin->winSize); } } else { RegionCopy(&pWin->borderSize, &pWin->winSize); } } /** * * \param x,y new window position * \param oldx,oldy old window position * \param destx,desty position relative to gravity */ void GravityTranslate(int x, int y, int oldx, int oldy, int dw, int dh, unsigned gravity, int *destx, int *desty) { switch (gravity) { case NorthGravity: *destx = x + dw / 2; *desty = y; break; case NorthEastGravity: *destx = x + dw; *desty = y; break; case WestGravity: *destx = x; *desty = y + dh / 2; break; case CenterGravity: *destx = x + dw / 2; *desty = y + dh / 2; break; case EastGravity: *destx = x + dw; *desty = y + dh / 2; break; case SouthWestGravity: *destx = x; *desty = y + dh; break; case SouthGravity: *destx = x + dw / 2; *desty = y + dh; break; case SouthEastGravity: *destx = x + dw; *desty = y + dh; break; case StaticGravity: *destx = oldx; *desty = oldy; break; default: *destx = x; *desty = y; break; } } /* XXX need to retile border on each window with ParentRelative origin */ void ResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh) { ScreenPtr pScreen; WindowPtr pSib, pChild; Bool resized = (dw || dh); pScreen = pWin->drawable.pScreen; for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib) { if (resized && (pSib->winGravity > NorthWestGravity)) { int cwsx, cwsy; cwsx = pSib->origin.x; cwsy = pSib->origin.y; GravityTranslate(cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh, pSib->winGravity, &cwsx, &cwsy); if (cwsx != pSib->origin.x || cwsy != pSib->origin.y) { xEvent event = { .u.gravity.window = pSib->drawable.id, .u.gravity.x = cwsx - wBorderWidth(pSib), .u.gravity.y = cwsy - wBorderWidth(pSib) }; event.u.u.type = GravityNotify; DeliverEvents(pSib, &event, 1, NullWindow); pSib->origin.x = cwsx; pSib->origin.y = cwsy; } } pSib->drawable.x = pWin->drawable.x + pSib->origin.x; pSib->drawable.y = pWin->drawable.y + pSib->origin.y; SetWinSize(pSib); SetBorderSize(pSib); (*pScreen->PositionWindow) (pSib, pSib->drawable.x, pSib->drawable.y); if ((pChild = pSib->firstChild)) { while (1) { pChild->drawable.x = pChild->parent->drawable.x + pChild->origin.x; pChild->drawable.y = pChild->parent->drawable.y + pChild->origin.y; SetWinSize(pChild); SetBorderSize(pChild); (*pScreen->PositionWindow) (pChild, pChild->drawable.x, pChild->drawable.y); if (pChild->firstChild) { pChild = pChild->firstChild; continue; } while (!pChild->nextSib && (pChild != pSib)) pChild = pChild->parent; if (pChild == pSib) break; pChild = pChild->nextSib; } } } } #define GET_INT16(m, f) \ if (m & mask) \ { \ f = (INT16) *pVlist;\ pVlist++; \ } #define GET_CARD16(m, f) \ if (m & mask) \ { \ f = (CARD16) *pVlist;\ pVlist++;\ } #define GET_CARD8(m, f) \ if (m & mask) \ { \ f = (CARD8) *pVlist;\ pVlist++;\ } #define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight)) /* * IsSiblingAboveMe * returns Above if pSib above pMe in stack or Below otherwise */ static int IsSiblingAboveMe(WindowPtr pMe, WindowPtr pSib) { WindowPtr pWin; pWin = pMe->parent->firstChild; while (pWin) { if (pWin == pSib) return Above; else if (pWin == pMe) return Below; pWin = pWin->nextSib; } return Below; } static BoxPtr WindowExtents(WindowPtr pWin, BoxPtr pBox) { pBox->x1 = pWin->drawable.x - wBorderWidth(pWin); pBox->y1 = pWin->drawable.y - wBorderWidth(pWin); pBox->x2 = pWin->drawable.x + (int) pWin->drawable.width + wBorderWidth(pWin); pBox->y2 = pWin->drawable.y + (int) pWin->drawable.height + wBorderWidth(pWin); return pBox; } #define IS_SHAPED(pWin) (wBoundingShape (pWin) != NULL) static RegionPtr MakeBoundingRegion(WindowPtr pWin, BoxPtr pBox) { RegionPtr pRgn = RegionCreate(pBox, 1); if (wBoundingShape(pWin)) { RegionTranslate(pRgn, -pWin->origin.x, -pWin->origin.y); RegionIntersect(pRgn, pRgn, wBoundingShape(pWin)); RegionTranslate(pRgn, pWin->origin.x, pWin->origin.y); } return pRgn; } static Bool ShapeOverlap(WindowPtr pWin, BoxPtr pWinBox, WindowPtr pSib, BoxPtr pSibBox) { RegionPtr pWinRgn, pSibRgn; Bool ret; if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib)) return TRUE; pWinRgn = MakeBoundingRegion(pWin, pWinBox); pSibRgn = MakeBoundingRegion(pSib, pSibBox); RegionIntersect(pWinRgn, pWinRgn, pSibRgn); ret = RegionNotEmpty(pWinRgn); RegionDestroy(pWinRgn); RegionDestroy(pSibRgn); return ret; } static Bool AnyWindowOverlapsMe(WindowPtr pWin, WindowPtr pHead, BoxPtr box) { WindowPtr pSib; BoxRec sboxrec; BoxPtr sbox; for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib) { if (pSib->mapped) { sbox = WindowExtents(pSib, &sboxrec); if (BOXES_OVERLAP(sbox, box) && ShapeOverlap(pWin, box, pSib, sbox)) return TRUE; } } return FALSE; } static Bool IOverlapAnyWindow(WindowPtr pWin, BoxPtr box) { WindowPtr pSib; BoxRec sboxrec; BoxPtr sbox; for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib) { if (pSib->mapped) { sbox = WindowExtents(pSib, &sboxrec); if (BOXES_OVERLAP(sbox, box) && ShapeOverlap(pWin, box, pSib, sbox)) return TRUE; } } return FALSE; } /* * WhereDoIGoInTheStack() * Given pWin and pSib and the relationshipe smode, return * the window that pWin should go ABOVE. * If a pSib is specified: * Above: pWin is placed just above pSib * Below: pWin is placed just below pSib * TopIf: if pSib occludes pWin, then pWin is placed * at the top of the stack * BottomIf: if pWin occludes pSib, then pWin is * placed at the bottom of the stack * Opposite: if pSib occludes pWin, then pWin is placed at the * top of the stack, else if pWin occludes pSib, then * pWin is placed at the bottom of the stack * * If pSib is NULL: * Above: pWin is placed at the top of the stack * Below: pWin is placed at the bottom of the stack * TopIf: if any sibling occludes pWin, then pWin is placed at * the top of the stack * BottomIf: if pWin occludes any sibline, then pWin is placed at * the bottom of the stack * Opposite: if any sibling occludes pWin, then pWin is placed at * the top of the stack, else if pWin occludes any * sibling, then pWin is placed at the bottom of the stack * */ static WindowPtr WhereDoIGoInTheStack(WindowPtr pWin, WindowPtr pSib, short x, short y, unsigned short w, unsigned short h, int smode) { BoxRec box; WindowPtr pHead, pFirst; if ((pWin == pWin->parent->firstChild) && (pWin == pWin->parent->lastChild)) return NULL; pHead = RealChildHead(pWin->parent); pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild; box.x1 = x; box.y1 = y; box.x2 = x + (int) w; box.y2 = y + (int) h; switch (smode) { case Above: if (pSib) return pSib; else if (pWin == pFirst) return pWin->nextSib; else return pFirst; case Below: if (pSib) if (pSib->nextSib != pWin) return pSib->nextSib; else return pWin->nextSib; else return NullWindow; case TopIf: if ((!pWin->mapped || (pSib && !pSib->mapped))) return pWin->nextSib; else if (pSib) { if ((IsSiblingAboveMe(pWin, pSib) == Above) && (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)) return pFirst; else return pWin->nextSib; } else if (AnyWindowOverlapsMe(pWin, pHead, &box)) return pFirst; else return pWin->nextSib; case BottomIf: if ((!pWin->mapped || (pSib && !pSib->mapped))) return pWin->nextSib; else if (pSib) { if ((IsSiblingAboveMe(pWin, pSib) == Below) && (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)) return NullWindow; else return pWin->nextSib; } else if (IOverlapAnyWindow(pWin, &box)) return NullWindow; else return pWin->nextSib; case Opposite: if ((!pWin->mapped || (pSib && !pSib->mapped))) return pWin->nextSib; else if (pSib) { if (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT) { if (IsSiblingAboveMe(pWin, pSib) == Above) return pFirst; else return NullWindow; } else return pWin->nextSib; } else if (AnyWindowOverlapsMe(pWin, pHead, &box)) { /* If I'm occluded, I can't possibly be the first child * if (pWin == pWin->parent->firstChild) * return pWin->nextSib; */ return pFirst; } else if (IOverlapAnyWindow(pWin, &box)) return NullWindow; else return pWin->nextSib; default: { /* should never happen; make something up. */ return pWin->nextSib; } } } static void ReflectStackChange(WindowPtr pWin, WindowPtr pSib, VTKind kind) { /* Note that pSib might be NULL */ Bool WasViewable = (Bool) pWin->viewable; Bool anyMarked; WindowPtr pFirstChange; WindowPtr pLayerWin; ScreenPtr pScreen = pWin->drawable.pScreen; /* if this is a root window, can't be restacked */ if (!pWin->parent) return; pFirstChange = MoveWindowInStack(pWin, pSib); if (WasViewable) { anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, &pLayerWin); if (pLayerWin != pWin) pFirstChange = pLayerWin; if (anyMarked) { (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, kind); (*pScreen->HandleExposures) (pLayerWin->parent); if (pWin->drawable.pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange, kind); } } if (pWin->realized) WindowsRestructured(); } /***** * ConfigureWindow *****/ int ConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) { #define RESTACK_WIN 0 #define MOVE_WIN 1 #define RESIZE_WIN 2 #define REBORDER_WIN 3 WindowPtr pSib = NullWindow; WindowPtr pParent = pWin->parent; Window sibwid = 0; Mask index2, tmask; XID *pVlist; short x, y, beforeX, beforeY; unsigned short w = pWin->drawable.width, h = pWin->drawable.height, bw = pWin->borderWidth; int rc, action, smode = Above; if ((pWin->drawable.class == InputOnly) && (mask & CWBorderWidth)) return BadMatch; if ((mask & CWSibling) && !(mask & CWStackMode)) return BadMatch; pVlist = vlist; if (pParent) { x = pWin->drawable.x - pParent->drawable.x - (int) bw; y = pWin->drawable.y - pParent->drawable.y - (int) bw; } else { x = pWin->drawable.x; y = pWin->drawable.y; } beforeX = x; beforeY = y; action = RESTACK_WIN; if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth)))) { GET_INT16(CWX, x); GET_INT16(CWY, y); action = MOVE_WIN; } /* or should be resized */ else if (mask & (CWX | CWY | CWWidth | CWHeight)) { GET_INT16(CWX, x); GET_INT16(CWY, y); GET_CARD16(CWWidth, w); GET_CARD16(CWHeight, h); if (!w || !h) { client->errorValue = 0; return BadValue; } action = RESIZE_WIN; } tmask = mask & ~ChangeMask; while (tmask) { index2 = (Mask) lowbit(tmask); tmask &= ~index2; switch (index2) { case CWBorderWidth: GET_CARD16(CWBorderWidth, bw); break; case CWSibling: sibwid = (Window) *pVlist; pVlist++; rc = dixLookupWindow(&pSib, sibwid, client, DixGetAttrAccess); if (rc != Success) { client->errorValue = sibwid; return rc; } if (pSib->parent != pParent) return BadMatch; if (pSib == pWin) return BadMatch; break; case CWStackMode: GET_CARD8(CWStackMode, smode); if ((smode != TopIf) && (smode != BottomIf) && (smode != Opposite) && (smode != Above) && (smode != Below)) { client->errorValue = smode; return BadValue; } break; default: client->errorValue = mask; return BadValue; } } /* root really can't be reconfigured, so just return */ if (!pParent) return Success; /* Figure out if the window should be moved. Doesnt make the changes to the window if event sent */ if (mask & CWStackMode) pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x, pParent->drawable.y + y, w + (bw << 1), h + (bw << 1), smode); else pSib = pWin->nextSib; if ((!pWin->overrideRedirect) && (RedirectSend(pParent))) { xEvent event = { .u.configureRequest.window = pWin->drawable.id, .u.configureRequest.sibling = (mask & CWSibling) ? sibwid : None, .u.configureRequest.x = x, .u.configureRequest.y = y, .u.configureRequest.width = w, .u.configureRequest.height = h, .u.configureRequest.borderWidth = bw, .u.configureRequest.valueMask = mask, .u.configureRequest.parent = pParent->drawable.id }; event.u.u.type = ConfigureRequest; event.u.u.detail = (mask & CWStackMode) ? smode : Above; #ifdef PANORAMIX if (!noPanoramiXExtension && (!pParent || !pParent->parent)) { event.u.configureRequest.x += screenInfo.screens[0]->x; event.u.configureRequest.y += screenInfo.screens[0]->y; } #endif if (MaybeDeliverEventsToClient(pParent, &event, 1, SubstructureRedirectMask, client) == 1) return Success; } if (action == RESIZE_WIN) { Bool size_change = (w != pWin->drawable.width) || (h != pWin->drawable.height); if (size_change && ((pWin->eventMask | wOtherEventMasks(pWin)) & ResizeRedirectMask)) { xEvent eventT = { .u.resizeRequest.window = pWin->drawable.id, .u.resizeRequest.width = w, .u.resizeRequest.height = h }; eventT.u.u.type = ResizeRequest; if (MaybeDeliverEventsToClient(pWin, &eventT, 1, ResizeRedirectMask, client) == 1) { /* if event is delivered, leave the actual size alone. */ w = pWin->drawable.width; h = pWin->drawable.height; size_change = FALSE; } } if (!size_change) { if (mask & (CWX | CWY)) action = MOVE_WIN; else if (mask & (CWStackMode | CWBorderWidth)) action = RESTACK_WIN; else /* really nothing to do */ return (Success); } } if (action == RESIZE_WIN) /* we've already checked whether there's really a size change */ goto ActuallyDoSomething; if ((mask & CWX) && (x != beforeX)) goto ActuallyDoSomething; if ((mask & CWY) && (y != beforeY)) goto ActuallyDoSomething; if ((mask & CWBorderWidth) && (bw != wBorderWidth(pWin))) goto ActuallyDoSomething; if (mask & CWStackMode) { #ifndef ROOTLESS /* See above for why we always reorder in rootless mode. */ if (pWin->nextSib != pSib) #endif goto ActuallyDoSomething; } return Success; ActuallyDoSomething: if (pWin->drawable.pScreen->ConfigNotify) { int ret; ret = (*pWin->drawable.pScreen->ConfigNotify) (pWin, x, y, w, h, bw, pSib); if (ret) { client->errorValue = 0; return ret; } } if (SubStrSend(pWin, pParent)) { xEvent event = { .u.configureNotify.window = pWin->drawable.id, .u.configureNotify.aboveSibling = pSib ? pSib->drawable.id : None, .u.configureNotify.x = x, .u.configureNotify.y = y, .u.configureNotify.width = w, .u.configureNotify.height = h, .u.configureNotify.borderWidth = bw, .u.configureNotify.override = pWin->overrideRedirect }; event.u.u.type = ConfigureNotify; #ifdef PANORAMIX if (!noPanoramiXExtension && (!pParent || !pParent->parent)) { event.u.configureNotify.x += screenInfo.screens[0]->x; event.u.configureNotify.y += screenInfo.screens[0]->y; } #endif DeliverEvents(pWin, &event, 1, NullWindow); } if (mask & CWBorderWidth) { if (action == RESTACK_WIN) { action = MOVE_WIN; pWin->borderWidth = bw; } else if ((action == MOVE_WIN) && (beforeX + wBorderWidth(pWin) == x + (int) bw) && (beforeY + wBorderWidth(pWin) == y + (int) bw)) { action = REBORDER_WIN; (*pWin->drawable.pScreen->ChangeBorderWidth) (pWin, bw); } else pWin->borderWidth = bw; } if (action == MOVE_WIN) (*pWin->drawable.pScreen->MoveWindow) (pWin, x, y, pSib, (mask & CWBorderWidth) ? VTOther : VTMove); else if (action == RESIZE_WIN) (*pWin->drawable.pScreen->ResizeWindow) (pWin, x, y, w, h, pSib); else if (mask & CWStackMode) ReflectStackChange(pWin, pSib, VTOther); if (action != RESTACK_WIN) CheckCursorConfinement(pWin); return Success; #undef RESTACK_WIN #undef MOVE_WIN #undef RESIZE_WIN #undef REBORDER_WIN } /****** * * CirculateWindow * For RaiseLowest, raises the lowest mapped child (if any) that is * obscured by another child to the top of the stack. For LowerHighest, * lowers the highest mapped child (if any) that is obscuring another * child to the bottom of the stack. Exposure processing is performed * ******/ int CirculateWindow(WindowPtr pParent, int direction, ClientPtr client) { WindowPtr pWin, pHead, pFirst; xEvent event; BoxRec box; pHead = RealChildHead(pParent); pFirst = pHead ? pHead->nextSib : pParent->firstChild; if (direction == RaiseLowest) { for (pWin = pParent->lastChild; (pWin != pHead) && !(pWin->mapped && AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box))); pWin = pWin->prevSib); if (pWin == pHead) return Success; } else { for (pWin = pFirst; pWin && !(pWin->mapped && IOverlapAnyWindow(pWin, WindowExtents(pWin, &box))); pWin = pWin->nextSib); if (!pWin) return Success; } event = (xEvent) { .u.circulate.window = pWin->drawable.id, .u.circulate.parent = pParent->drawable.id, .u.circulate.event = pParent->drawable.id, .u.circulate.place = (direction == RaiseLowest) ? PlaceOnTop : PlaceOnBottom, }; if (RedirectSend(pParent)) { event.u.u.type = CirculateRequest; if (MaybeDeliverEventsToClient(pParent, &event, 1, SubstructureRedirectMask, client) == 1) return Success; } event.u.u.type = CirculateNotify; DeliverEvents(pWin, &event, 1, NullWindow); ReflectStackChange(pWin, (direction == RaiseLowest) ? pFirst : NullWindow, VTStack); return Success; } static int CompareWIDs(WindowPtr pWin, void *value) { /* must conform to VisitWindowProcPtr */ Window *wid = (Window *) value; if (pWin->drawable.id == *wid) return WT_STOPWALKING; else return WT_WALKCHILDREN; } /***** * ReparentWindow *****/ int ReparentWindow(WindowPtr pWin, WindowPtr pParent, int x, int y, ClientPtr client) { WindowPtr pPrev, pPriorParent; Bool WasMapped = (Bool) (pWin->mapped); xEvent event; int bw = wBorderWidth(pWin); ScreenPtr pScreen; pScreen = pWin->drawable.pScreen; if (TraverseTree(pWin, CompareWIDs, (void *) &pParent->drawable.id) == WT_STOPWALKING) return BadMatch; if (!MakeWindowOptional(pWin)) return BadAlloc; if (WasMapped) UnmapWindow(pWin, FALSE); event = (xEvent) { .u.reparent.window = pWin->drawable.id, .u.reparent.parent = pParent->drawable.id, .u.reparent.x = x, .u.reparent.y = y, .u.reparent.override = pWin->overrideRedirect }; event.u.u.type = ReparentNotify; #ifdef PANORAMIX if (!noPanoramiXExtension && !pParent->parent) { event.u.reparent.x += screenInfo.screens[0]->x; event.u.reparent.y += screenInfo.screens[0]->y; } #endif DeliverEvents(pWin, &event, 1, pParent); /* take out of sibling chain */ pPriorParent = pPrev = pWin->parent; if (pPrev->firstChild == pWin) pPrev->firstChild = pWin->nextSib; if (pPrev->lastChild == pWin) pPrev->lastChild = pWin->prevSib; if (pWin->nextSib) pWin->nextSib->prevSib = pWin->prevSib; if (pWin->prevSib) pWin->prevSib->nextSib = pWin->nextSib; /* insert at begining of pParent */ pWin->parent = pParent; pPrev = RealChildHead(pParent); if (pPrev) { pWin->nextSib = pPrev->nextSib; if (pPrev->nextSib) pPrev->nextSib->prevSib = pWin; else pParent->lastChild = pWin; pPrev->nextSib = pWin; pWin->prevSib = pPrev; } else { pWin->nextSib = pParent->firstChild; pWin->prevSib = NullWindow; if (pParent->firstChild) pParent->firstChild->prevSib = pWin; else pParent->lastChild = pWin; pParent->firstChild = pWin; } pWin->origin.x = x + bw; pWin->origin.y = y + bw; pWin->drawable.x = x + bw + pParent->drawable.x; pWin->drawable.y = y + bw + pParent->drawable.y; /* clip to parent */ SetWinSize(pWin); SetBorderSize(pWin); if (pScreen->ReparentWindow) (*pScreen->ReparentWindow) (pWin, pPriorParent); (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y); ResizeChildrenWinSize(pWin, 0, 0, 0, 0); CheckWindowOptionalNeed(pWin); if (WasMapped) MapWindow(pWin, client); RecalculateDeliverableEvents(pWin); return Success; } static void RealizeTree(WindowPtr pWin) { WindowPtr pChild; RealizeWindowProcPtr Realize; Realize = pWin->drawable.pScreen->RealizeWindow; pChild = pWin; while (1) { if (pChild->mapped) { pChild->realized = TRUE; pChild->viewable = (pChild->drawable.class == InputOutput); (*Realize) (pChild); if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) return; pChild = pChild->nextSib; } } static Bool MaybeDeliverMapRequest(WindowPtr pWin, WindowPtr pParent, ClientPtr client) { xEvent event = { .u.mapRequest.window = pWin->drawable.id, .u.mapRequest.parent = pParent->drawable.id }; event.u.u.type = MapRequest; return MaybeDeliverEventsToClient(pParent, &event, 1, SubstructureRedirectMask, client) == 1; } static void DeliverMapNotify(WindowPtr pWin) { xEvent event = { .u.mapNotify.window = pWin->drawable.id, .u.mapNotify.override = pWin->overrideRedirect, }; event.u.u.type = MapNotify; DeliverEvents(pWin, &event, 1, NullWindow); } /***** * MapWindow * If some other client has selected SubStructureReDirect on the parent * and override-redirect is xFalse, then a MapRequest event is generated, * but the window remains unmapped. Otherwise, the window is mapped and a * MapNotify event is generated. *****/ int MapWindow(WindowPtr pWin, ClientPtr client) { ScreenPtr pScreen; WindowPtr pParent; WindowPtr pLayerWin; if (pWin->mapped) return Success; /* general check for permission to map window */ if (XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, RT_WINDOW, pWin, RT_NONE, NULL, DixShowAccess) != Success) return Success; pScreen = pWin->drawable.pScreen; if ((pParent = pWin->parent)) { Bool anyMarked; if ((!pWin->overrideRedirect) && (RedirectSend(pParent))) if (MaybeDeliverMapRequest(pWin, pParent, client)) return Success; pWin->mapped = TRUE; if (SubStrSend(pWin, pParent)) DeliverMapNotify(pWin); if (!pParent->realized) return Success; RealizeTree(pWin); if (pWin->viewable) { anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); if (anyMarked) { (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTMap); (*pScreen->HandleExposures) (pLayerWin->parent); if (pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, VTMap); } } WindowsRestructured(); } else { RegionRec temp; pWin->mapped = TRUE; pWin->realized = TRUE; /* for roots */ pWin->viewable = pWin->drawable.class == InputOutput; /* We SHOULD check for an error value here XXX */ (*pScreen->RealizeWindow) (pWin); if (pScreen->ClipNotify) (*pScreen->ClipNotify) (pWin, 0, 0); if (pScreen->PostValidateTree) (*pScreen->PostValidateTree) (NullWindow, pWin, VTMap); RegionNull(&temp); RegionCopy(&temp, &pWin->clipList); (*pScreen->WindowExposures) (pWin, &temp); RegionUninit(&temp); } return Success; } /***** * MapSubwindows * Performs a MapWindow all unmapped children of the window, in top * to bottom stacking order. *****/ void MapSubwindows(WindowPtr pParent, ClientPtr client) { WindowPtr pWin; WindowPtr pFirstMapped = NullWindow; ScreenPtr pScreen; Mask parentRedirect; Mask parentNotify; Bool anyMarked; WindowPtr pLayerWin; pScreen = pParent->drawable.pScreen; parentRedirect = RedirectSend(pParent); parentNotify = SubSend(pParent); anyMarked = FALSE; for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib) { if (!pWin->mapped) { if (parentRedirect && !pWin->overrideRedirect) if (MaybeDeliverMapRequest(pWin, pParent, client)) continue; pWin->mapped = TRUE; if (parentNotify || StrSend(pWin)) DeliverMapNotify(pWin); if (!pFirstMapped) pFirstMapped = pWin; if (pParent->realized) { RealizeTree(pWin); if (pWin->viewable) { anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL); } } } } if (pFirstMapped) { pLayerWin = (*pScreen->GetLayerWindow) (pParent); if (pLayerWin->parent != pParent) { anyMarked |= (*pScreen->MarkOverlappedWindows) (pLayerWin, pLayerWin, NULL); pFirstMapped = pLayerWin; } if (anyMarked) { (*pScreen->ValidateTree) (pLayerWin->parent, pFirstMapped, VTMap); (*pScreen->HandleExposures) (pLayerWin->parent); if (pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstMapped, VTMap); } WindowsRestructured(); } } static void UnrealizeTree(WindowPtr pWin, Bool fromConfigure) { WindowPtr pChild; UnrealizeWindowProcPtr Unrealize; MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; Unrealize = pWin->drawable.pScreen->UnrealizeWindow; MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow; pChild = pWin; while (1) { if (pChild->realized) { pChild->realized = FALSE; pChild->visibility = VisibilityNotViewable; #ifdef PANORAMIX if (!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) { PanoramiXRes *win; int rc = dixLookupResourceByType((void **) &win, pChild->drawable.id, XRT_WINDOW, serverClient, DixWriteAccess); if (rc == Success) win->u.win.visibility = VisibilityNotViewable; } #endif (*Unrealize) (pChild); DeleteWindowFromAnyEvents(pChild, FALSE); if (pChild->viewable) { pChild->viewable = FALSE; (*MarkUnrealizedWindow) (pChild, pWin, fromConfigure); pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; } if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) return; pChild = pChild->nextSib; } } static void DeliverUnmapNotify(WindowPtr pWin, Bool fromConfigure) { xEvent event = { .u.unmapNotify.window = pWin->drawable.id, .u.unmapNotify.fromConfigure = fromConfigure }; event.u.u.type = UnmapNotify; DeliverEvents(pWin, &event, 1, NullWindow); } /***** * UnmapWindow * If the window is already unmapped, this request has no effect. * Otherwise, the window is unmapped and an UnMapNotify event is * generated. Cannot unmap a root window. *****/ int UnmapWindow(WindowPtr pWin, Bool fromConfigure) { WindowPtr pParent; Bool wasRealized = (Bool) pWin->realized; Bool wasViewable = (Bool) pWin->viewable; ScreenPtr pScreen = pWin->drawable.pScreen; WindowPtr pLayerWin = pWin; if ((!pWin->mapped) || (!(pParent = pWin->parent))) return Success; if (SubStrSend(pWin, pParent)) DeliverUnmapNotify(pWin, fromConfigure); if (wasViewable && !fromConfigure) { pWin->valdata = UnmapValData; (*pScreen->MarkOverlappedWindows) (pWin, pWin->nextSib, &pLayerWin); (*pScreen->MarkWindow) (pLayerWin->parent); } pWin->mapped = FALSE; if (wasRealized) UnrealizeTree(pWin, fromConfigure); if (wasViewable) { if (!fromConfigure) { (*pScreen->ValidateTree) (pLayerWin->parent, pWin, VTUnmap); (*pScreen->HandleExposures) (pLayerWin->parent); if (pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pLayerWin->parent, pWin, VTUnmap); } } if (wasRealized && !fromConfigure) { WindowsRestructured(); WindowGone(pWin); } return Success; } /***** * UnmapSubwindows * Performs an UnmapWindow request with the specified mode on all mapped * children of the window, in bottom to top stacking order. *****/ void UnmapSubwindows(WindowPtr pWin) { WindowPtr pChild, pHead; Bool wasRealized = (Bool) pWin->realized; Bool wasViewable = (Bool) pWin->viewable; Bool anyMarked = FALSE; Mask parentNotify; WindowPtr pLayerWin = NULL; ScreenPtr pScreen = pWin->drawable.pScreen; if (!pWin->firstChild) return; parentNotify = SubSend(pWin); pHead = RealChildHead(pWin); if (wasViewable) pLayerWin = (*pScreen->GetLayerWindow) (pWin); for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) { if (pChild->mapped) { if (parentNotify || StrSend(pChild)) DeliverUnmapNotify(pChild, xFalse); if (pChild->viewable) { pChild->valdata = UnmapValData; anyMarked = TRUE; } pChild->mapped = FALSE; if (pChild->realized) UnrealizeTree(pChild, FALSE); } } if (wasViewable) { if (anyMarked) { if (pLayerWin->parent == pWin) (*pScreen->MarkWindow) (pWin); else { WindowPtr ptmp; (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin, NULL); (*pScreen->MarkWindow) (pLayerWin->parent); /* Windows between pWin and pLayerWin may not have been marked */ ptmp = pWin; while (ptmp != pLayerWin->parent) { (*pScreen->MarkWindow) (ptmp); ptmp = ptmp->parent; } pHead = pWin->firstChild; } (*pScreen->ValidateTree) (pLayerWin->parent, pHead, VTUnmap); (*pScreen->HandleExposures) (pLayerWin->parent); if (pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pLayerWin->parent, pHead, VTUnmap); } } if (wasRealized) { WindowsRestructured(); WindowGone(pWin); } } void HandleSaveSet(ClientPtr client) { WindowPtr pParent, pWin; int j; for (j = 0; j < client->numSaved; j++) { pWin = SaveSetWindow(client->saveSet[j]); if (SaveSetToRoot(client->saveSet[j])) pParent = pWin->drawable.pScreen->root; else { pParent = pWin->parent; while (pParent && (wClient(pParent) == client)) pParent = pParent->parent; } if (pParent) { if (pParent != pWin->parent) { /* unmap first so that ReparentWindow doesn't remap */ if (!SaveSetShouldMap(client->saveSet[j])) UnmapWindow(pWin, FALSE); ReparentWindow(pWin, pParent, pWin->drawable.x - wBorderWidth(pWin) - pParent->drawable.x, pWin->drawable.y - wBorderWidth(pWin) - pParent->drawable.y, client); if (!pWin->realized && pWin->mapped) pWin->mapped = FALSE; } if (SaveSetShouldMap(client->saveSet[j])) MapWindow(pWin, client); } } free(client->saveSet); client->numSaved = 0; client->saveSet = NULL; } /** * * \param x,y in root */ Bool PointInWindowIsVisible(WindowPtr pWin, int x, int y) { BoxRec box; if (!pWin->realized) return FALSE; if (RegionContainsPoint(&pWin->borderClip, x, y, &box) && (!wInputShape(pWin) || RegionContainsPoint(wInputShape(pWin), x - pWin->drawable.x, y - pWin->drawable.y, &box))) return TRUE; return FALSE; } RegionPtr NotClippedByChildren(WindowPtr pWin) { RegionPtr pReg = RegionCreate(NullBox, 1); if (pWin->parent || screenIsSaved != SCREEN_SAVER_ON || !HasSaverWindow(pWin->drawable.pScreen)) { RegionIntersect(pReg, &pWin->borderClip, &pWin->winSize); } return pReg; } void SendVisibilityNotify(WindowPtr pWin) { xEvent event; unsigned int visibility = pWin->visibility; #ifdef PANORAMIX /* This is not quite correct yet, but it's close */ if (!noPanoramiXExtension) { PanoramiXRes *win; WindowPtr pWin2; int rc, i, Scrnum; Scrnum = pWin->drawable.pScreen->myNum; win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum); if (!win || (win->u.win.visibility == visibility)) return; switch (visibility) { case VisibilityUnobscured: FOR_NSCREENS(i) { if (i == Scrnum) continue; rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, DixWriteAccess); if (rc == Success) { if (pWin2->visibility == VisibilityPartiallyObscured) return; if (!i) pWin = pWin2; } } break; case VisibilityPartiallyObscured: if (Scrnum) { rc = dixLookupWindow(&pWin2, win->info[0].id, serverClient, DixWriteAccess); if (rc == Success) pWin = pWin2; } break; case VisibilityFullyObscured: FOR_NSCREENS(i) { if (i == Scrnum) continue; rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, DixWriteAccess); if (rc == Success) { if (pWin2->visibility != VisibilityFullyObscured) return; if (!i) pWin = pWin2; } } break; } win->u.win.visibility = visibility; } #endif event = (xEvent) { .u.visibility.window = pWin->drawable.id, .u.visibility.state = visibility }; event.u.u.type = VisibilityNotify; DeliverEvents(pWin, &event, 1, NullWindow); } #define RANDOM_WIDTH 32 int dixSaveScreens(ClientPtr client, int on, int mode) { int rc, i, what, type; if (on == SCREEN_SAVER_FORCER) { if (mode == ScreenSaverReset) what = SCREEN_SAVER_OFF; else what = SCREEN_SAVER_ON; type = what; } else { what = on; type = what; if (what == screenIsSaved) type = SCREEN_SAVER_CYCLE; } for (i = 0; i < screenInfo.numScreens; i++) { rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], DixShowAccess | DixHideAccess); if (rc != Success) return rc; } for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr pScreen = screenInfo.screens[i]; if (on == SCREEN_SAVER_FORCER) (*pScreen->SaveScreen) (pScreen, on); if (pScreen->screensaver.ExternalScreenSaver) { if ((*pScreen->screensaver.ExternalScreenSaver) (pScreen, type, on == SCREEN_SAVER_FORCER)) continue; } if (type == screenIsSaved) continue; switch (type) { case SCREEN_SAVER_OFF: if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) { (*pScreen->SaveScreen) (pScreen, what); } else if (HasSaverWindow(pScreen)) { pScreen->screensaver.pWindow = NullWindow; FreeResource(pScreen->screensaver.wid, RT_NONE); } break; case SCREEN_SAVER_CYCLE: if (pScreen->screensaver.blanked == SCREEN_IS_TILED) { WindowPtr pWin = pScreen->screensaver.pWindow; /* make it look like screen saver is off, so that * NotClippedByChildren will compute a clip list * for the root window, so PaintWindow works */ screenIsSaved = SCREEN_SAVER_OFF; (*pWin->drawable.pScreen->MoveWindow) (pWin, (short) (- (rand() % RANDOM_WIDTH)), (short) (- (rand() % RANDOM_WIDTH)), pWin->nextSib, VTMove); screenIsSaved = SCREEN_SAVER_ON; } /* * Call the DDX saver in case it wants to do something * at cycle time */ else if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) { (*pScreen->SaveScreen) (pScreen, type); } break; case SCREEN_SAVER_ON: if (ScreenSaverBlanking != DontPreferBlanking) { if ((*pScreen->SaveScreen) (pScreen, what)) { pScreen->screensaver.blanked = SCREEN_IS_BLANKED; continue; } if ((ScreenSaverAllowExposures != DontAllowExposures) && TileScreenSaver(pScreen, SCREEN_IS_BLACK)) { pScreen->screensaver.blanked = SCREEN_IS_BLACK; continue; } } if ((ScreenSaverAllowExposures != DontAllowExposures) && TileScreenSaver(pScreen, SCREEN_IS_TILED)) { pScreen->screensaver.blanked = SCREEN_IS_TILED; } else pScreen->screensaver.blanked = SCREEN_ISNT_SAVED; break; } } screenIsSaved = what; if (mode == ScreenSaverReset) { if (on == SCREEN_SAVER_FORCER) { DeviceIntPtr dev; UpdateCurrentTimeIf(); nt_list_for_each_entry(dev, inputInfo.devices, next) NoticeTime(dev, currentTime); } SetScreenSaverTimer(); } return Success; } int SaveScreens(int on, int mode) { return dixSaveScreens(serverClient, on, mode); } static Bool TileScreenSaver(ScreenPtr pScreen, int kind) { int j; int result; XID attributes[3]; Mask mask; WindowPtr pWin; CursorMetricRec cm; unsigned char *srcbits, *mskbits; CursorPtr cursor; XID cursorID = 0; int attri; mask = 0; attri = 0; switch (kind) { case SCREEN_IS_TILED: switch (pScreen->root->backgroundState) { case BackgroundPixel: attributes[attri++] = pScreen->root->background.pixel; mask |= CWBackPixel; break; case BackgroundPixmap: attributes[attri++] = None; mask |= CWBackPixmap; break; default: break; } break; case SCREEN_IS_BLACK: attributes[attri++] = pScreen->root->drawable.pScreen->blackPixel; mask |= CWBackPixel; break; } mask |= CWOverrideRedirect; attributes[attri++] = xTrue; /* * create a blank cursor */ cm.width = 16; cm.height = 16; cm.xhot = 8; cm.yhot = 8; srcbits = malloc(BitmapBytePad(32) * 16); mskbits = malloc(BitmapBytePad(32) * 16); if (!srcbits || !mskbits) { free(srcbits); free(mskbits); cursor = 0; } else { for (j = 0; j < BitmapBytePad(32) * 16; j++) srcbits[j] = mskbits[j] = 0x0; result = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 0, 0, 0, 0, 0, 0, &cursor, serverClient, (XID) 0); if (cursor) { cursorID = FakeClientID(0); if (AddResource(cursorID, RT_CURSOR, (void *) cursor)) { attributes[attri] = cursorID; mask |= CWCursor; } else cursor = 0; } else { free(srcbits); free(mskbits); } } pWin = pScreen->screensaver.pWindow = CreateWindow(pScreen->screensaver.wid, pScreen->root, -RANDOM_WIDTH, -RANDOM_WIDTH, (unsigned short) pScreen->width + RANDOM_WIDTH, (unsigned short) pScreen->height + RANDOM_WIDTH, 0, InputOutput, mask, attributes, 0, serverClient, wVisual(pScreen->root), &result); if (cursor) FreeResource(cursorID, RT_NONE); if (!pWin) return FALSE; if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pScreen->screensaver.pWindow)) return FALSE; if (mask & CWBackPixmap) { MakeRootTile(pWin); (*pWin->drawable.pScreen->ChangeWindowAttributes) (pWin, CWBackPixmap); } MapWindow(pWin, serverClient); return TRUE; } /* * FindWindowWithOptional * * search ancestors of the given window for an entry containing * a WindowOpt structure. Assumptions: some parent will * contain the structure. */ WindowPtr FindWindowWithOptional(WindowPtr w) { do w = w->parent; while (!w->optional); return w; } /* * CheckWindowOptionalNeed * * check each optional entry in the given window to see if * the value is satisfied by the default rules. If so, * release the optional record */ void CheckWindowOptionalNeed(WindowPtr w) { WindowOptPtr optional; WindowOptPtr parentOptional; if (!w->parent || !w->optional) return; optional = w->optional; if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate]) return; if (optional->otherEventMasks != 0) return; if (optional->otherClients != NULL) return; if (optional->passiveGrabs != NULL) return; if (optional->userProps != NULL) return; if (optional->backingBitPlanes != (CARD32)~0L) return; if (optional->backingPixel != 0) return; if (optional->boundingShape != NULL) return; if (optional->clipShape != NULL) return; if (optional->inputShape != NULL) return; if (optional->inputMasks != NULL) return; if (optional->deviceCursors != NULL) { DevCursNodePtr pNode = optional->deviceCursors; while (pNode) { if (pNode->cursor != None) return; pNode = pNode->next; } } parentOptional = FindWindowWithOptional(w)->optional; if (optional->visual != parentOptional->visual) return; if (optional->cursor != None && (optional->cursor != parentOptional->cursor || w->parent->cursorIsNone)) return; if (optional->colormap != parentOptional->colormap) return; DisposeWindowOptional(w); } /* * MakeWindowOptional * * create an optional record and initialize it with the default * values. */ Bool MakeWindowOptional(WindowPtr pWin) { WindowOptPtr optional; WindowOptPtr parentOptional; if (pWin->optional) return TRUE; optional = malloc(sizeof(WindowOptRec)); if (!optional) return FALSE; optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate]; optional->otherEventMasks = 0; optional->otherClients = NULL; optional->passiveGrabs = NULL; optional->userProps = NULL; optional->backingBitPlanes = ~0L; optional->backingPixel = 0; optional->boundingShape = NULL; optional->clipShape = NULL; optional->inputShape = NULL; optional->inputMasks = NULL; optional->deviceCursors = NULL; parentOptional = FindWindowWithOptional(pWin)->optional; optional->visual = parentOptional->visual; if (!pWin->cursorIsNone) { optional->cursor = RefCursor(parentOptional->cursor); } else { optional->cursor = None; } optional->colormap = parentOptional->colormap; pWin->optional = optional; return TRUE; } /* * Changes the cursor struct for the given device and the given window. * A cursor that does not have a device cursor set will use whatever the * standard cursor is for the window. If all devices have a cursor set, * changing the window cursor (e.g. using XDefineCursor()) will not have any * visible effect. Only when one of the device cursors is set to None again, * this device's cursor will display the changed standard cursor. * * CursorIsNone of the window struct is NOT modified if you set a device * cursor. * * Assumption: If there is a node for a device in the list, the device has a * cursor. If the cursor is set to None, it is inherited by the parent. */ int ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor) { DevCursNodePtr pNode, pPrev; CursorPtr pOldCursor = NULL; ScreenPtr pScreen; WindowPtr pChild; if (!pWin->optional && !MakeWindowOptional(pWin)) return BadAlloc; /* 1) Check if window has device cursor set * Yes: 1.1) swap cursor with given cursor if parent does not have same * cursor, free old cursor * 1.2) free old cursor, use parent cursor * No: 1.1) add node to beginning of list. * 1.2) add cursor to node if parent does not have same cursor * 1.3) use parent cursor if parent does not have same cursor * 2) Patch up children if child has a devcursor * 2.1) if child has cursor None, it inherited from parent, set to old * cursor * 2.2) if child has same cursor as new cursor, remove and set to None */ pScreen = pWin->drawable.pScreen; if (WindowSeekDeviceCursor(pWin, pDev, &pNode, &pPrev)) { /* has device cursor */ if (pNode->cursor == pCursor) return Success; pOldCursor = pNode->cursor; if (!pCursor) { /* remove from list */ if (pPrev) pPrev->next = pNode->next; else /* first item in list */ pWin->optional->deviceCursors = pNode->next; free(pNode); goto out; } } else { /* no device cursor yet */ DevCursNodePtr pNewNode; if (!pCursor) return Success; pNewNode = malloc(sizeof(DevCursNodeRec)); pNewNode->dev = pDev; pNewNode->next = pWin->optional->deviceCursors; pWin->optional->deviceCursors = pNewNode; pNode = pNewNode; } if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor)) pNode->cursor = None; else { pNode->cursor = RefCursor(pCursor); } pNode = pPrev = NULL; /* fix up children */ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) { if (pNode->cursor == None) { /* inherited from parent */ pNode->cursor = RefCursor(pOldCursor); } else if (pNode->cursor == pCursor) { pNode->cursor = None; FreeCursor(pCursor, (Cursor) 0); /* fix up refcnt */ } } } out: CursorVisible = TRUE; if (pWin->realized) WindowHasNewCursor(pWin); if (pOldCursor) FreeCursor(pOldCursor, (Cursor) 0); /* FIXME: We SHOULD check for an error value here XXX (comment taken from ChangeWindowAttributes) */ (*pScreen->ChangeWindowAttributes) (pWin, CWCursor); return Success; } /* Get device cursor for given device or None if none is set */ CursorPtr WindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev) { DevCursorList pList; if (!pWin->optional || !pWin->optional->deviceCursors) return NULL; pList = pWin->optional->deviceCursors; while (pList) { if (pList->dev == pDev) { if (pList->cursor == None) /* inherited from parent */ return WindowGetDeviceCursor(pWin->parent, pDev); else return pList->cursor; } pList = pList->next; } return NULL; } /* Searches for a DevCursorNode for the given window and device. If one is * found, return True and set pNode and pPrev to the node and to the node * before the node respectively. Otherwise return False. * If the device is the first in list, pPrev is set to NULL. */ static Bool WindowSeekDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, DevCursNodePtr * pNode, DevCursNodePtr * pPrev) { DevCursorList pList; if (!pWin->optional) return FALSE; pList = pWin->optional->deviceCursors; if (pList && pList->dev == pDev) { *pNode = pList; *pPrev = NULL; return TRUE; } while (pList) { if (pList->next) { if (pList->next->dev == pDev) { *pNode = pList->next; *pPrev = pList; return TRUE; } } pList = pList->next; } return FALSE; } /* Return True if a parent has the same device cursor set or False if * otherwise */ static Bool WindowParentHasDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor) { WindowPtr pParent; DevCursNodePtr pParentNode, pParentPrev; pParent = pWin->parent; while (pParent) { if (WindowSeekDeviceCursor(pParent, pDev, &pParentNode, &pParentPrev)) { /* if there is a node in the list, the win has a dev cursor */ if (!pParentNode->cursor) /* inherited. */ pParent = pParent->parent; else if (pParentNode->cursor == pCursor) /* inherit */ return TRUE; else /* different cursor */ return FALSE; } else /* parent does not have a device cursor for our device */ return FALSE; } return FALSE; } /* * SetRootClip -- * Enable or disable rendering to the screen by * setting the root clip list and revalidating * all of the windows */ void SetRootClip(ScreenPtr pScreen, int enable) { WindowPtr pWin = pScreen->root; WindowPtr pChild; Bool WasViewable; Bool anyMarked = FALSE; WindowPtr pLayerWin; BoxRec box; enum RootClipMode mode = enable; if (!pWin) return; WasViewable = (Bool) (pWin->viewable); if (WasViewable) { for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { (void) (*pScreen->MarkOverlappedWindows) (pChild, pChild, &pLayerWin); } (*pScreen->MarkWindow) (pWin); anyMarked = TRUE; if (pWin->valdata) { if (HasBorder(pWin)) { RegionPtr borderVisible; borderVisible = RegionCreate(NullBox, 1); RegionSubtract(borderVisible, &pWin->borderClip, &pWin->winSize); pWin->valdata->before.borderVisible = borderVisible; } pWin->valdata->before.resized = TRUE; } } if (mode != ROOT_CLIP_NONE) { pWin->drawable.width = pScreen->width; pWin->drawable.height = pScreen->height; box.x1 = 0; box.y1 = 0; box.x2 = pScreen->width; box.y2 = pScreen->height; RegionInit(&pWin->winSize, &box, 1); RegionInit(&pWin->borderSize, &box, 1); /* * Use REGION_BREAK to avoid optimizations in ValidateTree * that assume the root borderClip can't change well, normally * it doesn't...) */ RegionBreak(&pWin->clipList); /* For INPUT_ONLY, empty the borderClip so no rendering will ever * be attempted to the screen pixmap (only redirected windows), * but we keep borderSize as full regardless. */ if (WasViewable && mode == ROOT_CLIP_FULL) RegionReset(&pWin->borderClip, &box); else RegionEmpty(&pWin->borderClip); } else { RegionEmpty(&pWin->borderClip); RegionBreak(&pWin->clipList); } ResizeChildrenWinSize(pWin, 0, 0, 0, 0); if (WasViewable) { if (pWin->firstChild) { anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin->firstChild, pWin->firstChild, NULL); } else { (*pScreen->MarkWindow) (pWin); anyMarked = TRUE; } if (anyMarked) { (*pScreen->ValidateTree) (pWin, NullWindow, VTOther); (*pScreen->HandleExposures) (pWin); if (pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pWin, NullWindow, VTOther); } } if (pWin->realized) WindowsRestructured(); FlushAllOutput(); } VisualPtr WindowGetVisual(WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; VisualID vid = wVisual(pWin); int i; for (i = 0; i < pScreen->numVisuals; i++) if (pScreen->visuals[i].vid == vid) return &pScreen->visuals[i]; return 0; } xorg-server-1.20.13/dix/stubmain.c0000644000175000017500000000263314100573756013650 00000000000000/*********************************************************** Copyright 2012 Jon TURNEY Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ int dix_main(int argc, char *argv[], char *envp[]); /* A default implementation of main, which can be overridden by the DDX */ int main(int argc, char *argv[], char *envp[]) { return dix_main(argc, argv, envp); } xorg-server-1.20.13/dix/buildatoms0000644000175000017500000000232214100573755013742 00000000000000#!/bin/sh hfile=../../../include/Xatom.h cfile=initatoms.c rm -f $hfile $cfile umask 222 awk ' BEGIN { hfile = "'$hfile'"; cfile = "'$cfile'"; hformat = "#define XA_%s ((Atom) %d)\n"; printf("#ifndef XATOM_H\n") > hfile; printf("#define XATOM_H 1\n\n") > hfile; printf("/* THIS IS A GENERATED FILE\n") > hfile; printf(" *\n") > hfile; printf(" * Do not change! Changing this file implies a protocol change!\n") > hfile; printf(" */\n\n") > hfile; printf("/* THIS IS A GENERATED FILE\n") > cfile; printf(" *\n") > cfile; printf(" * Do not change! Changing this file implies a protocol change!\n") > cfile; printf(" */\n\n") > cfile; printf("#include \"X.h\"\n") > cfile; printf("#include \"Xatom.h\"\n") > cfile; printf("#include \"misc.h\"\n") > cfile; printf("#include \"dix.h\"\n") > cfile; printf("void MakePredeclaredAtoms()\n") > cfile; printf("{\n") > cfile; } NF == 2 && $2 == "@" { printf(hformat, $1, ++atomno) > hfile ; printf(" if (MakeAtom(\"%s\", %d, 1) != XA_%s) AtomError();\n", $1, length($1), $1) > cfile ; } END { printf("\n") > hfile; printf(hformat, "LAST_PREDEFINED", atomno) > hfile ; printf("#endif /* XATOM_H */\n") > hfile; printf("}\n") > cfile ; } ' BuiltInAtoms exit 0 xorg-server-1.20.13/dix/BuiltInAtoms0000644000175000017500000002452314100573755014160 00000000000000File: .../x11/server/dix/BuiltInAtoms This file is of a fixed format and is used to generate both the file include/XAtom.h and dix/initatoms.c. Neither of those files should be edited directly. Changing the atoms in this file, or even the order in which they occur, is equivalent to forcing a new (minor) version number on the server. Take care. The format of the file is that each built in atom starts in column 1 with no text, other than spaces and tabs, on that line other than a mandatory trailing "@" at the end of the line. For each atom (Foo) below the defines will be of the form #define XA_Foo and the string value of the atom will be "Foo". The comment lines in this file are not guaranteed to be accurate. To see the current truth, look at the Xlib documentation as well as the protocol spec. Atoms occur in five distinct name spaces within the protocol. Any particular atom may or may not have some client interpretation within each of the name spaces. For each of the built in atoms, the intended semantics and the space within which it is defined is indicated. Those name spaces are Property names Property types Selections Font properties Type of a ClientMessage event (none built into server) For the font properties mentioned here, see the spec for more information. -- Selections -- PRIMARY @ Selection. SECONDARY @ Selection. -- Property types and names -- ARC @ Property type: x, y: INT16 width, height: CARD16, angle1, angle2: INT16 ATOM @ Property type: atom: ATOM BITMAP @ Property type: bitmap: PIXMAP This is asserted to be of depth 1. CARDINAL @ Property type: card: CARD32 or CARD16 or CARD8 the datum size is dependent on the property format COLORMAP @ Property type: colormap: COLORMAP CURSOR @ Property type: cursor: CURSOR CUT_BUFFER0 @ CUT_BUFFER1 @ CUT_BUFFER2 @ CUT_BUFFER3 @ CUT_BUFFER4 @ CUT_BUFFER5 @ CUT_BUFFER6 @ CUT_BUFFER7 @ Property name: (type: STRING) Used to implement cut buffer ring, in particular Andrew uses this mechanism. Anyone else using this sort of IPC mechanism should use these properties. Data is normally fetched and stored out of CUT_BUFFER0; the RotateProperties request is used to rotate these buffers. DRAWABLE @ Property type: drawable: DRAWABLE FONT @ Property type: font: FONT INTEGER @ Property type: card: INT32 or INT16 or INT8 the datum size is dependent on the property format PIXMAP @ Property type: pixmap: PIXMAP POINT @ Property type: x, y: INT16 RECTANGLE @ Property type: x, y: INT16 width, height: CARD16 RESOURCE_MANAGER @ Property name: (type: STRING) Contents of the user's resource manager data base. RGB_COLOR_MAP @ Property type: colormap: COLORMAP red-max: CARD32 red-mult: CARD32 green-max: CARD32 green-mult: CARD32 blue-max: CARD32 blue-mult: CARD32 base-pixel: CARD32 The fields `red_max', `green_max', and `blue_max' give the maximum red, green, and blue values, respectively. Each color coefficient ranges from 0 to its max, inclusive. For example, a common colormap allocation is 3/3/2: 3 planes for red, 3 planes for green, and 2 planes for blue. Such a colormap would have red_max == 7, green_max = 7, and blue_max = 3. An alternate allocation that uses only 216 colors is red_max = 5, green_max = 5, and blue_max = 5. The fields `red_mult', `green_mult', and `blue_mult' give the scale factors used to compose a full pixel value. (See next paragraph.) For a 3/3/2 allocation red_mult might be 32, green_mult might be 4, and blue_mult might be 1. For a 6-colors-each allocation, red_mult might be 36, green_mult might be 6, and blue_mult might be 1. The field `base_pixel' gives the base pixel value used to compose a full pixel value. Normally base_pixel is obtained from a call to XAllocColorPlanes(). Given integer red, green, and blue coefficients in their appropriate ranges, one can compute a corresponding pixel value with the expression: r * red_mult + g * green_mult + b * blue_mult + base_pixel For gray-scale colormaps, only the colormap, red_max, red_mult, and base_pixel fields are defined; the other fields are ignored. To compute a gray-scale pixel value, use: gray * red_mult + base_pixel This is provided to allow applications to share color maps. RGB_BEST_MAP @ RGB_BLUE_MAP @ RGB_DEFAULT_MAP @ RGB_GRAY_MAP @ RGB_GREEN_MAP @ RGB_RED_MAP @ Property name: (type: RGB_COLOR_MAP) The needs of most applications can be met with five colormaps. Polite applications may need only a small RGB space, and can use a portion of the default color map. Applications doing high-quality RGB rendering will need an entire colormap, filled with as large an RGB space as possible, e.g. 332. For color separations, an application may need maximum device resolution for each of red, green, and blue, even if this requires three renderings with three colormaps. Each of the above five names would be used for sharing color maps. STRING @ Property type: sequence of Bytes VISUALID @ Property type: visual: VISUALID WINDOW @ Property type: window: WINDOW WM_COMMAND @ Property name: (type: STRING) Command line arguments used to invoke this application. The arguments are delimited by null characters (ASCII 0). WM_HINTS @ Property type: flags: CARD32 input: BOOL32 initial-state: CARD32 icon-pixmap: PIXMAP icon-window: WINDOW icon_mask: BITMAP icon-x, icon-y: INT32 flags contains the following bits 0x00000001 input hint 0x00000002 state hint 0x00000004 icon pixmap hint 0x00000008 icon window hint 0x00000010 icon position hint values for initial-state 0 unspecified -> application does not care and WM should pick one. 1 normal 2 zoomed 3 iconic 4 inactive -> application believes itself to be seldomly used. WM may wish to place it on an inactive menu. This type is potentially extensible. The order is critical; append to the end only. Property name: (type: WM_HINTS) Additional hints set by the client for use by the window manager. WM_CLIENT_MACHINE @ Property name: (type: STRING) used to communicate with the window manager. The host name of the machine the client is running on may be set here. WM_ICON_NAME @ Property name: (type: STRING) what the application would like the label to be for the iconic form of the window. WM_ICON_SIZE @ Property type: minWidth, min-height: CARD32 maxWidth, max-height: CARD32 widthInc, height-inc: CARD32 Property name: (type: ICON_SIZE) The window manager may set this property on the root window to specify the icon sizes it allows. WM_NAME @ Property name: (type: STRING) used to communicate with the window manager. This is what the application would like the label for the window. WM_NORMAL_HINTS @ Property name: (type: SIZE_HINTS) used to communicate with the window manager. This is size hints for a window in its "normal" state. WM_SIZE_HINTS @ Property type: flags: CARD32 x, y: INT32 width, height: CARD32 min-width, min-height: CARD32 max-width, max-height: CARD32 width-inc, height-inc: CARD32 min-aspect-x, min-aspect-y: CARD32 max-aspect-x, max-aspect-y: CARD32 flags contains the following bits 0x00000001 user specified x and y 0x00000002 user specified width and height 0x00000004 program specified position 0x00000008 program specified size 0x00000010 program specified minimum size 0x00000020 program specified maximum size 0x00000040 program specified resize increment 0x00000080 program specified aspect ratio This type is potentially extensible. The order is critical; append to the end only. WM_ZOOM_HINTS @ Property name: (type: SIZE_HINTS) used to communicate with the window manager. This is size hints for a window in its "zoomed" state. -- Font properties -- MIN_SPACE @ Font property: CARD32 NORM_SPACE @ Font property: CARD32 MAX_SPACE @ Font property: CARD32 END_SPACE @ Font property: CARD32 SUPERSCRIPT_X @ Font property: INT32 SUPERSCRIPT_Y @ Font property: INT32 SUBSCRIPT_X @ Font property: INT32 SUBSCRIPT_Y @ Font property: INT32 UNDERLINE_POSITION @ Font property: INT32 UNDERLINE_THICKNESS @ Font property: CARD32 STRIKEOUT_ASCENT @ Font property: INT32 STRIKEOUT_DESCENT @ Font property: INT32 ITALIC_ANGLE @ Font property: INT32 X_HEIGHT @ Font property: INT32 QUAD_WIDTH @ Font property: INT32 WEIGHT @ Font property: CARD32 POINT_SIZE @ Font property: CARD32 RESOLUTION @ Font property: CARD32 The following optional properties on fonts have values that are atoms. The atom print name is the useful information. COPYRIGHT @ of the font distribution NOTICE @ trademark/copyright of the character shapes FONT_NAME @ name of this particular instance of a font FAMILY_NAME @ name of the 'font family' to which it belongs FULL_NAME @ full text name of the font The following aren't in order but putting them at the end avoids encoding changes. CAP_HEIGHT @ Font property: CARD32 WM_CLASS @ Property name: (type: STRING) Used (possibly by some window managers; definitely by session managers) to look up resources in the resource data base on behalf of the client who set this property. There are 2 elements: {char *resource_name; char *resource_class;} delimited by a null character (ascii 0) WM_TRANSIENT_FOR @ Property name: (type: WINDOW) Used by transient top-level windows, such as dialog boxes, to point to their logical "parents". The window manager can then take down the dialog boxes when the "parent" gets iconified, for instance. xorg-server-1.20.13/dix/Xserver.d0000644000175000017500000000536114100573755013465 00000000000000/* Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * Xserver dtrace provider definition */ #ifdef __APPLE__ #define string char * #define pid_t uint32_t #define zoneid_t uint32_t #elif defined(__FreeBSD__) #define zoneid_t id_t #else #include #endif typedef const uint8_t *const_uint8_p; typedef const double *const_double_p; provider Xserver { /* reqType, data, length, client id, request buffer */ probe request__start(string, uint8_t, uint16_t, int, void *); /* reqType, data, sequence, client id, result */ probe request__done(string, uint8_t, uint32_t, int, int); /* client id, client fd */ probe client__connect(int, int); /* client id, client address, client pid, client zone id */ probe client__auth(int, string, pid_t, zoneid_t); /* client id */ probe client__disconnect(int); /* resource id, resource type, value, resource type name */ probe resource__alloc(uint32_t, uint32_t, void *, string); /* resource id, resource type, value, resource type name */ probe resource__free(uint32_t, uint32_t, void *, string); /* client id, event type, event* */ probe send__event(int, uint8_t, void *); /* deviceid, type, button/keycode/touchid, flags, nvalues, mask, values */ probe input__event(int, int, uint32_t, uint32_t, int8_t, const_uint8_p, const_double_p); }; #pragma D attributes Unstable/Unstable/Common provider Xserver provider #pragma D attributes Private/Private/Unknown provider Xserver module #pragma D attributes Private/Private/Unknown provider Xserver function #pragma D attributes Unstable/Unstable/Common provider Xserver name #pragma D attributes Unstable/Unstable/Common provider Xserver args xorg-server-1.20.13/dix/Xserver-dtrace.h.in0000644000175000017500000001023514100573755015332 00000000000000/* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * Generated by dtrace(1M), and then modified for backwards compatibility * with older versions of dtrace. Used if dtrace -h fails. * (Since _ENABLED support was added after dtrace -h, this assumes if * dtrace -h fails, _ENABLED will too.) */ #ifndef _XSERVER_DTRACE_H #define _XSERVER_DTRACE_H #include #ifdef __cplusplus extern "C" { #endif #if _DTRACE_VERSION #define XSERVER_CLIENT_AUTH(arg0, arg1, arg2, arg3) \ __dtrace_Xserver___client__auth(arg0, arg1, arg2, arg3) #define XSERVER_CLIENT_CONNECT(arg0, arg1) \ __dtrace_Xserver___client__connect(arg0, arg1) #define XSERVER_CLIENT_DISCONNECT(arg0) \ __dtrace_Xserver___client__disconnect(arg0) #define XSERVER_REQUEST_DONE(arg0, arg1, arg2, arg3, arg4) \ __dtrace_Xserver___request__done(arg0, arg1, arg2, arg3, arg4) #define XSERVER_REQUEST_START(arg0, arg1, arg2, arg3, arg4) \ __dtrace_Xserver___request__start(arg0, arg1, arg2, arg3, arg4) #define XSERVER_RESOURCE_ALLOC(arg0, arg1, arg2, arg3) \ __dtrace_Xserver___resource__alloc(arg0, arg1, arg2, arg3) #define XSERVER_RESOURCE_FREE(arg0, arg1, arg2, arg3) \ __dtrace_Xserver___resource__free(arg0, arg1, arg2, arg3) #define XSERVER_SEND_EVENT(arg0, arg1, arg2) \ __dtrace_Xserver___send__event(arg0, arg1, arg2) #define XSERVER_INPUT_EVENT(arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ __dtrace_Xserver___input__event(arg0, arg1, arg2, arg3, arg4, arg5, arg6) extern void __dtrace_Xserver___client__auth(int, string, pid_t, zoneid_t); extern void __dtrace_Xserver___client__connect(int, int); extern void __dtrace_Xserver___client__disconnect(int); extern void __dtrace_Xserver___request__done(string, uint8_t, uint32_t, int, int); extern void __dtrace_Xserver___request__start(string, uint8_t, uint16_t, int, void *); extern void __dtrace_Xserver___resource__alloc(uint32_t, uint32_t, void *, string); extern void __dtrace_Xserver___resource__free(uint32_t, uint32_t, void *, string); extern void __dtrace_Xserver___send__event(int, uint8_t, void *); extern void __dtrace_Xserver___input__event(int, uint16_t, uint32_t, uint32_t, int8_t, uint8_t *, double *); #else #define XSERVER_CLIENT_AUTH(arg0, arg1, arg2, arg3) #define XSERVER_CLIENT_CONNECT(arg0, arg1) #define XSERVER_CLIENT_DISCONNECT(arg0) #define XSERVER_REQUEST_DONE(arg0, arg1, arg2, arg3, arg4) #define XSERVER_REQUEST_START(arg0, arg1, arg2, arg3, arg4) #define XSERVER_RESOURCE_ALLOC(arg0, arg1, arg2, arg3) #define XSERVER_RESOURCE_FREE(arg0, arg1, arg2, arg3) #define XSERVER_SEND_EVENT(arg0, arg1, arg2) #define XSERVER_INPUT_EVENT(arg0, arg1, arg2, arg3, arg4, arg5, arg6) #endif #define XSERVER_CLIENT_AUTH_ENABLED() (1) #define XSERVER_CLIENT_CONNECT_ENABLED() (1) #define XSERVER_CLIENT_DISCONNECT_ENABLED() (1) #define XSERVER_REQUEST_DONE_ENABLED() (1) #define XSERVER_REQUEST_START_ENABLED() (1) #define XSERVER_RESOURCE_ALLOC_ENABLED() (1) #define XSERVER_RESOURCE_FREE_ENABLED() (1) #define XSERVER_SEND_EVENT_ENABLED() (1) #define XSERVER_INPUT_EVENT_ENABLED() (1) #ifdef __cplusplus } #endif #endif /* _XSERVER_DTRACE_H */ xorg-server-1.20.13/dri3/0000755000175000017500000000000014100574020011774 500000000000000xorg-server-1.20.13/dri3/meson.build0000644000175000017500000000061014100573756014072 00000000000000srcs_dri3 = [ 'dri3.c', 'dri3_request.c', 'dri3_screen.c', ] hdrs_dri3 = [ 'dri3.h', ] libxserver_dri3 = [] if build_dri3 libxserver_dri3 = static_library('libxserver_dri3', srcs_dri3, include_directories: inc, dependencies: [ common_dep, libdrm_dep ], c_args: '-DHAVE_XORG_CONFIG_H' ) endif install_data(hdrs_dri3, install_dir: xorgsdkdir) xorg-server-1.20.13/dri3/Makefile.am0000644000175000017500000000032414100573756013766 00000000000000noinst_LTLIBRARIES = libdri3.la AM_CFLAGS = \ -DHAVE_XORG_CONFIG_H \ @DIX_CFLAGS@ @XORG_CFLAGS@ libdri3_la_SOURCES = \ dri3.h \ dri3_priv.h \ dri3.c \ dri3_request.c \ dri3_screen.c sdk_HEADERS = dri3.h xorg-server-1.20.13/dri3/dri3.h0000644000175000017500000001150514100573756012747 00000000000000/* * Copyright © 2013 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _DRI3_H_ #define _DRI3_H_ #ifdef DRI3 #include #include #define DRI3_SCREEN_INFO_VERSION 2 typedef int (*dri3_open_proc)(ScreenPtr screen, RRProviderPtr provider, int *fd); typedef int (*dri3_open_client_proc)(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd); typedef PixmapPtr (*dri3_pixmap_from_fd_proc) (ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp); typedef PixmapPtr (*dri3_pixmap_from_fds_proc) (ScreenPtr screen, CARD8 num_fds, const int *fds, CARD16 width, CARD16 height, const CARD32 *strides, const CARD32 *offsets, CARD8 depth, CARD8 bpp, CARD64 modifier); typedef int (*dri3_fd_from_pixmap_proc) (ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size); typedef int (*dri3_fds_from_pixmap_proc) (ScreenPtr screen, PixmapPtr pixmap, int *fds, uint32_t *strides, uint32_t *offsets, uint64_t *modifier); typedef int (*dri3_get_formats_proc) (ScreenPtr screen, CARD32 *num_formats, CARD32 **formats); typedef int (*dri3_get_modifiers_proc) (ScreenPtr screen, uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers); typedef int (*dri3_get_drawable_modifiers_proc) (DrawablePtr draw, uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers); typedef struct dri3_screen_info { uint32_t version; dri3_open_proc open; dri3_pixmap_from_fd_proc pixmap_from_fd; dri3_fd_from_pixmap_proc fd_from_pixmap; /* Version 1 */ dri3_open_client_proc open_client; /* Version 2 */ dri3_pixmap_from_fds_proc pixmap_from_fds; dri3_fds_from_pixmap_proc fds_from_pixmap; dri3_get_formats_proc get_formats; dri3_get_modifiers_proc get_modifiers; dri3_get_drawable_modifiers_proc get_drawable_modifiers; } dri3_screen_info_rec, *dri3_screen_info_ptr; extern _X_EXPORT Bool dri3_screen_init(ScreenPtr screen, const dri3_screen_info_rec *info); extern _X_EXPORT int dri3_send_open_reply(ClientPtr client, int fd); extern _X_EXPORT uint32_t drm_format_for_depth(uint32_t depth, uint32_t bpp); #endif #endif /* _DRI3_H_ */ xorg-server-1.20.13/dri3/Makefile.in0000644000175000017500000007061414100573775014011 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = dri3 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(sdk_HEADERS) $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libdri3_la_LIBADD = am_libdri3_la_OBJECTS = dri3.lo dri3_request.lo dri3_screen.lo libdri3_la_OBJECTS = $(am_libdri3_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dri3.Plo \ ./$(DEPDIR)/dri3_request.Plo ./$(DEPDIR)/dri3_screen.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libdri3_la_SOURCES) DIST_SOURCES = $(libdri3_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(sdkdir)" HEADERS = $(sdk_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libdri3.la AM_CFLAGS = \ -DHAVE_XORG_CONFIG_H \ @DIX_CFLAGS@ @XORG_CFLAGS@ libdri3_la_SOURCES = \ dri3.h \ dri3_priv.h \ dri3.c \ dri3_request.c \ dri3_screen.c sdk_HEADERS = dri3.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign dri3/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign dri3/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libdri3.la: $(libdri3_la_OBJECTS) $(libdri3_la_DEPENDENCIES) $(EXTRA_libdri3_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libdri3_la_OBJECTS) $(libdri3_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dri3.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dri3_request.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dri3_screen.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-sdkHEADERS: $(sdk_HEADERS) @$(NORMAL_INSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sdkdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sdkdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(sdkdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(sdkdir)" || exit $$?; \ done uninstall-sdkHEADERS: @$(NORMAL_UNINSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(sdkdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dri3.Plo -rm -f ./$(DEPDIR)/dri3_request.Plo -rm -f ./$(DEPDIR)/dri3_screen.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-sdkHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dri3.Plo -rm -f ./$(DEPDIR)/dri3_request.Plo -rm -f ./$(DEPDIR)/dri3_screen.Plo -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 TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am 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 tags-am uninstall uninstall-am \ uninstall-sdkHEADERS .PRECIOUS: Makefile # 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: xorg-server-1.20.13/dri3/dri3_priv.h0000644000175000017500000000665514100573756014021 00000000000000/* * Copyright © 2013 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _DRI3PRIV_H_ #define _DRI3PRIV_H_ #include #include "scrnintstr.h" #include "misc.h" #include "list.h" #include "windowstr.h" #include "dixstruct.h" #include #include "dri3.h" extern DevPrivateKeyRec dri3_screen_private_key; typedef struct dri3_dmabuf_format { uint32_t format; uint32_t num_modifiers; uint64_t *modifiers; } dri3_dmabuf_format_rec, *dri3_dmabuf_format_ptr; typedef struct dri3_screen_priv { CloseScreenProcPtr CloseScreen; ConfigNotifyProcPtr ConfigNotify; DestroyWindowProcPtr DestroyWindow; Bool formats_cached; CARD32 num_formats; dri3_dmabuf_format_ptr formats; const dri3_screen_info_rec *info; } dri3_screen_priv_rec, *dri3_screen_priv_ptr; #define wrap(priv,real,mem,func) {\ priv->mem = real->mem; \ real->mem = func; \ } #define unwrap(priv,real,mem) {\ real->mem = priv->mem; \ } static inline dri3_screen_priv_ptr dri3_screen_priv(ScreenPtr screen) { return (dri3_screen_priv_ptr)dixLookupPrivate(&(screen)->devPrivates, &dri3_screen_private_key); } int proc_dri3_dispatch(ClientPtr client); int sproc_dri3_dispatch(ClientPtr client); /* DDX interface */ int dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd); int dri3_pixmap_from_fds(PixmapPtr *ppixmap, ScreenPtr screen, CARD8 num_fds, const int *fds, CARD16 width, CARD16 height, const CARD32 *strides, const CARD32 *offsets, CARD8 depth, CARD8 bpp, CARD64 modifier); int dri3_fd_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size); int dri3_fds_from_pixmap(PixmapPtr pixmap, int *fds, uint32_t *strides, uint32_t *offsets, uint64_t *modifier); int dri3_get_supported_modifiers(ScreenPtr screen, DrawablePtr drawable, CARD8 depth, CARD8 bpp, CARD32 *num_drawable_modifiers, CARD64 **drawable_modifiers, CARD32 *num_screen_modifiers, CARD64 **screen_modifiers); #endif /* _DRI3PRIV_H_ */ xorg-server-1.20.13/dri3/dri3.c0000644000175000017500000000652514100573756012750 00000000000000/* * Copyright © 2013 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifdef HAVE_XORG_CONFIG_H #include #endif #include "dri3_priv.h" #include static int dri3_request; DevPrivateKeyRec dri3_screen_private_key; static int dri3_screen_generation; static Bool dri3_close_screen(ScreenPtr screen) { dri3_screen_priv_ptr screen_priv = dri3_screen_priv(screen); unwrap(screen_priv, screen, CloseScreen); free(screen_priv); return (*screen->CloseScreen) (screen); } Bool dri3_screen_init(ScreenPtr screen, const dri3_screen_info_rec *info) { dri3_screen_generation = serverGeneration; if (!dixRegisterPrivateKey(&dri3_screen_private_key, PRIVATE_SCREEN, 0)) return FALSE; if (!dri3_screen_priv(screen)) { dri3_screen_priv_ptr screen_priv = calloc(1, sizeof (dri3_screen_priv_rec)); if (!screen_priv) return FALSE; wrap(screen_priv, screen, CloseScreen, dri3_close_screen); screen_priv->info = info; dixSetPrivate(&screen->devPrivates, &dri3_screen_private_key, screen_priv); } return TRUE; } void dri3_extension_init(void) { ExtensionEntry *extension; int i; /* If no screens support DRI3, there's no point offering the * extension at all */ if (dri3_screen_generation != serverGeneration) return; #ifdef PANORAMIX if (!noPanoramiXExtension) return; #endif extension = AddExtension(DRI3_NAME, DRI3NumberEvents, DRI3NumberErrors, proc_dri3_dispatch, sproc_dri3_dispatch, NULL, StandardMinorOpcode); if (!extension) goto bail; dri3_request = extension->base; for (i = 0; i < screenInfo.numScreens; i++) { if (!dri3_screen_init(screenInfo.screens[i], NULL)) goto bail; } return; bail: FatalError("Cannot initialize DRI3 extension"); } uint32_t drm_format_for_depth(uint32_t depth, uint32_t bpp) { switch (bpp) { case 16: return DRM_FORMAT_RGB565; case 24: return DRM_FORMAT_XRGB8888; case 30: return DRM_FORMAT_XRGB2101010; case 32: return DRM_FORMAT_ARGB8888; default: return 0; } } xorg-server-1.20.13/dri3/dri3_request.c0000644000175000017500000004740314100573756014520 00000000000000/* * Copyright © 2013 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifdef HAVE_XORG_CONFIG_H #include #endif #include "dri3_priv.h" #include #include #include #include "../Xext/syncsdk.h" #include #include static Bool dri3_screen_can_one_point_two(ScreenPtr screen) { dri3_screen_priv_ptr dri3 = dri3_screen_priv(screen); if (dri3 && dri3->info && dri3->info->version >= 2 && dri3->info->pixmap_from_fds && dri3->info->fds_from_pixmap && dri3->info->get_formats && dri3->info->get_modifiers && dri3->info->get_drawable_modifiers) return TRUE; return FALSE; } static int proc_dri3_query_version(ClientPtr client) { REQUEST(xDRI3QueryVersionReq); xDRI3QueryVersionReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .majorVersion = SERVER_DRI3_MAJOR_VERSION, .minorVersion = SERVER_DRI3_MINOR_VERSION }; REQUEST_SIZE_MATCH(xDRI3QueryVersionReq); for (int i = 0; i < screenInfo.numScreens; i++) { if (!dri3_screen_can_one_point_two(screenInfo.screens[i])) { rep.minorVersion = 0; break; } } for (int i = 0; i < screenInfo.numGPUScreens; i++) { if (!dri3_screen_can_one_point_two(screenInfo.gpuscreens[i])) { rep.minorVersion = 0; break; } } /* From DRI3 proto: * * The client sends the highest supported version to the server * and the server sends the highest version it supports, but no * higher than the requested version. */ if (rep.majorVersion > stuff->majorVersion || (rep.majorVersion == stuff->majorVersion && rep.minorVersion > stuff->minorVersion)) { rep.majorVersion = stuff->majorVersion; rep.minorVersion = stuff->minorVersion; } if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.majorVersion); swapl(&rep.minorVersion); } WriteToClient(client, sizeof(rep), &rep); return Success; } int dri3_send_open_reply(ClientPtr client, int fd) { xDRI3OpenReply rep = { .type = X_Reply, .nfd = 1, .sequenceNumber = client->sequence, .length = 0, }; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); } if (WriteFdToClient(client, fd, TRUE) < 0) { close(fd); return BadAlloc; } WriteToClient(client, sizeof (rep), &rep); return Success; } static int proc_dri3_open(ClientPtr client) { REQUEST(xDRI3OpenReq); RRProviderPtr provider; DrawablePtr drawable; ScreenPtr screen; int fd; int status; REQUEST_SIZE_MATCH(xDRI3OpenReq); status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess); if (status != Success) return status; if (stuff->provider == None) provider = NULL; else if (!RRProviderType) { return BadMatch; } else { VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); if (drawable->pScreen != provider->pScreen) return BadMatch; } screen = drawable->pScreen; status = dri3_open(client, screen, provider, &fd); if (status != Success) return status; if (client->ignoreCount == 0) return dri3_send_open_reply(client, fd); return Success; } static int proc_dri3_pixmap_from_buffer(ClientPtr client) { REQUEST(xDRI3PixmapFromBufferReq); int fd; DrawablePtr drawable; PixmapPtr pixmap; CARD32 stride, offset; int rc; SetReqFds(client, 1); REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq); LEGAL_NEW_RESOURCE(stuff->pixmap, client); rc = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess); if (rc != Success) { client->errorValue = stuff->drawable; return rc; } if (!stuff->width || !stuff->height) { client->errorValue = 0; return BadValue; } if (stuff->width > 32767 || stuff->height > 32767) return BadAlloc; if (stuff->depth != 1) { DepthPtr depth = drawable->pScreen->allowedDepths; int i; for (i = 0; i < drawable->pScreen->numDepths; i++, depth++) if (depth->depth == stuff->depth) break; if (i == drawable->pScreen->numDepths) { client->errorValue = stuff->depth; return BadValue; } } fd = ReadFdFromClient(client); if (fd < 0) return BadValue; offset = 0; stride = stuff->stride; rc = dri3_pixmap_from_fds(&pixmap, drawable->pScreen, 1, &fd, stuff->width, stuff->height, &stride, &offset, stuff->depth, stuff->bpp, DRM_FORMAT_MOD_INVALID); close (fd); if (rc != Success) return rc; pixmap->drawable.id = stuff->pixmap; /* security creation/labeling check */ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, pixmap, RT_NONE, NULL, DixCreateAccess); if (rc != Success) { (*drawable->pScreen->DestroyPixmap) (pixmap); return rc; } if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap)) return BadAlloc; return Success; } static int proc_dri3_buffer_from_pixmap(ClientPtr client) { REQUEST(xDRI3BufferFromPixmapReq); xDRI3BufferFromPixmapReply rep = { .type = X_Reply, .nfd = 1, .sequenceNumber = client->sequence, .length = 0, }; int rc; int fd; PixmapPtr pixmap; REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq); rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP, client, DixWriteAccess); if (rc != Success) { client->errorValue = stuff->pixmap; return rc; } rep.width = pixmap->drawable.width; rep.height = pixmap->drawable.height; rep.depth = pixmap->drawable.depth; rep.bpp = pixmap->drawable.bitsPerPixel; fd = dri3_fd_from_pixmap(pixmap, &rep.stride, &rep.size); if (fd < 0) return BadPixmap; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.size); swaps(&rep.width); swaps(&rep.height); swaps(&rep.stride); } if (WriteFdToClient(client, fd, TRUE) < 0) { close(fd); return BadAlloc; } WriteToClient(client, sizeof(rep), &rep); return Success; } static int proc_dri3_fence_from_fd(ClientPtr client) { REQUEST(xDRI3FenceFromFDReq); DrawablePtr drawable; int fd; int status; SetReqFds(client, 1); REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq); LEGAL_NEW_RESOURCE(stuff->fence, client); status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess); if (status != Success) return status; fd = ReadFdFromClient(client); if (fd < 0) return BadValue; status = SyncCreateFenceFromFD(client, drawable, stuff->fence, fd, stuff->initially_triggered); return status; } static int proc_dri3_fd_from_fence(ClientPtr client) { REQUEST(xDRI3FDFromFenceReq); xDRI3FDFromFenceReply rep = { .type = X_Reply, .nfd = 1, .sequenceNumber = client->sequence, .length = 0, }; DrawablePtr drawable; int fd; int status; SyncFence *fence; REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq); status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess); if (status != Success) return status; status = SyncVerifyFence(&fence, stuff->fence, client, DixWriteAccess); if (status != Success) return status; fd = SyncFDFromFence(client, drawable, fence); if (fd < 0) return BadMatch; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); } if (WriteFdToClient(client, fd, FALSE) < 0) return BadAlloc; WriteToClient(client, sizeof(rep), &rep); return Success; } static int proc_dri3_get_supported_modifiers(ClientPtr client) { REQUEST(xDRI3GetSupportedModifiersReq); xDRI3GetSupportedModifiersReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, }; WindowPtr window; ScreenPtr pScreen; CARD64 *window_modifiers = NULL; CARD64 *screen_modifiers = NULL; CARD32 nwindowmodifiers = 0; CARD32 nscreenmodifiers = 0; int status; int i; REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq); status = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess); if (status != Success) return status; pScreen = window->drawable.pScreen; dri3_get_supported_modifiers(pScreen, &window->drawable, stuff->depth, stuff->bpp, &nwindowmodifiers, &window_modifiers, &nscreenmodifiers, &screen_modifiers); rep.numWindowModifiers = nwindowmodifiers; rep.numScreenModifiers = nscreenmodifiers; rep.length = bytes_to_int32(rep.numWindowModifiers * sizeof(CARD64)) + bytes_to_int32(rep.numScreenModifiers * sizeof(CARD64)); if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.numWindowModifiers); swapl(&rep.numScreenModifiers); for (i = 0; i < nwindowmodifiers; i++) swapll(&window_modifiers[i]); for (i = 0; i < nscreenmodifiers; i++) swapll(&screen_modifiers[i]); } WriteToClient(client, sizeof(rep), &rep); WriteToClient(client, nwindowmodifiers * sizeof(CARD64), window_modifiers); WriteToClient(client, nscreenmodifiers * sizeof(CARD64), screen_modifiers); free(window_modifiers); free(screen_modifiers); return Success; } static int proc_dri3_pixmap_from_buffers(ClientPtr client) { REQUEST(xDRI3PixmapFromBuffersReq); int fds[4]; CARD32 strides[4], offsets[4]; ScreenPtr screen; WindowPtr window; PixmapPtr pixmap; int rc; int i; SetReqFds(client, stuff->num_buffers); REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq); LEGAL_NEW_RESOURCE(stuff->pixmap, client); rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess); if (rc != Success) { client->errorValue = stuff->window; return rc; } screen = window->drawable.pScreen; if (!stuff->width || !stuff->height || !stuff->bpp || !stuff->depth) { client->errorValue = 0; return BadValue; } if (stuff->width > 32767 || stuff->height > 32767) return BadAlloc; if (stuff->depth != 1) { DepthPtr depth = screen->allowedDepths; int j; for (j = 0; j < screen->numDepths; j++, depth++) if (depth->depth == stuff->depth) break; if (j == screen->numDepths) { client->errorValue = stuff->depth; return BadValue; } } if (!stuff->num_buffers || stuff->num_buffers > 4) { client->errorValue = stuff->num_buffers; return BadValue; } for (i = 0; i < stuff->num_buffers; i++) { fds[i] = ReadFdFromClient(client); if (fds[i] < 0) { while (--i >= 0) close(fds[i]); return BadValue; } } strides[0] = stuff->stride0; strides[1] = stuff->stride1; strides[2] = stuff->stride2; strides[3] = stuff->stride3; offsets[0] = stuff->offset0; offsets[1] = stuff->offset1; offsets[2] = stuff->offset2; offsets[3] = stuff->offset3; rc = dri3_pixmap_from_fds(&pixmap, screen, stuff->num_buffers, fds, stuff->width, stuff->height, strides, offsets, stuff->depth, stuff->bpp, stuff->modifier); for (i = 0; i < stuff->num_buffers; i++) close (fds[i]); if (rc != Success) return rc; pixmap->drawable.id = stuff->pixmap; /* security creation/labeling check */ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, pixmap, RT_NONE, NULL, DixCreateAccess); if (rc != Success) { (*screen->DestroyPixmap) (pixmap); return rc; } if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap)) return BadAlloc; return Success; } static int proc_dri3_buffers_from_pixmap(ClientPtr client) { REQUEST(xDRI3BuffersFromPixmapReq); xDRI3BuffersFromPixmapReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, }; int rc; int fds[4]; int num_fds; uint32_t strides[4], offsets[4]; uint64_t modifier; int i; PixmapPtr pixmap; REQUEST_SIZE_MATCH(xDRI3BuffersFromPixmapReq); rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP, client, DixWriteAccess); if (rc != Success) { client->errorValue = stuff->pixmap; return rc; } num_fds = dri3_fds_from_pixmap(pixmap, fds, strides, offsets, &modifier); if (num_fds == 0) return BadPixmap; rep.nfd = num_fds; rep.length = bytes_to_int32(num_fds * 2 * sizeof(CARD32)); rep.width = pixmap->drawable.width; rep.height = pixmap->drawable.height; rep.depth = pixmap->drawable.depth; rep.bpp = pixmap->drawable.bitsPerPixel; rep.modifier = modifier; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swaps(&rep.width); swaps(&rep.height); swapll(&rep.modifier); for (i = 0; i < num_fds; i++) { swapl(&strides[i]); swapl(&offsets[i]); } } for (i = 0; i < num_fds; i++) { if (WriteFdToClient(client, fds[i], TRUE) < 0) { while (i--) close(fds[i]); return BadAlloc; } } WriteToClient(client, sizeof(rep), &rep); WriteToClient(client, num_fds * sizeof(CARD32), strides); WriteToClient(client, num_fds * sizeof(CARD32), offsets); return Success; } int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = { proc_dri3_query_version, /* 0 */ proc_dri3_open, /* 1 */ proc_dri3_pixmap_from_buffer, /* 2 */ proc_dri3_buffer_from_pixmap, /* 3 */ proc_dri3_fence_from_fd, /* 4 */ proc_dri3_fd_from_fence, /* 5 */ proc_dri3_get_supported_modifiers, /* 6 */ proc_dri3_pixmap_from_buffers, /* 7 */ proc_dri3_buffers_from_pixmap, /* 8 */ }; int proc_dri3_dispatch(ClientPtr client) { REQUEST(xReq); if (!client->local) return BadMatch; if (stuff->data >= DRI3NumberRequests || !proc_dri3_vector[stuff->data]) return BadRequest; return (*proc_dri3_vector[stuff->data]) (client); } static int _X_COLD sproc_dri3_query_version(ClientPtr client) { REQUEST(xDRI3QueryVersionReq); REQUEST_SIZE_MATCH(xDRI3QueryVersionReq); swaps(&stuff->length); swapl(&stuff->majorVersion); swapl(&stuff->minorVersion); return (*proc_dri3_vector[stuff->dri3ReqType]) (client); } static int _X_COLD sproc_dri3_open(ClientPtr client) { REQUEST(xDRI3OpenReq); REQUEST_SIZE_MATCH(xDRI3OpenReq); swaps(&stuff->length); swapl(&stuff->drawable); swapl(&stuff->provider); return (*proc_dri3_vector[stuff->dri3ReqType]) (client); } static int _X_COLD sproc_dri3_pixmap_from_buffer(ClientPtr client) { REQUEST(xDRI3PixmapFromBufferReq); REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq); swaps(&stuff->length); swapl(&stuff->pixmap); swapl(&stuff->drawable); swapl(&stuff->size); swaps(&stuff->width); swaps(&stuff->height); swaps(&stuff->stride); return (*proc_dri3_vector[stuff->dri3ReqType]) (client); } static int _X_COLD sproc_dri3_buffer_from_pixmap(ClientPtr client) { REQUEST(xDRI3BufferFromPixmapReq); REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq); swaps(&stuff->length); swapl(&stuff->pixmap); return (*proc_dri3_vector[stuff->dri3ReqType]) (client); } static int _X_COLD sproc_dri3_fence_from_fd(ClientPtr client) { REQUEST(xDRI3FenceFromFDReq); REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq); swaps(&stuff->length); swapl(&stuff->drawable); swapl(&stuff->fence); return (*proc_dri3_vector[stuff->dri3ReqType]) (client); } static int _X_COLD sproc_dri3_fd_from_fence(ClientPtr client) { REQUEST(xDRI3FDFromFenceReq); REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq); swaps(&stuff->length); swapl(&stuff->drawable); swapl(&stuff->fence); return (*proc_dri3_vector[stuff->dri3ReqType]) (client); } static int _X_COLD sproc_dri3_get_supported_modifiers(ClientPtr client) { REQUEST(xDRI3GetSupportedModifiersReq); REQUEST_SIZE_MATCH(xDRI3GetSupportedModifiersReq); swaps(&stuff->length); swapl(&stuff->window); return (*proc_dri3_vector[stuff->dri3ReqType]) (client); } static int _X_COLD sproc_dri3_pixmap_from_buffers(ClientPtr client) { REQUEST(xDRI3PixmapFromBuffersReq); REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq); swaps(&stuff->length); swapl(&stuff->pixmap); swapl(&stuff->window); swaps(&stuff->width); swaps(&stuff->height); swapl(&stuff->stride0); swapl(&stuff->offset0); swapl(&stuff->stride1); swapl(&stuff->offset1); swapl(&stuff->stride2); swapl(&stuff->offset2); swapl(&stuff->stride3); swapl(&stuff->offset3); swapll(&stuff->modifier); return (*proc_dri3_vector[stuff->dri3ReqType]) (client); } static int _X_COLD sproc_dri3_buffers_from_pixmap(ClientPtr client) { REQUEST(xDRI3BuffersFromPixmapReq); REQUEST_SIZE_MATCH(xDRI3BuffersFromPixmapReq); swaps(&stuff->length); swapl(&stuff->pixmap); return (*proc_dri3_vector[stuff->dri3ReqType]) (client); } int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = { sproc_dri3_query_version, /* 0 */ sproc_dri3_open, /* 1 */ sproc_dri3_pixmap_from_buffer, /* 2 */ sproc_dri3_buffer_from_pixmap, /* 3 */ sproc_dri3_fence_from_fd, /* 4 */ sproc_dri3_fd_from_fence, /* 5 */ sproc_dri3_get_supported_modifiers, /* 6 */ sproc_dri3_pixmap_from_buffers, /* 7 */ sproc_dri3_buffers_from_pixmap, /* 8 */ }; int _X_COLD sproc_dri3_dispatch(ClientPtr client) { REQUEST(xReq); if (!client->local) return BadMatch; if (stuff->data >= DRI3NumberRequests || !sproc_dri3_vector[stuff->data]) return BadRequest; return (*sproc_dri3_vector[stuff->data]) (client); } xorg-server-1.20.13/dri3/dri3_screen.c0000644000175000017500000002333414100573756014304 00000000000000/* * Copyright © 2013 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifdef HAVE_XORG_CONFIG_H #include #endif #include "dri3_priv.h" #include #include #include #include #include #include int dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd) { dri3_screen_priv_ptr ds = dri3_screen_priv(screen); const dri3_screen_info_rec *info = ds->info; if (info == NULL) return BadMatch; if (info->version >= 1 && info->open_client != NULL) return (*info->open_client) (client, screen, provider, fd); if (info->open != NULL) return (*info->open) (screen, provider, fd); return BadMatch; } int dri3_pixmap_from_fds(PixmapPtr *ppixmap, ScreenPtr screen, CARD8 num_fds, const int *fds, CARD16 width, CARD16 height, const CARD32 *strides, const CARD32 *offsets, CARD8 depth, CARD8 bpp, CARD64 modifier) { dri3_screen_priv_ptr ds = dri3_screen_priv(screen); const dri3_screen_info_rec *info = ds->info; PixmapPtr pixmap; if (!info) return BadImplementation; if (info->version >= 2 && info->pixmap_from_fds != NULL) { pixmap = (*info->pixmap_from_fds) (screen, num_fds, fds, width, height, strides, offsets, depth, bpp, modifier); } else if (info->pixmap_from_fd != NULL && num_fds == 1) { pixmap = (*info->pixmap_from_fd) (screen, fds[0], width, height, strides[0], depth, bpp); } else { return BadImplementation; } if (!pixmap) return BadAlloc; *ppixmap = pixmap; return Success; } int dri3_fds_from_pixmap(PixmapPtr pixmap, int *fds, uint32_t *strides, uint32_t *offsets, uint64_t *modifier) { ScreenPtr screen = pixmap->drawable.pScreen; dri3_screen_priv_ptr ds = dri3_screen_priv(screen); const dri3_screen_info_rec *info = ds->info; if (!info) return 0; if (info->version >= 2 && info->fds_from_pixmap != NULL) { return (*info->fds_from_pixmap)(screen, pixmap, fds, strides, offsets, modifier); } else if (info->fd_from_pixmap != NULL) { CARD16 stride; CARD32 size; fds[0] = (*info->fd_from_pixmap)(screen, pixmap, &stride, &size); if (fds[0] < 0) return 0; strides[0] = stride; offsets[0] = 0; *modifier = DRM_FORMAT_MOD_INVALID; return 1; } else { return 0; } } int dri3_fd_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { ScreenPtr screen = pixmap->drawable.pScreen; dri3_screen_priv_ptr ds = dri3_screen_priv(screen); const dri3_screen_info_rec *info = ds->info; uint32_t strides[4]; uint32_t offsets[4]; uint64_t modifier; int fds[4]; int num_fds; if (!info) return -1; /* Preferentially use the old interface, allowing the implementation to * ensure the buffer is in a single-plane format which doesn't need * modifiers. */ if (info->fd_from_pixmap != NULL) return (*info->fd_from_pixmap)(screen, pixmap, stride, size); if (info->version < 2 || info->fds_from_pixmap == NULL) return -1; /* If using the new interface, make sure that it's a single plane starting * at 0 within the BO. We don't check the modifier, as the client may * have an auxiliary mechanism for determining the modifier itself. */ num_fds = info->fds_from_pixmap(screen, pixmap, fds, strides, offsets, &modifier); if (num_fds != 1 || offsets[0] != 0) { int i; for (i = 0; i < num_fds; i++) close(fds[i]); return -1; } *stride = strides[0]; *size = size[0]; return fds[0]; } static int cache_formats_and_modifiers(ScreenPtr screen) { dri3_screen_priv_ptr ds = dri3_screen_priv(screen); const dri3_screen_info_rec *info = ds->info; CARD32 num_formats; CARD32 *formats; uint32_t num_modifiers; uint64_t *modifiers; int i; if (ds->formats_cached) return Success; if (!info) return BadImplementation; if (info->version < 2 || !info->get_formats || !info->get_modifiers) { ds->formats = NULL; ds->num_formats = 0; ds->formats_cached = TRUE; return Success; } if (!info->get_formats(screen, &num_formats, &formats)) return BadAlloc; if (!num_formats) { ds->num_formats = 0; ds->formats_cached = TRUE; return Success; } ds->formats = calloc(num_formats, sizeof(dri3_dmabuf_format_rec)); if (!ds->formats) return BadAlloc; for (i = 0; i < num_formats; i++) { dri3_dmabuf_format_ptr iter = &ds->formats[i]; if (!info->get_modifiers(screen, formats[i], &num_modifiers, &modifiers)) continue; if (!num_modifiers) continue; iter->format = formats[i]; iter->num_modifiers = num_modifiers; iter->modifiers = modifiers; } ds->num_formats = i; ds->formats_cached = TRUE; return Success; } int dri3_get_supported_modifiers(ScreenPtr screen, DrawablePtr drawable, CARD8 depth, CARD8 bpp, CARD32 *num_intersect_modifiers, CARD64 **intersect_modifiers, CARD32 *num_screen_modifiers, CARD64 **screen_modifiers) { dri3_screen_priv_ptr ds = dri3_screen_priv(screen); const dri3_screen_info_rec *info = ds->info; int i, j; int ret; uint32_t num_drawable_mods; uint64_t *drawable_mods; CARD64 *intersect_mods = NULL; CARD64 *screen_mods = NULL; CARD32 format; dri3_dmabuf_format_ptr screen_format = NULL; ret = cache_formats_and_modifiers(screen); if (ret != Success) return ret; format = drm_format_for_depth(depth, bpp); if (format == 0) return BadValue; /* Find screen-global modifiers from cache */ for (i = 0; i < ds->num_formats; i++) { if (ds->formats[i].format == format) { screen_format = &ds->formats[i]; break; } } if (screen_format == NULL) return BadMatch; if (screen_format->num_modifiers == 0) { *num_screen_modifiers = 0; *num_intersect_modifiers = 0; return Success; } if (!info->get_drawable_modifiers || !info->get_drawable_modifiers(drawable, format, &num_drawable_mods, &drawable_mods)) { num_drawable_mods = 0; drawable_mods = NULL; } /* We're allocating slightly more memory than necessary but it reduces * the complexity of finding the intersection set. */ screen_mods = malloc(screen_format->num_modifiers * sizeof(CARD64)); if (!screen_mods) return BadAlloc; if (num_drawable_mods > 0) { intersect_mods = malloc(screen_format->num_modifiers * sizeof(CARD64)); if (!intersect_mods) { free(screen_mods); return BadAlloc; } } *num_screen_modifiers = 0; *num_intersect_modifiers = 0; for (i = 0; i < screen_format->num_modifiers; i++) { CARD64 modifier = screen_format->modifiers[i]; Bool intersect = FALSE; for (j = 0; j < num_drawable_mods; j++) { if (drawable_mods[j] == modifier) { intersect = TRUE; break; } } if (intersect) { intersect_mods[*num_intersect_modifiers] = modifier; *num_intersect_modifiers += 1; } else { screen_mods[*num_screen_modifiers] = modifier; *num_screen_modifiers += 1; } } assert(*num_intersect_modifiers + *num_screen_modifiers == screen_format->num_modifiers); *intersect_modifiers = intersect_mods; *screen_modifiers = screen_mods; free(drawable_mods); return Success; } xorg-server-1.20.13/exa/0000755000175000017500000000000014100574020011710 500000000000000xorg-server-1.20.13/exa/meson.build0000644000175000017500000000074514100573756014017 00000000000000srcs_exa = [ 'exa.c', 'exa_classic.c', 'exa_migration_classic.c', 'exa_driver.c', 'exa_mixed.c', 'exa_migration_mixed.c', 'exa_accel.c', 'exa_glyphs.c', 'exa_offscreen.c', 'exa_render.c', 'exa_unaccel.c', ] libxserver_exa = static_library('libxserver_exa', srcs_exa, include_directories: inc, dependencies: common_dep, c_args: '-DHAVE_XORG_CONFIG_H' ) if build_xorg install_data('exa.h', install_dir: xorgsdkdir) endif xorg-server-1.20.13/exa/Makefile.am0000644000175000017500000000056414100573756013710 00000000000000noinst_LTLIBRARIES = libexa.la if XORG sdk_HEADERS = exa.h endif AM_CPPFLAGS = $(XORG_INCS) AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) libexa_la_SOURCES = \ exa.c \ exa.h \ exa_classic.c \ exa_migration_classic.c \ exa_driver.c \ exa_mixed.c \ exa_migration_mixed.c \ exa_accel.c \ exa_glyphs.c \ exa_offscreen.c \ exa_render.c \ exa_priv.h \ exa_unaccel.c xorg-server-1.20.13/exa/exa.h0000644000175000017500000010042514100573756012577 00000000000000/* * * Copyright (C) 2000 Keith Packard * 2004 Eric Anholt * 2005 Zack Rusin * * 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 copyright holders not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Copyright holders make no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /** @file * This is the header containing the public API of EXA for exa drivers. */ #ifndef EXA_H #define EXA_H #include "scrnintstr.h" #include "pixmapstr.h" #include "windowstr.h" #include "gcstruct.h" #include "picturestr.h" #include "fb.h" #define EXA_VERSION_MAJOR 2 #define EXA_VERSION_MINOR 6 #define EXA_VERSION_RELEASE 0 typedef struct _ExaOffscreenArea ExaOffscreenArea; typedef void (*ExaOffscreenSaveProc) (ScreenPtr pScreen, ExaOffscreenArea * area); typedef enum _ExaOffscreenState { ExaOffscreenAvail, ExaOffscreenRemovable, ExaOffscreenLocked } ExaOffscreenState; struct _ExaOffscreenArea { int base_offset; /* allocation base */ int offset; /* aligned offset */ int size; /* total allocation size */ unsigned last_use; void *privData; ExaOffscreenSaveProc save; ExaOffscreenState state; ExaOffscreenArea *next; unsigned eviction_cost; ExaOffscreenArea *prev; /* Double-linked list for defragmentation */ int align; /* required alignment */ }; /** * The ExaDriver structure is allocated through exaDriverAlloc(), and then * fllled in by drivers. */ typedef struct _ExaDriver { /** * exa_major and exa_minor should be set by the driver to the version of * EXA which the driver was compiled for (or configures itself at runtime * to support). This allows EXA to extend the structure for new features * without breaking ABI for drivers compiled against older versions. */ int exa_major, exa_minor; /** * memoryBase is the address of the beginning of framebuffer memory. * The visible screen should be within memoryBase to memoryBase + * memorySize. */ CARD8 *memoryBase; /** * offScreenBase is the offset from memoryBase of the beginning of the area * to be managed by EXA's linear offscreen memory manager. * * In XFree86 DDX drivers, this is probably: * (pScrn->displayWidth * cpp * pScrn->virtualY) */ unsigned long offScreenBase; /** * memorySize is the length (in bytes) of framebuffer memory beginning * from memoryBase. * * The offscreen memory manager will manage the area beginning at * (memoryBase + offScreenBase), with a length of (memorySize - * offScreenBase) * * In XFree86 DDX drivers, this is probably (pScrn->videoRam * 1024) */ unsigned long memorySize; /** * pixmapOffsetAlign is the byte alignment necessary for pixmap offsets * within framebuffer. * * Hardware typically has a required alignment of offsets, which may or may * not be a power of two. EXA will ensure that pixmaps managed by the * offscreen memory manager meet this alignment requirement. */ int pixmapOffsetAlign; /** * pixmapPitchAlign is the byte alignment necessary for pixmap pitches * within the framebuffer. * * Hardware typically has a required alignment of pitches for acceleration. * For 3D hardware, Composite acceleration often requires that source and * mask pixmaps (textures) have a power-of-two pitch, which can be demanded * using EXA_OFFSCREEN_ALIGN_POT. These pitch requirements only apply to * pixmaps managed by the offscreen memory manager. Thus, it is up to the * driver to ensure that the visible screen has an appropriate pitch for * acceleration. */ int pixmapPitchAlign; /** * The flags field is bitfield of boolean values controlling EXA's behavior. * * The flags in clude EXA_OFFSCREEN_PIXMAPS, EXA_OFFSCREEN_ALIGN_POT, and * EXA_TWO_BITBLT_DIRECTIONS. */ int flags; /** @{ */ /** * maxX controls the X coordinate limitation for rendering from the card. * The driver should never receive a request for rendering beyond maxX * in the X direction from the origin of a pixmap. */ int maxX; /** * maxY controls the Y coordinate limitation for rendering from the card. * The driver should never receive a request for rendering beyond maxY * in the Y direction from the origin of a pixmap. */ int maxY; /** @} */ /* private */ ExaOffscreenArea *offScreenAreas; Bool needsSync; int lastMarker; /** @name Solid * @{ */ /** * PrepareSolid() sets up the driver for doing a solid fill. * @param pPixmap Destination pixmap * @param alu raster operation * @param planemask write mask for the fill * @param fg "foreground" color for the fill * * This call should set up the driver for doing a series of solid fills * through the Solid() call. The alu raster op is one of the GX* * graphics functions listed in X.h, and typically maps to a similar * single-byte "ROP" setting in all hardware. The planemask controls * which bits of the destination should be affected, and will only represent * the bits up to the depth of pPixmap. The fg is the pixel value of the * foreground color referred to in ROP descriptions. * * Note that many drivers will need to store some of the data in the driver * private record, for sending to the hardware with each drawing command. * * The PrepareSolid() call is required of all drivers, but it may fail for any * reason. Failure results in a fallback to software rendering. */ Bool (*PrepareSolid) (PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg); /** * Solid() performs a solid fill set up in the last PrepareSolid() call. * * @param pPixmap destination pixmap * @param x1 left coordinate * @param y1 top coordinate * @param x2 right coordinate * @param y2 bottom coordinate * * Performs the fill set up by the last PrepareSolid() call, covering the * area from (x1,y1) to (x2,y2) in pPixmap. Note that the coordinates are * in the coordinate space of the destination pixmap, so the driver will * need to set up the hardware's offset and pitch for the destination * coordinates according to the pixmap's offset and pitch within * framebuffer. This likely means using exaGetPixmapOffset() and * exaGetPixmapPitch(). * * This call is required if PrepareSolid() ever succeeds. */ void (*Solid) (PixmapPtr pPixmap, int x1, int y1, int x2, int y2); /** * DoneSolid() finishes a set of solid fills. * * @param pPixmap destination pixmap. * * The DoneSolid() call is called at the end of a series of consecutive * Solid() calls following a successful PrepareSolid(). This allows drivers * to finish up emitting drawing commands that were buffered, or clean up * state from PrepareSolid(). * * This call is required if PrepareSolid() ever succeeds. */ void (*DoneSolid) (PixmapPtr pPixmap); /** @} */ /** @name Copy * @{ */ /** * PrepareCopy() sets up the driver for doing a copy within video * memory. * * @param pSrcPixmap source pixmap * @param pDstPixmap destination pixmap * @param dx X copy direction * @param dy Y copy direction * @param alu raster operation * @param planemask write mask for the fill * * This call should set up the driver for doing a series of copies from the * the pSrcPixmap to the pDstPixmap. The dx flag will be positive if the * hardware should do the copy from the left to the right, and dy will be * positive if the copy should be done from the top to the bottom. This * is to deal with self-overlapping copies when pSrcPixmap == pDstPixmap. * If your hardware can only support blits that are (left to right, top to * bottom) or (right to left, bottom to top), then you should set * #EXA_TWO_BITBLT_DIRECTIONS, and EXA will break down Copy operations to * ones that meet those requirements. The alu raster op is one of the GX* * graphics functions listed in X.h, and typically maps to a similar * single-byte "ROP" setting in all hardware. The planemask controls which * bits of the destination should be affected, and will only represent the * bits up to the depth of pPixmap. * * Note that many drivers will need to store some of the data in the driver * private record, for sending to the hardware with each drawing command. * * The PrepareCopy() call is required of all drivers, but it may fail for any * reason. Failure results in a fallback to software rendering. */ Bool (*PrepareCopy) (PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int dx, int dy, int alu, Pixel planemask); /** * Copy() performs a copy set up in the last PrepareCopy call. * * @param pDstPixmap destination pixmap * @param srcX source X coordinate * @param srcY source Y coordinate * @param dstX destination X coordinate * @param dstY destination Y coordinate * @param width width of the rectangle to be copied * @param height height of the rectangle to be copied. * * Performs the copy set up by the last PrepareCopy() call, copying the * rectangle from (srcX, srcY) to (srcX + width, srcY + width) in the source * pixmap to the same-sized rectangle at (dstX, dstY) in the destination * pixmap. Those rectangles may overlap in memory, if * pSrcPixmap == pDstPixmap. Note that this call does not receive the * pSrcPixmap as an argument -- if it's needed in this function, it should * be stored in the driver private during PrepareCopy(). As with Solid(), * the coordinates are in the coordinate space of each pixmap, so the driver * will need to set up source and destination pitches and offsets from those * pixmaps, probably using exaGetPixmapOffset() and exaGetPixmapPitch(). * * This call is required if PrepareCopy ever succeeds. */ void (*Copy) (PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height); /** * DoneCopy() finishes a set of copies. * * @param pPixmap destination pixmap. * * The DoneCopy() call is called at the end of a series of consecutive * Copy() calls following a successful PrepareCopy(). This allows drivers * to finish up emitting drawing commands that were buffered, or clean up * state from PrepareCopy(). * * This call is required if PrepareCopy() ever succeeds. */ void (*DoneCopy) (PixmapPtr pDstPixmap); /** @} */ /** @name Composite * @{ */ /** * CheckComposite() checks to see if a composite operation could be * accelerated. * * @param op Render operation * @param pSrcPicture source Picture * @param pMaskPicture mask picture * @param pDstPicture destination Picture * * The CheckComposite() call checks if the driver could handle acceleration * of op with the given source, mask, and destination pictures. This allows * drivers to check source and destination formats, supported operations, * transformations, and component alpha state, and send operations it can't * support to software rendering early on. This avoids costly pixmap * migration to the wrong places when the driver can't accelerate * operations. Note that because migration hasn't happened, the driver * can't know during CheckComposite() what the offsets and pitches of the * pixmaps are going to be. * * See PrepareComposite() for more details on likely issues that drivers * will have in accelerating Composite operations. * * The CheckComposite() call is recommended if PrepareComposite() is * implemented, but is not required. */ Bool (*CheckComposite) (int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture); /** * PrepareComposite() sets up the driver for doing a Composite operation * described in the Render extension protocol spec. * * @param op Render operation * @param pSrcPicture source Picture * @param pMaskPicture mask picture * @param pDstPicture destination Picture * @param pSrc source pixmap * @param pMask mask pixmap * @param pDst destination pixmap * * This call should set up the driver for doing a series of Composite * operations, as described in the Render protocol spec, with the given * pSrcPicture, pMaskPicture, and pDstPicture. The pSrc, pMask, and * pDst are the pixmaps containing the pixel data, and should be used for * setting the offset and pitch used for the coordinate spaces for each of * the Pictures. * * Notes on interpreting Picture structures: * - The Picture structures will always have a valid pDrawable. * - The Picture structures will never have alphaMap set. * - The mask Picture (and therefore pMask) may be NULL, in which case the * operation is simply src OP dst instead of src IN mask OP dst, and * mask coordinates should be ignored. * - pMarkPicture may have componentAlpha set, which greatly changes * the behavior of the Composite operation. componentAlpha has no effect * when set on pSrcPicture or pDstPicture. * - The source and mask Pictures may have a transformation set * (Picture->transform != NULL), which means that the source coordinates * should be transformed by that transformation, resulting in scaling, * rotation, etc. The PictureTransformPoint() call can transform * coordinates for you. Transforms have no effect on Pictures when used * as a destination. * - The source and mask pictures may have a filter set. PictFilterNearest * and PictFilterBilinear are defined in the Render protocol, but others * may be encountered, and must be handled correctly (usually by * PrepareComposite failing, and falling back to software). Filters have * no effect on Pictures when used as a destination. * - The source and mask Pictures may have repeating set, which must be * respected. Many chipsets will be unable to support repeating on * pixmaps that have a width or height that is not a power of two. * * If your hardware can't support source pictures (textures) with * non-power-of-two pitches, you should set #EXA_OFFSCREEN_ALIGN_POT. * * Note that many drivers will need to store some of the data in the driver * private record, for sending to the hardware with each drawing command. * * The PrepareComposite() call is not required. However, it is highly * recommended for performance of antialiased font rendering and performance * of cairo applications. Failure results in a fallback to software * rendering. */ Bool (*PrepareComposite) (int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst); /** * Composite() performs a Composite operation set up in the last * PrepareComposite() call. * * @param pDstPixmap destination pixmap * @param srcX source X coordinate * @param srcY source Y coordinate * @param maskX source X coordinate * @param maskY source Y coordinate * @param dstX destination X coordinate * @param dstY destination Y coordinate * @param width destination rectangle width * @param height destination rectangle height * * Performs the Composite operation set up by the last PrepareComposite() * call, to the rectangle from (dstX, dstY) to (dstX + width, dstY + height) * in the destination Pixmap. Note that if a transformation was set on * the source or mask Pictures, the source rectangles may not be the same * size as the destination rectangles and filtering. Getting the coordinate * transformation right at the subpixel level can be tricky, and rendercheck * can test this for you. * * This call is required if PrepareComposite() ever succeeds. */ void (*Composite) (PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height); /** * DoneComposite() finishes a set of Composite operations. * * @param pPixmap destination pixmap. * * The DoneComposite() call is called at the end of a series of consecutive * Composite() calls following a successful PrepareComposite(). This allows * drivers to finish up emitting drawing commands that were buffered, or * clean up state from PrepareComposite(). * * This call is required if PrepareComposite() ever succeeds. */ void (*DoneComposite) (PixmapPtr pDst); /** @} */ /** * UploadToScreen() loads a rectangle of data from src into pDst. * * @param pDst destination pixmap * @param x destination X coordinate. * @param y destination Y coordinate * @param width width of the rectangle to be copied * @param height height of the rectangle to be copied * @param src pointer to the beginning of the source data * @param src_pitch pitch (in bytes) of the lines of source data. * * UploadToScreen() copies data in system memory beginning at src (with * pitch src_pitch) into the destination pixmap from (x, y) to * (x + width, y + height). This is typically done with hostdata uploads, * where the CPU sets up a blit command on the hardware with instructions * that the blit data will be fed through some sort of aperture on the card. * * If UploadToScreen() is performed asynchronously, it is up to the driver * to call exaMarkSync(). This is in contrast to most other acceleration * calls in EXA. * * UploadToScreen() can aid in pixmap migration, but is most important for * the performance of exaGlyphs() (antialiased font drawing) by allowing * pipelining of data uploads, avoiding a sync of the card after each glyph. * * @return TRUE if the driver successfully uploaded the data. FALSE * indicates that EXA should fall back to doing the upload in software. * * UploadToScreen() is not required, but is recommended if Composite * acceleration is supported. */ Bool (*UploadToScreen) (PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch); /** * UploadToScratch() is no longer used and will be removed next time the EXA * major version needs to be bumped. */ Bool (*UploadToScratch) (PixmapPtr pSrc, PixmapPtr pDst); /** * DownloadFromScreen() loads a rectangle of data from pSrc into dst * * @param pSrc source pixmap * @param x source X coordinate. * @param y source Y coordinate * @param width width of the rectangle to be copied * @param height height of the rectangle to be copied * @param dst pointer to the beginning of the destination data * @param dst_pitch pitch (in bytes) of the lines of destination data. * * DownloadFromScreen() copies data from offscreen memory in pSrc from * (x, y) to (x + width, y + height), to system memory starting at * dst (with pitch dst_pitch). This would usually be done * using scatter-gather DMA, supported by a DRM call, or by blitting to AGP * and then synchronously reading from AGP. Because the implementation * might be synchronous, EXA leaves it up to the driver to call * exaMarkSync() if DownloadFromScreen() was asynchronous. This is in * contrast to most other acceleration calls in EXA. * * DownloadFromScreen() can aid in the largest bottleneck in pixmap * migration, which is the read from framebuffer when evicting pixmaps from * framebuffer memory. Thus, it is highly recommended, even though * implementations are typically complicated. * * @return TRUE if the driver successfully downloaded the data. FALSE * indicates that EXA should fall back to doing the download in software. * * DownloadFromScreen() is not required, but is highly recommended. */ Bool (*DownloadFromScreen) (PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch); /** * MarkSync() requests that the driver mark a synchronization point, * returning an driver-defined integer marker which could be requested for * synchronization to later in WaitMarker(). This might be used in the * future to avoid waiting for full hardware stalls before accessing pixmap * data with the CPU, but is not important in the current incarnation of * EXA. * * Note that drivers should call exaMarkSync() when they have done some * acceleration, rather than their own MarkSync() handler, as otherwise EXA * will be unaware of the driver's acceleration and not sync to it during * fallbacks. * * MarkSync() is optional. */ int (*MarkSync) (ScreenPtr pScreen); /** * WaitMarker() waits for all rendering before the given marker to have * completed. If the driver does not implement MarkSync(), marker is * meaningless, and all rendering by the hardware should be completed before * WaitMarker() returns. * * Note that drivers should call exaWaitSync() to wait for all acceleration * to finish, as otherwise EXA will be unaware of the driver having * synchronized, resulting in excessive WaitMarker() calls. * * WaitMarker() is required of all drivers. */ void (*WaitMarker) (ScreenPtr pScreen, int marker); /** @{ */ /** * PrepareAccess() is called before CPU access to an offscreen pixmap. * * @param pPix the pixmap being accessed * @param index the index of the pixmap being accessed. * * PrepareAccess() will be called before CPU access to an offscreen pixmap. * This can be used to set up hardware surfaces for byteswapping or * untiling, or to adjust the pixmap's devPrivate.ptr for the purpose of * making CPU access use a different aperture. * * The index is one of #EXA_PREPARE_DEST, #EXA_PREPARE_SRC, * #EXA_PREPARE_MASK, #EXA_PREPARE_AUX_DEST, #EXA_PREPARE_AUX_SRC, or * #EXA_PREPARE_AUX_MASK. Since only up to #EXA_NUM_PREPARE_INDICES pixmaps * will have PrepareAccess() called on them per operation, drivers can have * a small, statically-allocated space to maintain state for PrepareAccess() * and FinishAccess() in. Note that PrepareAccess() is only called once per * pixmap and operation, regardless of whether the pixmap is used as a * destination and/or source, and the index may not reflect the usage. * * PrepareAccess() may fail. An example might be the case of hardware that * can set up 1 or 2 surfaces for CPU access, but not 3. If PrepareAccess() * fails, EXA will migrate the pixmap to system memory. * DownloadFromScreen() must be implemented and must not fail if a driver * wishes to fail in PrepareAccess(). PrepareAccess() must not fail when * pPix is the visible screen, because the visible screen can not be * migrated. * * @return TRUE if PrepareAccess() successfully prepared the pixmap for CPU * drawing. * @return FALSE if PrepareAccess() is unsuccessful and EXA should use * DownloadFromScreen() to migate the pixmap out. */ Bool (*PrepareAccess) (PixmapPtr pPix, int index); /** * FinishAccess() is called after CPU access to an offscreen pixmap. * * @param pPix the pixmap being accessed * @param index the index of the pixmap being accessed. * * FinishAccess() will be called after finishing CPU access of an offscreen * pixmap set up by PrepareAccess(). Note that the FinishAccess() will not be * called if PrepareAccess() failed and the pixmap was migrated out. */ void (*FinishAccess) (PixmapPtr pPix, int index); /** * PixmapIsOffscreen() is an optional driver replacement to * exaPixmapHasGpuCopy(). Set to NULL if you want the standard behaviour * of exaPixmapHasGpuCopy(). * * @param pPix the pixmap * @return TRUE if the given drawable is in framebuffer memory. * * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen * memory, meaning that acceleration could probably be done to it, and that it * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it * with the CPU. * * */ Bool (*PixmapIsOffscreen) (PixmapPtr pPix); /** @name PrepareAccess() and FinishAccess() indices * @{ */ /** * EXA_PREPARE_DEST is the index for a pixmap that may be drawn to or * read from. */ #define EXA_PREPARE_DEST 0 /** * EXA_PREPARE_SRC is the index for a pixmap that may be read from */ #define EXA_PREPARE_SRC 1 /** * EXA_PREPARE_SRC is the index for a second pixmap that may be read * from. */ #define EXA_PREPARE_MASK 2 /** * EXA_PREPARE_AUX* are additional indices for other purposes, e.g. * separate alpha maps with Composite operations. */ #define EXA_PREPARE_AUX_DEST 3 #define EXA_PREPARE_AUX_SRC 4 #define EXA_PREPARE_AUX_MASK 5 #define EXA_NUM_PREPARE_INDICES 6 /** @} */ /** * maxPitchPixels controls the pitch limitation for rendering from * the card. * The driver should never receive a request for rendering a pixmap * that has a pitch (in pixels) beyond maxPitchPixels. * * Setting this field is optional -- if your hardware doesn't have * a pitch limitation in pixels, don't set this. If neither this value * nor maxPitchBytes is set, then maxPitchPixels is set to maxX. * If set, it must not be smaller than maxX. * * @sa maxPitchBytes */ int maxPitchPixels; /** * maxPitchBytes controls the pitch limitation for rendering from * the card. * The driver should never receive a request for rendering a pixmap * that has a pitch (in bytes) beyond maxPitchBytes. * * Setting this field is optional -- if your hardware doesn't have * a pitch limitation in bytes, don't set this. * If set, it must not be smaller than maxX * 4. * There's no default value for maxPitchBytes. * * @sa maxPitchPixels */ int maxPitchBytes; /* Hooks to allow driver to its own pixmap memory management */ void *(*CreatePixmap) (ScreenPtr pScreen, int size, int align); void (*DestroyPixmap) (ScreenPtr pScreen, void *driverPriv); /** * Returning a pixmap with non-NULL devPrivate.ptr implies a pixmap which is * not offscreen, which will never be accelerated and Prepare/FinishAccess won't * be called. */ Bool (*ModifyPixmapHeader) (PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, void *pPixData); /* hooks for drivers with tiling support: * driver MUST fill out new_fb_pitch with valid pitch of pixmap */ void *(*CreatePixmap2) (ScreenPtr pScreen, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_fb_pitch); /** @} */ Bool (*SharePixmapBacking)(PixmapPtr pPixmap, ScreenPtr slave, void **handle_p); Bool (*SetSharedPixmapBacking)(PixmapPtr pPixmap, void *handle); } ExaDriverRec, *ExaDriverPtr; /** @name EXA driver flags * @{ */ /** * EXA_OFFSCREEN_PIXMAPS indicates to EXA that the driver can support * offscreen pixmaps. */ #define EXA_OFFSCREEN_PIXMAPS (1 << 0) /** * EXA_OFFSCREEN_ALIGN_POT indicates to EXA that the driver needs pixmaps * to have a power-of-two pitch. */ #define EXA_OFFSCREEN_ALIGN_POT (1 << 1) /** * EXA_TWO_BITBLT_DIRECTIONS indicates to EXA that the driver can only * support copies that are (left-to-right, top-to-bottom) or * (right-to-left, bottom-to-top). */ #define EXA_TWO_BITBLT_DIRECTIONS (1 << 2) /** * EXA_HANDLES_PIXMAPS indicates to EXA that the driver can handle * all pixmap addressing and migration. */ #define EXA_HANDLES_PIXMAPS (1 << 3) /** * EXA_SUPPORTS_PREPARE_AUX indicates to EXA that the driver can handle the * EXA_PREPARE_AUX* indices in the Prepare/FinishAccess hooks. If there are no * such hooks, this flag has no effect. */ #define EXA_SUPPORTS_PREPARE_AUX (1 << 4) /** * EXA_SUPPORTS_OFFSCREEN_OVERLAPS indicates to EXA that the driver Copy hooks * can handle the source and destination occupying overlapping offscreen memory * areas. This allows the offscreen memory defragmentation code to defragment * areas where the defragmented position overlaps the fragmented position. * * Typically this is supported by traditional 2D engines but not by 3D engines. */ #define EXA_SUPPORTS_OFFSCREEN_OVERLAPS (1 << 5) /** * EXA_MIXED_PIXMAPS will hide unacceleratable pixmaps from drivers and manage the * problem known software fallbacks like trapezoids. This only migrates pixmaps one way * into a driver pixmap and then pins it. */ #define EXA_MIXED_PIXMAPS (1 << 6) /** @} */ /* in exa.c */ extern _X_EXPORT ExaDriverPtr exaDriverAlloc(void); extern _X_EXPORT Bool exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo); extern _X_EXPORT void exaDriverFini(ScreenPtr pScreen); extern _X_EXPORT void exaMarkSync(ScreenPtr pScreen); extern _X_EXPORT void exaWaitSync(ScreenPtr pScreen); extern _X_EXPORT unsigned long exaGetPixmapOffset(PixmapPtr pPix); extern _X_EXPORT unsigned long exaGetPixmapPitch(PixmapPtr pPix); extern _X_EXPORT unsigned long exaGetPixmapSize(PixmapPtr pPix); extern _X_EXPORT void *exaGetPixmapDriverPrivate(PixmapPtr p); /* in exa_offscreen.c */ extern _X_EXPORT ExaOffscreenArea *exaOffscreenAlloc(ScreenPtr pScreen, int size, int align, Bool locked, ExaOffscreenSaveProc save, void *privData); extern _X_EXPORT ExaOffscreenArea *exaOffscreenFree(ScreenPtr pScreen, ExaOffscreenArea * area); extern _X_EXPORT void ExaOffscreenMarkUsed(PixmapPtr pPixmap); extern _X_EXPORT void exaEnableDisableFBAccess(ScreenPtr pScreen, Bool enable); extern _X_EXPORT Bool exaDrawableIsOffscreen(DrawablePtr pDrawable); /* in exa.c */ extern _X_EXPORT void exaMoveInPixmap(PixmapPtr pPixmap); extern _X_EXPORT void exaMoveOutPixmap(PixmapPtr pPixmap); /* in exa_unaccel.c */ extern _X_EXPORT CARD32 exaGetPixmapFirstPixel(PixmapPtr pPixmap); /** * Returns TRUE if the given planemask covers all the significant bits in the * pixel values for pDrawable. */ #define EXA_PM_IS_SOLID(_pDrawable, _pm) \ (((_pm) & FbFullMask((_pDrawable)->depth)) == \ FbFullMask((_pDrawable)->depth)) #endif /* EXA_H */ xorg-server-1.20.13/exa/Makefile.in0000644000175000017500000007445414100573775013733 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = exa ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__sdk_HEADERS_DIST) \ $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libexa_la_LIBADD = am_libexa_la_OBJECTS = exa.lo exa_classic.lo exa_migration_classic.lo \ exa_driver.lo exa_mixed.lo exa_migration_mixed.lo exa_accel.lo \ exa_glyphs.lo exa_offscreen.lo exa_render.lo exa_unaccel.lo libexa_la_OBJECTS = $(am_libexa_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/exa.Plo ./$(DEPDIR)/exa_accel.Plo \ ./$(DEPDIR)/exa_classic.Plo ./$(DEPDIR)/exa_driver.Plo \ ./$(DEPDIR)/exa_glyphs.Plo \ ./$(DEPDIR)/exa_migration_classic.Plo \ ./$(DEPDIR)/exa_migration_mixed.Plo ./$(DEPDIR)/exa_mixed.Plo \ ./$(DEPDIR)/exa_offscreen.Plo ./$(DEPDIR)/exa_render.Plo \ ./$(DEPDIR)/exa_unaccel.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libexa_la_SOURCES) DIST_SOURCES = $(libexa_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__sdk_HEADERS_DIST = exa.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 = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(sdkdir)" HEADERS = $(sdk_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libexa.la @XORG_TRUE@sdk_HEADERS = exa.h AM_CPPFLAGS = $(XORG_INCS) AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) libexa_la_SOURCES = \ exa.c \ exa.h \ exa_classic.c \ exa_migration_classic.c \ exa_driver.c \ exa_mixed.c \ exa_migration_mixed.c \ exa_accel.c \ exa_glyphs.c \ exa_offscreen.c \ exa_render.c \ exa_priv.h \ exa_unaccel.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign exa/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign exa/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libexa.la: $(libexa_la_OBJECTS) $(libexa_la_DEPENDENCIES) $(EXTRA_libexa_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libexa_la_OBJECTS) $(libexa_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa_accel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa_classic.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa_driver.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa_glyphs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa_migration_classic.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa_migration_mixed.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa_mixed.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa_offscreen.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa_render.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exa_unaccel.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-sdkHEADERS: $(sdk_HEADERS) @$(NORMAL_INSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sdkdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sdkdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(sdkdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(sdkdir)" || exit $$?; \ done uninstall-sdkHEADERS: @$(NORMAL_UNINSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(sdkdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/exa.Plo -rm -f ./$(DEPDIR)/exa_accel.Plo -rm -f ./$(DEPDIR)/exa_classic.Plo -rm -f ./$(DEPDIR)/exa_driver.Plo -rm -f ./$(DEPDIR)/exa_glyphs.Plo -rm -f ./$(DEPDIR)/exa_migration_classic.Plo -rm -f ./$(DEPDIR)/exa_migration_mixed.Plo -rm -f ./$(DEPDIR)/exa_mixed.Plo -rm -f ./$(DEPDIR)/exa_offscreen.Plo -rm -f ./$(DEPDIR)/exa_render.Plo -rm -f ./$(DEPDIR)/exa_unaccel.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-sdkHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/exa.Plo -rm -f ./$(DEPDIR)/exa_accel.Plo -rm -f ./$(DEPDIR)/exa_classic.Plo -rm -f ./$(DEPDIR)/exa_driver.Plo -rm -f ./$(DEPDIR)/exa_glyphs.Plo -rm -f ./$(DEPDIR)/exa_migration_classic.Plo -rm -f ./$(DEPDIR)/exa_migration_mixed.Plo -rm -f ./$(DEPDIR)/exa_mixed.Plo -rm -f ./$(DEPDIR)/exa_offscreen.Plo -rm -f ./$(DEPDIR)/exa_render.Plo -rm -f ./$(DEPDIR)/exa_unaccel.Plo -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 TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am 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 tags-am uninstall uninstall-am \ uninstall-sdkHEADERS .PRECIOUS: Makefile # 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: xorg-server-1.20.13/exa/exa.c0000644000175000017500000010434114100573756012573 00000000000000/* * Copyright © 2001 Keith Packard * * Partly based on code that is Copyright © 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. */ /** @file * This file covers the initialization and teardown of EXA, and has various * functions not responsible for performing rendering, pixmap migration, or * memory management. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "exa_priv.h" #include "exa.h" DevPrivateKeyRec exaScreenPrivateKeyRec; #ifdef MITSHM static ShmFuncs exaShmFuncs = { NULL, NULL }; #endif /** * exaGetPixmapOffset() returns the offset (in bytes) within the framebuffer of * the beginning of the given pixmap. * * Note that drivers are free to, and often do, munge this offset as necessary * for handing to the hardware -- for example, translating it into a different * aperture. This function may need to be extended in the future if we grow * support for having multiple card-accessible offscreen, such as an AGP memory * pool alongside the framebuffer pool. */ unsigned long exaGetPixmapOffset(PixmapPtr pPix) { ExaScreenPriv(pPix->drawable.pScreen); ExaPixmapPriv(pPix); return (CARD8 *) pExaPixmap->fb_ptr - pExaScr->info->memoryBase; } void * exaGetPixmapDriverPrivate(PixmapPtr pPix) { ExaPixmapPriv(pPix); return pExaPixmap->driverPriv; } /** * exaGetPixmapPitch() returns the pitch (in bytes) of the given pixmap. * * This is a helper to make driver code more obvious, due to the rather obscure * naming of the pitch field in the pixmap. */ unsigned long exaGetPixmapPitch(PixmapPtr pPix) { return pPix->devKind; } /** * exaGetPixmapSize() returns the size in bytes of the given pixmap in video * memory. Only valid when the pixmap is currently in framebuffer. */ unsigned long exaGetPixmapSize(PixmapPtr pPix) { ExaPixmapPrivPtr pExaPixmap; pExaPixmap = ExaGetPixmapPriv(pPix); if (pExaPixmap != NULL) return pExaPixmap->fb_size; return 0; } /** * exaGetDrawablePixmap() returns a backing pixmap for a given drawable. * * @param pDrawable the drawable being requested. * * This function returns the backing pixmap for a drawable, whether it is a * redirected window, unredirected window, or already a pixmap. Note that * coordinate translation is needed when drawing to the backing pixmap of a * redirected window, and the translation coordinates are provided by calling * exaGetOffscreenPixmap() on the drawable. */ PixmapPtr exaGetDrawablePixmap(DrawablePtr pDrawable) { if (pDrawable->type == DRAWABLE_WINDOW) return pDrawable->pScreen->GetWindowPixmap((WindowPtr) pDrawable); else return (PixmapPtr) pDrawable; } /** * Sets the offsets to add to coordinates to make them address the same bits in * the backing drawable. These coordinates are nonzero only for redirected * windows. */ void exaGetDrawableDeltas(DrawablePtr pDrawable, PixmapPtr pPixmap, int *xp, int *yp) { #ifdef COMPOSITE if (pDrawable->type == DRAWABLE_WINDOW) { *xp = -pPixmap->screen_x; *yp = -pPixmap->screen_y; return; } #endif *xp = 0; *yp = 0; } /** * exaPixmapDirty() marks a pixmap as dirty, allowing for * optimizations in pixmap migration when no changes have occurred. */ void exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2) { BoxRec box; RegionRec region; box.x1 = max(x1, 0); box.y1 = max(y1, 0); box.x2 = min(x2, pPix->drawable.width); box.y2 = min(y2, pPix->drawable.height); if (box.x1 >= box.x2 || box.y1 >= box.y2) return; RegionInit(®ion, &box, 1); DamageDamageRegion(&pPix->drawable, ®ion); RegionUninit(®ion); } static int exaLog2(int val) { int bits; if (val <= 0) return 0; for (bits = 0; val != 0; bits++) val >>= 1; return bits - 1; } void exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, int w, int h, int bpp) { pExaPixmap->accel_blocked = 0; if (pExaScr->info->maxPitchPixels) { int max_pitch = pExaScr->info->maxPitchPixels * bits_to_bytes(bpp); if (pExaPixmap->fb_pitch > max_pitch) pExaPixmap->accel_blocked |= EXA_RANGE_PITCH; } if (pExaScr->info->maxPitchBytes && pExaPixmap->fb_pitch > pExaScr->info->maxPitchBytes) pExaPixmap->accel_blocked |= EXA_RANGE_PITCH; if (w > pExaScr->info->maxX) pExaPixmap->accel_blocked |= EXA_RANGE_WIDTH; if (h > pExaScr->info->maxY) pExaPixmap->accel_blocked |= EXA_RANGE_HEIGHT; } void exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, int w, int h, int bpp) { if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1) pExaPixmap->fb_pitch = bits_to_bytes((1 << (exaLog2(w - 1) + 1)) * bpp); else pExaPixmap->fb_pitch = bits_to_bytes(w * bpp); pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch, pExaScr->info->pixmapPitchAlign); } /** * Returns TRUE if the pixmap is not movable. This is the case where it's a * pixmap which has no private (almost always bad) or it's a scratch pixmap created by * some X Server internal component (the score says it's pinned). */ Bool exaPixmapIsPinned(PixmapPtr pPix) { ExaPixmapPriv(pPix); if (pExaPixmap == NULL) EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsPinned was called on a non-exa pixmap.\n"), TRUE); return pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED; } /** * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen * memory, meaning that acceleration could probably be done to it, and that it * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it * with the CPU. * * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly * deal with moving pixmaps in and out of system memory), EXA will give drivers * pixmaps as arguments for which exaPixmapHasGpuCopy() is TRUE. * * @return TRUE if the given drawable is in framebuffer memory. */ Bool exaPixmapHasGpuCopy(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) return FALSE; return (*pExaScr->pixmap_has_gpu_copy) (pPixmap); } /** * exaDrawableIsOffscreen() is a convenience wrapper for exaPixmapHasGpuCopy(). */ Bool exaDrawableIsOffscreen(DrawablePtr pDrawable) { return exaPixmapHasGpuCopy(exaGetDrawablePixmap(pDrawable)); } /** * Returns the pixmap which backs a drawable, and the offsets to add to * coordinates to make them address the same bits in the backing drawable. */ PixmapPtr exaGetOffscreenPixmap(DrawablePtr pDrawable, int *xp, int *yp) { PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); exaGetDrawableDeltas(pDrawable, pPixmap, xp, yp); if (exaPixmapHasGpuCopy(pPixmap)) return pPixmap; else return NULL; } /** * Returns TRUE if the pixmap GPU copy is being accessed. */ Bool ExaDoPrepareAccess(PixmapPtr pPixmap, int index) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); ExaPixmapPriv(pPixmap); Bool has_gpu_copy, ret; int i; if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) return FALSE; if (pExaPixmap == NULL) EXA_FatalErrorDebugWithRet(("EXA bug: ExaDoPrepareAccess was called on a non-exa pixmap.\n"), FALSE); /* Handle repeated / nested calls. */ for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) { if (pExaScr->access[i].pixmap == pPixmap) { pExaScr->access[i].count++; return pExaScr->access[i].retval; } } /* If slot for this index is taken, find an empty slot */ if (pExaScr->access[index].pixmap) { for (index = EXA_NUM_PREPARE_INDICES - 1; index >= 0; index--) if (!pExaScr->access[index].pixmap) break; } /* Access to this pixmap hasn't been prepared yet, so data pointer should be NULL. */ if (pPixmap->devPrivate.ptr != NULL) { EXA_FatalErrorDebug(("EXA bug: pPixmap->devPrivate.ptr was %p, but should have been NULL.\n", pPixmap->devPrivate.ptr)); } has_gpu_copy = exaPixmapHasGpuCopy(pPixmap); if (has_gpu_copy && pExaPixmap->fb_ptr) { pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; ret = TRUE; } else { pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; ret = FALSE; } /* Store so we can handle repeated / nested calls. */ pExaScr->access[index].pixmap = pPixmap; pExaScr->access[index].count = 1; if (!has_gpu_copy) goto out; exaWaitSync(pScreen); if (pExaScr->info->PrepareAccess == NULL) goto out; if (index >= EXA_PREPARE_AUX_DEST && !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) { if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) FatalError("Unsupported AUX indices used on a pinned pixmap.\n"); exaMoveOutPixmap(pPixmap); ret = FALSE; goto out; } if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) { if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED && !(pExaScr->info->flags & EXA_MIXED_PIXMAPS)) FatalError("Driver failed PrepareAccess on a pinned pixmap.\n"); exaMoveOutPixmap(pPixmap); ret = FALSE; goto out; } ret = TRUE; out: pExaScr->access[index].retval = ret; return ret; } /** * exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler. * * It deals with waiting for synchronization with the card, determining if * PrepareAccess() is necessary, and working around PrepareAccess() failure. */ void exaPrepareAccess(DrawablePtr pDrawable, int index) { PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); ExaScreenPriv(pDrawable->pScreen); if (pExaScr->prepare_access_reg) pExaScr->prepare_access_reg(pPixmap, index, NULL); else (void) ExaDoPrepareAccess(pPixmap, index); } /** * exaFinishAccess() is EXA's wrapper for the driver's FinishAccess() handler. * * It deals with calling the driver's FinishAccess() only if necessary. */ void exaFinishAccess(DrawablePtr pDrawable, int index) { ScreenPtr pScreen = pDrawable->pScreen; ExaScreenPriv(pScreen); PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); ExaPixmapPriv(pPixmap); int i; if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) return; if (pExaPixmap == NULL) EXA_FatalErrorDebugWithRet(("EXA bug: exaFinishAccesss was called on a non-exa pixmap.\n"),); /* Handle repeated / nested calls. */ for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) { if (pExaScr->access[i].pixmap == pPixmap) { if (--pExaScr->access[i].count > 0) return; break; } } /* Catch unbalanced Prepare/FinishAccess calls. */ if (i == EXA_NUM_PREPARE_INDICES) EXA_FatalErrorDebugWithRet(("EXA bug: FinishAccess called without PrepareAccess for pixmap 0x%p.\n", pPixmap),); pExaScr->access[i].pixmap = NULL; /* We always hide the devPrivate.ptr. */ pPixmap->devPrivate.ptr = NULL; /* Only call FinishAccess if PrepareAccess was called and succeeded. */ if (!pExaScr->info->FinishAccess || !pExaScr->access[i].retval) return; if (i >= EXA_PREPARE_AUX_DEST && !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) { ErrorF("EXA bug: Trying to call driver FinishAccess hook with " "unsupported index EXA_PREPARE_AUX*\n"); return; } (*pExaScr->info->FinishAccess) (pPixmap, i); } /** * Helper for things common to all schemes when a pixmap is destroyed */ void exaDestroyPixmap(PixmapPtr pPixmap) { ExaScreenPriv(pPixmap->drawable.pScreen); int i; /* Finish access if it was prepared (e.g. pixmap created during * software fallback) */ for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) { if (pExaScr->access[i].pixmap == pPixmap) { exaFinishAccess(&pPixmap->drawable, i); pExaScr->access[i].pixmap = NULL; break; } } } /** * Here begins EXA's GC code. * Do not ever access the fb/mi layer directly. */ static void exaValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable); static void exaDestroyGC(GCPtr pGC); static void exaChangeGC(GCPtr pGC, unsigned long mask); static void exaCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); static void exaChangeClip(GCPtr pGC, int type, void *pvalue, int nrects); static void exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc); static void exaDestroyClip(GCPtr pGC); const GCFuncs exaGCFuncs = { exaValidateGC, exaChangeGC, exaCopyGC, exaDestroyGC, exaChangeClip, exaDestroyClip, exaCopyClip }; static void exaValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) { /* fbValidateGC will do direct access to pixmaps if the tiling has changed. * Do a few smart things so fbValidateGC can do it's work. */ ScreenPtr pScreen = pDrawable->pScreen; ExaScreenPriv(pScreen); ExaGCPriv(pGC); PixmapPtr pTile = NULL; /* Either of these conditions is enough to trigger access to a tile pixmap. * With pGC->tileIsPixel == 1, you run the risk of dereferencing an invalid * tile pixmap pointer. */ if (pGC->fillStyle == FillTiled || ((changes & GCTile) && !pGC->tileIsPixel)) { pTile = pGC->tile.pixmap; } if (pGC->stipple) exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); if (pTile) exaPrepareAccess(&pTile->drawable, EXA_PREPARE_SRC); /* Calls to Create/DestroyPixmap have to be identified as special. */ pExaScr->fallback_counter++; swap(pExaGC, pGC, funcs); (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable); swap(pExaGC, pGC, funcs); pExaScr->fallback_counter--; if (pTile) exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC); if (pGC->stipple) exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); } /* Is exaPrepareAccessGC() needed? */ static void exaDestroyGC(GCPtr pGC) { ExaGCPriv(pGC); swap(pExaGC, pGC, funcs); (*pGC->funcs->DestroyGC) (pGC); swap(pExaGC, pGC, funcs); } static void exaChangeGC(GCPtr pGC, unsigned long mask) { ExaGCPriv(pGC); swap(pExaGC, pGC, funcs); (*pGC->funcs->ChangeGC) (pGC, mask); swap(pExaGC, pGC, funcs); } static void exaCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) { ExaGCPriv(pGCDst); swap(pExaGC, pGCDst, funcs); (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); swap(pExaGC, pGCDst, funcs); } static void exaChangeClip(GCPtr pGC, int type, void *pvalue, int nrects) { ExaGCPriv(pGC); swap(pExaGC, pGC, funcs); (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); swap(pExaGC, pGC, funcs); } static void exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc) { ExaGCPriv(pGCDst); swap(pExaGC, pGCDst, funcs); (*pGCDst->funcs->CopyClip) (pGCDst, pGCSrc); swap(pExaGC, pGCDst, funcs); } static void exaDestroyClip(GCPtr pGC) { ExaGCPriv(pGC); swap(pExaGC, pGC, funcs); (*pGC->funcs->DestroyClip) (pGC); swap(pExaGC, pGC, funcs); } /** * exaCreateGC makes a new GC and hooks up its funcs handler, so that * exaValidateGC() will get called. */ static int exaCreateGC(GCPtr pGC) { ScreenPtr pScreen = pGC->pScreen; ExaScreenPriv(pScreen); ExaGCPriv(pGC); Bool ret; swap(pExaScr, pScreen, CreateGC); if ((ret = (*pScreen->CreateGC) (pGC))) { wrap(pExaGC, pGC, funcs, &exaGCFuncs); wrap(pExaGC, pGC, ops, &exaOps); } swap(pExaScr, pScreen, CreateGC); return ret; } static Bool exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask) { Bool ret; ScreenPtr pScreen = pWin->drawable.pScreen; ExaScreenPriv(pScreen); if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC); if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE) exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK); pExaScr->fallback_counter++; swap(pExaScr, pScreen, ChangeWindowAttributes); ret = pScreen->ChangeWindowAttributes(pWin, mask); swap(pExaScr, pScreen, ChangeWindowAttributes); pExaScr->fallback_counter--; if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC); if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE) exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK); return ret; } static RegionPtr exaBitmapToRegion(PixmapPtr pPix) { RegionPtr ret; ScreenPtr pScreen = pPix->drawable.pScreen; ExaScreenPriv(pScreen); exaPrepareAccess(&pPix->drawable, EXA_PREPARE_SRC); swap(pExaScr, pScreen, BitmapToRegion); ret = (*pScreen->BitmapToRegion) (pPix); swap(pExaScr, pScreen, BitmapToRegion); exaFinishAccess(&pPix->drawable, EXA_PREPARE_SRC); return ret; } static Bool exaCreateScreenResources(ScreenPtr pScreen) { ExaScreenPriv(pScreen); PixmapPtr pScreenPixmap; Bool b; swap(pExaScr, pScreen, CreateScreenResources); b = pScreen->CreateScreenResources(pScreen); swap(pExaScr, pScreen, CreateScreenResources); if (!b) return FALSE; pScreenPixmap = pScreen->GetScreenPixmap(pScreen); if (pScreenPixmap) { ExaPixmapPriv(pScreenPixmap); exaSetAccelBlock(pExaScr, pExaPixmap, pScreenPixmap->drawable.width, pScreenPixmap->drawable.height, pScreenPixmap->drawable.bitsPerPixel); } return TRUE; } static void ExaBlockHandler(ScreenPtr pScreen, void *pTimeout) { ExaScreenPriv(pScreen); /* Move any deferred results from a software fallback to the driver pixmap */ if (pExaScr->deferred_mixed_pixmap) exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap); unwrap(pExaScr, pScreen, BlockHandler); (*pScreen->BlockHandler) (pScreen, pTimeout); wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler); /* The rest only applies to classic EXA */ if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS) return; /* Try and keep the offscreen memory area tidy every now and then (at most * once per second) when the server has been idle for at least 100ms. */ if (pExaScr->numOffscreenAvailable > 1) { CARD32 now = GetTimeInMillis(); pExaScr->nextDefragment = now + max(100, (INT32) (pExaScr->lastDefragment + 1000 - now)); AdjustWaitForDelay(pTimeout, pExaScr->nextDefragment - now); } } static void ExaWakeupHandler(ScreenPtr pScreen, int result) { ExaScreenPriv(pScreen); unwrap(pExaScr, pScreen, WakeupHandler); (*pScreen->WakeupHandler) (pScreen, result); wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler); if (result == 0 && pExaScr->numOffscreenAvailable > 1) { CARD32 now = GetTimeInMillis(); if ((int) (now - pExaScr->nextDefragment) > 0) { ExaOffscreenDefragment(pScreen); pExaScr->lastDefragment = now; } } } /** * exaCloseScreen() unwraps its wrapped screen functions and tears down EXA's * screen private, before calling down to the next CloseSccreen. */ static Bool exaCloseScreen(ScreenPtr pScreen) { ExaScreenPriv(pScreen); PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); if (ps->Glyphs == exaGlyphs) exaGlyphsFini(pScreen); if (pScreen->BlockHandler == ExaBlockHandler) unwrap(pExaScr, pScreen, BlockHandler); if (pScreen->WakeupHandler == ExaWakeupHandler) unwrap(pExaScr, pScreen, WakeupHandler); unwrap(pExaScr, pScreen, CreateGC); unwrap(pExaScr, pScreen, CloseScreen); unwrap(pExaScr, pScreen, GetImage); unwrap(pExaScr, pScreen, GetSpans); if (pExaScr->SavedCreatePixmap) unwrap(pExaScr, pScreen, CreatePixmap); if (pExaScr->SavedDestroyPixmap) unwrap(pExaScr, pScreen, DestroyPixmap); if (pExaScr->SavedModifyPixmapHeader) unwrap(pExaScr, pScreen, ModifyPixmapHeader); unwrap(pExaScr, pScreen, CopyWindow); unwrap(pExaScr, pScreen, ChangeWindowAttributes); unwrap(pExaScr, pScreen, BitmapToRegion); unwrap(pExaScr, pScreen, CreateScreenResources); if (pExaScr->SavedSharePixmapBacking) unwrap(pExaScr, pScreen, SharePixmapBacking); if (pExaScr->SavedSetSharedPixmapBacking) unwrap(pExaScr, pScreen, SetSharedPixmapBacking); unwrap(pExaScr, ps, Composite); if (pExaScr->SavedGlyphs) unwrap(pExaScr, ps, Glyphs); unwrap(pExaScr, ps, Trapezoids); unwrap(pExaScr, ps, Triangles); unwrap(pExaScr, ps, AddTraps); free(pExaScr); return (*pScreen->CloseScreen) (pScreen); } /** * This function allocates a driver structure for EXA drivers to fill in. By * having EXA allocate the structure, the driver structure can be extended * without breaking ABI between EXA and the drivers. The driver's * responsibility is to check beforehand that the EXA module has a matching * major number and sufficient minor. Drivers are responsible for freeing the * driver structure using free(). * * @return a newly allocated, zero-filled driver structure */ ExaDriverPtr exaDriverAlloc(void) { return calloc(1, sizeof(ExaDriverRec)); } /** * @param pScreen screen being initialized * @param pScreenInfo EXA driver record * * exaDriverInit sets up EXA given a driver record filled in by the driver. * pScreenInfo should have been allocated by exaDriverAlloc(). See the * comments in _ExaDriver for what must be filled in and what is optional. * * @return TRUE if EXA was successfully initialized. */ Bool exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo) { ExaScreenPrivPtr pExaScr; PictureScreenPtr ps; if (!pScreenInfo) return FALSE; if (pScreenInfo->exa_major != EXA_VERSION_MAJOR || pScreenInfo->exa_minor > EXA_VERSION_MINOR) { LogMessage(X_ERROR, "EXA(%d): driver's EXA version requirements " "(%d.%d) are incompatible with EXA version (%d.%d)\n", pScreen->myNum, pScreenInfo->exa_major, pScreenInfo->exa_minor, EXA_VERSION_MAJOR, EXA_VERSION_MINOR); return FALSE; } if (!pScreenInfo->CreatePixmap && !pScreenInfo->CreatePixmap2) { if (!pScreenInfo->memoryBase) { LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase " "must be non-zero\n", pScreen->myNum); return FALSE; } if (!pScreenInfo->memorySize) { LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memorySize must be " "non-zero\n", pScreen->myNum); return FALSE; } if (pScreenInfo->offScreenBase > pScreenInfo->memorySize) { LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must " "be <= ExaDriverRec::memorySize\n", pScreen->myNum); return FALSE; } } if (!pScreenInfo->PrepareSolid) { LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareSolid must be " "non-NULL\n", pScreen->myNum); return FALSE; } if (!pScreenInfo->PrepareCopy) { LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareCopy must be " "non-NULL\n", pScreen->myNum); return FALSE; } if (!pScreenInfo->WaitMarker) { LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::WaitMarker must be " "non-NULL\n", pScreen->myNum); return FALSE; } /* If the driver doesn't set any max pitch values, we'll just assume * that there's a limitation by pixels, and that it's the same as * maxX. * * We want maxPitchPixels or maxPitchBytes to be set so we can check * pixmaps against the max pitch in exaCreatePixmap() -- it matters * whether a pixmap is rejected because of its pitch or * because of its width. */ if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes) { pScreenInfo->maxPitchPixels = pScreenInfo->maxX; } ps = GetPictureScreenIfSet(pScreen); if (!dixRegisterPrivateKey(&exaScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) { LogMessage(X_WARNING, "EXA(%d): Failed to register screen private\n", pScreen->myNum); return FALSE; } pExaScr = calloc(sizeof(ExaScreenPrivRec), 1); if (!pExaScr) { LogMessage(X_WARNING, "EXA(%d): Failed to allocate screen private\n", pScreen->myNum); return FALSE; } pExaScr->info = pScreenInfo; dixSetPrivate(&pScreen->devPrivates, exaScreenPrivateKey, pExaScr); pExaScr->migration = ExaMigrationAlways; exaDDXDriverInit(pScreen); if (!dixRegisterScreenSpecificPrivateKey (pScreen, &pExaScr->gcPrivateKeyRec, PRIVATE_GC, sizeof(ExaGCPrivRec))) { LogMessage(X_WARNING, "EXA(%d): Failed to allocate GC private\n", pScreen->myNum); return FALSE; } /* * Replace various fb screen functions */ if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) && (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) || (pExaScr->info->flags & EXA_MIXED_PIXMAPS))) wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler); if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler); wrap(pExaScr, pScreen, CreateGC, exaCreateGC); wrap(pExaScr, pScreen, CloseScreen, exaCloseScreen); wrap(pExaScr, pScreen, GetImage, exaGetImage); wrap(pExaScr, pScreen, GetSpans, ExaCheckGetSpans); wrap(pExaScr, pScreen, CopyWindow, exaCopyWindow); wrap(pExaScr, pScreen, ChangeWindowAttributes, exaChangeWindowAttributes); wrap(pExaScr, pScreen, BitmapToRegion, exaBitmapToRegion); wrap(pExaScr, pScreen, CreateScreenResources, exaCreateScreenResources); if (ps) { wrap(pExaScr, ps, Composite, exaComposite); if (pScreenInfo->PrepareComposite) { wrap(pExaScr, ps, Glyphs, exaGlyphs); } else { wrap(pExaScr, ps, Glyphs, ExaCheckGlyphs); } wrap(pExaScr, ps, Trapezoids, exaTrapezoids); wrap(pExaScr, ps, Triangles, exaTriangles); wrap(pExaScr, ps, AddTraps, ExaCheckAddTraps); } #ifdef MITSHM /* * Don't allow shared pixmaps. */ ShmRegisterFuncs(pScreen, &exaShmFuncs); #endif /* * Hookup offscreen pixmaps */ if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) { if (!dixRegisterScreenSpecificPrivateKey (pScreen, &pExaScr->pixmapPrivateKeyRec, PRIVATE_PIXMAP, sizeof(ExaPixmapPrivRec))) { LogMessage(X_WARNING, "EXA(%d): Failed to allocate pixmap private\n", pScreen->myNum); return FALSE; } if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS) { if (pExaScr->info->flags & EXA_MIXED_PIXMAPS) { wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_mixed); wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_mixed); wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_mixed); wrap(pExaScr, pScreen, SharePixmapBacking, exaSharePixmapBacking_mixed); wrap(pExaScr, pScreen, SetSharedPixmapBacking, exaSetSharedPixmapBacking_mixed); pExaScr->do_migration = exaDoMigration_mixed; pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_mixed; pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed; pExaScr->do_move_out_pixmap = NULL; pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed; } else { wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver); wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver); wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_driver); pExaScr->do_migration = NULL; pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_driver; pExaScr->do_move_in_pixmap = NULL; pExaScr->do_move_out_pixmap = NULL; pExaScr->prepare_access_reg = NULL; } } else { wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic); wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_classic); wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_classic); pExaScr->do_migration = exaDoMigration_classic; pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_classic; pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic; pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic; pExaScr->prepare_access_reg = exaPrepareAccessReg_classic; } if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) { LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n", pScreen->myNum, pExaScr->info->memorySize - pExaScr->info->offScreenBase); } else { LogMessage(X_INFO, "EXA(%d): Driver allocated offscreen pixmaps\n", pScreen->myNum); } } else LogMessage(X_INFO, "EXA(%d): No offscreen pixmaps\n", pScreen->myNum); if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) { DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase, pExaScr->info->memorySize)); if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) { if (!exaOffscreenInit(pScreen)) { LogMessage(X_WARNING, "EXA(%d): Offscreen pixmap setup failed\n", pScreen->myNum); return FALSE; } } } if (ps->Glyphs == exaGlyphs) exaGlyphsInit(pScreen); LogMessage(X_INFO, "EXA(%d): Driver registered support for the following" " operations:\n", pScreen->myNum); assert(pScreenInfo->PrepareSolid != NULL); LogMessage(X_INFO, " Solid\n"); assert(pScreenInfo->PrepareCopy != NULL); LogMessage(X_INFO, " Copy\n"); if (pScreenInfo->PrepareComposite != NULL) { LogMessage(X_INFO, " Composite (RENDER acceleration)\n"); } if (pScreenInfo->UploadToScreen != NULL) { LogMessage(X_INFO, " UploadToScreen\n"); } if (pScreenInfo->DownloadFromScreen != NULL) { LogMessage(X_INFO, " DownloadFromScreen\n"); } return TRUE; } /** * exaDriverFini tears down EXA on a given screen. * * @param pScreen screen being torn down. */ void exaDriverFini(ScreenPtr pScreen) { /*right now does nothing */ } /** * exaMarkSync() should be called after any asynchronous drawing by the hardware. * * @param pScreen screen which drawing occurred on * * exaMarkSync() sets a flag to indicate that some asynchronous drawing has * happened and a WaitSync() will be necessary before relying on the contents of * offscreen memory from the CPU's perspective. It also calls an optional * driver MarkSync() callback, the return value of which may be used to do partial * synchronization with the hardware in the future. */ void exaMarkSync(ScreenPtr pScreen) { ExaScreenPriv(pScreen); pExaScr->info->needsSync = TRUE; if (pExaScr->info->MarkSync != NULL) { pExaScr->info->lastMarker = (*pExaScr->info->MarkSync) (pScreen); } } /** * exaWaitSync() ensures that all drawing has been completed. * * @param pScreen screen being synchronized. * * Calls down into the driver to ensure that all previous drawing has completed. * It should always be called before relying on the framebuffer contents * reflecting previous drawing, from a CPU perspective. */ void exaWaitSync(ScreenPtr pScreen) { ExaScreenPriv(pScreen); if (pExaScr->info->needsSync && !pExaScr->swappedOut) { (*pExaScr->info->WaitMarker) (pScreen, pExaScr->info->lastMarker); pExaScr->info->needsSync = FALSE; } } /** * Performs migration of the pixmaps according to the operation information * provided in pixmaps and can_accel and the migration scheme chosen in the * config file. */ void exaDoMigration(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) { ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen; ExaScreenPriv(pScreen); if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) return; if (pExaScr->do_migration) (*pExaScr->do_migration) (pixmaps, npixmaps, can_accel); } void exaMoveInPixmap(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) return; if (pExaScr->do_move_in_pixmap) (*pExaScr->do_move_in_pixmap) (pPixmap); } void exaMoveOutPixmap(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) return; if (pExaScr->do_move_out_pixmap) (*pExaScr->do_move_out_pixmap) (pPixmap); } xorg-server-1.20.13/exa/exa_classic.c0000644000175000017500000002005714100573756014275 00000000000000/* * Copyright © 2009 Maarten Maathuis * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "exa_priv.h" #include "exa.h" /* This file holds the classic exa specific implementation. */ static _X_INLINE void * ExaGetPixmapAddress(PixmapPtr p) { ExaPixmapPriv(p); if (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr) return pExaPixmap->fb_ptr; else return pExaPixmap->sys_ptr; } /** * exaCreatePixmap() creates a new pixmap. * * If width and height are 0, this won't be a full-fledged pixmap and it will * get ModifyPixmapHeader() called on it later. So, we mark it as pinned, because * ModifyPixmapHeader() would break migration. These types of pixmaps are used * for scratch pixmaps, or to represent the visible screen. */ PixmapPtr exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint) { PixmapPtr pPixmap; ExaPixmapPrivPtr pExaPixmap; BoxRec box; int bpp; ExaScreenPriv(pScreen); if (w > 32767 || h > 32767) return NullPixmap; swap(pExaScr, pScreen, CreatePixmap); pPixmap = pScreen->CreatePixmap(pScreen, w, h, depth, usage_hint); swap(pExaScr, pScreen, CreatePixmap); if (!pPixmap) return NULL; pExaPixmap = ExaGetPixmapPriv(pPixmap); pExaPixmap->driverPriv = NULL; bpp = pPixmap->drawable.bitsPerPixel; pExaPixmap->driverPriv = NULL; /* Scratch pixmaps may have w/h equal to zero, and may not be * migrated. */ if (!w || !h) pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; else pExaPixmap->score = EXA_PIXMAP_SCORE_INIT; pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; pExaPixmap->sys_pitch = pPixmap->devKind; pPixmap->devPrivate.ptr = NULL; pExaPixmap->use_gpu_copy = FALSE; pExaPixmap->fb_ptr = NULL; exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); pExaPixmap->fb_size = pExaPixmap->fb_pitch * h; if (pExaPixmap->fb_pitch > 131071) { swap(pExaScr, pScreen, DestroyPixmap); pScreen->DestroyPixmap(pPixmap); swap(pExaScr, pScreen, DestroyPixmap); return NULL; } /* Set up damage tracking */ pExaPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, pScreen, pPixmap); if (pExaPixmap->pDamage == NULL) { swap(pExaScr, pScreen, DestroyPixmap); pScreen->DestroyPixmap(pPixmap); swap(pExaScr, pScreen, DestroyPixmap); return NULL; } DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage); /* This ensures that pending damage reflects the current operation. */ /* This is used by exa to optimize migration. */ DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE); pExaPixmap->area = NULL; /* We set the initial pixmap as completely valid for a simple reason. * Imagine a 1000x1000 pixmap, it has 1 million pixels, 250000 of which * could form single pixel rects as part of a region. Setting the complete region * as valid is a natural defragmentation of the region. */ box.x1 = 0; box.y1 = 0; box.x2 = w; box.y2 = h; RegionInit(&pExaPixmap->validSys, &box, 0); RegionInit(&pExaPixmap->validFB, &box, 0); exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp); /* During a fallback we must prepare access. */ if (pExaScr->fallback_counter) exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); return pPixmap; } Bool exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, void *pPixData) { ScreenPtr pScreen; ExaScreenPrivPtr pExaScr; ExaPixmapPrivPtr pExaPixmap; Bool ret; if (!pPixmap) return FALSE; pScreen = pPixmap->drawable.pScreen; pExaScr = ExaGetScreenPriv(pScreen); pExaPixmap = ExaGetPixmapPriv(pPixmap); if (pExaPixmap) { if (pPixData) pExaPixmap->sys_ptr = pPixData; if (devKind > 0) pExaPixmap->sys_pitch = devKind; /* Classic EXA: * - Framebuffer. * - Scratch pixmap with gpu memory. */ if (pExaScr->info->memoryBase && pPixData) { if ((CARD8 *) pPixData >= pExaScr->info->memoryBase && ((CARD8 *) pPixData - pExaScr->info->memoryBase) < pExaScr->info->memorySize) { pExaPixmap->fb_ptr = pPixData; pExaPixmap->fb_pitch = devKind; pExaPixmap->use_gpu_copy = TRUE; } } if (width > 0 && height > 0 && bitsPerPixel > 0) { exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel); exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel); } /* Pixmaps subject to ModifyPixmapHeader will be pinned to system or * gpu memory, so there's no need to track damage. */ if (pExaPixmap->pDamage) { DamageDestroy(pExaPixmap->pDamage); pExaPixmap->pDamage = NULL; } } swap(pExaScr, pScreen, ModifyPixmapHeader); ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData); swap(pExaScr, pScreen, ModifyPixmapHeader); /* Always NULL this, we don't want lingering pointers. */ pPixmap->devPrivate.ptr = NULL; return ret; } Bool exaDestroyPixmap_classic(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); Bool ret; if (pPixmap->refcnt == 1) { ExaPixmapPriv(pPixmap); exaDestroyPixmap(pPixmap); if (pExaPixmap->area) { DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n", (void *) pPixmap->drawable.id, ExaGetPixmapPriv(pPixmap)->area->offset, pPixmap->drawable.width, pPixmap->drawable.height)); /* Free the offscreen area */ exaOffscreenFree(pPixmap->drawable.pScreen, pExaPixmap->area); pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; pPixmap->devKind = pExaPixmap->sys_pitch; } RegionUninit(&pExaPixmap->validSys); RegionUninit(&pExaPixmap->validFB); } swap(pExaScr, pScreen, DestroyPixmap); ret = pScreen->DestroyPixmap(pPixmap); swap(pExaScr, pScreen, DestroyPixmap); return ret; } Bool exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); ExaPixmapPriv(pPixmap); Bool ret; if (pExaScr->info->PixmapIsOffscreen) { void *old_ptr = pPixmap->devPrivate.ptr; pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap); ret = pExaScr->info->PixmapIsOffscreen(pPixmap); pPixmap->devPrivate.ptr = old_ptr; } else ret = (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr); return ret; } xorg-server-1.20.13/exa/exa_migration_classic.c0000644000175000017500000005751614100573756016360 00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * Michel Dänzer * */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "exa_priv.h" #include "exa.h" #if DEBUG_MIGRATE #define DBG_MIGRATE(a) ErrorF a #else #define DBG_MIGRATE(a) #endif /** * The fallback path for UTS/DFS failing is to just memcpy. exaCopyDirtyToSys * and exaCopyDirtyToFb both needed to do this loop. */ static void exaMemcpyBox(PixmapPtr pPixmap, BoxPtr pbox, CARD8 *src, int src_pitch, CARD8 *dst, int dst_pitch) { int i, cpp = pPixmap->drawable.bitsPerPixel / 8; int bytes = (pbox->x2 - pbox->x1) * cpp; src += pbox->y1 * src_pitch + pbox->x1 * cpp; dst += pbox->y1 * dst_pitch + pbox->x1 * cpp; for (i = pbox->y2 - pbox->y1; i; i--) { memcpy(dst, src, bytes); src += src_pitch; dst += dst_pitch; } } /** * Returns TRUE if the pixmap is dirty (has been modified in its current * location compared to the other), or lacks a private for tracking * dirtiness. */ static Bool exaPixmapIsDirty(PixmapPtr pPix) { ExaPixmapPriv(pPix); if (pExaPixmap == NULL) EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsDirty was called on a non-exa pixmap.\n"), TRUE); if (!pExaPixmap->pDamage) return FALSE; return RegionNotEmpty(DamageRegion(pExaPixmap->pDamage)) || !RegionEqual(&pExaPixmap->validSys, &pExaPixmap->validFB); } /** * Returns TRUE if the pixmap is either pinned in FB, or has a sufficient score * to be considered "should be in framebuffer". That's just anything that has * had more acceleration than fallbacks, or has no score yet. * * Only valid if using a migration scheme that tracks score. */ static Bool exaPixmapShouldBeInFB(PixmapPtr pPix) { ExaPixmapPriv(pPix); if (exaPixmapIsPinned(pPix)) return TRUE; return pExaPixmap->score >= 0; } /** * If the pixmap is currently dirty, this copies at least the dirty area from * FB to system or vice versa. Both areas must be allocated. */ static void exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc, Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h, char *sys, int sys_pitch), int fallback_index, void (*sync) (ScreenPtr pScreen)) { PixmapPtr pPixmap = migrate->pPix; ExaPixmapPriv(pPixmap); RegionPtr damage = DamageRegion(pExaPixmap->pDamage); RegionRec CopyReg; Bool save_use_gpu_copy; int save_pitch; BoxPtr pBox; int nbox; Bool access_prepared = FALSE; Bool need_sync = FALSE; /* Damaged bits are valid in current copy but invalid in other one */ if (pExaPixmap->use_gpu_copy) { RegionUnion(&pExaPixmap->validFB, &pExaPixmap->validFB, damage); RegionSubtract(&pExaPixmap->validSys, &pExaPixmap->validSys, damage); } else { RegionUnion(&pExaPixmap->validSys, &pExaPixmap->validSys, damage); RegionSubtract(&pExaPixmap->validFB, &pExaPixmap->validFB, damage); } RegionEmpty(damage); /* Copy bits valid in source but not in destination */ RegionNull(&CopyReg); RegionSubtract(&CopyReg, pValidSrc, pValidDst); if (migrate->as_dst) { ExaScreenPriv(pPixmap->drawable.pScreen); /* XXX: The pending damage region will be marked as damaged after the * operation, so it should serve as an upper bound for the region that * needs to be synchronized for the operation. Unfortunately, this * causes corruption in some cases, e.g. when starting compiz. See * https://bugs.freedesktop.org/show_bug.cgi?id=12916 . */ if (pExaScr->optimize_migration) { RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); #if DEBUG_MIGRATE if (RegionNil(pending_damage)) { static Bool firsttime = TRUE; if (firsttime) { ErrorF("%s: Pending damage region empty!\n", __func__); firsttime = FALSE; } } #endif /* Try to prevent destination valid region from growing too many * rects by filling it up to the extents of the union of the * destination valid region and the pending damage region. */ if (RegionNumRects(pValidDst) > 10) { BoxRec box; BoxPtr pValidExt, pDamageExt; RegionRec closure; pValidExt = RegionExtents(pValidDst); pDamageExt = RegionExtents(pending_damage); box.x1 = min(pValidExt->x1, pDamageExt->x1); box.y1 = min(pValidExt->y1, pDamageExt->y1); box.x2 = max(pValidExt->x2, pDamageExt->x2); box.y2 = max(pValidExt->y2, pDamageExt->y2); RegionInit(&closure, &box, 0); RegionIntersect(&CopyReg, &CopyReg, &closure); } else RegionIntersect(&CopyReg, &CopyReg, pending_damage); } /* The caller may provide a region to be subtracted from the calculated * dirty region. This is to avoid migration of bits that don't * contribute to the result of the operation. */ if (migrate->pReg) RegionSubtract(&CopyReg, &CopyReg, migrate->pReg); } else { /* The caller may restrict the region to be migrated for source pixmaps * to what's relevant for the operation. */ if (migrate->pReg) RegionIntersect(&CopyReg, &CopyReg, migrate->pReg); } pBox = RegionRects(&CopyReg); nbox = RegionNumRects(&CopyReg); save_use_gpu_copy = pExaPixmap->use_gpu_copy; save_pitch = pPixmap->devKind; pExaPixmap->use_gpu_copy = TRUE; pPixmap->devKind = pExaPixmap->fb_pitch; while (nbox--) { pBox->x1 = max(pBox->x1, 0); pBox->y1 = max(pBox->y1, 0); pBox->x2 = min(pBox->x2, pPixmap->drawable.width); pBox->y2 = min(pBox->y2, pPixmap->drawable.height); if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2) continue; if (!transfer || !transfer(pPixmap, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1, (char *) (pExaPixmap->sys_ptr + pBox->y1 * pExaPixmap->sys_pitch + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8), pExaPixmap->sys_pitch)) { if (!access_prepared) { ExaDoPrepareAccess(pPixmap, fallback_index); access_prepared = TRUE; } if (fallback_index == EXA_PREPARE_DEST) { exaMemcpyBox(pPixmap, pBox, pExaPixmap->sys_ptr, pExaPixmap->sys_pitch, pPixmap->devPrivate.ptr, pPixmap->devKind); } else { exaMemcpyBox(pPixmap, pBox, pPixmap->devPrivate.ptr, pPixmap->devKind, pExaPixmap->sys_ptr, pExaPixmap->sys_pitch); } } else need_sync = TRUE; pBox++; } pExaPixmap->use_gpu_copy = save_use_gpu_copy; pPixmap->devKind = save_pitch; /* Try to prevent source valid region from growing too many rects by * removing parts of it which are also in the destination valid region. * Removing anything beyond that would lead to data loss. */ if (RegionNumRects(pValidSrc) > 20) RegionSubtract(pValidSrc, pValidSrc, pValidDst); /* The copied bits are now valid in destination */ RegionUnion(pValidDst, pValidDst, &CopyReg); RegionUninit(&CopyReg); if (access_prepared) exaFinishAccess(&pPixmap->drawable, fallback_index); else if (need_sync && sync) sync(pPixmap->drawable.pScreen); } /** * If the pixmap is currently dirty, this copies at least the dirty area from * the framebuffer memory copy to the system memory copy. Both areas must be * allocated. */ void exaCopyDirtyToSys(ExaMigrationPtr migrate) { PixmapPtr pPixmap = migrate->pPix; ExaScreenPriv(pPixmap->drawable.pScreen); ExaPixmapPriv(pPixmap); exaCopyDirty(migrate, &pExaPixmap->validSys, &pExaPixmap->validFB, pExaScr->info->DownloadFromScreen, EXA_PREPARE_SRC, exaWaitSync); } /** * If the pixmap is currently dirty, this copies at least the dirty area from * the system memory copy to the framebuffer memory copy. Both areas must be * allocated. */ void exaCopyDirtyToFb(ExaMigrationPtr migrate) { PixmapPtr pPixmap = migrate->pPix; ExaScreenPriv(pPixmap->drawable.pScreen); ExaPixmapPriv(pPixmap); exaCopyDirty(migrate, &pExaPixmap->validFB, &pExaPixmap->validSys, pExaScr->info->UploadToScreen, EXA_PREPARE_DEST, NULL); } /** * Allocates a framebuffer copy of the pixmap if necessary, and then copies * any necessary pixmap data into the framebuffer copy and points the pixmap at * it. * * Note that when first allocated, a pixmap will have FALSE dirty flag. * This is intentional because pixmap data starts out undefined. So if we move * it in due to the first operation against it being accelerated, it will have * undefined framebuffer contents that we didn't have to upload. If we do * moveouts (and moveins) after the first movein, then we will only have to copy * back and forth if the pixmap was written to after the last synchronization of * the two copies. Then, at exaPixmapSave (when the framebuffer copy goes away) * we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move * all the data, since it's almost surely all valid now. */ static void exaDoMoveInPixmap(ExaMigrationPtr migrate) { PixmapPtr pPixmap = migrate->pPix; ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); ExaPixmapPriv(pPixmap); /* If we're VT-switched away, no touching card memory allowed. */ if (pExaScr->swappedOut) return; /* If we're not allowed to move, then fail. */ if (exaPixmapIsPinned(pPixmap)) return; /* Don't migrate in pixmaps which are less than 8bpp. This avoids a lot of * fragility in EXA, and <8bpp is probably not used enough any more to care * (at least, not in acceleratd paths). */ if (pPixmap->drawable.bitsPerPixel < 8) return; if (pExaPixmap->accel_blocked) return; if (pExaPixmap->area == NULL) { pExaPixmap->area = exaOffscreenAlloc(pScreen, pExaPixmap->fb_size, pExaScr->info->pixmapOffsetAlign, FALSE, exaPixmapSave, (void *) pPixmap); if (pExaPixmap->area == NULL) return; pExaPixmap->fb_ptr = (CARD8 *) pExaScr->info->memoryBase + pExaPixmap->area->offset; } exaCopyDirtyToFb(migrate); if (exaPixmapHasGpuCopy(pPixmap)) return; DBG_MIGRATE(("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap, (ExaGetPixmapPriv(pPixmap)->area ? ExaGetPixmapPriv(pPixmap)->area->offset : 0), pPixmap->drawable.width, pPixmap->drawable.height, exaPixmapIsDirty(pPixmap) ? 'd' : 'c')); pExaPixmap->use_gpu_copy = TRUE; pPixmap->devKind = pExaPixmap->fb_pitch; pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; } void exaMoveInPixmap_classic(PixmapPtr pPixmap) { static ExaMigrationRec migrate = {.as_dst = FALSE,.as_src = TRUE, .pReg = NULL }; migrate.pPix = pPixmap; exaDoMoveInPixmap(&migrate); } /** * Switches the current active location of the pixmap to system memory, copying * updated data out if necessary. */ static void exaDoMoveOutPixmap(ExaMigrationPtr migrate) { PixmapPtr pPixmap = migrate->pPix; ExaPixmapPriv(pPixmap); if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap)) return; exaCopyDirtyToSys(migrate); if (exaPixmapHasGpuCopy(pPixmap)) { DBG_MIGRATE(("<- %p (%p) (%dx%d) (%c)\n", pPixmap, (void *) (ExaGetPixmapPriv(pPixmap)->area ? ExaGetPixmapPriv(pPixmap)->area->offset : 0), pPixmap->drawable.width, pPixmap->drawable.height, exaPixmapIsDirty(pPixmap) ? 'd' : 'c')); pExaPixmap->use_gpu_copy = FALSE; pPixmap->devKind = pExaPixmap->sys_pitch; pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; } } void exaMoveOutPixmap_classic(PixmapPtr pPixmap) { static ExaMigrationRec migrate = {.as_dst = FALSE,.as_src = TRUE, .pReg = NULL }; migrate.pPix = pPixmap; exaDoMoveOutPixmap(&migrate); } /** * Copies out important pixmap data and removes references to framebuffer area. * Called when the memory manager decides it's time to kick the pixmap out of * framebuffer entirely. */ void exaPixmapSave(ScreenPtr pScreen, ExaOffscreenArea * area) { PixmapPtr pPixmap = area->privData; ExaPixmapPriv(pPixmap); exaMoveOutPixmap(pPixmap); pExaPixmap->fb_ptr = NULL; pExaPixmap->area = NULL; /* Mark all FB bits as invalid, so all valid system bits get copied to FB * next time */ RegionEmpty(&pExaPixmap->validFB); } /** * For the "greedy" migration scheme, pushes the pixmap toward being located in * framebuffer memory. */ static void exaMigrateTowardFb(ExaMigrationPtr migrate) { PixmapPtr pPixmap = migrate->pPix; ExaPixmapPriv(pPixmap); if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) { DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n", (void *) pPixmap)); return; } DBG_MIGRATE(("UseScreen %p score %d\n", (void *) pPixmap, pExaPixmap->score)); if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) { exaDoMoveInPixmap(migrate); pExaPixmap->score = 0; } if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX) pExaPixmap->score++; if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN && !exaPixmapHasGpuCopy(pPixmap)) { exaDoMoveInPixmap(migrate); } if (exaPixmapHasGpuCopy(pPixmap)) { exaCopyDirtyToFb(migrate); ExaOffscreenMarkUsed(pPixmap); } else exaCopyDirtyToSys(migrate); } /** * For the "greedy" migration scheme, pushes the pixmap toward being located in * system memory. */ static void exaMigrateTowardSys(ExaMigrationPtr migrate) { PixmapPtr pPixmap = migrate->pPix; ExaPixmapPriv(pPixmap); DBG_MIGRATE(("UseMem: %p score %d\n", (void *) pPixmap, pExaPixmap->score)); if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) return; if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) pExaPixmap->score = 0; if (pExaPixmap->score > EXA_PIXMAP_SCORE_MIN) pExaPixmap->score--; if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area) exaDoMoveOutPixmap(migrate); if (exaPixmapHasGpuCopy(pPixmap)) { exaCopyDirtyToFb(migrate); ExaOffscreenMarkUsed(pPixmap); } else exaCopyDirtyToSys(migrate); } /** * If the pixmap has both a framebuffer and system memory copy, this function * asserts that both of them are the same. */ static Bool exaAssertNotDirty(PixmapPtr pPixmap) { ExaPixmapPriv(pPixmap); CARD8 *dst, *src; RegionRec ValidReg; int dst_pitch, src_pitch, cpp, y, nbox, save_pitch; BoxPtr pBox; Bool ret = TRUE, save_use_gpu_copy; if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL) return ret; RegionNull(&ValidReg); RegionIntersect(&ValidReg, &pExaPixmap->validFB, &pExaPixmap->validSys); nbox = RegionNumRects(&ValidReg); if (!nbox) goto out; pBox = RegionRects(&ValidReg); dst_pitch = pExaPixmap->sys_pitch; src_pitch = pExaPixmap->fb_pitch; cpp = pPixmap->drawable.bitsPerPixel / 8; save_use_gpu_copy = pExaPixmap->use_gpu_copy; save_pitch = pPixmap->devKind; pExaPixmap->use_gpu_copy = TRUE; pPixmap->devKind = pExaPixmap->fb_pitch; if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC)) goto skip; while (nbox--) { int rowbytes; pBox->x1 = max(pBox->x1, 0); pBox->y1 = max(pBox->y1, 0); pBox->x2 = min(pBox->x2, pPixmap->drawable.width); pBox->y2 = min(pBox->y2, pPixmap->drawable.height); if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2) continue; rowbytes = (pBox->x2 - pBox->x1) * cpp; src = (CARD8 *) pPixmap->devPrivate.ptr + pBox->y1 * src_pitch + pBox->x1 * cpp; dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp; for (y = pBox->y1; y < pBox->y2; y++, src += src_pitch, dst += dst_pitch) { if (memcmp(dst, src, rowbytes) != 0) { ret = FALSE; exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2, pBox->y2); break; } } } skip: exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); pExaPixmap->use_gpu_copy = save_use_gpu_copy; pPixmap->devKind = save_pitch; out: RegionUninit(&ValidReg); return ret; } /** * Performs migration of the pixmaps according to the operation information * provided in pixmaps and can_accel and the migration scheme chosen in the * config file. */ void exaDoMigration_classic(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) { ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen; ExaScreenPriv(pScreen); int i, j; /* If this debugging flag is set, check each pixmap for whether it is marked * as clean, and if so, actually check if that's the case. This should help * catch issues with failing to mark a drawable as dirty. While it will * catch them late (after the operation happened), it at least explains what * went wrong, and instrumenting the code to find what operation happened * to the pixmap last shouldn't be hard. */ if (pExaScr->checkDirtyCorrectness) { for (i = 0; i < npixmaps; i++) { if (!exaPixmapIsDirty(pixmaps[i].pPix) && !exaAssertNotDirty(pixmaps[i].pPix)) ErrorF("%s: Pixmap %d dirty but not marked as such!\n", __func__, i); } } /* If anything is pinned in system memory, we won't be able to * accelerate. */ for (i = 0; i < npixmaps; i++) { if (exaPixmapIsPinned(pixmaps[i].pPix) && !exaPixmapHasGpuCopy(pixmaps[i].pPix)) { EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix, pixmaps[i].pPix->drawable.width, pixmaps[i].pPix->drawable.height)); can_accel = FALSE; break; } } if (pExaScr->migration == ExaMigrationSmart) { /* If we've got something as a destination that we shouldn't cause to * become newly dirtied, take the unaccelerated route. */ for (i = 0; i < npixmaps; i++) { if (pixmaps[i].as_dst && !exaPixmapShouldBeInFB(pixmaps[i].pPix) && !exaPixmapIsDirty(pixmaps[i].pPix)) { for (i = 0; i < npixmaps; i++) { if (!exaPixmapIsDirty(pixmaps[i].pPix)) exaDoMoveOutPixmap(pixmaps + i); } return; } } /* If we aren't going to accelerate, then we migrate everybody toward * system memory, and kick out if it's free. */ if (!can_accel) { for (i = 0; i < npixmaps; i++) { exaMigrateTowardSys(pixmaps + i); if (!exaPixmapIsDirty(pixmaps[i].pPix)) exaDoMoveOutPixmap(pixmaps + i); } return; } /* Finally, the acceleration path. Move them all in. */ for (i = 0; i < npixmaps; i++) { exaMigrateTowardFb(pixmaps + i); exaDoMoveInPixmap(pixmaps + i); } } else if (pExaScr->migration == ExaMigrationGreedy) { /* If we can't accelerate, either because the driver can't or because one of * the pixmaps is pinned in system memory, then we migrate everybody toward * system memory. * * We also migrate toward system if all pixmaps involved are currently in * system memory -- this can mitigate thrashing when there are significantly * more pixmaps active than would fit in memory. * * If not, then we migrate toward FB so that hopefully acceleration can * happen. */ if (!can_accel) { for (i = 0; i < npixmaps; i++) exaMigrateTowardSys(pixmaps + i); return; } for (i = 0; i < npixmaps; i++) { if (exaPixmapHasGpuCopy(pixmaps[i].pPix)) { /* Found one in FB, so move all to FB. */ for (j = 0; j < npixmaps; j++) exaMigrateTowardFb(pixmaps + i); return; } } /* Nobody's in FB, so move all away from FB. */ for (i = 0; i < npixmaps; i++) exaMigrateTowardSys(pixmaps + i); } else if (pExaScr->migration == ExaMigrationAlways) { /* Always move the pixmaps out if we can't accelerate. If we can * accelerate, try to move them all in. If that fails, then move them * back out. */ if (!can_accel) { for (i = 0; i < npixmaps; i++) exaDoMoveOutPixmap(pixmaps + i); return; } /* Now, try to move them all into FB */ for (i = 0; i < npixmaps; i++) { exaDoMoveInPixmap(pixmaps + i); } /* If we couldn't fit everything in, abort */ for (i = 0; i < npixmaps; i++) { if (!exaPixmapHasGpuCopy(pixmaps[i].pPix)) { return; } } /* Yay, everything has a gpu copy, mark memory as used */ for (i = 0; i < npixmaps; i++) { ExaOffscreenMarkUsed(pixmaps[i].pPix); } } } void exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg) { ExaMigrationRec pixmaps[1]; if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) { pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; } else { pixmaps[0].as_dst = FALSE; pixmaps[0].as_src = TRUE; } pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = pReg; exaDoMigration(pixmaps, 1, FALSE); (void) ExaDoPrepareAccess(pPixmap, index); } xorg-server-1.20.13/exa/exa_driver.c0000644000175000017500000001540114100573756014144 00000000000000/* * Copyright © 2009 Maarten Maathuis * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "exa_priv.h" #include "exa.h" /* This file holds the driver allocated pixmaps specific implementation. */ static _X_INLINE void * ExaGetPixmapAddress(PixmapPtr p) { ExaPixmapPriv(p); return pExaPixmap->sys_ptr; } /** * exaCreatePixmap() creates a new pixmap. * * Pixmaps are always marked as pinned, because exa has no control over them. */ PixmapPtr exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint) { PixmapPtr pPixmap; ExaPixmapPrivPtr pExaPixmap; int bpp; size_t paddedWidth, datasize; ExaScreenPriv(pScreen); if (w > 32767 || h > 32767) return NullPixmap; swap(pExaScr, pScreen, CreatePixmap); pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint); swap(pExaScr, pScreen, CreatePixmap); if (!pPixmap) return NULL; pExaPixmap = ExaGetPixmapPriv(pPixmap); pExaPixmap->driverPriv = NULL; bpp = pPixmap->drawable.bitsPerPixel; /* Set this before driver hooks, to allow for driver pixmaps without gpu * memory to back it. These pixmaps have a valid pointer at all times. */ pPixmap->devPrivate.ptr = NULL; if (pExaScr->info->CreatePixmap2) { int new_pitch = 0; pExaPixmap->driverPriv = pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp, &new_pitch); paddedWidth = pExaPixmap->fb_pitch = new_pitch; } else { paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits); if (paddedWidth / 4 > 32767 || h > 32767) return NullPixmap; exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); if (paddedWidth < pExaPixmap->fb_pitch) paddedWidth = pExaPixmap->fb_pitch; datasize = h * paddedWidth; pExaPixmap->driverPriv = pExaScr->info->CreatePixmap(pScreen, datasize, 0); } if (!pExaPixmap->driverPriv) { swap(pExaScr, pScreen, DestroyPixmap); pScreen->DestroyPixmap(pPixmap); swap(pExaScr, pScreen, DestroyPixmap); return NULL; } /* Allow ModifyPixmapHeader to set sys_ptr appropriately. */ pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; pExaPixmap->fb_ptr = NULL; pExaPixmap->pDamage = NULL; pExaPixmap->sys_ptr = NULL; (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL); pExaPixmap->area = NULL; exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp); pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap); /* During a fallback we must prepare access. */ if (pExaScr->fallback_counter) exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); return pPixmap; } Bool exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, void *pPixData) { ScreenPtr pScreen; ExaScreenPrivPtr pExaScr; ExaPixmapPrivPtr pExaPixmap; Bool ret; if (!pPixmap) return FALSE; pScreen = pPixmap->drawable.pScreen; pExaScr = ExaGetScreenPriv(pScreen); pExaPixmap = ExaGetPixmapPriv(pPixmap); if (pExaPixmap) { if (pPixData) pExaPixmap->sys_ptr = pPixData; if (devKind > 0) pExaPixmap->sys_pitch = devKind; if (width > 0 && height > 0 && bitsPerPixel > 0) { exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel); exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel); } } if (pExaScr->info->ModifyPixmapHeader) { ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData); /* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL. * If pPixmap->devPrivate.ptr is non-NULL, then we've got a * !has_gpu_copy pixmap. We need to store the pointer, * because PrepareAccess won't be called. */ if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) { pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; pExaPixmap->sys_pitch = pPixmap->devKind; } if (ret == TRUE) goto out; } swap(pExaScr, pScreen, ModifyPixmapHeader); ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData); swap(pExaScr, pScreen, ModifyPixmapHeader); out: /* Always NULL this, we don't want lingering pointers. */ pPixmap->devPrivate.ptr = NULL; return ret; } Bool exaDestroyPixmap_driver(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); Bool ret; if (pPixmap->refcnt == 1) { ExaPixmapPriv(pPixmap); exaDestroyPixmap(pPixmap); if (pExaPixmap->driverPriv) pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv); pExaPixmap->driverPriv = NULL; } swap(pExaScr, pScreen, DestroyPixmap); ret = pScreen->DestroyPixmap(pPixmap); swap(pExaScr, pScreen, DestroyPixmap); return ret; } Bool exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); void *saved_ptr; Bool ret; saved_ptr = pPixmap->devPrivate.ptr; pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap); ret = pExaScr->info->PixmapIsOffscreen(pPixmap); pPixmap->devPrivate.ptr = saved_ptr; return ret; } xorg-server-1.20.13/exa/exa_mixed.c0000644000175000017500000002300314100573756013754 00000000000000/* * Copyright © 2009 Maarten Maathuis * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "exa_priv.h" #include "exa.h" /* This file holds the driver allocated pixmaps + better initial placement code. */ static _X_INLINE void * ExaGetPixmapAddress(PixmapPtr p) { ExaPixmapPriv(p); return pExaPixmap->sys_ptr; } /** * exaCreatePixmap() creates a new pixmap. */ PixmapPtr exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint) { PixmapPtr pPixmap; ExaPixmapPrivPtr pExaPixmap; int bpp; size_t paddedWidth; ExaScreenPriv(pScreen); if (w > 32767 || h > 32767) return NullPixmap; swap(pExaScr, pScreen, CreatePixmap); pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint); swap(pExaScr, pScreen, CreatePixmap); if (!pPixmap) return NULL; pExaPixmap = ExaGetPixmapPriv(pPixmap); pExaPixmap->driverPriv = NULL; bpp = pPixmap->drawable.bitsPerPixel; paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits); if (paddedWidth / 4 > 32767 || h > 32767) return NullPixmap; /* We will allocate the system pixmap later if needed. */ pPixmap->devPrivate.ptr = NULL; pExaPixmap->sys_ptr = NULL; pExaPixmap->sys_pitch = paddedWidth; pExaPixmap->area = NULL; pExaPixmap->fb_ptr = NULL; pExaPixmap->pDamage = NULL; exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp); (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL); /* A scratch pixmap will become a driver pixmap right away. */ if (!w || !h) { exaCreateDriverPixmap_mixed(pPixmap); pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap); } else { pExaPixmap->use_gpu_copy = FALSE; if (w == 1 && h == 1) { pExaPixmap->sys_ptr = malloc(paddedWidth); /* Set up damage tracking */ pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL, DamageReportNonEmpty, TRUE, pPixmap->drawable.pScreen, pPixmap); if (pExaPixmap->pDamage) { DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage); /* This ensures that pending damage reflects the current * operation. This is used by exa to optimize migration. */ DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE); } } } /* During a fallback we must prepare access. */ if (pExaScr->fallback_counter) exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); return pPixmap; } Bool exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, void *pPixData) { ScreenPtr pScreen; ExaScreenPrivPtr pExaScr; ExaPixmapPrivPtr pExaPixmap; Bool ret, has_gpu_copy; if (!pPixmap) return FALSE; pScreen = pPixmap->drawable.pScreen; pExaScr = ExaGetScreenPriv(pScreen); pExaPixmap = ExaGetPixmapPriv(pPixmap); if (pPixData) { if (pExaPixmap->driverPriv) { if (pExaPixmap->pDamage) { DamageDestroy(pExaPixmap->pDamage); pExaPixmap->pDamage = NULL; } pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv); pExaPixmap->driverPriv = NULL; } pExaPixmap->use_gpu_copy = FALSE; pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; } has_gpu_copy = exaPixmapHasGpuCopy(pPixmap); if (width <= 0) width = pPixmap->drawable.width; if (height <= 0) height = pPixmap->drawable.height; if (bitsPerPixel <= 0) { if (depth <= 0) bitsPerPixel = pPixmap->drawable.bitsPerPixel; else bitsPerPixel = BitsPerPixel(depth); } if (depth <= 0) depth = pPixmap->drawable.depth; if (width != pPixmap->drawable.width || height != pPixmap->drawable.height || depth != pPixmap->drawable.depth || bitsPerPixel != pPixmap->drawable.bitsPerPixel) { if (pExaPixmap->driverPriv) { if (devKind > 0) pExaPixmap->fb_pitch = devKind; else exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel); exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel); RegionEmpty(&pExaPixmap->validFB); } /* Need to re-create system copy if there's also a GPU copy */ if (has_gpu_copy) { if (pExaPixmap->sys_ptr) { free(pExaPixmap->sys_ptr); pExaPixmap->sys_ptr = NULL; DamageDestroy(pExaPixmap->pDamage); pExaPixmap->pDamage = NULL; RegionEmpty(&pExaPixmap->validSys); if (pExaScr->deferred_mixed_pixmap == pPixmap) pExaScr->deferred_mixed_pixmap = NULL; } pExaPixmap->sys_pitch = PixmapBytePad(width, depth); } } if (has_gpu_copy) { pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; pPixmap->devKind = pExaPixmap->fb_pitch; } else { pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; pPixmap->devKind = pExaPixmap->sys_pitch; } /* Only pass driver pixmaps to the driver. */ if (pExaScr->info->ModifyPixmapHeader && pExaPixmap->driverPriv) { ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData); if (ret == TRUE) goto out; } swap(pExaScr, pScreen, ModifyPixmapHeader); ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData); swap(pExaScr, pScreen, ModifyPixmapHeader); out: if (has_gpu_copy) { pExaPixmap->fb_ptr = pPixmap->devPrivate.ptr; pExaPixmap->fb_pitch = pPixmap->devKind; } else { pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; pExaPixmap->sys_pitch = pPixmap->devKind; } /* Always NULL this, we don't want lingering pointers. */ pPixmap->devPrivate.ptr = NULL; return ret; } Bool exaDestroyPixmap_mixed(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); Bool ret; if (pPixmap->refcnt == 1) { ExaPixmapPriv(pPixmap); exaDestroyPixmap(pPixmap); if (pExaScr->deferred_mixed_pixmap == pPixmap) pExaScr->deferred_mixed_pixmap = NULL; if (pExaPixmap->driverPriv) pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv); pExaPixmap->driverPriv = NULL; if (pExaPixmap->pDamage) { free(pExaPixmap->sys_ptr); pExaPixmap->sys_ptr = NULL; pExaPixmap->pDamage = NULL; } } swap(pExaScr, pScreen, DestroyPixmap); ret = pScreen->DestroyPixmap(pPixmap); swap(pExaScr, pScreen, DestroyPixmap); return ret; } Bool exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); ExaPixmapPriv(pPixmap); void *saved_ptr; Bool ret; if (!pExaPixmap->driverPriv) return FALSE; saved_ptr = pPixmap->devPrivate.ptr; pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap); ret = pExaScr->info->PixmapIsOffscreen(pPixmap); pPixmap->devPrivate.ptr = saved_ptr; return ret; } Bool exaSharePixmapBacking_mixed(PixmapPtr pPixmap, ScreenPtr slave, void **handle_p) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); Bool ret = FALSE; exaMoveInPixmap(pPixmap); /* get the driver to give us a handle */ if (pExaScr->info->SharePixmapBacking) ret = pExaScr->info->SharePixmapBacking(pPixmap, slave, handle_p); return ret; } Bool exaSetSharedPixmapBacking_mixed(PixmapPtr pPixmap, void *handle) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); Bool ret = FALSE; if (pExaScr->info->SetSharedPixmapBacking) ret = pExaScr->info->SetSharedPixmapBacking(pPixmap, handle); if (ret == TRUE) exaMoveInPixmap(pPixmap); return ret; } xorg-server-1.20.13/exa/exa_migration_mixed.c0000644000175000017500000002200714100573756016030 00000000000000/* * Copyright © 2009 Maarten Maathuis * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "exa_priv.h" #include "exa.h" void exaCreateDriverPixmap_mixed(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); ExaPixmapPriv(pPixmap); int w = pPixmap->drawable.width, h = pPixmap->drawable.height; int depth = pPixmap->drawable.depth, bpp = pPixmap->drawable.bitsPerPixel; int usage_hint = pPixmap->usage_hint; int paddedWidth = pExaPixmap->sys_pitch; /* Already done. */ if (pExaPixmap->driverPriv) return; if (exaPixmapIsPinned(pPixmap)) return; /* Can't accel 1/4 bpp. */ if (pExaPixmap->accel_blocked || bpp < 8) return; if (pExaScr->info->CreatePixmap2) { int new_pitch = 0; pExaPixmap->driverPriv = pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp, &new_pitch); paddedWidth = pExaPixmap->fb_pitch = new_pitch; } else { if (paddedWidth < pExaPixmap->fb_pitch) paddedWidth = pExaPixmap->fb_pitch; pExaPixmap->driverPriv = pExaScr->info->CreatePixmap(pScreen, paddedWidth * h, 0); } if (!pExaPixmap->driverPriv) return; (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL); } void exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) { int i; /* If anything is pinned in system memory, we won't be able to * accelerate. */ for (i = 0; i < npixmaps; i++) { if (exaPixmapIsPinned(pixmaps[i].pPix) && !exaPixmapHasGpuCopy(pixmaps[i].pPix)) { can_accel = FALSE; break; } } /* We can do nothing. */ if (!can_accel) return; for (i = 0; i < npixmaps; i++) { PixmapPtr pPixmap = pixmaps[i].pPix; ExaPixmapPriv(pPixmap); if (!pExaPixmap->driverPriv) exaCreateDriverPixmap_mixed(pPixmap); if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) { ExaScreenPriv(pPixmap->drawable.pScreen); /* This pitch is needed for proper acceleration. For some reason * there are pixmaps without pDamage and a bad fb_pitch value. * So setting devKind when only exaPixmapHasGpuCopy() is true * causes corruption. Pixmaps without pDamage are not migrated * and should have a valid devKind at all times, so that's why this * isn't causing problems. Pixmaps have their gpu pitch set the * first time in the MPH call from exaCreateDriverPixmap_mixed(). */ pPixmap->devKind = pExaPixmap->fb_pitch; exaCopyDirtyToFb(pixmaps + i); if (pExaScr->deferred_mixed_pixmap == pPixmap && !pixmaps[i].as_dst && !pixmaps[i].pReg) pExaScr->deferred_mixed_pixmap = NULL; } pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap); } } void exaMoveInPixmap_mixed(PixmapPtr pPixmap) { ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = FALSE; pixmaps[0].as_src = TRUE; pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = NULL; exaDoMigration(pixmaps, 1, TRUE); } void exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure) { PixmapPtr pPixmap = closure; ExaPixmapPriv(pPixmap); /* Move back results of software rendering on system memory copy of mixed driver * pixmap (see exaPrepareAccessReg_mixed). * * Defer moving the destination back into the driver pixmap, to try and save * overhead on multiple subsequent software fallbacks. */ if (!pExaPixmap->use_gpu_copy && exaPixmapHasGpuCopy(pPixmap)) { ExaScreenPriv(pPixmap->drawable.pScreen); if (pExaScr->deferred_mixed_pixmap && pExaScr->deferred_mixed_pixmap != pPixmap) exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap); pExaScr->deferred_mixed_pixmap = pPixmap; } } /* With mixed pixmaps, if we fail to get direct access to the driver pixmap, we * use the DownloadFromScreen hook to retrieve contents to a copy in system * memory, perform software rendering on that and move back the results with the * UploadToScreen hook (see exaDamageReport_mixed). */ void exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg) { ExaPixmapPriv(pPixmap); Bool has_gpu_copy = exaPixmapHasGpuCopy(pPixmap); Bool success; success = ExaDoPrepareAccess(pPixmap, index); if (success && has_gpu_copy && pExaPixmap->pDamage) { /* You cannot do accelerated operations while a buffer is mapped. */ exaFinishAccess(&pPixmap->drawable, index); /* Update the gpu view of both deferred destination pixmaps and of * source pixmaps that were migrated with a bounding region. */ exaMoveInPixmap_mixed(pPixmap); success = ExaDoPrepareAccess(pPixmap, index); if (success) { /* We have a gpu pixmap that can be accessed, we don't need the cpu * copy anymore. Drivers that prefer DFS, should fail prepare * access. */ DamageDestroy(pExaPixmap->pDamage); pExaPixmap->pDamage = NULL; free(pExaPixmap->sys_ptr); pExaPixmap->sys_ptr = NULL; return; } } if (!success) { ExaMigrationRec pixmaps[1]; /* Do we need to allocate our system buffer? */ if (!pExaPixmap->sys_ptr) { pExaPixmap->sys_ptr = xallocarray(pExaPixmap->sys_pitch, pPixmap->drawable.height); if (!pExaPixmap->sys_ptr) FatalError("EXA: malloc failed for size %d bytes\n", pExaPixmap->sys_pitch * pPixmap->drawable.height); } if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) { pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; } else { pixmaps[0].as_dst = FALSE; pixmaps[0].as_src = TRUE; } pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = pReg; if (!pExaPixmap->pDamage && (has_gpu_copy || !exaPixmapIsPinned(pPixmap))) { Bool as_dst = pixmaps[0].as_dst; /* Set up damage tracking */ pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL, DamageReportNonEmpty, TRUE, pPixmap->drawable.pScreen, pPixmap); if (pExaPixmap->pDamage) { DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage); /* This ensures that pending damage reflects the current * operation. This is used by exa to optimize migration. */ DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE); } if (has_gpu_copy) { exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width, pPixmap->drawable.height); /* We don't know which region of the destination will be damaged, * have to assume all of it */ if (as_dst) { pixmaps[0].as_dst = FALSE; pixmaps[0].as_src = TRUE; pixmaps[0].pReg = NULL; } exaCopyDirtyToSys(pixmaps); } if (as_dst) exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width, pPixmap->drawable.height); } else if (has_gpu_copy) exaCopyDirtyToSys(pixmaps); pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; pPixmap->devKind = pExaPixmap->sys_pitch; pExaPixmap->use_gpu_copy = FALSE; } } xorg-server-1.20.13/exa/exa_accel.c0000644000175000017500000012332314100573756013723 00000000000000/* * Copyright © 2001 Keith Packard * * Partly based on code that is Copyright © 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. * * Authors: * Eric Anholt * Michel Dänzer * */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "exa_priv.h" #include #include "dixfontstr.h" #include "exa.h" static void exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, DDXPointPtr ppt, int *pwidth, int fSorted) { ScreenPtr pScreen = pDrawable->pScreen; ExaScreenPriv(pScreen); RegionPtr pClip = fbGetCompositeClip(pGC); PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); ExaPixmapPriv(pPixmap); BoxPtr pextent, pbox; int nbox; int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1; int partX1, partX2; int off_x, off_y; if (pExaScr->fallback_counter || pExaScr->swappedOut || pGC->fillStyle != FillSolid || pExaPixmap->accel_blocked) { ExaCheckFillSpans(pDrawable, pGC, n, ppt, pwidth, fSorted); return; } if (pExaScr->do_migration) { ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = NULL; exaDoMigration(pixmaps, 1, TRUE); } if (!(pPixmap = exaGetOffscreenPixmap(pDrawable, &off_x, &off_y)) || !(*pExaScr->info->PrepareSolid) (pPixmap, pGC->alu, pGC->planemask, pGC->fgPixel)) { ExaCheckFillSpans(pDrawable, pGC, n, ppt, pwidth, fSorted); return; } pextent = RegionExtents(pClip); extentX1 = pextent->x1; extentY1 = pextent->y1; extentX2 = pextent->x2; extentY2 = pextent->y2; while (n--) { fullX1 = ppt->x; fullY1 = ppt->y; fullX2 = fullX1 + (int) *pwidth; ppt++; pwidth++; if (fullY1 < extentY1 || extentY2 <= fullY1) continue; if (fullX1 < extentX1) fullX1 = extentX1; if (fullX2 > extentX2) fullX2 = extentX2; if (fullX1 >= fullX2) continue; nbox = RegionNumRects(pClip); if (nbox == 1) { (*pExaScr->info->Solid) (pPixmap, fullX1 + off_x, fullY1 + off_y, fullX2 + off_x, fullY1 + 1 + off_y); } else { pbox = RegionRects(pClip); while (nbox--) { if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) { partX1 = pbox->x1; if (partX1 < fullX1) partX1 = fullX1; partX2 = pbox->x2; if (partX2 > fullX2) partX2 = fullX2; if (partX2 > partX1) { (*pExaScr->info->Solid) (pPixmap, partX1 + off_x, fullY1 + off_y, partX2 + off_x, fullY1 + 1 + off_y); } } pbox++; } } } (*pExaScr->info->DoneSolid) (pPixmap); exaMarkSync(pScreen); } static Bool exaDoPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int format, char *bits, int src_stride) { ExaScreenPriv(pDrawable->pScreen); PixmapPtr pPix = exaGetDrawablePixmap(pDrawable); ExaPixmapPriv(pPix); RegionPtr pClip; BoxPtr pbox; int nbox; int xoff, yoff; int bpp = pDrawable->bitsPerPixel; Bool ret = TRUE; if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen) return FALSE; /* If there's a system copy, we want to save the result there */ if (pExaPixmap->pDamage) return FALSE; /* Don't bother with under 8bpp, XYPixmaps. */ if (format != ZPixmap || bpp < 8) return FALSE; /* Only accelerate copies: no rop or planemask. */ if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy) return FALSE; if (pExaScr->swappedOut) return FALSE; if (pExaScr->do_migration) { ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pPix; pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage); exaDoMigration(pixmaps, 1, TRUE); } pPix = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff); if (!pPix) return FALSE; x += pDrawable->x; y += pDrawable->y; pClip = fbGetCompositeClip(pGC); for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip); nbox--; pbox++) { int x1 = x; int y1 = y; int x2 = x + w; int y2 = y + h; char *src; Bool ok; if (x1 < pbox->x1) x1 = pbox->x1; if (y1 < pbox->y1) y1 = pbox->y1; if (x2 > pbox->x2) x2 = pbox->x2; if (y2 > pbox->y2) y2 = pbox->y2; if (x1 >= x2 || y1 >= y2) continue; src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8); ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff, x2 - x1, y2 - y1, src, src_stride); /* We have to fall back completely, and ignore what has already been completed. * Messing with the fb layer directly like we used to is completely unacceptable. */ if (!ok) { ret = FALSE; break; } } if (ret) exaMarkSync(pDrawable->pScreen); return ret; } static void exaPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, format, bits, PixmapBytePad(w, pDrawable->depth))) ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); } static Bool inline exaCopyNtoNTwoDir(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy) { ExaScreenPriv(pDstDrawable->pScreen); PixmapPtr pSrcPixmap, pDstPixmap; int src_off_x, src_off_y, dst_off_x, dst_off_y; int dirsetup; /* Need to get both pixmaps to call the driver routines */ pSrcPixmap = exaGetOffscreenPixmap(pSrcDrawable, &src_off_x, &src_off_y); pDstPixmap = exaGetOffscreenPixmap(pDstDrawable, &dst_off_x, &dst_off_y); if (!pSrcPixmap || !pDstPixmap) return FALSE; /* * Now the case of a chip that only supports xdir = ydir = 1 or * xdir = ydir = -1, but we have xdir != ydir. */ dirsetup = 0; /* No direction set up yet. */ for (; nbox; pbox++, nbox--) { if (dx >= 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) { /* Do a xdir = ydir = -1 blit instead. */ if (dirsetup != -1) { if (dirsetup != 0) pExaScr->info->DoneCopy(pDstPixmap); dirsetup = -1; if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, -1, -1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) return FALSE; } (*pExaScr->info->Copy) (pDstPixmap, src_off_x + pbox->x1 + dx, src_off_y + pbox->y1 + dy, dst_off_x + pbox->x1, dst_off_y + pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); } else if (dx < 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) { /* Do a xdir = ydir = 1 blit instead. */ if (dirsetup != 1) { if (dirsetup != 0) pExaScr->info->DoneCopy(pDstPixmap); dirsetup = 1; if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, 1, 1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) return FALSE; } (*pExaScr->info->Copy) (pDstPixmap, src_off_x + pbox->x1 + dx, src_off_y + pbox->y1 + dy, dst_off_x + pbox->x1, dst_off_y + pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); } else if (dx >= 0) { /* * xdir = 1, ydir = -1. * Perform line-by-line xdir = ydir = 1 blits, going up. */ int i; if (dirsetup != 1) { if (dirsetup != 0) pExaScr->info->DoneCopy(pDstPixmap); dirsetup = 1; if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, 1, 1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) return FALSE; } for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--) (*pExaScr->info->Copy) (pDstPixmap, src_off_x + pbox->x1 + dx, src_off_y + pbox->y1 + dy + i, dst_off_x + pbox->x1, dst_off_y + pbox->y1 + i, pbox->x2 - pbox->x1, 1); } else { /* * xdir = -1, ydir = 1. * Perform line-by-line xdir = ydir = -1 blits, going down. */ int i; if (dirsetup != -1) { if (dirsetup != 0) pExaScr->info->DoneCopy(pDstPixmap); dirsetup = -1; if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, -1, -1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) return FALSE; } for (i = 0; i < pbox->y2 - pbox->y1; i++) (*pExaScr->info->Copy) (pDstPixmap, src_off_x + pbox->x1 + dx, src_off_y + pbox->y1 + dy + i, dst_off_x + pbox->x1, dst_off_y + pbox->y1 + i, pbox->x2 - pbox->x1, 1); } } if (dirsetup != 0) pExaScr->info->DoneCopy(pDstPixmap); exaMarkSync(pDstDrawable->pScreen); return TRUE; } Bool exaHWCopyNtoN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown) { ExaScreenPriv(pDstDrawable->pScreen); PixmapPtr pSrcPixmap, pDstPixmap; ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap; int src_off_x, src_off_y; int dst_off_x, dst_off_y; RegionPtr srcregion = NULL, dstregion = NULL; xRectangle *rects; Bool ret = TRUE; /* avoid doing copy operations if no boxes */ if (nbox == 0) return TRUE; pSrcPixmap = exaGetDrawablePixmap(pSrcDrawable); pDstPixmap = exaGetDrawablePixmap(pDstDrawable); exaGetDrawableDeltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y); exaGetDrawableDeltas(pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y); rects = xallocarray(nbox, sizeof(xRectangle)); if (rects) { int i; int ordering; for (i = 0; i < nbox; i++) { rects[i].x = pbox[i].x1 + dx + src_off_x; rects[i].y = pbox[i].y1 + dy + src_off_y; rects[i].width = pbox[i].x2 - pbox[i].x1; rects[i].height = pbox[i].y2 - pbox[i].y1; } /* This must match the RegionCopy() logic for reversing rect order */ if (nbox == 1 || (dx > 0 && dy > 0) || (pDstDrawable != pSrcDrawable && (pDstDrawable->type != DRAWABLE_WINDOW || pSrcDrawable->type != DRAWABLE_WINDOW))) ordering = CT_YXBANDED; else ordering = CT_UNSORTED; srcregion = RegionFromRects(nbox, rects, ordering); free(rects); if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask, pGC->fillStyle, pGC->alu, pGC->clientClip != NULL)) { dstregion = RegionCreate(NullBox, 0); RegionCopy(dstregion, srcregion); RegionTranslate(dstregion, dst_off_x - dx - src_off_x, dst_off_y - dy - src_off_y); } } pSrcExaPixmap = ExaGetPixmapPriv(pSrcPixmap); pDstExaPixmap = ExaGetPixmapPriv(pDstPixmap); /* Check whether the accelerator can use this pixmap. * If the pitch of the pixmaps is out of range, there's nothing * we can do but fall back to software rendering. */ if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH || pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH) goto fallback; /* If the width or the height of either of the pixmaps * is out of range, check whether the boxes are actually out of the * addressable range as well. If they aren't, we can still do * the copying in hardware. */ if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) { int i; for (i = 0; i < nbox; i++) { /* src */ if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX || (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY) goto fallback; /* dst */ if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX || (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY) goto fallback; } } if (pExaScr->do_migration) { ExaMigrationRec pixmaps[2]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pDstPixmap; pixmaps[0].pReg = dstregion; pixmaps[1].as_dst = FALSE; pixmaps[1].as_src = TRUE; pixmaps[1].pPix = pSrcPixmap; pixmaps[1].pReg = srcregion; exaDoMigration(pixmaps, 2, TRUE); } /* Mixed directions must be handled specially if the card is lame */ if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) && reverse != upsidedown) { if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy)) goto out; goto fallback; } if (exaPixmapHasGpuCopy(pDstPixmap)) { /* Normal blitting. */ if (exaPixmapHasGpuCopy(pSrcPixmap)) { if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, upsidedown ? -1 : 1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) { goto fallback; } while (nbox--) { (*pExaScr->info->Copy) (pDstPixmap, pbox->x1 + dx + src_off_x, pbox->y1 + dy + src_off_y, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } (*pExaScr->info->DoneCopy) (pDstPixmap); exaMarkSync(pDstDrawable->pScreen); /* UTS: mainly for SHM PutImage's secondary path. * * Only taking this path for directly accessible pixmaps. */ } else if (!pDstExaPixmap->pDamage && pSrcExaPixmap->sys_ptr) { int bpp = pSrcDrawable->bitsPerPixel; int src_stride = exaGetPixmapPitch(pSrcPixmap); CARD8 *src = NULL; if (!pExaScr->info->UploadToScreen) goto fallback; if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) goto fallback; if (pSrcDrawable->bitsPerPixel < 8) goto fallback; if (pGC && !(pGC->alu == GXcopy && EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask))) goto fallback; while (nbox--) { src = pSrcExaPixmap->sys_ptr + (pbox->y1 + dy + src_off_y) * src_stride + (pbox->x1 + dx + src_off_x) * (bpp / 8); if (!pExaScr->info-> UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, (char *) src, src_stride)) goto fallback; pbox++; } } else goto fallback; } else goto fallback; goto out; fallback: ret = FALSE; out: if (dstregion) { RegionUninit(dstregion); RegionDestroy(dstregion); } if (srcregion) { RegionUninit(srcregion); RegionDestroy(srcregion); } return ret; } void exaCopyNtoN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { ExaScreenPriv(pDstDrawable->pScreen); if (pExaScr->fallback_counter || (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW)) return; if (exaHWCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown)) return; /* This is a CopyWindow, it's cleaner to fallback at the original call. */ if (pExaScr->fallback_flags & EXA_ACCEL_COPYWINDOW) { pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW; return; } /* fallback */ ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } RegionPtr exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty) { ExaScreenPriv(pDstDrawable->pScreen); if (pExaScr->fallback_counter || pExaScr->swappedOut) { return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty); } return miDoCopy(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, exaCopyNtoN, 0, NULL); } static void exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { ExaScreenPriv(pDrawable->pScreen); int i; xRectangle *prect; /* If we can't reuse the current GC as is, don't bother accelerating the * points. */ if (pExaScr->fallback_counter || pGC->fillStyle != FillSolid) { ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt); return; } prect = xallocarray(npt, sizeof(xRectangle)); for (i = 0; i < npt; i++) { prect[i].x = ppt[i].x; prect[i].y = ppt[i].y; if (i > 0 && mode == CoordModePrevious) { prect[i].x += prect[i - 1].x; prect[i].y += prect[i - 1].y; } prect[i].width = 1; prect[i].height = 1; } pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect); free(prect); } /** * exaPolylines() checks if it can accelerate the lines as a group of * horizontal or vertical lines (rectangles), and uses existing rectangle fill * acceleration if so. */ static void exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { ExaScreenPriv(pDrawable->pScreen); xRectangle *prect; int x1, x2, y1, y2; int i; if (pExaScr->fallback_counter) { ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt); return; } /* Don't try to do wide lines or non-solid fill style. */ if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) { ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt); return; } prect = xallocarray(npt - 1, sizeof(xRectangle)); x1 = ppt[0].x; y1 = ppt[0].y; /* If we have any non-horizontal/vertical, fall back. */ for (i = 0; i < npt - 1; i++) { if (mode == CoordModePrevious) { x2 = x1 + ppt[i + 1].x; y2 = y1 + ppt[i + 1].y; } else { x2 = ppt[i + 1].x; y2 = ppt[i + 1].y; } if (x1 != x2 && y1 != y2) { free(prect); ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt); return; } if (x1 < x2) { prect[i].x = x1; prect[i].width = x2 - x1 + 1; } else { prect[i].x = x2; prect[i].width = x1 - x2 + 1; } if (y1 < y2) { prect[i].y = y1; prect[i].height = y2 - y1 + 1; } else { prect[i].y = y2; prect[i].height = y1 - y2 + 1; } x1 = x2; y1 = y2; } pGC->ops->PolyFillRect(pDrawable, pGC, npt - 1, prect); free(prect); } /** * exaPolySegment() checks if it can accelerate the lines as a group of * horizontal or vertical lines (rectangles), and uses existing rectangle fill * acceleration if so. */ static void exaPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg) { ExaScreenPriv(pDrawable->pScreen); xRectangle *prect; int i; /* Don't try to do wide lines or non-solid fill style. */ if (pExaScr->fallback_counter || pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) { ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg); return; } /* If we have any non-horizontal/vertical, fall back. */ for (i = 0; i < nseg; i++) { if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) { ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg); return; } } prect = xallocarray(nseg, sizeof(xRectangle)); for (i = 0; i < nseg; i++) { if (pSeg[i].x1 < pSeg[i].x2) { prect[i].x = pSeg[i].x1; prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1; } else { prect[i].x = pSeg[i].x2; prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1; } if (pSeg[i].y1 < pSeg[i].y2) { prect[i].y = pSeg[i].y1; prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1; } else { prect[i].y = pSeg[i].y2; prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1; } /* don't paint last pixel */ if (pGC->capStyle == CapNotLast) { if (prect[i].width == 1) prect[i].height--; else prect[i].width--; } } pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect); free(prect); } static Bool exaFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, CARD32 planemask, CARD32 alu, Bool hasClientClip); static void exaPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect) { ExaScreenPriv(pDrawable->pScreen); RegionPtr pClip = fbGetCompositeClip(pGC); PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); ExaPixmapPriv(pPixmap); register BoxPtr pbox; BoxPtr pextent; int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1, fullY2; int partX1, partX2, partY1, partY2; int xoff, yoff; int xorg, yorg; int n; RegionPtr pReg = RegionFromRects(nrect, prect, CT_UNSORTED); /* Compute intersection of rects and clip region */ RegionTranslate(pReg, pDrawable->x, pDrawable->y); RegionIntersect(pReg, pClip, pReg); if (!RegionNumRects(pReg)) { goto out; } exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); if (pExaScr->fallback_counter || pExaScr->swappedOut || pExaPixmap->accel_blocked) { goto fallback; } /* For ROPs where overlaps don't matter, convert rectangles to region and * call exaFillRegion{Solid,Tiled}. */ if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) && (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear || pGC->alu == GXnoop || pGC->alu == GXcopyInverted || pGC->alu == GXset)) { if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) && exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ? pGC->fgPixel : pGC->tile.pixel, pGC->planemask, pGC->alu, pGC->clientClip != NULL)) || (pGC->fillStyle == FillTiled && !pGC->tileIsPixel && exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg, pGC->planemask, pGC->alu, pGC->clientClip != NULL))) { goto out; } } if (pGC->fillStyle != FillSolid && !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) { goto fallback; } if (pExaScr->do_migration) { ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = NULL; exaDoMigration(pixmaps, 1, TRUE); } if (!exaPixmapHasGpuCopy(pPixmap) || !(*pExaScr->info->PrepareSolid) (pPixmap, pGC->alu, pGC->planemask, pGC->fgPixel)) { fallback: ExaCheckPolyFillRect(pDrawable, pGC, nrect, prect); goto out; } xorg = pDrawable->x; yorg = pDrawable->y; pextent = RegionExtents(pClip); extentX1 = pextent->x1; extentY1 = pextent->y1; extentX2 = pextent->x2; extentY2 = pextent->y2; while (nrect--) { fullX1 = prect->x + xorg; fullY1 = prect->y + yorg; fullX2 = fullX1 + (int) prect->width; fullY2 = fullY1 + (int) prect->height; prect++; if (fullX1 < extentX1) fullX1 = extentX1; if (fullY1 < extentY1) fullY1 = extentY1; if (fullX2 > extentX2) fullX2 = extentX2; if (fullY2 > extentY2) fullY2 = extentY2; if ((fullX1 >= fullX2) || (fullY1 >= fullY2)) continue; n = RegionNumRects(pClip); if (n == 1) { (*pExaScr->info->Solid) (pPixmap, fullX1 + xoff, fullY1 + yoff, fullX2 + xoff, fullY2 + yoff); } else { pbox = RegionRects(pClip); /* * clip the rectangle to each box in the clip region * this is logically equivalent to calling Intersect(), * but rectangles may overlap each other here. */ while (n--) { partX1 = pbox->x1; if (partX1 < fullX1) partX1 = fullX1; partY1 = pbox->y1; if (partY1 < fullY1) partY1 = fullY1; partX2 = pbox->x2; if (partX2 > fullX2) partX2 = fullX2; partY2 = pbox->y2; if (partY2 > fullY2) partY2 = fullY2; pbox++; if (partX1 < partX2 && partY1 < partY2) { (*pExaScr->info->Solid) (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff, partY2 + yoff); } } } } (*pExaScr->info->DoneSolid) (pPixmap); exaMarkSync(pDrawable->pScreen); out: RegionUninit(pReg); RegionDestroy(pReg); } const GCOps exaOps = { exaFillSpans, ExaCheckSetSpans, exaPutImage, exaCopyArea, ExaCheckCopyPlane, exaPolyPoint, exaPolylines, exaPolySegment, miPolyRectangle, ExaCheckPolyArc, miFillPolygon, exaPolyFillRect, miPolyFillArc, miPolyText8, miPolyText16, miImageText8, miImageText16, ExaCheckImageGlyphBlt, ExaCheckPolyGlyphBlt, ExaCheckPushPixels, }; void exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { RegionRec rgnDst; int dx, dy; PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); ExaScreenPriv(pWin->drawable.pScreen); dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; RegionTranslate(prgnSrc, -dx, -dy); RegionInit(&rgnDst, NullBox, 0); RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc); #ifdef COMPOSITE if (pPixmap->screen_x || pPixmap->screen_y) RegionTranslate(&rgnDst, -pPixmap->screen_x, -pPixmap->screen_y); #endif if (pExaScr->fallback_counter) { pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW; goto fallback; } pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW; miCopyRegion(&pPixmap->drawable, &pPixmap->drawable, NULL, &rgnDst, dx, dy, exaCopyNtoN, 0, NULL); pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW; fallback: RegionUninit(&rgnDst); if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) { pExaScr->fallback_flags &= ~EXA_FALLBACK_COPYWINDOW; RegionTranslate(prgnSrc, dx, dy); ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc); } } static Bool exaFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, CARD32 planemask, CARD32 alu, Bool hasClientClip) { ExaScreenPriv(pDrawable->pScreen); PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); ExaPixmapPriv(pPixmap); int xoff, yoff; Bool ret = FALSE; exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); RegionTranslate(pRegion, xoff, yoff); if (pExaScr->fallback_counter || pExaPixmap->accel_blocked) goto out; if (pExaScr->do_migration) { ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid, alu, hasClientClip) ? NULL : pRegion; exaDoMigration(pixmaps, 1, TRUE); } if (exaPixmapHasGpuCopy(pPixmap) && (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel)) { int nbox; BoxPtr pBox; nbox = RegionNumRects(pRegion); pBox = RegionRects(pRegion); while (nbox--) { (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2, pBox->y2); pBox++; } (*pExaScr->info->DoneSolid) (pPixmap); exaMarkSync(pDrawable->pScreen); if (pExaPixmap->pDamage && pExaPixmap->sys_ptr && pDrawable->type == DRAWABLE_PIXMAP && pDrawable->width == 1 && pDrawable->height == 1 && pDrawable->bitsPerPixel != 24 && alu == GXcopy) { RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); switch (pDrawable->bitsPerPixel) { case 32: *(CARD32 *) pExaPixmap->sys_ptr = pixel; break; case 16: *(CARD16 *) pExaPixmap->sys_ptr = pixel; break; case 8: case 4: case 1: *(CARD8 *) pExaPixmap->sys_ptr = pixel; } RegionUnion(&pExaPixmap->validSys, &pExaPixmap->validSys, pRegion); RegionUnion(&pExaPixmap->validFB, &pExaPixmap->validFB, pRegion); RegionSubtract(pending_damage, pending_damage, pRegion); } ret = TRUE; } out: RegionTranslate(pRegion, -xoff, -yoff); return ret; } /* Try to do an accelerated tile of the pTile into pRegion of pDrawable. * Based on fbFillRegionTiled(), fbTile(). */ Bool exaFillRegionTiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu, Bool hasClientClip) { ExaScreenPriv(pDrawable->pScreen); PixmapPtr pPixmap; ExaPixmapPrivPtr pExaPixmap; ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile); int xoff, yoff; int tileWidth, tileHeight; int nbox = RegionNumRects(pRegion); BoxPtr pBox = RegionRects(pRegion); Bool ret = FALSE; int i; tileWidth = pTile->drawable.width; tileHeight = pTile->drawable.height; /* If we're filling with a solid color, grab it out and go to * FillRegionSolid, saving numerous copies. */ if (tileWidth == 1 && tileHeight == 1) return exaFillRegionSolid(pDrawable, pRegion, exaGetPixmapFirstPixel(pTile), planemask, alu, hasClientClip); pPixmap = exaGetDrawablePixmap(pDrawable); pExaPixmap = ExaGetPixmapPriv(pPixmap); if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked) return FALSE; if (pExaScr->do_migration) { ExaMigrationRec pixmaps[2]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pPixmap; pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled, alu, hasClientClip) ? NULL : pRegion; pixmaps[1].as_dst = FALSE; pixmaps[1].as_src = TRUE; pixmaps[1].pPix = pTile; pixmaps[1].pReg = NULL; exaDoMigration(pixmaps, 2, TRUE); } pPixmap = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff); if (!pPixmap || !exaPixmapHasGpuCopy(pTile)) return FALSE; if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask)) { if (xoff || yoff) RegionTranslate(pRegion, xoff, yoff); for (i = 0; i < nbox; i++) { int height = pBox[i].y2 - pBox[i].y1; int dstY = pBox[i].y1; int tileY; if (alu == GXcopy) height = min(height, tileHeight); modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY); while (height > 0) { int width = pBox[i].x2 - pBox[i].x1; int dstX = pBox[i].x1; int tileX; int h = tileHeight - tileY; if (alu == GXcopy) width = min(width, tileWidth); if (h > height) h = height; height -= h; modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth, tileX); while (width > 0) { int w = tileWidth - tileX; if (w > width) w = width; width -= w; (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY, w, h); dstX += w; tileX = 0; } dstY += h; tileY = 0; } } (*pExaScr->info->DoneCopy) (pPixmap); /* With GXcopy, we only need to do the basic algorithm up to the tile * size; then, we can just keep doubling the destination in each * direction until it fills the box. This way, the number of copy * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where * rx/ry is the ratio between box and tile width/height. This can make * a big difference if each driver copy incurs a significant constant * overhead. */ if (alu != GXcopy) ret = TRUE; else { Bool more_copy = FALSE; for (i = 0; i < nbox; i++) { int dstX = pBox[i].x1 + tileWidth; int dstY = pBox[i].y1 + tileHeight; if ((dstX < pBox[i].x2) || (dstY < pBox[i].y2)) { more_copy = TRUE; break; } } if (more_copy == FALSE) ret = TRUE; if (more_copy && (*pExaScr->info->PrepareCopy) (pPixmap, pPixmap, 1, 1, alu, planemask)) { for (i = 0; i < nbox; i++) { int dstX = pBox[i].x1 + tileWidth; int dstY = pBox[i].y1 + tileHeight; int width = min(pBox[i].x2 - dstX, tileWidth); int height = min(pBox[i].y2 - pBox[i].y1, tileHeight); while (dstX < pBox[i].x2) { (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1, dstX, pBox[i].y1, width, height); dstX += width; width = min(pBox[i].x2 - dstX, width * 2); } width = pBox[i].x2 - pBox[i].x1; height = min(pBox[i].y2 - dstY, tileHeight); while (dstY < pBox[i].y2) { (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1, pBox[i].x1, dstY, width, height); dstY += height; height = min(pBox[i].y2 - dstY, height * 2); } } (*pExaScr->info->DoneCopy) (pPixmap); ret = TRUE; } } exaMarkSync(pDrawable->pScreen); if (xoff || yoff) RegionTranslate(pRegion, -xoff, -yoff); } return ret; } /** * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory. * * This is probably the only case we actually care about. The rest fall through * to migration and fbGetImage, which hopefully will result in migration pushing * the pixmap out of framebuffer. */ void exaGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { ExaScreenPriv(pDrawable->pScreen); PixmapPtr pPix = exaGetDrawablePixmap(pDrawable); ExaPixmapPriv(pPix); int xoff, yoff; Bool ok; if (pExaScr->fallback_counter || pExaScr->swappedOut) goto fallback; /* If there's a system copy, we want to save the result there */ if (pExaPixmap->pDamage) goto fallback; pPix = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff); if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL) goto fallback; /* Only cover the ZPixmap, solid copy case. */ if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask)) goto fallback; /* Only try to handle the 8bpp and up cases, since we don't want to think * about <8bpp. */ if (pDrawable->bitsPerPixel < 8) goto fallback; ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff, pDrawable->y + y + yoff, w, h, d, PixmapBytePad(w, pDrawable->depth)); if (ok) { exaWaitSync(pDrawable->pScreen); return; } fallback: ExaCheckGetImage(pDrawable, x, y, w, h, format, planeMask, d); } xorg-server-1.20.13/exa/exa_glyphs.c0000644000175000017500000006446514100573756014175 00000000000000/* * Copyright © 2008 Red Hat, Inc. * Partly based on code 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 Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat * 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. * * 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: Owen Taylor * Based on code by: Keith Packard */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "exa_priv.h" #include "mipict.h" #if DEBUG_GLYPH_CACHE #define DBG_GLYPH_CACHE(a) ErrorF a #else #define DBG_GLYPH_CACHE(a) #endif /* Width of the pixmaps we use for the caches; this should be less than * max texture size of the driver; this may need to actually come from * the driver. */ #define CACHE_PICTURE_WIDTH 1024 /* Maximum number of glyphs we buffer on the stack before flushing * rendering to the mask or destination surface. */ #define GLYPH_BUFFER_SIZE 256 typedef struct { PicturePtr mask; ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE]; int count; } ExaGlyphBuffer, *ExaGlyphBufferPtr; typedef enum { ExaGlyphSuccess, /* Glyph added to render buffer */ ExaGlyphFail, /* out of memory, etc */ ExaGlyphNeedFlush, /* would evict a glyph already in the buffer */ } ExaGlyphCacheResult; void exaGlyphsInit(ScreenPtr pScreen) { ExaScreenPriv(pScreen); int i = 0; memset(pExaScr->glyphCaches, 0, sizeof(pExaScr->glyphCaches)); pExaScr->glyphCaches[i].format = PICT_a8; pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 16; i++; pExaScr->glyphCaches[i].format = PICT_a8; pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 32; i++; pExaScr->glyphCaches[i].format = PICT_a8r8g8b8; pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 16; i++; pExaScr->glyphCaches[i].format = PICT_a8r8g8b8; pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 32; i++; assert(i == EXA_NUM_GLYPH_CACHES); for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { pExaScr->glyphCaches[i].columns = CACHE_PICTURE_WIDTH / pExaScr->glyphCaches[i].glyphWidth; pExaScr->glyphCaches[i].size = 256; pExaScr->glyphCaches[i].hashSize = 557; } } static void exaUnrealizeGlyphCaches(ScreenPtr pScreen, unsigned int format) { ExaScreenPriv(pScreen); int i; for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; if (cache->format != format) continue; if (cache->picture) { FreePicture((void *) cache->picture, (XID) 0); cache->picture = NULL; } free(cache->hashEntries); cache->hashEntries = NULL; free(cache->glyphs); cache->glyphs = NULL; cache->glyphCount = 0; } } #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) /* All caches for a single format share a single pixmap for glyph storage, * allowing mixing glyphs of different sizes without paying a penalty * for switching between mask pixmaps. (Note that for a size of font * right at the border between two sizes, we might be switching for almost * every glyph.) * * This function allocates the storage pixmap, and then fills in the * rest of the allocated structures for all caches with the given format. */ static Bool exaRealizeGlyphCaches(ScreenPtr pScreen, unsigned int format) { ExaScreenPriv(pScreen); int depth = PIXMAN_FORMAT_DEPTH(format); PictFormatPtr pPictFormat; PixmapPtr pPixmap; PicturePtr pPicture; CARD32 component_alpha; int height; int i; int error; pPictFormat = PictureMatchFormat(pScreen, depth, format); if (!pPictFormat) return FALSE; /* Compute the total vertical size needed for the format */ height = 0; for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; int rows; if (cache->format != format) continue; cache->yOffset = height; rows = (cache->size + cache->columns - 1) / cache->columns; height += rows * cache->glyphHeight; } /* Now allocate the pixmap and picture */ pPixmap = (*pScreen->CreatePixmap) (pScreen, CACHE_PICTURE_WIDTH, height, depth, 0); if (!pPixmap) return FALSE; component_alpha = NeedsComponent(pPictFormat->format); pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat, CPComponentAlpha, &component_alpha, serverClient, &error); (*pScreen->DestroyPixmap) (pPixmap); /* picture holds a refcount */ if (!pPicture) return FALSE; /* And store the picture in all the caches for the format */ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; int j; if (cache->format != format) continue; cache->picture = pPicture; cache->picture->refcnt++; cache->hashEntries = xallocarray(cache->hashSize, sizeof(int)); cache->glyphs = xallocarray(cache->size, sizeof(ExaCachedGlyphRec)); cache->glyphCount = 0; if (!cache->hashEntries || !cache->glyphs) goto bail; for (j = 0; j < cache->hashSize; j++) cache->hashEntries[j] = -1; cache->evictionPosition = rand() % cache->size; } /* Each cache references the picture individually */ FreePicture((void *) pPicture, (XID) 0); return TRUE; bail: exaUnrealizeGlyphCaches(pScreen, format); return FALSE; } void exaGlyphsFini(ScreenPtr pScreen) { ExaScreenPriv(pScreen); int i; for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; if (cache->picture) exaUnrealizeGlyphCaches(pScreen, cache->format); } } static int exaGlyphCacheHashLookup(ExaGlyphCachePtr cache, GlyphPtr pGlyph) { int slot; slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize; while (TRUE) { /* hash table can never be full */ int entryPos = cache->hashEntries[slot]; if (entryPos == -1) return -1; if (memcmp (pGlyph->sha1, cache->glyphs[entryPos].sha1, sizeof(pGlyph->sha1)) == 0) { return entryPos; } slot--; if (slot < 0) slot = cache->hashSize - 1; } } static void exaGlyphCacheHashInsert(ExaGlyphCachePtr cache, GlyphPtr pGlyph, int pos) { int slot; memcpy(cache->glyphs[pos].sha1, pGlyph->sha1, sizeof(pGlyph->sha1)); slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize; while (TRUE) { /* hash table can never be full */ if (cache->hashEntries[slot] == -1) { cache->hashEntries[slot] = pos; return; } slot--; if (slot < 0) slot = cache->hashSize - 1; } } static void exaGlyphCacheHashRemove(ExaGlyphCachePtr cache, int pos) { int slot; int emptiedSlot = -1; slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hashSize; while (TRUE) { /* hash table can never be full */ int entryPos = cache->hashEntries[slot]; if (entryPos == -1) return; if (entryPos == pos) { cache->hashEntries[slot] = -1; emptiedSlot = slot; } else if (emptiedSlot != -1) { /* See if we can move this entry into the emptied slot, we can't * do that if if entry would have hashed between the current position * and the emptied slot. (taking wrapping into account). Bad positions * are: * * | XXXXXXXXXX | * i j * * |XXX XXXX| * j i * * i - slot, j - emptiedSlot * * (Knuth 6.4R) */ int entrySlot = (*(CARD32 *) cache->glyphs[entryPos].sha1) % cache->hashSize; if (!((entrySlot >= slot && entrySlot < emptiedSlot) || (emptiedSlot < slot && (entrySlot < emptiedSlot || entrySlot >= slot)))) { cache->hashEntries[emptiedSlot] = entryPos; cache->hashEntries[slot] = -1; emptiedSlot = slot; } } slot--; if (slot < 0) slot = cache->hashSize - 1; } } #define CACHE_X(pos) (((pos) % cache->columns) * cache->glyphWidth) #define CACHE_Y(pos) (cache->yOffset + ((pos) / cache->columns) * cache->glyphHeight) /* The most efficient thing to way to upload the glyph to the screen * is to use the UploadToScreen() driver hook; this allows us to * pipeline glyph uploads and to avoid creating gpu backed pixmaps for * glyphs that we'll never use again. * * If we can't do it with UploadToScreen (because the glyph has a gpu copy, * etc), we fall back to CompositePicture. * * We need to damage the cache pixmap manually in either case because the damage * layer unwrapped the picture screen before calling exaGlyphs. */ static void exaGlyphCacheUploadGlyph(ScreenPtr pScreen, ExaGlyphCachePtr cache, int x, int y, GlyphPtr pGlyph) { ExaScreenPriv(pScreen); PicturePtr pGlyphPicture = GetGlyphPicture(pGlyph, pScreen); PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable; ExaPixmapPriv(pGlyphPixmap); PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable; if (!pExaScr->info->UploadToScreen || pExaScr->swappedOut || pExaPixmap->accel_blocked) goto composite; /* If the glyph pixmap is already uploaded, no point in doing * things this way */ if (exaPixmapHasGpuCopy(pGlyphPixmap)) goto composite; /* UploadToScreen only works if bpp match */ if (pGlyphPixmap->drawable.bitsPerPixel != pCachePixmap->drawable.bitsPerPixel) goto composite; if (pExaScr->do_migration) { ExaMigrationRec pixmaps[1]; /* cache pixmap must have a gpu copy. */ pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pCachePixmap; pixmaps[0].pReg = NULL; exaDoMigration(pixmaps, 1, TRUE); } if (!exaPixmapHasGpuCopy(pCachePixmap)) goto composite; /* x,y are in pixmap coordinates, no need for cache{X,Y}off */ if (pExaScr->info->UploadToScreen(pCachePixmap, x, y, pGlyph->info.width, pGlyph->info.height, (char *) pExaPixmap->sys_ptr, pExaPixmap->sys_pitch)) goto damage; composite: CompositePicture(PictOpSrc, pGlyphPicture, None, cache->picture, 0, 0, 0, 0, x, y, pGlyph->info.width, pGlyph->info.height); damage: /* The cache pixmap isn't a window, so no need to offset coordinates. */ exaPixmapDirty(pCachePixmap, x, y, x + cache->glyphWidth, y + cache->glyphHeight); } static ExaGlyphCacheResult exaGlyphCacheBufferGlyph(ScreenPtr pScreen, ExaGlyphCachePtr cache, ExaGlyphBufferPtr buffer, GlyphPtr pGlyph, PicturePtr pSrc, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst) { ExaCompositeRectPtr rect; int pos; int x, y; if (buffer->mask && buffer->mask != cache->picture) return ExaGlyphNeedFlush; if (!cache->picture) { if (!exaRealizeGlyphCaches(pScreen, cache->format)) return ExaGlyphFail; } DBG_GLYPH_CACHE(("(%d,%d,%s): buffering glyph %lx\n", cache->glyphWidth, cache->glyphHeight, cache->format == PICT_a8 ? "A" : "ARGB", (long) *(CARD32 *) pGlyph->sha1)); pos = exaGlyphCacheHashLookup(cache, pGlyph); if (pos != -1) { DBG_GLYPH_CACHE((" found existing glyph at %d\n", pos)); x = CACHE_X(pos); y = CACHE_Y(pos); } else { if (cache->glyphCount < cache->size) { /* Space remaining; we fill from the start */ pos = cache->glyphCount; x = CACHE_X(pos); y = CACHE_Y(pos); cache->glyphCount++; DBG_GLYPH_CACHE((" storing glyph in free space at %d\n", pos)); exaGlyphCacheHashInsert(cache, pGlyph, pos); } else { /* Need to evict an entry. We have to see if any glyphs * already in the output buffer were at this position in * the cache */ pos = cache->evictionPosition; x = CACHE_X(pos); y = CACHE_Y(pos); DBG_GLYPH_CACHE((" evicting glyph at %d\n", pos)); if (buffer->count) { int i; for (i = 0; i < buffer->count; i++) { if (pSrc ? (buffer->rects[i].xMask == x && buffer->rects[i].yMask == y) : (buffer->rects[i].xSrc == x && buffer->rects[i].ySrc == y)) { DBG_GLYPH_CACHE((" must flush buffer\n")); return ExaGlyphNeedFlush; } } } /* OK, we're all set, swap in the new glyph */ exaGlyphCacheHashRemove(cache, pos); exaGlyphCacheHashInsert(cache, pGlyph, pos); /* And pick a new eviction position */ cache->evictionPosition = rand() % cache->size; } exaGlyphCacheUploadGlyph(pScreen, cache, x, y, pGlyph); } buffer->mask = cache->picture; rect = &buffer->rects[buffer->count]; if (pSrc) { rect->xSrc = xSrc; rect->ySrc = ySrc; rect->xMask = x; rect->yMask = y; } else { rect->xSrc = x; rect->ySrc = y; rect->xMask = 0; rect->yMask = 0; } rect->pDst = pDst; rect->xDst = xDst; rect->yDst = yDst; rect->width = pGlyph->info.width; rect->height = pGlyph->info.height; buffer->count++; return ExaGlyphSuccess; } #undef CACHE_X #undef CACHE_Y static ExaGlyphCacheResult exaBufferGlyph(ScreenPtr pScreen, ExaGlyphBufferPtr buffer, GlyphPtr pGlyph, PicturePtr pSrc, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst) { ExaScreenPriv(pScreen); unsigned int format = (GetGlyphPicture(pGlyph, pScreen))->format; int width = pGlyph->info.width; int height = pGlyph->info.height; ExaCompositeRectPtr rect; PicturePtr mask; int i; if (buffer->count == GLYPH_BUFFER_SIZE) return ExaGlyphNeedFlush; if (PICT_FORMAT_BPP(format) == 1) format = PICT_a8; for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; if (format == cache->format && width <= cache->glyphWidth && height <= cache->glyphHeight) { ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen, &pExaScr-> glyphCaches [i], buffer, pGlyph, pSrc, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst); switch (result) { case ExaGlyphFail: break; case ExaGlyphSuccess: case ExaGlyphNeedFlush: return result; } } } /* Couldn't find the glyph in the cache, use the glyph picture directly */ mask = GetGlyphPicture(pGlyph, pScreen); if (buffer->mask && buffer->mask != mask) return ExaGlyphNeedFlush; buffer->mask = mask; rect = &buffer->rects[buffer->count]; rect->xSrc = xSrc; rect->ySrc = ySrc; rect->xMask = xMask; rect->yMask = yMask; rect->xDst = xDst; rect->yDst = yDst; rect->width = width; rect->height = height; buffer->count++; return ExaGlyphSuccess; } static void exaGlyphsToMask(PicturePtr pMask, ExaGlyphBufferPtr buffer) { exaCompositeRects(PictOpAdd, buffer->mask, NULL, pMask, buffer->count, buffer->rects); buffer->count = 0; buffer->mask = NULL; } static void exaGlyphsToDst(CARD8 op, PicturePtr pSrc, PicturePtr pDst, ExaGlyphBufferPtr buffer) { exaCompositeRects(op, pSrc, buffer->mask, pDst, buffer->count, buffer->rects); buffer->count = 0; buffer->mask = NULL; } /* Cut and paste from render/glyph.c - probably should export it instead */ 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; } } } void exaGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { PixmapPtr pMaskPixmap = 0; PicturePtr pMask = NULL; ScreenPtr pScreen = pDst->pDrawable->pScreen; int width = 0, height = 0; int x, y; int first_xOff = list->xOff, first_yOff = list->yOff; int n; GlyphPtr glyph; int error; BoxRec extents = { 0, 0, 0, 0 }; CARD32 component_alpha; ExaGlyphBuffer buffer; if (maskFormat) { ExaScreenPriv(pScreen); 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; if (maskFormat->depth == 1) { PictFormatPtr a8Format = PictureMatchFormat(pScreen, 8, PICT_a8); if (a8Format) maskFormat = a8Format; } 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 || (!component_alpha && pExaScr->info->CheckComposite && !(*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, NULL, pMask))) { PictFormatPtr argbFormat; (*pScreen->DestroyPixmap) (pMaskPixmap); if (!pMask) return; /* The driver can't seem to composite to a8, let's try argb (but * without component-alpha) */ FreePicture((void *) pMask, (XID) 0); argbFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8); if (argbFormat) maskFormat = argbFormat; pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth, CREATE_PIXMAP_USAGE_SCRATCH); if (!pMaskPixmap) return; pMask = CreatePicture(0, &pMaskPixmap->drawable, maskFormat, 0, 0, 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 { x = 0; y = 0; } buffer.count = 0; buffer.mask = NULL; while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; while (n--) { glyph = *glyphs++; if (glyph->info.width > 0 && glyph->info.height > 0) { /* pGlyph->info.{x,y} compensate for empty space in the glyph. */ if (maskFormat) { if (exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask, 0, 0, 0, 0, x - glyph->info.x, y - glyph->info.y) == ExaGlyphNeedFlush) { exaGlyphsToMask(pMask, &buffer); exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask, 0, 0, 0, 0, x - glyph->info.x, y - glyph->info.y); } } else { if (exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst, xSrc + (x - glyph->info.x) - first_xOff, ySrc + (y - glyph->info.y) - first_yOff, 0, 0, x - glyph->info.x, y - glyph->info.y) == ExaGlyphNeedFlush) { exaGlyphsToDst(op, pSrc, pDst, &buffer); exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst, xSrc + (x - glyph->info.x) - first_xOff, ySrc + (y - glyph->info.y) - first_yOff, 0, 0, x - glyph->info.x, y - glyph->info.y); } } } x += glyph->info.xOff; y += glyph->info.yOff; } list++; } if (buffer.count) { if (maskFormat) exaGlyphsToMask(pMask, &buffer); else exaGlyphsToDst(op, pSrc, pDst, &buffer); } if (maskFormat) { x = extents.x1; y = extents.y1; CompositePicture(op, pSrc, pMask, pDst, xSrc + x - first_xOff, ySrc + y - first_yOff, 0, 0, x, y, width, height); FreePicture((void *) pMask, (XID) 0); (*pScreen->DestroyPixmap) (pMaskPixmap); } } xorg-server-1.20.13/exa/exa_offscreen.c0000644000175000017500000005025514100573756014631 00000000000000/* * Copyright © 2003 Anders Carlsson * * 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 Anders Carlsson not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Anders Carlsson makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * ANDERS CARLSSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL ANDERS CARLSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /** @file * This allocator allocates blocks of memory by maintaining a list of areas. * When allocating, the contiguous block of areas with the minimum eviction * cost is found and evicted in order to make room for the new allocation. */ #include "exa_priv.h" #include #include #include #if DEBUG_OFFSCREEN #define DBG_OFFSCREEN(a) ErrorF a #else #define DBG_OFFSCREEN(a) #endif #if DEBUG_OFFSCREEN static void ExaOffscreenValidate(ScreenPtr pScreen) { ExaScreenPriv(pScreen); ExaOffscreenArea *prev = 0, *area; assert(pExaScr->info->offScreenAreas->base_offset == pExaScr->info->offScreenBase); for (area = pExaScr->info->offScreenAreas; area; area = area->next) { assert(area->offset >= area->base_offset && area->offset < (area->base_offset + area->size)); if (prev) assert(prev->base_offset + prev->size == area->base_offset); prev = area; } assert(prev->base_offset + prev->size == pExaScr->info->memorySize); } #else #define ExaOffscreenValidate(s) #endif static ExaOffscreenArea * ExaOffscreenKickOut(ScreenPtr pScreen, ExaOffscreenArea * area) { if (area->save) (*area->save) (pScreen, area); return exaOffscreenFree(pScreen, area); } static void exaUpdateEvictionCost(ExaOffscreenArea * area, unsigned offScreenCounter) { unsigned age; if (area->state == ExaOffscreenAvail) return; age = offScreenCounter - area->last_use; /* This is unlikely to happen, but could result in a division by zero... */ if (age > (UINT_MAX / 2)) { age = UINT_MAX / 2; area->last_use = offScreenCounter - age; } area->eviction_cost = area->size / age; } static ExaOffscreenArea * exaFindAreaToEvict(ExaScreenPrivPtr pExaScr, int size, int align) { ExaOffscreenArea *begin, *end, *best; unsigned cost, best_cost; int avail, real_size; best_cost = UINT_MAX; begin = end = pExaScr->info->offScreenAreas; avail = 0; cost = 0; best = 0; while (end != NULL) { restart: while (begin != NULL && begin->state == ExaOffscreenLocked) begin = end = begin->next; if (begin == NULL) break; /* adjust size needed to account for alignment loss for this area */ real_size = size + (begin->base_offset + begin->size - size) % align; while (avail < real_size && end != NULL) { if (end->state == ExaOffscreenLocked) { /* Can't more room here, restart after this locked area */ avail = 0; cost = 0; begin = end; goto restart; } avail += end->size; exaUpdateEvictionCost(end, pExaScr->offScreenCounter); cost += end->eviction_cost; end = end->next; } /* Check the cost, update best */ if (avail >= real_size && cost < best_cost) { best = begin; best_cost = cost; } avail -= begin->size; cost -= begin->eviction_cost; begin = begin->next; } return best; } /** * exaOffscreenAlloc allocates offscreen memory * * @param pScreen current screen * @param size size in bytes of the allocation * @param align byte alignment requirement for the offset of the allocated area * @param locked whether the allocated area is locked and can't be kicked out * @param save callback for when the area is evicted from memory * @param privdata private data for the save callback. * * Allocates offscreen memory from the device associated with pScreen. size * and align deteremine where and how large the allocated area is, and locked * will mark whether it should be held in card memory. privdata may be any * pointer for the save callback when the area is removed. * * Note that locked areas do get evicted on VT switch unless the driver * requested version 2.1 or newer behavior. In that case, the save callback is * still called. */ ExaOffscreenArea * exaOffscreenAlloc(ScreenPtr pScreen, int size, int align, Bool locked, ExaOffscreenSaveProc save, void *privData) { ExaOffscreenArea *area; ExaScreenPriv(pScreen); int real_size = 0, largest_avail = 0; #if DEBUG_OFFSCREEN static int number = 0; ErrorF("================= ============ allocating a new pixmap %d\n", ++number); #endif ExaOffscreenValidate(pScreen); if (!align) align = 1; if (!size) { DBG_OFFSCREEN(("Alloc 0x%x -> EMPTY\n", size)); return NULL; } /* throw out requests that cannot fit */ if (size > (pExaScr->info->memorySize - pExaScr->info->offScreenBase)) { DBG_OFFSCREEN(("Alloc 0x%x vs (0x%lx) -> TOBIG\n", size, pExaScr->info->memorySize - pExaScr->info->offScreenBase)); return NULL; } /* Try to find a free space that'll fit. */ for (area = pExaScr->info->offScreenAreas; area; area = area->next) { /* skip allocated areas */ if (area->state != ExaOffscreenAvail) continue; /* adjust size to match alignment requirement */ real_size = size + (area->base_offset + area->size - size) % align; /* does it fit? */ if (real_size <= area->size) break; if (area->size > largest_avail) largest_avail = area->size; } if (!area) { area = exaFindAreaToEvict(pExaScr, size, align); if (!area) { DBG_OFFSCREEN(("Alloc 0x%x -> NOSPACE\n", size)); /* Could not allocate memory */ ExaOffscreenValidate(pScreen); return NULL; } /* adjust size needed to account for alignment loss for this area */ real_size = size + (area->base_offset + area->size - size) % align; /* * Kick out first area if in use */ if (area->state != ExaOffscreenAvail) area = ExaOffscreenKickOut(pScreen, area); /* * Now get the system to merge the other needed areas together */ while (area->size < real_size) { assert(area->next && area->next->state == ExaOffscreenRemovable); (void) ExaOffscreenKickOut(pScreen, area->next); } } /* save extra space in new area */ if (real_size < area->size) { ExaOffscreenArea *new_area = malloc(sizeof(ExaOffscreenArea)); if (!new_area) return NULL; new_area->base_offset = area->base_offset; new_area->offset = new_area->base_offset; new_area->align = 0; new_area->size = area->size - real_size; new_area->state = ExaOffscreenAvail; new_area->save = NULL; new_area->last_use = 0; new_area->eviction_cost = 0; new_area->next = area; new_area->prev = area->prev; if (area->prev->next) area->prev->next = new_area; else pExaScr->info->offScreenAreas = new_area; area->prev = new_area; area->base_offset = new_area->base_offset + new_area->size; area->size = real_size; } else pExaScr->numOffscreenAvailable--; /* * Mark this area as in use */ if (locked) area->state = ExaOffscreenLocked; else area->state = ExaOffscreenRemovable; area->privData = privData; area->save = save; area->last_use = pExaScr->offScreenCounter++; area->offset = (area->base_offset + align - 1); area->offset -= area->offset % align; area->align = align; ExaOffscreenValidate(pScreen); DBG_OFFSCREEN(("Alloc 0x%x -> 0x%x (0x%x)\n", size, area->base_offset, area->offset)); return area; } /** * Ejects all offscreen areas, and uninitializes the offscreen memory manager. */ void ExaOffscreenSwapOut(ScreenPtr pScreen) { ExaScreenPriv(pScreen); ExaOffscreenValidate(pScreen); /* loop until a single free area spans the space */ for (;;) { ExaOffscreenArea *area = pExaScr->info->offScreenAreas; if (!area) break; if (area->state == ExaOffscreenAvail) { area = area->next; if (!area) break; } assert(area->state != ExaOffscreenAvail); (void) ExaOffscreenKickOut(pScreen, area); ExaOffscreenValidate(pScreen); } ExaOffscreenValidate(pScreen); ExaOffscreenFini(pScreen); } /** Ejects all pixmaps managed by EXA. */ static void ExaOffscreenEjectPixmaps(ScreenPtr pScreen) { ExaScreenPriv(pScreen); ExaOffscreenValidate(pScreen); /* loop until a single free area spans the space */ for (;;) { ExaOffscreenArea *area; for (area = pExaScr->info->offScreenAreas; area != NULL; area = area->next) { if (area->state == ExaOffscreenRemovable && area->save == exaPixmapSave) { (void) ExaOffscreenKickOut(pScreen, area); ExaOffscreenValidate(pScreen); break; } } if (area == NULL) break; } ExaOffscreenValidate(pScreen); } void ExaOffscreenSwapIn(ScreenPtr pScreen) { exaOffscreenInit(pScreen); } /** * Prepares EXA for disabling of FB access, or restoring it. * * In version 2.1, the disabling results in pixmaps being ejected, while other * allocations remain. With this plus the prevention of migration while * swappedOut is set, EXA by itself should not cause any access of the * framebuffer to occur while swapped out. Any remaining issues are the * responsibility of the driver. * * Prior to version 2.1, all allocations, including locked ones, are ejected * when access is disabled, and the allocator is torn down while swappedOut * is set. This is more drastic, and caused implementation difficulties for * many drivers that could otherwise handle the lack of FB access while * swapped out. */ void exaEnableDisableFBAccess(ScreenPtr pScreen, Bool enable) { ExaScreenPriv(pScreen); if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS) return; if (!enable && pExaScr->disableFbCount++ == 0) { if (pExaScr->info->exa_minor < 1) ExaOffscreenSwapOut(pScreen); else ExaOffscreenEjectPixmaps(pScreen); pExaScr->swappedOut = TRUE; } if (enable && --pExaScr->disableFbCount == 0) { if (pExaScr->info->exa_minor < 1) ExaOffscreenSwapIn(pScreen); pExaScr->swappedOut = FALSE; } } /* merge the next free area into this one */ static void ExaOffscreenMerge(ExaScreenPrivPtr pExaScr, ExaOffscreenArea * area) { ExaOffscreenArea *next = area->next; /* account for space */ area->size += next->size; /* frob pointer */ area->next = next->next; if (area->next) area->next->prev = area; else pExaScr->info->offScreenAreas->prev = area; free(next); pExaScr->numOffscreenAvailable--; } /** * exaOffscreenFree frees an allocation. * * @param pScreen current screen * @param area offscreen area to free * * exaOffscreenFree frees an allocation created by exaOffscreenAlloc. Note that * the save callback of the area is not called, and it is up to the driver to * do any cleanup necessary as a result. * * @return pointer to the newly freed area. This behavior should not be relied * on. */ ExaOffscreenArea * exaOffscreenFree(ScreenPtr pScreen, ExaOffscreenArea * area) { ExaScreenPriv(pScreen); ExaOffscreenArea *next = area->next; ExaOffscreenArea *prev; DBG_OFFSCREEN(("Free 0x%x -> 0x%x (0x%x)\n", area->size, area->base_offset, area->offset)); ExaOffscreenValidate(pScreen); area->state = ExaOffscreenAvail; area->save = NULL; area->last_use = 0; area->eviction_cost = 0; /* * Find previous area */ if (area == pExaScr->info->offScreenAreas) prev = NULL; else prev = area->prev; pExaScr->numOffscreenAvailable++; /* link with next area if free */ if (next && next->state == ExaOffscreenAvail) ExaOffscreenMerge(pExaScr, area); /* link with prev area if free */ if (prev && prev->state == ExaOffscreenAvail) { area = prev; ExaOffscreenMerge(pExaScr, area); } ExaOffscreenValidate(pScreen); DBG_OFFSCREEN(("\tdone freeing\n")); return area; } void ExaOffscreenMarkUsed(PixmapPtr pPixmap) { ExaPixmapPriv(pPixmap); ExaScreenPriv(pPixmap->drawable.pScreen); if (!pExaPixmap || !pExaPixmap->area) return; pExaPixmap->area->last_use = pExaScr->offScreenCounter++; } /** * Defragment offscreen memory by compacting allocated areas at the end of it, * leaving the total amount of memory available as a single area at the * beginning (when there are no pinned allocations). */ _X_HIDDEN ExaOffscreenArea * ExaOffscreenDefragment(ScreenPtr pScreen) { ExaScreenPriv(pScreen); ExaOffscreenArea *area, *largest_available = NULL; int largest_size = 0; PixmapPtr pDstPix; ExaPixmapPrivPtr pExaDstPix; pDstPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, 0, 0); if (!pDstPix) return NULL; pExaDstPix = ExaGetPixmapPriv(pDstPix); pExaDstPix->use_gpu_copy = TRUE; for (area = pExaScr->info->offScreenAreas->prev; area != pExaScr->info->offScreenAreas;) { ExaOffscreenArea *prev = area->prev; PixmapPtr pSrcPix; ExaPixmapPrivPtr pExaSrcPix; Bool save_use_gpu_copy; int save_pitch; if (area->state != ExaOffscreenAvail || prev->state == ExaOffscreenLocked || (prev->state == ExaOffscreenRemovable && prev->save != exaPixmapSave)) { area = prev; continue; } if (prev->state == ExaOffscreenAvail) { if (area == largest_available) { largest_available = prev; largest_size += prev->size; } area = prev; ExaOffscreenMerge(pExaScr, area); continue; } if (area->size > largest_size) { largest_available = area; largest_size = area->size; } pSrcPix = prev->privData; pExaSrcPix = ExaGetPixmapPriv(pSrcPix); pExaDstPix->fb_ptr = pExaScr->info->memoryBase + area->base_offset + area->size - prev->size + prev->base_offset - prev->offset; pExaDstPix->fb_ptr -= (unsigned long) pExaDstPix->fb_ptr % prev->align; if (pExaDstPix->fb_ptr <= pExaSrcPix->fb_ptr) { area = prev; continue; } if (!(pExaScr->info->flags & EXA_SUPPORTS_OFFSCREEN_OVERLAPS) && (pExaSrcPix->fb_ptr + prev->size) > pExaDstPix->fb_ptr) { area = prev; continue; } save_use_gpu_copy = pExaSrcPix->use_gpu_copy; save_pitch = pSrcPix->devKind; pExaSrcPix->use_gpu_copy = TRUE; pSrcPix->devKind = pExaSrcPix->fb_pitch; pDstPix->drawable.width = pSrcPix->drawable.width; pDstPix->devKind = pSrcPix->devKind; pDstPix->drawable.height = pSrcPix->drawable.height; pDstPix->drawable.depth = pSrcPix->drawable.depth; pDstPix->drawable.bitsPerPixel = pSrcPix->drawable.bitsPerPixel; if (!pExaScr->info->PrepareCopy(pSrcPix, pDstPix, -1, -1, GXcopy, ~0)) { pExaSrcPix->use_gpu_copy = save_use_gpu_copy; pSrcPix->devKind = save_pitch; area = prev; continue; } pExaScr->info->Copy(pDstPix, 0, 0, 0, 0, pDstPix->drawable.width, pDstPix->drawable.height); pExaScr->info->DoneCopy(pDstPix); exaMarkSync(pScreen); DBG_OFFSCREEN(("Before swap: prev=0x%08x-0x%08x-0x%08x area=0x%08x-0x%08x-0x%08x\n", prev->base_offset, prev->offset, prev->base_offset + prev->size, area->base_offset, area->offset, area->base_offset + area->size)); /* Calculate swapped area offsets and sizes */ area->base_offset = prev->base_offset; area->offset = area->base_offset; prev->offset += pExaDstPix->fb_ptr - pExaSrcPix->fb_ptr; assert(prev->offset >= pExaScr->info->offScreenBase && prev->offset < pExaScr->info->memorySize); prev->base_offset = prev->offset; if (area->next) prev->size = area->next->base_offset - prev->base_offset; else prev->size = pExaScr->info->memorySize - prev->base_offset; area->size = prev->base_offset - area->base_offset; DBG_OFFSCREEN(("After swap: area=0x%08x-0x%08x-0x%08x prev=0x%08x-0x%08x-0x%08x\n", area->base_offset, area->offset, area->base_offset + area->size, prev->base_offset, prev->offset, prev->base_offset + prev->size)); /* Swap areas in list */ if (area->next) area->next->prev = prev; else pExaScr->info->offScreenAreas->prev = prev; if (prev->prev->next) prev->prev->next = area; else pExaScr->info->offScreenAreas = area; prev->next = area->next; area->next = prev; area->prev = prev->prev; prev->prev = area; if (!area->prev->next) pExaScr->info->offScreenAreas = area; #if DEBUG_OFFSCREEN if (prev->prev == prev || prev->next == prev) ErrorF("Whoops, prev points to itself!\n"); if (area->prev == area || area->next == area) ErrorF("Whoops, area points to itself!\n"); #endif pExaSrcPix->fb_ptr = pExaDstPix->fb_ptr; pExaSrcPix->use_gpu_copy = save_use_gpu_copy; pSrcPix->devKind = save_pitch; } pDstPix->drawable.width = 0; pDstPix->drawable.height = 0; pDstPix->drawable.depth = 0; pDstPix->drawable.bitsPerPixel = 0; (*pScreen->DestroyPixmap) (pDstPix); if (area->state == ExaOffscreenAvail && area->size > largest_size) return area; return largest_available; } /** * exaOffscreenInit initializes the offscreen memory manager. * * @param pScreen current screen * * exaOffscreenInit is called by exaDriverInit to set up the memory manager for * the screen, if any offscreen memory is available. */ Bool exaOffscreenInit(ScreenPtr pScreen) { ExaScreenPriv(pScreen); ExaOffscreenArea *area; /* Allocate a big free area */ area = malloc(sizeof(ExaOffscreenArea)); if (!area) return FALSE; area->state = ExaOffscreenAvail; area->base_offset = pExaScr->info->offScreenBase; area->offset = area->base_offset; area->align = 0; area->size = pExaScr->info->memorySize - area->base_offset; area->save = NULL; area->next = NULL; area->prev = area; area->last_use = 0; area->eviction_cost = 0; /* Add it to the free areas */ pExaScr->info->offScreenAreas = area; pExaScr->offScreenCounter = 1; pExaScr->numOffscreenAvailable = 1; ExaOffscreenValidate(pScreen); return TRUE; } void ExaOffscreenFini(ScreenPtr pScreen) { ExaScreenPriv(pScreen); ExaOffscreenArea *area; /* just free all of the area records */ while ((area = pExaScr->info->offScreenAreas)) { pExaScr->info->offScreenAreas = area->next; free(area); } } xorg-server-1.20.13/exa/exa_render.c0000644000175000017500000011663514100573756014143 00000000000000/* * Copyright © 2001 Keith Packard * * Partly based on code that is Copyright © 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 #endif #include #include "exa_priv.h" #include "mipict.h" #if DEBUG_TRACE_FALL static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n) { char format[20]; char size[20]; char loc; int temp; if (!pict) { snprintf(string, n, "None"); return; } switch (pict->format) { case PICT_a8r8g8b8: snprintf(format, 20, "ARGB8888"); break; case PICT_x8r8g8b8: snprintf(format, 20, "XRGB8888"); break; case PICT_b8g8r8a8: snprintf(format, 20, "BGRA8888"); break; case PICT_b8g8r8x8: snprintf(format, 20, "BGRX8888"); break; case PICT_r5g6b5: snprintf(format, 20, "RGB565 "); break; case PICT_x1r5g5b5: snprintf(format, 20, "RGB555 "); break; case PICT_a8: snprintf(format, 20, "A8 "); break; case PICT_a1: snprintf(format, 20, "A1 "); break; default: snprintf(format, 20, "0x%x", (int) pict->format); break; } if (pict->pDrawable) { loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm'; snprintf(size, 20, "%dx%d%s", pict->pDrawable->width, pict->pDrawable->height, pict->repeat ? " R" : ""); } else { loc = '-'; snprintf(size, 20, "%s", pict->repeat ? " R" : ""); } snprintf(string, n, "%p:%c fmt %s (%s)", pict->pDrawable, loc, format, size); } static void exaPrintCompositeFallback(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst) { char sop[20]; char srcdesc[40], maskdesc[40], dstdesc[40]; switch (op) { case PictOpSrc: snprintf(sop, sizeof(sop), "Src"); break; case PictOpOver: snprintf(sop, sizeof(sop), "Over"); break; default: snprintf(sop, sizeof(sop), "0x%x", (int) op); break; } exaCompositeFallbackPictDesc(pSrc, srcdesc, 40); exaCompositeFallbackPictDesc(pMask, maskdesc, 40); exaCompositeFallbackPictDesc(pDst, dstdesc, 40); ErrorF("Composite fallback: op %s, \n" " src %s, \n" " mask %s, \n" " dst %s, \n", sop, srcdesc, maskdesc, dstdesc); } #endif /* DEBUG_TRACE_FALL */ Bool exaOpReadsDestination(CARD8 op) { /* FALSE (does not read destination) is the list of ops in the protocol * document with "0" in the "Fb" column and no "Ab" in the "Fa" column. * That's just Clear and Src. ReduceCompositeOp() will already have * converted con/disjoint clear/src to Clear or Src. */ switch (op) { case PictOpClear: case PictOpSrc: return FALSE; default: return TRUE; } } static Bool exaGetPixelFromRGBA(CARD32 *pixel, CARD16 red, CARD16 green, CARD16 blue, CARD16 alpha, PictFormatPtr pFormat) { int rbits, bbits, gbits, abits; int rshift, bshift, gshift, ashift; *pixel = 0; if (!PICT_FORMAT_COLOR(pFormat->format) && PICT_FORMAT_TYPE(pFormat->format) != PICT_TYPE_A) return FALSE; rbits = PICT_FORMAT_R(pFormat->format); gbits = PICT_FORMAT_G(pFormat->format); bbits = PICT_FORMAT_B(pFormat->format); abits = PICT_FORMAT_A(pFormat->format); rshift = pFormat->direct.red; gshift = pFormat->direct.green; bshift = pFormat->direct.blue; ashift = pFormat->direct.alpha; *pixel |= (blue >> (16 - bbits)) << bshift; *pixel |= (red >> (16 - rbits)) << rshift; *pixel |= (green >> (16 - gbits)) << gshift; *pixel |= (alpha >> (16 - abits)) << ashift; return TRUE; } static Bool exaGetRGBAFromPixel(CARD32 pixel, CARD16 *red, CARD16 *green, CARD16 *blue, CARD16 *alpha, PictFormatPtr pFormat, PictFormatShort format) { int rbits, bbits, gbits, abits; int rshift, bshift, gshift, ashift; if (!PICT_FORMAT_COLOR(format) && PICT_FORMAT_TYPE(format) != PICT_TYPE_A) return FALSE; rbits = PICT_FORMAT_R(format); gbits = PICT_FORMAT_G(format); bbits = PICT_FORMAT_B(format); abits = PICT_FORMAT_A(format); if (pFormat) { rshift = pFormat->direct.red; gshift = pFormat->direct.green; bshift = pFormat->direct.blue; ashift = pFormat->direct.alpha; } else if (format == PICT_a8r8g8b8) { rshift = 16; gshift = 8; bshift = 0; ashift = 24; } else FatalError("EXA bug: exaGetRGBAFromPixel() doesn't match " "createSourcePicture()\n"); if (rbits) { *red = ((pixel >> rshift) & ((1 << rbits) - 1)) << (16 - rbits); while (rbits < 16) { *red |= *red >> rbits; rbits <<= 1; } *green = ((pixel >> gshift) & ((1 << gbits) - 1)) << (16 - gbits); while (gbits < 16) { *green |= *green >> gbits; gbits <<= 1; } *blue = ((pixel >> bshift) & ((1 << bbits) - 1)) << (16 - bbits); while (bbits < 16) { *blue |= *blue >> bbits; bbits <<= 1; } } else { *red = 0x0000; *green = 0x0000; *blue = 0x0000; } if (abits) { *alpha = ((pixel >> ashift) & ((1 << abits) - 1)) << (16 - abits); while (abits < 16) { *alpha |= *alpha >> abits; abits <<= 1; } } else *alpha = 0xffff; return TRUE; } static int exaTryDriverSolidFill(PicturePtr pSrc, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ExaScreenPriv(pDst->pDrawable->pScreen); RegionRec region; BoxPtr pbox; int nbox; int dst_off_x, dst_off_y; PixmapPtr pSrcPix, pDstPix; ExaPixmapPrivPtr pDstExaPix; CARD32 pixel; CARD16 red, green, blue, alpha; pDstPix = exaGetDrawablePixmap(pDst->pDrawable); pDstExaPix = ExaGetPixmapPriv(pDstPix); /* Check whether the accelerator can use the destination pixmap. */ if (pDstExaPix->accel_blocked) { return -1; } xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; if (pSrc->pDrawable) { xSrc += pSrc->pDrawable->x; ySrc += pSrc->pDrawable->y; } if (!miComputeCompositeRegion(®ion, pSrc, NULL, pDst, xSrc, ySrc, 0, 0, xDst, yDst, width, height)) return 1; exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); RegionTranslate(®ion, dst_off_x, dst_off_y); if (pSrc->pDrawable) { pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); pixel = exaGetPixmapFirstPixel(pSrcPix); } else miRenderColorToPixel(PictureMatchFormat(pDst->pDrawable->pScreen, 32, pSrc->format), &pSrc->pSourcePict->solidFill.fullcolor, &pixel); if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha, pSrc->pFormat, pSrc->format) || !exaGetPixelFromRGBA(&pixel, red, green, blue, alpha, pDst->pFormat)) { RegionUninit(®ion); return -1; } if (pExaScr->do_migration) { ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pDstPix; pixmaps[0].pReg = ®ion; exaDoMigration(pixmaps, 1, TRUE); } if (!exaPixmapHasGpuCopy(pDstPix)) { RegionUninit(®ion); return 0; } if (!(*pExaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel)) { RegionUninit(®ion); return -1; } nbox = RegionNumRects(®ion); pbox = RegionRects(®ion); while (nbox--) { (*pExaScr->info->Solid) (pDstPix, pbox->x1, pbox->y1, pbox->x2, pbox->y2); pbox++; } (*pExaScr->info->DoneSolid) (pDstPix); exaMarkSync(pDst->pDrawable->pScreen); RegionUninit(®ion); return 1; } static int exaTryDriverCompositeRects(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, int nrect, ExaCompositeRectPtr rects) { ExaScreenPriv(pDst->pDrawable->pScreen); int src_off_x = 0, src_off_y = 0, mask_off_x = 0, mask_off_y = 0; int dst_off_x, dst_off_y; PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix; ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix; if (!pExaScr->info->PrepareComposite) return -1; if (pSrc->pDrawable) { pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); pSrcExaPix = ExaGetPixmapPriv(pSrcPix); } if (pMask && pMask->pDrawable) { pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); pMaskExaPix = ExaGetPixmapPriv(pMaskPix); } pDstPix = exaGetDrawablePixmap(pDst->pDrawable); pDstExaPix = ExaGetPixmapPriv(pDstPix); /* Check whether the accelerator can use these pixmaps. * FIXME: If it cannot, use temporary pixmaps so that the drawing * happens within limits. */ if (pDstExaPix->accel_blocked || (pSrcExaPix && pSrcExaPix->accel_blocked) || (pMaskExaPix && pMaskExaPix->accel_blocked)) { return -1; } if (pExaScr->info->CheckComposite && !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) { return -1; } if (pExaScr->do_migration) { ExaMigrationRec pixmaps[3]; int i = 0; pixmaps[i].as_dst = TRUE; pixmaps[i].as_src = exaOpReadsDestination(op); pixmaps[i].pPix = pDstPix; pixmaps[i].pReg = NULL; i++; if (pSrcPix) { pixmaps[i].as_dst = FALSE; pixmaps[i].as_src = TRUE; pixmaps[i].pPix = pSrcPix; pixmaps[i].pReg = NULL; i++; } if (pMaskPix) { pixmaps[i].as_dst = FALSE; pixmaps[i].as_src = TRUE; pixmaps[i].pPix = pMaskPix; pixmaps[i].pReg = NULL; i++; } exaDoMigration(pixmaps, i, TRUE); } pDstPix = exaGetOffscreenPixmap(pDst->pDrawable, &dst_off_x, &dst_off_y); if (!pDstPix) return 0; if (pSrcPix) { pSrcPix = exaGetOffscreenPixmap(pSrc->pDrawable, &src_off_x, &src_off_y); if (!pSrcPix) return 0; } if (pMaskPix) { pMaskPix = exaGetOffscreenPixmap(pMask->pDrawable, &mask_off_x, &mask_off_y); if (!pMaskPix) return 0; } if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix, pMaskPix, pDstPix)) return -1; while (nrect--) { INT16 xDst = rects->xDst + pDst->pDrawable->x; INT16 yDst = rects->yDst + pDst->pDrawable->y; INT16 xMask = rects->xMask; INT16 yMask = rects->yMask; INT16 xSrc = rects->xSrc; INT16 ySrc = rects->ySrc; RegionRec region; BoxPtr pbox; int nbox; if (pMaskPix) { xMask += pMask->pDrawable->x; yMask += pMask->pDrawable->y; } if (pSrcPix) { xSrc += pSrc->pDrawable->x; ySrc += pSrc->pDrawable->y; } if (!miComputeCompositeRegion(®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, rects->width, rects->height)) goto next_rect; RegionTranslate(®ion, dst_off_x, dst_off_y); nbox = RegionNumRects(®ion); pbox = RegionRects(®ion); xMask = xMask + mask_off_x - xDst - dst_off_x; yMask = yMask + mask_off_y - yDst - dst_off_y; xSrc = xSrc + src_off_x - xDst - dst_off_x; ySrc = ySrc + src_off_y - yDst - dst_off_y; while (nbox--) { (*pExaScr->info->Composite) (pDstPix, pbox->x1 + xSrc, pbox->y1 + ySrc, pbox->x1 + xMask, pbox->y1 + yMask, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } next_rect: RegionUninit(®ion); rects++; } (*pExaScr->info->DoneComposite) (pDstPix); exaMarkSync(pDst->pDrawable->pScreen); return 1; } /** * Copy a number of rectangles from source to destination in a single * operation. This is specialized for glyph rendering: we don't have the * special-case fallbacks found in exaComposite() - if the driver can support * it, we use the driver functionality, otherwise we fall back straight to * software. */ void exaCompositeRects(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, int nrect, ExaCompositeRectPtr rects) { ExaScreenPriv(pDst->pDrawable->pScreen); int n; ExaCompositeRectPtr r; int ret; /* If we get a mask, that means we're rendering to the exaGlyphs * destination directly, so the damage layer takes care of this. */ if (!pMask) { RegionRec region; int x1 = MAXSHORT; int y1 = MAXSHORT; int x2 = MINSHORT; int y2 = MINSHORT; BoxRec box; /* We have to manage the damage ourselves, since CompositeRects isn't * something in the screen that can be managed by the damage extension, * and EXA depends on damage to track what needs to be migrated between * the gpu and the cpu. */ /* Compute the overall extents of the composited region - we're making * the assumption here that we are compositing a bunch of glyphs that * cluster closely together and damaging each glyph individually would * be a loss compared to damaging the bounding box. */ n = nrect; r = rects; while (n--) { int rect_x2 = r->xDst + r->width; int rect_y2 = r->yDst + r->height; if (r->xDst < x1) x1 = r->xDst; if (r->yDst < y1) y1 = r->yDst; if (rect_x2 > x2) x2 = rect_x2; if (rect_y2 > y2) y2 = rect_y2; r++; } if (x2 <= x1 || y2 <= y1) return; box.x1 = x1; box.x2 = x2 < MAXSHORT ? x2 : MAXSHORT; box.y1 = y1; box.y2 = y2 < MAXSHORT ? y2 : MAXSHORT; /* The pixmap migration code relies on pendingDamage indicating * the bounds of the current rendering, so we need to force * the actual damage into that region before we do anything, and * (see use of DamagePendingRegion in exaCopyDirty) */ RegionInit(®ion, &box, 1); DamageRegionAppend(pDst->pDrawable, ®ion); RegionUninit(®ion); } /************************************************************/ ValidatePicture(pSrc); if (pMask) ValidatePicture(pMask); ValidatePicture(pDst); ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect, rects); if (ret != 1) { if (ret == -1 && op == PictOpOver && pMask && pMask->componentAlpha && (!pExaScr->info->CheckComposite || ((*pExaScr->info->CheckComposite) (PictOpOutReverse, pSrc, pMask, pDst) && (*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, pMask, pDst)))) { ret = exaTryDriverCompositeRects(PictOpOutReverse, pSrc, pMask, pDst, nrect, rects); if (ret == 1) { op = PictOpAdd; ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect, rects); } } if (ret != 1) { n = nrect; r = rects; while (n--) { ExaCheckComposite(op, pSrc, pMask, pDst, r->xSrc, r->ySrc, r->xMask, r->yMask, r->xDst, r->yDst, r->width, r->height); r++; } } } /************************************************************/ if (!pMask) { /* Now we have to flush the damage out from pendingDamage => damage * Calling DamageRegionProcessPending has that effect. */ DamageRegionProcessPending(pDst->pDrawable); } } static int exaTryDriverComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ExaScreenPriv(pDst->pDrawable->pScreen); RegionRec region; BoxPtr pbox; int nbox; int src_off_x, src_off_y, mask_off_x = 0, mask_off_y = 0, dst_off_x, dst_off_y; PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix; ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix; if (pSrc->pDrawable) { pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); pSrcExaPix = ExaGetPixmapPriv(pSrcPix); } pDstPix = exaGetDrawablePixmap(pDst->pDrawable); pDstExaPix = ExaGetPixmapPriv(pDstPix); if (pMask && pMask->pDrawable) { pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); pMaskExaPix = ExaGetPixmapPriv(pMaskPix); } /* Check whether the accelerator can use these pixmaps. * FIXME: If it cannot, use temporary pixmaps so that the drawing * happens within limits. */ if (pDstExaPix->accel_blocked || (pSrcExaPix && pSrcExaPix->accel_blocked) || (pMaskExaPix && (pMaskExaPix->accel_blocked))) { return -1; } xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; if (pMaskPix) { xMask += pMask->pDrawable->x; yMask += pMask->pDrawable->y; } if (pSrcPix) { xSrc += pSrc->pDrawable->x; ySrc += pSrc->pDrawable->y; } if (pExaScr->info->CheckComposite && !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) { return -1; } if (!miComputeCompositeRegion(®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) return 1; exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); RegionTranslate(®ion, dst_off_x, dst_off_y); if (pExaScr->do_migration) { ExaMigrationRec pixmaps[3]; int i = 0; pixmaps[i].as_dst = TRUE; pixmaps[i].as_src = exaOpReadsDestination(op); pixmaps[i].pPix = pDstPix; pixmaps[i].pReg = pixmaps[0].as_src ? NULL : ®ion; i++; if (pSrcPix) { pixmaps[i].as_dst = FALSE; pixmaps[i].as_src = TRUE; pixmaps[i].pPix = pSrcPix; pixmaps[i].pReg = NULL; i++; } if (pMaskPix) { pixmaps[i].as_dst = FALSE; pixmaps[i].as_src = TRUE; pixmaps[i].pPix = pMaskPix; pixmaps[i].pReg = NULL; i++; } exaDoMigration(pixmaps, i, TRUE); } if (pSrcPix) { pSrcPix = exaGetOffscreenPixmap(pSrc->pDrawable, &src_off_x, &src_off_y); if (!pSrcPix) { RegionUninit(®ion); return 0; } } if (pMaskPix) { pMaskPix = exaGetOffscreenPixmap(pMask->pDrawable, &mask_off_x, &mask_off_y); if (!pMaskPix) { RegionUninit(®ion); return 0; } } if (!exaPixmapHasGpuCopy(pDstPix)) { RegionUninit(®ion); return 0; } if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix, pMaskPix, pDstPix)) { RegionUninit(®ion); return -1; } nbox = RegionNumRects(®ion); pbox = RegionRects(®ion); xMask = xMask + mask_off_x - xDst - dst_off_x; yMask = yMask + mask_off_y - yDst - dst_off_y; xSrc = xSrc + src_off_x - xDst - dst_off_x; ySrc = ySrc + src_off_y - yDst - dst_off_y; while (nbox--) { (*pExaScr->info->Composite) (pDstPix, pbox->x1 + xSrc, pbox->y1 + ySrc, pbox->x1 + xMask, pbox->y1 + yMask, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } (*pExaScr->info->DoneComposite) (pDstPix); exaMarkSync(pDst->pDrawable->pScreen); RegionUninit(®ion); return 1; } /** * exaTryMagicTwoPassCompositeHelper implements PictOpOver using two passes of * simpler operations PictOpOutReverse and PictOpAdd. Mainly used for component * alpha and limited 1-tmu cards. * * From http://anholt.livejournal.com/32058.html: * * The trouble is that component-alpha rendering requires two different sources * for blending: one for the source value to the blender, which is the * per-channel multiplication of source and mask, and one for the source alpha * for multiplying with the destination channels, which is the multiplication * of the source channels by the mask alpha. So the equation for Over is: * * dst.A = src.A * mask.A + (1 - (src.A * mask.A)) * dst.A * dst.R = src.R * mask.R + (1 - (src.A * mask.R)) * dst.R * dst.G = src.G * mask.G + (1 - (src.A * mask.G)) * dst.G * dst.B = src.B * mask.B + (1 - (src.A * mask.B)) * dst.B * * But we can do some simpler operations, right? How about PictOpOutReverse, * which has a source factor of 0 and dest factor of (1 - source alpha). We * can get the source alpha value (srca.X = src.A * mask.X) out of the texture * blenders pretty easily. So we can do a component-alpha OutReverse, which * gets us: * * dst.A = 0 + (1 - (src.A * mask.A)) * dst.A * dst.R = 0 + (1 - (src.A * mask.R)) * dst.R * dst.G = 0 + (1 - (src.A * mask.G)) * dst.G * dst.B = 0 + (1 - (src.A * mask.B)) * dst.B * * OK. And if an op doesn't use the source alpha value for the destination * factor, then we can do the channel multiplication in the texture blenders * to get the source value, and ignore the source alpha that we wouldn't use. * We've supported this in the Radeon driver for a long time. An example would * be PictOpAdd, which does: * * dst.A = src.A * mask.A + dst.A * dst.R = src.R * mask.R + dst.R * dst.G = src.G * mask.G + dst.G * dst.B = src.B * mask.B + dst.B * * Hey, this looks good! If we do a PictOpOutReverse and then a PictOpAdd right * after it, we get: * * dst.A = src.A * mask.A + ((1 - (src.A * mask.A)) * dst.A) * dst.R = src.R * mask.R + ((1 - (src.A * mask.R)) * dst.R) * dst.G = src.G * mask.G + ((1 - (src.A * mask.G)) * dst.G) * dst.B = src.B * mask.B + ((1 - (src.A * mask.B)) * dst.B) */ static int exaTryMagicTwoPassCompositeHelper(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ExaScreenPriv(pDst->pDrawable->pScreen); assert(op == PictOpOver); if (pExaScr->info->CheckComposite && (!(*pExaScr->info->CheckComposite) (PictOpOutReverse, pSrc, pMask, pDst) || !(*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, pMask, pDst))) { return -1; } /* Now, we think we should be able to accelerate this operation. First, * composite the destination to be the destination times the source alpha * factors. */ exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); /* Then, add in the source value times the destination alpha factors (1.0). */ exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); return 1; } void exaComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ExaScreenPriv(pDst->pDrawable->pScreen); int ret = -1; Bool saveSrcRepeat = pSrc->repeat; Bool saveMaskRepeat = pMask ? pMask->repeat : 0; RegionRec region; if (pExaScr->swappedOut) goto fallback; /* Remove repeat in source if useless */ if (pSrc->pDrawable && pSrc->repeat && !pSrc->transform && xSrc >= 0 && (xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 && (ySrc + height) <= pSrc->pDrawable->height) pSrc->repeat = 0; if (!pMask && !pSrc->alphaMap && !pDst->alphaMap && (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format)))) { if (pSrc->pDrawable ? (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && pSrc->repeat) : (pSrc->pSourcePict->type == SourcePictTypeSolidFill)) { ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height); if (ret == 1) goto done; } else if (pSrc->pDrawable && !pSrc->transform && ((op == PictOpSrc && (pSrc->format == pDst->format || (PICT_FORMAT_COLOR(pDst->format) && PICT_FORMAT_COLOR(pSrc->format) && pDst->format == PICT_FORMAT(PICT_FORMAT_BPP(pSrc->format), PICT_FORMAT_TYPE(pSrc->format), 0, PICT_FORMAT_R(pSrc->format), PICT_FORMAT_G(pSrc->format), PICT_FORMAT_B(pSrc->format))))) || (op == PictOpOver && pSrc->format == pDst->format && !PICT_FORMAT_A(pSrc->format)))) { if (!pSrc->repeat && xSrc >= 0 && ySrc >= 0 && (xSrc + width <= pSrc->pDrawable->width) && (ySrc + height <= pSrc->pDrawable->height)) { Bool suc; xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x; ySrc += pSrc->pDrawable->y; if (!miComputeCompositeRegion(®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) goto done; suc = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL, RegionRects(®ion), RegionNumRects(®ion), xSrc - xDst, ySrc - yDst, FALSE, FALSE); RegionUninit(®ion); /* Reset values to their original values. */ xDst -= pDst->pDrawable->x; yDst -= pDst->pDrawable->y; xSrc -= pSrc->pDrawable->x; ySrc -= pSrc->pDrawable->y; if (!suc) goto fallback; goto done; } if (pSrc->repeat && pSrc->repeatType == RepeatNormal && pSrc->pDrawable->type == DRAWABLE_PIXMAP) { DDXPointRec patOrg; /* Let's see if the driver can do the repeat in one go */ if (pExaScr->info->PrepareComposite && !pSrc->alphaMap && !pDst->alphaMap) { ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); if (ret == 1) goto done; } /* Now see if we can use exaFillRegionTiled() */ xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x; ySrc += pSrc->pDrawable->y; if (!miComputeCompositeRegion(®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) goto done; /* pattern origin is the point in the destination drawable * corresponding to (0,0) in the source */ patOrg.x = xDst - xSrc; patOrg.y = yDst - ySrc; ret = exaFillRegionTiled(pDst->pDrawable, ®ion, (PixmapPtr) pSrc->pDrawable, &patOrg, FB_ALLONES, GXcopy, CT_NONE); RegionUninit(®ion); if (ret) goto done; /* Let's be correct and restore the variables to their original state. */ xDst -= pDst->pDrawable->x; yDst -= pDst->pDrawable->y; xSrc -= pSrc->pDrawable->x; ySrc -= pSrc->pDrawable->y; } } } /* Remove repeat in mask if useless */ if (pMask && pMask->pDrawable && pMask->repeat && !pMask->transform && xMask >= 0 && (xMask + width) <= pMask->pDrawable->width && yMask >= 0 && (yMask + height) <= pMask->pDrawable->height) pMask->repeat = 0; if (pExaScr->info->PrepareComposite && !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap) { Bool isSrcSolid; ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); if (ret == 1) goto done; /* For generic masks and solid src pictures, mach64 can do Over in two * passes, similar to the component-alpha case. */ isSrcSolid = pSrc->pDrawable ? (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && pSrc->repeat) : (pSrc->pSourcePict->type == SourcePictTypeSolidFill); /* If we couldn't do the Composite in a single pass, and it was a * component-alpha Over, see if we can do it in two passes with * an OutReverse and then an Add. */ if (ret == -1 && op == PictOpOver && pMask && (pMask->componentAlpha || isSrcSolid)) { ret = exaTryMagicTwoPassCompositeHelper(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); if (ret == 1) goto done; } } fallback: #if DEBUG_TRACE_FALL exaPrintCompositeFallback(op, pSrc, pMask, pDst); #endif ExaCheckComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); done: pSrc->repeat = saveSrcRepeat; if (pMask) pMask->repeat = saveMaskRepeat; } /** * Same as miCreateAlphaPicture, except it uses ExaCheckPolyFillRect instead * of PolyFillRect to initialize the pixmap after creating it, to prevent * the pixmap from being migrated. * * See the comments about exaTrapezoids and exaTriangles. */ static PicturePtr exaCreateAlphaPicture(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; ExaCheckPolyFillRect(&pPixmap->drawable, pGC, 1, &rect); exaPixmapDirty(pPixmap, 0, 0, width, height); FreeScratchGC(pGC); pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat, 0, 0, serverClient, &error); (*pScreen->DestroyPixmap) (pPixmap); return pPicture; } /** * exaTrapezoids is essentially a copy of miTrapezoids that uses * exaCreateAlphaPicture instead of miCreateAlphaPicture. * * The problem with miCreateAlphaPicture is that it calls PolyFillRect * to initialize the contents after creating the pixmap, which * causes the pixmap to be moved in for acceleration. The subsequent * call to RasterizeTrapezoid won't be accelerated however, which * forces the pixmap to be moved out again. * * exaCreateAlphaPicture avoids this roundtrip by using ExaCheckPolyFillRect * to initialize the contents. */ void exaTrapezoids(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); BoxRec bounds; if (maskFormat) { PicturePtr pPicture; INT16 xDst, yDst; INT16 xRel, yRel; miTrapezoidBounds(ntrap, traps, &bounds); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; xDst = traps[0].left.p1.x >> 16; yDst = traps[0].left.p1.y >> 16; pPicture = exaCreateAlphaPicture(pScreen, pDst, maskFormat, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); if (!pPicture) return; exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); for (; ntrap; ntrap--, traps++) if (xTrapezoidValid(traps)) (*ps->RasterizeTrapezoid) (pPicture, traps, -bounds.x1, -bounds.y1); exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); 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++) exaTrapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps); } } /** * exaTriangles is essentially a copy of miTriangles that uses * exaCreateAlphaPicture instead of miCreateAlphaPicture. * * The problem with miCreateAlphaPicture is that it calls PolyFillRect * to initialize the contents after creating the pixmap, which * causes the pixmap to be moved in for acceleration. The subsequent * call to AddTriangles won't be accelerated however, which forces the pixmap * to be moved out again. * * exaCreateAlphaPicture avoids this roundtrip by using ExaCheckPolyFillRect * to initialize the contents. */ void exaTriangles(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); BoxRec bounds; if (maskFormat) { PicturePtr pPicture; INT16 xDst, yDst; INT16 xRel, yRel; miTriangleBounds(ntri, tris, &bounds); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; xDst = tris[0].p1.x >> 16; yDst = tris[0].p1.y >> 16; pPicture = exaCreateAlphaPicture(pScreen, pDst, maskFormat, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); if (!pPicture) return; exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris); exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); 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++) exaTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris); } } xorg-server-1.20.13/exa/exa_priv.h0000644000175000017500000005002214100573756013634 00000000000000/* * * Copyright (C) 2000 Keith Packard, member of The XFree86 Project, Inc. * 2005 Zack Rusin, Trolltech * * 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. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #ifndef EXAPRIV_H #define EXAPRIV_H #ifdef HAVE_DIX_CONFIG_H #include #endif #include "exa.h" #include #include #ifdef MITSHM #include "shmint.h" #endif #include "scrnintstr.h" #include "pixmapstr.h" #include "windowstr.h" #include "servermd.h" #include "colormapst.h" #include "gcstruct.h" #include "input.h" #include "mipointer.h" #include "mi.h" #include "dix.h" #include "fb.h" #include "fboverlay.h" #include "fbpict.h" #include "glyphstr.h" #include "damage.h" #define DEBUG_TRACE_FALL 0 #define DEBUG_MIGRATE 0 #define DEBUG_PIXMAP 0 #define DEBUG_OFFSCREEN 0 #define DEBUG_GLYPH_CACHE 0 #if DEBUG_TRACE_FALL #define EXA_FALLBACK(x) \ do { \ ErrorF("EXA fallback at %s: ", __FUNCTION__); \ ErrorF x; \ } while (0) char exaDrawableLocation(DrawablePtr pDrawable); #else #define EXA_FALLBACK(x) #endif #if DEBUG_PIXMAP #define DBG_PIXMAP(a) ErrorF a #else #define DBG_PIXMAP(a) #endif #ifndef EXA_MAX_FB #define EXA_MAX_FB FB_OVERLAY_MAX #endif #ifdef DEBUG #define EXA_FatalErrorDebug(x) FatalError x #define EXA_FatalErrorDebugWithRet(x, ret) FatalError x #else #define EXA_FatalErrorDebug(x) ErrorF x #define EXA_FatalErrorDebugWithRet(x, ret) \ do { \ ErrorF x; \ return ret; \ } while (0) #endif /** * This is the list of migration heuristics supported by EXA. See * exaDoMigration() for what their implementations do. */ enum ExaMigrationHeuristic { ExaMigrationGreedy, ExaMigrationAlways, ExaMigrationSmart }; typedef struct { unsigned char sha1[20]; } ExaCachedGlyphRec, *ExaCachedGlyphPtr; typedef struct { /* The identity of the cache, statically configured at initialization */ unsigned int format; int glyphWidth; int glyphHeight; int size; /* Size of cache; eventually this should be dynamically determined */ /* Hash table mapping from glyph sha1 to position in the glyph; we use * open addressing with a hash table size determined based on size and large * enough so that we always have a good amount of free space, so we can * use linear probing. (Linear probing is preferrable to double hashing * here because it allows us to easily remove entries.) */ int *hashEntries; int hashSize; ExaCachedGlyphPtr glyphs; int glyphCount; /* Current number of glyphs */ PicturePtr picture; /* Where the glyphs of the cache are stored */ int yOffset; /* y location within the picture where the cache starts */ int columns; /* Number of columns the glyphs are layed out in */ int evictionPosition; /* Next random position to evict a glyph */ } ExaGlyphCacheRec, *ExaGlyphCachePtr; #define EXA_NUM_GLYPH_CACHES 4 #define EXA_FALLBACK_COPYWINDOW (1 << 0) #define EXA_ACCEL_COPYWINDOW (1 << 1) typedef struct _ExaMigrationRec { Bool as_dst; Bool as_src; PixmapPtr pPix; RegionPtr pReg; } ExaMigrationRec, *ExaMigrationPtr; typedef void (*EnableDisableFBAccessProcPtr) (ScreenPtr, Bool); typedef struct { ExaDriverPtr info; ScreenBlockHandlerProcPtr SavedBlockHandler; ScreenWakeupHandlerProcPtr SavedWakeupHandler; CreateGCProcPtr SavedCreateGC; CloseScreenProcPtr SavedCloseScreen; GetImageProcPtr SavedGetImage; GetSpansProcPtr SavedGetSpans; CreatePixmapProcPtr SavedCreatePixmap; DestroyPixmapProcPtr SavedDestroyPixmap; CopyWindowProcPtr SavedCopyWindow; ChangeWindowAttributesProcPtr SavedChangeWindowAttributes; BitmapToRegionProcPtr SavedBitmapToRegion; CreateScreenResourcesProcPtr SavedCreateScreenResources; ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader; SharePixmapBackingProcPtr SavedSharePixmapBacking; SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking; SourceValidateProcPtr SavedSourceValidate; CompositeProcPtr SavedComposite; TrianglesProcPtr SavedTriangles; GlyphsProcPtr SavedGlyphs; TrapezoidsProcPtr SavedTrapezoids; AddTrapsProcPtr SavedAddTraps; void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap); void (*do_move_in_pixmap) (PixmapPtr pPixmap); void (*do_move_out_pixmap) (PixmapPtr pPixmap); void (*prepare_access_reg) (PixmapPtr pPixmap, int index, RegionPtr pReg); Bool swappedOut; enum ExaMigrationHeuristic migration; Bool checkDirtyCorrectness; unsigned disableFbCount; Bool optimize_migration; unsigned offScreenCounter; unsigned numOffscreenAvailable; CARD32 lastDefragment; CARD32 nextDefragment; PixmapPtr deferred_mixed_pixmap; /* Reference counting for accessed pixmaps */ struct { PixmapPtr pixmap; int count; Bool retval; } access[EXA_NUM_PREPARE_INDICES]; /* Holds information on fallbacks that cannot be relayed otherwise. */ unsigned int fallback_flags; unsigned int fallback_counter; ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES]; /** * Regions affected by fallback composite source / mask operations. */ RegionRec srcReg; RegionRec maskReg; PixmapPtr srcPix; PixmapPtr maskPix; DevPrivateKeyRec pixmapPrivateKeyRec; DevPrivateKeyRec gcPrivateKeyRec; } ExaScreenPrivRec, *ExaScreenPrivPtr; extern DevPrivateKeyRec exaScreenPrivateKeyRec; #define exaScreenPrivateKey (&exaScreenPrivateKeyRec) #define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixGetPrivate(&(s)->devPrivates, exaScreenPrivateKey)) #define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s) #define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixGetPrivateAddr(&(gc)->devPrivates, &ExaGetScreenPriv(gc->pScreen)->gcPrivateKeyRec)) #define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc) /* * Some macros to deal with function wrapping. */ #define wrap(priv, real, mem, func) {\ priv->Saved##mem = real->mem; \ real->mem = func; \ } #define unwrap(priv, real, mem) {\ real->mem = priv->Saved##mem; \ } #ifdef HAVE_TYPEOF #define swap(priv, real, mem) {\ typeof(real->mem) tmp = priv->Saved##mem; \ priv->Saved##mem = real->mem; \ real->mem = tmp; \ } #else #define swap(priv, real, mem) {\ const void *tmp = priv->Saved##mem; \ priv->Saved##mem = real->mem; \ real->mem = tmp; \ } #endif #define EXA_PRE_FALLBACK(_screen_) \ ExaScreenPriv(_screen_); \ pExaScr->fallback_counter++; #define EXA_POST_FALLBACK(_screen_) \ pExaScr->fallback_counter--; #define EXA_PRE_FALLBACK_GC(_gc_) \ ExaScreenPriv(_gc_->pScreen); \ ExaGCPriv(_gc_); \ pExaScr->fallback_counter++; \ swap(pExaGC, _gc_, ops); #define EXA_POST_FALLBACK_GC(_gc_) \ pExaScr->fallback_counter--; \ swap(pExaGC, _gc_, ops); /** Align an offset to an arbitrary alignment */ #define EXA_ALIGN(offset, align) (((offset) + (align) - 1) - \ (((offset) + (align) - 1) % (align))) /** Align an offset to a power-of-two alignment */ #define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1)) #define EXA_PIXMAP_SCORE_MOVE_IN 10 #define EXA_PIXMAP_SCORE_MAX 20 #define EXA_PIXMAP_SCORE_MOVE_OUT -10 #define EXA_PIXMAP_SCORE_MIN -20 #define EXA_PIXMAP_SCORE_PINNED 1000 #define EXA_PIXMAP_SCORE_INIT 1001 #define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &ExaGetScreenPriv((p)->drawable.pScreen)->pixmapPrivateKeyRec)) #define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p) #define EXA_RANGE_PITCH (1 << 0) #define EXA_RANGE_WIDTH (1 << 1) #define EXA_RANGE_HEIGHT (1 << 2) typedef struct { ExaOffscreenArea *area; int score; /**< score for the move-in vs move-out heuristic */ Bool use_gpu_copy; CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */ int sys_pitch; /**< pitch of pixmap in system memory */ CARD8 *fb_ptr; /**< pointer to pixmap data in framebuffer memory */ int fb_pitch; /**< pitch of pixmap in framebuffer memory */ unsigned int fb_size; /**< size of pixmap in framebuffer memory */ /** * Holds information about whether this pixmap can be used for * acceleration (== 0) or not (> 0). * * Contains a OR'ed combination of the following values: * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range * EXA_RANGE_WIDTH - set if the pixmap's width is out of range * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range */ unsigned int accel_blocked; /** * The damage record contains the areas of the pixmap's current location * (framebuffer or system) that have been damaged compared to the other * location. */ DamagePtr pDamage; /** * The valid regions mark the valid bits (at least, as they're derived from * damage, which may be overreported) of a pixmap's system and FB copies. */ RegionRec validSys, validFB; /** * Driver private storage per EXA pixmap */ void *driverPriv; } ExaPixmapPrivRec, *ExaPixmapPrivPtr; typedef struct { /* GC values from the layer below. */ const GCOps *Savedops; const GCFuncs *Savedfuncs; } ExaGCPrivRec, *ExaGCPrivPtr; typedef struct { PicturePtr pDst; INT16 xSrc; INT16 ySrc; INT16 xMask; INT16 yMask; INT16 xDst; INT16 yDst; INT16 width; INT16 height; } ExaCompositeRectRec, *ExaCompositeRectPtr; /** * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place * to set EXA options or hook in screen functions to handle using EXA as the AA. */ void exaDDXDriverInit(ScreenPtr pScreen); /* exa_unaccel.c */ void exaPrepareAccessGC(GCPtr pGC); void exaFinishAccessGC(GCPtr pGC); void ExaCheckFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nspans, DDXPointPtr ppt, int *pwidth, int fSorted); void ExaCheckSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); void ExaCheckPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits); void ExaCheckCopyNtoN(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); RegionPtr ExaCheckCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty); RegionPtr ExaCheckCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane); void ExaCheckPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit); void ExaCheckPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt); void ExaCheckPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nsegInit, xSegment * pSegInit); void ExaCheckPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs); void ExaCheckPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect); void ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase); void ExaCheckPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase); void ExaCheckPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y); void ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); void ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); void ExaCheckGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart); void ExaCheckAddTraps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap * traps); /* exa_accel.c */ static _X_INLINE Bool exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask, unsigned int fillStyle, unsigned char alu, Bool clientClip) { return ((alu != GXcopy && alu != GXclear && alu != GXset && alu != GXcopyInverted) || fillStyle == FillStippled || clientClip != FALSE || !EXA_PM_IS_SOLID(pDrawable, planemask)); } void exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); Bool exaFillRegionTiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu, Bool clientClip); void exaGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); RegionPtr exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty); Bool exaHWCopyNtoN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown); void exaCopyNtoN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); extern const GCOps exaOps; void ExaCheckComposite(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 ExaCheckGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs); /* exa_offscreen.c */ void ExaOffscreenSwapOut(ScreenPtr pScreen); void ExaOffscreenSwapIn(ScreenPtr pScreen); ExaOffscreenArea *ExaOffscreenDefragment(ScreenPtr pScreen); Bool exaOffscreenInit(ScreenPtr pScreen); void ExaOffscreenFini(ScreenPtr pScreen); /* exa.c */ Bool ExaDoPrepareAccess(PixmapPtr pPixmap, int index); void exaPrepareAccess(DrawablePtr pDrawable, int index); void exaFinishAccess(DrawablePtr pDrawable, int index); void exaDestroyPixmap(PixmapPtr pPixmap); void exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2); void exaGetDrawableDeltas(DrawablePtr pDrawable, PixmapPtr pPixmap, int *xp, int *yp); Bool exaPixmapHasGpuCopy(PixmapPtr p); PixmapPtr exaGetOffscreenPixmap(DrawablePtr pDrawable, int *xp, int *yp); PixmapPtr exaGetDrawablePixmap(DrawablePtr pDrawable); void exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, int w, int h, int bpp); void exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, int w, int h, int bpp); void exaDoMigration(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); Bool exaPixmapIsPinned(PixmapPtr pPix); extern const GCFuncs exaGCFuncs; /* exa_classic.c */ PixmapPtr exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint); Bool exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, void *pPixData); Bool exaDestroyPixmap_classic(PixmapPtr pPixmap); Bool exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap); /* exa_driver.c */ PixmapPtr exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint); Bool exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, void *pPixData); Bool exaDestroyPixmap_driver(PixmapPtr pPixmap); Bool exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap); /* exa_mixed.c */ PixmapPtr exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint); Bool exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, void *pPixData); Bool exaDestroyPixmap_mixed(PixmapPtr pPixmap); Bool exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap); /* exa_migration_mixed.c */ void exaCreateDriverPixmap_mixed(PixmapPtr pPixmap); void exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); void exaMoveInPixmap_mixed(PixmapPtr pPixmap); void exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure); void exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg); Bool exaSetSharedPixmapBacking_mixed(PixmapPtr pPixmap, void *handle); Bool exaSharePixmapBacking_mixed(PixmapPtr pPixmap, ScreenPtr slave, void **handle_p); /* exa_render.c */ Bool exaOpReadsDestination(CARD8 op); void exaComposite(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 exaCompositeRects(CARD8 op, PicturePtr Src, PicturePtr pMask, PicturePtr pDst, int nrect, ExaCompositeRectPtr rects); void exaTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps); void exaTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntri, xTriangle * tris); /* exa_glyph.c */ void exaGlyphsInit(ScreenPtr pScreen); void exaGlyphsFini(ScreenPtr pScreen); void exaGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs); /* exa_migration_classic.c */ void exaCopyDirtyToSys(ExaMigrationPtr migrate); void exaCopyDirtyToFb(ExaMigrationPtr migrate); void exaDoMigration_classic(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); void exaPixmapSave(ScreenPtr pScreen, ExaOffscreenArea * area); void exaMoveOutPixmap_classic(PixmapPtr pPixmap); void exaMoveInPixmap_classic(PixmapPtr pPixmap); void exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg); #endif /* EXAPRIV_H */ xorg-server-1.20.13/exa/exa_unaccel.c0000644000175000017500000006115014100573756014265 00000000000000/* * * 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. */ #include "exa_priv.h" #include "mipict.h" /* * These functions wrap the low-level fb rendering functions and * synchronize framebuffer/accelerated drawing by stalling until * the accelerator is idle */ /** * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the * current fill style. * * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are * 1bpp and never in fb, so we don't worry about them. * We should worry about them for completeness sake and going forward. */ void exaPrepareAccessGC(GCPtr pGC) { if (pGC->stipple) exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); if (pGC->fillStyle == FillTiled) exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC); } /** * Finishes access to the tile in the GC, if used. */ void exaFinishAccessGC(GCPtr pGC) { if (pGC->fillStyle == FillTiled) exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC); if (pGC->stipple) exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); } #if DEBUG_TRACE_FALL char exaDrawableLocation(DrawablePtr pDrawable) { return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm'; } #endif /* DEBUG_TRACE_FALL */ void ExaCheckFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nspans, DDXPointPtr ppt, int *pwidth, int fSorted) { EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); exaPrepareAccessGC(pGC); pGC->ops->FillSpans(pDrawable, pGC, nspans, ppt, pwidth, fSorted); exaFinishAccessGC(pGC); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) { EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); pGC->ops->SetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); ExaPixmapPriv(pPixmap); EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage || exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, pGC->alu, pGC->clientClip != NULL)) exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); else pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, DamagePendingRegion(pExaPixmap->pDamage)); pGC->ops->PutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckCopyNtoN(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { RegionRec reg; int xoff, yoff; EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); if (pExaScr->prepare_access_reg && RegionInitBoxes(®, pbox, nbox)) { PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc); exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff); RegionTranslate(®, xoff + dx, yoff + dy); pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®); RegionUninit(®); } else exaPrepareAccess(pSrc, EXA_PREPARE_SRC); if (pExaScr->prepare_access_reg && !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle, pGC->alu, pGC->clientClip != NULL) && RegionInitBoxes(®, pbox, nbox)) { PixmapPtr pPixmap = exaGetDrawablePixmap(pDst); exaGetDrawableDeltas(pDst, pPixmap, &xoff, &yoff); RegionTranslate(®, xoff, yoff); pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®); RegionUninit(®); } else exaPrepareAccess(pDst, EXA_PREPARE_DEST); /* This will eventually call fbCopyNtoN, with some calculation overhead. */ while (nbox--) { pGC->ops->CopyArea(pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y); pbox++; } exaFinishAccess(pSrc, EXA_PREPARE_SRC); exaFinishAccess(pDst, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } static void ExaFallbackPrepareReg(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height, int index, Bool checkReads) { ScreenPtr pScreen = pDrawable->pScreen; ExaScreenPriv(pScreen); if (pExaScr->prepare_access_reg && !(checkReads && exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, pGC->alu, pGC->clientClip != NULL))) { BoxRec box; RegionRec reg; int xoff, yoff; PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); box.x1 = pDrawable->x + x + xoff; box.y1 = pDrawable->y + y + yoff; box.x2 = box.x1 + width; box.y2 = box.y1 + height; RegionInit(®, &box, 1); pExaScr->prepare_access_reg(pPixmap, index, ®); RegionUninit(®); } else exaPrepareAccess(pDrawable, index); } RegionPtr ExaCheckCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { RegionPtr ret; EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, EXA_PREPARE_SRC, FALSE); ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, EXA_PREPARE_DEST, TRUE); ret = pGC->ops->CopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); exaFinishAccess(pSrc, EXA_PREPARE_SRC); exaFinishAccess(pDst, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); return ret; } RegionPtr ExaCheckCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane) { RegionPtr ret; EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, EXA_PREPARE_SRC, FALSE); ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, EXA_PREPARE_DEST, TRUE); ret = pGC->ops->CopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); exaFinishAccess(pSrc, EXA_PREPARE_SRC); exaFinishAccess(pDst, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); return ret; } void ExaCheckPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit) { EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); pGC->ops->PolyPoint(pDrawable, pGC, mode, npt, pptInit); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n", pDrawable, exaDrawableLocation(pDrawable), pGC->lineWidth, mode, npt)); exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); exaPrepareAccessGC(pGC); pGC->ops->Polylines(pDrawable, pGC, mode, npt, ppt); exaFinishAccessGC(pGC); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nsegInit, xSegment * pSegInit) { EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable, exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit)); exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); exaPrepareAccessGC(pGC); pGC->ops->PolySegment(pDrawable, pGC, nsegInit, pSegInit); exaFinishAccessGC(pGC); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs) { EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); exaPrepareAccessGC(pGC); pGC->ops->PolyArc(pDrawable, pGC, narcs, pArcs); exaFinishAccessGC(pGC); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect) { EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); exaPrepareAccessGC(pGC); pGC->ops->PolyFillRect(pDrawable, pGC, nrect, prect); exaFinishAccessGC(pGC); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase) { EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); exaPrepareAccessGC(pGC); pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); exaFinishAccessGC(pGC); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase) { EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable, exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu)); exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); exaPrepareAccessGC(pGC); pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); exaFinishAccessGC(pGC); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y) { EXA_PRE_FALLBACK_GC(pGC); EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable, exaDrawableLocation(&pBitmap->drawable), exaDrawableLocation(pDrawable))); ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h, EXA_PREPARE_DEST, TRUE); ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h, EXA_PREPARE_SRC, FALSE); exaPrepareAccessGC(pGC); pGC->ops->PushPixels(pGC, pBitmap, pDrawable, w, h, x, y); exaFinishAccessGC(pGC); exaFinishAccess(&pBitmap->drawable, EXA_PREPARE_SRC); exaFinishAccess(pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK_GC(pGC); } void ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { DrawablePtr pDrawable = &pWin->drawable; ScreenPtr pScreen = pDrawable->pScreen; EXA_PRE_FALLBACK(pScreen); EXA_FALLBACK(("from %p\n", pWin)); /* Only need the source bits, the destination region will be overwritten */ if (pExaScr->prepare_access_reg) { PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin); int xoff, yoff; exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff); RegionTranslate(prgnSrc, xoff, yoff); pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc); RegionTranslate(prgnSrc, -xoff, -yoff); } else exaPrepareAccess(pDrawable, EXA_PREPARE_SRC); swap(pExaScr, pScreen, CopyWindow); pScreen->CopyWindow(pWin, ptOldOrg, prgnSrc); swap(pExaScr, pScreen, CopyWindow); exaFinishAccess(pDrawable, EXA_PREPARE_SRC); EXA_POST_FALLBACK(pScreen); } void ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { ScreenPtr pScreen = pDrawable->pScreen; EXA_PRE_FALLBACK(pScreen); EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h, EXA_PREPARE_SRC, FALSE); swap(pExaScr, pScreen, GetImage); pScreen->GetImage(pDrawable, x, y, w, h, format, planeMask, d); swap(pExaScr, pScreen, GetImage); exaFinishAccess(pDrawable, EXA_PREPARE_SRC); EXA_POST_FALLBACK(pScreen); } void ExaCheckGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart) { ScreenPtr pScreen = pDrawable->pScreen; EXA_PRE_FALLBACK(pScreen); EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); exaPrepareAccess(pDrawable, EXA_PREPARE_SRC); swap(pExaScr, pScreen, GetSpans); pScreen->GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); swap(pExaScr, pScreen, GetSpans); exaFinishAccess(pDrawable, EXA_PREPARE_SRC); EXA_POST_FALLBACK(pScreen); } static void ExaSrcValidate(DrawablePtr pDrawable, int x, int y, int width, int height, unsigned int subWindowMode) { ScreenPtr pScreen = pDrawable->pScreen; ExaScreenPriv(pScreen); PixmapPtr pPix = exaGetDrawablePixmap(pDrawable); BoxRec box; RegionRec reg; RegionPtr dst; int xoff, yoff; if (pExaScr->srcPix == pPix) dst = &pExaScr->srcReg; else if (pExaScr->maskPix == pPix) dst = &pExaScr->maskReg; else return; exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff); box.x1 = x + xoff; box.y1 = y + yoff; box.x2 = box.x1 + width; box.y2 = box.y1 + height; RegionInit(®, &box, 1); RegionUnion(dst, dst, ®); RegionUninit(®); if (pExaScr->SavedSourceValidate) { swap(pExaScr, pScreen, SourceValidate); pScreen->SourceValidate(pDrawable, x, y, width, height, subWindowMode); swap(pExaScr, pScreen, SourceValidate); } } static Bool ExaPrepareCompositeReg(ScreenPtr pScreen, CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { RegionRec region; RegionPtr dstReg = NULL; RegionPtr srcReg = NULL; RegionPtr maskReg = NULL; PixmapPtr pSrcPix = NULL; PixmapPtr pMaskPix = NULL; PixmapPtr pDstPix; ExaScreenPriv(pScreen); Bool ret; RegionNull(®ion); if (pSrc->pDrawable) { pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); RegionNull(&pExaScr->srcReg); srcReg = &pExaScr->srcReg; pExaScr->srcPix = pSrcPix; if (pSrc != pDst) RegionTranslate(pSrc->pCompositeClip, -pSrc->pDrawable->x, -pSrc->pDrawable->y); } else pExaScr->srcPix = NULL; if (pMask && pMask->pDrawable) { pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); RegionNull(&pExaScr->maskReg); maskReg = &pExaScr->maskReg; pExaScr->maskPix = pMaskPix; if (pMask != pDst && pMask != pSrc) RegionTranslate(pMask->pCompositeClip, -pMask->pDrawable->x, -pMask->pDrawable->y); } else pExaScr->maskPix = NULL; RegionTranslate(pDst->pCompositeClip, -pDst->pDrawable->x, -pDst->pDrawable->y); pExaScr->SavedSourceValidate = ExaSrcValidate; swap(pExaScr, pScreen, SourceValidate); ret = miComputeCompositeRegion(®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); swap(pExaScr, pScreen, SourceValidate); RegionTranslate(pDst->pCompositeClip, pDst->pDrawable->x, pDst->pDrawable->y); if (pSrc->pDrawable && pSrc != pDst) RegionTranslate(pSrc->pCompositeClip, pSrc->pDrawable->x, pSrc->pDrawable->y); if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc) RegionTranslate(pMask->pCompositeClip, pMask->pDrawable->x, pMask->pDrawable->y); if (!ret) { if (srcReg) RegionUninit(srcReg); if (maskReg) RegionUninit(maskReg); return FALSE; } /** * Don't limit alphamaps readbacks for now until we've figured out how that * should be done. */ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) pExaScr-> prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable), EXA_PREPARE_AUX_SRC, NULL); if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) pExaScr-> prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable), EXA_PREPARE_AUX_MASK, NULL); if (pSrcPix) pExaScr->prepare_access_reg(pSrcPix, EXA_PREPARE_SRC, srcReg); if (pMaskPix) pExaScr->prepare_access_reg(pMaskPix, EXA_PREPARE_MASK, maskReg); if (srcReg) RegionUninit(srcReg); if (maskReg) RegionUninit(maskReg); pDstPix = exaGetDrawablePixmap(pDst->pDrawable); if (!exaOpReadsDestination(op)) { int xoff; int yoff; exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &xoff, &yoff); RegionTranslate(®ion, pDst->pDrawable->x + xoff, pDst->pDrawable->y + yoff); dstReg = ®ion; } if (pDst->alphaMap && pDst->alphaMap->pDrawable) pExaScr-> prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable), EXA_PREPARE_AUX_DEST, dstReg); pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg); RegionUninit(®ion); return TRUE; } void ExaCheckComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ScreenPtr pScreen = pDst->pDrawable->pScreen; PictureScreenPtr ps = GetPictureScreen(pScreen); EXA_PRE_FALLBACK(pScreen); if (pExaScr->prepare_access_reg) { if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) goto out_no_clip; } else { /* We need to prepare access to any separate alpha maps first, * in case the driver doesn't support EXA_PREPARE_AUX*, * in which case EXA_PREPARE_SRC may be used for moving them out. */ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); if (pDst->alphaMap && pDst->alphaMap->pDrawable) exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); exaPrepareAccess(pDst->pDrawable, EXA_PREPARE_DEST); EXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst)); if (pSrc->pDrawable != NULL) exaPrepareAccess(pSrc->pDrawable, EXA_PREPARE_SRC); if (pMask && pMask->pDrawable != NULL) exaPrepareAccess(pMask->pDrawable, EXA_PREPARE_MASK); } swap(pExaScr, ps, Composite); ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); swap(pExaScr, ps, Composite); if (pMask && pMask->pDrawable != NULL) exaFinishAccess(pMask->pDrawable, EXA_PREPARE_MASK); if (pSrc->pDrawable != NULL) exaFinishAccess(pSrc->pDrawable, EXA_PREPARE_SRC); exaFinishAccess(pDst->pDrawable, EXA_PREPARE_DEST); if (pDst->alphaMap && pDst->alphaMap->pDrawable) exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); out_no_clip: EXA_POST_FALLBACK(pScreen); } /** * Avoid migration ping-pong when using a mask. */ void ExaCheckGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { ScreenPtr pScreen = pDst->pDrawable->pScreen; EXA_PRE_FALLBACK(pScreen); miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); EXA_POST_FALLBACK(pScreen); } void ExaCheckAddTraps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap * traps) { ScreenPtr pScreen = pPicture->pDrawable->pScreen; PictureScreenPtr ps = GetPictureScreen(pScreen); EXA_PRE_FALLBACK(pScreen); EXA_FALLBACK(("to pict %p (%c)\n", pPicture, exaDrawableLocation(pPicture->pDrawable))); exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); swap(pExaScr, ps, AddTraps); ps->AddTraps(pPicture, x_off, y_off, ntrap, traps); swap(pExaScr, ps, AddTraps); exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); EXA_POST_FALLBACK(pScreen); } /** * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps * that happen to be 1x1. Pixmap must be at least 8bpp. */ CARD32 exaGetPixmapFirstPixel(PixmapPtr pPixmap) { switch (pPixmap->drawable.bitsPerPixel) { case 32: { CARD32 pixel; pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, ZPixmap, ~0, (char *) &pixel); return pixel; } case 16: { CARD16 pixel; pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, ZPixmap, ~0, (char *) &pixel); return pixel; } case 8: case 4: case 1: { CARD8 pixel; pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, ZPixmap, ~0, (char *) &pixel); return pixel; } default: FatalError("%s called for invalid bpp %d\n", __func__, pPixmap->drawable.bitsPerPixel); } } xorg-server-1.20.13/fb/0000755000175000017500000000000014100574017011530 500000000000000xorg-server-1.20.13/fb/meson.build0000644000175000017500000000152414100573756013625 00000000000000srcs_fb = [ 'fballpriv.c', 'fbarc.c', 'fbbits.c', 'fbblt.c', 'fbbltone.c', 'fbcmap_mi.c', 'fbcopy.c', 'fbfill.c', 'fbfillrect.c', 'fbfillsp.c', 'fbgc.c', 'fbgetsp.c', 'fbglyph.c', 'fbimage.c', 'fbline.c', 'fboverlay.c', 'fbpict.c', 'fbpixmap.c', 'fbpoint.c', 'fbpush.c', 'fbscreen.c', 'fbseg.c', 'fbsetsp.c', 'fbsolid.c', 'fbtrap.c', 'fbutil.c', 'fbwindow.c', ] hdrs_fb = [ 'fb.h', 'fboverlay.h', 'fbpict.h', 'fbrop.h', 'wfbrename.h' ] libxserver_fb = static_library('libxserver_fb', srcs_fb, include_directories: inc, dependencies: common_dep, pic: true, ) wfb_args = '-DFB_ACCESS_WRAPPER' libxserver_wfb = static_library('libxserver_wfb', srcs_fb, c_args: wfb_args, include_directories: inc, dependencies: common_dep, pic: true, build_by_default: false, ) install_data(hdrs_fb, install_dir: xorgsdkdir) xorg-server-1.20.13/fb/Makefile.am0000644000175000017500000000140414100573756013514 00000000000000noinst_LTLIBRARIES = libfb.la libwfb.la AM_CFLAGS = $(DIX_CFLAGS) if XORG sdk_HEADERS = fb.h fbrop.h fboverlay.h wfbrename.h fbpict.h endif libfb_la_CFLAGS = $(AM_CFLAGS) libfb_la_LIBADD = $(PIXMAN_LIBS) libwfb_la_CFLAGS = $(AM_CFLAGS) -DFB_ACCESS_WRAPPER libwfb_la_LIBADD = $(PIXMAN_LIBS) libfb_la_SOURCES = \ fb.h \ fballpriv.c \ fbarc.c \ fbbits.c \ fbbits.h \ fbblt.c \ fbbltone.c \ fbcmap_mi.c \ fbcopy.c \ fbfill.c \ fbfillrect.c \ fbfillsp.c \ fbgc.c \ fbgetsp.c \ fbglyph.c \ fbimage.c \ fbline.c \ fboverlay.c \ fboverlay.h \ fbpict.c \ fbpict.h \ fbpixmap.c \ fbpoint.c \ fbpush.c \ fbrop.h \ fbscreen.c \ fbseg.c \ fbsetsp.c \ fbsolid.c \ fbtrap.c \ fbutil.c \ fbwindow.c libwfb_la_SOURCES = $(libfb_la_SOURCES) xorg-server-1.20.13/fb/fb.h0000644000175000017500000007566514100573756012244 00000000000000/* * * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef _FB_H_ #define _FB_H_ #include #include #include "scrnintstr.h" #include "pixmap.h" #include "pixmapstr.h" #include "region.h" #include "gcstruct.h" #include "colormap.h" #include "miscstruct.h" #include "servermd.h" #include "windowstr.h" #include "privates.h" #include "mi.h" #include "migc.h" #include "picturestr.h" #ifdef FB_ACCESS_WRAPPER #include "wfbrename.h" #define FBPREFIX(x) wfb##x #define WRITE(ptr, val) ((*wfbWriteMemory)((ptr), (val), sizeof(*(ptr)))) #define READ(ptr) ((*wfbReadMemory)((ptr), sizeof(*(ptr)))) #define MEMCPY_WRAPPED(dst, src, size) do { \ size_t _i; \ CARD8 *_dst = (CARD8*)(dst), *_src = (CARD8*)(src); \ for(_i = 0; _i < size; _i++) { \ WRITE(_dst +_i, READ(_src + _i)); \ } \ } while(0) #define MEMSET_WRAPPED(dst, val, size) do { \ size_t _i; \ CARD8 *_dst = (CARD8*)(dst); \ for(_i = 0; _i < size; _i++) { \ WRITE(_dst +_i, (val)); \ } \ } while(0) #else #define FBPREFIX(x) fb##x #define WRITE(ptr, val) (*(ptr) = (val)) #define READ(ptr) (*(ptr)) #define MEMCPY_WRAPPED(dst, src, size) memcpy((dst), (src), (size)) #define MEMSET_WRAPPED(dst, val, size) memset((dst), (val), (size)) #endif /* * This single define controls the basic size of data manipulated * by this software; it must be log2(sizeof (FbBits) * 8) */ #ifndef FB_SHIFT #define FB_SHIFT LOG2_BITMAP_PAD #endif #define FB_UNIT (1 << FB_SHIFT) #define FB_MASK (FB_UNIT - 1) #define FB_ALLONES ((FbBits) -1) #if GLYPHPADBYTES != 4 #error "GLYPHPADBYTES must be 4" #endif #define FB_STIP_SHIFT LOG2_BITMAP_PAD #define FB_STIP_UNIT (1 << FB_STIP_SHIFT) #define FB_STIP_MASK (FB_STIP_UNIT - 1) #define FB_STIP_ALLONES ((FbStip) -1) #define FB_STIP_ODDSTRIDE(s) (((s) & (FB_MASK >> FB_STIP_SHIFT)) != 0) #define FB_STIP_ODDPTR(p) ((((long) (p)) & (FB_MASK >> 3)) != 0) #define FbStipStrideToBitsStride(s) (((s) >> (FB_SHIFT - FB_STIP_SHIFT))) #define FbBitsStrideToStipStride(s) (((s) << (FB_SHIFT - FB_STIP_SHIFT))) #define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1)) #if FB_SHIFT == 5 typedef CARD32 FbBits; #else #error "Unsupported FB_SHIFT" #endif #if LOG2_BITMAP_PAD == FB_SHIFT typedef FbBits FbStip; #endif typedef int FbStride; #ifdef FB_DEBUG extern _X_EXPORT void fbValidateDrawable(DrawablePtr d); extern _X_EXPORT void fbInitializeDrawable(DrawablePtr d); extern _X_EXPORT void fbSetBits(FbStip * bits, int stride, FbStip data); #define FB_HEAD_BITS (FbStip) (0xbaadf00d) #define FB_TAIL_BITS (FbStip) (0xbaddf0ad) #else #define fbValidateDrawable(d) #define fdInitializeDrawable(d) #endif #include "fbrop.h" #if BITMAP_BIT_ORDER == LSBFirst #define FbScrLeft(x,n) ((x) >> (n)) #define FbScrRight(x,n) ((x) << (n)) /* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */ #define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1)) #define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n))) #define FbPatternOffsetBits 0 #else #define FbScrLeft(x,n) ((x) << (n)) #define FbScrRight(x,n) ((x) >> (n)) /* #define FbLeftBits(x,n) ((x) >> (FB_UNIT - (n))) */ #define FbLeftStipBits(x,n) ((x) >> (FB_STIP_UNIT - (n))) #define FbStipMoveLsb(x,s,n) (x) #define FbPatternOffsetBits (sizeof (FbBits) - 1) #endif #include "micoord.h" #define FbStipLeft(x,n) FbScrLeft(x,n) #define FbStipRight(x,n) FbScrRight(x,n) #define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0) #define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0) #define FbRotStipLeft(x,n) FbStipLeft(x,n) | (n ? FbStipRight(x,FB_STIP_UNIT-n) : 0) #define FbRotStipRight(x,n) FbStipRight(x,n) | (n ? FbStipLeft(x,FB_STIP_UNIT-n) : 0) #define FbLeftMask(x) ( ((x) & FB_MASK) ? \ FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0) #define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \ FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0) #define FbLeftStipMask(x) ( ((x) & FB_STIP_MASK) ? \ FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) : 0) #define FbRightStipMask(x) ( ((FB_STIP_UNIT - (x)) & FB_STIP_MASK) ? \ FbScrLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - (x)) & FB_STIP_MASK) : 0) #define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \ FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK)) #define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \ FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK)) #define FbMaskBits(x,w,l,n,r) { \ n = (w); \ r = FbRightMask((x)+n); \ l = FbLeftMask(x); \ if (l) { \ n -= FB_UNIT - ((x) & FB_MASK); \ if (n < 0) { \ n = 0; \ l &= r; \ r = 0; \ } \ } \ n >>= FB_SHIFT; \ } #define FbByteMaskInvalid 0x10 #define FbPatternOffset(o,t) ((o) ^ (FbPatternOffsetBits & ~(sizeof (t) - 1))) #define FbPtrOffset(p,o,t) ((t *) ((CARD8 *) (p) + (o))) #define FbSelectPatternPart(xor,o,t) ((xor) >> (FbPatternOffset (o,t) << 3)) #define FbStorePart(dst,off,t,xor) (WRITE(FbPtrOffset(dst,off,t), \ FbSelectPart(xor,off,t))) #ifndef FbSelectPart #define FbSelectPart(x,o,t) FbSelectPatternPart(x,o,t) #endif #define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) { \ n = (w); \ lb = 0; \ rb = 0; \ r = FbRightMask((x)+n); \ if (r) { \ /* compute right byte length */ \ if ((copy) && (((x) + n) & 7) == 0) { \ rb = (((x) + n) & FB_MASK) >> 3; \ } else { \ rb = FbByteMaskInvalid; \ } \ } \ l = FbLeftMask(x); \ if (l) { \ /* compute left byte length */ \ if ((copy) && ((x) & 7) == 0) { \ lb = ((x) & FB_MASK) >> 3; \ } else { \ lb = FbByteMaskInvalid; \ } \ /* subtract out the portion painted by leftMask */ \ n -= FB_UNIT - ((x) & FB_MASK); \ if (n < 0) { \ if (lb != FbByteMaskInvalid) { \ if (rb == FbByteMaskInvalid) { \ lb = FbByteMaskInvalid; \ } else if (rb) { \ lb |= (rb - lb) << (FB_SHIFT - 3); \ rb = 0; \ } \ } \ n = 0; \ l &= r; \ r = 0; \ }\ } \ n >>= FB_SHIFT; \ } #define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ switch (lb) { \ case (sizeof (FbBits) - 3) | (1 << (FB_SHIFT - 3)): \ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ break; \ case (sizeof (FbBits) - 3) | (2 << (FB_SHIFT - 3)): \ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ break; \ case (sizeof (FbBits) - 2) | (1 << (FB_SHIFT - 3)): \ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ break; \ case sizeof (FbBits) - 3: \ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ case sizeof (FbBits) - 2: \ FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \ break; \ case sizeof (FbBits) - 1: \ FbStorePart(dst,sizeof (FbBits) - 1,CARD8,xor); \ break; \ default: \ WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, l)); \ break; \ } \ } #define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ switch (rb) { \ case 1: \ FbStorePart(dst,0,CARD8,xor); \ break; \ case 2: \ FbStorePart(dst,0,CARD16,xor); \ break; \ case 3: \ FbStorePart(dst,0,CARD16,xor); \ FbStorePart(dst,2,CARD8,xor); \ break; \ default: \ WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, r)); \ } \ } #define FbMaskStip(x,w,l,n,r) { \ n = (w); \ r = FbRightStipMask((x)+n); \ l = FbLeftStipMask(x); \ if (l) { \ n -= FB_STIP_UNIT - ((x) & FB_STIP_MASK); \ if (n < 0) { \ n = 0; \ l &= r; \ r = 0; \ } \ } \ n >>= FB_STIP_SHIFT; \ } /* * These macros are used to transparently stipple * in copy mode; the expected usage is with 'n' constant * so all of the conditional parts collapse into a minimal * sequence of partial word writes * * 'n' is the bytemask of which bytes to store, 'a' is the address * of the FbBits base unit, 'o' is the offset within that unit * * The term "lane" comes from the hardware term "byte-lane" which */ #define FbLaneCase1(n,a,o) \ if ((n) == 0x01) { \ WRITE((CARD8 *) ((a)+FbPatternOffset(o,CARD8)), fgxor); \ } #define FbLaneCase2(n,a,o) \ if ((n) == 0x03) { \ WRITE((CARD16 *) ((a)+FbPatternOffset(o,CARD16)), fgxor); \ } else { \ FbLaneCase1((n)&1,a,o) \ FbLaneCase1((n)>>1,a,(o)+1) \ } #define FbLaneCase4(n,a,o) \ if ((n) == 0x0f) { \ WRITE((CARD32 *) ((a)+FbPatternOffset(o,CARD32)), fgxor); \ } else { \ FbLaneCase2((n)&3,a,o) \ FbLaneCase2((n)>>2,a,(o)+2) \ } #define FbLaneCase(n,a) FbLaneCase4(n,(CARD8 *) (a),0) /* Macros for dealing with dashing */ #define FbDashDeclare \ unsigned char *__dash, *__firstDash, *__lastDash #define FbDashInit(pGC,pPriv,dashOffset,dashlen,even) { \ (even) = TRUE; \ __firstDash = (pGC)->dash; \ __lastDash = __firstDash + (pGC)->numInDashList; \ (dashOffset) %= (pPriv)->dashLength; \ \ __dash = __firstDash; \ while ((dashOffset) >= ((dashlen) = *__dash)) \ { \ (dashOffset) -= (dashlen); \ (even) = 1-(even); \ if (++__dash == __lastDash) \ __dash = __firstDash; \ } \ (dashlen) -= (dashOffset); \ } #define FbDashNext(dashlen) { \ if (++__dash == __lastDash) \ __dash = __firstDash; \ (dashlen) = *__dash; \ } /* as numInDashList is always even, this case can skip a test */ #define FbDashNextEven(dashlen) { \ (dashlen) = *++__dash; \ } #define FbDashNextOdd(dashlen) FbDashNext(dashlen) #define FbDashStep(dashlen,even) { \ if (!--(dashlen)) { \ FbDashNext(dashlen); \ (even) = 1-(even); \ } \ } extern _X_EXPORT const GCOps fbGCOps; extern _X_EXPORT const GCFuncs fbGCFuncs; /* Framebuffer access wrapper */ typedef FbBits(*ReadMemoryProcPtr) (const void *src, int size); typedef void (*WriteMemoryProcPtr) (void *dst, FbBits value, int size); typedef void (*SetupWrapProcPtr) (ReadMemoryProcPtr * pRead, WriteMemoryProcPtr * pWrite, DrawablePtr pDraw); typedef void (*FinishWrapProcPtr) (DrawablePtr pDraw); #ifdef FB_ACCESS_WRAPPER #define fbPrepareAccess(pDraw) \ fbGetScreenPrivate((pDraw)->pScreen)->setupWrap( \ &wfbReadMemory, \ &wfbWriteMemory, \ (pDraw)) #define fbFinishAccess(pDraw) \ fbGetScreenPrivate((pDraw)->pScreen)->finishWrap(pDraw) #else #define fbPrepareAccess(pPix) #define fbFinishAccess(pDraw) #endif extern _X_EXPORT DevPrivateKey fbGetScreenPrivateKey(void); /* private field of a screen */ typedef struct { #ifdef FB_ACCESS_WRAPPER SetupWrapProcPtr setupWrap; /* driver hook to set pixmap access wrapping */ FinishWrapProcPtr finishWrap; /* driver hook to clean up pixmap access wrapping */ #endif DevPrivateKeyRec gcPrivateKeyRec; DevPrivateKeyRec winPrivateKeyRec; } FbScreenPrivRec, *FbScreenPrivPtr; #define fbGetScreenPrivate(pScreen) ((FbScreenPrivPtr) \ dixLookupPrivate(&(pScreen)->devPrivates, fbGetScreenPrivateKey())) /* private field of GC */ typedef struct { FbBits and, xor; /* reduced rop values */ FbBits bgand, bgxor; /* for stipples */ FbBits fg, bg, pm; /* expanded and filled */ unsigned int dashLength; /* total of all dash elements */ } FbGCPrivRec, *FbGCPrivPtr; #define fbGetGCPrivateKey(pGC) (&fbGetScreenPrivate((pGC)->pScreen)->gcPrivateKeyRec) #define fbGetGCPrivate(pGC) ((FbGCPrivPtr)\ dixLookupPrivate(&(pGC)->devPrivates, fbGetGCPrivateKey(pGC))) #define fbGetCompositeClip(pGC) ((pGC)->pCompositeClip) #define fbGetExpose(pGC) ((pGC)->fExpose) #define fbGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivate) #define fbGetWinPrivateKey(pWin) (&fbGetScreenPrivate(((DrawablePtr) (pWin))->pScreen)->winPrivateKeyRec) #define fbGetWindowPixmap(pWin) ((PixmapPtr)\ dixLookupPrivate(&((WindowPtr)(pWin))->devPrivates, fbGetWinPrivateKey(pWin))) #define __fbPixDrawableX(pPix) ((pPix)->drawable.x) #define __fbPixDrawableY(pPix) ((pPix)->drawable.y) #ifdef COMPOSITE #define __fbPixOffXWin(pPix) (__fbPixDrawableX(pPix) - (pPix)->screen_x) #define __fbPixOffYWin(pPix) (__fbPixDrawableY(pPix) - (pPix)->screen_y) #else #define __fbPixOffXWin(pPix) (__fbPixDrawableX(pPix)) #define __fbPixOffYWin(pPix) (__fbPixDrawableY(pPix)) #endif #define __fbPixOffXPix(pPix) (__fbPixDrawableX(pPix)) #define __fbPixOffYPix(pPix) (__fbPixDrawableY(pPix)) #define fbGetDrawablePixmap(pDrawable, pixmap, xoff, yoff) { \ if ((pDrawable)->type != DRAWABLE_PIXMAP) { \ (pixmap) = fbGetWindowPixmap(pDrawable); \ (xoff) = __fbPixOffXWin(pixmap); \ (yoff) = __fbPixOffYWin(pixmap); \ } else { \ (pixmap) = (PixmapPtr) (pDrawable); \ (xoff) = __fbPixOffXPix(pixmap); \ (yoff) = __fbPixOffYPix(pixmap); \ } \ fbPrepareAccess(pDrawable); \ } #define fbGetPixmapBitsData(pixmap, pointer, stride, bpp) { \ (pointer) = (FbBits *) (pixmap)->devPrivate.ptr; \ (stride) = ((int) (pixmap)->devKind) / sizeof (FbBits); (void)(stride); \ (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ } #define fbGetPixmapStipData(pixmap, pointer, stride, bpp) { \ (pointer) = (FbStip *) (pixmap)->devPrivate.ptr; \ (stride) = ((int) (pixmap)->devKind) / sizeof (FbStip); (void)(stride); \ (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ } #define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ PixmapPtr _pPix; \ fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff); \ fbGetPixmapBitsData(_pPix, pointer, stride, bpp); \ } #define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ PixmapPtr _pPix; \ fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff); \ fbGetPixmapStipData(_pPix, pointer, stride, bpp); \ } /* * XFree86 empties the root BorderClip when the VT is inactive, * here's a macro which uses that to disable GetImage and GetSpans */ #define fbWindowEnabled(pWin) \ RegionNotEmpty(&(pWin)->borderClip) #define fbDrawableEnabled(pDrawable) \ ((pDrawable)->type == DRAWABLE_PIXMAP ? \ TRUE : fbWindowEnabled((WindowPtr) pDrawable)) #define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0) /* * Accelerated tiles are power of 2 width <= FB_UNIT */ #define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w)) /* * fballpriv.c */ extern _X_EXPORT Bool fbAllocatePrivates(ScreenPtr pScreen); /* * fbarc.c */ extern _X_EXPORT void fbPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs); /* * fbbits.c */ extern _X_EXPORT void fbBresSolid8(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x, int y, int e, int e1, int e3, int len); extern _X_EXPORT void fbBresDash8(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x, int y, int e, int e1, int e3, int len); extern _X_EXPORT void fbDots8(FbBits * dst, FbStride dstStride, int dstBpp, BoxPtr pBox, xPoint * pts, int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor); extern _X_EXPORT void fbArc8(FbBits * dst, FbStride dstStride, int dstBpp, xArc * arc, int dx, int dy, FbBits and, FbBits xor); extern _X_EXPORT void fbGlyph8(FbBits * dstLine, FbStride dstStride, int dstBpp, FbStip * stipple, FbBits fg, int height, int shift); extern _X_EXPORT void fbPolyline8(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ptsOrig); extern _X_EXPORT void fbPolySegment8(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg); extern _X_EXPORT void fbBresSolid16(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x, int y, int e, int e1, int e3, int len); extern _X_EXPORT void fbBresDash16(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x, int y, int e, int e1, int e3, int len); extern _X_EXPORT void fbDots16(FbBits * dst, FbStride dstStride, int dstBpp, BoxPtr pBox, xPoint * pts, int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor); extern _X_EXPORT void fbArc16(FbBits * dst, FbStride dstStride, int dstBpp, xArc * arc, int dx, int dy, FbBits and, FbBits xor); extern _X_EXPORT void fbGlyph16(FbBits * dstLine, FbStride dstStride, int dstBpp, FbStip * stipple, FbBits fg, int height, int shift); extern _X_EXPORT void fbPolyline16(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ptsOrig); extern _X_EXPORT void fbPolySegment16(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg); extern _X_EXPORT void fbBresSolid32(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x, int y, int e, int e1, int e3, int len); extern _X_EXPORT void fbBresDash32(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x, int y, int e, int e1, int e3, int len); extern _X_EXPORT void fbDots32(FbBits * dst, FbStride dstStride, int dstBpp, BoxPtr pBox, xPoint * pts, int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor); extern _X_EXPORT void fbArc32(FbBits * dst, FbStride dstStride, int dstBpp, xArc * arc, int dx, int dy, FbBits and, FbBits xor); extern _X_EXPORT void fbGlyph32(FbBits * dstLine, FbStride dstStride, int dstBpp, FbStip * stipple, FbBits fg, int height, int shift); extern _X_EXPORT void fbPolyline32(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ptsOrig); extern _X_EXPORT void fbPolySegment32(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg); /* * fbblt.c */ extern _X_EXPORT void fbBlt(FbBits * src, FbStride srcStride, int srcX, FbBits * dst, FbStride dstStride, int dstX, int width, int height, int alu, FbBits pm, int bpp, Bool reverse, Bool upsidedown); extern _X_EXPORT void fbBltStip(FbStip * src, FbStride srcStride, /* in FbStip units, not FbBits units */ int srcX, FbStip * dst, FbStride dstStride, /* in FbStip units, not FbBits units */ int dstX, int width, int height, int alu, FbBits pm, int bpp); /* * fbbltone.c */ extern _X_EXPORT void fbBltOne(FbStip * src, FbStride srcStride, int srcX, FbBits * dst, FbStride dstStride, int dstX, int dstBpp, int width, int height, FbBits fgand, FbBits fbxor, FbBits bgand, FbBits bgxor); extern _X_EXPORT void fbBltPlane(FbBits * src, FbStride srcStride, int srcX, int srcBpp, FbStip * dst, FbStride dstStride, int dstX, int width, int height, FbStip fgand, FbStip fgxor, FbStip bgand, FbStip bgxor, Pixel planeMask); /* * fbcmap_mi.c */ extern _X_EXPORT int fbListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps); extern _X_EXPORT void fbInstallColormap(ColormapPtr pmap); extern _X_EXPORT void fbUninstallColormap(ColormapPtr pmap); extern _X_EXPORT void fbResolveColor(unsigned short *pred, unsigned short *pgreen, unsigned short *pblue, VisualPtr pVisual); extern _X_EXPORT Bool fbInitializeColormap(ColormapPtr pmap); extern _X_EXPORT int fbExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem * indefs, xColorItem * outdefs); extern _X_EXPORT Bool fbCreateDefColormap(ScreenPtr pScreen); extern _X_EXPORT void fbClearVisualTypes(void); extern _X_EXPORT Bool fbSetVisualTypes(int depth, int visuals, int bitsPerRGB); extern _X_EXPORT Bool fbSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB, Pixel redMask, Pixel greenMask, Pixel blueMask); extern _X_EXPORT Bool fbInitVisuals(VisualPtr * visualp, DepthPtr * depthp, int *nvisualp, int *ndepthp, int *rootDepthp, VisualID * defaultVisp, unsigned long sizes, int bitsPerRGB); /* * fbcopy.c */ extern _X_EXPORT void fbCopyNtoN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); extern _X_EXPORT void fbCopy1toN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); extern _X_EXPORT void fbCopyNto1(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); extern _X_EXPORT RegionPtr fbCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut); extern _X_EXPORT RegionPtr fbCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut, unsigned long bitplane); /* * fbfill.c */ extern _X_EXPORT void fbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height); extern _X_EXPORT void fbSolidBoxClipped(DrawablePtr pDrawable, RegionPtr pClip, int xa, int ya, int xb, int yb, FbBits and, FbBits xor); /* * fbfillrect.c */ extern _X_EXPORT void fbPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectInit, xRectangle *prectInit); #define fbPolyFillArc miPolyFillArc #define fbFillPolygon miFillPolygon /* * fbfillsp.c */ extern _X_EXPORT void fbFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit, DDXPointPtr pptInit, int *pwidthInit, int fSorted); /* * fbgc.c */ extern _X_EXPORT Bool fbCreateGC(GCPtr pGC); extern _X_EXPORT void fbPadPixmap(PixmapPtr pPixmap); extern _X_EXPORT void fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable); /* * fbgetsp.c */ extern _X_EXPORT void fbGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pchardstStart); /* * fbglyph.c */ extern _X_EXPORT void fbPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase); extern _X_EXPORT void fbImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase); /* * fbimage.c */ extern _X_EXPORT void fbPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pImage); extern _X_EXPORT void fbPutZImage(DrawablePtr pDrawable, RegionPtr pClip, int alu, FbBits pm, int x, int y, int width, int height, FbStip * src, FbStride srcStride); extern _X_EXPORT void fbPutXYImage(DrawablePtr pDrawable, RegionPtr pClip, FbBits fg, FbBits bg, FbBits pm, int alu, Bool opaque, int x, int y, int width, int height, FbStip * src, FbStride srcStride, int srcX); extern _X_EXPORT void fbGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); /* * fbline.c */ extern _X_EXPORT void fbPolyLine(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt); extern _X_EXPORT void fbFixCoordModePrevious(int npt, DDXPointPtr ppt); extern _X_EXPORT void fbPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg); #define fbPolyRectangle miPolyRectangle /* * fbpict.c */ extern _X_EXPORT Bool fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats); extern _X_EXPORT void fbDestroyGlyphCache(void); /* * fbpixmap.c */ extern _X_EXPORT PixmapPtr fbCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, unsigned usage_hint); extern _X_EXPORT Bool fbDestroyPixmap(PixmapPtr pPixmap); extern _X_EXPORT RegionPtr fbPixmapToRegion(PixmapPtr pPix); /* * fbpoint.c */ extern _X_EXPORT void fbPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, xPoint * pptInit); /* * fbpush.c */ extern _X_EXPORT void fbPushImage(DrawablePtr pDrawable, GCPtr pGC, FbStip * src, FbStride srcStride, int srcX, int x, int y, int width, int height); extern _X_EXPORT void fbPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg); /* * fbscreen.c */ extern _X_EXPORT Bool fbCloseScreen(ScreenPtr pScreen); extern _X_EXPORT Bool fbRealizeFont(ScreenPtr pScreen, FontPtr pFont); extern _X_EXPORT Bool fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont); extern _X_EXPORT void fbQueryBestSize(int class, unsigned short *width, unsigned short *height, ScreenPtr pScreen); extern _X_EXPORT PixmapPtr _fbGetWindowPixmap(WindowPtr pWindow); extern _X_EXPORT void _fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap); extern _X_EXPORT Bool fbSetupScreen(ScreenPtr pScreen, void *pbits, /* pointer to screen bitmap */ int xsize, /* in pixels */ int ysize, int dpix, /* dots per inch */ int dpiy, int width, /* pixel width of frame buffer */ int bpp); /* bits per pixel of frame buffer */ #ifdef FB_ACCESS_WRAPPER extern _X_EXPORT Bool wfbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize, int dpix, int dpiy, int width, int bpp, SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap); extern _X_EXPORT Bool wfbScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize, int dpix, int dpiy, int width, int bpp, SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap); #endif extern _X_EXPORT Bool fbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize, int dpix, int dpiy, int width, int bpp); extern _X_EXPORT Bool fbScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize, int dpix, int dpiy, int width, int bpp); /* * fbseg.c */ typedef void FbBres(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x, int y, int e, int e1, int e3, int len); extern _X_EXPORT void fbSegment(DrawablePtr pDrawable, GCPtr pGC, int xa, int ya, int xb, int yb, Bool drawLast, int *dashOffset); /* * fbsetsp.c */ extern _X_EXPORT void fbSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *src, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); /* * fbsolid.c */ extern _X_EXPORT void fbSolid(FbBits * dst, FbStride dstStride, int dstX, int bpp, int width, int height, FbBits and, FbBits xor); /* * fbutil.c */ extern _X_EXPORT FbBits fbReplicatePixel(Pixel p, int bpp); #ifdef FB_ACCESS_WRAPPER extern _X_EXPORT ReadMemoryProcPtr wfbReadMemory; extern _X_EXPORT WriteMemoryProcPtr wfbWriteMemory; #endif /* * fbwindow.c */ extern _X_EXPORT Bool fbCreateWindow(WindowPtr pWin); extern _X_EXPORT Bool fbDestroyWindow(WindowPtr pWin); extern _X_EXPORT Bool fbRealizeWindow(WindowPtr pWindow); extern _X_EXPORT Bool fbPositionWindow(WindowPtr pWin, int x, int y); extern _X_EXPORT Bool fbUnrealizeWindow(WindowPtr pWindow); extern _X_EXPORT void fbCopyWindowProc(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); extern _X_EXPORT void fbCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); extern _X_EXPORT Bool fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask); extern _X_EXPORT void fbFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, FbBits and, FbBits xor); extern _X_EXPORT pixman_image_t *image_from_pict(PicturePtr pict, Bool has_clip, int *xoff, int *yoff); extern _X_EXPORT void free_pixman_pict(PicturePtr, pixman_image_t *); #endif /* _FB_H_ */ xorg-server-1.20.13/fb/fbrop.h0000644000175000017500000001055614100573756012751 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef _FBROP_H_ #define _FBROP_H_ typedef struct _mergeRopBits { FbBits ca1, cx1, ca2, cx2; } FbMergeRopRec, *FbMergeRopPtr; extern _X_EXPORT const FbMergeRopRec FbMergeRopBits[16]; #define FbDeclareMergeRop() FbBits _ca1, _cx1, _ca2, _cx2; #define FbDeclarePrebuiltMergeRop() FbBits _cca, _ccx; #define FbInitializeMergeRop(alu,pm) {\ const FbMergeRopRec *_bits; \ _bits = &FbMergeRopBits[alu]; \ _ca1 = _bits->ca1 & pm; \ _cx1 = _bits->cx1 | ~pm; \ _ca2 = _bits->ca2 & pm; \ _cx2 = _bits->cx2 & pm; \ } #define FbDestInvarientRop(alu,pm) ((pm) == FB_ALLONES && \ (((alu) >> 1 & 5) == ((alu) & 5))) #define FbDestInvarientMergeRop() (_ca1 == 0 && _cx1 == 0) /* AND has higher precedence than XOR */ #define FbDoMergeRop(src, dst) \ (((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2)) #define FbDoDestInvarientMergeRop(src) (((src) & _ca2) ^ _cx2) #define FbDoMaskMergeRop(src, dst, mask) \ (((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask))) #define FbDoLeftMaskByteMergeRop(dst, src, lb, l) { \ FbBits __xor = ((src) & _ca2) ^ _cx2; \ FbDoLeftMaskByteRRop(dst,lb,l,((src) & _ca1) ^ _cx1,__xor); \ } #define FbDoRightMaskByteMergeRop(dst, src, rb, r) { \ FbBits __xor = ((src) & _ca2) ^ _cx2; \ FbDoRightMaskByteRRop(dst,rb,r,((src) & _ca1) ^ _cx1,__xor); \ } #define FbDoRRop(dst, and, xor) (((dst) & (and)) ^ (xor)) #define FbDoMaskRRop(dst, and, xor, mask) \ (((dst) & ((and) | ~(mask))) ^ (xor & mask)) /* * Take a single bit (0 or 1) and generate a full mask */ #define fbFillFromBit(b,t) (~((t) ((b) & 1)-1)) #define fbXorT(rop,fg,pm,t) ((((fg) & fbFillFromBit((rop) >> 1,t)) | \ (~(fg) & fbFillFromBit((rop) >> 3,t))) & (pm)) #define fbAndT(rop,fg,pm,t) ((((fg) & fbFillFromBit (rop ^ (rop>>1),t)) | \ (~(fg) & fbFillFromBit((rop>>2) ^ (rop>>3),t))) | \ ~(pm)) #define fbXor(rop,fg,pm) fbXorT(rop,fg,pm,FbBits) #define fbAnd(rop,fg,pm) fbAndT(rop,fg,pm,FbBits) #define fbXorStip(rop,fg,pm) fbXorT(rop,fg,pm,FbStip) #define fbAndStip(rop,fg,pm) fbAndT(rop,fg,pm,FbStip) /* * Stippling operations; */ #define FbStippleRRop(dst, b, fa, fx, ba, bx) \ (FbDoRRop(dst, fa, fx) & b) | (FbDoRRop(dst, ba, bx) & ~b) #define FbStippleRRopMask(dst, b, fa, fx, ba, bx, m) \ (FbDoMaskRRop(dst, fa, fx, m) & (b)) | (FbDoMaskRRop(dst, ba, bx, m) & ~(b)) #define FbDoLeftMaskByteStippleRRop(dst, b, fa, fx, ba, bx, lb, l) { \ FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \ FbDoLeftMaskByteRRop(dst, lb, l, ((fa) & (b)) | ((ba) & ~(b)), __xor); \ } #define FbDoRightMaskByteStippleRRop(dst, b, fa, fx, ba, bx, rb, r) { \ FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \ FbDoRightMaskByteRRop(dst, rb, r, ((fa) & (b)) | ((ba) & ~(b)), __xor); \ } #define FbOpaqueStipple(b, fg, bg) (((fg) & (b)) | ((bg) & ~(b))) /* * Compute rop for using tile code for 1-bit dest stipples; modifies * existing rop to flip depending on pixel values */ #define FbStipple1RopPick(alu,b) (((alu) >> (2 - (((b) & 1) << 1))) & 3) #define FbOpaqueStipple1Rop(alu,fg,bg) (FbStipple1RopPick(alu,fg) | \ (FbStipple1RopPick(alu,bg) << 2)) #define FbStipple1Rop(alu,fg) (FbStipple1RopPick(alu,fg) | 4) #endif xorg-server-1.20.13/fb/fboverlay.h0000644000175000017500000000672314100573756013633 00000000000000/* * * 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 _FBOVERLAY_H_ #define _FBOVERLAY_H_ #include "privates.h" extern _X_EXPORT DevPrivateKey fbOverlayGetScreenPrivateKey(void); #ifndef FB_OVERLAY_MAX #define FB_OVERLAY_MAX 2 #endif typedef void (*fbOverlayPaintKeyProc) (DrawablePtr, RegionPtr, CARD32, int); typedef struct _fbOverlayLayer { union { struct { void *pbits; int width; int depth; } init; struct { PixmapPtr pixmap; RegionRec region; } run; } u; CARD32 key; /* special pixel value */ } FbOverlayLayer; typedef struct _fbOverlayScrPriv { int nlayers; fbOverlayPaintKeyProc PaintKey; miCopyProc CopyWindow; FbOverlayLayer layer[FB_OVERLAY_MAX]; } FbOverlayScrPrivRec, *FbOverlayScrPrivPtr; #define fbOverlayGetScrPriv(s) \ dixLookupPrivate(&(s)->devPrivates, fbOverlayGetScreenPrivateKey()) extern _X_EXPORT Bool fbOverlayCreateWindow(WindowPtr pWin); extern _X_EXPORT Bool fbOverlayCloseScreen(ScreenPtr pScreen); extern _X_EXPORT int fbOverlayWindowLayer(WindowPtr pWin); extern _X_EXPORT Bool fbOverlayCreateScreenResources(ScreenPtr pScreen); extern _X_EXPORT void fbOverlayPaintKey(DrawablePtr pDrawable, RegionPtr pRegion, CARD32 pixel, int layer); extern _X_EXPORT void fbOverlayUpdateLayerRegion(ScreenPtr pScreen, int layer, RegionPtr prgn); extern _X_EXPORT void fbOverlayCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); extern _X_EXPORT void fbOverlayWindowExposures(WindowPtr pWin, RegionPtr prgn); extern _X_EXPORT Bool fbOverlaySetupScreen(ScreenPtr pScreen, void *pbits1, void *pbits2, int xsize, int ysize, int dpix, int dpiy, int width1, int width2, int bpp1, int bpp2); extern _X_EXPORT Bool fbOverlayFinishScreenInit(ScreenPtr pScreen, void *pbits1, void *pbits2, int xsize, int ysize, int dpix, int dpiy, int width1, int width2, int bpp1, int bpp2, int depth1, int depth2); #endif /* _FBOVERLAY_H_ */ xorg-server-1.20.13/fb/wfbrename.h0000644000175000017500000001136514100573756013606 00000000000000#define fbAddTraps wfbAddTraps #define fbAddTriangles wfbAddTriangles #define fbAllocatePrivates wfbAllocatePrivates #define fbArc16 wfbArc16 #define fbArc32 wfbArc32 #define fbArc8 wfbArc8 #define fbBlt wfbBlt #define fbBltOne wfbBltOne #define fbBltPlane wfbBltPlane #define fbBltStip wfbBltStip #define fbBres wfbBres #define fbBresDash wfbBresDash #define fbBresDash16 wfbBresDash16 #define fbBresDash32 wfbBresDash32 #define fbBresDash8 wfbBresDash8 #define fbBresFill wfbBresFill #define fbBresFillDash wfbBresFillDash #define fbBresSolid wfbBresSolid #define fbBresSolid16 wfbBresSolid16 #define fbBresSolid32 wfbBresSolid32 #define fbBresSolid8 wfbBresSolid8 #define fbChangeWindowAttributes wfbChangeWindowAttributes #define fbClearVisualTypes wfbClearVisualTypes #define fbCloseScreen wfbCloseScreen #define fbComposite wfbComposite #define fbCopy1toN wfbCopy1toN #define fbCopyArea wfbCopyArea #define fbCopyNto1 wfbCopyNto1 #define fbCopyNtoN wfbCopyNtoN #define fbCopyPlane wfbCopyPlane #define fbCopyRegion wfbCopyRegion #define fbCopyWindow wfbCopyWindow #define fbCopyWindowProc wfbCopyWindowProc #define fbCreateDefColormap wfbCreateDefColormap #define fbCreateGC wfbCreateGC #define fbCreatePixmap wfbCreatePixmap #define fbCreateWindow wfbCreateWindow #define fbDestroyGlyphCache wfbDestroyGlyphCache #define fbDestroyPixmap wfbDestroyPixmap #define fbDestroyWindow wfbDestroyWindow #define fbDoCopy wfbDoCopy #define fbDots wfbDots #define fbDots16 wfbDots16 #define fbDots32 wfbDots32 #define fbDots8 wfbDots8 #define fbExpandDirectColors wfbExpandDirectColors #define fbFill wfbFill #define fbFillRegionSolid wfbFillRegionSolid #define fbFillSpans wfbFillSpans #define fbFixCoordModePrevious wfbFixCoordModePrevious #define fbGCFuncs wfbGCFuncs #define fbGCOps wfbGCOps #define fbGeneration wfbGeneration #define fbGetImage wfbGetImage #define fbGetScreenPrivateKey wfbGetScreenPrivateKey #define fbGetSpans wfbGetSpans #define _fbGetWindowPixmap _wfbGetWindowPixmap #define fbGlyph16 wfbGlyph16 #define fbGlyph32 wfbGlyph32 #define fbGlyph8 wfbGlyph8 #define fbGlyphs wfbGlyphs #define fbImageGlyphBlt wfbImageGlyphBlt #define fbIn wfbIn #define fbInitializeColormap wfbInitializeColormap #define fbInitVisuals wfbInitVisuals #define fbListInstalledColormaps wfbListInstalledColormaps #define FbMergeRopBits wFbMergeRopBits #define fbOver wfbOver #define fbOverlayCloseScreen wfbOverlayCloseScreen #define fbOverlayCopyWindow wfbOverlayCopyWindow #define fbOverlayCreateScreenResources wfbOverlayCreateScreenResources #define fbOverlayCreateWindow wfbOverlayCreateWindow #define fbOverlayFinishScreenInit wfbOverlayFinishScreenInit #define fbOverlayGeneration wfbOverlayGeneration #define fbOverlayGetScreenPrivateKey wfbOverlayGetScreenPrivateKey #define fbOverlayPaintKey wfbOverlayPaintKey #define fbOverlaySetupScreen wfbOverlaySetupScreen #define fbOverlayUpdateLayerRegion wfbOverlayUpdateLayerRegion #define fbOverlayWindowExposures wfbOverlayWindowExposures #define fbOverlayWindowLayer wfbOverlayWindowLayer #define fbPadPixmap wfbPadPixmap #define fbPictureInit wfbPictureInit #define fbPixmapToRegion wfbPixmapToRegion #define fbPolyArc wfbPolyArc #define fbPolyFillRect wfbPolyFillRect #define fbPolyGlyphBlt wfbPolyGlyphBlt #define fbPolyLine wfbPolyLine #define fbPolyline16 wfbPolyline16 #define fbPolyline32 wfbPolyline32 #define fbPolyline8 wfbPolyline8 #define fbPolyPoint wfbPolyPoint #define fbPolySegment wfbPolySegment #define fbPolySegment16 wfbPolySegment16 #define fbPolySegment32 wfbPolySegment32 #define fbPolySegment8 wfbPolySegment8 #define fbPositionWindow wfbPositionWindow #define fbPushFill wfbPushFill #define fbPushImage wfbPushImage #define fbPushPattern wfbPushPattern #define fbPushPixels wfbPushPixels #define fbPutImage wfbPutImage #define fbPutXYImage wfbPutXYImage #define fbPutZImage wfbPutZImage #define fbQueryBestSize wfbQueryBestSize #define fbRasterizeTrapezoid wfbRasterizeTrapezoid #define fbRealizeFont wfbRealizeFont #define fbReplicatePixel wfbReplicatePixel #define fbResolveColor wfbResolveColor #define fbScreenPrivateKeyRec wfbScreenPrivateKeyRec #define fbSegment wfbSegment #define fbSelectBres wfbSelectBres #define fbSetSpans wfbSetSpans #define fbSetupScreen wfbSetupScreen #define fbSetVisualTypes wfbSetVisualTypes #define fbSetVisualTypesAndMasks wfbSetVisualTypesAndMasks #define _fbSetWindowPixmap _wfbSetWindowPixmap #define fbSolid wfbSolid #define fbSolidBoxClipped wfbSolidBoxClipped #define fbTrapezoids wfbTrapezoids #define fbTriangles wfbTriangles #define fbUninstallColormap wfbUninstallColormap #define fbUnrealizeWindow wfbUnrealizeWindow #define fbUnrealizeFont wfbUnrealizeFont #define fbValidateGC wfbValidateGC #define fbWinPrivateKeyRec wfbWinPrivateKeyRec #define free_pixman_pict wfb_free_pixman_pict #define image_from_pict wfb_image_from_pict xorg-server-1.20.13/fb/fbpict.h0000644000175000017500000000507414100573756013107 00000000000000/* * * 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 #endif #ifndef _FBPICT_H_ #define _FBPICT_H_ /* fbpict.c */ extern _X_EXPORT void fbComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); /* fbtrap.c */ extern _X_EXPORT void fbAddTraps(PicturePtr pPicture, INT16 xOff, INT16 yOff, int ntrap, xTrap * traps); extern _X_EXPORT void fbRasterizeTrapezoid(PicturePtr alpha, xTrapezoid * trap, int x_off, int y_off); extern _X_EXPORT void fbAddTriangles(PicturePtr pPicture, INT16 xOff, INT16 yOff, int ntri, xTriangle * tris); extern _X_EXPORT void fbTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps); extern _X_EXPORT void fbTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris); extern _X_EXPORT void fbGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs); #endif /* _FBPICT_H_ */ xorg-server-1.20.13/fb/Makefile.in0000644000175000017500000027666014100573775013550 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = fb ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__sdk_HEADERS_DIST) \ $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libfb_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libfb_la_OBJECTS = libfb_la-fballpriv.lo libfb_la-fbarc.lo \ libfb_la-fbbits.lo libfb_la-fbblt.lo libfb_la-fbbltone.lo \ libfb_la-fbcmap_mi.lo libfb_la-fbcopy.lo libfb_la-fbfill.lo \ libfb_la-fbfillrect.lo libfb_la-fbfillsp.lo libfb_la-fbgc.lo \ libfb_la-fbgetsp.lo libfb_la-fbglyph.lo libfb_la-fbimage.lo \ libfb_la-fbline.lo libfb_la-fboverlay.lo libfb_la-fbpict.lo \ libfb_la-fbpixmap.lo libfb_la-fbpoint.lo libfb_la-fbpush.lo \ libfb_la-fbscreen.lo libfb_la-fbseg.lo libfb_la-fbsetsp.lo \ libfb_la-fbsolid.lo libfb_la-fbtrap.lo libfb_la-fbutil.lo \ libfb_la-fbwindow.lo libfb_la_OBJECTS = $(am_libfb_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libfb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libfb_la_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ libwfb_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__objects_1 = libwfb_la-fballpriv.lo libwfb_la-fbarc.lo \ libwfb_la-fbbits.lo libwfb_la-fbblt.lo libwfb_la-fbbltone.lo \ libwfb_la-fbcmap_mi.lo libwfb_la-fbcopy.lo libwfb_la-fbfill.lo \ libwfb_la-fbfillrect.lo libwfb_la-fbfillsp.lo \ libwfb_la-fbgc.lo libwfb_la-fbgetsp.lo libwfb_la-fbglyph.lo \ libwfb_la-fbimage.lo libwfb_la-fbline.lo \ libwfb_la-fboverlay.lo libwfb_la-fbpict.lo \ libwfb_la-fbpixmap.lo libwfb_la-fbpoint.lo libwfb_la-fbpush.lo \ libwfb_la-fbscreen.lo libwfb_la-fbseg.lo libwfb_la-fbsetsp.lo \ libwfb_la-fbsolid.lo libwfb_la-fbtrap.lo libwfb_la-fbutil.lo \ libwfb_la-fbwindow.lo am_libwfb_la_OBJECTS = $(am__objects_1) libwfb_la_OBJECTS = $(am_libwfb_la_OBJECTS) libwfb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libwfb_la_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libfb_la-fballpriv.Plo \ ./$(DEPDIR)/libfb_la-fbarc.Plo ./$(DEPDIR)/libfb_la-fbbits.Plo \ ./$(DEPDIR)/libfb_la-fbblt.Plo \ ./$(DEPDIR)/libfb_la-fbbltone.Plo \ ./$(DEPDIR)/libfb_la-fbcmap_mi.Plo \ ./$(DEPDIR)/libfb_la-fbcopy.Plo \ ./$(DEPDIR)/libfb_la-fbfill.Plo \ ./$(DEPDIR)/libfb_la-fbfillrect.Plo \ ./$(DEPDIR)/libfb_la-fbfillsp.Plo \ ./$(DEPDIR)/libfb_la-fbgc.Plo ./$(DEPDIR)/libfb_la-fbgetsp.Plo \ ./$(DEPDIR)/libfb_la-fbglyph.Plo \ ./$(DEPDIR)/libfb_la-fbimage.Plo \ ./$(DEPDIR)/libfb_la-fbline.Plo \ ./$(DEPDIR)/libfb_la-fboverlay.Plo \ ./$(DEPDIR)/libfb_la-fbpict.Plo \ ./$(DEPDIR)/libfb_la-fbpixmap.Plo \ ./$(DEPDIR)/libfb_la-fbpoint.Plo \ ./$(DEPDIR)/libfb_la-fbpush.Plo \ ./$(DEPDIR)/libfb_la-fbscreen.Plo \ ./$(DEPDIR)/libfb_la-fbseg.Plo \ ./$(DEPDIR)/libfb_la-fbsetsp.Plo \ ./$(DEPDIR)/libfb_la-fbsolid.Plo \ ./$(DEPDIR)/libfb_la-fbtrap.Plo \ ./$(DEPDIR)/libfb_la-fbutil.Plo \ ./$(DEPDIR)/libfb_la-fbwindow.Plo \ ./$(DEPDIR)/libwfb_la-fballpriv.Plo \ ./$(DEPDIR)/libwfb_la-fbarc.Plo \ ./$(DEPDIR)/libwfb_la-fbbits.Plo \ ./$(DEPDIR)/libwfb_la-fbblt.Plo \ ./$(DEPDIR)/libwfb_la-fbbltone.Plo \ ./$(DEPDIR)/libwfb_la-fbcmap_mi.Plo \ ./$(DEPDIR)/libwfb_la-fbcopy.Plo \ ./$(DEPDIR)/libwfb_la-fbfill.Plo \ ./$(DEPDIR)/libwfb_la-fbfillrect.Plo \ ./$(DEPDIR)/libwfb_la-fbfillsp.Plo \ ./$(DEPDIR)/libwfb_la-fbgc.Plo \ ./$(DEPDIR)/libwfb_la-fbgetsp.Plo \ ./$(DEPDIR)/libwfb_la-fbglyph.Plo \ ./$(DEPDIR)/libwfb_la-fbimage.Plo \ ./$(DEPDIR)/libwfb_la-fbline.Plo \ ./$(DEPDIR)/libwfb_la-fboverlay.Plo \ ./$(DEPDIR)/libwfb_la-fbpict.Plo \ ./$(DEPDIR)/libwfb_la-fbpixmap.Plo \ ./$(DEPDIR)/libwfb_la-fbpoint.Plo \ ./$(DEPDIR)/libwfb_la-fbpush.Plo \ ./$(DEPDIR)/libwfb_la-fbscreen.Plo \ ./$(DEPDIR)/libwfb_la-fbseg.Plo \ ./$(DEPDIR)/libwfb_la-fbsetsp.Plo \ ./$(DEPDIR)/libwfb_la-fbsolid.Plo \ ./$(DEPDIR)/libwfb_la-fbtrap.Plo \ ./$(DEPDIR)/libwfb_la-fbutil.Plo \ ./$(DEPDIR)/libwfb_la-fbwindow.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libfb_la_SOURCES) $(libwfb_la_SOURCES) DIST_SOURCES = $(libfb_la_SOURCES) $(libwfb_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__sdk_HEADERS_DIST = fb.h fbrop.h fboverlay.h wfbrename.h fbpict.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 = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(sdkdir)" HEADERS = $(sdk_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libfb.la libwfb.la AM_CFLAGS = $(DIX_CFLAGS) @XORG_TRUE@sdk_HEADERS = fb.h fbrop.h fboverlay.h wfbrename.h fbpict.h libfb_la_CFLAGS = $(AM_CFLAGS) libfb_la_LIBADD = $(PIXMAN_LIBS) libwfb_la_CFLAGS = $(AM_CFLAGS) -DFB_ACCESS_WRAPPER libwfb_la_LIBADD = $(PIXMAN_LIBS) libfb_la_SOURCES = \ fb.h \ fballpriv.c \ fbarc.c \ fbbits.c \ fbbits.h \ fbblt.c \ fbbltone.c \ fbcmap_mi.c \ fbcopy.c \ fbfill.c \ fbfillrect.c \ fbfillsp.c \ fbgc.c \ fbgetsp.c \ fbglyph.c \ fbimage.c \ fbline.c \ fboverlay.c \ fboverlay.h \ fbpict.c \ fbpict.h \ fbpixmap.c \ fbpoint.c \ fbpush.c \ fbrop.h \ fbscreen.c \ fbseg.c \ fbsetsp.c \ fbsolid.c \ fbtrap.c \ fbutil.c \ fbwindow.c libwfb_la_SOURCES = $(libfb_la_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign fb/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign fb/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libfb.la: $(libfb_la_OBJECTS) $(libfb_la_DEPENDENCIES) $(EXTRA_libfb_la_DEPENDENCIES) $(AM_V_CCLD)$(libfb_la_LINK) $(libfb_la_OBJECTS) $(libfb_la_LIBADD) $(LIBS) libwfb.la: $(libwfb_la_OBJECTS) $(libwfb_la_DEPENDENCIES) $(EXTRA_libwfb_la_DEPENDENCIES) $(AM_V_CCLD)$(libwfb_la_LINK) $(libwfb_la_OBJECTS) $(libwfb_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fballpriv.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbarc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbbits.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbblt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbbltone.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbcmap_mi.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbcopy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbfill.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbfillrect.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbfillsp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbgc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbgetsp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbglyph.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbimage.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbline.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fboverlay.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbpict.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbpixmap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbpoint.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbpush.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbscreen.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbseg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbsetsp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbsolid.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbtrap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbutil.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbwindow.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fballpriv.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbarc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbbits.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbblt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbbltone.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbcmap_mi.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbcopy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbfill.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbfillrect.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbfillsp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbgc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbgetsp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbglyph.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbimage.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbline.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fboverlay.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbpict.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbpixmap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbpoint.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbpush.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbscreen.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbseg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbsetsp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbsolid.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbtrap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbutil.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwfb_la-fbwindow.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libfb_la-fballpriv.lo: fballpriv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fballpriv.lo -MD -MP -MF $(DEPDIR)/libfb_la-fballpriv.Tpo -c -o libfb_la-fballpriv.lo `test -f 'fballpriv.c' || echo '$(srcdir)/'`fballpriv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fballpriv.Tpo $(DEPDIR)/libfb_la-fballpriv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fballpriv.c' object='libfb_la-fballpriv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fballpriv.lo `test -f 'fballpriv.c' || echo '$(srcdir)/'`fballpriv.c libfb_la-fbarc.lo: fbarc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbarc.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbarc.Tpo -c -o libfb_la-fbarc.lo `test -f 'fbarc.c' || echo '$(srcdir)/'`fbarc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbarc.Tpo $(DEPDIR)/libfb_la-fbarc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbarc.c' object='libfb_la-fbarc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbarc.lo `test -f 'fbarc.c' || echo '$(srcdir)/'`fbarc.c libfb_la-fbbits.lo: fbbits.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbbits.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbbits.Tpo -c -o libfb_la-fbbits.lo `test -f 'fbbits.c' || echo '$(srcdir)/'`fbbits.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbbits.Tpo $(DEPDIR)/libfb_la-fbbits.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbbits.c' object='libfb_la-fbbits.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbbits.lo `test -f 'fbbits.c' || echo '$(srcdir)/'`fbbits.c libfb_la-fbblt.lo: fbblt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbblt.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbblt.Tpo -c -o libfb_la-fbblt.lo `test -f 'fbblt.c' || echo '$(srcdir)/'`fbblt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbblt.Tpo $(DEPDIR)/libfb_la-fbblt.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbblt.c' object='libfb_la-fbblt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbblt.lo `test -f 'fbblt.c' || echo '$(srcdir)/'`fbblt.c libfb_la-fbbltone.lo: fbbltone.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbbltone.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbbltone.Tpo -c -o libfb_la-fbbltone.lo `test -f 'fbbltone.c' || echo '$(srcdir)/'`fbbltone.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbbltone.Tpo $(DEPDIR)/libfb_la-fbbltone.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbbltone.c' object='libfb_la-fbbltone.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbbltone.lo `test -f 'fbbltone.c' || echo '$(srcdir)/'`fbbltone.c libfb_la-fbcmap_mi.lo: fbcmap_mi.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbcmap_mi.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbcmap_mi.Tpo -c -o libfb_la-fbcmap_mi.lo `test -f 'fbcmap_mi.c' || echo '$(srcdir)/'`fbcmap_mi.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbcmap_mi.Tpo $(DEPDIR)/libfb_la-fbcmap_mi.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbcmap_mi.c' object='libfb_la-fbcmap_mi.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbcmap_mi.lo `test -f 'fbcmap_mi.c' || echo '$(srcdir)/'`fbcmap_mi.c libfb_la-fbcopy.lo: fbcopy.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbcopy.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbcopy.Tpo -c -o libfb_la-fbcopy.lo `test -f 'fbcopy.c' || echo '$(srcdir)/'`fbcopy.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbcopy.Tpo $(DEPDIR)/libfb_la-fbcopy.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbcopy.c' object='libfb_la-fbcopy.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbcopy.lo `test -f 'fbcopy.c' || echo '$(srcdir)/'`fbcopy.c libfb_la-fbfill.lo: fbfill.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbfill.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbfill.Tpo -c -o libfb_la-fbfill.lo `test -f 'fbfill.c' || echo '$(srcdir)/'`fbfill.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbfill.Tpo $(DEPDIR)/libfb_la-fbfill.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbfill.c' object='libfb_la-fbfill.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbfill.lo `test -f 'fbfill.c' || echo '$(srcdir)/'`fbfill.c libfb_la-fbfillrect.lo: fbfillrect.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbfillrect.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbfillrect.Tpo -c -o libfb_la-fbfillrect.lo `test -f 'fbfillrect.c' || echo '$(srcdir)/'`fbfillrect.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbfillrect.Tpo $(DEPDIR)/libfb_la-fbfillrect.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbfillrect.c' object='libfb_la-fbfillrect.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbfillrect.lo `test -f 'fbfillrect.c' || echo '$(srcdir)/'`fbfillrect.c libfb_la-fbfillsp.lo: fbfillsp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbfillsp.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbfillsp.Tpo -c -o libfb_la-fbfillsp.lo `test -f 'fbfillsp.c' || echo '$(srcdir)/'`fbfillsp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbfillsp.Tpo $(DEPDIR)/libfb_la-fbfillsp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbfillsp.c' object='libfb_la-fbfillsp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbfillsp.lo `test -f 'fbfillsp.c' || echo '$(srcdir)/'`fbfillsp.c libfb_la-fbgc.lo: fbgc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbgc.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbgc.Tpo -c -o libfb_la-fbgc.lo `test -f 'fbgc.c' || echo '$(srcdir)/'`fbgc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbgc.Tpo $(DEPDIR)/libfb_la-fbgc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbgc.c' object='libfb_la-fbgc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbgc.lo `test -f 'fbgc.c' || echo '$(srcdir)/'`fbgc.c libfb_la-fbgetsp.lo: fbgetsp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbgetsp.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbgetsp.Tpo -c -o libfb_la-fbgetsp.lo `test -f 'fbgetsp.c' || echo '$(srcdir)/'`fbgetsp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbgetsp.Tpo $(DEPDIR)/libfb_la-fbgetsp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbgetsp.c' object='libfb_la-fbgetsp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbgetsp.lo `test -f 'fbgetsp.c' || echo '$(srcdir)/'`fbgetsp.c libfb_la-fbglyph.lo: fbglyph.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbglyph.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbglyph.Tpo -c -o libfb_la-fbglyph.lo `test -f 'fbglyph.c' || echo '$(srcdir)/'`fbglyph.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbglyph.Tpo $(DEPDIR)/libfb_la-fbglyph.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbglyph.c' object='libfb_la-fbglyph.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbglyph.lo `test -f 'fbglyph.c' || echo '$(srcdir)/'`fbglyph.c libfb_la-fbimage.lo: fbimage.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbimage.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbimage.Tpo -c -o libfb_la-fbimage.lo `test -f 'fbimage.c' || echo '$(srcdir)/'`fbimage.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbimage.Tpo $(DEPDIR)/libfb_la-fbimage.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbimage.c' object='libfb_la-fbimage.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbimage.lo `test -f 'fbimage.c' || echo '$(srcdir)/'`fbimage.c libfb_la-fbline.lo: fbline.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbline.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbline.Tpo -c -o libfb_la-fbline.lo `test -f 'fbline.c' || echo '$(srcdir)/'`fbline.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbline.Tpo $(DEPDIR)/libfb_la-fbline.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbline.c' object='libfb_la-fbline.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbline.lo `test -f 'fbline.c' || echo '$(srcdir)/'`fbline.c libfb_la-fboverlay.lo: fboverlay.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fboverlay.lo -MD -MP -MF $(DEPDIR)/libfb_la-fboverlay.Tpo -c -o libfb_la-fboverlay.lo `test -f 'fboverlay.c' || echo '$(srcdir)/'`fboverlay.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fboverlay.Tpo $(DEPDIR)/libfb_la-fboverlay.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fboverlay.c' object='libfb_la-fboverlay.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fboverlay.lo `test -f 'fboverlay.c' || echo '$(srcdir)/'`fboverlay.c libfb_la-fbpict.lo: fbpict.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbpict.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbpict.Tpo -c -o libfb_la-fbpict.lo `test -f 'fbpict.c' || echo '$(srcdir)/'`fbpict.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbpict.Tpo $(DEPDIR)/libfb_la-fbpict.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpict.c' object='libfb_la-fbpict.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbpict.lo `test -f 'fbpict.c' || echo '$(srcdir)/'`fbpict.c libfb_la-fbpixmap.lo: fbpixmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbpixmap.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbpixmap.Tpo -c -o libfb_la-fbpixmap.lo `test -f 'fbpixmap.c' || echo '$(srcdir)/'`fbpixmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbpixmap.Tpo $(DEPDIR)/libfb_la-fbpixmap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpixmap.c' object='libfb_la-fbpixmap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbpixmap.lo `test -f 'fbpixmap.c' || echo '$(srcdir)/'`fbpixmap.c libfb_la-fbpoint.lo: fbpoint.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbpoint.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbpoint.Tpo -c -o libfb_la-fbpoint.lo `test -f 'fbpoint.c' || echo '$(srcdir)/'`fbpoint.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbpoint.Tpo $(DEPDIR)/libfb_la-fbpoint.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpoint.c' object='libfb_la-fbpoint.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbpoint.lo `test -f 'fbpoint.c' || echo '$(srcdir)/'`fbpoint.c libfb_la-fbpush.lo: fbpush.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbpush.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbpush.Tpo -c -o libfb_la-fbpush.lo `test -f 'fbpush.c' || echo '$(srcdir)/'`fbpush.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbpush.Tpo $(DEPDIR)/libfb_la-fbpush.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpush.c' object='libfb_la-fbpush.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbpush.lo `test -f 'fbpush.c' || echo '$(srcdir)/'`fbpush.c libfb_la-fbscreen.lo: fbscreen.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbscreen.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbscreen.Tpo -c -o libfb_la-fbscreen.lo `test -f 'fbscreen.c' || echo '$(srcdir)/'`fbscreen.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbscreen.Tpo $(DEPDIR)/libfb_la-fbscreen.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbscreen.c' object='libfb_la-fbscreen.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbscreen.lo `test -f 'fbscreen.c' || echo '$(srcdir)/'`fbscreen.c libfb_la-fbseg.lo: fbseg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbseg.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbseg.Tpo -c -o libfb_la-fbseg.lo `test -f 'fbseg.c' || echo '$(srcdir)/'`fbseg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbseg.Tpo $(DEPDIR)/libfb_la-fbseg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbseg.c' object='libfb_la-fbseg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbseg.lo `test -f 'fbseg.c' || echo '$(srcdir)/'`fbseg.c libfb_la-fbsetsp.lo: fbsetsp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbsetsp.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbsetsp.Tpo -c -o libfb_la-fbsetsp.lo `test -f 'fbsetsp.c' || echo '$(srcdir)/'`fbsetsp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbsetsp.Tpo $(DEPDIR)/libfb_la-fbsetsp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbsetsp.c' object='libfb_la-fbsetsp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbsetsp.lo `test -f 'fbsetsp.c' || echo '$(srcdir)/'`fbsetsp.c libfb_la-fbsolid.lo: fbsolid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbsolid.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbsolid.Tpo -c -o libfb_la-fbsolid.lo `test -f 'fbsolid.c' || echo '$(srcdir)/'`fbsolid.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbsolid.Tpo $(DEPDIR)/libfb_la-fbsolid.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbsolid.c' object='libfb_la-fbsolid.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbsolid.lo `test -f 'fbsolid.c' || echo '$(srcdir)/'`fbsolid.c libfb_la-fbtrap.lo: fbtrap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbtrap.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbtrap.Tpo -c -o libfb_la-fbtrap.lo `test -f 'fbtrap.c' || echo '$(srcdir)/'`fbtrap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbtrap.Tpo $(DEPDIR)/libfb_la-fbtrap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbtrap.c' object='libfb_la-fbtrap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbtrap.lo `test -f 'fbtrap.c' || echo '$(srcdir)/'`fbtrap.c libfb_la-fbutil.lo: fbutil.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbutil.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbutil.Tpo -c -o libfb_la-fbutil.lo `test -f 'fbutil.c' || echo '$(srcdir)/'`fbutil.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbutil.Tpo $(DEPDIR)/libfb_la-fbutil.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbutil.c' object='libfb_la-fbutil.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbutil.lo `test -f 'fbutil.c' || echo '$(srcdir)/'`fbutil.c libfb_la-fbwindow.lo: fbwindow.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbwindow.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbwindow.Tpo -c -o libfb_la-fbwindow.lo `test -f 'fbwindow.c' || echo '$(srcdir)/'`fbwindow.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbwindow.Tpo $(DEPDIR)/libfb_la-fbwindow.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbwindow.c' object='libfb_la-fbwindow.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbwindow.lo `test -f 'fbwindow.c' || echo '$(srcdir)/'`fbwindow.c libwfb_la-fballpriv.lo: fballpriv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fballpriv.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fballpriv.Tpo -c -o libwfb_la-fballpriv.lo `test -f 'fballpriv.c' || echo '$(srcdir)/'`fballpriv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fballpriv.Tpo $(DEPDIR)/libwfb_la-fballpriv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fballpriv.c' object='libwfb_la-fballpriv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fballpriv.lo `test -f 'fballpriv.c' || echo '$(srcdir)/'`fballpriv.c libwfb_la-fbarc.lo: fbarc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbarc.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbarc.Tpo -c -o libwfb_la-fbarc.lo `test -f 'fbarc.c' || echo '$(srcdir)/'`fbarc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbarc.Tpo $(DEPDIR)/libwfb_la-fbarc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbarc.c' object='libwfb_la-fbarc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbarc.lo `test -f 'fbarc.c' || echo '$(srcdir)/'`fbarc.c libwfb_la-fbbits.lo: fbbits.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbbits.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbbits.Tpo -c -o libwfb_la-fbbits.lo `test -f 'fbbits.c' || echo '$(srcdir)/'`fbbits.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbbits.Tpo $(DEPDIR)/libwfb_la-fbbits.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbbits.c' object='libwfb_la-fbbits.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbbits.lo `test -f 'fbbits.c' || echo '$(srcdir)/'`fbbits.c libwfb_la-fbblt.lo: fbblt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbblt.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbblt.Tpo -c -o libwfb_la-fbblt.lo `test -f 'fbblt.c' || echo '$(srcdir)/'`fbblt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbblt.Tpo $(DEPDIR)/libwfb_la-fbblt.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbblt.c' object='libwfb_la-fbblt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbblt.lo `test -f 'fbblt.c' || echo '$(srcdir)/'`fbblt.c libwfb_la-fbbltone.lo: fbbltone.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbbltone.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbbltone.Tpo -c -o libwfb_la-fbbltone.lo `test -f 'fbbltone.c' || echo '$(srcdir)/'`fbbltone.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbbltone.Tpo $(DEPDIR)/libwfb_la-fbbltone.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbbltone.c' object='libwfb_la-fbbltone.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbbltone.lo `test -f 'fbbltone.c' || echo '$(srcdir)/'`fbbltone.c libwfb_la-fbcmap_mi.lo: fbcmap_mi.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbcmap_mi.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbcmap_mi.Tpo -c -o libwfb_la-fbcmap_mi.lo `test -f 'fbcmap_mi.c' || echo '$(srcdir)/'`fbcmap_mi.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbcmap_mi.Tpo $(DEPDIR)/libwfb_la-fbcmap_mi.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbcmap_mi.c' object='libwfb_la-fbcmap_mi.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbcmap_mi.lo `test -f 'fbcmap_mi.c' || echo '$(srcdir)/'`fbcmap_mi.c libwfb_la-fbcopy.lo: fbcopy.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbcopy.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbcopy.Tpo -c -o libwfb_la-fbcopy.lo `test -f 'fbcopy.c' || echo '$(srcdir)/'`fbcopy.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbcopy.Tpo $(DEPDIR)/libwfb_la-fbcopy.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbcopy.c' object='libwfb_la-fbcopy.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbcopy.lo `test -f 'fbcopy.c' || echo '$(srcdir)/'`fbcopy.c libwfb_la-fbfill.lo: fbfill.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbfill.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbfill.Tpo -c -o libwfb_la-fbfill.lo `test -f 'fbfill.c' || echo '$(srcdir)/'`fbfill.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbfill.Tpo $(DEPDIR)/libwfb_la-fbfill.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbfill.c' object='libwfb_la-fbfill.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbfill.lo `test -f 'fbfill.c' || echo '$(srcdir)/'`fbfill.c libwfb_la-fbfillrect.lo: fbfillrect.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbfillrect.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbfillrect.Tpo -c -o libwfb_la-fbfillrect.lo `test -f 'fbfillrect.c' || echo '$(srcdir)/'`fbfillrect.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbfillrect.Tpo $(DEPDIR)/libwfb_la-fbfillrect.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbfillrect.c' object='libwfb_la-fbfillrect.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbfillrect.lo `test -f 'fbfillrect.c' || echo '$(srcdir)/'`fbfillrect.c libwfb_la-fbfillsp.lo: fbfillsp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbfillsp.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbfillsp.Tpo -c -o libwfb_la-fbfillsp.lo `test -f 'fbfillsp.c' || echo '$(srcdir)/'`fbfillsp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbfillsp.Tpo $(DEPDIR)/libwfb_la-fbfillsp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbfillsp.c' object='libwfb_la-fbfillsp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbfillsp.lo `test -f 'fbfillsp.c' || echo '$(srcdir)/'`fbfillsp.c libwfb_la-fbgc.lo: fbgc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbgc.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbgc.Tpo -c -o libwfb_la-fbgc.lo `test -f 'fbgc.c' || echo '$(srcdir)/'`fbgc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbgc.Tpo $(DEPDIR)/libwfb_la-fbgc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbgc.c' object='libwfb_la-fbgc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbgc.lo `test -f 'fbgc.c' || echo '$(srcdir)/'`fbgc.c libwfb_la-fbgetsp.lo: fbgetsp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbgetsp.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbgetsp.Tpo -c -o libwfb_la-fbgetsp.lo `test -f 'fbgetsp.c' || echo '$(srcdir)/'`fbgetsp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbgetsp.Tpo $(DEPDIR)/libwfb_la-fbgetsp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbgetsp.c' object='libwfb_la-fbgetsp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbgetsp.lo `test -f 'fbgetsp.c' || echo '$(srcdir)/'`fbgetsp.c libwfb_la-fbglyph.lo: fbglyph.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbglyph.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbglyph.Tpo -c -o libwfb_la-fbglyph.lo `test -f 'fbglyph.c' || echo '$(srcdir)/'`fbglyph.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbglyph.Tpo $(DEPDIR)/libwfb_la-fbglyph.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbglyph.c' object='libwfb_la-fbglyph.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbglyph.lo `test -f 'fbglyph.c' || echo '$(srcdir)/'`fbglyph.c libwfb_la-fbimage.lo: fbimage.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbimage.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbimage.Tpo -c -o libwfb_la-fbimage.lo `test -f 'fbimage.c' || echo '$(srcdir)/'`fbimage.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbimage.Tpo $(DEPDIR)/libwfb_la-fbimage.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbimage.c' object='libwfb_la-fbimage.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbimage.lo `test -f 'fbimage.c' || echo '$(srcdir)/'`fbimage.c libwfb_la-fbline.lo: fbline.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbline.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbline.Tpo -c -o libwfb_la-fbline.lo `test -f 'fbline.c' || echo '$(srcdir)/'`fbline.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbline.Tpo $(DEPDIR)/libwfb_la-fbline.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbline.c' object='libwfb_la-fbline.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbline.lo `test -f 'fbline.c' || echo '$(srcdir)/'`fbline.c libwfb_la-fboverlay.lo: fboverlay.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fboverlay.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fboverlay.Tpo -c -o libwfb_la-fboverlay.lo `test -f 'fboverlay.c' || echo '$(srcdir)/'`fboverlay.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fboverlay.Tpo $(DEPDIR)/libwfb_la-fboverlay.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fboverlay.c' object='libwfb_la-fboverlay.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fboverlay.lo `test -f 'fboverlay.c' || echo '$(srcdir)/'`fboverlay.c libwfb_la-fbpict.lo: fbpict.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbpict.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbpict.Tpo -c -o libwfb_la-fbpict.lo `test -f 'fbpict.c' || echo '$(srcdir)/'`fbpict.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbpict.Tpo $(DEPDIR)/libwfb_la-fbpict.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpict.c' object='libwfb_la-fbpict.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbpict.lo `test -f 'fbpict.c' || echo '$(srcdir)/'`fbpict.c libwfb_la-fbpixmap.lo: fbpixmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbpixmap.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbpixmap.Tpo -c -o libwfb_la-fbpixmap.lo `test -f 'fbpixmap.c' || echo '$(srcdir)/'`fbpixmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbpixmap.Tpo $(DEPDIR)/libwfb_la-fbpixmap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpixmap.c' object='libwfb_la-fbpixmap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbpixmap.lo `test -f 'fbpixmap.c' || echo '$(srcdir)/'`fbpixmap.c libwfb_la-fbpoint.lo: fbpoint.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbpoint.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbpoint.Tpo -c -o libwfb_la-fbpoint.lo `test -f 'fbpoint.c' || echo '$(srcdir)/'`fbpoint.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbpoint.Tpo $(DEPDIR)/libwfb_la-fbpoint.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpoint.c' object='libwfb_la-fbpoint.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbpoint.lo `test -f 'fbpoint.c' || echo '$(srcdir)/'`fbpoint.c libwfb_la-fbpush.lo: fbpush.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbpush.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbpush.Tpo -c -o libwfb_la-fbpush.lo `test -f 'fbpush.c' || echo '$(srcdir)/'`fbpush.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbpush.Tpo $(DEPDIR)/libwfb_la-fbpush.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpush.c' object='libwfb_la-fbpush.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbpush.lo `test -f 'fbpush.c' || echo '$(srcdir)/'`fbpush.c libwfb_la-fbscreen.lo: fbscreen.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbscreen.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbscreen.Tpo -c -o libwfb_la-fbscreen.lo `test -f 'fbscreen.c' || echo '$(srcdir)/'`fbscreen.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbscreen.Tpo $(DEPDIR)/libwfb_la-fbscreen.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbscreen.c' object='libwfb_la-fbscreen.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbscreen.lo `test -f 'fbscreen.c' || echo '$(srcdir)/'`fbscreen.c libwfb_la-fbseg.lo: fbseg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbseg.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbseg.Tpo -c -o libwfb_la-fbseg.lo `test -f 'fbseg.c' || echo '$(srcdir)/'`fbseg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbseg.Tpo $(DEPDIR)/libwfb_la-fbseg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbseg.c' object='libwfb_la-fbseg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbseg.lo `test -f 'fbseg.c' || echo '$(srcdir)/'`fbseg.c libwfb_la-fbsetsp.lo: fbsetsp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbsetsp.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbsetsp.Tpo -c -o libwfb_la-fbsetsp.lo `test -f 'fbsetsp.c' || echo '$(srcdir)/'`fbsetsp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbsetsp.Tpo $(DEPDIR)/libwfb_la-fbsetsp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbsetsp.c' object='libwfb_la-fbsetsp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbsetsp.lo `test -f 'fbsetsp.c' || echo '$(srcdir)/'`fbsetsp.c libwfb_la-fbsolid.lo: fbsolid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbsolid.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbsolid.Tpo -c -o libwfb_la-fbsolid.lo `test -f 'fbsolid.c' || echo '$(srcdir)/'`fbsolid.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbsolid.Tpo $(DEPDIR)/libwfb_la-fbsolid.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbsolid.c' object='libwfb_la-fbsolid.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbsolid.lo `test -f 'fbsolid.c' || echo '$(srcdir)/'`fbsolid.c libwfb_la-fbtrap.lo: fbtrap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbtrap.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbtrap.Tpo -c -o libwfb_la-fbtrap.lo `test -f 'fbtrap.c' || echo '$(srcdir)/'`fbtrap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbtrap.Tpo $(DEPDIR)/libwfb_la-fbtrap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbtrap.c' object='libwfb_la-fbtrap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbtrap.lo `test -f 'fbtrap.c' || echo '$(srcdir)/'`fbtrap.c libwfb_la-fbutil.lo: fbutil.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbutil.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbutil.Tpo -c -o libwfb_la-fbutil.lo `test -f 'fbutil.c' || echo '$(srcdir)/'`fbutil.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbutil.Tpo $(DEPDIR)/libwfb_la-fbutil.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbutil.c' object='libwfb_la-fbutil.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbutil.lo `test -f 'fbutil.c' || echo '$(srcdir)/'`fbutil.c libwfb_la-fbwindow.lo: fbwindow.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -MT libwfb_la-fbwindow.lo -MD -MP -MF $(DEPDIR)/libwfb_la-fbwindow.Tpo -c -o libwfb_la-fbwindow.lo `test -f 'fbwindow.c' || echo '$(srcdir)/'`fbwindow.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwfb_la-fbwindow.Tpo $(DEPDIR)/libwfb_la-fbwindow.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbwindow.c' object='libwfb_la-fbwindow.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwfb_la_CFLAGS) $(CFLAGS) -c -o libwfb_la-fbwindow.lo `test -f 'fbwindow.c' || echo '$(srcdir)/'`fbwindow.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-sdkHEADERS: $(sdk_HEADERS) @$(NORMAL_INSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sdkdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sdkdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(sdkdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(sdkdir)" || exit $$?; \ done uninstall-sdkHEADERS: @$(NORMAL_UNINSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(sdkdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/libfb_la-fballpriv.Plo -rm -f ./$(DEPDIR)/libfb_la-fbarc.Plo -rm -f ./$(DEPDIR)/libfb_la-fbbits.Plo -rm -f ./$(DEPDIR)/libfb_la-fbblt.Plo -rm -f ./$(DEPDIR)/libfb_la-fbbltone.Plo -rm -f ./$(DEPDIR)/libfb_la-fbcmap_mi.Plo -rm -f ./$(DEPDIR)/libfb_la-fbcopy.Plo -rm -f ./$(DEPDIR)/libfb_la-fbfill.Plo -rm -f ./$(DEPDIR)/libfb_la-fbfillrect.Plo -rm -f ./$(DEPDIR)/libfb_la-fbfillsp.Plo -rm -f ./$(DEPDIR)/libfb_la-fbgc.Plo -rm -f ./$(DEPDIR)/libfb_la-fbgetsp.Plo -rm -f ./$(DEPDIR)/libfb_la-fbglyph.Plo -rm -f ./$(DEPDIR)/libfb_la-fbimage.Plo -rm -f ./$(DEPDIR)/libfb_la-fbline.Plo -rm -f ./$(DEPDIR)/libfb_la-fboverlay.Plo -rm -f ./$(DEPDIR)/libfb_la-fbpict.Plo -rm -f ./$(DEPDIR)/libfb_la-fbpixmap.Plo -rm -f ./$(DEPDIR)/libfb_la-fbpoint.Plo -rm -f ./$(DEPDIR)/libfb_la-fbpush.Plo -rm -f ./$(DEPDIR)/libfb_la-fbscreen.Plo -rm -f ./$(DEPDIR)/libfb_la-fbseg.Plo -rm -f ./$(DEPDIR)/libfb_la-fbsetsp.Plo -rm -f ./$(DEPDIR)/libfb_la-fbsolid.Plo -rm -f ./$(DEPDIR)/libfb_la-fbtrap.Plo -rm -f ./$(DEPDIR)/libfb_la-fbutil.Plo -rm -f ./$(DEPDIR)/libfb_la-fbwindow.Plo -rm -f ./$(DEPDIR)/libwfb_la-fballpriv.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbarc.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbbits.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbblt.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbbltone.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbcmap_mi.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbcopy.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbfill.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbfillrect.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbfillsp.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbgc.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbgetsp.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbglyph.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbimage.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbline.Plo -rm -f ./$(DEPDIR)/libwfb_la-fboverlay.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbpict.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbpixmap.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbpoint.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbpush.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbscreen.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbseg.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbsetsp.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbsolid.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbtrap.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbutil.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbwindow.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-sdkHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libfb_la-fballpriv.Plo -rm -f ./$(DEPDIR)/libfb_la-fbarc.Plo -rm -f ./$(DEPDIR)/libfb_la-fbbits.Plo -rm -f ./$(DEPDIR)/libfb_la-fbblt.Plo -rm -f ./$(DEPDIR)/libfb_la-fbbltone.Plo -rm -f ./$(DEPDIR)/libfb_la-fbcmap_mi.Plo -rm -f ./$(DEPDIR)/libfb_la-fbcopy.Plo -rm -f ./$(DEPDIR)/libfb_la-fbfill.Plo -rm -f ./$(DEPDIR)/libfb_la-fbfillrect.Plo -rm -f ./$(DEPDIR)/libfb_la-fbfillsp.Plo -rm -f ./$(DEPDIR)/libfb_la-fbgc.Plo -rm -f ./$(DEPDIR)/libfb_la-fbgetsp.Plo -rm -f ./$(DEPDIR)/libfb_la-fbglyph.Plo -rm -f ./$(DEPDIR)/libfb_la-fbimage.Plo -rm -f ./$(DEPDIR)/libfb_la-fbline.Plo -rm -f ./$(DEPDIR)/libfb_la-fboverlay.Plo -rm -f ./$(DEPDIR)/libfb_la-fbpict.Plo -rm -f ./$(DEPDIR)/libfb_la-fbpixmap.Plo -rm -f ./$(DEPDIR)/libfb_la-fbpoint.Plo -rm -f ./$(DEPDIR)/libfb_la-fbpush.Plo -rm -f ./$(DEPDIR)/libfb_la-fbscreen.Plo -rm -f ./$(DEPDIR)/libfb_la-fbseg.Plo -rm -f ./$(DEPDIR)/libfb_la-fbsetsp.Plo -rm -f ./$(DEPDIR)/libfb_la-fbsolid.Plo -rm -f ./$(DEPDIR)/libfb_la-fbtrap.Plo -rm -f ./$(DEPDIR)/libfb_la-fbutil.Plo -rm -f ./$(DEPDIR)/libfb_la-fbwindow.Plo -rm -f ./$(DEPDIR)/libwfb_la-fballpriv.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbarc.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbbits.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbblt.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbbltone.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbcmap_mi.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbcopy.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbfill.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbfillrect.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbfillsp.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbgc.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbgetsp.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbglyph.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbimage.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbline.Plo -rm -f ./$(DEPDIR)/libwfb_la-fboverlay.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbpict.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbpixmap.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbpoint.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbpush.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbscreen.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbseg.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbsetsp.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbsolid.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbtrap.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbutil.Plo -rm -f ./$(DEPDIR)/libwfb_la-fbwindow.Plo -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 TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am 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 tags-am uninstall uninstall-am \ uninstall-sdkHEADERS .PRECIOUS: Makefile # 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: xorg-server-1.20.13/fb/fballpriv.c0000644000175000017500000000372414100573756013614 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" static DevPrivateKeyRec fbScreenPrivateKeyRec; DevPrivateKey fbGetScreenPrivateKey(void) { return &fbScreenPrivateKeyRec; } Bool fbAllocatePrivates(ScreenPtr pScreen) { FbScreenPrivPtr pScrPriv; if (!dixRegisterPrivateKey (&fbScreenPrivateKeyRec, PRIVATE_SCREEN, sizeof(FbScreenPrivRec))) return FALSE; pScrPriv = fbGetScreenPrivate(pScreen); if (!dixRegisterScreenSpecificPrivateKey (pScreen, &pScrPriv->gcPrivateKeyRec, PRIVATE_GC, sizeof(FbGCPrivRec))) return FALSE; if (!dixRegisterScreenSpecificPrivateKey (pScreen, &pScrPriv->winPrivateKeyRec, PRIVATE_WINDOW, 0)) return FALSE; return TRUE; } #ifdef FB_ACCESS_WRAPPER ReadMemoryProcPtr wfbReadMemory; WriteMemoryProcPtr wfbWriteMemory; #endif xorg-server-1.20.13/fb/fbarc.c0000644000175000017500000001167614100573756012715 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" #include "mizerarc.h" #include typedef void (*FbArc) (FbBits * dst, FbStride dstStride, int dstBpp, xArc * arc, int dx, int dy, FbBits and, FbBits xor); void fbPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs) { FbArc arc; if (pGC->lineWidth == 0) { arc = 0; if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid) { switch (pDrawable->bitsPerPixel) { case 8: arc = fbArc8; break; case 16: arc = fbArc16; break; case 32: arc = fbArc32; break; } } if (arc) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; BoxRec box; int x2, y2; RegionPtr cclip; #ifdef FB_ACCESS_WRAPPER int wrapped = 1; #endif cclip = fbGetCompositeClip(pGC); fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); while (narcs--) { if (miCanZeroArc(parcs)) { box.x1 = parcs->x + pDrawable->x; box.y1 = parcs->y + pDrawable->y; /* * Because box.x2 and box.y2 get truncated to 16 bits, and the * RECT_IN_REGION test treats the resulting number as a signed * integer, the RECT_IN_REGION test alone can go the wrong way. * This can result in a server crash because the rendering * routines in this file deal directly with cpu addresses * of pixels to be stored, and do not clip or otherwise check * that all such addresses are within their respective pixmaps. * So we only allow the RECT_IN_REGION test to be used for * values that can be expressed correctly in a signed short. */ x2 = box.x1 + (int) parcs->width + 1; box.x2 = x2; y2 = box.y1 + (int) parcs->height + 1; box.y2 = y2; if ((x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && (RegionContainsRect(cclip, &box) == rgnIN)) { #ifdef FB_ACCESS_WRAPPER if (!wrapped) { fbPrepareAccess(pDrawable); wrapped = 1; } #endif (*arc) (dst, dstStride, dstBpp, parcs, pDrawable->x + dstXoff, pDrawable->y + dstYoff, pPriv->and, pPriv->xor); } else { #ifdef FB_ACCESS_WRAPPER if (wrapped) { fbFinishAccess(pDrawable); wrapped = 0; } #endif miZeroPolyArc(pDrawable, pGC, 1, parcs); } } else { #ifdef FB_ACCESS_WRAPPER if (wrapped) { fbFinishAccess(pDrawable); wrapped = 0; } #endif miPolyArc(pDrawable, pGC, 1, parcs); } parcs++; } #ifdef FB_ACCESS_WRAPPER if (wrapped) { fbFinishAccess(pDrawable); wrapped = 0; } #endif } else miZeroPolyArc(pDrawable, pGC, narcs, parcs); } else miPolyArc(pDrawable, pGC, narcs, parcs); } xorg-server-1.20.13/fb/fbbits.c0000644000175000017500000000507414100573756013104 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" #include "miline.h" #include "mizerarc.h" #undef BRESSOLID #undef BRESDASH #undef DOTS #undef ARC #undef GLYPH #undef BITS #undef BITS2 #undef BITS4 #define BRESSOLID fbBresSolid8 #define BRESDASH fbBresDash8 #define DOTS fbDots8 #define ARC fbArc8 #define GLYPH fbGlyph8 #define POLYLINE fbPolyline8 #define POLYSEGMENT fbPolySegment8 #define BITS BYTE #define BITS2 CARD16 #define BITS4 CARD32 #include "fbbits.h" #undef BRESSOLID #undef BRESDASH #undef DOTS #undef ARC #undef GLYPH #undef POLYLINE #undef POLYSEGMENT #undef BITS #undef BITS2 #undef BITS4 #define BRESSOLID fbBresSolid16 #define BRESDASH fbBresDash16 #define DOTS fbDots16 #define ARC fbArc16 #define GLYPH fbGlyph16 #define POLYLINE fbPolyline16 #define POLYSEGMENT fbPolySegment16 #define BITS CARD16 #define BITS2 CARD32 #include "fbbits.h" #undef BRESSOLID #undef BRESDASH #undef DOTS #undef ARC #undef GLYPH #undef POLYLINE #undef POLYSEGMENT #undef BITS #undef BITS2 #define BRESSOLID fbBresSolid32 #define BRESDASH fbBresDash32 #define DOTS fbDots32 #define ARC fbArc32 #define GLYPH fbGlyph32 #define POLYLINE fbPolyline32 #define POLYSEGMENT fbPolySegment32 #define BITS CARD32 #include "fbbits.h" #undef BRESSOLID #undef BRESDASH #undef DOTS #undef ARC #undef GLYPH #undef POLYLINE #undef POLYSEGMENT #undef BITS xorg-server-1.20.13/fb/fbbits.h0000644000175000017500000006051014100573756013105 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * This file defines functions for drawing some primitives using * underlying datatypes instead of masks */ #define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000) #ifdef HAVE_DIX_CONFIG_H #include #endif #ifdef BITSSTORE #define STORE(b,x) BITSSTORE(b,x) #else #define STORE(b,x) WRITE((b), (x)) #endif #ifdef BITSRROP #define RROP(b,a,x) BITSRROP(b,a,x) #else #define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x))) #endif #ifdef BITSUNIT #define UNIT BITSUNIT #define USE_SOLID #else #define UNIT BITS #endif /* * Define the following before including this file: * * BRESSOLID name of function for drawing a solid segment * BRESDASH name of function for drawing a dashed segment * DOTS name of function for drawing dots * ARC name of function for drawing a solid arc * BITS type of underlying unit */ #ifdef BRESSOLID void BRESSOLID(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); UNIT *bits; FbStride bitsStride; FbStride majorStep, minorStep; BITS xor = (BITS) pPriv->xor; fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); bits = ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff); bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); if (signdy < 0) bitsStride = -bitsStride; if (axis == X_AXIS) { majorStep = signdx; minorStep = bitsStride; } else { majorStep = bitsStride; minorStep = signdx; } while (len--) { STORE(bits, xor); bits += majorStep; e += e1; if (e >= 0) { bits += minorStep; e += e3; } } fbFinishAccess(pDrawable); } #endif #ifdef BRESDASH void BRESDASH(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); UNIT *bits; FbStride bitsStride; FbStride majorStep, minorStep; BITS xorfg, xorbg; FbDashDeclare; int dashlen; Bool even; Bool doOdd; fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); doOdd = pGC->lineStyle == LineDoubleDash; xorfg = (BITS) pPriv->xor; xorbg = (BITS) pPriv->bgxor; FbDashInit(pGC, pPriv, dashOffset, dashlen, even); bits = ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff); bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); if (signdy < 0) bitsStride = -bitsStride; if (axis == X_AXIS) { majorStep = signdx; minorStep = bitsStride; } else { majorStep = bitsStride; minorStep = signdx; } if (dashlen >= len) dashlen = len; if (doOdd) { if (!even) goto doubleOdd; for (;;) { len -= dashlen; while (dashlen--) { STORE(bits, xorfg); bits += majorStep; if ((e += e1) >= 0) { e += e3; bits += minorStep; } } if (!len) break; FbDashNextEven(dashlen); if (dashlen >= len) dashlen = len; doubleOdd: len -= dashlen; while (dashlen--) { STORE(bits, xorbg); bits += majorStep; if ((e += e1) >= 0) { e += e3; bits += minorStep; } } if (!len) break; FbDashNextOdd(dashlen); if (dashlen >= len) dashlen = len; } } else { if (!even) goto onOffOdd; for (;;) { len -= dashlen; while (dashlen--) { STORE(bits, xorfg); bits += majorStep; if ((e += e1) >= 0) { e += e3; bits += minorStep; } } if (!len) break; FbDashNextEven(dashlen); if (dashlen >= len) dashlen = len; onOffOdd: len -= dashlen; while (dashlen--) { bits += majorStep; if ((e += e1) >= 0) { e += e3; bits += minorStep; } } if (!len) break; FbDashNextOdd(dashlen); if (dashlen >= len) dashlen = len; } } fbFinishAccess(pDrawable); } #endif #ifdef DOTS void DOTS(FbBits * dst, FbStride dstStride, int dstBpp, BoxPtr pBox, xPoint * ptsOrig, int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor) { INT32 *pts = (INT32 *) ptsOrig; UNIT *bits = (UNIT *) dst; UNIT *point; BITS bxor = (BITS) xor; BITS band = (BITS) and; FbStride bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); INT32 ul, lr; INT32 pt; ul = coordToInt(pBox->x1 - xorg, pBox->y1 - yorg); lr = coordToInt(pBox->x2 - xorg - 1, pBox->y2 - yorg - 1); bits += bitsStride * (yorg + yoff) + (xorg + xoff); if (and == 0) { while (npt--) { pt = *pts++; if (!isClipped(pt, ul, lr)) { point = bits + intToY(pt) * bitsStride + intToX(pt); STORE(point, bxor); } } } else { while (npt--) { pt = *pts++; if (!isClipped(pt, ul, lr)) { point = bits + intToY(pt) * bitsStride + intToX(pt); RROP(point, band, bxor); } } } } #endif #ifdef ARC #define ARCCOPY(d) STORE(d,xorBits) #define ARCRROP(d) RROP(d,andBits,xorBits) void ARC(FbBits * dst, FbStride dstStride, int dstBpp, xArc * arc, int drawX, int drawY, FbBits and, FbBits xor) { UNIT *bits; FbStride bitsStride; miZeroArcRec info; Bool do360; int x; UNIT *yorgp, *yorgop; BITS andBits, xorBits; int yoffset, dyoffset; int y, a, b, d, mask; int k1, k3, dx, dy; bits = (UNIT *) dst; bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); andBits = (BITS) and; xorBits = (BITS) xor; do360 = miZeroArcSetup(arc, &info, TRUE); yorgp = bits + ((info.yorg + drawY) * bitsStride); yorgop = bits + ((info.yorgo + drawY) * bitsStride); info.xorg = (info.xorg + drawX); info.xorgo = (info.xorgo + drawX); MIARCSETUP(); yoffset = y ? bitsStride : 0; dyoffset = 0; mask = info.initialMask; if (!(arc->width & 1)) { if (andBits == 0) { if (mask & 2) ARCCOPY(yorgp + info.xorgo); if (mask & 8) ARCCOPY(yorgop + info.xorgo); } else { if (mask & 2) ARCRROP(yorgp + info.xorgo); if (mask & 8) ARCRROP(yorgop + info.xorgo); } } if (!info.end.x || !info.end.y) { mask = info.end.mask; info.end = info.altend; } if (do360 && (arc->width == arc->height) && !(arc->width & 1)) { int xoffset = bitsStride; UNIT *yorghb = yorgp + (info.h * bitsStride) + info.xorg; UNIT *yorgohb = yorghb - info.h; yorgp += info.xorg; yorgop += info.xorg; yorghb += info.h; while (1) { if (andBits == 0) { ARCCOPY(yorgp + yoffset + x); ARCCOPY(yorgp + yoffset - x); ARCCOPY(yorgop - yoffset - x); ARCCOPY(yorgop - yoffset + x); } else { ARCRROP(yorgp + yoffset + x); ARCRROP(yorgp + yoffset - x); ARCRROP(yorgop - yoffset - x); ARCRROP(yorgop - yoffset + x); } if (a < 0) break; if (andBits == 0) { ARCCOPY(yorghb - xoffset - y); ARCCOPY(yorgohb - xoffset + y); ARCCOPY(yorgohb + xoffset + y); ARCCOPY(yorghb + xoffset - y); } else { ARCRROP(yorghb - xoffset - y); ARCRROP(yorgohb - xoffset + y); ARCRROP(yorgohb + xoffset + y); ARCRROP(yorghb + xoffset - y); } xoffset += bitsStride; MIARCCIRCLESTEP(yoffset += bitsStride; ); } yorgp -= info.xorg; yorgop -= info.xorg; x = info.w; yoffset = info.h * bitsStride; } else if (do360) { while (y < info.h || x < info.w) { MIARCOCTANTSHIFT(dyoffset = bitsStride; ); if (andBits == 0) { ARCCOPY(yorgp + yoffset + info.xorg + x); ARCCOPY(yorgp + yoffset + info.xorgo - x); ARCCOPY(yorgop - yoffset + info.xorgo - x); ARCCOPY(yorgop - yoffset + info.xorg + x); } else { ARCRROP(yorgp + yoffset + info.xorg + x); ARCRROP(yorgp + yoffset + info.xorgo - x); ARCRROP(yorgop - yoffset + info.xorgo - x); ARCRROP(yorgop - yoffset + info.xorg + x); } MIARCSTEP(yoffset += dyoffset; , yoffset += bitsStride; ); } } else { while (y < info.h || x < info.w) { MIARCOCTANTSHIFT(dyoffset = bitsStride; ); if ((x == info.start.x) || (y == info.start.y)) { mask = info.start.mask; info.start = info.altstart; } if (andBits == 0) { if (mask & 1) ARCCOPY(yorgp + yoffset + info.xorg + x); if (mask & 2) ARCCOPY(yorgp + yoffset + info.xorgo - x); if (mask & 4) ARCCOPY(yorgop - yoffset + info.xorgo - x); if (mask & 8) ARCCOPY(yorgop - yoffset + info.xorg + x); } else { if (mask & 1) ARCRROP(yorgp + yoffset + info.xorg + x); if (mask & 2) ARCRROP(yorgp + yoffset + info.xorgo - x); if (mask & 4) ARCRROP(yorgop - yoffset + info.xorgo - x); if (mask & 8) ARCRROP(yorgop - yoffset + info.xorg + x); } if ((x == info.end.x) || (y == info.end.y)) { mask = info.end.mask; info.end = info.altend; } MIARCSTEP(yoffset += dyoffset; , yoffset += bitsStride; ); } } if ((x == info.start.x) || (y == info.start.y)) mask = info.start.mask; if (andBits == 0) { if (mask & 1) ARCCOPY(yorgp + yoffset + info.xorg + x); if (mask & 4) ARCCOPY(yorgop - yoffset + info.xorgo - x); if (arc->height & 1) { if (mask & 2) ARCCOPY(yorgp + yoffset + info.xorgo - x); if (mask & 8) ARCCOPY(yorgop - yoffset + info.xorg + x); } } else { if (mask & 1) ARCRROP(yorgp + yoffset + info.xorg + x); if (mask & 4) ARCRROP(yorgop - yoffset + info.xorgo - x); if (arc->height & 1) { if (mask & 2) ARCRROP(yorgp + yoffset + info.xorgo - x); if (mask & 8) ARCRROP(yorgop - yoffset + info.xorg + x); } } } #undef ARCCOPY #undef ARCRROP #endif #ifdef GLYPH #if BITMAP_BIT_ORDER == LSBFirst #define WRITE_ADDR1(n) (n) #define WRITE_ADDR2(n) (n) #define WRITE_ADDR4(n) (n) #else #define WRITE_ADDR1(n) ((n) ^ 3) #define WRITE_ADDR2(n) ((n) ^ 2) #define WRITE_ADDR4(n) ((n)) #endif #define WRITE1(d,n,fg) WRITE(d + WRITE_ADDR1(n), (BITS) (fg)) #ifdef BITS2 #define WRITE2(d,n,fg) WRITE((BITS2 *) &((d)[WRITE_ADDR2(n)]), (BITS2) (fg)) #else #define WRITE2(d,n,fg) (WRITE1(d,n,fg), WRITE1(d,(n)+1,fg)) #endif #ifdef BITS4 #define WRITE4(d,n,fg) WRITE((BITS4 *) &((d)[WRITE_ADDR4(n)]), (BITS4) (fg)) #else #define WRITE4(d,n,fg) (WRITE2(d,n,fg), WRITE2(d,(n)+2,fg)) #endif void GLYPH(FbBits * dstBits, FbStride dstStride, int dstBpp, FbStip * stipple, FbBits fg, int x, int height) { int lshift; FbStip bits; BITS *dstLine; BITS *dst; int n; int shift; dstLine = (BITS *) dstBits; dstLine += x & ~3; dstStride *= (sizeof(FbBits) / sizeof(BITS)); shift = x & 3; lshift = 4 - shift; while (height--) { bits = *stipple++; dst = (BITS *) dstLine; n = lshift; while (bits) { switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) { case 0: break; case 1: WRITE1(dst, 0, fg); break; case 2: WRITE1(dst, 1, fg); break; case 3: WRITE2(dst, 0, fg); break; case 4: WRITE1(dst, 2, fg); break; case 5: WRITE1(dst, 0, fg); WRITE1(dst, 2, fg); break; case 6: WRITE1(dst, 1, fg); WRITE1(dst, 2, fg); break; case 7: WRITE2(dst, 0, fg); WRITE1(dst, 2, fg); break; case 8: WRITE1(dst, 3, fg); break; case 9: WRITE1(dst, 0, fg); WRITE1(dst, 3, fg); break; case 10: WRITE1(dst, 1, fg); WRITE1(dst, 3, fg); break; case 11: WRITE2(dst, 0, fg); WRITE1(dst, 3, fg); break; case 12: WRITE2(dst, 2, fg); break; case 13: WRITE1(dst, 0, fg); WRITE2(dst, 2, fg); break; case 14: WRITE1(dst, 1, fg); WRITE2(dst, 2, fg); break; case 15: WRITE4(dst, 0, fg); break; } bits = FbStipLeft(bits, n); n = 4; dst += 4; } dstLine += dstStride; } } #undef WRITE_ADDR1 #undef WRITE_ADDR2 #undef WRITE_ADDR4 #undef WRITE1 #undef WRITE2 #undef WRITE4 #endif #ifdef POLYLINE void POLYLINE(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ptsOrig) { INT32 *pts = (INT32 *) ptsOrig; int xoff = pDrawable->x; int yoff = pDrawable->y; unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); BoxPtr pBox = RegionExtents(fbGetCompositeClip(pGC)); FbBits *dst; int dstStride; int dstBpp; int dstXoff, dstYoff; UNIT *bits, *bitsBase; FbStride bitsStride; BITS xor = fbGetGCPrivate(pGC)->xor; BITS and = fbGetGCPrivate(pGC)->and; int dashoffset = 0; INT32 ul, lr; INT32 pt1, pt2; int e, e1, e3, len; int stepmajor, stepminor; int octant; if (mode == CoordModePrevious) fbFixCoordModePrevious(npt, ptsOrig); fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); bitsBase = ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff); ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff); lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1); pt1 = *pts++; npt--; pt2 = *pts++; npt--; for (;;) { if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) { fbSegment(pDrawable, pGC, intToX(pt1) + xoff, intToY(pt1) + yoff, intToX(pt2) + xoff, intToY(pt2) + yoff, npt == 0 && pGC->capStyle != CapNotLast, &dashoffset); if (!npt) { fbFinishAccess(pDrawable); return; } pt1 = pt2; pt2 = *pts++; npt--; } else { bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1); for (;;) { CalcLineDeltas(intToX(pt1), intToY(pt1), intToX(pt2), intToY(pt2), len, e1, stepmajor, stepminor, 1, bitsStride, octant); if (len < e1) { e3 = len; len = e1; e1 = e3; e3 = stepminor; stepminor = stepmajor; stepmajor = e3; SetYMajorOctant(octant); } e = -len; e1 <<= 1; e3 = e << 1; FIXUP_ERROR(e, octant, bias); if (and == 0) { while (len--) { STORE(bits, xor); bits += stepmajor; e += e1; if (e >= 0) { bits += stepminor; e += e3; } } } else { while (len--) { RROP(bits, and, xor); bits += stepmajor; e += e1; if (e >= 0) { bits += stepminor; e += e3; } } } if (!npt) { if (pGC->capStyle != CapNotLast && pt2 != *((INT32 *) ptsOrig)) { RROP(bits, and, xor); } fbFinishAccess(pDrawable); return; } pt1 = pt2; pt2 = *pts++; --npt; if (isClipped(pt2, ul, lr)) break; } } } fbFinishAccess(pDrawable); } #endif #ifdef POLYSEGMENT void POLYSEGMENT(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg) { INT32 *pts = (INT32 *) pseg; int xoff = pDrawable->x; int yoff = pDrawable->y; unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); BoxPtr pBox = RegionExtents(fbGetCompositeClip(pGC)); FbBits *dst; int dstStride; int dstBpp; int dstXoff, dstYoff; UNIT *bits, *bitsBase; FbStride bitsStride; FbBits xorBits = fbGetGCPrivate(pGC)->xor; FbBits andBits = fbGetGCPrivate(pGC)->and; BITS xor = xorBits; BITS and = andBits; int dashoffset = 0; INT32 ul, lr; INT32 pt1, pt2; int e, e1, e3, len; int stepmajor, stepminor; int octant; Bool capNotLast; fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT)); bitsBase = ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff); ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff); lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1); capNotLast = pGC->capStyle == CapNotLast; while (nseg--) { pt1 = *pts++; pt2 = *pts++; if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) { fbSegment(pDrawable, pGC, intToX(pt1) + xoff, intToY(pt1) + yoff, intToX(pt2) + xoff, intToY(pt2) + yoff, !capNotLast, &dashoffset); } else { CalcLineDeltas(intToX(pt1), intToY(pt1), intToX(pt2), intToY(pt2), len, e1, stepmajor, stepminor, 1, bitsStride, octant); if (e1 == 0 && len > 3) { int x1, x2; FbBits *dstLine; int dstX, width; FbBits startmask, endmask; int nmiddle; if (stepmajor < 0) { x1 = intToX(pt2); x2 = intToX(pt1) + 1; if (capNotLast) x1++; } else { x1 = intToX(pt1); x2 = intToX(pt2); if (!capNotLast) x2++; } dstX = (x1 + xoff + dstXoff) * (sizeof(UNIT) * 8); width = (x2 - x1) * (sizeof(UNIT) * 8); dstLine = dst + (intToY(pt1) + yoff + dstYoff) * dstStride; dstLine += dstX >> FB_SHIFT; dstX &= FB_MASK; FbMaskBits(dstX, width, startmask, nmiddle, endmask); if (startmask) { WRITE(dstLine, FbDoMaskRRop(READ(dstLine), andBits, xorBits, startmask)); dstLine++; } if (!andBits) while (nmiddle--) WRITE(dstLine++, xorBits); else while (nmiddle--) { WRITE(dstLine, FbDoRRop(READ(dstLine), andBits, xorBits)); dstLine++; } if (endmask) WRITE(dstLine, FbDoMaskRRop(READ(dstLine), andBits, xorBits, endmask)); } else { bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1); if (len < e1) { e3 = len; len = e1; e1 = e3; e3 = stepminor; stepminor = stepmajor; stepmajor = e3; SetYMajorOctant(octant); } e = -len; e1 <<= 1; e3 = e << 1; FIXUP_ERROR(e, octant, bias); if (!capNotLast) len++; if (and == 0) { while (len--) { STORE(bits, xor); bits += stepmajor; e += e1; if (e >= 0) { bits += stepminor; e += e3; } } } else { while (len--) { RROP(bits, and, xor); bits += stepmajor; e += e1; if (e >= 0) { bits += stepminor; e += e3; } } } } } } fbFinishAccess(pDrawable); } #endif #undef STORE #undef RROP #undef UNIT #undef USE_SOLID #undef isClipped xorg-server-1.20.13/fb/fbblt.c0000644000175000017500000002514314100573756012723 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "fb.h" #define InitializeShifts(sx,dx,ls,rs) { \ if (sx != dx) { \ if (sx > dx) { \ ls = sx - dx; \ rs = FB_UNIT - ls; \ } else { \ rs = dx - sx; \ ls = FB_UNIT - rs; \ } \ } \ } void fbBlt(FbBits * srcLine, FbStride srcStride, int srcX, FbBits * dstLine, FbStride dstStride, int dstX, int width, int height, int alu, FbBits pm, int bpp, Bool reverse, Bool upsidedown) { FbBits *src, *dst; int leftShift, rightShift; FbBits startmask, endmask; FbBits bits, bits1; int n, nmiddle; Bool destInvarient; int startbyte, endbyte; FbDeclareMergeRop(); if (alu == GXcopy && pm == FB_ALLONES && !(srcX & 7) && !(dstX & 7) && !(width & 7)) { CARD8 *src_byte = (CARD8 *) srcLine + (srcX >> 3); CARD8 *dst_byte = (CARD8 *) dstLine + (dstX >> 3); FbStride src_byte_stride = srcStride << (FB_SHIFT - 3); FbStride dst_byte_stride = dstStride << (FB_SHIFT - 3); int width_byte = (width >> 3); /* Make sure there's no overlap; we can't use memcpy in that * case as it's not well defined, so fall through to the * general code */ if (src_byte + width_byte <= dst_byte || dst_byte + width_byte <= src_byte) { int i; if (!upsidedown) for (i = 0; i < height; i++) MEMCPY_WRAPPED(dst_byte + i * dst_byte_stride, src_byte + i * src_byte_stride, width_byte); else for (i = height - 1; i >= 0; i--) MEMCPY_WRAPPED(dst_byte + i * dst_byte_stride, src_byte + i * src_byte_stride, width_byte); return; } } FbInitializeMergeRop(alu, pm); destInvarient = FbDestInvarientMergeRop(); if (upsidedown) { srcLine += (height - 1) * (srcStride); dstLine += (height - 1) * (dstStride); srcStride = -srcStride; dstStride = -dstStride; } FbMaskBitsBytes(dstX, width, destInvarient, startmask, startbyte, nmiddle, endmask, endbyte); if (reverse) { srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1; dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1; srcX = (srcX + width - 1) & FB_MASK; dstX = (dstX + width - 1) & FB_MASK; } else { srcLine += srcX >> FB_SHIFT; dstLine += dstX >> FB_SHIFT; srcX &= FB_MASK; dstX &= FB_MASK; } if (srcX == dstX) { while (height--) { src = srcLine; srcLine += srcStride; dst = dstLine; dstLine += dstStride; if (reverse) { if (endmask) { bits = READ(--src); --dst; FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); } n = nmiddle; if (destInvarient) { while (n--) WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src))); } else { while (n--) { bits = READ(--src); --dst; WRITE(dst, FbDoMergeRop(bits, READ(dst))); } } if (startmask) { bits = READ(--src); --dst; FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); } } else { if (startmask) { bits = READ(src++); FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); dst++; } n = nmiddle; if (destInvarient) { #if 0 /* * This provides some speedup on screen->screen blts * over the PCI bus, usually about 10%. But fb * isn't usually used for this operation... */ if (_ca2 + 1 == 0 && _cx2 == 0) { FbBits t1, t2, t3, t4; while (n >= 4) { t1 = *src++; t2 = *src++; t3 = *src++; t4 = *src++; *dst++ = t1; *dst++ = t2; *dst++ = t3; *dst++ = t4; n -= 4; } } #endif while (n--) WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++))); } else { while (n--) { bits = READ(src++); WRITE(dst, FbDoMergeRop(bits, READ(dst))); dst++; } } if (endmask) { bits = READ(src); FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); } } } } else { if (srcX > dstX) { leftShift = srcX - dstX; rightShift = FB_UNIT - leftShift; } else { rightShift = dstX - srcX; leftShift = FB_UNIT - rightShift; } while (height--) { src = srcLine; srcLine += srcStride; dst = dstLine; dstLine += dstStride; bits1 = 0; if (reverse) { if (srcX < dstX) bits1 = READ(--src); if (endmask) { bits = FbScrRight(bits1, rightShift); if (FbScrRight(endmask, leftShift)) { bits1 = READ(--src); bits |= FbScrLeft(bits1, leftShift); } --dst; FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); } n = nmiddle; if (destInvarient) { while (n--) { bits = FbScrRight(bits1, rightShift); bits1 = READ(--src); bits |= FbScrLeft(bits1, leftShift); --dst; WRITE(dst, FbDoDestInvarientMergeRop(bits)); } } else { while (n--) { bits = FbScrRight(bits1, rightShift); bits1 = READ(--src); bits |= FbScrLeft(bits1, leftShift); --dst; WRITE(dst, FbDoMergeRop(bits, READ(dst))); } } if (startmask) { bits = FbScrRight(bits1, rightShift); if (FbScrRight(startmask, leftShift)) { bits1 = READ(--src); bits |= FbScrLeft(bits1, leftShift); } --dst; FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); } } else { if (srcX > dstX) bits1 = READ(src++); if (startmask) { bits = FbScrLeft(bits1, leftShift); if (FbScrLeft(startmask, rightShift)) { bits1 = READ(src++); bits |= FbScrRight(bits1, rightShift); } FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); dst++; } n = nmiddle; if (destInvarient) { while (n--) { bits = FbScrLeft(bits1, leftShift); bits1 = READ(src++); bits |= FbScrRight(bits1, rightShift); WRITE(dst, FbDoDestInvarientMergeRop(bits)); dst++; } } else { while (n--) { bits = FbScrLeft(bits1, leftShift); bits1 = READ(src++); bits |= FbScrRight(bits1, rightShift); WRITE(dst, FbDoMergeRop(bits, READ(dst))); dst++; } } if (endmask) { bits = FbScrLeft(bits1, leftShift); if (FbScrLeft(endmask, rightShift)) { bits1 = READ(src); bits |= FbScrRight(bits1, rightShift); } FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); } } } } } void fbBltStip(FbStip * src, FbStride srcStride, /* in FbStip units, not FbBits units */ int srcX, FbStip * dst, FbStride dstStride, /* in FbStip units, not FbBits units */ int dstX, int width, int height, int alu, FbBits pm, int bpp) { fbBlt((FbBits *) src, FbStipStrideToBitsStride(srcStride), srcX, (FbBits *) dst, FbStipStrideToBitsStride(dstStride), dstX, width, height, alu, pm, bpp, FALSE, FALSE); } xorg-server-1.20.13/fb/fbbltone.c0000644000175000017500000003520214100573756013422 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" /* * Stipple masks are independent of bit/byte order as long * as bitorder == byteorder. FB doesn't handle the case * where these differ */ #define BitsMask(x,w) ((FB_ALLONES << ((x) & FB_MASK)) & \ (FB_ALLONES >> ((FB_UNIT - ((x) + (w))) & FB_MASK))) #define Mask(x,w) BitsMask((x)*(w),(w)) #define SelMask(b,n,w) ((((b) >> n) & 1) * Mask(n,w)) #define C1(b,w) \ (SelMask(b,0,w)) #define C2(b,w) \ (SelMask(b,0,w) | \ SelMask(b,1,w)) #define C4(b,w) \ (SelMask(b,0,w) | \ SelMask(b,1,w) | \ SelMask(b,2,w) | \ SelMask(b,3,w)) #define C8(b,w) \ (SelMask(b,0,w) | \ SelMask(b,1,w) | \ SelMask(b,2,w) | \ SelMask(b,3,w) | \ SelMask(b,4,w) | \ SelMask(b,5,w) | \ SelMask(b,6,w) | \ SelMask(b,7,w)) static const FbBits fbStipple8Bits[256] = { C8(0, 4), C8(1, 4), C8(2, 4), C8(3, 4), C8(4, 4), C8(5, 4), C8(6, 4), C8(7, 4), C8(8, 4), C8(9, 4), C8(10, 4), C8(11, 4), C8(12, 4), C8(13, 4), C8(14, 4), C8(15, 4), C8(16, 4), C8(17, 4), C8(18, 4), C8(19, 4), C8(20, 4), C8(21, 4), C8(22, 4), C8(23, 4), C8(24, 4), C8(25, 4), C8(26, 4), C8(27, 4), C8(28, 4), C8(29, 4), C8(30, 4), C8(31, 4), C8(32, 4), C8(33, 4), C8(34, 4), C8(35, 4), C8(36, 4), C8(37, 4), C8(38, 4), C8(39, 4), C8(40, 4), C8(41, 4), C8(42, 4), C8(43, 4), C8(44, 4), C8(45, 4), C8(46, 4), C8(47, 4), C8(48, 4), C8(49, 4), C8(50, 4), C8(51, 4), C8(52, 4), C8(53, 4), C8(54, 4), C8(55, 4), C8(56, 4), C8(57, 4), C8(58, 4), C8(59, 4), C8(60, 4), C8(61, 4), C8(62, 4), C8(63, 4), C8(64, 4), C8(65, 4), C8(66, 4), C8(67, 4), C8(68, 4), C8(69, 4), C8(70, 4), C8(71, 4), C8(72, 4), C8(73, 4), C8(74, 4), C8(75, 4), C8(76, 4), C8(77, 4), C8(78, 4), C8(79, 4), C8(80, 4), C8(81, 4), C8(82, 4), C8(83, 4), C8(84, 4), C8(85, 4), C8(86, 4), C8(87, 4), C8(88, 4), C8(89, 4), C8(90, 4), C8(91, 4), C8(92, 4), C8(93, 4), C8(94, 4), C8(95, 4), C8(96, 4), C8(97, 4), C8(98, 4), C8(99, 4), C8(100, 4), C8(101, 4), C8(102, 4), C8(103, 4), C8(104, 4), C8(105, 4), C8(106, 4), C8(107, 4), C8(108, 4), C8(109, 4), C8(110, 4), C8(111, 4), C8(112, 4), C8(113, 4), C8(114, 4), C8(115, 4), C8(116, 4), C8(117, 4), C8(118, 4), C8(119, 4), C8(120, 4), C8(121, 4), C8(122, 4), C8(123, 4), C8(124, 4), C8(125, 4), C8(126, 4), C8(127, 4), C8(128, 4), C8(129, 4), C8(130, 4), C8(131, 4), C8(132, 4), C8(133, 4), C8(134, 4), C8(135, 4), C8(136, 4), C8(137, 4), C8(138, 4), C8(139, 4), C8(140, 4), C8(141, 4), C8(142, 4), C8(143, 4), C8(144, 4), C8(145, 4), C8(146, 4), C8(147, 4), C8(148, 4), C8(149, 4), C8(150, 4), C8(151, 4), C8(152, 4), C8(153, 4), C8(154, 4), C8(155, 4), C8(156, 4), C8(157, 4), C8(158, 4), C8(159, 4), C8(160, 4), C8(161, 4), C8(162, 4), C8(163, 4), C8(164, 4), C8(165, 4), C8(166, 4), C8(167, 4), C8(168, 4), C8(169, 4), C8(170, 4), C8(171, 4), C8(172, 4), C8(173, 4), C8(174, 4), C8(175, 4), C8(176, 4), C8(177, 4), C8(178, 4), C8(179, 4), C8(180, 4), C8(181, 4), C8(182, 4), C8(183, 4), C8(184, 4), C8(185, 4), C8(186, 4), C8(187, 4), C8(188, 4), C8(189, 4), C8(190, 4), C8(191, 4), C8(192, 4), C8(193, 4), C8(194, 4), C8(195, 4), C8(196, 4), C8(197, 4), C8(198, 4), C8(199, 4), C8(200, 4), C8(201, 4), C8(202, 4), C8(203, 4), C8(204, 4), C8(205, 4), C8(206, 4), C8(207, 4), C8(208, 4), C8(209, 4), C8(210, 4), C8(211, 4), C8(212, 4), C8(213, 4), C8(214, 4), C8(215, 4), C8(216, 4), C8(217, 4), C8(218, 4), C8(219, 4), C8(220, 4), C8(221, 4), C8(222, 4), C8(223, 4), C8(224, 4), C8(225, 4), C8(226, 4), C8(227, 4), C8(228, 4), C8(229, 4), C8(230, 4), C8(231, 4), C8(232, 4), C8(233, 4), C8(234, 4), C8(235, 4), C8(236, 4), C8(237, 4), C8(238, 4), C8(239, 4), C8(240, 4), C8(241, 4), C8(242, 4), C8(243, 4), C8(244, 4), C8(245, 4), C8(246, 4), C8(247, 4), C8(248, 4), C8(249, 4), C8(250, 4), C8(251, 4), C8(252, 4), C8(253, 4), C8(254, 4), C8(255, 4), }; static const FbBits fbStipple4Bits[16] = { C4(0, 8), C4(1, 8), C4(2, 8), C4(3, 8), C4(4, 8), C4(5, 8), C4(6, 8), C4(7, 8), C4(8, 8), C4(9, 8), C4(10, 8), C4(11, 8), C4(12, 8), C4(13, 8), C4(14, 8), C4(15, 8), }; static const FbBits fbStipple2Bits[4] = { C2(0, 16), C2(1, 16), C2(2, 16), C2(3, 16), }; static const FbBits fbStipple1Bits[2] = { C1(0, 32), C1(1, 32), }; #ifdef __clang__ /* shift overflow is intentional */ #pragma clang diagnostic ignored "-Wshift-overflow" #endif /* * Example: srcX = 13 dstX = 8 (FB unit 32 dstBpp 8) * * **** **** **** **** **** **** **** **** * ^ * ******** ******** ******** ******** * ^ * leftShift = 12 * rightShift = 20 * * Example: srcX = 0 dstX = 8 (FB unit 32 dstBpp 8) * * **** **** **** **** **** **** **** **** * ^ * ******** ******** ******** ******** * ^ * * leftShift = 24 * rightShift = 8 */ #define LoadBits {\ if (leftShift) { \ bitsRight = (src < srcEnd ? READ(src++) : 0); \ bits = (FbStipLeft (bitsLeft, leftShift) | \ FbStipRight(bitsRight, rightShift)); \ bitsLeft = bitsRight; \ } else \ bits = (src < srcEnd ? READ(src++) : 0); \ } void fbBltOne(FbStip * src, FbStride srcStride, /* FbStip units per scanline */ int srcX, /* bit position of source */ FbBits * dst, FbStride dstStride, /* FbBits units per scanline */ int dstX, /* bit position of dest */ int dstBpp, /* bits per destination unit */ int width, /* width in bits of destination */ int height, /* height in scanlines */ FbBits fgand, /* rrop values */ FbBits fgxor, FbBits bgand, FbBits bgxor) { const FbBits *fbBits; FbBits *srcEnd; int pixelsPerDst; /* dst pixels per FbBits */ int unitsPerSrc; /* src patterns per FbStip */ int leftShift, rightShift; /* align source with dest */ FbBits startmask, endmask; /* dest scanline masks */ FbStip bits = 0, bitsLeft, bitsRight; /* source bits */ FbStip left; FbBits mask; int nDst; /* dest longwords (w.o. end) */ int w; int n, nmiddle; int dstS; /* stipple-relative dst X coordinate */ Bool copy; /* accelerate dest-invariant */ Bool transparent; /* accelerate 0 nop */ int srcinc; /* source units consumed */ Bool endNeedsLoad = FALSE; /* need load for endmask */ int startbyte, endbyte; /* * Do not read past the end of the buffer! */ srcEnd = src + height * srcStride; /* * Number of destination units in FbBits == number of stipple pixels * used each time */ pixelsPerDst = FB_UNIT / dstBpp; /* * Number of source stipple patterns in FbStip */ unitsPerSrc = FB_STIP_UNIT / pixelsPerDst; copy = FALSE; transparent = FALSE; if (bgand == 0 && fgand == 0) copy = TRUE; else if (bgand == FB_ALLONES && bgxor == 0) transparent = TRUE; /* * Adjust source and dest to nearest FbBits boundary */ src += srcX >> FB_STIP_SHIFT; dst += dstX >> FB_SHIFT; srcX &= FB_STIP_MASK; dstX &= FB_MASK; FbMaskBitsBytes(dstX, width, copy, startmask, startbyte, nmiddle, endmask, endbyte); /* * Compute effective dest alignment requirement for * source -- must align source to dest unit boundary */ dstS = dstX / dstBpp; /* * Compute shift constants for effective alignement */ if (srcX >= dstS) { leftShift = srcX - dstS; rightShift = FB_STIP_UNIT - leftShift; } else { rightShift = dstS - srcX; leftShift = FB_STIP_UNIT - rightShift; } /* * Get pointer to stipple mask array for this depth */ fbBits = 0; /* unused */ switch (pixelsPerDst) { case 8: fbBits = fbStipple8Bits; break; case 4: fbBits = fbStipple4Bits; break; case 2: fbBits = fbStipple2Bits; break; case 1: fbBits = fbStipple1Bits; break; default: return; } /* * Compute total number of destination words written, but * don't count endmask */ nDst = nmiddle; if (startmask) nDst++; dstStride -= nDst; /* * Compute total number of source words consumed */ srcinc = (nDst + unitsPerSrc - 1) / unitsPerSrc; if (srcX > dstS) srcinc++; if (endmask) { endNeedsLoad = nDst % unitsPerSrc == 0; if (endNeedsLoad) srcinc++; } srcStride -= srcinc; /* * Copy rectangle */ while (height--) { w = nDst; /* total units across scanline */ n = unitsPerSrc; /* units avail in single stipple */ if (n > w) n = w; bitsLeft = 0; if (srcX > dstS) bitsLeft = READ(src++); if (n) { /* * Load first set of stipple bits */ LoadBits; /* * Consume stipple bits for startmask */ if (startmask) { mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)]; if (mask || !transparent) FbDoLeftMaskByteStippleRRop(dst, mask, fgand, fgxor, bgand, bgxor, startbyte, startmask); bits = FbStipLeft(bits, pixelsPerDst); dst++; n--; w--; } /* * Consume stipple bits across scanline */ for (;;) { w -= n; if (copy) { while (n--) { mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)]; WRITE(dst, FbOpaqueStipple(mask, fgxor, bgxor)); dst++; bits = FbStipLeft(bits, pixelsPerDst); } } else { while (n--) { left = FbLeftStipBits(bits, pixelsPerDst); if (left || !transparent) { mask = fbBits[left]; WRITE(dst, FbStippleRRop(READ(dst), mask, fgand, fgxor, bgand, bgxor)); } dst++; bits = FbStipLeft(bits, pixelsPerDst); } } if (!w) break; /* * Load another set and reset number of available units */ LoadBits; n = unitsPerSrc; if (n > w) n = w; } } /* * Consume stipple bits for endmask */ if (endmask) { if (endNeedsLoad) { LoadBits; } mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)]; if (mask || !transparent) FbDoRightMaskByteStippleRRop(dst, mask, fgand, fgxor, bgand, bgxor, endbyte, endmask); } dst += dstStride; src += srcStride; } } /* * Not very efficient, but simple -- copy a single plane * from an N bit image to a 1 bit image */ void fbBltPlane(FbBits * src, FbStride srcStride, int srcX, int srcBpp, FbStip * dst, FbStride dstStride, int dstX, int width, int height, FbStip fgand, FbStip fgxor, FbStip bgand, FbStip bgxor, Pixel planeMask) { FbBits *s; FbBits pm; FbBits srcMask; FbBits srcMaskFirst; FbBits srcMask0 = 0; FbBits srcBits; FbStip dstBits; FbStip *d; FbStip dstMask; FbStip dstMaskFirst; FbStip dstUnion; int w; int wt; if (!width) return; src += srcX >> FB_SHIFT; srcX &= FB_MASK; dst += dstX >> FB_STIP_SHIFT; dstX &= FB_STIP_MASK; w = width / srcBpp; pm = fbReplicatePixel(planeMask, srcBpp); srcMaskFirst = pm & FbBitsMask(srcX, srcBpp); srcMask0 = pm & FbBitsMask(0, srcBpp); dstMaskFirst = FbStipMask(dstX, 1); while (height--) { d = dst; dst += dstStride; s = src; src += srcStride; srcMask = srcMaskFirst; srcBits = READ(s++); dstMask = dstMaskFirst; dstUnion = 0; dstBits = 0; wt = w; while (wt--) { if (!srcMask) { srcBits = READ(s++); srcMask = srcMask0; } if (!dstMask) { WRITE(d, FbStippleRRopMask(READ(d), dstBits, fgand, fgxor, bgand, bgxor, dstUnion)); d++; dstMask = FbStipMask(0, 1); dstUnion = 0; dstBits = 0; } if (srcBits & srcMask) dstBits |= dstMask; dstUnion |= dstMask; if (srcBpp == FB_UNIT) srcMask = 0; else srcMask = FbScrRight(srcMask, srcBpp); dstMask = FbStipRight(dstMask, 1); } if (dstUnion) WRITE(d, FbStippleRRopMask(READ(d), dstBits, fgand, fgxor, bgand, bgxor, dstUnion)); } } xorg-server-1.20.13/fb/fbcmap_mi.c0000644000175000017500000000637714100573756013557 00000000000000/* * Copyright (c) 1987, Oracle and/or its affiliates. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /** * This version of fbcmap.c is implemented in terms of mi functions. * These functions used to be in fbcmap.c and depended upon the symbol * XFree86Server being defined. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "fb.h" #include "micmap.h" int fbListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps) { return miListInstalledColormaps(pScreen, pmaps); } void fbInstallColormap(ColormapPtr pmap) { miInstallColormap(pmap); } void fbUninstallColormap(ColormapPtr pmap) { miUninstallColormap(pmap); } void fbResolveColor(unsigned short *pred, unsigned short *pgreen, unsigned short *pblue, VisualPtr pVisual) { miResolveColor(pred, pgreen, pblue, pVisual); } Bool fbInitializeColormap(ColormapPtr pmap) { return miInitializeColormap(pmap); } int fbExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem * indefs, xColorItem * outdefs) { return miExpandDirectColors(pmap, ndef, indefs, outdefs); } Bool fbCreateDefColormap(ScreenPtr pScreen) { return miCreateDefColormap(pScreen); } void fbClearVisualTypes(void) { miClearVisualTypes(); } Bool fbSetVisualTypes(int depth, int visuals, int bitsPerRGB) { return miSetVisualTypes(depth, visuals, bitsPerRGB, -1); } Bool fbSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB, Pixel redMask, Pixel greenMask, Pixel blueMask) { return miSetVisualTypesAndMasks(depth, visuals, bitsPerRGB, -1, redMask, greenMask, blueMask); } /* * Given a list of formats for a screen, create a list * of visuals and depths for the screen which coorespond to * the set which can be used with this version of fb. */ Bool fbInitVisuals(VisualPtr * visualp, DepthPtr * depthp, int *nvisualp, int *ndepthp, int *rootDepthp, VisualID * defaultVisp, unsigned long sizes, int bitsPerRGB) { return miInitVisuals(visualp, depthp, nvisualp, ndepthp, rootDepthp, defaultVisp, sizes, bitsPerRGB, -1); } xorg-server-1.20.13/fb/fbcopy.c0000644000175000017500000002241414100573756013112 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "fb.h" void fbCopyNtoN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { CARD8 alu = pGC ? pGC->alu : GXcopy; FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES; FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); while (nbox--) { #ifndef FB_ACCESS_WRAPPER /* pixman_blt() doesn't support accessors yet */ if (pm == FB_ALLONES && alu == GXcopy && !reverse && !upsidedown) { if (!pixman_blt ((uint32_t *) src, (uint32_t *) dst, srcStride, dstStride, srcBpp, dstBpp, (pbox->x1 + dx + srcXoff), (pbox->y1 + dy + srcYoff), (pbox->x1 + dstXoff), (pbox->y1 + dstYoff), (pbox->x2 - pbox->x1), (pbox->y2 - pbox->y1))) goto fallback; else goto next; } fallback: #endif fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride, srcStride, (pbox->x1 + dx + srcXoff) * srcBpp, dst + (pbox->y1 + dstYoff) * dstStride, dstStride, (pbox->x1 + dstXoff) * dstBpp, (pbox->x2 - pbox->x1) * dstBpp, (pbox->y2 - pbox->y1), alu, pm, dstBpp, reverse, upsidedown); #ifndef FB_ACCESS_WRAPPER next: #endif pbox++; } fbFinishAccess(pDstDrawable); fbFinishAccess(pSrcDrawable); } void fbCopy1toN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); while (nbox--) { if (dstBpp == 1) { fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride, srcStride, (pbox->x1 + dx + srcXoff) * srcBpp, dst + (pbox->y1 + dstYoff) * dstStride, dstStride, (pbox->x1 + dstXoff) * dstBpp, (pbox->x2 - pbox->x1) * dstBpp, (pbox->y2 - pbox->y1), FbOpaqueStipple1Rop(pGC->alu, pGC->fgPixel, pGC->bgPixel), pPriv->pm, dstBpp, reverse, upsidedown); } else { fbBltOne((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride), srcStride * (FB_UNIT / FB_STIP_UNIT), (pbox->x1 + dx + srcXoff), dst + (pbox->y1 + dstYoff) * dstStride, dstStride, (pbox->x1 + dstXoff) * dstBpp, dstBpp, (pbox->x2 - pbox->x1) * dstBpp, (pbox->y2 - pbox->y1), pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor); } pbox++; } fbFinishAccess(pDstDrawable); fbFinishAccess(pSrcDrawable); } void fbCopyNto1(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); while (nbox--) { if (pDstDrawable->bitsPerPixel == 1) { FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbStip *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); fbGetStipDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride, srcStride, (pbox->x1 + dx + srcXoff) * srcBpp, srcBpp, dst + (pbox->y1 + dstYoff) * dstStride, dstStride, (pbox->x1 + dstXoff) * dstBpp, (pbox->x2 - pbox->x1) * srcBpp, (pbox->y2 - pbox->y1), (FbStip) pPriv->and, (FbStip) pPriv->xor, (FbStip) pPriv->bgand, (FbStip) pPriv->bgxor, bitplane); fbFinishAccess(pDstDrawable); fbFinishAccess(pSrcDrawable); } else { FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; FbStip *tmp; FbStride tmpStride; int width, height; width = pbox->x2 - pbox->x1; height = pbox->y2 - pbox->y1; tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT); tmp = xallocarray(tmpStride * height, sizeof(FbStip)); if (!tmp) return; fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride, srcStride, (pbox->x1 + dx + srcXoff) * srcBpp, srcBpp, tmp, tmpStride, 0, width * srcBpp, height, fbAndStip(GXcopy, FB_ALLONES, FB_ALLONES), fbXorStip(GXcopy, FB_ALLONES, FB_ALLONES), fbAndStip(GXcopy, 0, FB_ALLONES), fbXorStip(GXcopy, 0, FB_ALLONES), bitplane); fbBltOne(tmp, tmpStride, 0, dst + (pbox->y1 + dstYoff) * dstStride, dstStride, (pbox->x1 + dstXoff) * dstBpp, dstBpp, width * dstBpp, height, pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor); free(tmp); fbFinishAccess(pDstDrawable); fbFinishAccess(pSrcDrawable); } pbox++; } } RegionPtr fbCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut) { return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, fbCopyNtoN, 0, 0); } RegionPtr fbCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut, unsigned long bitplane) { if (pSrcDrawable->bitsPerPixel > 1) return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0); else if (bitplane & 1) return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, fbCopy1toN, (Pixel) bitplane, 0); else return miHandleExposures(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut); } xorg-server-1.20.13/fb/fbfill.c0000644000175000017500000002115014100573756013062 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" static void fbTile(FbBits * dst, FbStride dstStride, int dstX, int width, int height, FbBits * tile, FbStride tileStride, int tileWidth, int tileHeight, int alu, FbBits pm, int bpp, int xRot, int yRot) { int tileX, tileY; int widthTmp; int h, w; int x, y; modulus(-yRot, tileHeight, tileY); y = 0; while (height) { h = tileHeight - tileY; if (h > height) h = height; height -= h; widthTmp = width; x = dstX; modulus(dstX - xRot, tileWidth, tileX); while (widthTmp) { w = tileWidth - tileX; if (w > widthTmp) w = widthTmp; widthTmp -= w; fbBlt(tile + tileY * tileStride, tileStride, tileX, dst + y * dstStride, dstStride, x, w, h, alu, pm, bpp, FALSE, FALSE); x += w; tileX = 0; } y += h; tileY = 0; } } static void fbStipple(FbBits * dst, FbStride dstStride, int dstX, int dstBpp, int width, int height, FbStip * stip, FbStride stipStride, int stipWidth, int stipHeight, FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot) { int stipX, stipY, sx; int widthTmp; int h, w; int x, y; modulus(-yRot, stipHeight, stipY); modulus(dstX / dstBpp - xRot, stipWidth, stipX); y = 0; while (height) { h = stipHeight - stipY; if (h > height) h = height; height -= h; widthTmp = width; x = dstX; sx = stipX; while (widthTmp) { w = (stipWidth - sx) * dstBpp; if (w > widthTmp) w = widthTmp; widthTmp -= w; fbBltOne(stip + stipY * stipStride, stipStride, sx, dst + y * dstStride, dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor); x += w; sx = 0; } y += h; stipY = 0; } } void fbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height) { FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); switch (pGC->fillStyle) { case FillSolid: #ifndef FB_ACCESS_WRAPPER if (pPriv->and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp, x + dstXoff, y + dstYoff, width, height, pPriv->xor)) #endif fbSolid(dst + (y + dstYoff) * dstStride, dstStride, (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height, pPriv->and, pPriv->xor); break; case FillStippled: case FillOpaqueStippled:{ PixmapPtr pStip = pGC->stipple; int stipWidth = pStip->drawable.width; int stipHeight = pStip->drawable.height; if (dstBpp == 1) { int alu; FbBits *stip; FbStride stipStride; int stipBpp; _X_UNUSED int stipXoff, stipYoff; if (pGC->fillStyle == FillStippled) alu = FbStipple1Rop(pGC->alu, pGC->fgPixel); else alu = FbOpaqueStipple1Rop(pGC->alu, pGC->fgPixel, pGC->bgPixel); fbGetDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); fbTile(dst + (y + dstYoff) * dstStride, dstStride, x + dstXoff, width, height, stip, stipStride, stipWidth, stipHeight, alu, pPriv->pm, dstBpp, (pGC->patOrg.x + pDrawable->x + dstXoff), pGC->patOrg.y + pDrawable->y - y); fbFinishAccess(&pStip->drawable); } else { FbStip *stip; FbStride stipStride; int stipBpp; _X_UNUSED int stipXoff, stipYoff; FbBits fgand, fgxor, bgand, bgxor; fgand = pPriv->and; fgxor = pPriv->xor; if (pGC->fillStyle == FillStippled) { bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); } else { bgand = pPriv->bgand; bgxor = pPriv->bgxor; } fbGetStipDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); fbStipple(dst + (y + dstYoff) * dstStride, dstStride, (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height, stip, stipStride, stipWidth, stipHeight, fgand, fgxor, bgand, bgxor, pGC->patOrg.x + pDrawable->x + dstXoff, pGC->patOrg.y + pDrawable->y - y); fbFinishAccess(&pStip->drawable); } break; } case FillTiled:{ PixmapPtr pTile = pGC->tile.pixmap; FbBits *tile; FbStride tileStride; int tileBpp; int tileWidth; int tileHeight; _X_UNUSED int tileXoff, tileYoff; fbGetDrawable(&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff); tileWidth = pTile->drawable.width; tileHeight = pTile->drawable.height; fbTile(dst + (y + dstYoff) * dstStride, dstStride, (x + dstXoff) * dstBpp, width * dstBpp, height, tile, tileStride, tileWidth * tileBpp, tileHeight, pGC->alu, pPriv->pm, dstBpp, (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp, pGC->patOrg.y + pDrawable->y - y); fbFinishAccess(&pTile->drawable); break; } } fbValidateDrawable(pDrawable); fbFinishAccess(pDrawable); } void fbSolidBoxClipped(DrawablePtr pDrawable, RegionPtr pClip, int x1, int y1, int x2, int y2, FbBits and, FbBits xor) { FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; BoxPtr pbox; int nbox; int partX1, partX2, partY1, partY2; fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip); nbox--; pbox++) { partX1 = pbox->x1; if (partX1 < x1) partX1 = x1; partX2 = pbox->x2; if (partX2 > x2) partX2 = x2; if (partX2 <= partX1) continue; partY1 = pbox->y1; if (partY1 < y1) partY1 = y1; partY2 = pbox->y2; if (partY2 > y2) partY2 = y2; if (partY2 <= partY1) continue; #ifndef FB_ACCESS_WRAPPER if (and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp, partX1 + dstXoff, partY1 + dstYoff, (partX2 - partX1), (partY2 - partY1), xor)) #endif fbSolid(dst + (partY1 + dstYoff) * dstStride, dstStride, (partX1 + dstXoff) * dstBpp, dstBpp, (partX2 - partX1) * dstBpp, (partY2 - partY1), and, xor); } fbFinishAccess(pDrawable); } xorg-server-1.20.13/fb/fbfillrect.c0000644000175000017500000000647414100573756013754 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" void fbPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect) { RegionPtr pClip = fbGetCompositeClip(pGC); register BoxPtr pbox; BoxPtr pextent; int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1, fullY2; int partX1, partX2, partY1, partY2; int xorg, yorg; int n; xorg = pDrawable->x; yorg = pDrawable->y; pextent = RegionExtents(pClip); extentX1 = pextent->x1; extentY1 = pextent->y1; extentX2 = pextent->x2; extentY2 = pextent->y2; while (nrect--) { fullX1 = prect->x + xorg; fullY1 = prect->y + yorg; fullX2 = fullX1 + (int) prect->width; fullY2 = fullY1 + (int) prect->height; prect++; if (fullX1 < extentX1) fullX1 = extentX1; if (fullY1 < extentY1) fullY1 = extentY1; if (fullX2 > extentX2) fullX2 = extentX2; if (fullY2 > extentY2) fullY2 = extentY2; if ((fullX1 >= fullX2) || (fullY1 >= fullY2)) continue; n = RegionNumRects(pClip); if (n == 1) { fbFill(pDrawable, pGC, fullX1, fullY1, fullX2 - fullX1, fullY2 - fullY1); } else { pbox = RegionRects(pClip); /* * clip the rectangle to each box in the clip region * this is logically equivalent to calling Intersect() */ while (n--) { partX1 = pbox->x1; if (partX1 < fullX1) partX1 = fullX1; partY1 = pbox->y1; if (partY1 < fullY1) partY1 = fullY1; partX2 = pbox->x2; if (partX2 > fullX2) partX2 = fullX2; partY2 = pbox->y2; if (partY2 > fullY2) partY2 = fullY2; pbox++; if (partX1 < partX2 && partY1 < partY2) fbFill(pDrawable, pGC, partX1, partY1, partX2 - partX1, partY2 - partY1); } } } } xorg-server-1.20.13/fb/fbfillsp.c0000644000175000017500000000547314100573756013437 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" void fbFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, DDXPointPtr ppt, int *pwidth, int fSorted) { RegionPtr pClip = fbGetCompositeClip(pGC); BoxPtr pextent, pbox; int nbox; int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1; int partX1, partX2; pextent = RegionExtents(pClip); extentX1 = pextent->x1; extentY1 = pextent->y1; extentX2 = pextent->x2; extentY2 = pextent->y2; while (n--) { fullX1 = ppt->x; fullY1 = ppt->y; fullX2 = fullX1 + (int) *pwidth; ppt++; pwidth++; if (fullY1 < extentY1 || extentY2 <= fullY1) continue; if (fullX1 < extentX1) fullX1 = extentX1; if (fullX2 > extentX2) fullX2 = extentX2; if (fullX1 >= fullX2) continue; nbox = RegionNumRects(pClip); if (nbox == 1) { fbFill(pDrawable, pGC, fullX1, fullY1, fullX2 - fullX1, 1); } else { pbox = RegionRects(pClip); while (nbox--) { if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) { partX1 = pbox->x1; if (partX1 < fullX1) partX1 = fullX1; partX2 = pbox->x2; if (partX2 > fullX2) partX2 = fullX2; if (partX2 > partX1) { fbFill(pDrawable, pGC, partX1, fullY1, partX2 - partX1, 1); } } pbox++; } } } } xorg-server-1.20.13/fb/fbgc.c0000644000175000017500000001162314100573756012531 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "fb.h" const GCFuncs fbGCFuncs = { fbValidateGC, miChangeGC, miCopyGC, miDestroyGC, miChangeClip, miDestroyClip, miCopyClip, }; const GCOps fbGCOps = { fbFillSpans, fbSetSpans, fbPutImage, fbCopyArea, fbCopyPlane, fbPolyPoint, fbPolyLine, fbPolySegment, fbPolyRectangle, fbPolyArc, miFillPolygon, fbPolyFillRect, fbPolyFillArc, miPolyText8, miPolyText16, miImageText8, miImageText16, fbImageGlyphBlt, fbPolyGlyphBlt, fbPushPixels }; Bool fbCreateGC(GCPtr pGC) { pGC->ops = (GCOps *) &fbGCOps; pGC->funcs = (GCFuncs *) &fbGCFuncs; /* fb wants to translate before scan conversion */ pGC->miTranslate = 1; pGC->fExpose = 1; return TRUE; } /* * Pad pixmap to FB_UNIT bits wide */ void fbPadPixmap(PixmapPtr pPixmap) { int width; FbBits *bits; FbBits b; FbBits mask; int height; int w; int stride; int bpp; _X_UNUSED int xOff, yOff; fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff); width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel; height = pPixmap->drawable.height; mask = FbBitsMask(0, width); while (height--) { b = READ(bits) & mask; w = width; while (w < FB_UNIT) { b = b | FbScrRight(b, w); w <<= 1; } WRITE(bits, b); bits += stride; } fbFinishAccess(&pPixmap->drawable); } void fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); FbBits mask; /* * if the client clip is different or moved OR the subwindowMode has * changed OR the window's clip has changed since the last validation * we need to recompute the composite clip */ if ((changes & (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) || (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)) ) { miComputeCompositeClip(pGC, pDrawable); } if (changes & GCTile) { if (!pGC->tileIsPixel && FbEvenTile(pGC->tile.pixmap->drawable.width * pDrawable->bitsPerPixel)) fbPadPixmap(pGC->tile.pixmap); } if (changes & GCStipple) { if (pGC->stipple) { if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel < FB_UNIT) fbPadPixmap(pGC->stipple); } } /* * Recompute reduced rop values */ if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) { int s; FbBits depthMask; mask = FbFullMask(pDrawable->bitsPerPixel); depthMask = FbFullMask(pDrawable->depth); pPriv->fg = pGC->fgPixel & mask; pPriv->bg = pGC->bgPixel & mask; if ((pGC->planemask & depthMask) == depthMask) pPriv->pm = mask; else pPriv->pm = pGC->planemask & mask; s = pDrawable->bitsPerPixel; while (s < FB_UNIT) { pPriv->fg |= pPriv->fg << s; pPriv->bg |= pPriv->bg << s; pPriv->pm |= pPriv->pm << s; s <<= 1; } pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm); pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm); pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm); pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm); } if (changes & GCDashList) { unsigned short n = pGC->numInDashList; unsigned char *dash = pGC->dash; unsigned int dashLength = 0; while (n--) dashLength += (unsigned int) *dash++; pPriv->dashLength = dashLength; } } xorg-server-1.20.13/fb/fbgetsp.c0000644000175000017500000000433114100573756013260 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" void fbGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pchardstStart) { FbBits *src, *dst; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; int xoff; /* * XFree86 DDX empties the root borderClip when the VT is * switched away; this checks for that case */ if (!fbDrawableEnabled(pDrawable)) return; fbGetDrawable(pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); while (nspans--) { xoff = (int) (((long) pchardstStart) & (FB_MASK >> 3)); dst = (FbBits *) (pchardstStart - xoff); xoff <<= 3; fbBlt(src + (ppt->y + srcYoff) * srcStride, srcStride, (ppt->x + srcXoff) * srcBpp, dst, 1, xoff, *pwidth * srcBpp, 1, GXcopy, FB_ALLONES, srcBpp, FALSE, FALSE); pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth); ppt++; pwidth++; } fbFinishAccess(pDrawable); } xorg-server-1.20.13/fb/fbglyph.c0000644000175000017500000001637414100573756013273 00000000000000/* * * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" #include #include "dixfontstr.h" static Bool fbGlyphIn(RegionPtr pRegion, int x, int y, int width, int height) { BoxRec box; BoxPtr pExtents = RegionExtents(pRegion); /* * Check extents by hand to avoid 16 bit overflows */ if (x < (int) pExtents->x1) return FALSE; if ((int) pExtents->x2 < x + width) return FALSE; if (y < (int) pExtents->y1) return FALSE; if ((int) pExtents->y2 < y + height) return FALSE; box.x1 = x; box.x2 = x + width; box.y1 = y; box.y2 = y + height; return RegionContainsRect(pRegion, &box) == rgnIN; } void fbPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); CharInfoPtr pci; unsigned char *pglyph; /* pointer bits in glyph */ int gx, gy; int gWidth, gHeight; /* width and height of glyph */ FbStride gStride; /* stride of glyph */ void (*glyph) (FbBits *, FbStride, int, FbStip *, FbBits, int, int); FbBits *dst = 0; FbStride dstStride = 0; int dstBpp = 0; int dstXoff = 0, dstYoff = 0; glyph = 0; if (pGC->fillStyle == FillSolid && pPriv->and == 0) { dstBpp = pDrawable->bitsPerPixel; switch (dstBpp) { case 8: glyph = fbGlyph8; break; case 16: glyph = fbGlyph16; break; case 32: glyph = fbGlyph32; break; } } x += pDrawable->x; y += pDrawable->y; while (nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(pglyphBase, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { gx = x + pci->metrics.leftSideBearing; gy = y - pci->metrics.ascent; if (glyph && gWidth <= sizeof(FbStip) * 8 && fbGlyphIn(fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) { fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pPriv->xor, gx + dstXoff, gHeight); fbFinishAccess(pDrawable); } else { gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip); fbPushImage(pDrawable, pGC, (FbStip *) pglyph, gStride, 0, gx, gy, gWidth, gHeight); } } x += pci->metrics.characterWidth; } } void fbImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppciInit, void *pglyphBase) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); CharInfoPtr *ppci; CharInfoPtr pci; unsigned char *pglyph; /* pointer bits in glyph */ int gWidth, gHeight; /* width and height of glyph */ FbStride gStride; /* stride of glyph */ Bool opaque; int n; int gx, gy; void (*glyph) (FbBits *, FbStride, int, FbStip *, FbBits, int, int); FbBits *dst = 0; FbStride dstStride = 0; int dstBpp = 0; int dstXoff = 0, dstYoff = 0; glyph = 0; if (pPriv->and == 0) { dstBpp = pDrawable->bitsPerPixel; switch (dstBpp) { case 8: glyph = fbGlyph8; break; case 16: glyph = fbGlyph16; break; case 32: glyph = fbGlyph32; break; } } x += pDrawable->x; y += pDrawable->y; if (TERMINALFONT(pGC->font) && !glyph) { opaque = TRUE; } else { int xBack, widthBack; int yBack, heightBack; ppci = ppciInit; n = nglyph; widthBack = 0; while (n--) widthBack += (*ppci++)->metrics.characterWidth; xBack = x; if (widthBack < 0) { xBack += widthBack; widthBack = -widthBack; } yBack = y - FONTASCENT(pGC->font); heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); fbSolidBoxClipped(pDrawable, fbGetCompositeClip(pGC), xBack, yBack, xBack + widthBack, yBack + heightBack, fbAnd(GXcopy, pPriv->bg, pPriv->pm), fbXor(GXcopy, pPriv->bg, pPriv->pm)); opaque = FALSE; } ppci = ppciInit; while (nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(pglyphBase, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { gx = x + pci->metrics.leftSideBearing; gy = y - pci->metrics.ascent; if (glyph && gWidth <= sizeof(FbStip) * 8 && fbGlyphIn(fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) { fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pPriv->fg, gx + dstXoff, gHeight); fbFinishAccess(pDrawable); } else { gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip); fbPutXYImage(pDrawable, fbGetCompositeClip(pGC), pPriv->fg, pPriv->bg, pPriv->pm, GXcopy, opaque, gx, gy, gWidth, gHeight, (FbStip *) pglyph, gStride, 0); } } x += pci->metrics.characterWidth; } } xorg-server-1.20.13/fb/fbimage.c0000644000175000017500000002003214100573756013214 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "fb.h" void fbPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pImage) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); unsigned long i; FbStride srcStride; FbStip *src = (FbStip *) pImage; x += pDrawable->x; y += pDrawable->y; switch (format) { case XYBitmap: srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); fbPutXYImage(pDrawable, fbGetCompositeClip(pGC), pPriv->fg, pPriv->bg, pPriv->pm, pGC->alu, TRUE, x, y, w, h, src, srcStride, leftPad); break; case XYPixmap: srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); for (i = (unsigned long) 1 << (pDrawable->depth - 1); i; i >>= 1) { if (i & pGC->planemask) { fbPutXYImage(pDrawable, fbGetCompositeClip(pGC), FB_ALLONES, 0, fbReplicatePixel(i, pDrawable->bitsPerPixel), pGC->alu, TRUE, x, y, w, h, src, srcStride, leftPad); } src += srcStride * h; } break; case ZPixmap: srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof(FbStip); fbPutZImage(pDrawable, fbGetCompositeClip(pGC), pGC->alu, pPriv->pm, x, y, w, h, src, srcStride); } } void fbPutZImage(DrawablePtr pDrawable, RegionPtr pClip, int alu, FbBits pm, int x, int y, int width, int height, FbStip * src, FbStride srcStride) { FbStip *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; int nbox; BoxPtr pbox; int x1, y1, x2, y2; fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip); nbox--; pbox++) { x1 = x; y1 = y; x2 = x + width; y2 = y + height; if (x1 < pbox->x1) x1 = pbox->x1; if (y1 < pbox->y1) y1 = pbox->y1; if (x2 > pbox->x2) x2 = pbox->x2; if (y2 > pbox->y2) y2 = pbox->y2; if (x1 >= x2 || y1 >= y2) continue; fbBltStip(src + (y1 - y) * srcStride, srcStride, (x1 - x) * dstBpp, dst + (y1 + dstYoff) * dstStride, dstStride, (x1 + dstXoff) * dstBpp, (x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp); } fbFinishAccess(pDrawable); } void fbPutXYImage(DrawablePtr pDrawable, RegionPtr pClip, FbBits fg, FbBits bg, FbBits pm, int alu, Bool opaque, int x, int y, int width, int height, FbStip * src, FbStride srcStride, int srcX) { FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; int nbox; BoxPtr pbox; int x1, y1, x2, y2; FbBits fgand = 0, fgxor = 0, bgand = 0, bgxor = 0; fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); if (dstBpp == 1) { if (opaque) alu = FbOpaqueStipple1Rop(alu, fg, bg); else alu = FbStipple1Rop(alu, fg); } else { fgand = fbAnd(alu, fg, pm); fgxor = fbXor(alu, fg, pm); if (opaque) { bgand = fbAnd(alu, bg, pm); bgxor = fbXor(alu, bg, pm); } else { bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); } } for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip); nbox--; pbox++) { x1 = x; y1 = y; x2 = x + width; y2 = y + height; if (x1 < pbox->x1) x1 = pbox->x1; if (y1 < pbox->y1) y1 = pbox->y1; if (x2 > pbox->x2) x2 = pbox->x2; if (y2 > pbox->y2) y2 = pbox->y2; if (x1 >= x2 || y1 >= y2) continue; if (dstBpp == 1) { fbBltStip(src + (y1 - y) * srcStride, srcStride, (x1 - x) + srcX, (FbStip *) (dst + (y1 + dstYoff) * dstStride), FbBitsStrideToStipStride(dstStride), (x1 + dstXoff) * dstBpp, (x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp); } else { fbBltOne(src + (y1 - y) * srcStride, srcStride, (x1 - x) + srcX, dst + (y1 + dstYoff) * dstStride, dstStride, (x1 + dstXoff) * dstBpp, dstBpp, (x2 - x1) * dstBpp, (y2 - y1), fgand, fgxor, bgand, bgxor); } } fbFinishAccess(pDrawable); } void fbGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbStip *dst; FbStride dstStride; /* * XFree86 DDX empties the root borderClip when the VT is * switched away; this checks for that case */ if (!fbDrawableEnabled(pDrawable)) return; fbGetDrawable(pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); x += pDrawable->x; y += pDrawable->y; dst = (FbStip *) d; if (format == ZPixmap || srcBpp == 1) { FbBits pm; pm = fbReplicatePixel(planeMask, srcBpp); dstStride = PixmapBytePad(w, pDrawable->depth); dstStride /= sizeof(FbStip); fbBltStip((FbStip *) (src + (y + srcYoff) * srcStride), FbBitsStrideToStipStride(srcStride), (x + srcXoff) * srcBpp, dst, dstStride, 0, w * srcBpp, h, GXcopy, FB_ALLONES, srcBpp); if (pm != FB_ALLONES) { for (int i = 0; i < dstStride * h; i++) dst[i] &= pm; } } else { dstStride = BitmapBytePad(w) / sizeof(FbStip); fbBltPlane(src + (y + srcYoff) * srcStride, srcStride, (x + srcXoff) * srcBpp, srcBpp, dst, dstStride, 0, w * srcBpp, h, fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), fbAndStip(GXcopy, 0, FB_STIP_ALLONES), fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask); } fbFinishAccess(pDrawable); } xorg-server-1.20.13/fb/fbline.c0000644000175000017500000001013714100573756013066 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" static void fbZeroLine(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { int x1, y1, x2, y2; int x, y; int dashOffset; x = pDrawable->x; y = pDrawable->y; x1 = ppt->x; y1 = ppt->y; dashOffset = pGC->dashOffset; while (--npt) { ++ppt; x2 = ppt->x; y2 = ppt->y; if (mode == CoordModePrevious) { x2 += x1; y2 += y1; } fbSegment(pDrawable, pGC, x1 + x, y1 + y, x2 + x, y2 + y, npt == 1 && pGC->capStyle != CapNotLast, &dashOffset); x1 = x2; y1 = y2; } } static void fbZeroSegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSegs) { int dashOffset; int x, y; Bool drawLast = pGC->capStyle != CapNotLast; x = pDrawable->x; y = pDrawable->y; while (nseg--) { dashOffset = pGC->dashOffset; fbSegment(pDrawable, pGC, pSegs->x1 + x, pSegs->y1 + y, pSegs->x2 + x, pSegs->y2 + y, drawLast, &dashOffset); pSegs++; } } void fbFixCoordModePrevious(int npt, DDXPointPtr ppt) { int x, y; x = ppt->x; y = ppt->y; npt--; while (npt--) { ppt++; x = (ppt->x += x); y = (ppt->y += y); } } void fbPolyLine(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { void (*line) (DrawablePtr, GCPtr, int mode, int npt, DDXPointPtr ppt); if (pGC->lineWidth == 0) { line = fbZeroLine; if (pGC->fillStyle == FillSolid && pGC->lineStyle == LineSolid && RegionNumRects(fbGetCompositeClip(pGC)) == 1) { switch (pDrawable->bitsPerPixel) { case 8: line = fbPolyline8; break; case 16: line = fbPolyline16; break; case 32: line = fbPolyline32; break; } } } else { if (pGC->lineStyle != LineSolid) line = miWideDash; else line = miWideLine; } (*line) (pDrawable, pGC, mode, npt, ppt); } void fbPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg) { void (*seg) (DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg); if (pGC->lineWidth == 0) { seg = fbZeroSegment; if (pGC->fillStyle == FillSolid && pGC->lineStyle == LineSolid && RegionNumRects(fbGetCompositeClip(pGC)) == 1) { switch (pDrawable->bitsPerPixel) { case 8: seg = fbPolySegment8; break; case 16: seg = fbPolySegment16; break; case 32: seg = fbPolySegment32; break; } } } else { seg = miPolySegment; } (*seg) (pDrawable, pGC, nseg, pseg); } xorg-server-1.20.13/fb/fboverlay.c0000644000175000017500000002417414100573756013626 00000000000000/* * * 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 #endif #include #include "fb.h" #include "fboverlay.h" #include "shmint.h" static DevPrivateKeyRec fbOverlayScreenPrivateKeyRec; #define fbOverlayScreenPrivateKey (&fbOverlayScreenPrivateKeyRec) DevPrivateKey fbOverlayGetScreenPrivateKey(void) { return fbOverlayScreenPrivateKey; } /* * Replace this if you want something supporting * multiple overlays with the same depth */ Bool fbOverlayCreateWindow(WindowPtr pWin) { FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen); int i; PixmapPtr pPixmap; if (pWin->drawable.class != InputOutput) return TRUE; for (i = 0; i < pScrPriv->nlayers; i++) { pPixmap = pScrPriv->layer[i].u.run.pixmap; if (pWin->drawable.depth == pPixmap->drawable.depth) { dixSetPrivate(&pWin->devPrivates, fbGetWinPrivateKey(pWin), pPixmap); /* * Make sure layer keys are written correctly by * having non-root layers set to full while the * root layer is set to empty. This will cause * all of the layers to get painted when the root * is mapped */ if (!pWin->parent) { RegionEmpty(&pScrPriv->layer[i].u.run.region); } return TRUE; } } return FALSE; } Bool fbOverlayCloseScreen(ScreenPtr pScreen) { FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); int i; for (i = 0; i < pScrPriv->nlayers; i++) { (*pScreen->DestroyPixmap) (pScrPriv->layer[i].u.run.pixmap); RegionUninit(&pScrPriv->layer[i].u.run.region); } return TRUE; } /* * Return layer containing this window */ int fbOverlayWindowLayer(WindowPtr pWin) { FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen); int i; for (i = 0; i < pScrPriv->nlayers; i++) if (dixLookupPrivate(&pWin->devPrivates, fbGetWinPrivateKey(pWin)) == (void *) pScrPriv->layer[i].u.run.pixmap) return i; return 0; } Bool fbOverlayCreateScreenResources(ScreenPtr pScreen) { int i; FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); PixmapPtr pPixmap; void *pbits; int width; int depth; BoxRec box; if (!miCreateScreenResources(pScreen)) return FALSE; box.x1 = 0; box.y1 = 0; box.x2 = pScreen->width; box.y2 = pScreen->height; for (i = 0; i < pScrPriv->nlayers; i++) { pbits = pScrPriv->layer[i].u.init.pbits; width = pScrPriv->layer[i].u.init.width; depth = pScrPriv->layer[i].u.init.depth; pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, 0); if (!pPixmap) return FALSE; if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width, pScreen->height, depth, BitsPerPixel(depth), PixmapBytePad(width, depth), pbits)) return FALSE; pScrPriv->layer[i].u.run.pixmap = pPixmap; RegionInit(&pScrPriv->layer[i].u.run.region, &box, 0); } pScreen->devPrivate = pScrPriv->layer[0].u.run.pixmap; return TRUE; } void fbOverlayPaintKey(DrawablePtr pDrawable, RegionPtr pRegion, CARD32 pixel, int layer) { fbFillRegionSolid(pDrawable, pRegion, 0, fbReplicatePixel(pixel, pDrawable->bitsPerPixel)); } /* * Track visible region for each layer */ void fbOverlayUpdateLayerRegion(ScreenPtr pScreen, int layer, RegionPtr prgn) { FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); int i; RegionRec rgnNew; if (!prgn || !RegionNotEmpty(prgn)) return; for (i = 0; i < pScrPriv->nlayers; i++) { if (i == layer) { /* add new piece to this fb */ RegionUnion(&pScrPriv->layer[i].u.run.region, &pScrPriv->layer[i].u.run.region, prgn); } else if (RegionNotEmpty(&pScrPriv->layer[i].u.run.region)) { /* paint new piece with chroma key */ RegionNull(&rgnNew); RegionIntersect(&rgnNew, prgn, &pScrPriv->layer[i].u.run.region); (*pScrPriv->PaintKey) (&pScrPriv->layer[i].u.run.pixmap->drawable, &rgnNew, pScrPriv->layer[i].key, i); RegionUninit(&rgnNew); /* remove piece from other fbs */ RegionSubtract(&pScrPriv->layer[i].u.run.region, &pScrPriv->layer[i].u.run.region, prgn); } } } /* * Copy only areas in each layer containing real bits */ void fbOverlayCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { ScreenPtr pScreen = pWin->drawable.pScreen; FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen); RegionRec rgnDst; int dx, dy; int i; RegionRec layerRgn[FB_OVERLAY_MAX]; PixmapPtr pPixmap; dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; /* * Clip to existing bits */ RegionTranslate(prgnSrc, -dx, -dy); RegionNull(&rgnDst); RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc); RegionTranslate(&rgnDst, dx, dy); /* * Compute the portion of each fb affected by this copy */ for (i = 0; i < pScrPriv->nlayers; i++) { RegionNull(&layerRgn[i]); RegionIntersect(&layerRgn[i], &rgnDst, &pScrPriv->layer[i].u.run.region); if (RegionNotEmpty(&layerRgn[i])) { RegionTranslate(&layerRgn[i], -dx, -dy); pPixmap = pScrPriv->layer[i].u.run.pixmap; miCopyRegion(&pPixmap->drawable, &pPixmap->drawable, 0, &layerRgn[i], dx, dy, pScrPriv->CopyWindow, 0, (void *) (long) i); } } /* * Update regions */ for (i = 0; i < pScrPriv->nlayers; i++) { if (RegionNotEmpty(&layerRgn[i])) fbOverlayUpdateLayerRegion(pScreen, i, &layerRgn[i]); RegionUninit(&layerRgn[i]); } RegionUninit(&rgnDst); } void fbOverlayWindowExposures(WindowPtr pWin, RegionPtr prgn) { fbOverlayUpdateLayerRegion(pWin->drawable.pScreen, fbOverlayWindowLayer(pWin), prgn); miWindowExposures(pWin, prgn); } Bool fbOverlaySetupScreen(ScreenPtr pScreen, void *pbits1, void *pbits2, int xsize, int ysize, int dpix, int dpiy, int width1, int width2, int bpp1, int bpp2) { return fbSetupScreen(pScreen, pbits1, xsize, ysize, dpix, dpiy, width1, bpp1); } Bool fbOverlayFinishScreenInit(ScreenPtr pScreen, void *pbits1, void *pbits2, int xsize, int ysize, int dpix, int dpiy, int width1, int width2, int bpp1, int bpp2, int depth1, int depth2) { VisualPtr visuals; DepthPtr depths; int nvisuals; int ndepths; VisualID defaultVisual; FbOverlayScrPrivPtr pScrPriv; if (!dixRegisterPrivateKey (&fbOverlayScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) return FALSE; if (bpp1 == 24 || bpp2 == 24) return FALSE; pScrPriv = malloc(sizeof(FbOverlayScrPrivRec)); if (!pScrPriv) return FALSE; if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &depth1, &defaultVisual, ((unsigned long) 1 << (bpp1 - 1)) | ((unsigned long) 1 << (bpp2 - 1)), 8)) { free(pScrPriv); return FALSE; } if (!miScreenInit(pScreen, 0, xsize, ysize, dpix, dpiy, 0, depth1, ndepths, depths, defaultVisual, nvisuals, visuals)) { free(pScrPriv); return FALSE; } /* MI thinks there's no frame buffer */ #ifdef MITSHM ShmRegisterFbFuncs(pScreen); #endif pScreen->minInstalledCmaps = 1; pScreen->maxInstalledCmaps = 2; pScrPriv->nlayers = 2; pScrPriv->PaintKey = fbOverlayPaintKey; pScrPriv->CopyWindow = fbCopyWindowProc; pScrPriv->layer[0].u.init.pbits = pbits1; pScrPriv->layer[0].u.init.width = width1; pScrPriv->layer[0].u.init.depth = depth1; pScrPriv->layer[1].u.init.pbits = pbits2; pScrPriv->layer[1].u.init.width = width2; pScrPriv->layer[1].u.init.depth = depth2; dixSetPrivate(&pScreen->devPrivates, fbOverlayScreenPrivateKey, pScrPriv); /* overwrite miCloseScreen with our own */ pScreen->CloseScreen = fbOverlayCloseScreen; pScreen->CreateScreenResources = fbOverlayCreateScreenResources; pScreen->CreateWindow = fbOverlayCreateWindow; pScreen->WindowExposures = fbOverlayWindowExposures; pScreen->CopyWindow = fbOverlayCopyWindow; return TRUE; } xorg-server-1.20.13/fb/fbpict.c0000644000175000017500000003414214100573756013100 00000000000000/* * * Copyright © 2000 SuSE, Inc. * Copyright © 2007 Red Hat, 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 #endif #include #include "fb.h" #include "picturestr.h" #include "mipict.h" #include "fbpict.h" void fbComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { pixman_image_t *src, *mask, *dest; int src_xoff, src_yoff; int msk_xoff, msk_yoff; int dst_xoff, dst_yoff; miCompositeSourceValidate(pSrc); if (pMask) miCompositeSourceValidate(pMask); src = image_from_pict(pSrc, FALSE, &src_xoff, &src_yoff); mask = image_from_pict(pMask, FALSE, &msk_xoff, &msk_yoff); dest = image_from_pict(pDst, TRUE, &dst_xoff, &dst_yoff); if (src && dest && !(pMask && !mask)) { pixman_image_composite(op, src, mask, dest, xSrc + src_xoff, ySrc + src_yoff, xMask + msk_xoff, yMask + msk_yoff, xDst + dst_xoff, yDst + dst_yoff, width, height); } free_pixman_pict(pSrc, src); free_pixman_pict(pMask, mask); free_pixman_pict(pDst, dest); } static pixman_glyph_cache_t *glyphCache; void fbDestroyGlyphCache(void) { if (glyphCache) { pixman_glyph_cache_destroy (glyphCache); glyphCache = NULL; } } static void fbUnrealizeGlyph(ScreenPtr pScreen, GlyphPtr pGlyph) { if (glyphCache) pixman_glyph_cache_remove (glyphCache, pGlyph, NULL); } void fbGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { #define N_STACK_GLYPHS 512 ScreenPtr pScreen = pDst->pDrawable->pScreen; pixman_glyph_t stack_glyphs[N_STACK_GLYPHS]; pixman_glyph_t *pglyphs = stack_glyphs; pixman_image_t *srcImage, *dstImage; int srcXoff, srcYoff, dstXoff, dstYoff; GlyphPtr glyph; int n_glyphs; int x, y; int i, n; int xDst = list->xOff, yDst = list->yOff; miCompositeSourceValidate(pSrc); n_glyphs = 0; for (i = 0; i < nlist; ++i) n_glyphs += list[i].len; if (!glyphCache) glyphCache = pixman_glyph_cache_create(); pixman_glyph_cache_freeze (glyphCache); if (n_glyphs > N_STACK_GLYPHS) { if (!(pglyphs = xallocarray(n_glyphs, sizeof(pixman_glyph_t)))) goto out; } i = 0; x = y = 0; while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; while (n--) { const void *g; glyph = *glyphs++; if (!(g = pixman_glyph_cache_lookup (glyphCache, glyph, NULL))) { pixman_image_t *glyphImage; PicturePtr pPicture; int xoff, yoff; pPicture = GetGlyphPicture(glyph, pScreen); if (!pPicture) { n_glyphs--; goto next; } if (!(glyphImage = image_from_pict(pPicture, FALSE, &xoff, &yoff))) goto out; g = pixman_glyph_cache_insert(glyphCache, glyph, NULL, glyph->info.x, glyph->info.y, glyphImage); free_pixman_pict(pPicture, glyphImage); if (!g) goto out; } pglyphs[i].x = x; pglyphs[i].y = y; pglyphs[i].glyph = g; i++; next: x += glyph->info.xOff; y += glyph->info.yOff; } list++; } if (!(srcImage = image_from_pict(pSrc, FALSE, &srcXoff, &srcYoff))) goto out; if (!(dstImage = image_from_pict(pDst, TRUE, &dstXoff, &dstYoff))) goto out_free_src; if (maskFormat) { pixman_format_code_t format; pixman_box32_t extents; format = maskFormat->format | (maskFormat->depth << 24); pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents); pixman_composite_glyphs(op, srcImage, dstImage, format, xSrc + srcXoff + extents.x1 - xDst, ySrc + srcYoff + extents.y1 - yDst, extents.x1, extents.y1, extents.x1 + dstXoff, extents.y1 + dstYoff, extents.x2 - extents.x1, extents.y2 - extents.y1, glyphCache, n_glyphs, pglyphs); } else { pixman_composite_glyphs_no_mask(op, srcImage, dstImage, xSrc + srcXoff - xDst, ySrc + srcYoff - yDst, dstXoff, dstYoff, glyphCache, n_glyphs, pglyphs); } free_pixman_pict(pDst, dstImage); out_free_src: free_pixman_pict(pSrc, srcImage); out: pixman_glyph_cache_thaw(glyphCache); if (pglyphs != stack_glyphs) free(pglyphs); } static pixman_image_t * create_solid_fill_image(PicturePtr pict) { PictSolidFill *solid = &pict->pSourcePict->solidFill; /* pixman_color_t and xRenderColor have the same layout */ pixman_color_t *color = (pixman_color_t *)&solid->fullcolor; return pixman_image_create_solid_fill(color); } static pixman_image_t * create_linear_gradient_image(PictGradient * gradient) { PictLinearGradient *linear = (PictLinearGradient *) gradient; pixman_point_fixed_t p1; pixman_point_fixed_t p2; p1.x = linear->p1.x; p1.y = linear->p1.y; p2.x = linear->p2.x; p2.y = linear->p2.y; return pixman_image_create_linear_gradient(&p1, &p2, (pixman_gradient_stop_t *) gradient->stops, gradient->nstops); } static pixman_image_t * create_radial_gradient_image(PictGradient * gradient) { PictRadialGradient *radial = (PictRadialGradient *) gradient; pixman_point_fixed_t c1; pixman_point_fixed_t c2; c1.x = radial->c1.x; c1.y = radial->c1.y; c2.x = radial->c2.x; c2.y = radial->c2.y; return pixman_image_create_radial_gradient(&c1, &c2, radial->c1.radius, radial->c2.radius, (pixman_gradient_stop_t *) gradient->stops, gradient->nstops); } static pixman_image_t * create_conical_gradient_image(PictGradient * gradient) { PictConicalGradient *conical = (PictConicalGradient *) gradient; pixman_point_fixed_t center; center.x = conical->center.x; center.y = conical->center.y; return pixman_image_create_conical_gradient(¢er, conical->angle, (pixman_gradient_stop_t *) gradient->stops, gradient->nstops); } static pixman_image_t * create_bits_picture(PicturePtr pict, Bool has_clip, int *xoff, int *yoff) { PixmapPtr pixmap; FbBits *bits; FbStride stride; int bpp; pixman_image_t *image; fbGetDrawablePixmap(pict->pDrawable, pixmap, *xoff, *yoff); fbGetPixmapBitsData(pixmap, bits, stride, bpp); image = pixman_image_create_bits((pixman_format_code_t) pict->format, pixmap->drawable.width, pixmap->drawable.height, (uint32_t *) bits, stride * sizeof(FbStride)); if (!image) return NULL; #ifdef FB_ACCESS_WRAPPER pixman_image_set_accessors(image, (pixman_read_memory_func_t) wfbReadMemory, (pixman_write_memory_func_t) wfbWriteMemory); #endif /* pCompositeClip is undefined for source pictures, so * only set the clip region for pictures with drawables */ if (has_clip) { if (pict->clientClip) pixman_image_set_has_client_clip(image, TRUE); if (*xoff || *yoff) pixman_region_translate(pict->pCompositeClip, *xoff, *yoff); pixman_image_set_clip_region(image, pict->pCompositeClip); if (*xoff || *yoff) pixman_region_translate(pict->pCompositeClip, -*xoff, -*yoff); } /* Indexed table */ if (pict->pFormat->index.devPrivate) pixman_image_set_indexed(image, pict->pFormat->index.devPrivate); /* Add in drawable origin to position within the image */ *xoff += pict->pDrawable->x; *yoff += pict->pDrawable->y; return image; } static pixman_image_t *image_from_pict_internal(PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map); static void image_destroy(pixman_image_t *image, void *data) { fbFinishAccess((DrawablePtr)data); } static void set_image_properties(pixman_image_t * image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map) { pixman_repeat_t repeat; pixman_filter_t filter; if (pict->transform) { /* For source images, adjust the transform to account * for the drawable offset within the pixman image, * then set the offset to 0 as it will be used * to compute positions within the transformed image. */ if (!has_clip) { struct pixman_transform adjusted; adjusted = *pict->transform; pixman_transform_translate(&adjusted, NULL, pixman_int_to_fixed(*xoff), pixman_int_to_fixed(*yoff)); pixman_image_set_transform(image, &adjusted); *xoff = 0; *yoff = 0; } else pixman_image_set_transform(image, pict->transform); } switch (pict->repeatType) { default: case RepeatNone: repeat = PIXMAN_REPEAT_NONE; break; case RepeatPad: repeat = PIXMAN_REPEAT_PAD; break; case RepeatNormal: repeat = PIXMAN_REPEAT_NORMAL; break; case RepeatReflect: repeat = PIXMAN_REPEAT_REFLECT; break; } pixman_image_set_repeat(image, repeat); /* Fetch alpha map unless 'pict' is being used * as the alpha map for this operation */ if (pict->alphaMap && !is_alpha_map) { int alpha_xoff, alpha_yoff; pixman_image_t *alpha_map = image_from_pict_internal(pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff, TRUE); pixman_image_set_alpha_map(image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y); free_pixman_pict(pict->alphaMap, alpha_map); } pixman_image_set_component_alpha(image, pict->componentAlpha); switch (pict->filter) { default: case PictFilterNearest: case PictFilterFast: filter = PIXMAN_FILTER_NEAREST; break; case PictFilterBilinear: case PictFilterGood: filter = PIXMAN_FILTER_BILINEAR; break; case PictFilterConvolution: filter = PIXMAN_FILTER_CONVOLUTION; break; } if (pict->pDrawable) pixman_image_set_destroy_function(image, &image_destroy, pict->pDrawable); pixman_image_set_filter(image, filter, (pixman_fixed_t *) pict->filter_params, pict->filter_nparams); pixman_image_set_source_clipping(image, TRUE); } static pixman_image_t * image_from_pict_internal(PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map) { pixman_image_t *image = NULL; if (!pict) return NULL; if (pict->pDrawable) { image = create_bits_picture(pict, has_clip, xoff, yoff); } else if (pict->pSourcePict) { SourcePict *sp = pict->pSourcePict; if (sp->type == SourcePictTypeSolidFill) { image = create_solid_fill_image(pict); } else { PictGradient *gradient = &pict->pSourcePict->gradient; if (sp->type == SourcePictTypeLinear) image = create_linear_gradient_image(gradient); else if (sp->type == SourcePictTypeRadial) image = create_radial_gradient_image(gradient); else if (sp->type == SourcePictTypeConical) image = create_conical_gradient_image(gradient); } *xoff = *yoff = 0; } if (image) set_image_properties(image, pict, has_clip, xoff, yoff, is_alpha_map); return image; } pixman_image_t * image_from_pict(PicturePtr pict, Bool has_clip, int *xoff, int *yoff) { return image_from_pict_internal(pict, has_clip, xoff, yoff, FALSE); } void free_pixman_pict(PicturePtr pict, pixman_image_t * image) { if (image) pixman_image_unref(image); } Bool fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) { PictureScreenPtr ps; if (!miPictureInit(pScreen, formats, nformats)) return FALSE; ps = GetPictureScreen(pScreen); ps->Composite = fbComposite; ps->Glyphs = fbGlyphs; ps->UnrealizeGlyph = fbUnrealizeGlyph; ps->CompositeRects = miCompositeRects; ps->RasterizeTrapezoid = fbRasterizeTrapezoid; ps->Trapezoids = fbTrapezoids; ps->AddTraps = fbAddTraps; ps->AddTriangles = fbAddTriangles; ps->Triangles = fbTriangles; return TRUE; } xorg-server-1.20.13/fb/fbpixmap.c0000644000175000017500000002536514100573756013446 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "fb.h" PixmapPtr fbCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, unsigned usage_hint) { PixmapPtr pPixmap; size_t datasize; size_t paddedWidth; int adjust; int base; int bpp = BitsPerPixel(depth); paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits); if (paddedWidth / 4 > 32767 || height > 32767) return NullPixmap; datasize = height * paddedWidth; base = pScreen->totalPixmapSize; adjust = 0; if (base & 7) adjust = 8 - (base & 7); datasize += adjust; #ifdef FB_DEBUG datasize += 2 * paddedWidth; #endif pPixmap = AllocatePixmap(pScreen, datasize); if (!pPixmap) return NullPixmap; pPixmap->drawable.type = DRAWABLE_PIXMAP; pPixmap->drawable.class = 0; pPixmap->drawable.pScreen = pScreen; pPixmap->drawable.depth = depth; pPixmap->drawable.bitsPerPixel = bpp; pPixmap->drawable.id = 0; pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; pPixmap->drawable.x = 0; pPixmap->drawable.y = 0; pPixmap->drawable.width = width; pPixmap->drawable.height = height; pPixmap->devKind = paddedWidth; pPixmap->refcnt = 1; pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap + base + adjust); pPixmap->master_pixmap = NULL; #ifdef FB_DEBUG pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth); fbInitializeDrawable(&pPixmap->drawable); #endif #ifdef COMPOSITE pPixmap->screen_x = 0; pPixmap->screen_y = 0; #endif pPixmap->usage_hint = usage_hint; return pPixmap; } Bool fbDestroyPixmap(PixmapPtr pPixmap) { if (--pPixmap->refcnt) return TRUE; FreePixmap(pPixmap); return TRUE; } #define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \ if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \ (!((reg)->data->numRects && \ ((r-1)->y1 == (ry1)) && \ ((r-1)->y2 == (ry2)) && \ ((r-1)->x1 <= (rx1)) && \ ((r-1)->x2 >= (rx2))))) \ { \ if ((reg)->data->numRects == (reg)->data->size) \ { \ RegionRectAlloc(reg, 1); \ fr = RegionBoxptr(reg); \ r = fr + (reg)->data->numRects; \ } \ r->x1 = (rx1); \ r->y1 = (ry1); \ r->x2 = (rx2); \ r->y2 = (ry2); \ (reg)->data->numRects++; \ if(r->x1 < (reg)->extents.x1) \ (reg)->extents.x1 = r->x1; \ if(r->x2 > (reg)->extents.x2) \ (reg)->extents.x2 = r->x2; \ r++; \ } /* Convert bitmap clip mask into clipping region. * First, goes through each line and makes boxes by noting the transitions * from 0 to 1 and 1 to 0. * Then it coalesces the current line with the previous if they have boxes * at the same X coordinates. */ RegionPtr fbPixmapToRegion(PixmapPtr pPix) { register RegionPtr pReg; FbBits *pw, w; register int ib; int width, h, base, rx1 = 0, crects; FbBits *pwLineEnd; int irectPrevStart, irectLineStart; register BoxPtr prectO, prectN; BoxPtr FirstRect, rects, prectLineStart; Bool fInBox, fSame; register FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1); FbBits *pwLine; int nWidth; pReg = RegionCreate(NULL, 1); if (!pReg) return NullRegion; FirstRect = RegionBoxptr(pReg); rects = FirstRect; fbPrepareAccess(&pPix->drawable); pwLine = (FbBits *) pPix->devPrivate.ptr; nWidth = pPix->devKind >> (FB_SHIFT - 3); width = pPix->drawable.width; pReg->extents.x1 = width - 1; pReg->extents.x2 = 0; irectPrevStart = -1; for (h = 0; h < pPix->drawable.height; h++) { pw = pwLine; pwLine += nWidth; irectLineStart = rects - FirstRect; /* If the Screen left most bit of the word is set, we're starting in * a box */ if (READ(pw) & mask0) { fInBox = TRUE; rx1 = 0; } else fInBox = FALSE; /* Process all words which are fully in the pixmap */ pwLineEnd = pw + (width >> FB_SHIFT); for (base = 0; pw < pwLineEnd; base += FB_UNIT) { w = READ(pw++); if (fInBox) { if (!~w) continue; } else { if (!w) continue; } for (ib = 0; ib < FB_UNIT; ib++) { /* If the Screen left most bit of the word is set, we're * starting a box */ if (w & mask0) { if (!fInBox) { rx1 = base + ib; /* start new box */ fInBox = TRUE; } } else { if (fInBox) { /* end box */ ADDRECT(pReg, rects, FirstRect, rx1, h, base + ib, h + 1); fInBox = FALSE; } } /* Shift the word VISUALLY left one. */ w = FbScrLeft(w, 1); } } if (width & FB_MASK) { /* Process final partial word on line */ w = READ(pw++); for (ib = 0; ib < (width & FB_MASK); ib++) { /* If the Screen left most bit of the word is set, we're * starting a box */ if (w & mask0) { if (!fInBox) { rx1 = base + ib; /* start new box */ fInBox = TRUE; } } else { if (fInBox) { /* end box */ ADDRECT(pReg, rects, FirstRect, rx1, h, base + ib, h + 1); fInBox = FALSE; } } /* Shift the word VISUALLY left one. */ w = FbScrLeft(w, 1); } } /* If scanline ended with last bit set, end the box */ if (fInBox) { ADDRECT(pReg, rects, FirstRect, rx1, h, base + (width & FB_MASK), h + 1); } /* if all rectangles on this line have the same x-coords as * those on the previous line, then add 1 to all the previous y2s and * throw away all the rectangles from this line */ fSame = FALSE; if (irectPrevStart != -1) { crects = irectLineStart - irectPrevStart; if (crects == ((rects - FirstRect) - irectLineStart)) { prectO = FirstRect + irectPrevStart; prectN = prectLineStart = FirstRect + irectLineStart; fSame = TRUE; while (prectO < prectLineStart) { if ((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2)) { fSame = FALSE; break; } prectO++; prectN++; } if (fSame) { prectO = FirstRect + irectPrevStart; while (prectO < prectLineStart) { prectO->y2 += 1; prectO++; } rects -= crects; pReg->data->numRects -= crects; } } } if (!fSame) irectPrevStart = irectLineStart; } if (!pReg->data->numRects) pReg->extents.x1 = pReg->extents.x2 = 0; else { pReg->extents.y1 = RegionBoxptr(pReg)->y1; pReg->extents.y2 = RegionEnd(pReg)->y2; if (pReg->data->numRects == 1) { free(pReg->data); pReg->data = (RegDataPtr) NULL; } } fbFinishAccess(&pPix->drawable); #ifdef DEBUG if (!RegionIsValid(pReg)) FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__); #endif return pReg; } #ifdef FB_DEBUG #ifndef WIN32 #include #else #include #endif static Bool fbValidateBits(FbStip * bits, int stride, FbStip data) { while (stride--) { if (*bits != data) { #ifdef WIN32 NCD_DEBUG((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)", bits, *bits, data)); #else fprintf(stderr, "fbValidateBits failed\n"); #endif return FALSE; } bits++; } } void fbValidateDrawable(DrawablePtr pDrawable) { FbStip *bits, *first, *last; int stride, bpp; int xoff, yoff; int height; Bool failed; if (pDrawable->type != DRAWABLE_PIXMAP) pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable); fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff); first = bits - stride; last = bits + stride * pDrawable->height; if (!fbValidateBits(first, stride, FB_HEAD_BITS) || !fbValidateBits(last, stride, FB_TAIL_BITS)) fbInitializeDrawable(pDrawable); fbFinishAccess(pDrawable); } void fbSetBits(FbStip * bits, int stride, FbStip data) { while (stride--) *bits++ = data; } void fbInitializeDrawable(DrawablePtr pDrawable) { FbStip *bits, *first, *last; int stride, bpp; int xoff, yoff; fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff); first = bits - stride; last = bits + stride * pDrawable->height; fbSetBits(first, stride, FB_HEAD_BITS); fbSetBits(last, stride, FB_TAIL_BITS); fbFinishAccess(pDrawable); } #endif /* FB_DEBUG */ xorg-server-1.20.13/fb/fbpoint.c0000644000175000017500000000721514100573756013273 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" typedef void (*FbDots) (FbBits * dst, FbStride dstStride, int dstBpp, BoxPtr pBox, xPoint * pts, int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor); static void fbDots(FbBits * dstOrig, FbStride dstStride, int dstBpp, BoxPtr pBox, xPoint * pts, int npt, int xorg, int yorg, int xoff, int yoff, FbBits andOrig, FbBits xorOrig) { FbStip *dst = (FbStip *) dstOrig; int x1, y1, x2, y2; int x, y; FbStip *d; FbStip and = andOrig; FbStip xor = xorOrig; dstStride = FbBitsStrideToStipStride(dstStride); x1 = pBox->x1; y1 = pBox->y1; x2 = pBox->x2; y2 = pBox->y2; while (npt--) { x = pts->x + xorg; y = pts->y + yorg; pts++; if (x1 <= x && x < x2 && y1 <= y && y < y2) { FbStip mask; x = (x + xoff) * dstBpp; d = dst + ((y + yoff) * dstStride) + (x >> FB_STIP_SHIFT); x &= FB_STIP_MASK; mask = FbStipMask(x, dstBpp); WRITE(d, FbDoMaskRRop(READ(d), and, xor, mask)); } } } void fbPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int nptInit, xPoint * pptInit) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); RegionPtr pClip = fbGetCompositeClip(pGC); FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; FbDots dots; FbBits and, xor; xPoint *ppt; int npt; BoxPtr pBox; int nBox; /* make pointlist origin relative */ ppt = pptInit; npt = nptInit; if (mode == CoordModePrevious) { npt--; while (npt--) { ppt++; ppt->x += (ppt - 1)->x; ppt->y += (ppt - 1)->y; } } fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); and = pPriv->and; xor = pPriv->xor; dots = fbDots; switch (dstBpp) { case 8: dots = fbDots8; break; case 16: dots = fbDots16; break; case 32: dots = fbDots32; break; } for (nBox = RegionNumRects(pClip), pBox = RegionRects(pClip); nBox--; pBox++) (*dots) (dst, dstStride, dstBpp, pBox, pptInit, nptInit, pDrawable->x, pDrawable->y, dstXoff, dstYoff, and, xor); fbFinishAccess(pDrawable); } xorg-server-1.20.13/fb/fbpush.c0000644000175000017500000001316514100573756013122 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" static void fbPushPattern(DrawablePtr pDrawable, GCPtr pGC, FbStip * src, FbStride srcStride, int srcX, int x, int y, int width, int height) { FbStip *s, bitsMask, bitsMask0, bits; int xspan; int w; int lenspan; src += srcX >> FB_STIP_SHIFT; srcX &= FB_STIP_MASK; bitsMask0 = FbStipMask(srcX, 1); while (height--) { bitsMask = bitsMask0; w = width; s = src; src += srcStride; bits = READ(s++); xspan = x; while (w) { if (bits & bitsMask) { lenspan = 0; do { lenspan++; if (lenspan == w) break; bitsMask = FbStipRight(bitsMask, 1); if (!bitsMask) { bits = READ(s++); bitsMask = FbBitsMask(0, 1); } } while (bits & bitsMask); fbFill(pDrawable, pGC, xspan, y, lenspan, 1); xspan += lenspan; w -= lenspan; } else { do { w--; xspan++; if (!w) break; bitsMask = FbStipRight(bitsMask, 1); if (!bitsMask) { bits = READ(s++); bitsMask = FbBitsMask(0, 1); } } while (!(bits & bitsMask)); } } y++; } } static void fbPushFill(DrawablePtr pDrawable, GCPtr pGC, FbStip * src, FbStride srcStride, int srcX, int x, int y, int width, int height) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); if (pGC->fillStyle == FillSolid) { FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; int dstX; int dstWidth; fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); dst = dst + (y + dstYoff) * dstStride; dstX = (x + dstXoff) * dstBpp; dstWidth = width * dstBpp; if (dstBpp == 1) { fbBltStip(src, srcStride, srcX, (FbStip *) dst, FbBitsStrideToStipStride(dstStride), dstX, dstWidth, height, FbStipple1Rop(pGC->alu, pGC->fgPixel), pPriv->pm, dstBpp); } else { fbBltOne(src, srcStride, srcX, dst, dstStride, dstX, dstBpp, dstWidth, height, pPriv->and, pPriv->xor, fbAnd(GXnoop, (FbBits) 0, FB_ALLONES), fbXor(GXnoop, (FbBits) 0, FB_ALLONES)); } fbFinishAccess(pDrawable); } else { fbPushPattern(pDrawable, pGC, src, srcStride, srcX, x, y, width, height); } } void fbPushImage(DrawablePtr pDrawable, GCPtr pGC, FbStip * src, FbStride srcStride, int srcX, int x, int y, int width, int height) { RegionPtr pClip = fbGetCompositeClip(pGC); int nbox; BoxPtr pbox; int x1, y1, x2, y2; for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip); nbox--; pbox++) { x1 = x; y1 = y; x2 = x + width; y2 = y + height; if (x1 < pbox->x1) x1 = pbox->x1; if (y1 < pbox->y1) y1 = pbox->y1; if (x2 > pbox->x2) x2 = pbox->x2; if (y2 > pbox->y2) y2 = pbox->y2; if (x1 >= x2 || y1 >= y2) continue; fbPushFill(pDrawable, pGC, src + (y1 - y) * srcStride, srcStride, srcX + (x1 - x), x1, y1, x2 - x1, y2 - y1); } } void fbPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg) { FbStip *stip; FbStride stipStride; int stipBpp; _X_UNUSED int stipXoff, stipYoff; fbGetStipDrawable(&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); fbPushImage(pDrawable, pGC, stip, stipStride, 0, xOrg, yOrg, dx, dy); } xorg-server-1.20.13/fb/fbscreen.c0000644000175000017500000001541314100573756013420 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" Bool fbCloseScreen(ScreenPtr pScreen) { int d; DepthPtr depths = pScreen->allowedDepths; fbDestroyGlyphCache(); for (d = 0; d < pScreen->numDepths; d++) free(depths[d].vids); free(depths); free(pScreen->visuals); if (pScreen->devPrivate) FreePixmap((PixmapPtr)pScreen->devPrivate); return TRUE; } Bool fbRealizeFont(ScreenPtr pScreen, FontPtr pFont) { return TRUE; } Bool fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont) { return TRUE; } void fbQueryBestSize(int class, unsigned short *width, unsigned short *height, ScreenPtr pScreen) { unsigned short w; switch (class) { case CursorShape: if (*width > pScreen->width) *width = pScreen->width; if (*height > pScreen->height) *height = pScreen->height; break; case TileShape: case StippleShape: w = *width; if ((w & (w - 1)) && w < FB_UNIT) { for (w = 1; w < *width; w <<= 1); *width = w; } } } PixmapPtr _fbGetWindowPixmap(WindowPtr pWindow) { return fbGetWindowPixmap(pWindow); } void _fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap) { dixSetPrivate(&pWindow->devPrivates, fbGetWinPrivateKey(pWindow), pPixmap); } Bool fbSetupScreen(ScreenPtr pScreen, void *pbits, /* pointer to screen bitmap */ int xsize, /* in pixels */ int ysize, int dpix, /* dots per inch */ int dpiy, int width, /* pixel width of frame buffer */ int bpp) { /* bits per pixel for screen */ if (!fbAllocatePrivates(pScreen)) return FALSE; pScreen->defColormap = FakeClientID(0); /* let CreateDefColormap do whatever it wants for pixels */ pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0; pScreen->QueryBestSize = fbQueryBestSize; /* SaveScreen */ pScreen->GetImage = fbGetImage; pScreen->GetSpans = fbGetSpans; pScreen->CreateWindow = fbCreateWindow; pScreen->DestroyWindow = fbDestroyWindow; pScreen->PositionWindow = fbPositionWindow; pScreen->ChangeWindowAttributes = fbChangeWindowAttributes; pScreen->RealizeWindow = fbRealizeWindow; pScreen->UnrealizeWindow = fbUnrealizeWindow; pScreen->CopyWindow = fbCopyWindow; pScreen->CreatePixmap = fbCreatePixmap; pScreen->DestroyPixmap = fbDestroyPixmap; pScreen->RealizeFont = fbRealizeFont; pScreen->UnrealizeFont = fbUnrealizeFont; pScreen->CreateGC = fbCreateGC; pScreen->CreateColormap = fbInitializeColormap; pScreen->DestroyColormap = (void (*)(ColormapPtr)) NoopDDA; pScreen->InstallColormap = fbInstallColormap; pScreen->UninstallColormap = fbUninstallColormap; pScreen->ListInstalledColormaps = fbListInstalledColormaps; pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *)) NoopDDA; pScreen->ResolveColor = fbResolveColor; pScreen->BitmapToRegion = fbPixmapToRegion; pScreen->GetWindowPixmap = _fbGetWindowPixmap; pScreen->SetWindowPixmap = _fbSetWindowPixmap; return TRUE; } #ifdef FB_ACCESS_WRAPPER Bool wfbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize, int dpix, int dpiy, int width, int bpp, SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap) #else Bool fbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize, int dpix, int dpiy, int width, int bpp) #endif { VisualPtr visuals; DepthPtr depths; int nvisuals; int ndepths; int rootdepth; VisualID defaultVisual; #ifdef FB_DEBUG int stride; ysize -= 2; stride = (width * bpp) / 8; fbSetBits((FbStip *) pbits, stride / sizeof(FbStip), FB_HEAD_BITS); pbits = (void *) ((char *) pbits + stride); fbSetBits((FbStip *) ((char *) pbits + stride * ysize), stride / sizeof(FbStip), FB_TAIL_BITS); #endif /* fb requires power-of-two bpp */ if (Ones(bpp) != 1) return FALSE; #ifdef FB_ACCESS_WRAPPER fbGetScreenPrivate(pScreen)->setupWrap = setupWrap; fbGetScreenPrivate(pScreen)->finishWrap = finishWrap; #endif rootdepth = 0; if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth, &defaultVisual, ((unsigned long) 1 << (bpp - 1)), 8)) return FALSE; if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, rootdepth, ndepths, depths, defaultVisual, nvisuals, visuals)) return FALSE; /* overwrite miCloseScreen with our own */ pScreen->CloseScreen = fbCloseScreen; return TRUE; } /* dts * (inch/dot) * (25.4 mm / inch) = mm */ #ifdef FB_ACCESS_WRAPPER Bool wfbScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize, int dpix, int dpiy, int width, int bpp, SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap) { if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)) return FALSE; if (!wfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp, setupWrap, finishWrap)) return FALSE; return TRUE; } #else Bool fbScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize, int dpix, int dpiy, int width, int bpp) { if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)) return FALSE; if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)) return FALSE; return TRUE; } #endif xorg-server-1.20.13/fb/fbseg.c0000644000175000017500000003113014100573756012711 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "fb.h" #include "miline.h" #define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \ ((dir < 0) ? FbStipLeft(mask,bpp) : \ FbStipRight(mask,bpp))) static void fbBresSolid(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbStip *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); FbStip and = (FbStip) pPriv->and; FbStip xor = (FbStip) pPriv->xor; FbStip mask, mask0; FbStip bits; fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); dst += ((y1 + dstYoff) * dstStride); x1 = (x1 + dstXoff) * dstBpp; dst += x1 >> FB_STIP_SHIFT; x1 &= FB_STIP_MASK; mask0 = FbStipMask(0, dstBpp); mask = FbStipRight(mask0, x1); if (signdx < 0) mask0 = FbStipRight(mask0, FB_STIP_UNIT - dstBpp); if (signdy < 0) dstStride = -dstStride; if (axis == X_AXIS) { bits = 0; while (len--) { bits |= mask; mask = fbBresShiftMask(mask, signdx, dstBpp); if (!mask) { WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits)); bits = 0; dst += signdx; mask = mask0; } e += e1; if (e >= 0) { if (bits) { WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits)); bits = 0; } dst += dstStride; e += e3; } } if (bits) WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits)); } else { while (len--) { WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, mask)); dst += dstStride; e += e1; if (e >= 0) { e += e3; mask = fbBresShiftMask(mask, signdx, dstBpp); if (!mask) { dst += signdx; mask = mask0; } } } } fbFinishAccess(pDrawable); } static void fbBresDash(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbStip *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); FbStip and = (FbStip) pPriv->and; FbStip xor = (FbStip) pPriv->xor; FbStip bgand = (FbStip) pPriv->bgand; FbStip bgxor = (FbStip) pPriv->bgxor; FbStip mask, mask0; FbDashDeclare; int dashlen; Bool even; Bool doOdd; fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); doOdd = pGC->lineStyle == LineDoubleDash; FbDashInit(pGC, pPriv, dashOffset, dashlen, even); dst += ((y1 + dstYoff) * dstStride); x1 = (x1 + dstXoff) * dstBpp; dst += x1 >> FB_STIP_SHIFT; x1 &= FB_STIP_MASK; mask0 = FbStipMask(0, dstBpp); mask = FbStipRight(mask0, x1); if (signdx < 0) mask0 = FbStipRight(mask0, FB_STIP_UNIT - dstBpp); if (signdy < 0) dstStride = -dstStride; while (len--) { if (even) WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, mask)); else if (doOdd) WRITE(dst, FbDoMaskRRop(READ(dst), bgand, bgxor, mask)); if (axis == X_AXIS) { mask = fbBresShiftMask(mask, signdx, dstBpp); if (!mask) { dst += signdx; mask = mask0; } e += e1; if (e >= 0) { dst += dstStride; e += e3; } } else { dst += dstStride; e += e1; if (e >= 0) { e += e3; mask = fbBresShiftMask(mask, signdx, dstBpp); if (!mask) { dst += signdx; mask = mask0; } } } FbDashStep(dashlen, even); } fbFinishAccess(pDrawable); } static void fbBresFill(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { while (len--) { fbFill(pDrawable, pGC, x1, y1, 1, 1); if (axis == X_AXIS) { x1 += signdx; e += e1; if (e >= 0) { e += e3; y1 += signdy; } } else { y1 += signdy; e += e1; if (e >= 0) { e += e3; x1 += signdx; } } } } static void fbSetFg(DrawablePtr pDrawable, GCPtr pGC, Pixel fg) { if (fg != pGC->fgPixel) { ChangeGCVal val; val.val = fg; ChangeGC(NullClient, pGC, GCForeground, &val); ValidateGC(pDrawable, pGC); } } static void fbBresFillDash(DrawablePtr pDrawable, GCPtr pGC, int dashOffset, int signdx, int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); FbDashDeclare; int dashlen; Bool even; Bool doOdd; Bool doBg; Pixel fg, bg; fg = pGC->fgPixel; bg = pGC->bgPixel; /* whether to fill the odd dashes */ doOdd = pGC->lineStyle == LineDoubleDash; /* whether to switch fg to bg when filling odd dashes */ doBg = doOdd && (pGC->fillStyle == FillSolid || pGC->fillStyle == FillStippled); /* compute current dash position */ FbDashInit(pGC, pPriv, dashOffset, dashlen, even); while (len--) { if (even || doOdd) { if (doBg) { if (even) fbSetFg(pDrawable, pGC, fg); else fbSetFg(pDrawable, pGC, bg); } fbFill(pDrawable, pGC, x1, y1, 1, 1); } if (axis == X_AXIS) { x1 += signdx; e += e1; if (e >= 0) { e += e3; y1 += signdy; } } else { y1 += signdy; e += e1; if (e >= 0) { e += e3; x1 += signdx; } } FbDashStep(dashlen, even); } if (doBg) fbSetFg(pDrawable, pGC, fg); } /* * For drivers that want to bail drawing some lines, this * function takes care of selecting the appropriate rasterizer * based on the contents of the specified GC. */ static FbBres * fbSelectBres(DrawablePtr pDrawable, GCPtr pGC) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); int dstBpp = pDrawable->bitsPerPixel; FbBres *bres; if (pGC->lineStyle == LineSolid) { bres = fbBresFill; if (pGC->fillStyle == FillSolid) { bres = fbBresSolid; if (pPriv->and == 0) { switch (dstBpp) { case 8: bres = fbBresSolid8; break; case 16: bres = fbBresSolid16; break; case 32: bres = fbBresSolid32; break; } } } } else { bres = fbBresFillDash; if (pGC->fillStyle == FillSolid) { bres = fbBresDash; if (pPriv->and == 0 && (pGC->lineStyle == LineOnOffDash || pPriv->bgand == 0)) { switch (dstBpp) { case 8: bres = fbBresDash8; break; case 16: bres = fbBresDash16; break; case 32: bres = fbBresDash32; break; } } } } return bres; } void fbSegment(DrawablePtr pDrawable, GCPtr pGC, int x1, int y1, int x2, int y2, Bool drawLast, int *dashOffset) { FbBres *bres; RegionPtr pClip = fbGetCompositeClip(pGC); BoxPtr pBox; int nBox; int adx; /* abs values of dx and dy */ int ady; int signdx; /* sign of dx and dy */ int signdy; int e, e1, e2, e3; /* bresenham error and increments */ int len; /* length of segment */ int axis; /* major axis */ int octant; int dashoff; int doff; unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); unsigned int oc1; /* outcode of point 1 */ unsigned int oc2; /* outcode of point 2 */ nBox = RegionNumRects(pClip); pBox = RegionRects(pClip); bres = fbSelectBres(pDrawable, pGC); CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant); if (adx > ady) { axis = X_AXIS; e1 = ady << 1; e2 = e1 - (adx << 1); e = e1 - adx; len = adx; } else { axis = Y_AXIS; e1 = adx << 1; e2 = e1 - (ady << 1); e = e1 - ady; SetYMajorOctant(octant); len = ady; } FIXUP_ERROR(e, octant, bias); /* * Adjust error terms to compare against zero */ e3 = e2 - e1; e = e - e1; /* we have bresenham parameters and two points. all we have to do now is clip and draw. */ if (drawLast) len++; dashoff = *dashOffset; *dashOffset = dashoff + len; while (nBox--) { oc1 = 0; oc2 = 0; OUTCODES(oc1, x1, y1, pBox); OUTCODES(oc2, x2, y2, pBox); if ((oc1 | oc2) == 0) { (*bres) (pDrawable, pGC, dashoff, signdx, signdy, axis, x1, y1, e, e1, e3, len); break; } else if (oc1 & oc2) { pBox++; } else { int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; int clip1 = 0, clip2 = 0; int clipdx, clipdy; int err; if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2 - 1, pBox->y2 - 1, &new_x1, &new_y1, &new_x2, &new_y2, adx, ady, &clip1, &clip2, octant, bias, oc1, oc2) == -1) { pBox++; continue; } if (axis == X_AXIS) len = abs(new_x2 - new_x1); else len = abs(new_y2 - new_y1); if (clip2 != 0 || drawLast) len++; if (len) { /* unwind bresenham error term to first point */ doff = dashoff; err = e; if (clip1) { clipdx = abs(new_x1 - x1); clipdy = abs(new_y1 - y1); if (axis == X_AXIS) { doff += clipdx; err += e3 * clipdy + e1 * clipdx; } else { doff += clipdy; err += e3 * clipdx + e1 * clipdy; } } (*bres) (pDrawable, pGC, doff, signdx, signdy, axis, new_x1, new_y1, err, e1, e3, len); } pBox++; } } /* while (nBox--) */ } xorg-server-1.20.13/fb/fbsetsp.c0000644000175000017500000000543314100573756013300 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" void fbSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *src, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); RegionPtr pClip = fbGetCompositeClip(pGC); FbBits *dst, *d, *s; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; BoxPtr pbox; int n; int xoff; int x1, x2; fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); while (nspans--) { d = dst + (ppt->y + dstYoff) * dstStride; xoff = (int) (((long) src) & (FB_MASK >> 3)); s = (FbBits *) (src - xoff); xoff <<= 3; n = RegionNumRects(pClip); pbox = RegionRects(pClip); while (n--) { if (pbox->y1 > ppt->y) break; if (pbox->y2 > ppt->y) { x1 = ppt->x; x2 = x1 + *pwidth; if (pbox->x1 > x1) x1 = pbox->x1; if (pbox->x2 < x2) x2 = pbox->x2; if (x1 < x2) fbBlt((FbBits *) s, 0, (x1 - ppt->x) * dstBpp + xoff, d, dstStride, (x1 + dstXoff) * dstBpp, (x2 - x1) * dstBpp, 1, pGC->alu, pPriv->pm, dstBpp, FALSE, FALSE); } } src += PixmapBytePad(*pwidth, pDrawable->depth); ppt++; pwidth++; } fbValidateDrawable(pDrawable); fbFinishAccess(pDrawable); } xorg-server-1.20.13/fb/fbsolid.c0000644000175000017500000000425114100573756013251 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #define FbSelectPart(xor,o,t) xor #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" void fbSolid(FbBits * dst, FbStride dstStride, int dstX, int bpp, int width, int height, FbBits and, FbBits xor) { FbBits startmask, endmask; int n, nmiddle; int startbyte, endbyte; dst += dstX >> FB_SHIFT; dstX &= FB_MASK; FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte, nmiddle, endmask, endbyte); if (startmask) dstStride--; dstStride -= nmiddle; while (height--) { if (startmask) { FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor); dst++; } n = nmiddle; if (!and) while (n--) WRITE(dst++, xor); else while (n--) { WRITE(dst, FbDoRRop(READ(dst), and, xor)); dst++; } if (endmask) FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor); dst += dstStride; } } xorg-server-1.20.13/fb/fbtrap.c0000644000175000017500000001312714100573756013107 00000000000000/* * 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 #endif #include "fb.h" #include "picturestr.h" #include "mipict.h" #include "fbpict.h" #include "damage.h" void fbAddTraps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap * traps) { pixman_image_t *image; int dst_xoff, dst_yoff; if (!(image = image_from_pict(pPicture, FALSE, &dst_xoff, &dst_yoff))) return; pixman_add_traps(image, x_off + dst_xoff, y_off + dst_yoff, ntrap, (pixman_trap_t *) traps); free_pixman_pict(pPicture, image); } void fbRasterizeTrapezoid(PicturePtr pPicture, xTrapezoid * trap, int x_off, int y_off) { pixman_image_t *image; int dst_xoff, dst_yoff; if (!(image = image_from_pict(pPicture, FALSE, &dst_xoff, &dst_yoff))) return; pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) trap, x_off + dst_xoff, y_off + dst_yoff); free_pixman_pict(pPicture, image); } void fbAddTriangles(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri, xTriangle * tris) { pixman_image_t *image; int dst_xoff, dst_yoff; if (!(image = image_from_pict(pPicture, FALSE, &dst_xoff, &dst_yoff))) return; pixman_add_triangles(image, dst_xoff + x_off, dst_yoff + y_off, ntri, (pixman_triangle_t *) tris); free_pixman_pict(pPicture, image); } typedef void (*CompositeShapesFunc) (pixman_op_t op, pixman_image_t * src, pixman_image_t * dst, pixman_format_code_t mask_format, int x_src, int y_src, int x_dst, int y_dst, int n_shapes, const uint8_t * shapes); static void fbShapes(CompositeShapesFunc composite, pixman_op_t op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, int16_t xSrc, int16_t ySrc, int nshapes, int shape_size, const uint8_t * shapes) { pixman_image_t *src, *dst; int src_xoff, src_yoff; int dst_xoff, dst_yoff; miCompositeSourceValidate(pSrc); src = image_from_pict(pSrc, FALSE, &src_xoff, &src_yoff); dst = image_from_pict(pDst, TRUE, &dst_xoff, &dst_yoff); if (src && dst) { pixman_format_code_t format; DamageRegionAppend(pDst->pDrawable, pDst->pCompositeClip); if (!maskFormat) { int i; if (pDst->polyEdge == PolyEdgeSharp) format = PIXMAN_a1; else format = PIXMAN_a8; for (i = 0; i < nshapes; ++i) { composite(op, src, dst, format, xSrc + src_xoff, ySrc + src_yoff, dst_xoff, dst_yoff, 1, shapes + i * shape_size); } } else { switch (PICT_FORMAT_A(maskFormat->format)) { case 1: format = PIXMAN_a1; break; case 4: format = PIXMAN_a4; break; default: case 8: format = PIXMAN_a8; break; } composite(op, src, dst, format, xSrc + src_xoff, ySrc + src_yoff, dst_xoff, dst_yoff, nshapes, shapes); } DamageRegionProcessPending(pDst->pDrawable); } free_pixman_pict(pSrc, src); free_pixman_pict(pDst, dst); } void fbTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps) { xSrc -= (traps[0].left.p1.x >> 16); ySrc -= (traps[0].left.p1.y >> 16); fbShapes((CompositeShapesFunc) pixman_composite_trapezoids, op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, sizeof(xTrapezoid), (const uint8_t *) traps); } void fbTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris) { xSrc -= (tris[0].p1.x >> 16); ySrc -= (tris[0].p1.y >> 16); fbShapes((CompositeShapesFunc) pixman_composite_triangles, op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, sizeof(xTriangle), (const uint8_t *) tris); } xorg-server-1.20.13/fb/fbutil.c0000644000175000017500000000521614100573756013116 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "fb.h" FbBits fbReplicatePixel(Pixel p, int bpp) { FbBits b = p; b &= FbFullMask(bpp); while (bpp < FB_UNIT) { b |= b << bpp; bpp <<= 1; } return b; } #define O 0 #define I FB_ALLONES const FbMergeRopRec FbMergeRopBits[16] = { {O, O, O, O}, /* clear 0x0 0 */ {I, O, O, O}, /* and 0x1 src AND dst */ {I, O, I, O}, /* andReverse 0x2 src AND NOT dst */ {O, O, I, O}, /* copy 0x3 src */ {I, I, O, O}, /* andInverted 0x4 NOT src AND dst */ {O, I, O, O}, /* noop 0x5 dst */ {O, I, I, O}, /* xor 0x6 src XOR dst */ {I, I, I, O}, /* or 0x7 src OR dst */ {I, I, I, I}, /* nor 0x8 NOT src AND NOT dst */ {O, I, I, I}, /* equiv 0x9 NOT src XOR dst */ {O, I, O, I}, /* invert 0xa NOT dst */ {I, I, O, I}, /* orReverse 0xb src OR NOT dst */ {O, O, I, I}, /* copyInverted 0xc NOT src */ {I, O, I, I}, /* orInverted 0xd NOT src OR dst */ {I, O, O, I}, /* nand 0xe NOT src OR NOT dst */ {O, O, O, I}, /* set 0xf 1 */ }; xorg-server-1.20.13/fb/fbwindow.c0000644000175000017500000001242214100573756013445 00000000000000/* * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "fb.h" Bool fbCreateWindow(WindowPtr pWin) { dixSetPrivate(&pWin->devPrivates, fbGetWinPrivateKey(pWin), fbGetScreenPixmap(pWin->drawable.pScreen)); return TRUE; } Bool fbDestroyWindow(WindowPtr pWin) { return TRUE; } Bool fbRealizeWindow(WindowPtr pWindow) { return TRUE; } Bool fbPositionWindow(WindowPtr pWin, int x, int y) { return TRUE; } Bool fbUnrealizeWindow(WindowPtr pWindow) { return TRUE; } void fbCopyWindowProc(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); while (nbox--) { fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride, srcStride, (pbox->x1 + dx + srcXoff) * srcBpp, dst + (pbox->y1 + dstYoff) * dstStride, dstStride, (pbox->x1 + dstXoff) * dstBpp, (pbox->x2 - pbox->x1) * dstBpp, (pbox->y2 - pbox->y1), GXcopy, FB_ALLONES, dstBpp, reverse, upsidedown); pbox++; } fbFinishAccess(pDstDrawable); fbFinishAccess(pSrcDrawable); } void fbCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { RegionRec rgnDst; int dx, dy; PixmapPtr pPixmap = fbGetWindowPixmap(pWin); DrawablePtr pDrawable = &pPixmap->drawable; dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; RegionTranslate(prgnSrc, -dx, -dy); RegionNull(&rgnDst); RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc); #ifdef COMPOSITE if (pPixmap->screen_x || pPixmap->screen_y) RegionTranslate(&rgnDst, -pPixmap->screen_x, -pPixmap->screen_y); #endif miCopyRegion(pDrawable, pDrawable, 0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); RegionUninit(&rgnDst); fbValidateDrawable(&pWin->drawable); } static void fbFixupWindowPixmap(DrawablePtr pDrawable, PixmapPtr *ppPixmap) { PixmapPtr pPixmap = *ppPixmap; if (FbEvenTile(pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel)) fbPadPixmap(pPixmap); } Bool fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask) { if (mask & CWBackPixmap) { if (pWin->backgroundState == BackgroundPixmap) fbFixupWindowPixmap(&pWin->drawable, &pWin->background.pixmap); } if (mask & CWBorderPixmap) { if (pWin->borderIsPixel == FALSE) fbFixupWindowPixmap(&pWin->drawable, &pWin->border.pixmap); } return TRUE; } void fbFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, FbBits and, FbBits xor) { FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; int n = RegionNumRects(pRegion); BoxPtr pbox = RegionRects(pRegion); #ifndef FB_ACCESS_WRAPPER int try_mmx = 0; if (!and) try_mmx = 1; #endif fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); while (n--) { #ifndef FB_ACCESS_WRAPPER if (!try_mmx || !pixman_fill((uint32_t *) dst, dstStride, dstBpp, pbox->x1 + dstXoff, pbox->y1 + dstYoff, (pbox->x2 - pbox->x1), (pbox->y2 - pbox->y1), xor)) { #endif fbSolid(dst + (pbox->y1 + dstYoff) * dstStride, dstStride, (pbox->x1 + dstXoff) * dstBpp, dstBpp, (pbox->x2 - pbox->x1) * dstBpp, pbox->y2 - pbox->y1, and, xor); #ifndef FB_ACCESS_WRAPPER } #endif fbValidateDrawable(pDrawable); pbox++; } fbFinishAccess(pDrawable); } xorg-server-1.20.13/glamor/0000755000175000017500000000000014100574022012416 500000000000000xorg-server-1.20.13/glamor/meson.build0000644000175000017500000000232614100573756014520 00000000000000srcs_glamor = [ 'glamor.c', 'glamor_copy.c', 'glamor_core.c', 'glamor_dash.c', 'glamor_font.c', 'glamor_glx.c', 'glamor_composite_glyphs.c', 'glamor_image.c', 'glamor_lines.c', 'glamor_segs.c', 'glamor_render.c', 'glamor_gradient.c', 'glamor_prepare.c', 'glamor_program.c', 'glamor_rects.c', 'glamor_spans.c', 'glamor_text.c', 'glamor_transfer.c', 'glamor_transform.c', 'glamor_trapezoid.c', 'glamor_triangles.c', 'glamor_addtraps.c', 'glamor_glyphblt.c', 'glamor_points.c', 'glamor_pixmap.c', 'glamor_largepixmap.c', 'glamor_picture.c', 'glamor_vbo.c', 'glamor_window.c', 'glamor_fbo.c', 'glamor_compositerects.c', 'glamor_utils.c', 'glamor_sync.c', ] if build_xv srcs_glamor += 'glamor_xv.c' endif epoxy_dep = dependency('epoxy') glamor = static_library('glamor', srcs_glamor, include_directories: inc, dependencies: [ common_dep, epoxy_dep, ], ) glamor_egl_stubs = static_library('glamor_egl_stubs', 'glamor_egl_stubs.c', include_directories: inc, dependencies: common_dep, ) if build_xorg install_data('glamor.h', install_dir: xorgsdkdir) endif xorg-server-1.20.13/glamor/Makefile.am0000644000175000017500000000220014100573756014401 00000000000000noinst_LTLIBRARIES = libglamor.la libglamor_egl_stubs.la libglamor_la_LIBADD = $(GLAMOR_LIBS) AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS) libglamor_la_SOURCES = \ glamor.c \ glamor_context.h \ glamor_copy.c \ glamor_core.c \ glamor_dash.c \ glamor_debug.h \ glamor_font.c \ glamor_font.h \ glamor_glx.c \ glamor_composite_glyphs.c \ glamor_image.c \ glamor_lines.c \ glamor_segs.c \ glamor_render.c \ glamor_gradient.c \ glamor_prepare.c \ glamor_prepare.h \ glamor_program.c \ glamor_program.h \ glamor_rects.c \ glamor_spans.c \ glamor_text.c \ glamor_transfer.c \ glamor_transfer.h \ glamor_transform.c \ glamor_transform.h \ glamor_trapezoid.c \ glamor_triangles.c\ glamor_addtraps.c\ glamor_glyphblt.c\ glamor_points.c\ glamor_priv.h\ glamor_pixmap.c\ glamor_largepixmap.c\ glamor_picture.c\ glamor_vbo.c \ glamor_window.c\ glamor_fbo.c\ glamor_compositerects.c\ glamor_utils.c\ glamor_utils.h\ glamor_sync.c \ glamor.h if XV libglamor_la_SOURCES += \ glamor_xv.c endif libglamor_egl_stubs_la_SOURCES = \ glamor_egl_stubs.c \ glamor_egl_ext.h \ glamor_egl.h sdk_HEADERS = glamor.h xorg-server-1.20.13/glamor/glamor.h0000644000175000017500000004163114100573756014012 00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Eric Anholt * Zhigang Gong * */ #ifndef GLAMOR_H #define GLAMOR_H #include #include #include #include #include #include #ifdef GLAMOR_FOR_XORG #include #endif struct glamor_context; struct gbm_bo; struct gbm_device; /* * glamor_pixmap_type : glamor pixmap's type. * @MEMORY: pixmap is in memory. * @TEXTURE_DRM: pixmap is in a texture created from a DRM buffer. * @SEPARATE_TEXTURE: The texture is created from a DRM buffer, but * the format is incompatible, so this type of pixmap * will never fallback to DDX layer. * @DRM_ONLY: pixmap is in a external DRM buffer. * @TEXTURE_ONLY: pixmap is in an internal texture. */ typedef enum glamor_pixmap_type { GLAMOR_MEMORY = 0, /* Newly calloc()ed pixmaps are memory. */ GLAMOR_TEXTURE_DRM, GLAMOR_DRM_ONLY, GLAMOR_TEXTURE_ONLY, } glamor_pixmap_type_t; typedef Bool (*GetDrawableModifiersFuncPtr) (DrawablePtr draw, uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers); #define GLAMOR_EGL_EXTERNAL_BUFFER 3 #define GLAMOR_USE_EGL_SCREEN (1 << 0) #define GLAMOR_NO_DRI3 (1 << 1) #define GLAMOR_VALID_FLAGS (GLAMOR_USE_EGL_SCREEN \ | GLAMOR_NO_DRI3) /* until we need geometry shaders GL3.1 should suffice. */ #define GLAMOR_GL_CORE_VER_MAJOR 3 #define GLAMOR_GL_CORE_VER_MINOR 1 /* @glamor_init: Initialize glamor internal data structure. * * @screen: Current screen pointer. * @flags: Please refer the flags description above. * * @GLAMOR_USE_EGL_SCREEN: * If you are using EGL layer, then please set this bit * on, otherwise, clear it. * * @GLAMOR_NO_DRI3 * Disable the built-in DRI3 support * * This function initializes necessary internal data structure * for glamor. And before calling into this function, the OpenGL * environment should be ready. Should be called before any real * glamor rendering or texture allocation functions. And should * be called after the DDX's screen initialization or at the last * step of the DDX's screen initialization. */ extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags); extern _X_EXPORT void glamor_fini(ScreenPtr screen); /* This function is used to free the glamor private screen's * resources. If the DDX driver is not set GLAMOR_USE_SCREEN, * then, DDX need to call this function at proper stage, if * it is the xorg DDX driver,then it should be called at free * screen stage not the close screen stage. The reason is after * call to this function, the xorg DDX may need to destroy the * screen pixmap which must be a glamor pixmap and requires * the internal data structure still exist at that time. * Otherwise, the glamor internal structure will not be freed.*/ extern _X_EXPORT Bool glamor_close_screen(ScreenPtr screen); extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap); extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex); extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type); extern _X_EXPORT void glamor_clear_pixmap(PixmapPtr pixmap); extern _X_EXPORT void glamor_block_handler(ScreenPtr screen); extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage); extern _X_EXPORT Bool glamor_destroy_pixmap(PixmapPtr pixmap); #define GLAMOR_CREATE_PIXMAP_CPU 0x100 #define GLAMOR_CREATE_PIXMAP_FIXUP 0x101 #define GLAMOR_CREATE_FBO_NO_FBO 0x103 #define GLAMOR_CREATE_NO_LARGE 0x105 #define GLAMOR_CREATE_PIXMAP_NO_TEXTURE 0x106 /* @glamor_egl_exchange_buffers: Exchange the underlying buffers(KHR image,fbo). * * @front: front pixmap. * @back: back pixmap. * * Used by the DRI2 page flip. This function will exchange the KHR images and * fbos of the two pixmaps. * */ extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back); extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back); /* The DDX is not supposed to call these four functions */ extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen); extern _X_EXPORT int glamor_egl_fds_from_pixmap(ScreenPtr, PixmapPtr, int *, uint32_t *, uint32_t *, uint64_t *); extern _X_EXPORT int glamor_egl_fd_name_from_pixmap(ScreenPtr, PixmapPtr, CARD16 *, CARD32 *); extern _X_EXPORT struct gbm_device *glamor_egl_get_gbm_device(ScreenPtr screen); extern _X_EXPORT int glamor_egl_fd_from_pixmap(ScreenPtr, PixmapPtr, CARD16 *, CARD32 *); /* @glamor_supports_pixmap_import_export: Returns whether * glamor_fds_from_pixmap(), glamor_name_from_pixmap(), and * glamor_pixmap_from_fds() are supported. * * @screen: Current screen pointer. * * To have DRI3 support enabled, glamor and glamor_egl need to be * initialized. glamor also has to be compiled with gbm support. * * The EGL layer needs to have the following extensions working: * * .EGL_KHR_surfaceless_context * */ extern _X_EXPORT Bool glamor_supports_pixmap_import_export(ScreenPtr screen); /* @glamor_fds_from_pixmap: Get a dma-buf fd from a pixmap. * * @screen: Current screen pointer. * @pixmap: The pixmap from which we want the fd. * @fds, @strides, @offsets: Pointers to fill info of each plane. * @modifier: Pointer to fill the modifier of the buffer. * * the pixmap and the buffer associated by the fds will share the same * content. The caller is responsible to close the returned file descriptors. * Returns the number of planes, -1 on error. * */ extern _X_EXPORT int glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, uint32_t *strides, uint32_t *offsets, uint64_t *modifier); /* @glamor_fd_from_pixmap: Get a dma-buf fd from a pixmap. * * @screen: Current screen pointer. * @pixmap: The pixmap from which we want the fd. * @stride, @size: Pointers to fill the stride and size of the * buffer associated to the fd. * * the pixmap and the buffer associated by the fd will share the same * content. * Returns the fd on success, -1 on error. * */ extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size); /* @glamor_shareable_fd_from_pixmap: Get a dma-buf fd suitable for sharing * with other GPUs from a pixmap. * * @screen: Current screen pointer. * @pixmap: The pixmap from which we want the fd. * @stride, @size: Pointers to fill the stride and size of the * buffer associated to the fd. * * The returned fd will point to a buffer which is suitable for sharing * across GPUs (not using GPU specific tiling). * The pixmap and the buffer associated by the fd will share the same * content. * The pixmap's stride may be modified by this function. * Returns the fd on success, -1 on error. * */ extern _X_EXPORT int glamor_shareable_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size); /** * @glamor_name_from_pixmap: Gets a gem name from a pixmap. * * @pixmap: The pixmap from which we want the gem name. * * the pixmap and the buffer associated by the gem name will share the * same content. This function can be used by the DDX to support DRI2, * and needs the same set of buffer export GL extensions as DRI3 * support. * * Returns the name on success, -1 on error. * */ extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size); /* @glamor_gbm_bo_from_pixmap: Get a GBM bo from a pixmap. * * @screen: Current screen pointer. * @pixmap: The pixmap from which we want the fd. * @stride, @size: Pointers to fill the stride and size of the * buffer associated to the fd. * * the pixmap and the buffer represented by the gbm_bo will share the same * content. * * Returns the gbm_bo on success, NULL on error. * */ extern _X_EXPORT struct gbm_bo *glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap); /* @glamor_pixmap_from_fds: Creates a pixmap to wrap a dma-buf fds. * * @screen: Current screen pointer. * @num_fds: Number of fds to import * @fds: The dma-buf fds to import. * @width: The width of the buffers. * @height: The height of the buffers. * @stride: The stride of the buffers. * @depth: The depth of the buffers. * @bpp: The bpp of the buffers. * @modifier: The modifier of the buffers. * * Returns a valid pixmap if the import succeeded, else NULL. * */ extern _X_EXPORT PixmapPtr glamor_pixmap_from_fds(ScreenPtr screen, CARD8 num_fds, const int *fds, CARD16 width, CARD16 height, const CARD32 *strides, const CARD32 *offsets, CARD8 depth, CARD8 bpp, uint64_t modifier); /* @glamor_pixmap_from_fd: Creates a pixmap to wrap a dma-buf fd. * * @screen: Current screen pointer. * @fd: The dma-buf fd to import. * @width: The width of the buffer. * @height: The height of the buffer. * @stride: The stride of the buffer. * @depth: The depth of the buffer. * @bpp: The bpp of the buffer. * * Returns a valid pixmap if the import succeeded, else NULL. * */ extern _X_EXPORT PixmapPtr glamor_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp); /* @glamor_back_pixmap_from_fd: Backs an existing pixmap with a dma-buf fd. * * @pixmap: Pixmap to change backing for * @fd: The dma-buf fd to import. * @width: The width of the buffer. * @height: The height of the buffer. * @stride: The stride of the buffer. * @depth: The depth of the buffer. * @bpp: The number of bpp of the buffer. * * Returns TRUE if successful, FALSE on failure. * */ extern _X_EXPORT Bool glamor_back_pixmap_from_fd(PixmapPtr pixmap, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp); extern _X_EXPORT Bool glamor_get_formats(ScreenPtr screen, CARD32 *num_formats, CARD32 **formats); extern _X_EXPORT Bool glamor_get_modifiers(ScreenPtr screen, uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers); extern _X_EXPORT Bool glamor_get_drawable_modifiers(DrawablePtr draw, uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers); extern _X_EXPORT void glamor_set_drawable_modifiers_func(ScreenPtr screen, GetDrawableModifiersFuncPtr func); #ifdef GLAMOR_FOR_XORG #define GLAMOR_EGL_MODULE_NAME "glamoregl" /* @glamor_egl_init: Initialize EGL environment. * * @scrn: Current screen info pointer. * @fd: Current drm fd. * * This function creates and intialize EGL contexts. * Should be called from DDX's preInit function. * Return TRUE if success, otherwise return FALSE. * */ extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd); extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen); /* @glamor_egl_create_textured_screen: Create textured screen pixmap. * * @screen: screen pointer to be processed. * @handle: screen pixmap's BO handle. * @stride: screen pixmap's stride in bytes. * * This function is similar with the create_textured_pixmap. As the * screen pixmap is a special, we handle it separately in this function. */ extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride); /* Obsolete entrypoint, temporarily left here for API compatibility * for xf86-video-ati. */ #define glamor_egl_create_textured_screen_ext(a, b, c, d) \ glamor_egl_create_textured_screen(a, b, c) /* * @glamor_egl_create_textured_pixmap: Try to create a textured pixmap from * a BO handle. * * @pixmap: The pixmap need to be processed. * @handle: The BO's handle attached to this pixmap at DDX layer. * @stride: Stride in bytes for this pixmap. * * This function try to create a texture from the handle and attach * the texture to the pixmap , thus glamor can render to this pixmap * as well. Return true if successful, otherwise return FALSE. */ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride); /* * @glamor_egl_create_textured_pixmap_from_bo: Try to create a textured pixmap * from a gbm_bo. * * @pixmap: The pixmap need to be processed. * @bo: a pointer on a gbm_bo structure attached to this pixmap at DDX layer. * * This function is similar to glamor_egl_create_textured_pixmap. */ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, struct gbm_bo *bo, Bool used_modifiers); extern _X_EXPORT const char *glamor_egl_get_driver_name(ScreenPtr screen); #endif extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx); extern _X_EXPORT int glamor_create_gc(GCPtr gc); extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable); extern _X_EXPORT void glamor_destroy_gc(GCPtr gc); #define HAS_GLAMOR_DESTROY_GC 1 extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region); extern _X_EXPORT void glamor_finish(ScreenPtr screen); #define HAS_GLAMOR_TEXT 1 #ifdef GLAMOR_FOR_XORG extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen, int num_texture_ports); #endif #endif /* GLAMOR_H */ xorg-server-1.20.13/glamor/Makefile.in0000644000175000017500000011327214100573775014427 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @XV_TRUE@am__append_1 = \ @XV_TRUE@ glamor_xv.c subdir = glamor ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(sdk_HEADERS) $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libglamor_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__libglamor_la_SOURCES_DIST = glamor.c glamor_context.h \ glamor_copy.c glamor_core.c glamor_dash.c glamor_debug.h \ glamor_font.c glamor_font.h glamor_glx.c \ glamor_composite_glyphs.c glamor_image.c glamor_lines.c \ glamor_segs.c glamor_render.c glamor_gradient.c \ glamor_prepare.c glamor_prepare.h glamor_program.c \ glamor_program.h glamor_rects.c glamor_spans.c glamor_text.c \ glamor_transfer.c glamor_transfer.h glamor_transform.c \ glamor_transform.h glamor_trapezoid.c glamor_triangles.c \ glamor_addtraps.c glamor_glyphblt.c glamor_points.c \ glamor_priv.h glamor_pixmap.c glamor_largepixmap.c \ glamor_picture.c glamor_vbo.c glamor_window.c glamor_fbo.c \ glamor_compositerects.c glamor_utils.c glamor_utils.h \ glamor_sync.c glamor.h glamor_xv.c @XV_TRUE@am__objects_1 = glamor_xv.lo am_libglamor_la_OBJECTS = glamor.lo glamor_copy.lo glamor_core.lo \ glamor_dash.lo glamor_font.lo glamor_glx.lo \ glamor_composite_glyphs.lo glamor_image.lo glamor_lines.lo \ glamor_segs.lo glamor_render.lo glamor_gradient.lo \ glamor_prepare.lo glamor_program.lo glamor_rects.lo \ glamor_spans.lo glamor_text.lo glamor_transfer.lo \ glamor_transform.lo glamor_trapezoid.lo glamor_triangles.lo \ glamor_addtraps.lo glamor_glyphblt.lo glamor_points.lo \ glamor_pixmap.lo glamor_largepixmap.lo glamor_picture.lo \ glamor_vbo.lo glamor_window.lo glamor_fbo.lo \ glamor_compositerects.lo glamor_utils.lo glamor_sync.lo \ $(am__objects_1) libglamor_la_OBJECTS = $(am_libglamor_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libglamor_egl_stubs_la_LIBADD = am_libglamor_egl_stubs_la_OBJECTS = glamor_egl_stubs.lo libglamor_egl_stubs_la_OBJECTS = $(am_libglamor_egl_stubs_la_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/glamor.Plo \ ./$(DEPDIR)/glamor_addtraps.Plo \ ./$(DEPDIR)/glamor_composite_glyphs.Plo \ ./$(DEPDIR)/glamor_compositerects.Plo \ ./$(DEPDIR)/glamor_copy.Plo ./$(DEPDIR)/glamor_core.Plo \ ./$(DEPDIR)/glamor_dash.Plo ./$(DEPDIR)/glamor_egl_stubs.Plo \ ./$(DEPDIR)/glamor_fbo.Plo ./$(DEPDIR)/glamor_font.Plo \ ./$(DEPDIR)/glamor_glx.Plo ./$(DEPDIR)/glamor_glyphblt.Plo \ ./$(DEPDIR)/glamor_gradient.Plo ./$(DEPDIR)/glamor_image.Plo \ ./$(DEPDIR)/glamor_largepixmap.Plo \ ./$(DEPDIR)/glamor_lines.Plo ./$(DEPDIR)/glamor_picture.Plo \ ./$(DEPDIR)/glamor_pixmap.Plo ./$(DEPDIR)/glamor_points.Plo \ ./$(DEPDIR)/glamor_prepare.Plo ./$(DEPDIR)/glamor_program.Plo \ ./$(DEPDIR)/glamor_rects.Plo ./$(DEPDIR)/glamor_render.Plo \ ./$(DEPDIR)/glamor_segs.Plo ./$(DEPDIR)/glamor_spans.Plo \ ./$(DEPDIR)/glamor_sync.Plo ./$(DEPDIR)/glamor_text.Plo \ ./$(DEPDIR)/glamor_transfer.Plo \ ./$(DEPDIR)/glamor_transform.Plo \ ./$(DEPDIR)/glamor_trapezoid.Plo \ ./$(DEPDIR)/glamor_triangles.Plo ./$(DEPDIR)/glamor_utils.Plo \ ./$(DEPDIR)/glamor_vbo.Plo ./$(DEPDIR)/glamor_window.Plo \ ./$(DEPDIR)/glamor_xv.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libglamor_la_SOURCES) $(libglamor_egl_stubs_la_SOURCES) DIST_SOURCES = $(am__libglamor_la_SOURCES_DIST) \ $(libglamor_egl_stubs_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(sdkdir)" HEADERS = $(sdk_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libglamor.la libglamor_egl_stubs.la libglamor_la_LIBADD = $(GLAMOR_LIBS) AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS) libglamor_la_SOURCES = glamor.c glamor_context.h glamor_copy.c \ glamor_core.c glamor_dash.c glamor_debug.h glamor_font.c \ glamor_font.h glamor_glx.c glamor_composite_glyphs.c \ glamor_image.c glamor_lines.c glamor_segs.c glamor_render.c \ glamor_gradient.c glamor_prepare.c glamor_prepare.h \ glamor_program.c glamor_program.h glamor_rects.c \ glamor_spans.c glamor_text.c glamor_transfer.c \ glamor_transfer.h glamor_transform.c glamor_transform.h \ glamor_trapezoid.c glamor_triangles.c glamor_addtraps.c \ glamor_glyphblt.c glamor_points.c glamor_priv.h \ glamor_pixmap.c glamor_largepixmap.c glamor_picture.c \ glamor_vbo.c glamor_window.c glamor_fbo.c \ glamor_compositerects.c glamor_utils.c glamor_utils.h \ glamor_sync.c glamor.h $(am__append_1) libglamor_egl_stubs_la_SOURCES = \ glamor_egl_stubs.c \ glamor_egl_ext.h \ glamor_egl.h sdk_HEADERS = glamor.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign glamor/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign glamor/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libglamor.la: $(libglamor_la_OBJECTS) $(libglamor_la_DEPENDENCIES) $(EXTRA_libglamor_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libglamor_la_OBJECTS) $(libglamor_la_LIBADD) $(LIBS) libglamor_egl_stubs.la: $(libglamor_egl_stubs_la_OBJECTS) $(libglamor_egl_stubs_la_DEPENDENCIES) $(EXTRA_libglamor_egl_stubs_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libglamor_egl_stubs_la_OBJECTS) $(libglamor_egl_stubs_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_addtraps.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_composite_glyphs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_compositerects.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_copy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_core.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_dash.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_egl_stubs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_fbo.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_font.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_glx.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_glyphblt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_gradient.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_image.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_largepixmap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_lines.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_picture.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_pixmap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_points.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_prepare.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_program.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_rects.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_render.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_segs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_spans.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_sync.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_text.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_transfer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_transform.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_trapezoid.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_triangles.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_vbo.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_window.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_xv.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-sdkHEADERS: $(sdk_HEADERS) @$(NORMAL_INSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sdkdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sdkdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(sdkdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(sdkdir)" || exit $$?; \ done uninstall-sdkHEADERS: @$(NORMAL_UNINSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(sdkdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/glamor.Plo -rm -f ./$(DEPDIR)/glamor_addtraps.Plo -rm -f ./$(DEPDIR)/glamor_composite_glyphs.Plo -rm -f ./$(DEPDIR)/glamor_compositerects.Plo -rm -f ./$(DEPDIR)/glamor_copy.Plo -rm -f ./$(DEPDIR)/glamor_core.Plo -rm -f ./$(DEPDIR)/glamor_dash.Plo -rm -f ./$(DEPDIR)/glamor_egl_stubs.Plo -rm -f ./$(DEPDIR)/glamor_fbo.Plo -rm -f ./$(DEPDIR)/glamor_font.Plo -rm -f ./$(DEPDIR)/glamor_glx.Plo -rm -f ./$(DEPDIR)/glamor_glyphblt.Plo -rm -f ./$(DEPDIR)/glamor_gradient.Plo -rm -f ./$(DEPDIR)/glamor_image.Plo -rm -f ./$(DEPDIR)/glamor_largepixmap.Plo -rm -f ./$(DEPDIR)/glamor_lines.Plo -rm -f ./$(DEPDIR)/glamor_picture.Plo -rm -f ./$(DEPDIR)/glamor_pixmap.Plo -rm -f ./$(DEPDIR)/glamor_points.Plo -rm -f ./$(DEPDIR)/glamor_prepare.Plo -rm -f ./$(DEPDIR)/glamor_program.Plo -rm -f ./$(DEPDIR)/glamor_rects.Plo -rm -f ./$(DEPDIR)/glamor_render.Plo -rm -f ./$(DEPDIR)/glamor_segs.Plo -rm -f ./$(DEPDIR)/glamor_spans.Plo -rm -f ./$(DEPDIR)/glamor_sync.Plo -rm -f ./$(DEPDIR)/glamor_text.Plo -rm -f ./$(DEPDIR)/glamor_transfer.Plo -rm -f ./$(DEPDIR)/glamor_transform.Plo -rm -f ./$(DEPDIR)/glamor_trapezoid.Plo -rm -f ./$(DEPDIR)/glamor_triangles.Plo -rm -f ./$(DEPDIR)/glamor_utils.Plo -rm -f ./$(DEPDIR)/glamor_vbo.Plo -rm -f ./$(DEPDIR)/glamor_window.Plo -rm -f ./$(DEPDIR)/glamor_xv.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-sdkHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/glamor.Plo -rm -f ./$(DEPDIR)/glamor_addtraps.Plo -rm -f ./$(DEPDIR)/glamor_composite_glyphs.Plo -rm -f ./$(DEPDIR)/glamor_compositerects.Plo -rm -f ./$(DEPDIR)/glamor_copy.Plo -rm -f ./$(DEPDIR)/glamor_core.Plo -rm -f ./$(DEPDIR)/glamor_dash.Plo -rm -f ./$(DEPDIR)/glamor_egl_stubs.Plo -rm -f ./$(DEPDIR)/glamor_fbo.Plo -rm -f ./$(DEPDIR)/glamor_font.Plo -rm -f ./$(DEPDIR)/glamor_glx.Plo -rm -f ./$(DEPDIR)/glamor_glyphblt.Plo -rm -f ./$(DEPDIR)/glamor_gradient.Plo -rm -f ./$(DEPDIR)/glamor_image.Plo -rm -f ./$(DEPDIR)/glamor_largepixmap.Plo -rm -f ./$(DEPDIR)/glamor_lines.Plo -rm -f ./$(DEPDIR)/glamor_picture.Plo -rm -f ./$(DEPDIR)/glamor_pixmap.Plo -rm -f ./$(DEPDIR)/glamor_points.Plo -rm -f ./$(DEPDIR)/glamor_prepare.Plo -rm -f ./$(DEPDIR)/glamor_program.Plo -rm -f ./$(DEPDIR)/glamor_rects.Plo -rm -f ./$(DEPDIR)/glamor_render.Plo -rm -f ./$(DEPDIR)/glamor_segs.Plo -rm -f ./$(DEPDIR)/glamor_spans.Plo -rm -f ./$(DEPDIR)/glamor_sync.Plo -rm -f ./$(DEPDIR)/glamor_text.Plo -rm -f ./$(DEPDIR)/glamor_transfer.Plo -rm -f ./$(DEPDIR)/glamor_transform.Plo -rm -f ./$(DEPDIR)/glamor_trapezoid.Plo -rm -f ./$(DEPDIR)/glamor_triangles.Plo -rm -f ./$(DEPDIR)/glamor_utils.Plo -rm -f ./$(DEPDIR)/glamor_vbo.Plo -rm -f ./$(DEPDIR)/glamor_window.Plo -rm -f ./$(DEPDIR)/glamor_xv.Plo -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 TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am 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 tags-am uninstall uninstall-am \ uninstall-sdkHEADERS .PRECIOUS: Makefile # 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: xorg-server-1.20.13/glamor/glamor.c0000644000175000017500000007531214100573756014010 00000000000000/* * Copyright © 2008,2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Eric Anholt * Zhigang Gong * Chad Versace */ /** @file glamor.c * This file covers the initialization and teardown of glamor, and has various * functions not responsible for performing rendering. */ #include #include #include "glamor_priv.h" #include "mipict.h" DevPrivateKeyRec glamor_screen_private_key; DevPrivateKeyRec glamor_pixmap_private_key; DevPrivateKeyRec glamor_gc_private_key; glamor_screen_private * glamor_get_screen_private(ScreenPtr screen) { return (glamor_screen_private *) dixLookupPrivate(&screen->devPrivates, &glamor_screen_private_key); } void glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv) { dixSetPrivate(&screen->devPrivates, &glamor_screen_private_key, priv); } /** * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable. * * @param drawable the drawable being requested. * * This function returns the backing pixmap for a drawable, whether it is a * redirected window, unredirected window, or already a pixmap. Note that * coordinate translation is needed when drawing to the backing pixmap of a * redirected window, and the translation coordinates are provided by calling * exaGetOffscreenPixmap() on the drawable. */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable) { if (drawable->type == DRAWABLE_WINDOW) return drawable->pScreen->GetWindowPixmap((WindowPtr) drawable); else return (PixmapPtr) drawable; } static void glamor_init_pixmap_private_small(PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv) { pixmap_priv->box.x1 = 0; pixmap_priv->box.x2 = pixmap->drawable.width; pixmap_priv->box.y1 = 0; pixmap_priv->box.y2 = pixmap->drawable.height; pixmap_priv->block_w = pixmap->drawable.width; pixmap_priv->block_h = pixmap->drawable.height; pixmap_priv->block_hcnt = 1; pixmap_priv->block_wcnt = 1; pixmap_priv->box_array = &pixmap_priv->box; pixmap_priv->fbo_array = &pixmap_priv->fbo; } _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type) { glamor_pixmap_private *pixmap_priv; pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv->type = type; glamor_init_pixmap_private_small(pixmap, pixmap_priv); } _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv; glamor_pixmap_fbo *fbo; GLenum format; glamor_priv = glamor_get_screen_private(screen); pixmap_priv = glamor_get_pixmap_private(pixmap); if (pixmap_priv->fbo) { fbo = glamor_pixmap_detach_fbo(pixmap_priv); glamor_destroy_fbo(glamor_priv, fbo); } format = gl_iformat_for_pixmap(pixmap); fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width, pixmap->drawable.height, format, tex, 0); if (fbo == NULL) { ErrorF("XXX fail to create fbo.\n"); return; } glamor_pixmap_attach_fbo(pixmap, fbo); } _X_EXPORT void glamor_clear_pixmap(PixmapPtr pixmap) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv; glamor_pixmap_private *pixmap_priv; glamor_priv = glamor_get_screen_private(screen); pixmap_priv = glamor_get_pixmap_private(pixmap); assert(pixmap_priv->fbo != NULL); glamor_pixmap_clear_fbo(glamor_priv, pixmap_priv->fbo); } uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); if (!pixmap_priv) return 0; if (!pixmap_priv->fbo) return 0; if (pixmap_priv->type != GLAMOR_TEXTURE_ONLY) return 0; return pixmap_priv->fbo->tex; } void glamor_bind_texture(glamor_screen_private *glamor_priv, GLenum texture, glamor_pixmap_fbo *fbo, Bool destination_red) { glActiveTexture(texture); glBindTexture(GL_TEXTURE_2D, fbo->tex); /* If we're pulling data from a GL_RED texture, then whether we * want to make it an A,0,0,0 result or a 0,0,0,R result depends * on whether the destination is also a GL_RED texture. * * For GL_RED destinations, we need to leave the bits in the R * channel. For all other destinations, we need to clear out the R * channel so that it returns zero for R, G and B. * * Note that we're leaving the SWIZZLE_A value alone; for GL_RED * destinations, that means we'll actually be returning R,0,0,R, * but it doesn't matter as the bits in the alpha channel aren't * going anywhere. */ /* Is the operand a GL_RED fbo? */ if (glamor_fbo_red_is_alpha(glamor_priv, fbo)) { /* If destination is also GL_RED, then preserve the bits in * the R channel */ if (destination_red) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED); else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ZERO); } } PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage) { PixmapPtr pixmap; glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_fbo *fbo = NULL; int pitch; GLenum format; if (w > 32767 || h > 32767) return NullPixmap; if ((usage == GLAMOR_CREATE_PIXMAP_CPU || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= glamor_priv->glyph_max_dim && h <= glamor_priv->glyph_max_dim) || (w == 0 && h == 0) || !glamor_check_pixmap_fbo_depth(depth))) return fbCreatePixmap(screen, w, h, depth, usage); else pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); pixmap_priv = glamor_get_pixmap_private(pixmap); format = gl_iformat_for_pixmap(pixmap); pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3; screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL); pixmap_priv->type = GLAMOR_TEXTURE_ONLY; if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) { glamor_init_pixmap_private_small(pixmap, pixmap_priv); return pixmap; } else if (usage == GLAMOR_CREATE_NO_LARGE || glamor_check_fbo_size(glamor_priv, w, h)) { glamor_init_pixmap_private_small(pixmap, pixmap_priv); fbo = glamor_create_fbo(glamor_priv, w, h, format, usage); } else { int tile_size = glamor_priv->max_fbo_size; DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n", pixmap, w, h, tile_size); fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage, tile_size, tile_size, pixmap_priv); } if (fbo == NULL) { fbDestroyPixmap(pixmap); return fbCreatePixmap(screen, w, h, depth, usage); } glamor_pixmap_attach_fbo(pixmap, fbo); return pixmap; } Bool glamor_destroy_pixmap(PixmapPtr pixmap) { if (pixmap->refcnt == 1) { glamor_pixmap_destroy_fbo(pixmap); } return fbDestroyPixmap(pixmap); } void glamor_block_handler(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); glFlush(); } static void _glamor_block_handler(ScreenPtr screen, void *timeout) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); glFlush(); screen->BlockHandler = glamor_priv->saved_procs.block_handler; screen->BlockHandler(screen, timeout); glamor_priv->saved_procs.block_handler = screen->BlockHandler; screen->BlockHandler = _glamor_block_handler; } static void glamor_set_debug_level(int *debug_level) { char *debug_level_string; debug_level_string = getenv("GLAMOR_DEBUG"); if (debug_level_string && sscanf(debug_level_string, "%d", debug_level) == 1) return; *debug_level = 0; } int glamor_debug_level; void glamor_gldrawarrays_quads_using_indices(glamor_screen_private *glamor_priv, unsigned count) { unsigned i; /* For a single quad, don't bother with an index buffer. */ if (count == 1) goto fallback; if (glamor_priv->ib_size < count) { /* Basic GLES2 doesn't have any way to map buffer objects for * writing, but it's long past time for drivers to have * MapBufferRange. */ if (!glamor_priv->has_map_buffer_range) goto fallback; /* Lazy create the buffer name, and only bind it once since * none of the glamor code binds it to anything else. */ if (!glamor_priv->ib) { glGenBuffers(1, &glamor_priv->ib); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ib); } /* For now, only support GL_UNSIGNED_SHORTs. */ if (count > ((1 << 16) - 1) / 4) { goto fallback; } else { uint16_t *data; size_t size = count * 6 * sizeof(GLushort); glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW); data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); for (i = 0; i < count; i++) { data[i * 6 + 0] = i * 4 + 0; data[i * 6 + 1] = i * 4 + 1; data[i * 6 + 2] = i * 4 + 2; data[i * 6 + 3] = i * 4 + 0; data[i * 6 + 4] = i * 4 + 2; data[i * 6 + 5] = i * 4 + 3; } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); glamor_priv->ib_size = count; glamor_priv->ib_type = GL_UNSIGNED_SHORT; } } glDrawElements(GL_TRIANGLES, count * 6, glamor_priv->ib_type, NULL); return; fallback: for (i = 0; i < count; i++) glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4); } static Bool glamor_check_instruction_count(int gl_version) { GLint max_native_alu_instructions; /* Avoid using glamor if the reported instructions limit is too low, * as this would cause glamor to fallback on sw due to large shaders * which ends up being unbearably slow. */ if (gl_version < 30) { if (!epoxy_has_gl_extension("GL_ARB_fragment_program")) { ErrorF("GL_ARB_fragment_program required\n"); return FALSE; } glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, &max_native_alu_instructions); if (max_native_alu_instructions < GLAMOR_MIN_ALU_INSTRUCTIONS) { LogMessage(X_WARNING, "glamor requires at least %d instructions (%d reported)\n", GLAMOR_MIN_ALU_INSTRUCTIONS, max_native_alu_instructions); return FALSE; } } return TRUE; } static void GLAPIENTRY glamor_debug_output_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { ScreenPtr screen = (void *)userParam; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); if (glamor_priv->suppress_gl_out_of_memory_logging && source == GL_DEBUG_SOURCE_API && type == GL_DEBUG_TYPE_ERROR) { return; } LogMessageVerb(X_ERROR, 0, "glamor%d: GL error: %*s\n", screen->myNum, length, message); } /** * Configures GL_ARB_debug_output to give us immediate callbacks when * GL errors occur, so that we can log them. */ static void glamor_setup_debug_output(ScreenPtr screen) { if (!epoxy_has_gl_extension("GL_ARB_debug_output")) return; glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); /* Disable debugging messages other than GL API errors */ glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE); glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, NULL, GL_TRUE); glDebugMessageCallback(glamor_debug_output_callback, screen); /* If KHR_debug is present, all debug output is disabled by * default on non-debug contexts. */ if (epoxy_has_gl_extension("GL_KHR_debug")) glEnable(GL_DEBUG_OUTPUT); } /** Set up glamor for an already-configured GL context. */ Bool glamor_init(ScreenPtr screen, unsigned int flags) { glamor_screen_private *glamor_priv; int gl_version; int glsl_major, glsl_minor; int max_viewport_size[2]; const char *shading_version_string; int shading_version_offset; PictureScreenPtr ps = GetPictureScreenIfSet(screen); if (flags & ~GLAMOR_VALID_FLAGS) { ErrorF("glamor_init: Invalid flags %x\n", flags); return FALSE; } glamor_priv = calloc(1, sizeof(*glamor_priv)); if (glamor_priv == NULL) return FALSE; glamor_priv->flags = flags; if (!dixRegisterPrivateKey(&glamor_screen_private_key, PRIVATE_SCREEN, 0)) { LogMessage(X_WARNING, "glamor%d: Failed to allocate screen private\n", screen->myNum); goto free_glamor_private; } glamor_set_screen_private(screen, glamor_priv); if (!dixRegisterPrivateKey(&glamor_pixmap_private_key, PRIVATE_PIXMAP, sizeof(struct glamor_pixmap_private))) { LogMessage(X_WARNING, "glamor%d: Failed to allocate pixmap private\n", screen->myNum); goto free_glamor_private; } if (!dixRegisterPrivateKey(&glamor_gc_private_key, PRIVATE_GC, sizeof (glamor_gc_private))) { LogMessage(X_WARNING, "glamor%d: Failed to allocate gc private\n", screen->myNum); goto free_glamor_private; } glamor_priv->saved_procs.close_screen = screen->CloseScreen; screen->CloseScreen = glamor_close_screen; glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap; screen->DestroyPixmap = glamor_destroy_pixmap; /* If we are using egl screen, call egl screen init to * register correct close screen function. */ if (flags & GLAMOR_USE_EGL_SCREEN) { glamor_egl_screen_init(screen, &glamor_priv->ctx); } else { if (!glamor_glx_screen_init(&glamor_priv->ctx)) goto fail; } glamor_make_current(glamor_priv); if (epoxy_is_desktop_gl()) glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP; else glamor_priv->gl_flavor = GLAMOR_GL_ES2; gl_version = epoxy_gl_version(); /* assume a core profile if we are GL 3.1 and don't have ARB_compatibility */ glamor_priv->is_core_profile = gl_version >= 31 && !epoxy_has_gl_extension("GL_ARB_compatibility"); shading_version_string = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION); if (!shading_version_string) { LogMessage(X_WARNING, "glamor%d: Failed to get GLSL version\n", screen->myNum); goto fail; } shading_version_offset = 0; if (strncmp("OpenGL ES GLSL ES ", shading_version_string, 18) == 0) shading_version_offset = 18; if (sscanf(shading_version_string + shading_version_offset, "%i.%i", &glsl_major, &glsl_minor) != 2) { LogMessage(X_WARNING, "glamor%d: Failed to parse GLSL version string %s\n", screen->myNum, shading_version_string); goto fail; } glamor_priv->glsl_version = glsl_major * 100 + glsl_minor; if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { /* Force us back to the base version of our programs on an ES * context, anyway. Basically glamor only uses desktop 1.20 * or 1.30 currently. 1.30's new features are also present in * ES 3.0, but our glamor_program.c constructions use a lot of * compatibility features (to reduce the diff between 1.20 and * 1.30 programs). */ glamor_priv->glsl_version = 120; } /* We'd like to require GL_ARB_map_buffer_range or * GL_OES_map_buffer_range, since it offers more information to * the driver than plain old glMapBuffer() or glBufferSubData(). * It's been supported on Mesa on the desktop since 2009 and on * GLES2 since October 2012. It's supported on Apple's iOS * drivers for SGX535 and A7, but apparently not on most Android * devices (the OES extension spec wasn't released until June * 2012). * * 82% of 0 A.D. players (desktop GL) submitting hardware reports * have support for it, with most of the ones lacking it being on * Windows with Intel 4-series (G45) graphics or older. */ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { if (gl_version < 21) { ErrorF("Require OpenGL version 2.1 or later.\n"); goto fail; } if (!glamor_priv->is_core_profile && !epoxy_has_gl_extension("GL_ARB_texture_border_clamp")) { ErrorF("GL_ARB_texture_border_clamp required\n"); goto fail; } if (!glamor_check_instruction_count(gl_version)) goto fail; /* Glamor rendering assumes that platforms with GLSL 130+ * have instanced arrays, but this is not always the case. * etnaviv offers GLSL 140 with OpenGL 2.1. */ if (glamor_priv->glsl_version >= 130 && !epoxy_has_gl_extension("GL_ARB_instanced_arrays")) glamor_priv->glsl_version = 120; } else { if (gl_version < 20) { ErrorF("Require Open GLES2.0 or later.\n"); goto fail; } if (!epoxy_has_gl_extension("GL_EXT_texture_format_BGRA8888")) { ErrorF("GL_EXT_texture_format_BGRA8888 required\n"); goto fail; } if (!epoxy_has_gl_extension("GL_OES_texture_border_clamp")) { ErrorF("GL_OES_texture_border_clamp required\n"); goto fail; } } if (!epoxy_has_gl_extension("GL_ARB_vertex_array_object") && !epoxy_has_gl_extension("GL_OES_vertex_array_object")) { ErrorF("GL_{ARB,OES}_vertex_array_object required\n"); goto fail; } glamor_priv->has_rw_pbo = FALSE; if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) glamor_priv->has_rw_pbo = TRUE; glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug"); glamor_priv->has_pack_invert = epoxy_has_gl_extension("GL_MESA_pack_invert"); glamor_priv->has_fbo_blit = epoxy_has_gl_extension("GL_EXT_framebuffer_blit"); glamor_priv->has_map_buffer_range = epoxy_has_gl_extension("GL_ARB_map_buffer_range") || epoxy_has_gl_extension("GL_EXT_map_buffer_range"); glamor_priv->has_buffer_storage = epoxy_has_gl_extension("GL_ARB_buffer_storage"); glamor_priv->has_mesa_tile_raster_order = epoxy_has_gl_extension("GL_MESA_tile_raster_order"); glamor_priv->has_nv_texture_barrier = epoxy_has_gl_extension("GL_NV_texture_barrier"); glamor_priv->has_unpack_subimage = glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP || epoxy_gl_version() >= 30 || epoxy_has_gl_extension("GL_EXT_unpack_subimage"); glamor_priv->has_pack_subimage = glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP || epoxy_gl_version() >= 30 || epoxy_has_gl_extension("GL_NV_pack_subimage"); glamor_priv->has_dual_blend = glamor_priv->glsl_version >= 130 && epoxy_has_gl_extension("GL_ARB_blend_func_extended"); glamor_priv->can_copyplane = (gl_version >= 30); glamor_setup_debug_output(screen); glamor_priv->use_quads = (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) && !glamor_priv->is_core_profile; /* Driver-specific hack: Avoid using GL_QUADS on VC4, where * they'll be emulated more expensively than we can with our * cached IB. */ if (strstr((char *)glGetString(GL_VENDOR), "Broadcom") && (strstr((char *)glGetString(GL_RENDERER), "VC4") || strstr((char *)glGetString(GL_RENDERER), "V3D"))) glamor_priv->use_quads = FALSE; glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size); glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size); glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[0]); glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[1]); #ifdef MAX_FBO_SIZE glamor_priv->max_fbo_size = MAX_FBO_SIZE; #endif glamor_priv->has_texture_swizzle = (epoxy_has_gl_extension("GL_ARB_texture_swizzle") || (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && gl_version >= 30)); glamor_priv->one_channel_format = GL_ALPHA; if (epoxy_has_gl_extension("GL_ARB_texture_rg") && glamor_priv->has_texture_swizzle) { glamor_priv->one_channel_format = GL_RED; } glamor_set_debug_level(&glamor_debug_level); if (!glamor_font_init(screen)) goto fail; glamor_priv->saved_procs.block_handler = screen->BlockHandler; screen->BlockHandler = _glamor_block_handler; if (!glamor_composite_glyphs_init(screen)) { ErrorF("Failed to initialize composite masks\n"); goto fail; } glamor_priv->saved_procs.create_gc = screen->CreateGC; screen->CreateGC = glamor_create_gc; glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap; screen->CreatePixmap = glamor_create_pixmap; glamor_priv->saved_procs.get_spans = screen->GetSpans; screen->GetSpans = glamor_get_spans; glamor_priv->saved_procs.get_image = screen->GetImage; screen->GetImage = glamor_get_image; glamor_priv->saved_procs.change_window_attributes = screen->ChangeWindowAttributes; screen->ChangeWindowAttributes = glamor_change_window_attributes; glamor_priv->saved_procs.copy_window = screen->CopyWindow; screen->CopyWindow = glamor_copy_window; glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion; screen->BitmapToRegion = glamor_bitmap_to_region; glamor_priv->saved_procs.composite = ps->Composite; ps->Composite = glamor_composite; glamor_priv->saved_procs.trapezoids = ps->Trapezoids; ps->Trapezoids = glamor_trapezoids; glamor_priv->saved_procs.triangles = ps->Triangles; ps->Triangles = glamor_triangles; glamor_priv->saved_procs.addtraps = ps->AddTraps; ps->AddTraps = glamor_add_traps; glamor_priv->saved_procs.composite_rects = ps->CompositeRects; ps->CompositeRects = glamor_composite_rectangles; glamor_priv->saved_procs.glyphs = ps->Glyphs; ps->Glyphs = glamor_composite_glyphs; glamor_init_vbo(screen); glamor_init_gradient_shader(screen); glamor_pixmap_init(screen); glamor_sync_init(screen); glamor_priv->screen = screen; return TRUE; fail: /* Restore default CloseScreen and DestroyPixmap handlers */ screen->CloseScreen = glamor_priv->saved_procs.close_screen; screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap; free_glamor_private: free(glamor_priv); glamor_set_screen_private(screen, NULL); return FALSE; } static void glamor_release_screen_priv(ScreenPtr screen) { glamor_screen_private *glamor_priv; glamor_priv = glamor_get_screen_private(screen); glamor_fini_vbo(screen); glamor_pixmap_fini(screen); free(glamor_priv); glamor_set_screen_private(screen, NULL); } Bool glamor_close_screen(ScreenPtr screen) { glamor_screen_private *glamor_priv; PixmapPtr screen_pixmap; PictureScreenPtr ps = GetPictureScreenIfSet(screen); glamor_priv = glamor_get_screen_private(screen); glamor_sync_close(screen); glamor_composite_glyphs_fini(screen); screen->CloseScreen = glamor_priv->saved_procs.close_screen; screen->CreateGC = glamor_priv->saved_procs.create_gc; screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap; screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap; screen->GetSpans = glamor_priv->saved_procs.get_spans; screen->ChangeWindowAttributes = glamor_priv->saved_procs.change_window_attributes; screen->CopyWindow = glamor_priv->saved_procs.copy_window; screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region; screen->BlockHandler = glamor_priv->saved_procs.block_handler; ps->Composite = glamor_priv->saved_procs.composite; ps->Trapezoids = glamor_priv->saved_procs.trapezoids; ps->Triangles = glamor_priv->saved_procs.triangles; ps->CompositeRects = glamor_priv->saved_procs.composite_rects; ps->Glyphs = glamor_priv->saved_procs.glyphs; screen_pixmap = screen->GetScreenPixmap(screen); glamor_pixmap_destroy_fbo(screen_pixmap); glamor_release_screen_priv(screen); return screen->CloseScreen(screen); } void glamor_fini(ScreenPtr screen) { /* Do nothing currently. */ } void glamor_enable_dri3(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_priv->dri3_enabled = TRUE; } Bool glamor_supports_pixmap_import_export(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); return glamor_priv->dri3_enabled; } _X_EXPORT void glamor_set_drawable_modifiers_func(ScreenPtr screen, GetDrawableModifiersFuncPtr func) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_priv->get_drawable_modifiers = func; } _X_EXPORT Bool glamor_get_drawable_modifiers(DrawablePtr draw, uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers) { struct glamor_screen_private *glamor_priv = glamor_get_screen_private(draw->pScreen); if (glamor_priv->get_drawable_modifiers) { return glamor_priv->get_drawable_modifiers(draw, format, num_modifiers, modifiers); } *num_modifiers = 0; *modifiers = NULL; return TRUE; } static int _glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, uint32_t *strides, uint32_t *offsets, CARD32 *size, uint64_t *modifier) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); if (!glamor_priv->dri3_enabled) return 0; switch (pixmap_priv->type) { case GLAMOR_TEXTURE_DRM: case GLAMOR_TEXTURE_ONLY: if (!glamor_pixmap_ensure_fbo(pixmap, pixmap->drawable.depth == 30 ? GL_RGB10_A2 : GL_RGBA, 0)) return 0; if (modifier) { return glamor_egl_fds_from_pixmap(screen, pixmap, fds, strides, offsets, modifier); } else { CARD16 stride; fds[0] = glamor_egl_fd_from_pixmap(screen, pixmap, &stride, size); strides[0] = stride; return fds[0] >= 0; } default: break; } return 0; } _X_EXPORT int glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, uint32_t *strides, uint32_t *offsets, uint64_t *modifier) { return _glamor_fds_from_pixmap(screen, pixmap, fds, strides, offsets, NULL, modifier); } _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { int fd; int ret; uint32_t stride32; ret = _glamor_fds_from_pixmap(screen, pixmap, &fd, &stride32, NULL, size, NULL); if (ret != 1) return -1; *stride = stride32; return fd; } _X_EXPORT int glamor_shareable_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { unsigned orig_usage_hint = pixmap->usage_hint; int ret; /* * The actual difference between a sharable and non sharable buffer * is decided 4 call levels deep in glamor_make_pixmap_exportable() * based on pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED * 2 of those calls are also exported API, so we cannot just add a flag. */ pixmap->usage_hint = CREATE_PIXMAP_USAGE_SHARED; ret = glamor_fd_from_pixmap(screen, pixmap, stride, size); pixmap->usage_hint = orig_usage_hint; return ret; } int glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); switch (pixmap_priv->type) { case GLAMOR_TEXTURE_DRM: case GLAMOR_TEXTURE_ONLY: if (!glamor_pixmap_ensure_fbo(pixmap, pixmap->drawable.depth == 30 ? GL_RGB10_A2 : GL_RGBA, 0)) return -1; return glamor_egl_fd_name_from_pixmap(pixmap->drawable.pScreen, pixmap, stride, size); default: break; } return -1; } void glamor_finish(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); glFinish(); } xorg-server-1.20.13/glamor/glamor_context.h0000644000175000017500000000352514100573756015556 00000000000000/* * Copyright © 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ /** * @file glamor_context.h * * This is the struct of state required for context switching in * glamor. It has to use types that don't require including either * server headers or Xlib headers, since it will be included by both * the server and the GLX (xlib) code. */ struct glamor_context { /** Either an EGLDisplay or an Xlib Display */ void *display; /** Either a GLXContext or an EGLContext. */ void *ctx; /** The EGLSurface we should MakeCurrent to */ void *drawable; /** The GLXDrawable we should MakeCurrent to */ uint32_t drawable_xid; void (*make_current)(struct glamor_context *glamor_ctx); }; Bool glamor_glx_screen_init(struct glamor_context *glamor_ctx); xorg-server-1.20.13/glamor/glamor_copy.c0000644000175000017500000006331214100573756015037 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_transfer.h" #include "glamor_prepare.h" #include "glamor_transform.h" struct copy_args { PixmapPtr src_pixmap; glamor_pixmap_fbo *src; uint32_t bitplane; int dx, dy; }; static Bool use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg) { struct copy_args *args = arg; glamor_pixmap_fbo *src = args->src; glamor_bind_texture(glamor_get_screen_private(dst->drawable.pScreen), GL_TEXTURE0, src, TRUE); glUniform2f(prog->fill_offset_uniform, args->dx, args->dy); glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height); return TRUE; } static const glamor_facet glamor_facet_copyarea = { "copy_area", .vs_vars = "attribute vec2 primitive;\n", .vs_exec = (GLAMOR_POS(gl_Position, primitive.xy) " fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"), .fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n", .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos, .use = use_copyarea, }; /* * Configure the copy plane program for the current operation */ static Bool use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg) { struct copy_args *args = arg; glamor_pixmap_fbo *src = args->src; glamor_bind_texture(glamor_get_screen_private(dst->drawable.pScreen), GL_TEXTURE0, src, TRUE); glUniform2f(prog->fill_offset_uniform, args->dx, args->dy); glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height); glamor_set_color(dst, gc->fgPixel, prog->fg_uniform); glamor_set_color(dst, gc->bgPixel, prog->bg_uniform); /* XXX handle 2 10 10 10 and 1555 formats; presumably the pixmap private knows this? */ switch (args->src_pixmap->drawable.depth) { case 30: glUniform4ui(prog->bitplane_uniform, (args->bitplane >> 20) & 0x3ff, (args->bitplane >> 10) & 0x3ff, (args->bitplane ) & 0x3ff, 0); glUniform4f(prog->bitmul_uniform, 0x3ff, 0x3ff, 0x3ff, 0); break; case 24: glUniform4ui(prog->bitplane_uniform, (args->bitplane >> 16) & 0xff, (args->bitplane >> 8) & 0xff, (args->bitplane ) & 0xff, 0); glUniform4f(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0); break; case 32: glUniform4ui(prog->bitplane_uniform, (args->bitplane >> 16) & 0xff, (args->bitplane >> 8) & 0xff, (args->bitplane ) & 0xff, (args->bitplane >> 24) & 0xff); glUniform4f(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0xff); break; case 16: glUniform4ui(prog->bitplane_uniform, (args->bitplane >> 11) & 0x1f, (args->bitplane >> 5) & 0x3f, (args->bitplane ) & 0x1f, 0); glUniform4f(prog->bitmul_uniform, 0x1f, 0x3f, 0x1f, 0); break; case 15: glUniform4ui(prog->bitplane_uniform, (args->bitplane >> 10) & 0x1f, (args->bitplane >> 5) & 0x1f, (args->bitplane ) & 0x1f, 0); glUniform4f(prog->bitmul_uniform, 0x1f, 0x1f, 0x1f, 0); break; case 8: glUniform4ui(prog->bitplane_uniform, 0, 0, 0, args->bitplane); glUniform4f(prog->bitmul_uniform, 0, 0, 0, 0xff); break; case 1: glUniform4ui(prog->bitplane_uniform, 0, 0, 0, args->bitplane); glUniform4f(prog->bitmul_uniform, 0, 0, 0, 0xff); break; } return TRUE; } static const glamor_facet glamor_facet_copyplane = { "copy_plane", .version = 130, .vs_vars = "attribute vec2 primitive;\n", .vs_exec = (GLAMOR_POS(gl_Position, (primitive.xy)) " fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"), .fs_exec = (" uvec4 bits = uvec4(round(texture2D(sampler, fill_pos) * bitmul));\n" " if ((bits & bitplane) != uvec4(0,0,0,0))\n" " gl_FragColor = fg;\n" " else\n" " gl_FragColor = bg;\n"), .locations = glamor_program_location_fillsamp|glamor_program_location_fillpos|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane, .use = use_copyplane, }; /* * When all else fails, pull the bits out of the GPU and do the * operation with fb */ static void glamor_copy_bail(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { if (bitplane) { if (src->bitsPerPixel > 1) fbCopyNto1(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); else fbCopy1toN(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } else { fbCopyNtoN(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } } glamor_finish_access(dst); glamor_finish_access(src); } /** * Implements CopyPlane and CopyArea from the CPU to the GPU by using * the source as a texture and painting that into the destination. * * This requires that source and dest are different textures, or that * (if the copy area doesn't overlap), GL_NV_texture_barrier is used * to ensure that the caches are flushed at the right times. */ static Bool glamor_copy_cpu_fbo(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { ScreenPtr screen = dst->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); int dst_xoff, dst_yoff; if (gc && gc->alu != GXcopy) goto bail; if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; glamor_make_current(glamor_priv); if (!glamor_prepare_access(src, GLAMOR_ACCESS_RO)) goto bail; glamor_get_drawable_deltas(dst, dst_pixmap, &dst_xoff, &dst_yoff); if (bitplane) { FbBits *tmp_bits; FbStride tmp_stride; int tmp_bpp; int tmp_xoff, tmp_yoff; PixmapPtr tmp_pix = fbCreatePixmap(screen, dst_pixmap->drawable.width, dst_pixmap->drawable.height, dst->depth, 0); if (!tmp_pix) { glamor_finish_access(src); goto bail; } tmp_pix->drawable.x = dst_xoff; tmp_pix->drawable.y = dst_yoff; fbGetDrawable(&tmp_pix->drawable, tmp_bits, tmp_stride, tmp_bpp, tmp_xoff, tmp_yoff); if (src->bitsPerPixel > 1) fbCopyNto1(src, &tmp_pix->drawable, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); else fbCopy1toN(src, &tmp_pix->drawable, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); glamor_upload_boxes(dst_pixmap, box, nbox, tmp_xoff, tmp_yoff, dst_xoff, dst_yoff, (uint8_t *) tmp_bits, tmp_stride * sizeof(FbBits)); fbDestroyPixmap(tmp_pix); } else { FbBits *src_bits; FbStride src_stride; int src_bpp; int src_xoff, src_yoff; fbGetDrawable(src, src_bits, src_stride, src_bpp, src_xoff, src_yoff); glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff + dx, src_yoff + dy, dst_xoff, dst_yoff, (uint8_t *) src_bits, src_stride * sizeof (FbBits)); } glamor_finish_access(src); return TRUE; bail: return FALSE; } /** * Implements CopyArea from the GPU to the CPU using glReadPixels from the * source FBO. */ static Bool glamor_copy_fbo_cpu(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { ScreenPtr screen = dst->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); FbBits *dst_bits; FbStride dst_stride; int dst_bpp; int src_xoff, src_yoff; int dst_xoff, dst_yoff; if (gc && gc->alu != GXcopy) goto bail; if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; glamor_make_current(glamor_priv); if (!glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) goto bail; glamor_get_drawable_deltas(src, src_pixmap, &src_xoff, &src_yoff); fbGetDrawable(dst, dst_bits, dst_stride, dst_bpp, dst_xoff, dst_yoff); glamor_download_boxes(src_pixmap, box, nbox, src_xoff + dx, src_yoff + dy, dst_xoff, dst_yoff, (uint8_t *) dst_bits, dst_stride * sizeof (FbBits)); glamor_finish_access(dst); return TRUE; bail: return FALSE; } /* Include the enums here for the moment, to keep from needing to bump epoxy. */ #ifndef GL_TILE_RASTER_ORDER_FIXED_MESA #define GL_TILE_RASTER_ORDER_FIXED_MESA 0x8BB8 #define GL_TILE_RASTER_ORDER_INCREASING_X_MESA 0x8BB9 #define GL_TILE_RASTER_ORDER_INCREASING_Y_MESA 0x8BBA #endif /* * Copy from GPU to GPU by using the source * as a texture and painting that into the destination */ static Bool glamor_copy_fbo_fbo_draw(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { ScreenPtr screen = dst->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap); int src_box_index, dst_box_index; int dst_off_x, dst_off_y; int src_off_x, src_off_y; GLshort *v; char *vbo_offset; struct copy_args args; glamor_program *prog; const glamor_facet *copy_facet; int n; Bool ret = FALSE; BoxRec bounds = glamor_no_rendering_bounds(); glamor_make_current(glamor_priv); if (gc && !glamor_set_planemask(gc->depth, gc->planemask)) goto bail_ctx; if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy)) goto bail_ctx; if (bitplane && !glamor_priv->can_copyplane) goto bail_ctx; if (bitplane) { prog = &glamor_priv->copy_plane_prog; copy_facet = &glamor_facet_copyplane; } else { prog = &glamor_priv->copy_area_prog; copy_facet = &glamor_facet_copyarea; } if (prog->failed) goto bail_ctx; if (!prog->prog) { if (!glamor_build_program(screen, prog, copy_facet, NULL, NULL, NULL)) goto bail_ctx; } args.src_pixmap = src_pixmap; args.bitplane = bitplane; /* Set up the vertex buffers for the points */ v = glamor_get_vbo_space(dst->pScreen, nbox * 8 * sizeof (int16_t), &vbo_offset); if (src_pixmap == dst_pixmap && glamor_priv->has_mesa_tile_raster_order) { glEnable(GL_TILE_RASTER_ORDER_FIXED_MESA); if (dx >= 0) glEnable(GL_TILE_RASTER_ORDER_INCREASING_X_MESA); else glDisable(GL_TILE_RASTER_ORDER_INCREASING_X_MESA); if (dy >= 0) glEnable(GL_TILE_RASTER_ORDER_INCREASING_Y_MESA); else glDisable(GL_TILE_RASTER_ORDER_INCREASING_Y_MESA); } glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 2 * sizeof (GLshort), vbo_offset); if (nbox < 100) { bounds = glamor_start_rendering_bounds(); for (int i = 0; i < nbox; i++) glamor_bounds_union_box(&bounds, &box[i]); } for (n = 0; n < nbox; n++) { v[0] = box->x1; v[1] = box->y1; v[2] = box->x1; v[3] = box->y2; v[4] = box->x2; v[5] = box->y2; v[6] = box->x2; v[7] = box->y1; v += 8; box++; } glamor_put_vbo_space(screen); glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y); glEnable(GL_SCISSOR_TEST); glamor_pixmap_loop(src_priv, src_box_index) { BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_index); args.dx = dx + src_off_x - src_box->x1; args.dy = dy + src_off_y - src_box->y1; args.src = glamor_pixmap_fbo_at(src_priv, src_box_index); if (!glamor_use_program(dst_pixmap, gc, prog, &args)) goto bail_ctx; glamor_pixmap_loop(dst_priv, dst_box_index) { BoxRec scissor = { .x1 = max(-args.dx, bounds.x1), .y1 = max(-args.dy, bounds.y1), .x2 = min(-args.dx + src_box->x2 - src_box->x1, bounds.x2), .y2 = min(-args.dy + src_box->y2 - src_box->y1, bounds.y2), }; if (scissor.x1 >= scissor.x2 || scissor.y1 >= scissor.y2) continue; if (!glamor_set_destination_drawable(dst, dst_box_index, FALSE, FALSE, prog->matrix_uniform, &dst_off_x, &dst_off_y)) goto bail_ctx; glScissor(scissor.x1 + dst_off_x, scissor.y1 + dst_off_y, scissor.x2 - scissor.x1, scissor.y2 - scissor.y1); glamor_glDrawArrays_GL_QUADS(glamor_priv, nbox); } } ret = TRUE; bail_ctx: if (src_pixmap == dst_pixmap && glamor_priv->has_mesa_tile_raster_order) { glDisable(GL_TILE_RASTER_ORDER_FIXED_MESA); } glDisable(GL_SCISSOR_TEST); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); return ret; } /** * Copies from the GPU to the GPU using a temporary pixmap in between, * to correctly handle overlapping copies. */ static Bool glamor_copy_fbo_fbo_temp(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { ScreenPtr screen = dst->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr tmp_pixmap; BoxRec bounds; int n; BoxPtr tmp_box; if (nbox == 0) return TRUE; /* Sanity check state to avoid getting halfway through and bailing * at the last second. Might be nice to have checks that didn't * involve setting state. */ glamor_make_current(glamor_priv); if (gc && !glamor_set_planemask(gc->depth, gc->planemask)) goto bail_ctx; if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy)) goto bail_ctx; /* Find the size of the area to copy */ bounds = box[0]; for (n = 1; n < nbox; n++) { bounds.x1 = min(bounds.x1, box[n].x1); bounds.x2 = max(bounds.x2, box[n].x2); bounds.y1 = min(bounds.y1, box[n].y1); bounds.y2 = max(bounds.y2, box[n].y2); } /* Allocate a suitable temporary pixmap */ tmp_pixmap = glamor_create_pixmap(screen, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1, src->depth, 0); if (!tmp_pixmap) goto bail; tmp_box = calloc(nbox, sizeof (BoxRec)); if (!tmp_box) goto bail_pixmap; /* Convert destination boxes into tmp pixmap boxes */ for (n = 0; n < nbox; n++) { tmp_box[n].x1 = box[n].x1 - bounds.x1; tmp_box[n].x2 = box[n].x2 - bounds.x1; tmp_box[n].y1 = box[n].y1 - bounds.y1; tmp_box[n].y2 = box[n].y2 - bounds.y1; } if (!glamor_copy_fbo_fbo_draw(src, &tmp_pixmap->drawable, NULL, tmp_box, nbox, dx + bounds.x1, dy + bounds.y1, FALSE, FALSE, 0, NULL)) goto bail_box; if (!glamor_copy_fbo_fbo_draw(&tmp_pixmap->drawable, dst, gc, box, nbox, -bounds.x1, -bounds.y1, FALSE, FALSE, bitplane, closure)) goto bail_box; free(tmp_box); glamor_destroy_pixmap(tmp_pixmap); return TRUE; bail_box: free(tmp_box); bail_pixmap: glamor_destroy_pixmap(tmp_pixmap); bail: return FALSE; bail_ctx: return FALSE; } /** * Returns TRUE if the copy has to be implemented with * glamor_copy_fbo_fbo_temp() instead of glamor_copy_fbo_fbo(). * * If the src and dst are in the same pixmap, then glamor_copy_fbo_fbo()'s * sampling would give undefined results (since the same texture would be * bound as an FBO destination and as a texture source). However, if we * have GL_NV_texture_barrier, we can take advantage of the exception it * added: * * "- If a texel has been written, then in order to safely read the result * a texel fetch must be in a subsequent Draw separated by the command * * void TextureBarrierNV(void); * * TextureBarrierNV() will guarantee that writes have completed and caches * have been invalidated before subsequent Draws are executed." */ static Bool glamor_copy_needs_temp(DrawablePtr src, DrawablePtr dst, BoxPtr box, int nbox, int dx, int dy) { PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); ScreenPtr screen = dst->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); int n; int dst_off_x, dst_off_y; int src_off_x, src_off_y; BoxRec bounds; if (src_pixmap != dst_pixmap) return FALSE; if (nbox == 0) return FALSE; if (!glamor_priv->has_nv_texture_barrier) return TRUE; if (!glamor_priv->has_mesa_tile_raster_order) { glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_off_x, &dst_off_y); bounds = box[0]; for (n = 1; n < nbox; n++) { bounds.x1 = min(bounds.x1, box[n].x1); bounds.y1 = min(bounds.y1, box[n].y1); bounds.x2 = max(bounds.x2, box[n].x2); bounds.y2 = max(bounds.y2, box[n].y2); } /* Check to see if the pixmap-relative boxes overlap in both X and Y, * in which case we can't rely on NV_texture_barrier and must * make a temporary copy * * dst.x1 < src.x2 && * src.x1 < dst.x2 && * * dst.y1 < src.y2 && * src.y1 < dst.y2 */ if (bounds.x1 + dst_off_x < bounds.x2 + dx + src_off_x && bounds.x1 + dx + src_off_x < bounds.x2 + dst_off_x && bounds.y1 + dst_off_y < bounds.y2 + dy + src_off_y && bounds.y1 + dy + src_off_y < bounds.y2 + dst_off_y) { return TRUE; } } glTextureBarrierNV(); return FALSE; } static Bool glamor_copy_gl(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap); if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_priv)) { if (GLAMOR_PIXMAP_PRIV_HAS_FBO(src_priv)) { if (glamor_copy_needs_temp(src, dst, box, nbox, dx, dy)) return glamor_copy_fbo_fbo_temp(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); else return glamor_copy_fbo_fbo_draw(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } return glamor_copy_cpu_fbo(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } else if (GLAMOR_PIXMAP_PRIV_HAS_FBO(src_priv) && dst_priv->type != GLAMOR_DRM_ONLY && bitplane == 0) { return glamor_copy_fbo_cpu(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } return FALSE; } void glamor_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { if (nbox == 0) return; if (glamor_copy_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure)) return; glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } RegionPtr glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, int srcx, int srcy, int width, int height, int dstx, int dsty) { return miDoCopy(src, dst, gc, srcx, srcy, width, height, dstx, dsty, glamor_copy, 0, NULL); } RegionPtr glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc, int srcx, int srcy, int width, int height, int dstx, int dsty, unsigned long bitplane) { if ((bitplane & FbFullMask(src->depth)) == 0) return miHandleExposures(src, dst, gc, srcx, srcy, width, height, dstx, dsty); return miDoCopy(src, dst, gc, srcx, srcy, width, height, dstx, dsty, glamor_copy, bitplane, NULL); } void glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region) { PixmapPtr pixmap = glamor_get_drawable_pixmap(&window->drawable); DrawablePtr drawable = &pixmap->drawable; RegionRec dst_region; int dx, dy; dx = old_origin.x - window->drawable.x; dy = old_origin.y - window->drawable.y; RegionTranslate(src_region, -dx, -dy); RegionNull(&dst_region); RegionIntersect(&dst_region, &window->borderClip, src_region); #ifdef COMPOSITE if (pixmap->screen_x || pixmap->screen_y) RegionTranslate(&dst_region, -pixmap->screen_x, -pixmap->screen_y); #endif miCopyRegion(drawable, drawable, 0, &dst_region, dx, dy, glamor_copy, 0, 0); RegionUninit(&dst_region); } xorg-server-1.20.13/glamor/glamor_core.c0000644000175000017500000002111714100573756015012 00000000000000/* * Copyright © 2001 Keith Packard * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Eric Anholt * */ /** @file glamor_core.c * * This file covers core X rendering in glamor. */ #include #include "glamor_priv.h" Bool glamor_get_drawable_location(const DrawablePtr drawable) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); if (pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) return 'm'; else return 'f'; } GLint glamor_compile_glsl_prog(GLenum type, const char *source) { GLint ok; GLint prog; prog = glCreateShader(type); glShaderSource(prog, 1, (const GLchar **) &source, NULL); glCompileShader(prog); glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); if (!ok) { GLchar *info; GLint size; glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); info = malloc(size); if (info) { glGetShaderInfoLog(prog, size, NULL, info); ErrorF("Failed to compile %s: %s\n", type == GL_FRAGMENT_SHADER ? "FS" : "VS", info); ErrorF("Program source:\n%s", source); free(info); } else ErrorF("Failed to get shader compilation info.\n"); FatalError("GLSL compile failure\n"); } return prog; } void glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...) { GLint ok; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); if (glamor_priv->has_khr_debug) { char *label; va_list va; va_start(va, format); XNFvasprintf(&label, format, va); glObjectLabel(GL_PROGRAM, prog, -1, label); free(label); va_end(va); } glLinkProgram(prog); glGetProgramiv(prog, GL_LINK_STATUS, &ok); if (!ok) { GLchar *info; GLint size; glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); info = malloc(size); glGetProgramInfoLog(prog, size, NULL, info); ErrorF("Failed to link: %s\n", info); FatalError("GLSL link failure\n"); } } static GCOps glamor_gc_ops = { .FillSpans = glamor_fill_spans, .SetSpans = glamor_set_spans, .PutImage = glamor_put_image, .CopyArea = glamor_copy_area, .CopyPlane = glamor_copy_plane, .PolyPoint = glamor_poly_point, .Polylines = glamor_poly_lines, .PolySegment = glamor_poly_segment, .PolyRectangle = miPolyRectangle, .PolyArc = miPolyArc, .FillPolygon = miFillPolygon, .PolyFillRect = glamor_poly_fill_rect, .PolyFillArc = miPolyFillArc, .PolyText8 = glamor_poly_text8, .PolyText16 = glamor_poly_text16, .ImageText8 = glamor_image_text8, .ImageText16 = glamor_image_text16, .ImageGlyphBlt = miImageGlyphBlt, .PolyGlyphBlt = glamor_poly_glyph_blt, .PushPixels = glamor_push_pixels, }; /* * When the stipple is changed or drawn to, invalidate any * cached copy */ static void glamor_invalidate_stipple(GCPtr gc) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); if (gc_priv->stipple) { if (gc_priv->stipple_damage) DamageUnregister(gc_priv->stipple_damage); glamor_destroy_pixmap(gc_priv->stipple); gc_priv->stipple = NULL; } } static void glamor_stipple_damage_report(DamagePtr damage, RegionPtr region, void *closure) { GCPtr gc = closure; glamor_invalidate_stipple(gc); } static void glamor_stipple_damage_destroy(DamagePtr damage, void *closure) { GCPtr gc = closure; glamor_gc_private *gc_priv = glamor_get_gc_private(gc); gc_priv->stipple_damage = NULL; glamor_invalidate_stipple(gc); } void glamor_track_stipple(GCPtr gc) { if (gc->stipple) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); if (!gc_priv->stipple_damage) gc_priv->stipple_damage = DamageCreate(glamor_stipple_damage_report, glamor_stipple_damage_destroy, DamageReportNonEmpty, TRUE, gc->pScreen, gc); if (gc_priv->stipple_damage) DamageRegister(&gc->stipple->drawable, gc_priv->stipple_damage); } } /** * uxa_validate_gc() sets the ops to glamor's implementations, which may be * accelerated or may sync the card and fall back to fb. */ void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) { /* fbValidateGC will do direct access to pixmaps if the tiling has changed. * Preempt fbValidateGC by doing its work and masking the change out, so * that we can do the Prepare/finish_access. */ if (changes & GCTile) { if (!gc->tileIsPixel) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(gc->tile.pixmap); if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) && FbEvenTile(gc->tile.pixmap->drawable.width * drawable->bitsPerPixel)) { glamor_fallback ("GC %p tile changed %p.\n", gc, gc->tile.pixmap); if (glamor_prepare_access (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW)) { fbPadPixmap(gc->tile.pixmap); glamor_finish_access(&gc->tile.pixmap->drawable); } } } /* Mask out the GCTile change notification, now that we've done FB's * job for it. */ changes &= ~GCTile; } if (changes & GCStipple) glamor_invalidate_stipple(gc); if (changes & GCStipple && gc->stipple) { /* We can't inline stipple handling like we do for GCTile because * it sets fbgc privates. */ if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { fbValidateGC(gc, changes, drawable); glamor_finish_access(&gc->stipple->drawable); } } else { fbValidateGC(gc, changes, drawable); } if (changes & GCDashList) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); if (gc_priv->dash) { glamor_destroy_pixmap(gc_priv->dash); gc_priv->dash = NULL; } } gc->ops = &glamor_gc_ops; } void glamor_destroy_gc(GCPtr gc) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); if (gc_priv->dash) { glamor_destroy_pixmap(gc_priv->dash); gc_priv->dash = NULL; } glamor_invalidate_stipple(gc); if (gc_priv->stipple_damage) DamageDestroy(gc_priv->stipple_damage); miDestroyGC(gc); } static GCFuncs glamor_gc_funcs = { glamor_validate_gc, miChangeGC, miCopyGC, glamor_destroy_gc, miChangeClip, miDestroyClip, miCopyClip }; /** * exaCreateGC makes a new GC and hooks up its funcs handler, so that * exaValidateGC() will get called. */ int glamor_create_gc(GCPtr gc) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); gc_priv->dash = NULL; gc_priv->stipple = NULL; if (!fbCreateGC(gc)) return FALSE; gc->funcs = &glamor_gc_funcs; return TRUE; } RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap) { RegionPtr ret; glamor_fallback("pixmap %p \n", pixmap); if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO)) return NULL; ret = fbPixmapToRegion(pixmap); glamor_finish_access(&pixmap->drawable); return ret; } xorg-server-1.20.13/glamor/glamor_dash.c0000644000175000017500000002507514100573756015010 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_program.h" #include "glamor_transform.h" #include "glamor_transfer.h" #include "glamor_prepare.h" static const char dash_vs_vars[] = "attribute vec3 primitive;\n" "varying float dash_offset;\n"; static const char dash_vs_exec[] = " dash_offset = primitive.z / dash_length;\n" " vec2 pos = vec2(0,0);\n" GLAMOR_POS(gl_Position, primitive.xy); static const char dash_fs_vars[] = "varying float dash_offset;\n"; static const char on_off_fs_exec[] = " float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n" " if (pattern == 0.0)\n" " discard;\n"; /* XXX deal with stippled double dashed lines once we have stippling support */ static const char double_fs_exec[] = " float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n" " if (pattern == 0.0)\n" " gl_FragColor = bg;\n" " else\n" " gl_FragColor = fg;\n"; static const glamor_facet glamor_facet_on_off_dash_lines = { .version = 130, .name = "poly_lines_on_off_dash", .vs_vars = dash_vs_vars, .vs_exec = dash_vs_exec, .fs_vars = dash_fs_vars, .fs_exec = on_off_fs_exec, .locations = glamor_program_location_dash, }; static const glamor_facet glamor_facet_double_dash_lines = { .version = 130, .name = "poly_lines_double_dash", .vs_vars = dash_vs_vars, .vs_exec = dash_vs_exec, .fs_vars = dash_fs_vars, .fs_exec = double_fs_exec, .locations = (glamor_program_location_dash| glamor_program_location_fg| glamor_program_location_bg), }; static PixmapPtr glamor_get_dash_pixmap(GCPtr gc) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); ScreenPtr screen = gc->pScreen; PixmapPtr pixmap; int offset; int d; uint32_t pixel; GCPtr scratch_gc; if (gc_priv->dash) return gc_priv->dash; offset = 0; for (d = 0; d < gc->numInDashList; d++) offset += gc->dash[d]; pixmap = glamor_create_pixmap(screen, offset, 1, 8, 0); if (!pixmap) goto bail; scratch_gc = GetScratchGC(8, screen); if (!scratch_gc) goto bail_pixmap; pixel = 0xffffffff; offset = 0; for (d = 0; d < gc->numInDashList; d++) { xRectangle rect; ChangeGCVal changes; changes.val = pixel; (void) ChangeGC(NullClient, scratch_gc, GCForeground, &changes); ValidateGC(&pixmap->drawable, scratch_gc); rect.x = offset; rect.y = 0; rect.width = gc->dash[d]; rect.height = 1; scratch_gc->ops->PolyFillRect (&pixmap->drawable, scratch_gc, 1, &rect); offset += gc->dash[d]; pixel = ~pixel; } FreeScratchGC(scratch_gc); gc_priv->dash = pixmap; return pixmap; bail_pixmap: glamor_destroy_pixmap(pixmap); bail: return NULL; } static glamor_program * glamor_dash_setup(DrawablePtr drawable, GCPtr gc) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); PixmapPtr dash_pixmap; glamor_pixmap_private *dash_priv; glamor_program *prog; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; if (gc->lineWidth != 0) goto bail; dash_pixmap = glamor_get_dash_pixmap(gc); dash_priv = glamor_get_pixmap_private(dash_pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dash_priv)) goto bail; glamor_make_current(glamor_priv); switch (gc->lineStyle) { case LineOnOffDash: prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->on_off_dash_line_progs, &glamor_facet_on_off_dash_lines); if (!prog) goto bail; break; case LineDoubleDash: if (gc->fillStyle != FillSolid) goto bail; prog = &glamor_priv->double_dash_line_prog; if (!prog->prog) { if (!glamor_build_program(screen, prog, &glamor_facet_double_dash_lines, NULL, NULL, NULL)) goto bail; } if (!glamor_use_program(pixmap, gc, prog, NULL)) goto bail; glamor_set_color(pixmap, gc->fgPixel, prog->fg_uniform); glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform); break; default: goto bail; } /* Set the dash pattern as texture 1 */ glamor_bind_texture(glamor_priv, GL_TEXTURE1, dash_priv->fbo, FALSE); glUniform1i(prog->dash_uniform, 1); glUniform1f(prog->dash_length_uniform, dash_pixmap->drawable.width); return prog; bail: return NULL; } static void glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog, int n, GLenum mode) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); int box_index; int off_x, off_y; glEnable(GL_SCISSOR_TEST); glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y); while (nbox--) { glScissor(box->x1 + off_x, box->y1 + off_y, box->x2 - box->x1, box->y2 - box->y1); box++; glDrawArrays(mode, 0, n); } } glDisable(GL_SCISSOR_TEST); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); } static int glamor_line_length(short x1, short y1, short x2, short y2) { return max(abs(x2 - x1), abs(y2 - y1)); } Bool glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points) { ScreenPtr screen = drawable->pScreen; glamor_program *prog; short *v; char *vbo_offset; int add_last; int dash_pos; int prev_x, prev_y; int i; if (n < 2) return TRUE; if (!(prog = glamor_dash_setup(drawable, gc))) return FALSE; add_last = 0; if (gc->capStyle != CapNotLast) add_last = 1; /* Set up the vertex buffers for the points */ v = glamor_get_vbo_space(drawable->pScreen, (n + add_last) * 3 * sizeof (short), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE, 3 * sizeof (short), vbo_offset); dash_pos = gc->dashOffset; prev_x = prev_y = 0; for (i = 0; i < n; i++) { int this_x = points[i].x; int this_y = points[i].y; if (i) { if (mode == CoordModePrevious) { this_x += prev_x; this_y += prev_y; } dash_pos += glamor_line_length(prev_x, prev_y, this_x, this_y); } v[0] = prev_x = this_x; v[1] = prev_y = this_y; v[2] = dash_pos; v += 3; } if (add_last) { v[0] = prev_x + 1; v[1] = prev_y; v[2] = dash_pos + 1; } glamor_put_vbo_space(screen); glamor_dash_loop(drawable, gc, prog, n + add_last, GL_LINE_STRIP); return TRUE; } static short * glamor_add_segment(short *v, short x1, short y1, short x2, short y2, int dash_start, int dash_end) { v[0] = x1; v[1] = y1; v[2] = dash_start; v[3] = x2; v[4] = y2; v[5] = dash_end; return v + 6; } Bool glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc, int nseg, xSegment *segs) { ScreenPtr screen = drawable->pScreen; glamor_program *prog; short *v; char *vbo_offset; int dash_start = gc->dashOffset; int add_last; int i; if (!(prog = glamor_dash_setup(drawable, gc))) return FALSE; add_last = 0; if (gc->capStyle != CapNotLast) add_last = 1; /* Set up the vertex buffers for the points */ v = glamor_get_vbo_space(drawable->pScreen, (nseg< * */ #ifndef __GLAMOR_DEBUG_H__ #define __GLAMOR_DEBUG_H__ #define GLAMOR_DEBUG_NONE 0 #define GLAMOR_DEBUG_UNIMPL 0 #define GLAMOR_DEBUG_FALLBACK 1 #define GLAMOR_DEBUG_TEXTURE_DOWNLOAD 2 #define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD 3 extern void AbortServer(void) _X_NORETURN; #define GLAMOR_PANIC(_format_, ...) \ do { \ LogMessageVerb(X_NONE, 0, "Glamor Fatal Error" \ " at %32s line %d: " _format_ "\n", \ __FUNCTION__, __LINE__, \ ##__VA_ARGS__ ); \ exit(1); \ } while(0) #define __debug_output_message(_format_, _prefix_, ...) \ LogMessageVerb(X_NONE, 0, \ "%32s:\t" _format_ , \ /*_prefix_,*/ \ __FUNCTION__, \ ##__VA_ARGS__) #define glamor_debug_output(_level_, _format_,...) \ do { \ if (glamor_debug_level >= _level_) \ __debug_output_message(_format_, \ "Glamor debug", \ ##__VA_ARGS__); \ } while(0) #define glamor_fallback(_format_,...) \ do { \ if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) \ __debug_output_message(_format_, \ "Glamor fallback", \ ##__VA_ARGS__);} while(0) #define DEBUGF(str, ...) do {} while(0) //#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__) #define DEBUGRegionPrint(x) do {} while (0) //#define DEBUGRegionPrint RegionPrint #endif xorg-server-1.20.13/glamor/glamor_font.c0000644000175000017500000001712314100573756015032 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_font.h" #include static int glamor_font_generation; static int glamor_font_private_index; static int glamor_font_screen_count; glamor_font_t * glamor_font_get(ScreenPtr screen, FontPtr font) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_font_t *privates; glamor_font_t *glamor_font; int overall_width, overall_height; int num_rows; int num_cols; int glyph_width_pixels; int glyph_width_bytes; int glyph_height; int row, col; unsigned char c[2]; CharInfoPtr glyph; unsigned long count; char *bits; if (glamor_priv->glsl_version < 130) return NULL; privates = FontGetPrivate(font, glamor_font_private_index); if (!privates) { privates = calloc(glamor_font_screen_count, sizeof (glamor_font_t)); if (!privates) return NULL; xfont2_font_set_private(font, glamor_font_private_index, privates); } glamor_font = &privates[screen->myNum]; if (glamor_font->realized) return glamor_font; /* Figure out how many glyphs are in the font */ num_cols = font->info.lastCol - font->info.firstCol + 1; num_rows = font->info.lastRow - font->info.firstRow + 1; /* Figure out the size of each glyph */ glyph_width_pixels = font->info.maxbounds.rightSideBearing - font->info.minbounds.leftSideBearing; glyph_height = font->info.maxbounds.ascent + font->info.maxbounds.descent; glyph_width_bytes = (glyph_width_pixels + 7) >> 3; glamor_font->glyph_width_pixels = glyph_width_pixels; glamor_font->glyph_width_bytes = glyph_width_bytes; glamor_font->glyph_height = glyph_height; /* * Layout the font two blocks of columns wide. * This avoids a problem with some fonts that are too high to fit. */ glamor_font->row_width = glyph_width_bytes * num_cols; if (num_rows > 1) { overall_width = glamor_font->row_width * 2; overall_height = glyph_height * ((num_rows + 1) / 2); } else { overall_width = glamor_font->row_width; overall_height = glyph_height; } if (overall_width > glamor_priv->max_fbo_size || overall_height > glamor_priv->max_fbo_size) { /* fallback if we don't fit inside a texture */ return NULL; } bits = malloc(overall_width * overall_height); if (!bits) return NULL; /* Check whether the font has a default character */ c[0] = font->info.lastRow + 1; c[1] = font->info.lastCol + 1; (*font->get_glyphs)(font, 1, c, TwoD16Bit, &count, &glyph); glamor_font->default_char = count ? glyph : NULL; glamor_font->default_row = font->info.defaultCh >> 8; glamor_font->default_col = font->info.defaultCh; glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); glGenTextures(1, &glamor_font->texture_id); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, glamor_font->texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /* Paint all of the glyphs */ for (row = 0; row < num_rows; row++) { for (col = 0; col < num_cols; col++) { c[0] = row + font->info.firstRow; c[1] = col + font->info.firstCol; (*font->get_glyphs)(font, 1, c, TwoD16Bit, &count, &glyph); if (count) { char *dst; char *src = glyph->bits; unsigned y; dst = bits; /* get offset of start of first row */ dst += (row / 2) * glyph_height * overall_width; /* add offset into second row */ dst += (row & 1) ? glamor_font->row_width : 0; dst += col * glyph_width_bytes; for (y = 0; y < GLYPHHEIGHTPIXELS(glyph); y++) { memcpy(dst, src, GLYPHWIDTHBYTES(glyph)); dst += overall_width; src += GLYPHWIDTHBYTESPADDED(glyph); } } } } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glamor_priv->suppress_gl_out_of_memory_logging = true; glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, overall_width, overall_height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, bits); glamor_priv->suppress_gl_out_of_memory_logging = false; if (glGetError() == GL_OUT_OF_MEMORY) return NULL; free(bits); glamor_font->realized = TRUE; return glamor_font; } static Bool glamor_realize_font(ScreenPtr screen, FontPtr font) { return TRUE; } static Bool glamor_unrealize_font(ScreenPtr screen, FontPtr font) { glamor_screen_private *glamor_priv; glamor_font_t *privates = FontGetPrivate(font, glamor_font_private_index); glamor_font_t *glamor_font; int s; if (!privates) return TRUE; glamor_font = &privates[screen->myNum]; if (!glamor_font->realized) return TRUE; /* Unrealize the font, freeing the allocated texture */ glamor_font->realized = FALSE; glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); glDeleteTextures(1, &glamor_font->texture_id); /* Check to see if all of the screens are done with this font * and free the private when that happens */ for (s = 0; s < glamor_font_screen_count; s++) if (privates[s].realized) return TRUE; free(privates); xfont2_font_set_private(font, glamor_font_private_index, NULL); return TRUE; } Bool glamor_font_init(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); if (glamor_priv->glsl_version < 130) return TRUE; if (glamor_font_generation != serverGeneration) { glamor_font_private_index = xfont2_allocate_font_private_index(); if (glamor_font_private_index == -1) return FALSE; glamor_font_screen_count = 0; glamor_font_generation = serverGeneration; } if (screen->myNum >= glamor_font_screen_count) glamor_font_screen_count = screen->myNum + 1; screen->RealizeFont = glamor_realize_font; screen->UnrealizeFont = glamor_unrealize_font; return TRUE; } xorg-server-1.20.13/glamor/glamor_font.h0000644000175000017500000000330614100573756015035 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _GLAMOR_FONT_H_ #define _GLAMOR_FONT_H_ typedef struct { Bool realized; CharInfoPtr default_char; CARD8 default_row; CARD8 default_col; GLuint texture_id; GLuint row_width; CARD16 glyph_width_bytes; CARD16 glyph_width_pixels; CARD16 glyph_height; } glamor_font_t; glamor_font_t * glamor_font_get(ScreenPtr screen, FontPtr font); Bool glamor_font_init(ScreenPtr screen); void glamor_fini_glyph_shader(ScreenPtr screen); #endif /* _GLAMOR_FONT_H_ */ xorg-server-1.20.13/glamor/glamor_glx.c0000644000175000017500000000444614100573756014662 00000000000000/* * Copyright © 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include "glamor_context.h" /** * @file glamor_glx.c * * GLX context management for glamor. * * This has to be kept separate from the server sources because of * Xlib's conflicting definition of CARD32 and similar typedefs. */ static void glamor_glx_make_current(struct glamor_context *glamor_ctx) { /* There's only a single global dispatch table in Mesa. EGL, GLX, * and AIGLX's direct dispatch table manipulation don't talk to * each other. We need to set the context to NULL first to avoid * GLX's no-op context change fast path when switching back to * GLX. */ glXMakeCurrent(glamor_ctx->display, None, None); glXMakeCurrent(glamor_ctx->display, glamor_ctx->drawable_xid, glamor_ctx->ctx); } Bool glamor_glx_screen_init(struct glamor_context *glamor_ctx) { glamor_ctx->ctx = glXGetCurrentContext(); if (!glamor_ctx->ctx) return False; glamor_ctx->display = glXGetCurrentDisplay(); if (!glamor_ctx->display) return False; glamor_ctx->drawable_xid = glXGetCurrentDrawable(); glamor_ctx->make_current = glamor_glx_make_current; return True; } xorg-server-1.20.13/glamor/glamor_composite_glyphs.c0000644000175000017500000005110114100573756017446 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include #include "Xprintf.h" #include "glamor_priv.h" #include "glamor_transform.h" #include "glamor_transfer.h" #include #define DEFAULT_ATLAS_DIM 1024 static DevPrivateKeyRec glamor_glyph_private_key; struct glamor_glyph_private { int16_t x; int16_t y; uint32_t serial; }; struct glamor_glyph_atlas { PixmapPtr atlas; PictFormatPtr format; int x, y; int row_height; int nglyph; uint32_t serial; }; static inline struct glamor_glyph_private *glamor_get_glyph_private(PixmapPtr pixmap) { return dixLookupPrivate(&pixmap->devPrivates, &glamor_glyph_private_key); } static inline void glamor_copy_glyph(PixmapPtr glyph_pixmap, DrawablePtr atlas_draw, int16_t x, int16_t y) { DrawablePtr glyph_draw = &glyph_pixmap->drawable; BoxRec box = { .x1 = 0, .y1 = 0, .x2 = glyph_draw->width, .y2 = glyph_draw->height, }; PixmapPtr upload_pixmap = glyph_pixmap; if (glyph_pixmap->drawable.bitsPerPixel != atlas_draw->bitsPerPixel) { /* If we're dealing with 1-bit glyphs, we copy them to a * temporary 8-bit pixmap and upload them from there, since * that's what GL can handle. */ ScreenPtr screen = atlas_draw->pScreen; GCPtr scratch_gc; ChangeGCVal changes[2]; upload_pixmap = glamor_create_pixmap(screen, glyph_draw->width, glyph_draw->height, atlas_draw->depth, GLAMOR_CREATE_PIXMAP_CPU); if (!upload_pixmap) return; scratch_gc = GetScratchGC(upload_pixmap->drawable.depth, screen); if (!scratch_gc) { glamor_destroy_pixmap(upload_pixmap); return; } changes[0].val = 0xff; changes[1].val = 0x00; if (ChangeGC(NullClient, scratch_gc, GCForeground|GCBackground, changes) != Success) { glamor_destroy_pixmap(upload_pixmap); FreeScratchGC(scratch_gc); return; } ValidateGC(&upload_pixmap->drawable, scratch_gc); (*scratch_gc->ops->CopyPlane)(glyph_draw, &upload_pixmap->drawable, scratch_gc, 0, 0, glyph_draw->width, glyph_draw->height, 0, 0, 0x1); } glamor_upload_boxes((PixmapPtr) atlas_draw, &box, 1, 0, 0, x, y, upload_pixmap->devPrivate.ptr, upload_pixmap->devKind); if (upload_pixmap != glyph_pixmap) glamor_destroy_pixmap(upload_pixmap); } static Bool glamor_glyph_atlas_init(ScreenPtr screen, struct glamor_glyph_atlas *atlas) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PictFormatPtr format = atlas->format; atlas->atlas = glamor_create_pixmap(screen, glamor_priv->glyph_atlas_dim, glamor_priv->glyph_atlas_dim, format->depth, GLAMOR_CREATE_FBO_NO_FBO); if (!glamor_pixmap_has_fbo(atlas->atlas)) { glamor_destroy_pixmap(atlas->atlas); atlas->atlas = NULL; } atlas->x = 0; atlas->y = 0; atlas->row_height = 0; atlas->serial++; atlas->nglyph = 0; return TRUE; } static Bool glamor_glyph_can_add(struct glamor_glyph_atlas *atlas, int dim, DrawablePtr glyph_draw) { /* Step down */ if (atlas->x + glyph_draw->width > dim) { atlas->x = 0; atlas->y += atlas->row_height; atlas->row_height = 0; } /* Check for overfull */ if (atlas->y + glyph_draw->height > dim) return FALSE; return TRUE; } static Bool glamor_glyph_add(struct glamor_glyph_atlas *atlas, DrawablePtr glyph_draw) { PixmapPtr glyph_pixmap = (PixmapPtr) glyph_draw; struct glamor_glyph_private *glyph_priv = glamor_get_glyph_private(glyph_pixmap); glamor_copy_glyph(glyph_pixmap, &atlas->atlas->drawable, atlas->x, atlas->y); glyph_priv->x = atlas->x; glyph_priv->y = atlas->y; glyph_priv->serial = atlas->serial; atlas->x += glyph_draw->width; if (atlas->row_height < glyph_draw->height) atlas->row_height = glyph_draw->height; atlas->nglyph++; return TRUE; } static const glamor_facet glamor_facet_composite_glyphs_130 = { .name = "composite_glyphs", .version = 130, .vs_vars = ("attribute vec4 primitive;\n" "attribute vec2 source;\n" "varying vec2 glyph_pos;\n"), .vs_exec = (" vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n" GLAMOR_POS(gl_Position, (primitive.xy + pos)) " glyph_pos = (source + pos) * ATLAS_DIM_INV;\n"), .fs_vars = ("varying vec2 glyph_pos;\n" "out vec4 color0;\n" "out vec4 color1;\n"), .fs_exec = (" vec4 mask = texture2D(atlas, glyph_pos);\n"), .source_name = "source", .locations = glamor_program_location_atlas, }; static const glamor_facet glamor_facet_composite_glyphs_120 = { .name = "composite_glyphs", .vs_vars = ("attribute vec2 primitive;\n" "attribute vec2 source;\n" "varying vec2 glyph_pos;\n"), .vs_exec = (" vec2 pos = vec2(0,0);\n" GLAMOR_POS(gl_Position, primitive.xy) " glyph_pos = source.xy * ATLAS_DIM_INV;\n"), .fs_vars = ("varying vec2 glyph_pos;\n"), .fs_exec = (" vec4 mask = texture2D(atlas, glyph_pos);\n"), .source_name = "source", .locations = glamor_program_location_atlas, }; static inline Bool glamor_glyph_use_130(glamor_screen_private *glamor_priv) { return glamor_priv->glsl_version >= 130; } static Bool glamor_glyphs_init_facet(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); return asprintf(&glamor_priv->glyph_defines, "#define ATLAS_DIM_INV %20.18f\n", 1.0/glamor_priv->glyph_atlas_dim) > 0; } static void glamor_glyphs_fini_facet(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); free(glamor_priv->glyph_defines); } static void glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog, struct glamor_glyph_atlas *atlas, int nglyph) { DrawablePtr drawable = dst->pDrawable; glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); PixmapPtr atlas_pixmap = atlas->atlas; glamor_pixmap_private *atlas_priv = glamor_get_pixmap_private(atlas_pixmap); glamor_pixmap_fbo *atlas_fbo = glamor_pixmap_fbo_at(atlas_priv, 0); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); int box_index; int off_x, off_y; glamor_put_vbo_space(drawable->pScreen); glEnable(GL_SCISSOR_TEST); glamor_bind_texture(glamor_priv, GL_TEXTURE1, atlas_fbo, FALSE); for (;;) { if (!glamor_use_program_render(prog, op, src, dst)) break; glUniform1i(prog->atlas_uniform, 1); glamor_pixmap_loop(pixmap_priv, box_index) { BoxPtr box = RegionRects(dst->pCompositeClip); int nbox = RegionNumRects(dst->pCompositeClip); glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y); /* Run over the clip list, drawing the glyphs * in each box */ while (nbox--) { glScissor(box->x1 + off_x, box->y1 + off_y, box->x2 - box->x1, box->y2 - box->y1); box++; if (glamor_glyph_use_130(glamor_priv)) glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nglyph); else glamor_glDrawArrays_GL_QUADS(glamor_priv, nglyph); } } if (prog->alpha != glamor_program_alpha_ca_first) break; prog++; } glDisable(GL_SCISSOR_TEST); if (glamor_glyph_use_130(glamor_priv)) { glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0); glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0); } glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisable(GL_BLEND); } static GLshort * glamor_glyph_start(ScreenPtr screen, int count) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); GLshort *v; char *vbo_offset; /* Set up the vertex buffers for the font and destination */ if (glamor_glyph_use_130(glamor_priv)) { v = glamor_get_vbo_space(screen, count * (6 * sizeof (GLshort)), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1); glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE, 6 * sizeof (GLshort), vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 1); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE, 6 * sizeof (GLshort), vbo_offset + 4 * sizeof (GLshort)); } else { v = glamor_get_vbo_space(screen, count * (16 * sizeof (GLshort)), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 4 * sizeof (GLshort), vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE, 4 * sizeof (GLshort), vbo_offset + 2 * sizeof (GLshort)); } return v; } static inline struct glamor_glyph_atlas * glamor_atlas_for_glyph(glamor_screen_private *glamor_priv, DrawablePtr drawable) { if (drawable->depth == 32) return glamor_priv->glyph_atlas_argb; else return glamor_priv->glyph_atlas_a; } void glamor_composite_glyphs(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr glyph_format, INT16 x_src, INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { int glyphs_queued; GLshort *v = NULL; DrawablePtr drawable = dst->pDrawable; ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_program *prog = NULL; glamor_program_render *glyphs_program = &glamor_priv->glyphs_program; struct glamor_glyph_atlas *glyph_atlas = NULL; int x = 0, y = 0; int n; int glyph_atlas_dim = glamor_priv->glyph_atlas_dim; int glyph_max_dim = glamor_priv->glyph_max_dim; int nglyph = 0; int screen_num = screen->myNum; for (n = 0; n < nlist; n++) nglyph += list[n].len; glamor_make_current(glamor_priv); glyphs_queued = 0; while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; list++; while (n--) { GlyphPtr glyph = *glyphs++; /* Glyph not empty? */ if (glyph->info.width && glyph->info.height) { PicturePtr glyph_pict = GlyphPicture(glyph)[screen_num]; DrawablePtr glyph_draw = glyph_pict->pDrawable; /* Need to draw with slow path? */ if (_X_UNLIKELY(glyph_draw->width > glyph_max_dim || glyph_draw->height > glyph_max_dim || !glamor_pixmap_is_memory((PixmapPtr)glyph_draw))) { if (glyphs_queued) { glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued); glyphs_queued = 0; } bail_one: glamor_composite(op, src, glyph_pict, dst, x_src + (x - glyph->info.x), (y - glyph->info.y), 0, 0, x - glyph->info.x, y - glyph->info.y, glyph_draw->width, glyph_draw->height); } else { struct glamor_glyph_private *glyph_priv = glamor_get_glyph_private((PixmapPtr)(glyph_draw)); struct glamor_glyph_atlas *next_atlas = glamor_atlas_for_glyph(glamor_priv, glyph_draw); /* Switching source glyph format? */ if (_X_UNLIKELY(next_atlas != glyph_atlas)) { if (glyphs_queued) { glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued); glyphs_queued = 0; } glyph_atlas = next_atlas; } /* Glyph not cached in current atlas? */ if (_X_UNLIKELY(glyph_priv->serial != glyph_atlas->serial)) { if (!glamor_glyph_can_add(glyph_atlas, glyph_atlas_dim, glyph_draw)) { if (glyphs_queued) { glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued); glyphs_queued = 0; } if (glyph_atlas->atlas) { (*screen->DestroyPixmap)(glyph_atlas->atlas); glyph_atlas->atlas = NULL; } } if (!glyph_atlas->atlas) { glamor_glyph_atlas_init(screen, glyph_atlas); if (!glyph_atlas->atlas) goto bail_one; } glamor_glyph_add(glyph_atlas, glyph_draw); } /* First glyph in the current atlas? */ if (_X_UNLIKELY(glyphs_queued == 0)) { if (glamor_glyph_use_130(glamor_priv)) prog = glamor_setup_program_render(op, src, glyph_pict, dst, glyphs_program, &glamor_facet_composite_glyphs_130, glamor_priv->glyph_defines); else prog = glamor_setup_program_render(op, src, glyph_pict, dst, glyphs_program, &glamor_facet_composite_glyphs_120, glamor_priv->glyph_defines); if (!prog) goto bail_one; v = glamor_glyph_start(screen, nglyph); } /* Add the glyph */ glyphs_queued++; if (_X_LIKELY(glamor_glyph_use_130(glamor_priv))) { v[0] = x - glyph->info.x; v[1] = y - glyph->info.y; v[2] = glyph_draw->width; v[3] = glyph_draw->height; v[4] = glyph_priv->x; v[5] = glyph_priv->y; v += 6; } else { v[0] = x - glyph->info.x; v[1] = y - glyph->info.y; v[2] = glyph_priv->x; v[3] = glyph_priv->y; v += 4; v[0] = x - glyph->info.x + glyph_draw->width; v[1] = y - glyph->info.y; v[2] = glyph_priv->x + glyph_draw->width; v[3] = glyph_priv->y; v += 4; v[0] = x - glyph->info.x + glyph_draw->width; v[1] = y - glyph->info.y + glyph_draw->height; v[2] = glyph_priv->x + glyph_draw->width; v[3] = glyph_priv->y + glyph_draw->height; v += 4; v[0] = x - glyph->info.x; v[1] = y - glyph->info.y + glyph_draw->height; v[2] = glyph_priv->x; v[3] = glyph_priv->y + glyph_draw->height; v += 4; } } } x += glyph->info.xOff; y += glyph->info.yOff; nglyph--; } } if (glyphs_queued) glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued); return; } static struct glamor_glyph_atlas * glamor_alloc_glyph_atlas(ScreenPtr screen, int depth, CARD32 f) { PictFormatPtr format; struct glamor_glyph_atlas *glyph_atlas; format = PictureMatchFormat(screen, depth, f); if (!format) return NULL; glyph_atlas = calloc (1, sizeof (struct glamor_glyph_atlas)); if (!glyph_atlas) return NULL; glyph_atlas->format = format; glyph_atlas->serial = 1; return glyph_atlas; } Bool glamor_composite_glyphs_init(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); if (!dixRegisterPrivateKey(&glamor_glyph_private_key, PRIVATE_PIXMAP, sizeof (struct glamor_glyph_private))) return FALSE; /* Make glyph atlases of a reasonable size, but no larger than the maximum * supported by the hardware */ glamor_priv->glyph_atlas_dim = MIN(DEFAULT_ATLAS_DIM, glamor_priv->max_fbo_size); /* Don't stick huge glyphs in the atlases */ glamor_priv->glyph_max_dim = glamor_priv->glyph_atlas_dim / 8; glamor_priv->glyph_atlas_a = glamor_alloc_glyph_atlas(screen, 8, PICT_a8); if (!glamor_priv->glyph_atlas_a) return FALSE; glamor_priv->glyph_atlas_argb = glamor_alloc_glyph_atlas(screen, 32, PICT_a8r8g8b8); if (!glamor_priv->glyph_atlas_argb) { free (glamor_priv->glyph_atlas_a); return FALSE; } if (!glamor_glyphs_init_facet(screen)) return FALSE; return TRUE; } static void glamor_free_glyph_atlas(struct glamor_glyph_atlas *atlas) { if (!atlas) return; if (atlas->atlas) (*atlas->atlas->drawable.pScreen->DestroyPixmap)(atlas->atlas); free (atlas); } void glamor_composite_glyphs_fini(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_glyphs_fini_facet(screen); glamor_free_glyph_atlas(glamor_priv->glyph_atlas_a); glamor_free_glyph_atlas(glamor_priv->glyph_atlas_argb); } xorg-server-1.20.13/glamor/glamor_image.c0000644000175000017500000001252514100573756015147 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_transfer.h" #include "glamor_transform.h" /* * PutImage. Only does ZPixmap right now as other formats are quite a bit harder */ static Bool glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; uint32_t byte_stride = PixmapBytePad(w, drawable->depth); RegionRec region; BoxRec box; int off_x, off_y; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return FALSE; if (gc->alu != GXcopy) goto bail; if (!glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; if (format == XYPixmap && drawable->depth == 1 && leftPad == 0) format = ZPixmap; if (format != ZPixmap) goto bail; x += drawable->x; y += drawable->y; box.x1 = x; box.y1 = y; box.x2 = box.x1 + w; box.y2 = box.y1 + h; RegionInit(®ion, &box, 1); RegionIntersect(®ion, ®ion, gc->pCompositeClip); glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); if (off_x || off_y) { x += off_x; y += off_y; RegionTranslate(®ion, off_x, off_y); } glamor_make_current(glamor_priv); glamor_upload_region(pixmap, ®ion, x, y, (uint8_t *) bits, byte_stride); RegionUninit(®ion); return TRUE; bail: return FALSE; } static void glamor_put_image_bail(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { if (glamor_prepare_access_box(drawable, GLAMOR_ACCESS_RW, x, y, w, h)) fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits); glamor_finish_access(drawable); } void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits)) return; glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits); } static Bool glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h, unsigned int format, unsigned long plane_mask, char *d) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; uint32_t byte_stride = PixmapBytePad(w, drawable->depth); BoxRec box; int off_x, off_y; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; if (format != ZPixmap) goto bail; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); box.x1 = x; box.x2 = x + w; box.y1 = y; box.y2 = y + h; glamor_download_boxes(pixmap, &box, 1, drawable->x + off_x, drawable->y + off_y, -x, -y, (uint8_t *) d, byte_stride); if (!glamor_pm_is_solid(drawable->depth, plane_mask)) { FbStip pm = fbReplicatePixel(plane_mask, drawable->bitsPerPixel); FbStip *dst = (void *)d; uint32_t dstStride = byte_stride / sizeof(FbStip); for (int i = 0; i < dstStride * h; i++) dst[i] &= pm; } return TRUE; bail: return FALSE; } static void glamor_get_image_bail(DrawablePtr drawable, int x, int y, int w, int h, unsigned int format, unsigned long plane_mask, char *d) { if (glamor_prepare_access_box(drawable, GLAMOR_ACCESS_RO, x, y, w, h)) fbGetImage(drawable, x, y, w, h, format, plane_mask, d); glamor_finish_access(drawable); } void glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h, unsigned int format, unsigned long plane_mask, char *d) { if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d)) return; glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d); } xorg-server-1.20.13/glamor/glamor_lines.c0000644000175000017500000001234014100573756015172 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_program.h" #include "glamor_transform.h" #include "glamor_prepare.h" static const glamor_facet glamor_facet_poly_lines = { .name = "poly_lines", .vs_vars = "attribute vec2 primitive;\n", .vs_exec = (" vec2 pos = vec2(0.0,0.0);\n" GLAMOR_POS(gl_Position, primitive.xy)), }; static Bool glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; glamor_program *prog; int off_x, off_y; DDXPointPtr v; char *vbo_offset; int box_index; int add_last; Bool ret = FALSE; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; add_last = 0; if (gc->capStyle != CapNotLast) add_last = 1; if (n < 2) return TRUE; glamor_make_current(glamor_priv); prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_line_program, &glamor_facet_poly_lines); if (!prog) goto bail; /* Set up the vertex buffers for the points */ v = glamor_get_vbo_space(drawable->pScreen, (n + add_last) * sizeof (DDXPointRec), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, sizeof (DDXPointRec), vbo_offset); if (mode == CoordModePrevious) { int i; DDXPointRec here = { 0, 0 }; for (i = 0; i < n; i++) { here.x += points[i].x; here.y += points[i].y; v[i] = here; } } else { memcpy(v, points, n * sizeof (DDXPointRec)); } if (add_last) { v[n].x = v[n-1].x + 1; v[n].y = v[n-1].y; } glamor_put_vbo_space(screen); glEnable(GL_SCISSOR_TEST); glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); if (!glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y)) goto bail; while (nbox--) { glScissor(box->x1 + off_x, box->y1 + off_y, box->x2 - box->x1, box->y2 - box->y1); box++; glDrawArrays(GL_LINE_STRIP, 0, n + add_last); } } ret = TRUE; bail: glDisable(GL_SCISSOR_TEST); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); return ret; } static Bool glamor_poly_lines_gl(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points) { if (gc->lineWidth != 0) return FALSE; switch (gc->lineStyle) { case LineSolid: return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points); case LineOnOffDash: return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points); case LineDoubleDash: if (gc->fillStyle == FillTiled) return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points); else return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points); default: return FALSE; } } static void glamor_poly_lines_bail(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points) { glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); miPolylines(drawable, gc, mode, n, points); } void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points) { if (glamor_poly_lines_gl(drawable, gc, mode, n, points)) return; glamor_poly_lines_bail(drawable, gc, mode, n, points); } xorg-server-1.20.13/glamor/glamor_segs.c0000644000175000017500000001261414100573756015025 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_program.h" #include "glamor_transform.h" #include "glamor_prepare.h" static const glamor_facet glamor_facet_poly_segment = { .name = "poly_segment", .vs_vars = "attribute vec2 primitive;\n", .vs_exec = (" vec2 pos = vec2(0.0,0.0);\n" GLAMOR_POS(gl_Position, primitive.xy)), }; static Bool glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc, int nseg, xSegment *segs) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; glamor_program *prog; int off_x, off_y; xSegment *v; char *vbo_offset; int box_index; int add_last; Bool ret = FALSE; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; add_last = 0; if (gc->capStyle != CapNotLast) add_last = 1; glamor_make_current(glamor_priv); prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_segment_program, &glamor_facet_poly_segment); if (!prog) goto bail; /* Set up the vertex buffers for the points */ v = glamor_get_vbo_space(drawable->pScreen, (nseg << add_last) * sizeof (xSegment), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, sizeof(DDXPointRec), vbo_offset); if (add_last) { int i, j; for (i = 0, j=0; i < nseg; i++) { v[j++] = segs[i]; v[j].x1 = segs[i].x2; v[j].y1 = segs[i].y2; v[j].x2 = segs[i].x2+1; v[j].y2 = segs[i].y2; j++; } } else memcpy(v, segs, nseg * sizeof (xSegment)); glamor_put_vbo_space(screen); glEnable(GL_SCISSOR_TEST); glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); if (!glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y)) goto bail; while (nbox--) { glScissor(box->x1 + off_x, box->y1 + off_y, box->x2 - box->x1, box->y2 - box->y1); box++; glDrawArrays(GL_LINES, 0, nseg << (1 + add_last)); } } ret = TRUE; glDisable(GL_SCISSOR_TEST); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); bail: return ret; } static Bool glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc, int nseg, xSegment *segs) { if (gc->lineWidth != 0) return FALSE; switch (gc->lineStyle) { case LineSolid: return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs); case LineOnOffDash: return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs); case LineDoubleDash: if (gc->fillStyle == FillTiled) return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs); else return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs); default: return FALSE; } } static void glamor_poly_segment_bail(DrawablePtr drawable, GCPtr gc, int nseg, xSegment *segs) { glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (gc->lineWidth == 0) { if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && glamor_prepare_access_gc(gc)) { fbPolySegment(drawable, gc, nseg, segs); } glamor_finish_access_gc(gc); glamor_finish_access(drawable); } else miPolySegment(drawable, gc, nseg, segs); } void glamor_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg, xSegment *segs) { if (glamor_poly_segment_gl(drawable, gc, nseg, segs)) return; glamor_poly_segment_bail(drawable, gc, nseg, segs); } xorg-server-1.20.13/glamor/glamor_render.c0000644000175000017500000017627514100573756015361 00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Eric Anholt * Zhigang Gong * Junyan He * */ /** @file glamor_render.c * * Render acceleration implementation */ #include "glamor_priv.h" #include "mipict.h" #include "fbpict.h" #if 0 //#define DEBUGF(str, ...) do {} while(0) #define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__) //#define DEBUGRegionPrint(x) do {} while (0) #define DEBUGRegionPrint RegionPrint #endif static struct blendinfo composite_op_info[] = { [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO}, [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO}, [PictOpDst] = {0, 0, GL_ZERO, GL_ONE}, [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE}, [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO}, [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA}, [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO}, [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}, [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA}, [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, }; #define RepeatFix 10 static GLuint glamor_create_composite_fs(struct shader_key *key) { const char *repeat_define = "#define RepeatNone 0\n" "#define RepeatNormal 1\n" "#define RepeatPad 2\n" "#define RepeatReflect 3\n" "#define RepeatFix 10\n" "uniform int source_repeat_mode;\n" "uniform int mask_repeat_mode;\n"; const char *relocate_texture = "vec2 rel_tex_coord(vec2 texture, vec4 wh, int repeat) \n" "{\n" " vec2 rel_tex; \n" " rel_tex = texture * wh.xy; \n" " if (repeat == RepeatFix + RepeatNone)\n" " return rel_tex; \n" " else if (repeat == RepeatFix + RepeatNormal) \n" " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); \n" " else if (repeat == RepeatFix + RepeatPad) { \n" " if (rel_tex.x >= 1.0) \n" " rel_tex.x = 1.0 - wh.z * wh.x / 2.; \n" " else if (rel_tex.x < 0.0) \n" " rel_tex.x = 0.0; \n" " if (rel_tex.y >= 1.0) \n" " rel_tex.y = 1.0 - wh.w * wh.y / 2.; \n" " else if (rel_tex.y < 0.0) \n" " rel_tex.y = 0.0; \n" " rel_tex = rel_tex / wh.xy; \n" " } else if (repeat == RepeatFix + RepeatReflect) {\n" " if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n" " rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x)) / wh.x;\n" " else \n" " rel_tex.x = fract(rel_tex.x) / wh.x;\n" " if ((1.0 - mod(abs(floor(rel_tex.y)), 2.0)) < 0.001)\n" " rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y)) / wh.y;\n" " else \n" " rel_tex.y = fract(rel_tex.y) / wh.y;\n" " } \n" " return rel_tex; \n" "}\n"; /* The texture and the pixmap size is not match eaxctly, so can't sample it directly. * rel_sampler will recalculate the texture coords.*/ const char *rel_sampler = " vec4 rel_sampler_rgba(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n" "{\n" " if (repeat >= RepeatFix) {\n" " tex = rel_tex_coord(tex, wh, repeat);\n" " if (repeat == RepeatFix + RepeatNone) {\n" " if (tex.x < 0.0 || tex.x >= 1.0 || \n" " tex.y < 0.0 || tex.y >= 1.0)\n" " return vec4(0.0, 0.0, 0.0, 0.0);\n" " tex = (fract(tex) / wh.xy);\n" " }\n" " }\n" " return texture2D(tex_image, tex);\n" "}\n" " vec4 rel_sampler_rgbx(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n" "{\n" " if (repeat >= RepeatFix) {\n" " tex = rel_tex_coord(tex, wh, repeat);\n" " if (repeat == RepeatFix + RepeatNone) {\n" " if (tex.x < 0.0 || tex.x >= 1.0 || \n" " tex.y < 0.0 || tex.y >= 1.0)\n" " return vec4(0.0, 0.0, 0.0, 0.0);\n" " tex = (fract(tex) / wh.xy);\n" " }\n" " }\n" " return vec4(texture2D(tex_image, tex).rgb, 1.0);\n" "}\n"; const char *source_solid_fetch = "uniform vec4 source;\n" "vec4 get_source()\n" "{\n" " return source;\n" "}\n"; const char *source_alpha_pixmap_fetch = "varying vec2 source_texture;\n" "uniform sampler2D source_sampler;\n" "uniform vec4 source_wh;" "vec4 get_source()\n" "{\n" " return rel_sampler_rgba(source_sampler, source_texture,\n" " source_wh, source_repeat_mode);\n" "}\n"; const char *source_pixmap_fetch = "varying vec2 source_texture;\n" "uniform sampler2D source_sampler;\n" "uniform vec4 source_wh;\n" "vec4 get_source()\n" "{\n" " return rel_sampler_rgbx(source_sampler, source_texture,\n" " source_wh, source_repeat_mode);\n" "}\n"; const char *mask_none = "vec4 get_mask()\n" "{\n" " return vec4(0.0, 0.0, 0.0, 1.0);\n" "}\n"; const char *mask_solid_fetch = "uniform vec4 mask;\n" "vec4 get_mask()\n" "{\n" " return mask;\n" "}\n"; const char *mask_alpha_pixmap_fetch = "varying vec2 mask_texture;\n" "uniform sampler2D mask_sampler;\n" "uniform vec4 mask_wh;\n" "vec4 get_mask()\n" "{\n" " return rel_sampler_rgba(mask_sampler, mask_texture,\n" " mask_wh, mask_repeat_mode);\n" "}\n"; const char *mask_pixmap_fetch = "varying vec2 mask_texture;\n" "uniform sampler2D mask_sampler;\n" "uniform vec4 mask_wh;\n" "vec4 get_mask()\n" "{\n" " return rel_sampler_rgbx(mask_sampler, mask_texture,\n" " mask_wh, mask_repeat_mode);\n" "}\n"; const char *dest_swizzle_default = "vec4 dest_swizzle(vec4 color)\n" "{" " return color;" "}"; const char *dest_swizzle_alpha_to_red = "vec4 dest_swizzle(vec4 color)\n" "{" " float undef;\n" " return vec4(color.a, undef, undef, undef);" "}"; const char *in_normal = "void main()\n" "{\n" " gl_FragColor = dest_swizzle(get_source() * get_mask().a);\n" "}\n"; const char *in_ca_source = "void main()\n" "{\n" " gl_FragColor = dest_swizzle(get_source() * get_mask());\n" "}\n"; const char *in_ca_alpha = "void main()\n" "{\n" " gl_FragColor = dest_swizzle(get_source().a * get_mask());\n" "}\n"; const char *in_ca_dual_blend = "out vec4 color0;\n" "out vec4 color1;\n" "void main()\n" "{\n" " color0 = dest_swizzle(get_source() * get_mask());\n" " color1 = dest_swizzle(get_source().a * get_mask());\n" "}\n"; const char *header_ca_dual_blend = "#version 130\n"; char *source; const char *source_fetch; const char *mask_fetch = ""; const char *in; const char *header; const char *header_norm = ""; const char *dest_swizzle; GLuint prog; switch (key->source) { case SHADER_SOURCE_SOLID: source_fetch = source_solid_fetch; break; case SHADER_SOURCE_TEXTURE_ALPHA: source_fetch = source_alpha_pixmap_fetch; break; case SHADER_SOURCE_TEXTURE: source_fetch = source_pixmap_fetch; break; default: FatalError("Bad composite shader source"); } switch (key->mask) { case SHADER_MASK_NONE: mask_fetch = mask_none; break; case SHADER_MASK_SOLID: mask_fetch = mask_solid_fetch; break; case SHADER_MASK_TEXTURE_ALPHA: mask_fetch = mask_alpha_pixmap_fetch; break; case SHADER_MASK_TEXTURE: mask_fetch = mask_pixmap_fetch; break; default: FatalError("Bad composite shader mask"); } /* If we're storing to an a8 texture but our texture format is * GL_RED because of a core context, then we need to make sure to * put the alpha into the red channel. */ switch (key->dest_swizzle) { case SHADER_DEST_SWIZZLE_DEFAULT: dest_swizzle = dest_swizzle_default; break; case SHADER_DEST_SWIZZLE_ALPHA_TO_RED: dest_swizzle = dest_swizzle_alpha_to_red; break; default: FatalError("Bad composite shader dest swizzle"); } header = header_norm; switch (key->in) { case glamor_program_alpha_normal: in = in_normal; break; case glamor_program_alpha_ca_first: in = in_ca_source; break; case glamor_program_alpha_ca_second: in = in_ca_alpha; break; case glamor_program_alpha_dual_blend: in = in_ca_dual_blend; header = header_ca_dual_blend; break; default: FatalError("Bad composite IN type"); } XNFasprintf(&source, "%s" GLAMOR_DEFAULT_PRECISION "%s%s%s%s%s%s%s", header, repeat_define, relocate_texture, rel_sampler, source_fetch, mask_fetch, dest_swizzle, in); prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source); free(source); return prog; } static GLuint glamor_create_composite_vs(struct shader_key *key) { const char *main_opening = "attribute vec4 v_position;\n" "attribute vec4 v_texcoord0;\n" "attribute vec4 v_texcoord1;\n" "varying vec2 source_texture;\n" "varying vec2 mask_texture;\n" "void main()\n" "{\n" " gl_Position = v_position;\n"; const char *source_coords = " source_texture = v_texcoord0.xy;\n"; const char *mask_coords = " mask_texture = v_texcoord1.xy;\n"; const char *main_closing = "}\n"; const char *source_coords_setup = ""; const char *mask_coords_setup = ""; char *source; GLuint prog; if (key->source != SHADER_SOURCE_SOLID) source_coords_setup = source_coords; if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID) mask_coords_setup = mask_coords; XNFasprintf(&source, "%s%s%s%s", main_opening, source_coords_setup, mask_coords_setup, main_closing); prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, source); free(source); return prog; } static void glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, glamor_composite_shader *shader) { GLuint vs, fs, prog; GLint source_sampler_uniform_location, mask_sampler_uniform_location; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); vs = glamor_create_composite_vs(key); if (vs == 0) return; fs = glamor_create_composite_fs(key); if (fs == 0) return; prog = glCreateProgram(); glAttachShader(prog, vs); glAttachShader(prog, fs); glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position"); glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1"); if (key->in == glamor_program_alpha_dual_blend) { glBindFragDataLocationIndexed(prog, 0, 0, "color0"); glBindFragDataLocationIndexed(prog, 0, 1, "color1"); } glamor_link_glsl_prog(screen, prog, "composite"); shader->prog = prog; glUseProgram(prog); if (key->source == SHADER_SOURCE_SOLID) { shader->source_uniform_location = glGetUniformLocation(prog, "source"); } else { source_sampler_uniform_location = glGetUniformLocation(prog, "source_sampler"); glUniform1i(source_sampler_uniform_location, 0); shader->source_wh = glGetUniformLocation(prog, "source_wh"); shader->source_repeat_mode = glGetUniformLocation(prog, "source_repeat_mode"); } if (key->mask != SHADER_MASK_NONE) { if (key->mask == SHADER_MASK_SOLID) { shader->mask_uniform_location = glGetUniformLocation(prog, "mask"); } else { mask_sampler_uniform_location = glGetUniformLocation(prog, "mask_sampler"); glUniform1i(mask_sampler_uniform_location, 1); shader->mask_wh = glGetUniformLocation(prog, "mask_wh"); shader->mask_repeat_mode = glGetUniformLocation(prog, "mask_repeat_mode"); } } } static glamor_composite_shader * glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_composite_shader *shader; shader = &glamor_priv->composite_shader[key->source][key->mask][key->in][key->dest_swizzle]; if (shader->prog == 0) glamor_create_composite_shader(screen, key, shader); return shader; } static GLenum glamor_translate_blend_alpha_to_red(GLenum blend) { switch (blend) { case GL_SRC_ALPHA: return GL_SRC_COLOR; case GL_DST_ALPHA: return GL_DST_COLOR; case GL_ONE_MINUS_SRC_ALPHA: return GL_ONE_MINUS_SRC_COLOR; case GL_ONE_MINUS_DST_ALPHA: return GL_ONE_MINUS_DST_COLOR; default: return blend; } } static Bool glamor_set_composite_op(ScreenPtr screen, CARD8 op, struct blendinfo *op_info_result, PicturePtr dest, PicturePtr mask, enum ca_state ca_state, struct shader_key *key) { GLenum source_blend, dest_blend; struct blendinfo *op_info; if (op >= ARRAY_SIZE(composite_op_info)) { glamor_fallback("unsupported render op %d \n", op); return GL_FALSE; } op_info = &composite_op_info[op]; source_blend = op_info->source_blend; dest_blend = op_info->dest_blend; /* If there's no dst alpha channel, adjust the blend op so that we'll treat * it as always 1. */ if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) { if (source_blend == GL_DST_ALPHA) source_blend = GL_ONE; else if (source_blend == GL_ONE_MINUS_DST_ALPHA) source_blend = GL_ZERO; } /* Set up the source alpha value for blending in component alpha mode. */ if (ca_state == CA_DUAL_BLEND) { switch (dest_blend) { case GL_SRC_ALPHA: dest_blend = GL_SRC1_COLOR; break; case GL_ONE_MINUS_SRC_ALPHA: dest_blend = GL_ONE_MINUS_SRC1_COLOR; break; } } else if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha) { switch (dest_blend) { case GL_SRC_ALPHA: dest_blend = GL_SRC_COLOR; break; case GL_ONE_MINUS_SRC_ALPHA: dest_blend = GL_ONE_MINUS_SRC_COLOR; break; } } /* If we're outputting our alpha to the red channel, then any * reads of alpha for blending need to come from the red channel. */ if (key->dest_swizzle == SHADER_DEST_SWIZZLE_ALPHA_TO_RED) { source_blend = glamor_translate_blend_alpha_to_red(source_blend); dest_blend = glamor_translate_blend_alpha_to_red(dest_blend); } op_info_result->source_blend = source_blend; op_info_result->dest_blend = dest_blend; op_info_result->source_alpha = op_info->source_alpha; op_info_result->dest_alpha = op_info->dest_alpha; return TRUE; } static void glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit, PicturePtr picture, PixmapPtr pixmap, GLuint wh_location, GLuint repeat_location, glamor_pixmap_private *dest_priv) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_fbo *fbo = pixmap_priv->fbo; float wh[4]; int repeat_type; glamor_make_current(glamor_priv); /* The red channel swizzling doesn't depend on whether we're using * 'fbo' as source or mask as we must have the same answer in case * the same fbo is being used for both. That means the mask * channel will sometimes get red bits in the R channel, and * sometimes get zero bits in the R channel, which is harmless. */ glamor_bind_texture(glamor_priv, GL_TEXTURE0 + unit, fbo, glamor_fbo_red_is_alpha(glamor_priv, dest_priv->fbo)); repeat_type = picture->repeatType; switch (picture->repeatType) { case RepeatNone: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); break; case RepeatNormal: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); break; case RepeatPad: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); break; case RepeatReflect: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); break; } switch (picture->filter) { default: case PictFilterFast: case PictFilterNearest: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); break; case PictFilterGood: case PictFilterBest: case PictFilterBilinear: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); break; } /* Handle RepeatNone in the shader when the source is missing the * alpha channel, as GL will return an alpha for 1 if the texture * is RGB (no alpha), which we use for 16bpp textures. */ if (glamor_pixmap_priv_is_large(pixmap_priv) || (!PICT_FORMAT_A(picture->format) && repeat_type == RepeatNone && picture->transform)) { glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, pixmap_priv); glUniform4fv(wh_location, 1, wh); repeat_type += RepeatFix; } glUniform1i(repeat_location, repeat_type); } static void glamor_set_composite_solid(float *color, GLint uniform_location) { glUniform4fv(uniform_location, 1, color); } static char glamor_get_picture_location(PicturePtr picture) { if (picture == NULL) return ' '; if (picture->pDrawable == NULL) { switch (picture->pSourcePict->type) { case SourcePictTypeSolidFill: return 'c'; case SourcePictTypeLinear: return 'l'; case SourcePictTypeRadial: return 'r'; default: return '?'; } } return glamor_get_drawable_location(picture->pDrawable); } static void * glamor_setup_composite_vbo(ScreenPtr screen, int n_verts) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); int vert_size; char *vbo_offset; float *vb; glamor_priv->render_nr_quads = 0; glamor_priv->vb_stride = 2 * sizeof(float); if (glamor_priv->has_source_coords) glamor_priv->vb_stride += 2 * sizeof(float); if (glamor_priv->has_mask_coords) glamor_priv->vb_stride += 2 * sizeof(float); vert_size = n_verts * glamor_priv->vb_stride; glamor_make_current(glamor_priv); vb = glamor_get_vbo_space(screen, vert_size, &vbo_offset); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); if (glamor_priv->has_source_coords) { glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, vbo_offset + 2 * sizeof(float)); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); } if (glamor_priv->has_mask_coords) { glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, vbo_offset + (glamor_priv->has_source_coords ? 4 : 2) * sizeof(float)); glEnableVertexAttribArray(GLAMOR_VERTEX_MASK); } return vb; } static void glamor_flush_composite_rects(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); if (!glamor_priv->render_nr_quads) return; glamor_glDrawArrays_GL_QUADS(glamor_priv, glamor_priv->render_nr_quads); } static const int pict_format_combine_tab[][3] = { {PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB}, {PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR}, }; static Bool combine_pict_format(PictFormatShort * des, const PictFormatShort src, const PictFormatShort mask, glamor_program_alpha in_ca) { PictFormatShort new_vis; int src_type, mask_type, src_bpp; int i; if (src == mask) { *des = src; return TRUE; } src_bpp = PICT_FORMAT_BPP(src); assert(src_bpp == PICT_FORMAT_BPP(mask)); new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask); switch (in_ca) { case glamor_program_alpha_normal: src_type = PICT_FORMAT_TYPE(src); mask_type = PICT_TYPE_A; break; case glamor_program_alpha_ca_first: src_type = PICT_FORMAT_TYPE(src); mask_type = PICT_FORMAT_TYPE(mask); break; case glamor_program_alpha_ca_second: src_type = PICT_TYPE_A; mask_type = PICT_FORMAT_TYPE(mask); break; case glamor_program_alpha_dual_blend: src_type = PICT_FORMAT_TYPE(src); mask_type = PICT_FORMAT_TYPE(mask); break; default: return FALSE; } if (src_type == mask_type) { *des = PICT_VISFORMAT(src_bpp, src_type, new_vis); return TRUE; } for (i = 0; i < ARRAY_SIZE(pict_format_combine_tab); i++) { if ((src_type == pict_format_combine_tab[i][0] && mask_type == pict_format_combine_tab[i][1]) || (src_type == pict_format_combine_tab[i][1] && mask_type == pict_format_combine_tab[i][0])) { *des = PICT_VISFORMAT(src_bpp, pict_format_combine_tab[i] [2], new_vis); return TRUE; } } return FALSE; } static void glamor_set_normalize_tcoords_generic(PixmapPtr pixmap, glamor_pixmap_private *priv, int repeat_type, float *matrix, float xscale, float yscale, int x1, int y1, int x2, int y2, float *texcoords, int stride) { if (!matrix && repeat_type == RepeatNone) glamor_set_normalize_tcoords_ext(priv, xscale, yscale, x1, y1, x2, y2, texcoords, stride); else if (matrix && repeat_type == RepeatNone) glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, yscale, x1, y1, x2, y2, texcoords, stride); else if (!matrix && repeat_type != RepeatNone) glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type, xscale, yscale, x1, y1, x2, y2, texcoords, stride); else if (matrix && repeat_type != RepeatNone) glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, repeat_type, matrix, xscale, yscale, x1, y1, x2, y2, texcoords, stride); } /** * Returns whether the general composite path supports this picture * format for a pixmap that is permanently stored in an FBO (as * opposed to the dynamic upload path). * * We could support many more formats by using GL_ARB_texture_view to * parse the same bits as different formats. For now, we only support * tweaking whether we sample the alpha bits, or just force them to 1. */ static Bool glamor_render_format_is_supported(PicturePtr picture) { PictFormatShort storage_format; /* Source-only pictures should always work */ if (!picture->pDrawable) return TRUE; storage_format = format_for_depth(picture->pDrawable->depth); switch (picture->format) { case PICT_x2r10g10b10: return storage_format == PICT_x2r10g10b10; case PICT_a8r8g8b8: case PICT_x8r8g8b8: return storage_format == PICT_a8r8g8b8 || storage_format == PICT_x8r8g8b8; case PICT_a8: return storage_format == PICT_a8; default: return FALSE; } } static Bool glamor_composite_choose_shader(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, PixmapPtr source_pixmap, PixmapPtr mask_pixmap, PixmapPtr dest_pixmap, glamor_pixmap_private *source_pixmap_priv, glamor_pixmap_private *mask_pixmap_priv, glamor_pixmap_private *dest_pixmap_priv, struct shader_key *s_key, glamor_composite_shader ** shader, struct blendinfo *op_info, PictFormatShort *psaved_source_format, enum ca_state ca_state) { ScreenPtr screen = dest->pDrawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); Bool source_needs_upload = FALSE; Bool mask_needs_upload = FALSE; PictFormatShort saved_source_format = 0; struct shader_key key; GLfloat source_solid_color[4]; GLfloat mask_solid_color[4]; Bool ret = FALSE; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { glamor_fallback("dest has no fbo.\n"); goto fail; } if (!glamor_render_format_is_supported(dest)) { glamor_fallback("Unsupported dest picture format.\n"); goto fail; } memset(&key, 0, sizeof(key)); if (!source) { key.source = SHADER_SOURCE_SOLID; source_solid_color[0] = 0.0; source_solid_color[1] = 0.0; source_solid_color[2] = 0.0; source_solid_color[3] = 0.0; } else if (!source->pDrawable) { SourcePictPtr sp = source->pSourcePict; if (sp->type == SourcePictTypeSolidFill) { key.source = SHADER_SOURCE_SOLID; glamor_get_rgba_from_color(&sp->solidFill.fullcolor, source_solid_color); } else goto fail; } else { if (PICT_FORMAT_A(source->format)) key.source = SHADER_SOURCE_TEXTURE_ALPHA; else key.source = SHADER_SOURCE_TEXTURE; } if (mask) { if (!mask->pDrawable) { SourcePictPtr sp = mask->pSourcePict; if (sp->type == SourcePictTypeSolidFill) { key.mask = SHADER_MASK_SOLID; glamor_get_rgba_from_color(&sp->solidFill.fullcolor, mask_solid_color); } else goto fail; } else { if (PICT_FORMAT_A(mask->format)) key.mask = SHADER_MASK_TEXTURE_ALPHA; else key.mask = SHADER_MASK_TEXTURE; } if (!mask->componentAlpha) { key.in = glamor_program_alpha_normal; } else { if (op == PictOpClear) key.mask = SHADER_MASK_NONE; else if (glamor_priv->has_dual_blend) key.in = glamor_program_alpha_dual_blend; else if (op == PictOpSrc || op == PictOpAdd || op == PictOpIn || op == PictOpOut || op == PictOpOverReverse) key.in = glamor_program_alpha_ca_second; else if (op == PictOpOutReverse || op == PictOpInReverse) { key.in = glamor_program_alpha_ca_first; } else { glamor_fallback("Unsupported component alpha op: %d\n", op); goto fail; } } } else { key.mask = SHADER_MASK_NONE; } if (dest_pixmap->drawable.bitsPerPixel <= 8 && glamor_priv->one_channel_format == GL_RED) { key.dest_swizzle = SHADER_DEST_SWIZZLE_ALPHA_TO_RED; } else { key.dest_swizzle = SHADER_DEST_SWIZZLE_DEFAULT; } if (source && source->alphaMap) { glamor_fallback("source alphaMap\n"); goto fail; } if (mask && mask->alphaMap) { glamor_fallback("mask alphaMap\n"); goto fail; } if (key.source == SHADER_SOURCE_TEXTURE || key.source == SHADER_SOURCE_TEXTURE_ALPHA) { if (source_pixmap == dest_pixmap) { /* XXX source and the dest share the same texture. * Does it need special handle? */ glamor_fallback("source == dest\n"); } if (source_pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) { source_needs_upload = TRUE; } } if (key.mask == SHADER_MASK_TEXTURE || key.mask == SHADER_MASK_TEXTURE_ALPHA) { if (mask_pixmap == dest_pixmap) { glamor_fallback("mask == dest\n"); goto fail; } if (mask_pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) { mask_needs_upload = TRUE; } } if (source_needs_upload && mask_needs_upload && source_pixmap == mask_pixmap) { if (source->format != mask->format) { saved_source_format = source->format; if (!combine_pict_format(&source->format, source->format, mask->format, key.in)) { glamor_fallback("combine source %x mask %x failed.\n", source->format, mask->format); goto fail; } /* XXX * By default, glamor_upload_picture_to_texture will wire alpha to 1 * if one picture doesn't have alpha. So we don't do that again in * rendering function. But here is a special case, as source and * mask share the same texture but may have different formats. For * example, source doesn't have alpha, but mask has alpha. Then the * texture will have the alpha value for the mask. And will not wire * to 1 for the source. In this case, we have to use different shader * to wire the source's alpha to 1. * * But this may cause a potential problem if the source's repeat mode * is REPEAT_NONE, and if the source is smaller than the dest, then * for the region not covered by the source may be painted incorrectly. * because we wire the alpha to 1. * **/ if (!PICT_FORMAT_A(saved_source_format) && PICT_FORMAT_A(mask->format)) key.source = SHADER_SOURCE_TEXTURE; if (!PICT_FORMAT_A(mask->format) && PICT_FORMAT_A(saved_source_format)) key.mask = SHADER_MASK_TEXTURE; } if (!glamor_upload_picture_to_texture(source)) { glamor_fallback("Failed to upload source texture.\n"); goto fail; } mask_needs_upload = FALSE; } else { if (source_needs_upload) { if (!glamor_upload_picture_to_texture(source)) { glamor_fallback("Failed to upload source texture.\n"); goto fail; } } else { if (source && !glamor_render_format_is_supported(source)) { glamor_fallback("Unsupported source picture format.\n"); goto fail; } } if (mask_needs_upload) { if (!glamor_upload_picture_to_texture(mask)) { glamor_fallback("Failed to upload mask texture.\n"); goto fail; } } else if (mask) { if (!glamor_render_format_is_supported(mask)) { glamor_fallback("Unsupported mask picture format.\n"); goto fail; } } } /* If the source and mask are two differently-formatted views of * the same pixmap bits, and the pixmap was already uploaded (so * the dynamic code above doesn't apply), then fall back to * software. We should use texture views to fix this properly. */ if (source_pixmap && source_pixmap == mask_pixmap && source->format != mask->format) { goto fail; } if (!glamor_set_composite_op(screen, op, op_info, dest, mask, ca_state, &key)) { goto fail; } *shader = glamor_lookup_composite_shader(screen, &key); if ((*shader)->prog == 0) { glamor_fallback("no shader program for this render acccel mode\n"); goto fail; } if (key.source == SHADER_SOURCE_SOLID) memcpy(&(*shader)->source_solid_color[0], source_solid_color, 4 * sizeof(float)); else { (*shader)->source_pixmap = source_pixmap; (*shader)->source = source; } if (key.mask == SHADER_MASK_SOLID) memcpy(&(*shader)->mask_solid_color[0], mask_solid_color, 4 * sizeof(float)); else { (*shader)->mask_pixmap = mask_pixmap; (*shader)->mask = mask; } ret = TRUE; memcpy(s_key, &key, sizeof(key)); *psaved_source_format = saved_source_format; goto done; fail: if (saved_source_format) source->format = saved_source_format; done: return ret; } static void glamor_composite_set_shader_blend(glamor_screen_private *glamor_priv, glamor_pixmap_private *dest_priv, struct shader_key *key, glamor_composite_shader *shader, struct blendinfo *op_info) { glamor_make_current(glamor_priv); glUseProgram(shader->prog); if (key->source == SHADER_SOURCE_SOLID) { glamor_set_composite_solid(shader->source_solid_color, shader->source_uniform_location); } else { glamor_set_composite_texture(glamor_priv, 0, shader->source, shader->source_pixmap, shader->source_wh, shader->source_repeat_mode, dest_priv); } if (key->mask != SHADER_MASK_NONE) { if (key->mask == SHADER_MASK_SOLID) { glamor_set_composite_solid(shader->mask_solid_color, shader->mask_uniform_location); } else { glamor_set_composite_texture(glamor_priv, 1, shader->mask, shader->mask_pixmap, shader->mask_wh, shader->mask_repeat_mode, dest_priv); } } if (glamor_priv->gl_flavor != GLAMOR_GL_ES2) glDisable(GL_COLOR_LOGIC_OP); if (op_info->source_blend == GL_ONE && op_info->dest_blend == GL_ZERO) { glDisable(GL_BLEND); } else { glEnable(GL_BLEND); glBlendFunc(op_info->source_blend, op_info->dest_blend); } } static Bool glamor_composite_with_shader(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, PixmapPtr source_pixmap, PixmapPtr mask_pixmap, PixmapPtr dest_pixmap, glamor_pixmap_private *source_pixmap_priv, glamor_pixmap_private *mask_pixmap_priv, glamor_pixmap_private *dest_pixmap_priv, int nrect, glamor_composite_rect_t *rects, enum ca_state ca_state) { ScreenPtr screen = dest->pDrawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); GLfloat dst_xscale, dst_yscale; GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1; struct shader_key key, key_ca; int dest_x_off, dest_y_off; int source_x_off, source_y_off; int mask_x_off, mask_y_off; PictFormatShort saved_source_format = 0; float src_matrix[9], mask_matrix[9]; float *psrc_matrix = NULL, *pmask_matrix = NULL; int nrect_max; Bool ret = FALSE; glamor_composite_shader *shader = NULL, *shader_ca = NULL; struct blendinfo op_info, op_info_ca; if (!glamor_composite_choose_shader(op, source, mask, dest, source_pixmap, mask_pixmap, dest_pixmap, source_pixmap_priv, mask_pixmap_priv, dest_pixmap_priv, &key, &shader, &op_info, &saved_source_format, ca_state)) { glamor_fallback("glamor_composite_choose_shader failed\n"); goto fail; } if (ca_state == CA_TWO_PASS) { if (!glamor_composite_choose_shader(PictOpAdd, source, mask, dest, source_pixmap, mask_pixmap, dest_pixmap, source_pixmap_priv, mask_pixmap_priv, dest_pixmap_priv, &key_ca, &shader_ca, &op_info_ca, &saved_source_format, ca_state)) { glamor_fallback("glamor_composite_choose_shader failed\n"); goto fail; } } glamor_make_current(glamor_priv); glamor_set_destination_pixmap_priv_nc(glamor_priv, dest_pixmap, dest_pixmap_priv); glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv, &key, shader, &op_info); glamor_set_alu(screen, GXcopy); glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID; glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID); dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, &dest_x_off, &dest_y_off); pixmap_priv_get_dest_scale(dest_pixmap, dest_pixmap_priv, &dst_xscale, &dst_yscale); if (glamor_priv->has_source_coords) { glamor_get_drawable_deltas(source->pDrawable, source_pixmap, &source_x_off, &source_y_off); pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale); if (source->transform) { psrc_matrix = src_matrix; glamor_picture_get_matrixf(source, psrc_matrix); } } if (glamor_priv->has_mask_coords) { glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, &mask_x_off, &mask_y_off); pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale); if (mask->transform) { pmask_matrix = mask_matrix; glamor_picture_get_matrixf(mask, pmask_matrix); } } nrect_max = MIN(nrect, GLAMOR_COMPOSITE_VBO_VERT_CNT / 4); if (nrect < 100) { BoxRec bounds = glamor_start_rendering_bounds(); for (int i = 0; i < nrect; i++) { BoxRec box = { .x1 = rects[i].x_dst, .y1 = rects[i].y_dst, .x2 = rects[i].x_dst + rects[i].width, .y2 = rects[i].y_dst + rects[i].height, }; glamor_bounds_union_box(&bounds, &box); } if (bounds.x1 >= bounds.x2 || bounds.y1 >= bounds.y2) goto disable_va; glEnable(GL_SCISSOR_TEST); glScissor(bounds.x1 + dest_x_off, bounds.y1 + dest_y_off, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); } while (nrect) { int mrect, rect_processed; int vb_stride; float *vertices; mrect = nrect > nrect_max ? nrect_max : nrect; vertices = glamor_setup_composite_vbo(screen, mrect * 4); rect_processed = mrect; vb_stride = glamor_priv->vb_stride / sizeof(float); while (mrect--) { INT16 x_source; INT16 y_source; INT16 x_mask; INT16 y_mask; INT16 x_dest; INT16 y_dest; CARD16 width; CARD16 height; x_dest = rects->x_dst + dest_x_off; y_dest = rects->y_dst + dest_y_off; x_source = rects->x_src + source_x_off; y_source = rects->y_src + source_y_off; x_mask = rects->x_mask + mask_x_off; y_mask = rects->y_mask + mask_y_off; width = rects->width; height = rects->height; DEBUGF ("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n", x_dest, y_dest, x_source, y_source, x_mask, y_mask, width, height); glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale, dst_yscale, x_dest, y_dest, x_dest + width, y_dest + height, vertices, vb_stride); vertices += 2; if (key.source != SHADER_SOURCE_SOLID) { glamor_set_normalize_tcoords_generic(source_pixmap, source_pixmap_priv, source->repeatType, psrc_matrix, src_xscale, src_yscale, x_source, y_source, x_source + width, y_source + height, vertices, vb_stride); vertices += 2; } if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { glamor_set_normalize_tcoords_generic(mask_pixmap, mask_pixmap_priv, mask->repeatType, pmask_matrix, mask_xscale, mask_yscale, x_mask, y_mask, x_mask + width, y_mask + height, vertices, vb_stride); vertices += 2; } glamor_priv->render_nr_quads++; rects++; /* We've incremented by one of our 4 verts, now do the other 3. */ vertices += 3 * vb_stride; } glamor_put_vbo_space(screen); glamor_flush_composite_rects(screen); nrect -= rect_processed; if (ca_state == CA_TWO_PASS) { glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv, &key_ca, shader_ca, &op_info_ca); glamor_flush_composite_rects(screen); if (nrect) glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv, &key, shader, &op_info); } } glDisable(GL_SCISSOR_TEST); disable_va: glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); glDisable(GL_BLEND); DEBUGF("finish rendering.\n"); if (saved_source_format) source->format = saved_source_format; ret = TRUE; fail: if (mask_pixmap && glamor_pixmap_is_memory(mask_pixmap)) glamor_pixmap_destroy_fbo(mask_pixmap); if (source_pixmap && glamor_pixmap_is_memory(source_pixmap)) glamor_pixmap_destroy_fbo(source_pixmap); return ret; } static PicturePtr glamor_convert_gradient_picture(ScreenPtr screen, PicturePtr source, int x_source, int y_source, int width, int height) { PixmapPtr pixmap; PicturePtr dst = NULL; int error; PictFormatPtr pFormat; PictFormatShort format; if (source->pDrawable) { pFormat = source->pFormat; format = pFormat->format; } else { format = PICT_a8r8g8b8; pFormat = PictureMatchFormat(screen, 32, format); } if (!source->pDrawable) { if (source->pSourcePict->type == SourcePictTypeLinear) { dst = glamor_generate_linear_gradient_picture(screen, source, x_source, y_source, width, height, format); } else if (source->pSourcePict->type == SourcePictTypeRadial) { dst = glamor_generate_radial_gradient_picture(screen, source, x_source, y_source, width, height, format); } if (dst) { return dst; } } pixmap = glamor_create_pixmap(screen, width, height, PIXMAN_FORMAT_DEPTH(format), GLAMOR_CREATE_PIXMAP_CPU); if (!pixmap) return NULL; dst = CreatePicture(0, &pixmap->drawable, pFormat, 0, 0, serverClient, &error); glamor_destroy_pixmap(pixmap); if (!dst) return NULL; ValidatePicture(dst); fbComposite(PictOpSrc, source, NULL, dst, x_source, y_source, 0, 0, 0, 0, width, height); return dst; } Bool glamor_composite_clipped_region(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, PixmapPtr source_pixmap, PixmapPtr mask_pixmap, PixmapPtr dest_pixmap, RegionPtr region, int x_source, int y_source, int x_mask, int y_mask, int x_dest, int y_dest) { glamor_pixmap_private *source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); glamor_pixmap_private *mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); glamor_pixmap_private *dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(dest_pixmap->drawable.pScreen); ScreenPtr screen = dest->pDrawable->pScreen; PicturePtr temp_src = source, temp_mask = mask; PixmapPtr temp_src_pixmap = source_pixmap; PixmapPtr temp_mask_pixmap = mask_pixmap; glamor_pixmap_private *temp_src_priv = source_pixmap_priv; glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv; int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; BoxPtr extent; glamor_composite_rect_t rect[10]; glamor_composite_rect_t *prect = rect; int prect_size = ARRAY_SIZE(rect); int ok = FALSE; int i; int width; int height; BoxPtr box; int nbox; enum ca_state ca_state = CA_NONE; extent = RegionExtents(region); box = RegionRects(region); nbox = RegionNumRects(region); width = extent->x2 - extent->x1; height = extent->y2 - extent->y1; x_temp_src = x_source; y_temp_src = y_source; x_temp_mask = x_mask; y_temp_mask = y_mask; DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n", x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); /* Is the composite operation equivalent to a copy? */ if (source && !mask && !source->alphaMap && !dest->alphaMap && source->pDrawable && !source->transform /* CopyArea is only defined with matching depths. */ && dest->pDrawable->depth == source->pDrawable->depth && ((op == PictOpSrc && (source->format == dest->format || (PICT_FORMAT_COLOR(dest->format) && PICT_FORMAT_COLOR(source->format) && dest->format == PICT_FORMAT(PICT_FORMAT_BPP(source->format), PICT_FORMAT_TYPE(source->format), 0, PICT_FORMAT_R(source->format), PICT_FORMAT_G(source->format), PICT_FORMAT_B(source->format))))) || (op == PictOpOver && source->format == dest->format && !PICT_FORMAT_A(source->format))) && x_source >= 0 && y_source >= 0 && (x_source + width) <= source->pDrawable->width && (y_source + height) <= source->pDrawable->height) { x_source += source->pDrawable->x; y_source += source->pDrawable->y; x_dest += dest->pDrawable->x; y_dest += dest->pDrawable->y; glamor_copy(source->pDrawable, dest->pDrawable, NULL, box, nbox, x_source - x_dest, y_source - y_dest, FALSE, FALSE, 0, NULL); ok = TRUE; goto out; } /* XXX is it possible source mask have non-zero drawable.x/y? */ if (source && ((!source->pDrawable && (source->pSourcePict->type != SourcePictTypeSolidFill)) || (source->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) && (source_pixmap->drawable.width != width || source_pixmap->drawable.height != height)))) { temp_src = glamor_convert_gradient_picture(screen, source, extent->x1 + x_source - x_dest - dest->pDrawable->x, extent->y1 + y_source - y_dest - dest->pDrawable->y, width, height); if (!temp_src) { temp_src = source; goto out; } temp_src_pixmap = (PixmapPtr) (temp_src->pDrawable); temp_src_priv = glamor_get_pixmap_private(temp_src_pixmap); x_temp_src = -extent->x1 + x_dest + dest->pDrawable->x; y_temp_src = -extent->y1 + y_dest + dest->pDrawable->y; } if (mask && ((!mask->pDrawable && (mask->pSourcePict->type != SourcePictTypeSolidFill)) || (mask->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv) && (mask_pixmap->drawable.width != width || mask_pixmap->drawable.height != height)))) { /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity * to do reduce one conversion. */ temp_mask = glamor_convert_gradient_picture(screen, mask, extent->x1 + x_mask - x_dest - dest->pDrawable->x, extent->y1 + y_mask - y_dest - dest->pDrawable->y, width, height); if (!temp_mask) { temp_mask = mask; goto out; } temp_mask_pixmap = (PixmapPtr) (temp_mask->pDrawable); temp_mask_priv = glamor_get_pixmap_private(temp_mask_pixmap); x_temp_mask = -extent->x1 + x_dest + dest->pDrawable->x; y_temp_mask = -extent->y1 + y_dest + dest->pDrawable->y; } if (mask && mask->componentAlpha) { if (glamor_priv->has_dual_blend) { ca_state = CA_DUAL_BLEND; } else { if (op == PictOpOver) { if (glamor_pixmap_is_memory(mask_pixmap)) { glamor_fallback("two pass not supported on memory pximaps\n"); goto out; } ca_state = CA_TWO_PASS; op = PictOpOutReverse; } } } if (temp_src_pixmap == dest_pixmap) { glamor_fallback("source and dest pixmaps are the same\n"); goto out; } if (temp_mask_pixmap == dest_pixmap) { glamor_fallback("mask and dest pixmaps are the same\n"); goto out; } x_dest += dest->pDrawable->x; y_dest += dest->pDrawable->y; if (temp_src && temp_src->pDrawable) { x_temp_src += temp_src->pDrawable->x; y_temp_src += temp_src->pDrawable->y; } if (temp_mask && temp_mask->pDrawable) { x_temp_mask += temp_mask->pDrawable->x; y_temp_mask += temp_mask->pDrawable->y; } if (nbox > ARRAY_SIZE(rect)) { prect = calloc(nbox, sizeof(*prect)); if (prect) prect_size = nbox; else { prect = rect; prect_size = ARRAY_SIZE(rect); } } while (nbox) { int box_cnt; box_cnt = nbox > prect_size ? prect_size : nbox; for (i = 0; i < box_cnt; i++) { prect[i].x_src = box[i].x1 + x_temp_src - x_dest; prect[i].y_src = box[i].y1 + y_temp_src - y_dest; prect[i].x_mask = box[i].x1 + x_temp_mask - x_dest; prect[i].y_mask = box[i].y1 + y_temp_mask - y_dest; prect[i].x_dst = box[i].x1; prect[i].y_dst = box[i].y1; prect[i].width = box[i].x2 - box[i].x1; prect[i].height = box[i].y2 - box[i].y1; DEBUGF("dest %d %d \n", prect[i].x_dst, prect[i].y_dst); } ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest, temp_src_pixmap, temp_mask_pixmap, dest_pixmap, temp_src_priv, temp_mask_priv, dest_pixmap_priv, box_cnt, prect, ca_state); if (!ok) break; nbox -= box_cnt; box += box_cnt; } if (prect != rect) free(prect); out: if (temp_src != source) FreePicture(temp_src, 0); if (temp_mask != mask) FreePicture(temp_mask, 0); return ok; } void glamor_composite(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, INT16 x_source, INT16 y_source, INT16 x_mask, INT16 y_mask, INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height) { ScreenPtr screen = dest->pDrawable->pScreen; PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); RegionRec region; BoxPtr extent; int nbox, ok = FALSE; int force_clip = 0; if (source->pDrawable) { source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); if (glamor_pixmap_drm_only(source_pixmap)) goto fail; } if (mask && mask->pDrawable) { mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); if (glamor_pixmap_drm_only(mask_pixmap)) goto fail; } DEBUGF ("source pixmap %p (%d %d) mask(%d %d) dest(%d %d) width %d height %d \n", source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); if (!glamor_pixmap_has_fbo(dest_pixmap)) goto fail; if (op >= ARRAY_SIZE(composite_op_info)) { glamor_fallback("Unsupported composite op %x\n", op); goto fail; } if (mask && mask->componentAlpha && !glamor_priv->has_dual_blend) { if (op == PictOpAtop || op == PictOpAtopReverse || op == PictOpXor || op >= PictOpSaturate) { glamor_fallback("glamor_composite(): component alpha op %x\n", op); goto fail; } } if ((source && source->filter >= PictFilterConvolution) || (mask && mask->filter >= PictFilterConvolution)) { glamor_fallback("glamor_composite(): unsupported filter\n"); goto fail; } if (!miComputeCompositeRegion(®ion, source, mask, dest, x_source + (source_pixmap ? source->pDrawable->x : 0), y_source + (source_pixmap ? source->pDrawable->y : 0), x_mask + (mask_pixmap ? mask->pDrawable->x : 0), y_mask + (mask_pixmap ? mask->pDrawable->y : 0), x_dest + dest->pDrawable->x, y_dest + dest->pDrawable->y, width, height)) { return; } nbox = REGION_NUM_RECTS(®ion); DEBUGF("first clipped when compositing.\n"); DEBUGRegionPrint(®ion); extent = RegionExtents(®ion); if (nbox == 0) return; /* If destination is not a large pixmap, but the region is larger * than texture size limitation, and source or mask is memory pixmap, * then there may be need to load a large memory pixmap to a * texture, and this is not permitted. Then we force to clip the * destination and make sure latter will not upload a large memory * pixmap. */ if (!glamor_check_fbo_size(glamor_priv, extent->x2 - extent->x1, extent->y2 - extent->y1) && glamor_pixmap_is_large(dest_pixmap) && ((source_pixmap && (glamor_pixmap_is_memory(source_pixmap) || source->repeatType == RepeatPad)) || (mask_pixmap && (glamor_pixmap_is_memory(mask_pixmap) || mask->repeatType == RepeatPad)) || (!source_pixmap && (source->pSourcePict->type != SourcePictTypeSolidFill)) || (!mask_pixmap && mask && mask->pSourcePict->type != SourcePictTypeSolidFill))) force_clip = 1; if (force_clip || glamor_pixmap_is_large(dest_pixmap) || (source_pixmap && glamor_pixmap_is_large(source_pixmap)) || (mask_pixmap && glamor_pixmap_is_large(mask_pixmap))) ok = glamor_composite_largepixmap_region(op, source, mask, dest, source_pixmap, mask_pixmap, dest_pixmap, ®ion, force_clip, x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); else ok = glamor_composite_clipped_region(op, source, mask, dest, source_pixmap, mask_pixmap, dest_pixmap, ®ion, x_source, y_source, x_mask, y_mask, x_dest, y_dest); REGION_UNINIT(dest->pDrawable->pScreen, ®ion); if (ok) return; fail: glamor_fallback ("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c) to pict %p:%p %dx%d (%c)\n", source, source->pDrawable, source->pDrawable ? source->pDrawable->width : 0, source->pDrawable ? source->pDrawable->height : 0, mask, (!mask) ? NULL : mask->pDrawable, (!mask || !mask->pDrawable) ? 0 : mask->pDrawable->width, (!mask || !mask->pDrawable) ? 0 : mask->pDrawable->height, glamor_get_picture_location(source), glamor_get_picture_location(mask), dest, dest->pDrawable, dest->pDrawable->width, dest->pDrawable->height, glamor_get_picture_location(dest)); if (glamor_prepare_access_picture_box(dest, GLAMOR_ACCESS_RW, x_dest, y_dest, width, height) && glamor_prepare_access_picture_box(source, GLAMOR_ACCESS_RO, x_source, y_source, width, height) && glamor_prepare_access_picture_box(mask, GLAMOR_ACCESS_RO, x_mask, y_mask, width, height)) { fbComposite(op, source, mask, dest, x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); } glamor_finish_access_picture(mask); glamor_finish_access_picture(source); glamor_finish_access_picture(dest); } xorg-server-1.20.13/glamor/glamor_gradient.c0000644000175000017500000015511014100573756015660 00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Junyan He * */ /** @file glamor_gradient.c * * Gradient acceleration implementation */ #include "glamor_priv.h" #define LINEAR_SMALL_STOPS (6 + 2) #define LINEAR_LARGE_STOPS (16 + 2) #define RADIAL_SMALL_STOPS (6 + 2) #define RADIAL_LARGE_STOPS (16 + 2) static char * _glamor_create_getcolor_fs_source(ScreenPtr screen, int stops_count, int use_array) { char *gradient_fs = NULL; #define gradient_fs_getcolor\ GLAMOR_DEFAULT_PRECISION\ "uniform int n_stop;\n"\ "uniform float stops[%d];\n"\ "uniform vec4 stop_colors[%d];\n"\ "vec4 get_color(float stop_len)\n"\ "{\n"\ " int i = 0;\n"\ " vec4 stop_color_before;\n"\ " vec4 gradient_color;\n"\ " float stop_delta;\n"\ " float percentage; \n"\ " \n"\ " if(stop_len < stops[0])\n"\ " return vec4(0.0, 0.0, 0.0, 0.0); \n"\ " for(i = 1; i < n_stop; i++) {\n"\ " if(stop_len < stops[i])\n"\ " break; \n"\ " }\n"\ " if(i == n_stop)\n"\ " return vec4(0.0, 0.0, 0.0, 0.0); \n"\ " \n"\ " stop_color_before = stop_colors[i-1];\n"\ " stop_delta = stops[i] - stops[i-1];\n"\ " if(stop_delta > 2.0)\n"\ " percentage = 0.0;\n" /*For comply with pixman, walker->stepper overflow.*/\ " else if(stop_delta < 0.000001)\n"\ " percentage = 0.0;\n"\ " else \n"\ " percentage = (stop_len - stops[i-1])/stop_delta;\n"\ " \n"\ " gradient_color = stop_color_before;\n"\ " if(percentage != 0.0)\n"\ " gradient_color += (stop_colors[i] - gradient_color)*percentage;\n"\ " return vec4(gradient_color.rgb * gradient_color.a, gradient_color.a);\n"\ "}\n" /* Because the array access for shader is very slow, the performance is very low if use array. So use global uniform to replace for it if the number of n_stops is small. */ const char *gradient_fs_getcolor_no_array = GLAMOR_DEFAULT_PRECISION "uniform int n_stop;\n" "uniform float stop0;\n" "uniform float stop1;\n" "uniform float stop2;\n" "uniform float stop3;\n" "uniform float stop4;\n" "uniform float stop5;\n" "uniform float stop6;\n" "uniform float stop7;\n" "uniform vec4 stop_color0;\n" "uniform vec4 stop_color1;\n" "uniform vec4 stop_color2;\n" "uniform vec4 stop_color3;\n" "uniform vec4 stop_color4;\n" "uniform vec4 stop_color5;\n" "uniform vec4 stop_color6;\n" "uniform vec4 stop_color7;\n" "\n" "vec4 get_color(float stop_len)\n" "{\n" " vec4 stop_color_before;\n" " vec4 stop_color_after;\n" " vec4 gradient_color;\n" " float stop_before;\n" " float stop_delta;\n" " float percentage; \n" " \n" " if((stop_len < stop0) && (n_stop >= 1)) {\n" " stop_color_before = vec4(0.0, 0.0, 0.0, 0.0);\n" " stop_delta = 0.0;\n" " } else if((stop_len < stop1) && (n_stop >= 2)) {\n" " stop_color_before = stop_color0;\n" " stop_color_after = stop_color1;\n" " stop_before = stop0;\n" " stop_delta = stop1 - stop0;\n" " } else if((stop_len < stop2) && (n_stop >= 3)) {\n" " stop_color_before = stop_color1;\n" " stop_color_after = stop_color2;\n" " stop_before = stop1;\n" " stop_delta = stop2 - stop1;\n" " } else if((stop_len < stop3) && (n_stop >= 4)){\n" " stop_color_before = stop_color2;\n" " stop_color_after = stop_color3;\n" " stop_before = stop2;\n" " stop_delta = stop3 - stop2;\n" " } else if((stop_len < stop4) && (n_stop >= 5)){\n" " stop_color_before = stop_color3;\n" " stop_color_after = stop_color4;\n" " stop_before = stop3;\n" " stop_delta = stop4 - stop3;\n" " } else if((stop_len < stop5) && (n_stop >= 6)){\n" " stop_color_before = stop_color4;\n" " stop_color_after = stop_color5;\n" " stop_before = stop4;\n" " stop_delta = stop5 - stop4;\n" " } else if((stop_len < stop6) && (n_stop >= 7)){\n" " stop_color_before = stop_color5;\n" " stop_color_after = stop_color6;\n" " stop_before = stop5;\n" " stop_delta = stop6 - stop5;\n" " } else if((stop_len < stop7) && (n_stop >= 8)){\n" " stop_color_before = stop_color6;\n" " stop_color_after = stop_color7;\n" " stop_before = stop6;\n" " stop_delta = stop7 - stop6;\n" " } else {\n" " stop_color_before = vec4(0.0, 0.0, 0.0, 0.0);\n" " stop_delta = 0.0;\n" " }\n" " if(stop_delta > 2.0)\n" " percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow. " else if(stop_delta < 0.000001)\n" " percentage = 0.0;\n" " else\n" " percentage = (stop_len - stop_before)/stop_delta;\n" " \n" " gradient_color = stop_color_before;\n" " if(percentage != 0.0)\n" " gradient_color += (stop_color_after - gradient_color)*percentage;\n" " return vec4(gradient_color.rgb * gradient_color.a, gradient_color.a);\n" "}\n"; if (use_array) { XNFasprintf(&gradient_fs, gradient_fs_getcolor, stops_count, stops_count); return gradient_fs; } else { return XNFstrdup(gradient_fs_getcolor_no_array); } } static void _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen) { glamor_screen_private *glamor_priv; int index; GLint gradient_prog = 0; char *gradient_fs = NULL; GLint fs_prog, vs_prog; const char *gradient_vs = GLAMOR_DEFAULT_PRECISION "attribute vec4 v_position;\n" "attribute vec4 v_texcoord;\n" "varying vec2 source_texture;\n" "\n" "void main()\n" "{\n" " gl_Position = v_position;\n" " source_texture = v_texcoord.xy;\n" "}\n"; /* * Refer to pixman radial gradient. * * The problem is given the two circles of c1 and c2 with the radius of r1 and * r1, we need to caculate the t, which is used to do interpolate with stops, * using the fomula: * length((1-t)*c1 + t*c2 - p) = (1-t)*r1 + t*r2 * expand the fomula with xy coond, get the following: * sqrt(sqr((1-t)*c1.x + t*c2.x - p.x) + sqr((1-t)*c1.y + t*c2.y - p.y)) * = (1-t)r1 + t*r2 * <====> At*t- 2Bt + C = 0 * where A = sqr(c2.x - c1.x) + sqr(c2.y - c1.y) - sqr(r2 -r1) * B = (p.x - c1.x)*(c2.x - c1.x) + (p.y - c1.y)*(c2.y - c1.y) + r1*(r2 -r1) * C = sqr(p.x - c1.x) + sqr(p.y - c1.y) - r1*r1 * * solve the fomula and we get the result of * t = (B + sqrt(B*B - A*C)) / A or * t = (B - sqrt(B*B - A*C)) / A (quadratic equation have two solutions) * * The solution we are going to prefer is the bigger one, unless the * radius associated to it is negative (or it falls outside the valid t range) */ #define gradient_radial_fs_template\ GLAMOR_DEFAULT_PRECISION\ "uniform mat3 transform_mat;\n"\ "uniform int repeat_type;\n"\ "uniform float A_value;\n"\ "uniform vec2 c1;\n"\ "uniform float r1;\n"\ "uniform vec2 c2;\n"\ "uniform float r2;\n"\ "varying vec2 source_texture;\n"\ "\n"\ "vec4 get_color(float stop_len);\n"\ "\n"\ "int t_invalid;\n"\ "\n"\ "float get_stop_len()\n"\ "{\n"\ " float t = 0.0;\n"\ " float sqrt_value;\n"\ " t_invalid = 0;\n"\ " \n"\ " vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"\ " vec3 source_texture_trans = transform_mat * tmp;\n"\ " source_texture_trans.xy = source_texture_trans.xy/source_texture_trans.z;\n"\ " float B_value = (source_texture_trans.x - c1.x) * (c2.x - c1.x)\n"\ " + (source_texture_trans.y - c1.y) * (c2.y - c1.y)\n"\ " + r1 * (r2 - r1);\n"\ " float C_value = (source_texture_trans.x - c1.x) * (source_texture_trans.x - c1.x)\n"\ " + (source_texture_trans.y - c1.y) * (source_texture_trans.y - c1.y)\n"\ " - r1*r1;\n"\ " if(abs(A_value) < 0.00001) {\n"\ " if(B_value == 0.0) {\n"\ " t_invalid = 1;\n"\ " return t;\n"\ " }\n"\ " t = 0.5 * C_value / B_value;"\ " } else {\n"\ " sqrt_value = B_value * B_value - A_value * C_value;\n"\ " if(sqrt_value < 0.0) {\n"\ " t_invalid = 1;\n"\ " return t;\n"\ " }\n"\ " sqrt_value = sqrt(sqrt_value);\n"\ " t = (B_value + sqrt_value) / A_value;\n"\ " }\n"\ " if(repeat_type == %d) {\n" /* RepeatNone case. */\ " if((t <= 0.0) || (t > 1.0))\n"\ /* try another if first one invalid*/\ " t = (B_value - sqrt_value) / A_value;\n"\ " \n"\ " if((t <= 0.0) || (t > 1.0)) {\n" /*still invalid, return.*/\ " t_invalid = 1;\n"\ " return t;\n"\ " }\n"\ " } else {\n"\ " if(t * (r2 - r1) <= -1.0 * r1)\n"\ /* try another if first one invalid*/\ " t = (B_value - sqrt_value) / A_value;\n"\ " \n"\ " if(t * (r2 -r1) <= -1.0 * r1) {\n" /*still invalid, return.*/\ " t_invalid = 1;\n"\ " return t;\n"\ " }\n"\ " }\n"\ " \n"\ " if(repeat_type == %d){\n" /* repeat normal*/\ " t = fract(t);\n"\ " }\n"\ " \n"\ " if(repeat_type == %d) {\n" /* repeat reflect*/\ " t = abs(fract(t * 0.5 + 0.5) * 2.0 - 1.0);\n"\ " }\n"\ " \n"\ " return t;\n"\ "}\n"\ "\n"\ "void main()\n"\ "{\n"\ " float stop_len = get_stop_len();\n"\ " if(t_invalid == 1) {\n"\ " gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"\ " } else {\n"\ " gl_FragColor = get_color(stop_len);\n"\ " }\n"\ "}\n"\ "\n"\ "%s\n" /* fs_getcolor_source */ char *fs_getcolor_source; glamor_priv = glamor_get_screen_private(screen); if ((glamor_priv->radial_max_nstops >= stops_count) && (dyn_gen)) { /* Very Good, not to generate again. */ return; } glamor_make_current(glamor_priv); if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) { glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]); glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0; } gradient_prog = glCreateProgram(); vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, gradient_vs); fs_getcolor_source = _glamor_create_getcolor_fs_source(screen, stops_count, (stops_count > 0)); XNFasprintf(&gradient_fs, gradient_radial_fs_template, PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT, fs_getcolor_source); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs); free(gradient_fs); free(fs_getcolor_source); glAttachShader(gradient_prog, vs_prog); glAttachShader(gradient_prog, fs_prog); glDeleteShader(vs_prog); glDeleteShader(fs_prog); glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position"); glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord"); glamor_link_glsl_prog(screen, gradient_prog, "radial gradient"); if (dyn_gen) { index = 2; glamor_priv->radial_max_nstops = stops_count; } else if (stops_count) { index = 1; } else { index = 0; } glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog; } static void _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen) { glamor_screen_private *glamor_priv; int index = 0; GLint gradient_prog = 0; char *gradient_fs = NULL; GLint fs_prog, vs_prog; const char *gradient_vs = GLAMOR_DEFAULT_PRECISION "attribute vec4 v_position;\n" "attribute vec4 v_texcoord;\n" "varying vec2 source_texture;\n" "\n" "void main()\n" "{\n" " gl_Position = v_position;\n" " source_texture = v_texcoord.xy;\n" "}\n"; /* * | * |\ * | \ * | \ * | \ * |\ \ * | \ \ * cos_val = |\ p1d \ / * sqrt(1/(slope*slope+1.0)) ------>\ \ \ / * | \ \ \ * | \ \ / \ * | \ *Pt1\ * *p1 | \ \ *P * \ | / \ \ / * \ | / \ \ / * \ | pd \ * \ | \ / \ * p2* | \ / \ / * slope = (p2.y - p1.y) / | / p2d / * (p2.x - p1.x) | / \ / * | / \ / * | / / * | / / * | / *Pt2 * | / * | / * | / * | / * | / * -------+--------------------------------- * O| * | * | * * step 1: compute the distance of p, pt1 and pt2 in the slope direction. * Caculate the distance on Y axis first and multiply cos_val to * get the value on slope direction(pd, p1d and p2d represent the * distance of p, pt1, and pt2 respectively). * * step 2: caculate the percentage of (pd - p1d)/(p2d - p1d). * If (pd - p1d) > (p2d - p1d) or < 0, then sub or add (p2d - p1d) * to make it in the range of [0, (p2d - p1d)]. * * step 3: compare the percentage to every stop and find the stpos just * before and after it. Use the interpolation fomula to compute RGBA. */ #define gradient_fs_template \ GLAMOR_DEFAULT_PRECISION\ "uniform mat3 transform_mat;\n"\ "uniform int repeat_type;\n"\ "uniform int hor_ver;\n"\ "uniform float pt_slope;\n"\ "uniform float cos_val;\n"\ "uniform float p1_distance;\n"\ "uniform float pt_distance;\n"\ "varying vec2 source_texture;\n"\ "\n"\ "vec4 get_color(float stop_len);\n"\ "\n"\ "float get_stop_len()\n"\ "{\n"\ " vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"\ " float distance;\n"\ " float _p1_distance;\n"\ " float _pt_distance;\n"\ " float y_dist;\n"\ " vec3 source_texture_trans = transform_mat * tmp;\n"\ " \n"\ " if(hor_ver == 0) { \n" /*Normal case.*/\ " y_dist = source_texture_trans.y - source_texture_trans.x*pt_slope;\n"\ " distance = y_dist * cos_val;\n"\ " _p1_distance = p1_distance * source_texture_trans.z;\n"\ " _pt_distance = pt_distance * source_texture_trans.z;\n"\ " \n"\ " } else if (hor_ver == 1) {\n"/*horizontal case.*/\ " distance = source_texture_trans.x;\n"\ " _p1_distance = p1_distance * source_texture_trans.z;\n"\ " _pt_distance = pt_distance * source_texture_trans.z;\n"\ " } \n"\ " \n"\ " distance = (distance - _p1_distance) / _pt_distance;\n"\ " \n"\ " if(repeat_type == %d){\n" /* repeat normal*/\ " distance = fract(distance);\n"\ " }\n"\ " \n"\ " if(repeat_type == %d) {\n" /* repeat reflect*/\ " distance = abs(fract(distance * 0.5 + 0.5) * 2.0 - 1.0);\n"\ " }\n"\ " \n"\ " return distance;\n"\ "}\n"\ "\n"\ "void main()\n"\ "{\n"\ " float stop_len = get_stop_len();\n"\ " gl_FragColor = get_color(stop_len);\n"\ "}\n"\ "\n"\ "%s" /* fs_getcolor_source */ char *fs_getcolor_source; glamor_priv = glamor_get_screen_private(screen); if ((glamor_priv->linear_max_nstops >= stops_count) && (dyn_gen)) { /* Very Good, not to generate again. */ return; } glamor_make_current(glamor_priv); if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) { glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]); glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0; } gradient_prog = glCreateProgram(); vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, gradient_vs); fs_getcolor_source = _glamor_create_getcolor_fs_source(screen, stops_count, stops_count > 0); XNFasprintf(&gradient_fs, gradient_fs_template, PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT, fs_getcolor_source); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs); free(gradient_fs); free(fs_getcolor_source); glAttachShader(gradient_prog, vs_prog); glAttachShader(gradient_prog, fs_prog); glDeleteShader(vs_prog); glDeleteShader(fs_prog); glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position"); glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord"); glamor_link_glsl_prog(screen, gradient_prog, "linear gradient"); if (dyn_gen) { index = 2; glamor_priv->linear_max_nstops = stops_count; } else if (stops_count) { index = 1; } else { index = 0; } glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog; } void glamor_init_gradient_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv; int i; glamor_priv = glamor_get_screen_private(screen); for (i = 0; i < 3; i++) { glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i] = 0; glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i] = 0; } glamor_priv->linear_max_nstops = 0; glamor_priv->radial_max_nstops = 0; _glamor_create_linear_gradient_program(screen, 0, 0); _glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0); _glamor_create_radial_gradient_program(screen, 0, 0); _glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0); } static void _glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3], int width, int height, int normalize) { /* * Because in the shader program, we normalize all the pixel cood to [0, 1], * so with the transform matrix, the correct logic should be: * v_s = A*T*v * v_s: point vector in shader after normalized. * A: The transition matrix from width X height --> 1.0 X 1.0 * T: The transform matrix. * v: point vector in width X height space. * * result is OK if we use this fomula. But for every point in width X height space, * we can just use their normalized point vector in shader, namely we can just * use the result of A*v in shader. So we have no chance to insert T in A*v. * We can just convert v_s = A*T*v to v_s = A*T*inv(A)*A*v, where inv(A) is the * inverse matrix of A. Now, v_s = (A*T*inv(A)) * (A*v) * So, to get the correct v_s, we need to cacula1 the matrix: (A*T*inv(A)), and * we name this matrix T_s. * * Firstly, because A is for the scale conversion, we find * -- -- * |1/w 0 0 | * A = | 0 1/h 0 | * | 0 0 1.0| * -- -- * so T_s = A*T*inv(a) and result * * -- -- * | t11 h*t12/w t13/w| * T_s = | w*t21/h t22 t23/h| * | w*t31 h*t32 t33 | * -- -- */ to[0][0] = (float) pixman_fixed_to_double(from->matrix[0][0]); to[0][1] = (float) pixman_fixed_to_double(from->matrix[0][1]) * (normalize ? (((float) height) / ((float) width)) : 1.0); to[0][2] = (float) pixman_fixed_to_double(from->matrix[0][2]) / (normalize ? ((float) width) : 1.0); to[1][0] = (float) pixman_fixed_to_double(from->matrix[1][0]) * (normalize ? (((float) width) / ((float) height)) : 1.0); to[1][1] = (float) pixman_fixed_to_double(from->matrix[1][1]); to[1][2] = (float) pixman_fixed_to_double(from->matrix[1][2]) / (normalize ? ((float) height) : 1.0); to[2][0] = (float) pixman_fixed_to_double(from->matrix[2][0]) * (normalize ? ((float) width) : 1.0); to[2][1] = (float) pixman_fixed_to_double(from->matrix[2][1]) * (normalize ? ((float) height) : 1.0); to[2][2] = (float) pixman_fixed_to_double(from->matrix[2][2]); DEBUGF("the transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n", to[0][0], to[0][1], to[0][2], to[1][0], to[1][1], to[1][2], to[2][0], to[2][1], to[2][2]); } static int _glamor_gradient_set_pixmap_destination(ScreenPtr screen, glamor_screen_private *glamor_priv, PicturePtr dst_picture, GLfloat *xscale, GLfloat *yscale, int x_source, int y_source, int tex_normalize) { glamor_pixmap_private *pixmap_priv; PixmapPtr pixmap = NULL; GLfloat *v; char *vbo_offset; pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable); pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */ return 0; } glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv); pixmap_priv_get_dest_scale(pixmap, pixmap_priv, xscale, yscale); DEBUGF("xscale = %f, yscale = %f," " x_source = %d, y_source = %d, width = %d, height = %d\n", *xscale, *yscale, x_source, y_source, dst_picture->pDrawable->width, dst_picture->pDrawable->height); v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat), &vbo_offset); glamor_set_normalize_vcoords_tri_strip(*xscale, *yscale, 0, 0, (INT16) (dst_picture->pDrawable-> width), (INT16) (dst_picture->pDrawable-> height), v); if (tex_normalize) { glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale, x_source, y_source, (INT16) (dst_picture-> pDrawable->width + x_source), (INT16) (dst_picture-> pDrawable->height + y_source), &v[8]); } else { glamor_set_tcoords_tri_strip(x_source, y_source, (INT16) (dst_picture->pDrawable->width) + x_source, (INT16) (dst_picture->pDrawable->height) + y_source, &v[8]); } DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f," "rightbottom: %f X %f, leftbottom : %f X %f\n", v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f," "rightbottom: %f X %f, leftbottom : %f X %f\n", v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]); glamor_make_current(glamor_priv); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 0, vbo_offset); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 0, vbo_offset + 8 * sizeof(GLfloat)); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glamor_put_vbo_space(screen); return 1; } static int _glamor_gradient_set_stops(PicturePtr src_picture, PictGradient *pgradient, GLfloat *stop_colors, GLfloat *n_stops) { int i; int count = 1; for (i = 0; i < pgradient->nstops; i++) { stop_colors[count * 4] = pixman_fixed_to_double(pgradient->stops[i].color.red); stop_colors[count * 4 + 1] = pixman_fixed_to_double(pgradient->stops[i].color.green); stop_colors[count * 4 + 2] = pixman_fixed_to_double(pgradient->stops[i].color.blue); stop_colors[count * 4 + 3] = pixman_fixed_to_double(pgradient->stops[i].color.alpha); n_stops[count] = (GLfloat) pixman_fixed_to_double(pgradient->stops[i].x); count++; } /* for the end stop. */ count++; switch (src_picture->repeatType) { #define REPEAT_FILL_STOPS(m, n) \ stop_colors[(m)*4 + 0] = stop_colors[(n)*4 + 0]; \ stop_colors[(m)*4 + 1] = stop_colors[(n)*4 + 1]; \ stop_colors[(m)*4 + 2] = stop_colors[(n)*4 + 2]; \ stop_colors[(m)*4 + 3] = stop_colors[(n)*4 + 3]; default: case PIXMAN_REPEAT_NONE: stop_colors[0] = 0.0; //R stop_colors[1] = 0.0; //G stop_colors[2] = 0.0; //B stop_colors[3] = 0.0; //Alpha n_stops[0] = n_stops[1]; stop_colors[0 + (count - 1) * 4] = 0.0; //R stop_colors[1 + (count - 1) * 4] = 0.0; //G stop_colors[2 + (count - 1) * 4] = 0.0; //B stop_colors[3 + (count - 1) * 4] = 0.0; //Alpha n_stops[count - 1] = n_stops[count - 2]; break; case PIXMAN_REPEAT_NORMAL: REPEAT_FILL_STOPS(0, count - 2); n_stops[0] = n_stops[count - 2] - 1.0; REPEAT_FILL_STOPS(count - 1, 1); n_stops[count - 1] = n_stops[1] + 1.0; break; case PIXMAN_REPEAT_REFLECT: REPEAT_FILL_STOPS(0, 1); n_stops[0] = -n_stops[1]; REPEAT_FILL_STOPS(count - 1, count - 2); n_stops[count - 1] = 1.0 + 1.0 - n_stops[count - 2]; break; case PIXMAN_REPEAT_PAD: REPEAT_FILL_STOPS(0, 1); n_stops[0] = -(float) INT_MAX; REPEAT_FILL_STOPS(count - 1, count - 2); n_stops[count - 1] = (float) INT_MAX; break; #undef REPEAT_FILL_STOPS } for (i = 0; i < count; i++) { DEBUGF("n_stops[%d] = %f, color = r:%f g:%f b:%f a:%f\n", i, n_stops[i], stop_colors[i * 4], stop_colors[i * 4 + 1], stop_colors[i * 4 + 2], stop_colors[i * 4 + 3]); } return count; } PicturePtr glamor_generate_radial_gradient_picture(ScreenPtr screen, PicturePtr src_picture, int x_source, int y_source, int width, int height, PictFormatShort format) { glamor_screen_private *glamor_priv; PicturePtr dst_picture = NULL; PixmapPtr pixmap = NULL; GLint gradient_prog = 0; int error; int stops_count = 0; int count = 0; GLfloat *stop_colors = NULL; GLfloat *n_stops = NULL; GLfloat xscale, yscale; float transform_mat[3][3]; static const float identity_mat[3][3] = { {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0} }; GLfloat stop_colors_st[RADIAL_SMALL_STOPS * 4]; GLfloat n_stops_st[RADIAL_SMALL_STOPS]; GLfloat A_value; GLfloat cxy[4]; float c1x, c1y, c2x, c2y, r1, r2; GLint transform_mat_uniform_location = 0; GLint repeat_type_uniform_location = 0; GLint n_stop_uniform_location = 0; GLint stops_uniform_location = 0; GLint stop_colors_uniform_location = 0; GLint stop0_uniform_location = 0; GLint stop1_uniform_location = 0; GLint stop2_uniform_location = 0; GLint stop3_uniform_location = 0; GLint stop4_uniform_location = 0; GLint stop5_uniform_location = 0; GLint stop6_uniform_location = 0; GLint stop7_uniform_location = 0; GLint stop_color0_uniform_location = 0; GLint stop_color1_uniform_location = 0; GLint stop_color2_uniform_location = 0; GLint stop_color3_uniform_location = 0; GLint stop_color4_uniform_location = 0; GLint stop_color5_uniform_location = 0; GLint stop_color6_uniform_location = 0; GLint stop_color7_uniform_location = 0; GLint A_value_uniform_location = 0; GLint c1_uniform_location = 0; GLint r1_uniform_location = 0; GLint c2_uniform_location = 0; GLint r2_uniform_location = 0; glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); /* Create a pixmap with VBO. */ pixmap = glamor_create_pixmap(screen, width, height, PIXMAN_FORMAT_DEPTH(format), 0); if (!pixmap) goto GRADIENT_FAIL; dst_picture = CreatePicture(0, &pixmap->drawable, PictureMatchFormat(screen, PIXMAN_FORMAT_DEPTH(format), format), 0, 0, serverClient, &error); /* Release the reference, picture will hold the last one. */ glamor_destroy_pixmap(pixmap); if (!dst_picture) goto GRADIENT_FAIL; ValidatePicture(dst_picture); stops_count = src_picture->pSourcePict->radial.nstops + 2; /* Because the max value of nstops is unknown, so create a program when nstops > LINEAR_LARGE_STOPS. */ if (stops_count <= RADIAL_SMALL_STOPS) { gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][0]; } else if (stops_count <= RADIAL_LARGE_STOPS) { gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][1]; } else { _glamor_create_radial_gradient_program(screen, src_picture->pSourcePict->linear. nstops + 2, 1); gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]; } /* Bind all the uniform vars . */ transform_mat_uniform_location = glGetUniformLocation(gradient_prog, "transform_mat"); repeat_type_uniform_location = glGetUniformLocation(gradient_prog, "repeat_type"); n_stop_uniform_location = glGetUniformLocation(gradient_prog, "n_stop"); A_value_uniform_location = glGetUniformLocation(gradient_prog, "A_value"); c1_uniform_location = glGetUniformLocation(gradient_prog, "c1"); r1_uniform_location = glGetUniformLocation(gradient_prog, "r1"); c2_uniform_location = glGetUniformLocation(gradient_prog, "c2"); r2_uniform_location = glGetUniformLocation(gradient_prog, "r2"); if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_SMALL_STOPS) { stop0_uniform_location = glGetUniformLocation(gradient_prog, "stop0"); stop1_uniform_location = glGetUniformLocation(gradient_prog, "stop1"); stop2_uniform_location = glGetUniformLocation(gradient_prog, "stop2"); stop3_uniform_location = glGetUniformLocation(gradient_prog, "stop3"); stop4_uniform_location = glGetUniformLocation(gradient_prog, "stop4"); stop5_uniform_location = glGetUniformLocation(gradient_prog, "stop5"); stop6_uniform_location = glGetUniformLocation(gradient_prog, "stop6"); stop7_uniform_location = glGetUniformLocation(gradient_prog, "stop7"); stop_color0_uniform_location = glGetUniformLocation(gradient_prog, "stop_color0"); stop_color1_uniform_location = glGetUniformLocation(gradient_prog, "stop_color1"); stop_color2_uniform_location = glGetUniformLocation(gradient_prog, "stop_color2"); stop_color3_uniform_location = glGetUniformLocation(gradient_prog, "stop_color3"); stop_color4_uniform_location = glGetUniformLocation(gradient_prog, "stop_color4"); stop_color5_uniform_location = glGetUniformLocation(gradient_prog, "stop_color5"); stop_color6_uniform_location = glGetUniformLocation(gradient_prog, "stop_color6"); stop_color7_uniform_location = glGetUniformLocation(gradient_prog, "stop_color7"); } else { stops_uniform_location = glGetUniformLocation(gradient_prog, "stops"); stop_colors_uniform_location = glGetUniformLocation(gradient_prog, "stop_colors"); } glUseProgram(gradient_prog); glUniform1i(repeat_type_uniform_location, src_picture->repeatType); if (src_picture->transform) { _glamor_gradient_convert_trans_matrix(src_picture->transform, transform_mat, width, height, 0); glUniformMatrix3fv(transform_mat_uniform_location, 1, 1, &transform_mat[0][0]); } else { glUniformMatrix3fv(transform_mat_uniform_location, 1, 1, &identity_mat[0][0]); } if (!_glamor_gradient_set_pixmap_destination (screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source, 0)) goto GRADIENT_FAIL; glamor_set_alu(screen, GXcopy); /* Set all the stops and colors to shader. */ if (stops_count > RADIAL_SMALL_STOPS) { stop_colors = xallocarray(stops_count, 4 * sizeof(float)); if (stop_colors == NULL) { ErrorF("Failed to allocate stop_colors memory.\n"); goto GRADIENT_FAIL; } n_stops = xallocarray(stops_count, sizeof(float)); if (n_stops == NULL) { ErrorF("Failed to allocate n_stops memory.\n"); goto GRADIENT_FAIL; } } else { stop_colors = stop_colors_st; n_stops = n_stops_st; } count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient, stop_colors, n_stops); if (src_picture->pSourcePict->linear.nstops + 2 <= RADIAL_SMALL_STOPS) { int j = 0; glUniform4f(stop_color0_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color1_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color2_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color3_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color4_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color5_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color6_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color7_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j = 0; glUniform1f(stop0_uniform_location, n_stops[j++]); glUniform1f(stop1_uniform_location, n_stops[j++]); glUniform1f(stop2_uniform_location, n_stops[j++]); glUniform1f(stop3_uniform_location, n_stops[j++]); glUniform1f(stop4_uniform_location, n_stops[j++]); glUniform1f(stop5_uniform_location, n_stops[j++]); glUniform1f(stop6_uniform_location, n_stops[j++]); glUniform1f(stop7_uniform_location, n_stops[j++]); glUniform1i(n_stop_uniform_location, count); } else { glUniform4fv(stop_colors_uniform_location, count, stop_colors); glUniform1fv(stops_uniform_location, count, n_stops); glUniform1i(n_stop_uniform_location, count); } c1x = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.x); c1y = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.y); c2x = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.x); c2y = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.y); r1 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c1. radius); r2 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2. radius); glamor_set_circle_centre(width, height, c1x, c1y, cxy); glUniform2fv(c1_uniform_location, 1, cxy); glUniform1f(r1_uniform_location, r1); glamor_set_circle_centre(width, height, c2x, c2y, cxy); glUniform2fv(c2_uniform_location, 1, cxy); glUniform1f(r2_uniform_location, r2); A_value = (c2x - c1x) * (c2x - c1x) + (c2y - c1y) * (c2y - c1y) - (r2 - r1) * (r2 - r1); glUniform1f(A_value_uniform_location, A_value); DEBUGF("C1:(%f, %f) R1:%f\nC2:(%f, %f) R2:%f\nA = %f\n", c1x, c1y, r1, c2x, c2y, r2, A_value); /* Now rendering. */ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); /* Do the clear logic. */ if (stops_count > RADIAL_SMALL_STOPS) { free(n_stops); free(stop_colors); } glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); return dst_picture; GRADIENT_FAIL: if (dst_picture) { FreePicture(dst_picture, 0); } if (stops_count > RADIAL_SMALL_STOPS) { if (n_stops) free(n_stops); if (stop_colors) free(stop_colors); } glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); return NULL; } PicturePtr glamor_generate_linear_gradient_picture(ScreenPtr screen, PicturePtr src_picture, int x_source, int y_source, int width, int height, PictFormatShort format) { glamor_screen_private *glamor_priv; PicturePtr dst_picture = NULL; PixmapPtr pixmap = NULL; GLint gradient_prog = 0; int error; float pt_distance; float p1_distance; GLfloat cos_val; int stops_count = 0; GLfloat *stop_colors = NULL; GLfloat *n_stops = NULL; int count = 0; float slope; GLfloat xscale, yscale; GLfloat pt1[2], pt2[2]; float transform_mat[3][3]; static const float identity_mat[3][3] = { {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0} }; GLfloat stop_colors_st[LINEAR_SMALL_STOPS * 4]; GLfloat n_stops_st[LINEAR_SMALL_STOPS]; GLint transform_mat_uniform_location = 0; GLint n_stop_uniform_location = 0; GLint stops_uniform_location = 0; GLint stop0_uniform_location = 0; GLint stop1_uniform_location = 0; GLint stop2_uniform_location = 0; GLint stop3_uniform_location = 0; GLint stop4_uniform_location = 0; GLint stop5_uniform_location = 0; GLint stop6_uniform_location = 0; GLint stop7_uniform_location = 0; GLint stop_colors_uniform_location = 0; GLint stop_color0_uniform_location = 0; GLint stop_color1_uniform_location = 0; GLint stop_color2_uniform_location = 0; GLint stop_color3_uniform_location = 0; GLint stop_color4_uniform_location = 0; GLint stop_color5_uniform_location = 0; GLint stop_color6_uniform_location = 0; GLint stop_color7_uniform_location = 0; GLint pt_slope_uniform_location = 0; GLint repeat_type_uniform_location = 0; GLint hor_ver_uniform_location = 0; GLint cos_val_uniform_location = 0; GLint p1_distance_uniform_location = 0; GLint pt_distance_uniform_location = 0; glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); /* Create a pixmap with VBO. */ pixmap = glamor_create_pixmap(screen, width, height, PIXMAN_FORMAT_DEPTH(format), 0); if (!pixmap) goto GRADIENT_FAIL; dst_picture = CreatePicture(0, &pixmap->drawable, PictureMatchFormat(screen, PIXMAN_FORMAT_DEPTH(format), format), 0, 0, serverClient, &error); /* Release the reference, picture will hold the last one. */ glamor_destroy_pixmap(pixmap); if (!dst_picture) goto GRADIENT_FAIL; ValidatePicture(dst_picture); stops_count = src_picture->pSourcePict->linear.nstops + 2; /* Because the max value of nstops is unknown, so create a program when nstops > LINEAR_LARGE_STOPS. */ if (stops_count <= LINEAR_SMALL_STOPS) { gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][0]; } else if (stops_count <= LINEAR_LARGE_STOPS) { gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][1]; } else { _glamor_create_linear_gradient_program(screen, src_picture->pSourcePict->linear. nstops + 2, 1); gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]; } /* Bind all the uniform vars . */ n_stop_uniform_location = glGetUniformLocation(gradient_prog, "n_stop"); pt_slope_uniform_location = glGetUniformLocation(gradient_prog, "pt_slope"); repeat_type_uniform_location = glGetUniformLocation(gradient_prog, "repeat_type"); hor_ver_uniform_location = glGetUniformLocation(gradient_prog, "hor_ver"); transform_mat_uniform_location = glGetUniformLocation(gradient_prog, "transform_mat"); cos_val_uniform_location = glGetUniformLocation(gradient_prog, "cos_val"); p1_distance_uniform_location = glGetUniformLocation(gradient_prog, "p1_distance"); pt_distance_uniform_location = glGetUniformLocation(gradient_prog, "pt_distance"); if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) { stop0_uniform_location = glGetUniformLocation(gradient_prog, "stop0"); stop1_uniform_location = glGetUniformLocation(gradient_prog, "stop1"); stop2_uniform_location = glGetUniformLocation(gradient_prog, "stop2"); stop3_uniform_location = glGetUniformLocation(gradient_prog, "stop3"); stop4_uniform_location = glGetUniformLocation(gradient_prog, "stop4"); stop5_uniform_location = glGetUniformLocation(gradient_prog, "stop5"); stop6_uniform_location = glGetUniformLocation(gradient_prog, "stop6"); stop7_uniform_location = glGetUniformLocation(gradient_prog, "stop7"); stop_color0_uniform_location = glGetUniformLocation(gradient_prog, "stop_color0"); stop_color1_uniform_location = glGetUniformLocation(gradient_prog, "stop_color1"); stop_color2_uniform_location = glGetUniformLocation(gradient_prog, "stop_color2"); stop_color3_uniform_location = glGetUniformLocation(gradient_prog, "stop_color3"); stop_color4_uniform_location = glGetUniformLocation(gradient_prog, "stop_color4"); stop_color5_uniform_location = glGetUniformLocation(gradient_prog, "stop_color5"); stop_color6_uniform_location = glGetUniformLocation(gradient_prog, "stop_color6"); stop_color7_uniform_location = glGetUniformLocation(gradient_prog, "stop_color7"); } else { stops_uniform_location = glGetUniformLocation(gradient_prog, "stops"); stop_colors_uniform_location = glGetUniformLocation(gradient_prog, "stop_colors"); } glUseProgram(gradient_prog); glUniform1i(repeat_type_uniform_location, src_picture->repeatType); /* set the transform matrix. */ if (src_picture->transform) { _glamor_gradient_convert_trans_matrix(src_picture->transform, transform_mat, width, height, 1); glUniformMatrix3fv(transform_mat_uniform_location, 1, 1, &transform_mat[0][0]); } else { glUniformMatrix3fv(transform_mat_uniform_location, 1, 1, &identity_mat[0][0]); } if (!_glamor_gradient_set_pixmap_destination (screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source, 1)) goto GRADIENT_FAIL; glamor_set_alu(screen, GXcopy); /* Normalize the PTs. */ glamor_set_normalize_pt(xscale, yscale, pixman_fixed_to_double(src_picture->pSourcePict-> linear.p1.x), pixman_fixed_to_double(src_picture->pSourcePict-> linear.p1.y), pt1); DEBUGF("pt1:(%f, %f) ---> (%f %f)\n", pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x), pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y), pt1[0], pt1[1]); glamor_set_normalize_pt(xscale, yscale, pixman_fixed_to_double(src_picture->pSourcePict-> linear.p2.x), pixman_fixed_to_double(src_picture->pSourcePict-> linear.p2.y), pt2); DEBUGF("pt2:(%f, %f) ---> (%f %f)\n", pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x), pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y), pt2[0], pt2[1]); /* Set all the stops and colors to shader. */ if (stops_count > LINEAR_SMALL_STOPS) { stop_colors = xallocarray(stops_count, 4 * sizeof(float)); if (stop_colors == NULL) { ErrorF("Failed to allocate stop_colors memory.\n"); goto GRADIENT_FAIL; } n_stops = xallocarray(stops_count, sizeof(float)); if (n_stops == NULL) { ErrorF("Failed to allocate n_stops memory.\n"); goto GRADIENT_FAIL; } } else { stop_colors = stop_colors_st; n_stops = n_stops_st; } count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient, stop_colors, n_stops); if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) { int j = 0; glUniform4f(stop_color0_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color1_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color2_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color3_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color4_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color5_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color6_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j++; glUniform4f(stop_color7_uniform_location, stop_colors[4 * j + 0], stop_colors[4 * j + 1], stop_colors[4 * j + 2], stop_colors[4 * j + 3]); j = 0; glUniform1f(stop0_uniform_location, n_stops[j++]); glUniform1f(stop1_uniform_location, n_stops[j++]); glUniform1f(stop2_uniform_location, n_stops[j++]); glUniform1f(stop3_uniform_location, n_stops[j++]); glUniform1f(stop4_uniform_location, n_stops[j++]); glUniform1f(stop5_uniform_location, n_stops[j++]); glUniform1f(stop6_uniform_location, n_stops[j++]); glUniform1f(stop7_uniform_location, n_stops[j++]); glUniform1i(n_stop_uniform_location, count); } else { glUniform4fv(stop_colors_uniform_location, count, stop_colors); glUniform1fv(stops_uniform_location, count, n_stops); glUniform1i(n_stop_uniform_location, count); } if (src_picture->pSourcePict->linear.p2.y == src_picture->pSourcePict->linear.p1.y) { // The horizontal case. glUniform1i(hor_ver_uniform_location, 1); DEBUGF("p1.y: %f, p2.y: %f, enter the horizontal case\n", pt1[1], pt2[1]); p1_distance = pt1[0]; pt_distance = (pt2[0] - p1_distance); glUniform1f(p1_distance_uniform_location, p1_distance); glUniform1f(pt_distance_uniform_location, pt_distance); } else { /* The slope need to compute here. In shader, the viewport set will change the original slope and the slope which is vertical to it will not be correct. */ slope = -(float) (src_picture->pSourcePict->linear.p2.x - src_picture->pSourcePict->linear.p1.x) / (float) (src_picture->pSourcePict->linear.p2.y - src_picture->pSourcePict->linear.p1.y); slope = slope * yscale / xscale; glUniform1f(pt_slope_uniform_location, slope); glUniform1i(hor_ver_uniform_location, 0); cos_val = sqrt(1.0 / (slope * slope + 1.0)); glUniform1f(cos_val_uniform_location, cos_val); p1_distance = (pt1[1] - pt1[0] * slope) * cos_val; pt_distance = (pt2[1] - pt2[0] * slope) * cos_val - p1_distance; glUniform1f(p1_distance_uniform_location, p1_distance); glUniform1f(pt_distance_uniform_location, pt_distance); } /* Now rendering. */ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); /* Do the clear logic. */ if (stops_count > LINEAR_SMALL_STOPS) { free(n_stops); free(stop_colors); } glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); return dst_picture; GRADIENT_FAIL: if (dst_picture) { FreePicture(dst_picture, 0); } if (stops_count > LINEAR_SMALL_STOPS) { if (n_stops) free(n_stops); if (stop_colors) free(stop_colors); } glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); return NULL; } xorg-server-1.20.13/glamor/glamor_prepare.c0000644000175000017500000002256714100573756015532 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_prepare.h" #include "glamor_transfer.h" /* * Make a pixmap ready to draw with fb by * creating a PBO large enough for the whole object * and downloading all of the FBOs into it. */ static Bool glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); int gl_access, gl_usage; RegionRec region; if (priv->type == GLAMOR_DRM_ONLY) return FALSE; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) return TRUE; glamor_make_current(glamor_priv); RegionInit(®ion, box, 1); /* See if it's already mapped */ if (pixmap->devPrivate.ptr) { /* * Someone else has mapped this pixmap; * we'll assume that it's directly mapped * by a lower level driver */ if (!priv->prepared) return TRUE; /* In X, multiple Drawables can be stored in the same Pixmap (such as * each individual window in a non-composited screen pixmap, or the * reparented window contents inside the window-manager-decorated window * pixmap on a composited screen). * * As a result, when doing a series of mappings for a fallback, we may * need to add more boxes to the set of data we've downloaded, as we go. */ RegionSubtract(®ion, ®ion, &priv->prepare_region); if (!RegionNotEmpty(®ion)) return TRUE; if (access == GLAMOR_ACCESS_RW) FatalError("attempt to remap buffer as writable"); if (priv->pbo) { glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); pixmap->devPrivate.ptr = NULL; } } else { RegionInit(&priv->prepare_region, box, 1); if (glamor_priv->has_rw_pbo) { if (priv->pbo == 0) glGenBuffers(1, &priv->pbo); gl_usage = GL_STREAM_READ; glamor_priv->suppress_gl_out_of_memory_logging = true; glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo); glBufferData(GL_PIXEL_PACK_BUFFER, pixmap->devKind * pixmap->drawable.height, NULL, gl_usage); glamor_priv->suppress_gl_out_of_memory_logging = false; if (glGetError() == GL_OUT_OF_MEMORY) { if (!glamor_priv->logged_any_pbo_allocation_failure) { LogMessageVerb(X_WARNING, 0, "glamor: Failed to allocate %d " "bytes PBO due to GL_OUT_OF_MEMORY.\n", pixmap->devKind * pixmap->drawable.height); glamor_priv->logged_any_pbo_allocation_failure = true; } glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); glDeleteBuffers(1, &priv->pbo); priv->pbo = 0; } } if (!priv->pbo) { pixmap->devPrivate.ptr = xallocarray(pixmap->devKind, pixmap->drawable.height); if (!pixmap->devPrivate.ptr) return FALSE; } priv->map_access = access; } glamor_download_boxes(pixmap, RegionRects(®ion), RegionNumRects(®ion), 0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind); RegionUninit(®ion); if (priv->pbo) { if (priv->map_access == GLAMOR_ACCESS_RW) gl_access = GL_READ_WRITE; else gl_access = GL_READ_ONLY; pixmap->devPrivate.ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); } priv->prepared = TRUE; return TRUE; } /* * When we're done with the drawable, unmap the PBO, reupload * if we were writing to it and then unbind it to release the memory */ static void glamor_fini_pixmap(PixmapPtr pixmap) { glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) return; if (!priv->prepared) return; if (priv->pbo) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->pbo); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); pixmap->devPrivate.ptr = NULL; } if (priv->map_access == GLAMOR_ACCESS_RW) { glamor_upload_boxes(pixmap, RegionRects(&priv->prepare_region), RegionNumRects(&priv->prepare_region), 0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind); } RegionUninit(&priv->prepare_region); if (priv->pbo) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glDeleteBuffers(1, &priv->pbo); priv->pbo = 0; } else { free(pixmap->devPrivate.ptr); pixmap->devPrivate.ptr = NULL; } priv->prepared = FALSE; } Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); BoxRec box; int off_x, off_y; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); box.x1 = drawable->x + off_x; box.x2 = box.x1 + drawable->width; box.y1 = drawable->y + off_y; box.y2 = box.y1 + drawable->height; return glamor_prep_pixmap_box(pixmap, access, &box); } Bool glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access, int x, int y, int w, int h) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); BoxRec box; int off_x, off_y; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); box.x1 = drawable->x + x + off_x; box.x2 = box.x1 + w; box.y1 = drawable->y + y + off_y; box.y2 = box.y1 + h; return glamor_prep_pixmap_box(pixmap, access, &box); } void glamor_finish_access(DrawablePtr drawable) { glamor_fini_pixmap(glamor_get_drawable_pixmap(drawable)); } /* * Make a picture ready to use with fb. */ Bool glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access) { if (!picture || !picture->pDrawable) return TRUE; return glamor_prepare_access(picture->pDrawable, access); } Bool glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access, int x, int y, int w, int h) { if (!picture || !picture->pDrawable) return TRUE; /* If a transform is set, we don't know what the bounds is on the * source, so just prepare the whole pixmap. XXX: We could * potentially work out where in the source would be sampled based * on the transform, and we don't need do do this for destination * pixmaps at all. */ if (picture->transform) { return glamor_prepare_access_box(picture->pDrawable, access, 0, 0, picture->pDrawable->width, picture->pDrawable->height); } else { return glamor_prepare_access_box(picture->pDrawable, access, x, y, w, h); } } void glamor_finish_access_picture(PicturePtr picture) { if (!picture || !picture->pDrawable) return; glamor_finish_access(picture->pDrawable); } /* * Make a GC ready to use with fb. This just * means making sure the appropriate fill pixmap is * in CPU memory again */ Bool glamor_prepare_access_gc(GCPtr gc) { switch (gc->fillStyle) { case FillTiled: return glamor_prepare_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO); case FillStippled: case FillOpaqueStippled: return glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO); } return TRUE; } /* * Free any temporary CPU pixmaps for the GC */ void glamor_finish_access_gc(GCPtr gc) { switch (gc->fillStyle) { case FillTiled: glamor_finish_access(&gc->tile.pixmap->drawable); break; case FillStippled: case FillOpaqueStippled: glamor_finish_access(&gc->stipple->drawable); break; } } xorg-server-1.20.13/glamor/glamor_prepare.h0000644000175000017500000000354414100573756015531 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _GLAMOR_PREPARE_H_ #define _GLAMOR_PREPARE_H_ Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); Bool glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access, int x, int y, int w, int h); void glamor_finish_access(DrawablePtr drawable); Bool glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access); Bool glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access, int x, int y, int w, int h); void glamor_finish_access_picture(PicturePtr picture); Bool glamor_prepare_access_gc(GCPtr gc); void glamor_finish_access_gc(GCPtr gc); #endif /* _GLAMOR_PREPARE_H_ */ xorg-server-1.20.13/glamor/glamor_program.c0000644000175000017500000005445514100573756015544 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_transform.h" #include "glamor_program.h" static Bool use_solid(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) { return glamor_set_solid(pixmap, gc, TRUE, prog->fg_uniform); } const glamor_facet glamor_fill_solid = { .name = "solid", .fs_exec = " gl_FragColor = fg;\n", .locations = glamor_program_location_fg, .use = use_solid, }; static Bool use_tile(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) { return glamor_set_tiled(pixmap, gc, prog->fill_offset_uniform, prog->fill_size_inv_uniform); } static const glamor_facet glamor_fill_tile = { .name = "tile", .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n", .fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n", .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos, .use = use_tile, }; static Bool use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) { return glamor_set_stippled(pixmap, gc, prog->fg_uniform, prog->fill_offset_uniform, prog->fill_size_inv_uniform); } static const glamor_facet glamor_fill_stipple = { .name = "stipple", .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n", .fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n" " if (a == 0.0)\n" " discard;\n" " gl_FragColor = fg;\n"), .locations = glamor_program_location_fg | glamor_program_location_fillsamp | glamor_program_location_fillpos, .use = use_stipple, }; static Bool use_opaque_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) { if (!use_stipple(pixmap, gc, prog, arg)) return FALSE; glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform); return TRUE; } static const glamor_facet glamor_fill_opaque_stipple = { .name = "opaque_stipple", .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n", .fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n" " if (a == 0.0)\n" " gl_FragColor = bg;\n" " else\n" " gl_FragColor = fg;\n"), .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fillsamp | glamor_program_location_fillpos, .use = use_opaque_stipple }; static const glamor_facet *glamor_facet_fill[4] = { &glamor_fill_solid, &glamor_fill_tile, &glamor_fill_stipple, &glamor_fill_opaque_stipple, }; typedef struct { glamor_program_location location; const char *vs_vars; const char *fs_vars; } glamor_location_var; static glamor_location_var location_vars[] = { { .location = glamor_program_location_fg, .fs_vars = "uniform vec4 fg;\n" }, { .location = glamor_program_location_bg, .fs_vars = "uniform vec4 bg;\n" }, { .location = glamor_program_location_fillsamp, .fs_vars = "uniform sampler2D sampler;\n" }, { .location = glamor_program_location_fillpos, .vs_vars = ("uniform vec2 fill_offset;\n" "uniform vec2 fill_size_inv;\n" "varying vec2 fill_pos;\n"), .fs_vars = ("varying vec2 fill_pos;\n") }, { .location = glamor_program_location_font, .fs_vars = "uniform usampler2D font;\n", }, { .location = glamor_program_location_bitplane, .fs_vars = ("uniform uvec4 bitplane;\n" "uniform vec4 bitmul;\n"), }, { .location = glamor_program_location_dash, .vs_vars = "uniform float dash_length;\n", .fs_vars = "uniform sampler2D dash;\n", }, { .location = glamor_program_location_atlas, .fs_vars = "uniform sampler2D atlas;\n", }, }; static char * add_var(char *cur, const char *add) { char *new; if (!add) return cur; new = realloc(cur, strlen(cur) + strlen(add) + 1); if (!new) { free(cur); return NULL; } strcat(new, add); return new; } static char * vs_location_vars(glamor_program_location locations) { int l; char *vars = strdup(""); for (l = 0; vars && l < ARRAY_SIZE(location_vars); l++) if (locations & location_vars[l].location) vars = add_var(vars, location_vars[l].vs_vars); return vars; } static char * fs_location_vars(glamor_program_location locations) { int l; char *vars = strdup(""); for (l = 0; vars && l < ARRAY_SIZE(location_vars); l++) if (locations & location_vars[l].location) vars = add_var(vars, location_vars[l].fs_vars); return vars; } static const char vs_template[] = "%s" /* version */ "%s" /* defines */ "%s" /* prim vs_vars */ "%s" /* fill vs_vars */ "%s" /* location vs_vars */ GLAMOR_DECLARE_MATRIX "void main() {\n" "%s" /* prim vs_exec, outputs 'pos' and gl_Position */ "%s" /* fill vs_exec */ "}\n"; static const char fs_template[] = "%s" /* version */ GLAMOR_DEFAULT_PRECISION "%s" /* defines */ "%s" /* prim fs_vars */ "%s" /* fill fs_vars */ "%s" /* location fs_vars */ "void main() {\n" "%s" /* prim fs_exec */ "%s" /* fill fs_exec */ "%s" /* combine */ "}\n"; static const char * str(const char *s) { if (!s) return ""; return s; } static const glamor_facet facet_null_fill = { .name = "" }; #define DBG 0 static GLint glamor_get_uniform(glamor_program *prog, glamor_program_location location, const char *name) { GLint uniform; if (location && (prog->locations & location) == 0) return -2; uniform = glGetUniformLocation(prog->prog, name); #if DBG ErrorF("%s uniform %d\n", name, uniform); #endif return uniform; } Bool glamor_build_program(ScreenPtr screen, glamor_program *prog, const glamor_facet *prim, const glamor_facet *fill, const char *combine, const char *defines) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_program_location locations = prim->locations; glamor_program_flag flags = prim->flags; int version = prim->version; char *version_string = NULL; char *fs_vars = NULL; char *vs_vars = NULL; char *vs_prog_string; char *fs_prog_string; GLint fs_prog, vs_prog; if (!fill) fill = &facet_null_fill; locations |= fill->locations; flags |= fill->flags; version = MAX(version, fill->version); if (version > glamor_priv->glsl_version) goto fail; vs_vars = vs_location_vars(locations); fs_vars = fs_location_vars(locations); if (!vs_vars) goto fail; if (!fs_vars) goto fail; if (version) { if (asprintf(&version_string, "#version %d\n", version) < 0) version_string = NULL; if (!version_string) goto fail; } if (asprintf(&vs_prog_string, vs_template, str(version_string), str(defines), str(prim->vs_vars), str(fill->vs_vars), vs_vars, str(prim->vs_exec), str(fill->vs_exec)) < 0) vs_prog_string = NULL; if (asprintf(&fs_prog_string, fs_template, str(version_string), str(defines), str(prim->fs_vars), str(fill->fs_vars), fs_vars, str(prim->fs_exec), str(fill->fs_exec), str(combine)) < 0) fs_prog_string = NULL; if (!vs_prog_string || !fs_prog_string) goto fail; prog->prog = glCreateProgram(); #if DBG ErrorF("\n\tProgram %d for %s %s\n\tVertex shader:\n\n\t================\n%s\n\n\tFragment Shader:\n\n%s\t================\n", prog->prog, prim->name, fill->name, vs_prog_string, fs_prog_string); #endif prog->flags = flags; prog->locations = locations; prog->prim_use = prim->use; prog->prim_use_render = prim->use_render; prog->fill_use = fill->use; prog->fill_use_render = fill->use_render; vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_prog_string); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_prog_string); free(vs_prog_string); free(fs_prog_string); glAttachShader(prog->prog, vs_prog); glDeleteShader(vs_prog); glAttachShader(prog->prog, fs_prog); glDeleteShader(fs_prog); glBindAttribLocation(prog->prog, GLAMOR_VERTEX_POS, "primitive"); if (prim->source_name) { #if DBG ErrorF("Bind GLAMOR_VERTEX_SOURCE to %s\n", prim->source_name); #endif glBindAttribLocation(prog->prog, GLAMOR_VERTEX_SOURCE, prim->source_name); } if (prog->alpha == glamor_program_alpha_dual_blend) { glBindFragDataLocationIndexed(prog->prog, 0, 0, "color0"); glBindFragDataLocationIndexed(prog->prog, 0, 1, "color1"); } glamor_link_glsl_prog(screen, prog->prog, "%s_%s", prim->name, fill->name); prog->matrix_uniform = glamor_get_uniform(prog, glamor_program_location_none, "v_matrix"); prog->fg_uniform = glamor_get_uniform(prog, glamor_program_location_fg, "fg"); prog->bg_uniform = glamor_get_uniform(prog, glamor_program_location_bg, "bg"); prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fillpos, "fill_offset"); prog->fill_size_inv_uniform = glamor_get_uniform(prog, glamor_program_location_fillpos, "fill_size_inv"); prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font"); prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane"); prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul"); prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash"); prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length"); prog->atlas_uniform = glamor_get_uniform(prog, glamor_program_location_atlas, "atlas"); free(version_string); free(fs_vars); free(vs_vars); return TRUE; fail: prog->failed = 1; if (prog->prog) { glDeleteProgram(prog->prog); prog->prog = 0; } free(version_string); free(fs_vars); free(vs_vars); return FALSE; } Bool glamor_use_program(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) { glUseProgram(prog->prog); if (prog->prim_use && !prog->prim_use(pixmap, gc, prog, arg)) return FALSE; if (prog->fill_use && !prog->fill_use(pixmap, gc, prog, arg)) return FALSE; return TRUE; } glamor_program * glamor_use_program_fill(PixmapPtr pixmap, GCPtr gc, glamor_program_fill *program_fill, const glamor_facet *prim) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_program *prog = &program_fill->progs[gc->fillStyle]; int fill_style = gc->fillStyle; const glamor_facet *fill; if (prog->failed) return FALSE; if (!prog->prog) { fill = glamor_facet_fill[fill_style]; if (!fill) return NULL; if (!glamor_build_program(screen, prog, prim, fill, NULL, NULL)) return NULL; } if (!glamor_use_program(pixmap, gc, prog, NULL)) return NULL; return prog; } static struct blendinfo composite_op_info[] = { [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO}, [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO}, [PictOpDst] = {0, 0, GL_ZERO, GL_ONE}, [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE}, [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO}, [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA}, [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO}, [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}, [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA}, [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, }; static void glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst) { glamor_screen_private *glamor_priv = glamor_get_screen_private(dst->pDrawable->pScreen); GLenum src_blend, dst_blend; struct blendinfo *op_info; switch (alpha) { case glamor_program_alpha_ca_first: op = PictOpOutReverse; break; case glamor_program_alpha_ca_second: op = PictOpAdd; break; default: break; } if (glamor_priv->gl_flavor != GLAMOR_GL_ES2) glDisable(GL_COLOR_LOGIC_OP); if (op == PictOpSrc) return; op_info = &composite_op_info[op]; src_blend = op_info->source_blend; dst_blend = op_info->dest_blend; /* If there's no dst alpha channel, adjust the blend op so that we'll treat * it as always 1. */ if (PICT_FORMAT_A(dst->format) == 0 && op_info->dest_alpha) { if (src_blend == GL_DST_ALPHA) src_blend = GL_ONE; else if (src_blend == GL_ONE_MINUS_DST_ALPHA) src_blend = GL_ZERO; } /* Set up the source alpha value for blending in component alpha mode. */ if (alpha == glamor_program_alpha_dual_blend) { switch (dst_blend) { case GL_SRC_ALPHA: dst_blend = GL_SRC1_COLOR; break; case GL_ONE_MINUS_SRC_ALPHA: dst_blend = GL_ONE_MINUS_SRC1_COLOR; break; } } else if (alpha != glamor_program_alpha_normal) { switch (dst_blend) { case GL_SRC_ALPHA: dst_blend = GL_SRC_COLOR; break; case GL_ONE_MINUS_SRC_ALPHA: dst_blend = GL_ONE_MINUS_SRC_COLOR; break; } } glEnable(GL_BLEND); glBlendFunc(src_blend, dst_blend); } static Bool use_source_solid(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog) { PictSolidFill *solid = &src->pSourcePict->solidFill; float color[4]; glamor_get_rgba_from_color(&solid->fullcolor, color); glamor_set_blend(op, prog->alpha, dst); glUniform4fv(prog->fg_uniform, 1, color); return TRUE; } static const glamor_facet glamor_source_solid = { .name = "render_solid", .fs_exec = " vec4 source = fg;\n", .locations = glamor_program_location_fg, .use_render = use_source_solid, }; static Bool use_source_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog) { glamor_set_blend(op, prog->alpha, dst); return glamor_set_texture((PixmapPtr) src->pDrawable, glamor_picture_red_is_alpha(dst), 0, 0, prog->fill_offset_uniform, prog->fill_size_inv_uniform); } static const glamor_facet glamor_source_picture = { .name = "render_picture", .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n", .fs_exec = " vec4 source = texture2D(sampler, fill_pos);\n", .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos, .use_render = use_source_picture, }; static Bool use_source_1x1_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog) { glamor_set_blend(op, prog->alpha, dst); return glamor_set_texture_pixmap((PixmapPtr) src->pDrawable, glamor_picture_red_is_alpha(dst)); } static const glamor_facet glamor_source_1x1_picture = { .name = "render_picture", .fs_exec = " vec4 source = texture2D(sampler, vec2(0.5));\n", .locations = glamor_program_location_fillsamp, .use_render = use_source_1x1_picture, }; static const glamor_facet *glamor_facet_source[glamor_program_source_count] = { [glamor_program_source_solid] = &glamor_source_solid, [glamor_program_source_picture] = &glamor_source_picture, [glamor_program_source_1x1_picture] = &glamor_source_1x1_picture, }; static const char *glamor_combine[] = { [glamor_program_alpha_normal] = " gl_FragColor = source * mask.a;\n", [glamor_program_alpha_ca_first] = " gl_FragColor = source.a * mask;\n", [glamor_program_alpha_ca_second] = " gl_FragColor = source * mask;\n", [glamor_program_alpha_dual_blend] = " color0 = source * mask;\n" " color1 = source.a * mask;\n" }; static Bool glamor_setup_one_program_render(ScreenPtr screen, glamor_program *prog, glamor_program_source source_type, glamor_program_alpha alpha, const glamor_facet *prim, const char *defines) { if (prog->failed) return FALSE; if (!prog->prog) { const glamor_facet *fill = glamor_facet_source[source_type]; if (!fill) return FALSE; prog->alpha = alpha; if (!glamor_build_program(screen, prog, prim, fill, glamor_combine[alpha], defines)) return FALSE; } return TRUE; } glamor_program * glamor_setup_program_render(CARD8 op, PicturePtr src, PicturePtr mask, PicturePtr dst, glamor_program_render *program_render, const glamor_facet *prim, const char *defines) { ScreenPtr screen = dst->pDrawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_program_alpha alpha; glamor_program_source source_type; glamor_program *prog; if (op > ARRAY_SIZE(composite_op_info)) return NULL; if (glamor_is_component_alpha(mask)) { if (glamor_priv->has_dual_blend) { alpha = glamor_program_alpha_dual_blend; } else { /* This only works for PictOpOver */ if (op != PictOpOver) return NULL; alpha = glamor_program_alpha_ca_first; } } else alpha = glamor_program_alpha_normal; if (src->pDrawable) { /* Can't do transforms, alphamaps or sourcing from non-pixmaps yet */ if (src->transform || src->alphaMap || src->pDrawable->type != DRAWABLE_PIXMAP) return NULL; if (src->pDrawable->width == 1 && src->pDrawable->height == 1 && src->repeat) source_type = glamor_program_source_1x1_picture; else source_type = glamor_program_source_picture; } else { SourcePictPtr sp = src->pSourcePict; if (!sp) return NULL; switch (sp->type) { case SourcePictTypeSolidFill: source_type = glamor_program_source_solid; break; default: return NULL; } } prog = &program_render->progs[source_type][alpha]; if (!glamor_setup_one_program_render(screen, prog, source_type, alpha, prim, defines)) return NULL; if (alpha == glamor_program_alpha_ca_first) { /* Make sure we can also build the second program before * deciding to use this path. */ if (!glamor_setup_one_program_render(screen, &program_render->progs[source_type][glamor_program_alpha_ca_second], source_type, glamor_program_alpha_ca_second, prim, defines)) return NULL; } return prog; } Bool glamor_use_program_render(glamor_program *prog, CARD8 op, PicturePtr src, PicturePtr dst) { glUseProgram(prog->prog); if (prog->prim_use_render && !prog->prim_use_render(op, src, dst, prog)) return FALSE; if (prog->fill_use_render && !prog->fill_use_render(op, src, dst, prog)) return FALSE; return TRUE; } xorg-server-1.20.13/glamor/glamor_program.h0000644000175000017500000001327014100573756015537 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _GLAMOR_PROGRAM_H_ #define _GLAMOR_PROGRAM_H_ typedef enum { glamor_program_location_none = 0, glamor_program_location_fg = 1, glamor_program_location_bg = 2, glamor_program_location_fillsamp = 4, glamor_program_location_fillpos = 8, glamor_program_location_font = 16, glamor_program_location_bitplane = 32, glamor_program_location_dash = 64, glamor_program_location_atlas = 128, } glamor_program_location; typedef enum { glamor_program_flag_none = 0, } glamor_program_flag; typedef enum { glamor_program_alpha_normal, glamor_program_alpha_ca_first, glamor_program_alpha_ca_second, glamor_program_alpha_dual_blend, glamor_program_alpha_count } glamor_program_alpha; typedef struct _glamor_program glamor_program; typedef Bool (*glamor_use) (PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg); typedef Bool (*glamor_use_render) (CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog); typedef struct { const char *name; const int version; char *vs_defines; char *fs_defines; const char *vs_vars; const char *vs_exec; const char *fs_vars; const char *fs_exec; const glamor_program_location locations; const glamor_program_flag flags; const char *source_name; glamor_use use; glamor_use_render use_render; } glamor_facet; struct _glamor_program { GLint prog; GLint failed; GLint matrix_uniform; GLint fg_uniform; GLint bg_uniform; GLint fill_size_inv_uniform; GLint fill_offset_uniform; GLint font_uniform; GLint bitplane_uniform; GLint bitmul_uniform; GLint dash_uniform; GLint dash_length_uniform; GLint atlas_uniform; glamor_program_location locations; glamor_program_flag flags; glamor_use prim_use; glamor_use fill_use; glamor_program_alpha alpha; glamor_use_render prim_use_render; glamor_use_render fill_use_render; }; typedef struct { glamor_program progs[4]; } glamor_program_fill; extern const glamor_facet glamor_fill_solid; Bool glamor_build_program(ScreenPtr screen, glamor_program *prog, const glamor_facet *prim, const glamor_facet *fill, const char *combine, const char *defines); Bool glamor_use_program(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg); glamor_program * glamor_use_program_fill(PixmapPtr pixmap, GCPtr gc, glamor_program_fill *program_fill, const glamor_facet *prim); typedef enum { glamor_program_source_solid, glamor_program_source_picture, glamor_program_source_1x1_picture, glamor_program_source_count, } glamor_program_source; typedef struct { glamor_program progs[glamor_program_source_count][glamor_program_alpha_count]; } glamor_program_render; static inline Bool glamor_is_component_alpha(PicturePtr mask) { if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) return TRUE; return FALSE; } glamor_program * glamor_setup_program_render(CARD8 op, PicturePtr src, PicturePtr mask, PicturePtr dst, glamor_program_render *program_render, const glamor_facet *prim, const char *defines); Bool glamor_use_program_render(glamor_program *prog, CARD8 op, PicturePtr src, PicturePtr dst); #endif /* _GLAMOR_PROGRAM_H_ */ xorg-server-1.20.13/glamor/glamor_rects.c0000644000175000017500000001574014100573756015207 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_program.h" #include "glamor_transform.h" static const glamor_facet glamor_facet_polyfillrect_130 = { .name = "poly_fill_rect", .version = 130, .source_name = "size", .vs_vars = "attribute vec2 primitive;\n" "attribute vec2 size;\n", .vs_exec = (" vec2 pos = size * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n" GLAMOR_POS(gl_Position, (primitive.xy + pos))), }; static const glamor_facet glamor_facet_polyfillrect_120 = { .name = "poly_fill_rect", .vs_vars = "attribute vec2 primitive;\n", .vs_exec = (" vec2 pos = vec2(0,0);\n" GLAMOR_POS(gl_Position, primitive.xy)), }; static Bool glamor_poly_fill_rect_gl(DrawablePtr drawable, GCPtr gc, int nrect, xRectangle *prect) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; glamor_program *prog; int off_x, off_y; GLshort *v; char *vbo_offset; int box_index; Bool ret = FALSE; BoxRec bounds = glamor_no_rendering_bounds(); pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; glamor_make_current(glamor_priv); if (nrect < 100) { bounds = glamor_start_rendering_bounds(); for (int i = 0; i < nrect; i++) glamor_bounds_union_rect(&bounds, &prect[i]); } if (glamor_priv->glsl_version >= 130) { prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_fill_rect_program, &glamor_facet_polyfillrect_130); if (!prog) goto bail; /* Set up the vertex buffers for the points */ v = glamor_get_vbo_space(drawable->pScreen, nrect * sizeof (xRectangle), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 4 * sizeof (short), vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 1); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_UNSIGNED_SHORT, GL_FALSE, 4 * sizeof (short), vbo_offset + 2 * sizeof (short)); memcpy(v, prect, nrect * sizeof (xRectangle)); glamor_put_vbo_space(screen); } else { int n; prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_fill_rect_program, &glamor_facet_polyfillrect_120); if (!prog) goto bail; /* Set up the vertex buffers for the points */ v = glamor_get_vbo_space(drawable->pScreen, nrect * 8 * sizeof (short), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 2 * sizeof (short), vbo_offset); for (n = 0; n < nrect; n++) { v[0] = prect->x; v[1] = prect->y; v[2] = prect->x; v[3] = prect->y + prect->height; v[4] = prect->x + prect->width; v[5] = prect->y + prect->height; v[6] = prect->x + prect->width; v[7] = prect->y; prect++; v += 8; } glamor_put_vbo_space(screen); } glEnable(GL_SCISSOR_TEST); glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); if (!glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y)) goto bail; while (nbox--) { BoxRec scissor = { .x1 = max(box->x1, bounds.x1 + drawable->x), .y1 = max(box->y1, bounds.y1 + drawable->y), .x2 = min(box->x2, bounds.x2 + drawable->x), .y2 = min(box->y2, bounds.y2 + drawable->y), }; box++; if (scissor.x1 >= scissor.x2 || scissor.y1 >= scissor.y2) continue; glScissor(scissor.x1 + off_x, scissor.y1 + off_y, scissor.x2 - scissor.x1, scissor.y2 - scissor.y1); if (glamor_priv->glsl_version >= 130) glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nrect); else { glamor_glDrawArrays_GL_QUADS(glamor_priv, nrect); } } } ret = TRUE; bail: glDisable(GL_SCISSOR_TEST); if (glamor_priv->glsl_version >= 130) { glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0); } glDisableVertexAttribArray(GLAMOR_VERTEX_POS); return ret; } static void glamor_poly_fill_rect_bail(DrawablePtr drawable, GCPtr gc, int nrect, xRectangle *prect) { glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && glamor_prepare_access_gc(gc)) { fbPolyFillRect(drawable, gc, nrect, prect); } glamor_finish_access_gc(gc); glamor_finish_access(drawable); } void glamor_poly_fill_rect(DrawablePtr drawable, GCPtr gc, int nrect, xRectangle *prect) { if (glamor_poly_fill_rect_gl(drawable, gc, nrect, prect)) return; glamor_poly_fill_rect_bail(drawable, gc, nrect, prect); } xorg-server-1.20.13/glamor/glamor_spans.c0000644000175000017500000003002614100573756015205 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_transform.h" #include "glamor_transfer.h" glamor_program fill_spans_progs[4]; static const glamor_facet glamor_facet_fillspans_130 = { .name = "fill_spans", .version = 130, .vs_vars = "attribute vec3 primitive;\n", .vs_exec = (" vec2 pos = vec2(primitive.z,1) * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n" GLAMOR_POS(gl_Position, (primitive.xy + pos))), }; static const glamor_facet glamor_facet_fillspans_120 = { .name = "fill_spans", .vs_vars = "attribute vec2 primitive;\n", .vs_exec = (" vec2 pos = vec2(0,0);\n" GLAMOR_POS(gl_Position, primitive.xy)), }; static Bool glamor_fill_spans_gl(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr points, int *widths, int sorted) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; glamor_program *prog; int off_x, off_y; GLshort *v; char *vbo_offset; int c; int box_index; Bool ret = FALSE; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; glamor_make_current(glamor_priv); if (glamor_priv->glsl_version >= 130) { prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->fill_spans_program, &glamor_facet_fillspans_130); if (!prog) goto bail; /* Set up the vertex buffers for the points */ v = glamor_get_vbo_space(drawable->pScreen, n * (4 * sizeof (GLshort)), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1); glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE, 4 * sizeof (GLshort), vbo_offset); for (c = 0; c < n; c++) { v[0] = points->x; v[1] = points->y; v[2] = *widths++; points++; v += 4; } glamor_put_vbo_space(screen); } else { prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->fill_spans_program, &glamor_facet_fillspans_120); if (!prog) goto bail; /* Set up the vertex buffers for the points */ v = glamor_get_vbo_space(drawable->pScreen, n * 8 * sizeof (short), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 2 * sizeof (short), vbo_offset); for (c = 0; c < n; c++) { v[0] = points->x; v[1] = points->y; v[2] = points->x; v[3] = points->y + 1; v[4] = points->x + *widths; v[5] = points->y + 1; v[6] = points->x + *widths; v[7] = points->y; widths++; points++; v += 8; } glamor_put_vbo_space(screen); } glEnable(GL_SCISSOR_TEST); glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); if (!glamor_set_destination_drawable(drawable, box_index, FALSE, FALSE, prog->matrix_uniform, &off_x, &off_y)) goto bail; while (nbox--) { glScissor(box->x1 + off_x, box->y1 + off_y, box->x2 - box->x1, box->y2 - box->y1); box++; if (glamor_priv->glsl_version >= 130) glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, n); else { glamor_glDrawArrays_GL_QUADS(glamor_priv, n); } } } ret = TRUE; bail: glDisable(GL_SCISSOR_TEST); if (glamor_priv->glsl_version >= 130) glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); return ret; } static void glamor_fill_spans_bail(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr points, int *widths, int sorted) { if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && glamor_prepare_access_gc(gc)) { fbFillSpans(drawable, gc, n, points, widths, sorted); } glamor_finish_access_gc(gc); glamor_finish_access(drawable); } void glamor_fill_spans(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr points, int *widths, int sorted) { if (glamor_fill_spans_gl(drawable, gc, n, points, widths, sorted)) return; glamor_fill_spans_bail(drawable, gc, n, points, widths, sorted); } static Bool glamor_get_spans_gl(DrawablePtr drawable, int wmax, DDXPointPtr points, int *widths, int count, char *dst) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; int box_index; int n; char *d; GLenum type; GLenum format; int off_x, off_y; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); glamor_format_for_pixmap(pixmap, &format, &type); glamor_make_current(glamor_priv); glamor_pixmap_loop(pixmap_priv, box_index) { BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index); glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_index); glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); glPixelStorei(GL_PACK_ALIGNMENT, 4); d = dst; for (n = 0; n < count; n++) { int x1 = points[n].x + off_x; int y = points[n].y + off_y; int w = widths[n]; int x2 = x1 + w; char *l; l = d; d += PixmapBytePad(w, drawable->depth); /* clip */ if (x1 < box->x1) { l += (box->x1 - x1) * (drawable->bitsPerPixel >> 3); x1 = box->x1; } if (x2 > box->x2) x2 = box->x2; if (x1 >= x2) continue; if (y < box->y1) continue; if (y >= box->y2) continue; glReadPixels(x1 - box->x1, y - box->y1, x2 - x1, 1, format, type, l); } } return TRUE; bail: return FALSE; } static void glamor_get_spans_bail(DrawablePtr drawable, int wmax, DDXPointPtr points, int *widths, int count, char *dst) { if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) fbGetSpans(drawable, wmax, points, widths, count, dst); glamor_finish_access(drawable); } void glamor_get_spans(DrawablePtr drawable, int wmax, DDXPointPtr points, int *widths, int count, char *dst) { if (glamor_get_spans_gl(drawable, wmax, points, widths, count, dst)) return; glamor_get_spans_bail(drawable, wmax, points, widths, count, dst); } static Bool glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int numPoints, int sorted) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; int box_index; int n; char *s; GLenum type; GLenum format; int off_x, off_y; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; if (gc->alu != GXcopy) goto bail; if (!glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); glamor_format_for_pixmap(pixmap, &format, &type); glamor_make_current(glamor_priv); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glamor_pixmap_loop(pixmap_priv, box_index) { BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index); glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_index); glamor_bind_texture(glamor_priv, GL_TEXTURE0, fbo, TRUE); s = src; for (n = 0; n < numPoints; n++) { BoxPtr clip_box = RegionRects(gc->pCompositeClip); int nclip_box = RegionNumRects(gc->pCompositeClip); int w = widths[n]; int y = points[n].y; int x = points[n].x; while (nclip_box--) { int x1 = x; int x2 = x + w; int y1 = y; char *l = s; /* clip to composite clip */ if (x1 < clip_box->x1) { l += (clip_box->x1 - x1) * (drawable->bitsPerPixel >> 3); x1 = clip_box->x1; } if (x2 > clip_box->x2) x2 = clip_box->x2; if (y < clip_box->y1) continue; if (y >= clip_box->y2) continue; /* adjust to pixmap coordinates */ x1 += off_x; x2 += off_x; y1 += off_y; if (x1 < box->x1) { l += (box->x1 - x1) * (drawable->bitsPerPixel >> 3); x1 = box->x1; } if (x2 > box->x2) x2 = box->x2; if (x1 >= x2) continue; if (y1 < box->y1) continue; if (y1 >= box->y2) continue; glTexSubImage2D(GL_TEXTURE_2D, 0, x1 - box->x1, y1 - box->y1, x2 - x1, 1, format, type, l); } s += PixmapBytePad(w, drawable->depth); } } return TRUE; bail: return FALSE; } static void glamor_set_spans_bail(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int numPoints, int sorted) { if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && glamor_prepare_access_gc(gc)) fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted); glamor_finish_access_gc(gc); glamor_finish_access(drawable); } void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int numPoints, int sorted) { if (glamor_set_spans_gl(drawable, gc, src, points, widths, numPoints, sorted)) return; glamor_set_spans_bail(drawable, gc, src, points, widths, numPoints, sorted); } xorg-server-1.20.13/glamor/glamor_text.c0000644000175000017500000003731314100573756015053 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include #include "glamor_transform.h" /* * Fill in the array of charinfo pointers for the provided characters. For * missing characters, place a NULL in the array so that the charinfo array * aligns exactly with chars */ static void glamor_get_glyphs(FontPtr font, glamor_font_t *glamor_font, int count, char *chars, Bool sixteen, CharInfoPtr *charinfo) { unsigned long nglyphs; FontEncoding encoding; int char_step; int c; if (sixteen) { char_step = 2; if (FONTLASTROW(font) == 0) encoding = Linear16Bit; else encoding = TwoD16Bit; } else { char_step = 1; encoding = Linear8Bit; } /* If the font has a default character, then we shouldn't have to * worry about missing glyphs, so just get the whole string all at * once. Otherwise, we have to fetch chars one at a time to notice * missing ones. */ if (glamor_font->default_char) { GetGlyphs(font, (unsigned long) count, (unsigned char *) chars, encoding, &nglyphs, charinfo); /* Make sure it worked. There's a bug in libXfont through * version 1.4.7 which would cause it to fail when the font is * a 2D font without a first row, and the application sends a * 1-d request. In this case, libXfont would return zero * glyphs, even when the font had a default character. * * It's easy enough for us to work around that bug here by * simply checking the returned nglyphs and falling through to * the one-at-a-time code below. Not doing this check would * result in uninitialized memory accesses in the rendering code. */ if (nglyphs == count) return; } for (c = 0; c < count; c++) { GetGlyphs(font, 1, (unsigned char *) chars, encoding, &nglyphs, &charinfo[c]); if (!nglyphs) charinfo[c] = NULL; chars += char_step; } } /* * Construct quads for the provided list of characters and draw them */ static int glamor_text(DrawablePtr drawable, GCPtr gc, glamor_font_t *glamor_font, glamor_program *prog, int x, int y, int count, char *s_chars, CharInfoPtr *charinfo, Bool sixteen) { unsigned char *chars = (unsigned char *) s_chars; FontPtr font = gc->font; int off_x, off_y; int c; int nglyph; GLshort *v; char *vbo_offset; CharInfoPtr ci; int firstRow = font->info.firstRow; int firstCol = font->info.firstCol; int glyph_spacing_x = glamor_font->glyph_width_bytes * 8; int glyph_spacing_y = glamor_font->glyph_height; int box_index; PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); /* Set the font as texture 1 */ glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, glamor_font->texture_id); glUniform1i(prog->font_uniform, 1); /* Set up the vertex buffers for the font and destination */ v = glamor_get_vbo_space(drawable->pScreen, count * (6 * sizeof (GLshort)), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1); glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE, 6 * sizeof (GLshort), vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 1); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE, 6 * sizeof (GLshort), vbo_offset + 4 * sizeof (GLshort)); /* Set the vertex coordinates */ nglyph = 0; for (c = 0; c < count; c++) { if ((ci = *charinfo++)) { int x1 = x + ci->metrics.leftSideBearing; int y1 = y - ci->metrics.ascent; int width = GLYPHWIDTHPIXELS(ci); int height = GLYPHHEIGHTPIXELS(ci); int tx, ty = 0; int row = 0, col; int second_row = 0; x += ci->metrics.characterWidth; if (sixteen) { if (ci == glamor_font->default_char) { row = glamor_font->default_row; col = glamor_font->default_col; } else { row = chars[0]; col = chars[1]; } if (FONTLASTROW(font) != 0) { ty = ((row - firstRow) / 2) * glyph_spacing_y; second_row = (row - firstRow) & 1; } else col += row << 8; } else { if (ci == glamor_font->default_char) col = glamor_font->default_col; else col = chars[0]; } tx = (col - firstCol) * glyph_spacing_x; /* adjust for second row layout */ tx += second_row * glamor_font->row_width * 8; v[ 0] = x1; v[ 1] = y1; v[ 2] = width; v[ 3] = height; v[ 4] = tx; v[ 5] = ty; v += 6; nglyph++; } chars += 1 + sixteen; } glamor_put_vbo_space(drawable->pScreen); if (nglyph != 0) { glEnable(GL_SCISSOR_TEST); glamor_pixmap_loop(pixmap_priv, box_index) { BoxPtr box = RegionRects(gc->pCompositeClip); int nbox = RegionNumRects(gc->pCompositeClip); glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y); /* Run over the clip list, drawing the glyphs * in each box */ while (nbox--) { glScissor(box->x1 + off_x, box->y1 + off_y, box->x2 - box->x1, box->y2 - box->y1); box++; glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nglyph); } } glDisable(GL_SCISSOR_TEST); } glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); return x; } static const char vs_vars_text[] = "attribute vec4 primitive;\n" "attribute vec2 source;\n" "varying vec2 glyph_pos;\n"; static const char vs_exec_text[] = " vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n" GLAMOR_POS(gl_Position, (primitive.xy + pos)) " glyph_pos = source + pos;\n"; static const char fs_vars_text[] = "varying vec2 glyph_pos;\n"; static const char fs_exec_text[] = " ivec2 itile_texture = ivec2(glyph_pos);\n" " uint x = uint(itile_texture.x & 7);\n" " itile_texture.x >>= 3;\n" " uint texel = texelFetch(font, itile_texture, 0).x;\n" " uint bit = (texel >> x) & uint(1);\n" " if (bit == uint(0))\n" " discard;\n"; static const char fs_exec_te[] = " ivec2 itile_texture = ivec2(glyph_pos);\n" " uint x = uint(itile_texture.x & 7);\n" " itile_texture.x >>= 3;\n" " uint texel = texelFetch(font, itile_texture, 0).x;\n" " uint bit = (texel >> x) & uint(1);\n" " if (bit == uint(0))\n" " gl_FragColor = bg;\n" " else\n" " gl_FragColor = fg;\n"; static const glamor_facet glamor_facet_poly_text = { .name = "poly_text", .version = 130, .vs_vars = vs_vars_text, .vs_exec = vs_exec_text, .fs_vars = fs_vars_text, .fs_exec = fs_exec_text, .source_name = "source", .locations = glamor_program_location_font, }; static Bool glamor_poly_text(DrawablePtr drawable, GCPtr gc, int x, int y, int count, char *chars, Bool sixteen, int *final_pos) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_program *prog; glamor_pixmap_private *pixmap_priv; glamor_font_t *glamor_font; CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ glamor_font = glamor_font_get(drawable->pScreen, gc->font); if (!glamor_font) goto bail; glamor_get_glyphs(gc->font, glamor_font, count, chars, sixteen, charinfo); pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; glamor_make_current(glamor_priv); prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_text_progs, &glamor_facet_poly_text); if (!prog) goto bail; x = glamor_text(drawable, gc, glamor_font, prog, x, y, count, chars, charinfo, sixteen); *final_pos = x; return TRUE; bail: return FALSE; } int glamor_poly_text8(DrawablePtr drawable, GCPtr gc, int x, int y, int count, char *chars) { int final_pos; if (glamor_poly_text(drawable, gc, x, y, count, chars, FALSE, &final_pos)) return final_pos; return miPolyText8(drawable, gc, x, y, count, chars); } int glamor_poly_text16(DrawablePtr drawable, GCPtr gc, int x, int y, int count, unsigned short *chars) { int final_pos; if (glamor_poly_text(drawable, gc, x, y, count, (char *) chars, TRUE, &final_pos)) return final_pos; return miPolyText16(drawable, gc, x, y, count, chars); } /* * Draw image text, which is always solid in copy mode and has the * background cleared while painting the text. For fonts which have * their bitmap metrics exactly equal to the area to clear, we can use * the accelerated version which paints both fg and bg at the same * time. Otherwise, clear the whole area and then paint the glyphs on * top */ static const glamor_facet glamor_facet_image_text = { .name = "image_text", .version = 130, .vs_vars = vs_vars_text, .vs_exec = vs_exec_text, .fs_vars = fs_vars_text, .fs_exec = fs_exec_text, .source_name = "source", .locations = glamor_program_location_font, }; static Bool use_image_solid(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) { return glamor_set_solid(pixmap, gc, FALSE, prog->fg_uniform); } static const glamor_facet glamor_facet_image_fill = { .name = "solid", .fs_exec = " gl_FragColor = fg;\n", .locations = glamor_program_location_fg, .use = use_image_solid, }; static Bool glamor_te_text_use(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) { if (!glamor_set_solid(pixmap, gc, FALSE, prog->fg_uniform)) return FALSE; glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform); return TRUE; } static const glamor_facet glamor_facet_te_text = { .name = "te_text", .version = 130, .vs_vars = vs_vars_text, .vs_exec = vs_exec_text, .fs_vars = fs_vars_text, .fs_exec = fs_exec_te, .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_font, .source_name = "source", .use = glamor_te_text_use, }; static Bool glamor_image_text(DrawablePtr drawable, GCPtr gc, int x, int y, int count, char *chars, Bool sixteen) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_program *prog; glamor_pixmap_private *pixmap_priv; glamor_font_t *glamor_font; const glamor_facet *prim_facet; const glamor_facet *fill_facet; CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return FALSE; glamor_font = glamor_font_get(drawable->pScreen, gc->font); if (!glamor_font) return FALSE; glamor_get_glyphs(gc->font, glamor_font, count, chars, sixteen, charinfo); glamor_make_current(glamor_priv); if (TERMINALFONT(gc->font)) prog = &glamor_priv->te_text_prog; else prog = &glamor_priv->image_text_prog; if (prog->failed) goto bail; if (!prog->prog) { if (TERMINALFONT(gc->font)) { prim_facet = &glamor_facet_te_text; fill_facet = NULL; } else { prim_facet = &glamor_facet_image_text; fill_facet = &glamor_facet_image_fill; } if (!glamor_build_program(screen, prog, prim_facet, fill_facet, NULL, NULL)) goto bail; } if (!TERMINALFONT(gc->font)) { int width = 0; int c; RegionRec region; BoxRec box; int off_x, off_y; /* Check planemask before drawing background to * bail early if it's not OK */ if (!glamor_set_planemask(gc->depth, gc->planemask)) goto bail; for (c = 0; c < count; c++) if (charinfo[c]) width += charinfo[c]->metrics.characterWidth; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); if (width >= 0) { box.x1 = drawable->x + x; box.x2 = drawable->x + x + width; } else { box.x1 = drawable->x + x + width; box.x2 = drawable->x + x; } box.y1 = drawable->y + y - gc->font->info.fontAscent; box.y2 = drawable->y + y + gc->font->info.fontDescent; RegionInit(®ion, &box, 1); RegionIntersect(®ion, ®ion, gc->pCompositeClip); RegionTranslate(®ion, off_x, off_y); glamor_solid_boxes(pixmap, RegionRects(®ion), RegionNumRects(®ion), gc->bgPixel); RegionUninit(®ion); } if (!glamor_use_program(pixmap, gc, prog, NULL)) goto bail; (void) glamor_text(drawable, gc, glamor_font, prog, x, y, count, chars, charinfo, sixteen); return TRUE; bail: return FALSE; } void glamor_image_text8(DrawablePtr drawable, GCPtr gc, int x, int y, int count, char *chars) { if (!glamor_image_text(drawable, gc, x, y, count, chars, FALSE)) miImageText8(drawable, gc, x, y, count, chars); } void glamor_image_text16(DrawablePtr drawable, GCPtr gc, int x, int y, int count, unsigned short *chars) { if (!glamor_image_text(drawable, gc, x, y, count, (char *) chars, TRUE)) miImageText16(drawable, gc, x, y, count, chars); } xorg-server-1.20.13/glamor/glamor_transfer.c0000644000175000017500000002064014100573756015706 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_transfer.h" /* XXX a kludge for now */ void glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type) { switch (pixmap->drawable.depth) { case 24: case 32: *format = GL_BGRA; *type = GL_UNSIGNED_INT_8_8_8_8_REV; break; case 30: *format = GL_BGRA; *type = GL_UNSIGNED_INT_2_10_10_10_REV; break; case 16: *format = GL_RGB; *type = GL_UNSIGNED_SHORT_5_6_5; break; case 15: *format = GL_BGRA; *type = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; case 8: *format = glamor_get_screen_private(pixmap->drawable.pScreen)->one_channel_format; *type = GL_UNSIGNED_BYTE; break; default: FatalError("Invalid pixmap depth %d\n", pixmap->drawable.depth); break; } } /* * Write a region of bits into a pixmap */ void glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, int dx_src, int dy_src, int dx_dst, int dy_dst, uint8_t *bits, uint32_t byte_stride) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); int box_index; int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3; GLenum type; GLenum format; glamor_format_for_pixmap(pixmap, &format, &type); glamor_make_current(glamor_priv); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); if (glamor_priv->has_unpack_subimage) glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel); glamor_pixmap_loop(priv, box_index) { BoxPtr box = glamor_pixmap_box_at(priv, box_index); glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_index); BoxPtr boxes = in_boxes; int nbox = in_nbox; glamor_bind_texture(glamor_priv, GL_TEXTURE0, fbo, TRUE); while (nbox--) { /* compute drawable coordinates */ int x1 = MAX(boxes->x1 + dx_dst, box->x1); int x2 = MIN(boxes->x2 + dx_dst, box->x2); int y1 = MAX(boxes->y1 + dy_dst, box->y1); int y2 = MIN(boxes->y2 + dy_dst, box->y2); size_t ofs = (y1 - dy_dst + dy_src) * byte_stride; ofs += (x1 - dx_dst + dx_src) * bytes_per_pixel; boxes++; if (x2 <= x1 || y2 <= y1) continue; if (glamor_priv->has_unpack_subimage || x2 - x1 == byte_stride / bytes_per_pixel) { glTexSubImage2D(GL_TEXTURE_2D, 0, x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits + ofs); } else { for (; y1 < y2; y1++, ofs += byte_stride) glTexSubImage2D(GL_TEXTURE_2D, 0, x1 - box->x1, y1 - box->y1, x2 - x1, 1, format, type, bits + ofs); } } } if (glamor_priv->has_unpack_subimage) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } /* * Upload a region of data */ void glamor_upload_region(PixmapPtr pixmap, RegionPtr region, int region_x, int region_y, uint8_t *bits, uint32_t byte_stride) { glamor_upload_boxes(pixmap, RegionRects(region), RegionNumRects(region), -region_x, -region_y, 0, 0, bits, byte_stride); } /* * Take the data in the pixmap and stuff it back into the FBO */ void glamor_upload_pixmap(PixmapPtr pixmap) { BoxRec box; box.x1 = 0; box.x2 = pixmap->drawable.width; box.y1 = 0; box.y2 = pixmap->drawable.height; glamor_upload_boxes(pixmap, &box, 1, 0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind); } /* * Read stuff from the pixmap FBOs and write to memory */ void glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, int dx_src, int dy_src, int dx_dst, int dy_dst, uint8_t *bits, uint32_t byte_stride) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); int box_index; int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3; GLenum type; GLenum format; glamor_format_for_pixmap(pixmap, &format, &type); glamor_make_current(glamor_priv); glPixelStorei(GL_PACK_ALIGNMENT, 4); if (glamor_priv->has_pack_subimage) glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel); glamor_pixmap_loop(priv, box_index) { BoxPtr box = glamor_pixmap_box_at(priv, box_index); glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_index); BoxPtr boxes = in_boxes; int nbox = in_nbox; /* This should not be called on GLAMOR_FBO_NO_FBO-allocated pixmaps. */ assert(fbo->fb); glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); while (nbox--) { /* compute drawable coordinates */ int x1 = MAX(boxes->x1 + dx_src, box->x1); int x2 = MIN(boxes->x2 + dx_src, box->x2); int y1 = MAX(boxes->y1 + dy_src, box->y1); int y2 = MIN(boxes->y2 + dy_src, box->y2); size_t ofs = (y1 - dy_src + dy_dst) * byte_stride; ofs += (x1 - dx_src + dx_dst) * bytes_per_pixel; boxes++; if (x2 <= x1 || y2 <= y1) continue; if (glamor_priv->has_pack_subimage || x2 - x1 == byte_stride / bytes_per_pixel) { glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits + ofs); } else { for (; y1 < y2; y1++, ofs += byte_stride) glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, 1, format, type, bits + ofs); } } } if (glamor_priv->has_pack_subimage) glPixelStorei(GL_PACK_ROW_LENGTH, 0); } /* * Read data from the pixmap FBO */ void glamor_download_rect(PixmapPtr pixmap, int x, int y, int w, int h, uint8_t *bits) { BoxRec box; box.x1 = x; box.x2 = x + w; box.y1 = y; box.y2 = y + h; glamor_download_boxes(pixmap, &box, 1, 0, 0, -x, -y, bits, PixmapBytePad(w, pixmap->drawable.depth)); } /* * Pull the data from the FBO down to the pixmap */ void glamor_download_pixmap(PixmapPtr pixmap) { BoxRec box; box.x1 = 0; box.x2 = pixmap->drawable.width; box.y1 = 0; box.y2 = pixmap->drawable.height; glamor_download_boxes(pixmap, &box, 1, 0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind); } xorg-server-1.20.13/glamor/glamor_transfer.h0000644000175000017500000000416314100573756015715 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _GLAMOR_TRANSFER_H_ #define _GLAMOR_TRANSFER_H_ void glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type); void glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, int dx_src, int dy_src, int dx_dst, int dy_dst, uint8_t *bits, uint32_t byte_stride); void glamor_upload_region(PixmapPtr pixmap, RegionPtr region, int region_x, int region_y, uint8_t *bits, uint32_t byte_stride); void glamor_upload_pixmap(PixmapPtr pixmap); void glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, int dx_src, int dy_src, int dx_dst, int dy_dst, uint8_t *bits, uint32_t byte_stride); void glamor_download_rect(PixmapPtr pixmap, int x, int y, int w, int h, uint8_t *bits); void glamor_download_pixmap(PixmapPtr pixmap); #endif /* _GLAMOR_TRANSFER_H_ */ xorg-server-1.20.13/glamor/glamor_transform.c0000644000175000017500000002272514100573756016103 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "glamor_transform.h" /* * Set up rendering to target the specified drawable, computing an * appropriate transform for the vertex shader to convert * drawable-relative coordinates into pixmap-relative coordinates. If * requested, the offset from pixmap origin coordinates back to window * system coordinates will be returned in *p_off_x, *p_off_y so that * clipping computations can be adjusted as appropriate */ Bool glamor_set_destination_drawable(DrawablePtr drawable, int box_index, Bool do_drawable_translate, Bool center_offset, GLint matrix_uniform_location, int *p_off_x, int *p_off_y) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); int off_x, off_y; BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index); int w = box->x2 - box->x1; int h = box->y2 - box->y1; float scale_x = 2.0f / (float) w; float scale_y = 2.0f / (float) h; float center_adjust = 0.0f; glamor_pixmap_fbo *pixmap_fbo; pixmap_fbo = glamor_pixmap_fbo_at(pixmap_priv, box_index); if (!pixmap_fbo) return FALSE; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); off_x -= box->x1; off_y -= box->y1; if (p_off_x) { *p_off_x = off_x; *p_off_y = off_y; } /* A tricky computation to find the right value for the two linear functions * that transform rendering coordinates to pixmap coordinates * * pixmap_x = render_x + drawable->x + off_x * pixmap_y = render_y + drawable->y + off_y * * gl_x = pixmap_x * 2 / width - 1 * gl_y = pixmap_y * 2 / height - 1 * * gl_x = (render_x + drawable->x + off_x) * 2 / width - 1 * * gl_x = (render_x) * 2 / width + (drawable->x + off_x) * 2 / width - 1 */ if (do_drawable_translate) { off_x += drawable->x; off_y += drawable->y; } /* * To get GL_POINTS drawn in the right spot, we need to adjust the * coordinates by 1/2 a pixel. */ if (center_offset) center_adjust = 0.5f; glUniform4f(matrix_uniform_location, scale_x, (off_x + center_adjust) * scale_x - 1.0f, scale_y, (off_y + center_adjust) * scale_y - 1.0f); glamor_set_destination_pixmap_fbo(glamor_priv, pixmap_fbo, 0, 0, w, h); return TRUE; } /* * Set up for solid rendering to the specified pixmap using alu, fg and planemask * from the specified GC. Load the target color into the specified uniform */ void glamor_set_color_depth(ScreenPtr pScreen, int depth, CARD32 pixel, GLint uniform) { glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen); float color[4]; glamor_get_rgba_from_pixel(pixel, &color[0], &color[1], &color[2], &color[3], format_for_depth(depth)); if ((depth == 1 || depth == 8) && glamor_priv->one_channel_format == GL_RED) color[0] = color[3]; glUniform4fv(uniform, 1, color); } Bool glamor_set_solid(PixmapPtr pixmap, GCPtr gc, Bool use_alu, GLint uniform) { CARD32 pixel; int alu = use_alu ? gc->alu : GXcopy; if (!glamor_set_planemask(gc->depth, gc->planemask)) return FALSE; pixel = gc->fgPixel; if (!glamor_set_alu(pixmap->drawable.pScreen, alu)) { switch (gc->alu) { case GXclear: pixel = 0; break; case GXcopyInverted: pixel = ~pixel; break; case GXset: pixel = ~0 & gc->planemask; break; default: return FALSE; } } glamor_set_color(pixmap, gc->fgPixel, uniform); return TRUE; } Bool glamor_set_texture_pixmap(PixmapPtr texture, Bool destination_red) { glamor_pixmap_private *texture_priv; texture_priv = glamor_get_pixmap_private(texture); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(texture_priv)) return FALSE; if (glamor_pixmap_priv_is_large(texture_priv)) return FALSE; glamor_bind_texture(glamor_get_screen_private(texture->drawable.pScreen), GL_TEXTURE0, texture_priv->fbo, destination_red); /* we're not setting the sampler uniform here as we always use * GL_TEXTURE0, and the default value for uniforms is zero. So, * save a bit of CPU time by taking advantage of that. */ return TRUE; } Bool glamor_set_texture(PixmapPtr texture, Bool destination_red, int off_x, int off_y, GLint offset_uniform, GLint size_inv_uniform) { if (!glamor_set_texture_pixmap(texture, destination_red)) return FALSE; glUniform2f(offset_uniform, off_x, off_y); glUniform2f(size_inv_uniform, 1.0f/texture->drawable.width, 1.0f/texture->drawable.height); return TRUE; } Bool glamor_set_tiled(PixmapPtr pixmap, GCPtr gc, GLint offset_uniform, GLint size_inv_uniform) { if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu)) return FALSE; if (!glamor_set_planemask(gc->depth, gc->planemask)) return FALSE; return glamor_set_texture(gc->tile.pixmap, TRUE, -gc->patOrg.x, -gc->patOrg.y, offset_uniform, size_inv_uniform); } static PixmapPtr glamor_get_stipple_pixmap(GCPtr gc) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); ScreenPtr screen = gc->pScreen; PixmapPtr bitmap; PixmapPtr pixmap; GCPtr scratch_gc; ChangeGCVal changes[2]; if (gc_priv->stipple) return gc_priv->stipple; bitmap = gc->stipple; if (!bitmap) goto bail; pixmap = glamor_create_pixmap(screen, bitmap->drawable.width, bitmap->drawable.height, 8, GLAMOR_CREATE_NO_LARGE); if (!pixmap) goto bail; scratch_gc = GetScratchGC(8, screen); if (!scratch_gc) goto bail_pixmap; changes[0].val = 0xff; changes[1].val = 0x00; if (ChangeGC(NullClient, scratch_gc, GCForeground|GCBackground, changes) != Success) goto bail_gc; ValidateGC(&pixmap->drawable, scratch_gc); (*scratch_gc->ops->CopyPlane)(&bitmap->drawable, &pixmap->drawable, scratch_gc, 0, 0, bitmap->drawable.width, bitmap->drawable.height, 0, 0, 0x1); FreeScratchGC(scratch_gc); gc_priv->stipple = pixmap; glamor_track_stipple(gc); return pixmap; bail_gc: FreeScratchGC(scratch_gc); bail_pixmap: glamor_destroy_pixmap(pixmap); bail: return NULL; } Bool glamor_set_stippled(PixmapPtr pixmap, GCPtr gc, GLint fg_uniform, GLint offset_uniform, GLint size_uniform) { PixmapPtr stipple; stipple = glamor_get_stipple_pixmap(gc); if (!stipple) return FALSE; if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform)) return FALSE; return glamor_set_texture(stipple, FALSE, -gc->patOrg.x, -gc->patOrg.y, offset_uniform, size_uniform); } xorg-server-1.20.13/glamor/glamor_transform.h0000644000175000017500000000736214100573756016110 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _GLAMOR_TRANSFORM_H_ #define _GLAMOR_TRANSFORM_H_ Bool glamor_set_destination_drawable(DrawablePtr drawable, int box_index, Bool do_drawable_translate, Bool center_offset, GLint matrix_uniform_location, int *p_off_x, int *p_off_y); void glamor_set_color_depth(ScreenPtr pScreen, int depth, CARD32 pixel, GLint uniform); static inline void glamor_set_color(PixmapPtr pixmap, CARD32 pixel, GLint uniform) { glamor_set_color_depth(pixmap->drawable.pScreen, pixmap->drawable.depth, pixel, uniform); } Bool glamor_set_texture_pixmap(PixmapPtr texture, Bool destination_red); Bool glamor_set_texture(PixmapPtr texture, Bool destination_red, int off_x, int off_y, GLint offset_uniform, GLint size_uniform); Bool glamor_set_solid(PixmapPtr pixmap, GCPtr gc, Bool use_alu, GLint uniform); Bool glamor_set_tiled(PixmapPtr pixmap, GCPtr gc, GLint offset_uniform, GLint size_uniform); Bool glamor_set_stippled(PixmapPtr pixmap, GCPtr gc, GLint fg_uniform, GLint offset_uniform, GLint size_uniform); /* * Vertex shader bits that transform X coordinates to pixmap * coordinates using the matrix computed above */ #define GLAMOR_DECLARE_MATRIX "uniform vec4 v_matrix;\n" #define GLAMOR_X_POS(x) #x " *v_matrix.x + v_matrix.y" #define GLAMOR_Y_POS(y) #y " *v_matrix.z + v_matrix.w" #if 0 #define GLAMOR_POS(dst,src) \ " " #dst ".x = " #src ".x * v_matrix.x + v_matrix.y;\n" \ " " #dst ".y = " #src ".y * v_matrix.z + v_matrix.w;\n" \ " " #dst ".z = 0.0;\n" \ " " #dst ".w = 1.0;\n" #endif #define GLAMOR_POS(dst,src) \ " " #dst ".xy = " #src ".xy * v_matrix.xz + v_matrix.yw;\n" \ " " #dst ".zw = vec2(0.0,1.0);\n" #endif /* _GLAMOR_TRANSFORM_H_ */ xorg-server-1.20.13/glamor/glamor_trapezoid.c0000644000175000017500000001175514100573756016072 00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Junyan He * */ /** @file glamor_trapezoid.c * * Trapezoid acceleration implementation */ #include "glamor_priv.h" #include "mipict.h" #include "fbpict.h" /** * Creates an appropriate picture for temp mask use. */ static PicturePtr glamor_create_mask_picture(ScreenPtr screen, PicturePtr dst, PictFormatPtr pict_format, CARD16 width, CARD16 height) { PixmapPtr pixmap; PicturePtr picture; int error; if (!pict_format) { if (dst->polyEdge == PolyEdgeSharp) pict_format = PictureMatchFormat(screen, 1, PICT_a1); else pict_format = PictureMatchFormat(screen, 8, PICT_a8); if (!pict_format) return 0; } pixmap = glamor_create_pixmap(screen, 0, 0, pict_format->depth, GLAMOR_CREATE_PIXMAP_CPU); if (!pixmap) return 0; picture = CreatePicture(0, &pixmap->drawable, pict_format, 0, 0, serverClient, &error); glamor_destroy_pixmap(pixmap); return picture; } /** * glamor_trapezoids will generate trapezoid mask accumulating in * system memory. */ void glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid *traps) { ScreenPtr screen = dst->pDrawable->pScreen; BoxRec bounds; PicturePtr picture; INT16 x_dst, y_dst; INT16 x_rel, y_rel; int width, height, stride; PixmapPtr pixmap; pixman_image_t *image = NULL; /* If a mask format wasn't provided, we get to choose, but behavior should * be as if there was no temporary mask the traps were accumulated into. */ if (!mask_format) { if (dst->polyEdge == PolyEdgeSharp) mask_format = PictureMatchFormat(screen, 1, PICT_a1); else mask_format = PictureMatchFormat(screen, 8, PICT_a8); for (; ntrap; ntrap--, traps++) glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, 1, traps); return; } miTrapezoidBounds(ntrap, traps, &bounds); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; x_dst = traps[0].left.p1.x >> 16; y_dst = traps[0].left.p1.y >> 16; width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; stride = PixmapBytePad(width, mask_format->depth); picture = glamor_create_mask_picture(screen, dst, mask_format, width, height); if (!picture) return; image = pixman_image_create_bits(picture->format, width, height, NULL, stride); if (!image) { FreePicture(picture, 0); return; } for (; ntrap; ntrap--, traps++) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, -bounds.x1, -bounds.y1); pixmap = glamor_get_drawable_pixmap(picture->pDrawable); screen->ModifyPixmapHeader(pixmap, width, height, mask_format->depth, BitsPerPixel(mask_format->depth), PixmapBytePad(width, mask_format->depth), pixman_image_get_data(image)); x_rel = bounds.x1 + x_src - x_dst; y_rel = bounds.y1 + y_src - y_dst; CompositePicture(op, src, picture, dst, x_rel, y_rel, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); if (image) pixman_image_unref(image); FreePicture(picture, 0); } xorg-server-1.20.13/glamor/glamor_triangles.c0000644000175000017500000000337314100573756016056 00000000000000/* * Copyright © 2009 Intel Corporation * Copyright © 1998 Keith Packard * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Zhigang Gong * */ #include "glamor_priv.h" void glamor_triangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris) { if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW) && glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) { fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris); } glamor_finish_access_picture(pSrc); glamor_finish_access_picture(pDst); } xorg-server-1.20.13/glamor/glamor_addtraps.c0000644000175000017500000000306514100573756015666 00000000000000/* * Copyright © 2009 Intel Corporation * Copyright © 1998 Keith Packard * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Zhigang Gong * */ #include "glamor_priv.h" void glamor_add_traps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap *traps) { if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) { fbAddTraps(pPicture, x_off, y_off, ntrap, traps); } glamor_finish_access_picture(pPicture); } xorg-server-1.20.13/glamor/glamor_glyphblt.c0000644000175000017500000002050614100573756015710 00000000000000/* * Copyright © 2009 Intel Corporation * Copyright © 1998 Keith Packard * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Zhigang Gong * */ #include "glamor_priv.h" #include #include "glamor_transform.h" static const glamor_facet glamor_facet_poly_glyph_blt = { .name = "poly_glyph_blt", .vs_vars = "attribute vec2 primitive;\n", .vs_exec = (" vec2 pos = vec2(0,0);\n" GLAMOR_POS(gl_Position, primitive)), }; static Bool glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, int start_x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyph_base) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; glamor_program *prog; RegionPtr clip = gc->pCompositeClip; int box_index; Bool ret = FALSE; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; glamor_make_current(glamor_priv); prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_glyph_blt_progs, &glamor_facet_poly_glyph_blt); if (!prog) goto bail; glEnableVertexAttribArray(GLAMOR_VERTEX_POS); start_x += drawable->x; y += drawable->y; glamor_pixmap_loop(pixmap_priv, box_index) { int x; int n; int num_points, max_points; INT16 *points = NULL; int off_x, off_y; char *vbo_offset; if (!glamor_set_destination_drawable(drawable, box_index, FALSE, TRUE, prog->matrix_uniform, &off_x, &off_y)) goto bail; max_points = 500; num_points = 0; x = start_x; for (n = 0; n < nglyph; n++) { CharInfoPtr charinfo = ppci[n]; int w = GLYPHWIDTHPIXELS(charinfo); int h = GLYPHHEIGHTPIXELS(charinfo); uint8_t *glyphbits = FONTGLYPHBITS(NULL, charinfo); if (w && h) { int glyph_x = x + charinfo->metrics.leftSideBearing; int glyph_y = y - charinfo->metrics.ascent; int glyph_stride = GLYPHWIDTHBYTESPADDED(charinfo); int xx, yy; for (yy = 0; yy < h; yy++) { uint8_t *glyph = glyphbits; for (xx = 0; xx < w; glyph += ((xx&7) == 7), xx++) { int pt_x_i = glyph_x + xx; int pt_y_i = glyph_y + yy; if (!(*glyph & (1 << (xx & 7)))) continue; if (!RegionContainsPoint(clip, pt_x_i, pt_y_i, NULL)) continue; if (!num_points) { points = glamor_get_vbo_space(screen, max_points * (2 * sizeof (INT16)), &vbo_offset); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 0, vbo_offset); } *points++ = pt_x_i; *points++ = pt_y_i; num_points++; if (num_points == max_points) { glamor_put_vbo_space(screen); glDrawArrays(GL_POINTS, 0, num_points); num_points = 0; } } glyphbits += glyph_stride; } } x += charinfo->metrics.characterWidth; } if (num_points) { glamor_put_vbo_space(screen); glDrawArrays(GL_POINTS, 0, num_points); } } ret = TRUE; bail: glDisableVertexAttribArray(GLAMOR_VERTEX_POS); return ret; } void glamor_poly_glyph_blt(DrawablePtr drawable, GCPtr gc, int start_x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyph_base) { if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base)) return; miPolyGlyphBlt(drawable, gc, start_x, y, nglyph, ppci, pglyph_base); } static Bool glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable, int w, int h, int x, int y) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; uint8_t *bitmap_data = bitmap->devPrivate.ptr; int bitmap_stride = bitmap->devKind; glamor_program *prog; RegionPtr clip = gc->pCompositeClip; int box_index; int yy, xx; int num_points; INT16 *points = NULL; char *vbo_offset; Bool ret = FALSE; if (w * h > MAXINT / (2 * sizeof(float))) goto bail; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; glamor_make_current(glamor_priv); prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_glyph_blt_progs, &glamor_facet_poly_glyph_blt); if (!prog) goto bail; glEnableVertexAttribArray(GLAMOR_VERTEX_POS); points = glamor_get_vbo_space(screen, w * h * sizeof(INT16) * 2, &vbo_offset); num_points = 0; /* Note that because fb sets miTranslate in the GC, our incoming X * and Y are in screen coordinate space (same for spans, but not * other operations). */ for (yy = 0; yy < h; yy++) { uint8_t *bitmap_row = bitmap_data + yy * bitmap_stride; for (xx = 0; xx < w; xx++) { if (bitmap_row[xx / 8] & (1 << xx % 8) && RegionContainsPoint(clip, x + xx, y + yy, NULL)) { *points++ = x + xx; *points++ = y + yy; num_points++; } } } glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 0, vbo_offset); glamor_put_vbo_space(screen); glamor_pixmap_loop(pixmap_priv, box_index) { if (!glamor_set_destination_drawable(drawable, box_index, FALSE, TRUE, prog->matrix_uniform, NULL, NULL)) goto bail; glDrawArrays(GL_POINTS, 0, num_points); } ret = TRUE; bail: glDisableVertexAttribArray(GLAMOR_VERTEX_POS); return ret; } void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y) { if (glamor_push_pixels_gl(pGC, pBitmap, pDrawable, w, h, x, y)) return; miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); } xorg-server-1.20.13/glamor/glamor_points.c0000644000175000017500000000776114100573756015407 00000000000000/* * Copyright © 2009 Intel Corporation * Copyright © 1998 Keith Packard * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Zhigang Gong * */ #include "glamor_priv.h" #include "glamor_transform.h" static const glamor_facet glamor_facet_point = { .name = "poly_point", .vs_vars = "attribute vec2 primitive;\n", .vs_exec = GLAMOR_POS(gl_Position, primitive), }; static Bool glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPointPtr ppt) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_program *prog = &glamor_priv->point_prog; glamor_pixmap_private *pixmap_priv; int off_x, off_y; GLshort *vbo_ppt; char *vbo_offset; int box_index; Bool ret = FALSE; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; glamor_make_current(glamor_priv); if (prog->failed) goto bail; if (!prog->prog) { if (!glamor_build_program(screen, prog, &glamor_facet_point, &glamor_fill_solid, NULL, NULL)) goto bail; } if (!glamor_use_program(pixmap, gc, prog, NULL)) goto bail; vbo_ppt = glamor_get_vbo_space(screen, npt * (2 * sizeof (INT16)), &vbo_offset); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 0, vbo_offset); if (mode == CoordModePrevious) { int n = npt; INT16 x = 0, y = 0; while (n--) { vbo_ppt[0] = (x += ppt->x); vbo_ppt[1] = (y += ppt->y); vbo_ppt += 2; ppt++; } } else memcpy(vbo_ppt, ppt, npt * (2 * sizeof (INT16))); glamor_put_vbo_space(screen); glEnable(GL_SCISSOR_TEST); glamor_pixmap_loop(pixmap_priv, box_index) { int nbox = RegionNumRects(gc->pCompositeClip); BoxPtr box = RegionRects(gc->pCompositeClip); if (!glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y)) goto bail; while (nbox--) { glScissor(box->x1 + off_x, box->y1 + off_y, box->x2 - box->x1, box->y2 - box->y1); box++; glDrawArrays(GL_POINTS, 0, npt); } } ret = TRUE; bail: glDisable(GL_SCISSOR_TEST); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); return ret; } void glamor_poly_point(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPointPtr ppt) { if (glamor_poly_point_gl(drawable, gc, mode, npt, ppt)) return; miPolyPoint(drawable, gc, mode, npt, ppt); } xorg-server-1.20.13/glamor/glamor_priv.h0000644000175000017500000007005714100573756015056 00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Eric Anholt * */ #ifndef GLAMOR_PRIV_H #define GLAMOR_PRIV_H #include "dix-config.h" #include "glamor.h" #include "xvdix.h" #if XSYNC #include "misyncshm.h" #include "misyncstr.h" #endif #include #ifdef GLAMOR_HAS_GBM #define MESA_EGL_NO_X11_HEADERS #define EGL_NO_X11 #include #endif #define GLAMOR_DEFAULT_PRECISION \ "#ifdef GL_ES\n" \ "precision mediump float;\n" \ "#endif\n" #include "glyphstr.h" #include "glamor_debug.h" #include "glamor_context.h" #include "glamor_program.h" #include struct glamor_pixmap_private; typedef struct glamor_composite_shader { GLuint prog; GLint dest_to_dest_uniform_location; GLint dest_to_source_uniform_location; GLint dest_to_mask_uniform_location; GLint source_uniform_location; GLint mask_uniform_location; GLint source_wh; GLint mask_wh; GLint source_repeat_mode; GLint mask_repeat_mode; union { float source_solid_color[4]; struct { PixmapPtr source_pixmap; PicturePtr source; }; }; union { float mask_solid_color[4]; struct { PixmapPtr mask_pixmap; PicturePtr mask; }; }; } glamor_composite_shader; enum ca_state { CA_NONE, CA_TWO_PASS, CA_DUAL_BLEND, }; enum shader_source { SHADER_SOURCE_SOLID, SHADER_SOURCE_TEXTURE, SHADER_SOURCE_TEXTURE_ALPHA, SHADER_SOURCE_COUNT, }; enum shader_mask { SHADER_MASK_NONE, SHADER_MASK_SOLID, SHADER_MASK_TEXTURE, SHADER_MASK_TEXTURE_ALPHA, SHADER_MASK_COUNT, }; enum shader_dest_swizzle { SHADER_DEST_SWIZZLE_DEFAULT, SHADER_DEST_SWIZZLE_ALPHA_TO_RED, SHADER_DEST_SWIZZLE_COUNT, }; struct shader_key { enum shader_source source; enum shader_mask mask; glamor_program_alpha in; enum shader_dest_swizzle dest_swizzle; }; struct blendinfo { Bool dest_alpha; Bool source_alpha; GLenum source_blend; GLenum dest_blend; }; typedef struct { INT16 x_src; INT16 y_src; INT16 x_mask; INT16 y_mask; INT16 x_dst; INT16 y_dst; INT16 width; INT16 height; } glamor_composite_rect_t; enum glamor_vertex_type { GLAMOR_VERTEX_POS, GLAMOR_VERTEX_SOURCE, GLAMOR_VERTEX_MASK }; enum gradient_shader { SHADER_GRADIENT_LINEAR, SHADER_GRADIENT_RADIAL, SHADER_GRADIENT_CONICAL, SHADER_GRADIENT_COUNT, }; struct glamor_screen_private; struct glamor_pixmap_private; enum glamor_gl_flavor { GLAMOR_GL_DESKTOP, // OPENGL API GLAMOR_GL_ES2 // OPENGL ES2.0 API }; #define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024) struct glamor_saved_procs { CloseScreenProcPtr close_screen; CreateGCProcPtr create_gc; CreatePixmapProcPtr create_pixmap; DestroyPixmapProcPtr destroy_pixmap; GetSpansProcPtr get_spans; GetImageProcPtr get_image; CompositeProcPtr composite; CompositeRectsProcPtr composite_rects; TrapezoidsProcPtr trapezoids; GlyphsProcPtr glyphs; ChangeWindowAttributesProcPtr change_window_attributes; CopyWindowProcPtr copy_window; BitmapToRegionProcPtr bitmap_to_region; TrianglesProcPtr triangles; AddTrapsProcPtr addtraps; #if XSYNC SyncScreenFuncsRec sync_screen_funcs; #endif ScreenBlockHandlerProcPtr block_handler; }; typedef struct glamor_screen_private { enum glamor_gl_flavor gl_flavor; int glsl_version; Bool has_pack_invert; Bool has_fbo_blit; Bool has_map_buffer_range; Bool has_buffer_storage; Bool has_khr_debug; Bool has_mesa_tile_raster_order; Bool has_nv_texture_barrier; Bool has_pack_subimage; Bool has_unpack_subimage; Bool has_rw_pbo; Bool use_quads; Bool has_dual_blend; Bool has_texture_swizzle; Bool is_core_profile; Bool can_copyplane; int max_fbo_size; GLuint one_channel_format; /* glamor point shader */ glamor_program point_prog; /* glamor spans shaders */ glamor_program_fill fill_spans_program; /* glamor rect shaders */ glamor_program_fill poly_fill_rect_program; /* glamor glyphblt shaders */ glamor_program_fill poly_glyph_blt_progs; /* glamor text shaders */ glamor_program_fill poly_text_progs; glamor_program te_text_prog; glamor_program image_text_prog; /* glamor copy shaders */ glamor_program copy_area_prog; glamor_program copy_plane_prog; /* glamor line shader */ glamor_program_fill poly_line_program; /* glamor segment shaders */ glamor_program_fill poly_segment_program; /* glamor dash line shader */ glamor_program_fill on_off_dash_line_progs; glamor_program double_dash_line_prog; /* glamor composite_glyphs shaders */ glamor_program_render glyphs_program; struct glamor_glyph_atlas *glyph_atlas_a; struct glamor_glyph_atlas *glyph_atlas_argb; int glyph_atlas_dim; int glyph_max_dim; char *glyph_defines; /** Vertex buffer for all GPU rendering. */ GLuint vao; GLuint vbo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ int vbo_offset; int vbo_size; Bool vbo_mapped; /** * Pointer to glamor_get_vbo_space()'s current VBO mapping. * * Note that this is not necessarily equal to the pointer returned * by glamor_get_vbo_space(), so it can't be used in place of that. */ char *vb; int vb_stride; /** Cached index buffer for translating GL_QUADS to triangles. */ GLuint ib; /** Index buffer type: GL_UNSIGNED_SHORT or GL_UNSIGNED_INT */ GLenum ib_type; /** Number of quads the index buffer has indices for. */ unsigned ib_size; Bool has_source_coords, has_mask_coords; int render_nr_quads; glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] [SHADER_MASK_COUNT] [glamor_program_alpha_count] [SHADER_DEST_SWIZZLE_COUNT]; /* glamor gradient, 0 for small nstops, 1 for large nstops and 2 for dynamic generate. */ GLint gradient_prog[SHADER_GRADIENT_COUNT][3]; int linear_max_nstops; int radial_max_nstops; struct glamor_saved_procs saved_procs; GetDrawableModifiersFuncPtr get_drawable_modifiers; int flags; ScreenPtr screen; int dri3_enabled; Bool suppress_gl_out_of_memory_logging; Bool logged_any_fbo_allocation_failure; Bool logged_any_pbo_allocation_failure; /* xv */ glamor_program xv_prog; struct glamor_context ctx; } glamor_screen_private; typedef enum glamor_access { GLAMOR_ACCESS_RO, GLAMOR_ACCESS_RW, } glamor_access_t; enum glamor_fbo_state { /** There is no storage attached to the pixmap. */ GLAMOR_FBO_UNATTACHED, /** * The pixmap has FBO storage attached, but devPrivate.ptr doesn't * point at anything. */ GLAMOR_FBO_NORMAL, }; typedef struct glamor_pixmap_fbo { GLuint tex; /**< GL texture name */ GLuint fb; /**< GL FBO name */ int width; /**< width in pixels */ int height; /**< height in pixels */ GLenum format; /**< GL format used to create the texture. */ GLenum type; /**< GL type used to create the texture. */ } glamor_pixmap_fbo; typedef struct glamor_pixmap_clipped_regions { int block_idx; RegionPtr region; } glamor_pixmap_clipped_regions; typedef struct glamor_pixmap_private { glamor_pixmap_type_t type; enum glamor_fbo_state gl_fbo; /** * If devPrivate.ptr is non-NULL (meaning we're within * glamor_prepare_access), determies whether we should re-upload * that data on glamor_finish_access(). */ glamor_access_t map_access; glamor_pixmap_fbo *fbo; /** current fbo's coords in the whole pixmap. */ BoxRec box; GLuint pbo; RegionRec prepare_region; Bool prepared; #ifdef GLAMOR_HAS_GBM EGLImageKHR image; Bool used_modifiers; #endif /** block width of this large pixmap. */ int block_w; /** block height of this large pixmap. */ int block_h; /** block_wcnt: block count in one block row. */ int block_wcnt; /** block_hcnt: block count in one block column. */ int block_hcnt; /** * The list of boxes for the bounds of the FBOs making up the * pixmap. * * For a 2048x2048 pixmap with GL FBO size limits of 1024x1024: * * ****************** * * fbo0 * fbo1 * * * * * * ****************** * * fbo2 * fbo3 * * * * * * ****************** * * box[0] = {0,0,1024,1024} * box[1] = {1024,0,2048,2048} * ... */ BoxPtr box_array; /** * Array of fbo structs containing the actual GL texture/fbo * names. */ glamor_pixmap_fbo **fbo_array; } glamor_pixmap_private; extern DevPrivateKeyRec glamor_pixmap_private_key; static inline glamor_pixmap_private * glamor_get_pixmap_private(PixmapPtr pixmap) { if (pixmap == NULL) return NULL; return dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key); } /* * Returns TRUE if pixmap has no image object */ static inline Bool glamor_pixmap_drm_only(PixmapPtr pixmap) { glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); return priv->type == GLAMOR_DRM_ONLY; } /* * Returns TRUE if pixmap is plain memory (not a GL object at all) */ static inline Bool glamor_pixmap_is_memory(PixmapPtr pixmap) { glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); return priv->type == GLAMOR_MEMORY; } /* * Returns TRUE if pixmap requires multiple textures to hold it */ static inline Bool glamor_pixmap_priv_is_large(glamor_pixmap_private *priv) { return priv->block_wcnt > 1 || priv->block_hcnt > 1; } static inline Bool glamor_pixmap_priv_is_small(glamor_pixmap_private *priv) { return priv->block_wcnt <= 1 && priv->block_hcnt <= 1; } static inline Bool glamor_pixmap_is_large(PixmapPtr pixmap) { glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); return glamor_pixmap_priv_is_large(priv); } /* * Returns TRUE if pixmap has an FBO */ static inline Bool glamor_pixmap_has_fbo(PixmapPtr pixmap) { glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); return priv->gl_fbo == GLAMOR_FBO_NORMAL; } static inline void glamor_set_pixmap_fbo_current(glamor_pixmap_private *priv, int idx) { if (glamor_pixmap_priv_is_large(priv)) { priv->fbo = priv->fbo_array[idx]; priv->box = priv->box_array[idx]; } } static inline glamor_pixmap_fbo * glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int box) { assert(box < priv->block_wcnt * priv->block_hcnt); return priv->fbo_array[box]; } static inline BoxPtr glamor_pixmap_box_at(glamor_pixmap_private *priv, int box) { assert(box < priv->block_wcnt * priv->block_hcnt); return &priv->box_array[box]; } static inline int glamor_pixmap_wcnt(glamor_pixmap_private *priv) { return priv->block_wcnt; } static inline int glamor_pixmap_hcnt(glamor_pixmap_private *priv) { return priv->block_hcnt; } #define glamor_pixmap_loop(priv, box_index) \ for (box_index = 0; box_index < glamor_pixmap_hcnt(priv) * \ glamor_pixmap_wcnt(priv); box_index++) \ /* GC private structure. Currently holds only any computed dash pixmap */ typedef struct { PixmapPtr dash; PixmapPtr stipple; DamagePtr stipple_damage; } glamor_gc_private; extern DevPrivateKeyRec glamor_gc_private_key; extern DevPrivateKeyRec glamor_screen_private_key; extern glamor_screen_private * glamor_get_screen_private(ScreenPtr screen); extern void glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv); static inline glamor_gc_private * glamor_get_gc_private(GCPtr gc) { return dixLookupPrivate(&gc->devPrivates, &glamor_gc_private_key); } /** * Returns TRUE if the given planemask covers all the significant bits in the * pixel values for pDrawable. */ static inline Bool glamor_pm_is_solid(int depth, unsigned long planemask) { return (planemask & FbFullMask(depth)) == FbFullMask(depth); } extern int glamor_debug_level; /* glamor.c */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); glamor_pixmap_fbo *glamor_pixmap_detach_fbo(glamor_pixmap_private * pixmap_priv); void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo); glamor_pixmap_fbo *glamor_create_fbo_from_tex(glamor_screen_private * glamor_priv, int w, int h, GLenum format, GLint tex, int flag); glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private *glamor_priv, int w, int h, GLenum format, int flag); void glamor_destroy_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo); void glamor_pixmap_destroy_fbo(PixmapPtr pixmap); Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap); void glamor_pixmap_clear_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo); /* Return whether 'picture' is alpha-only */ static inline Bool glamor_picture_is_alpha(PicturePtr picture) { return picture->format == PICT_a1 || picture->format == PICT_a8; } /* Return whether 'fbo' is storing alpha bits in the red channel */ static inline Bool glamor_fbo_red_is_alpha(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo) { /* True when the format is GL_RED (that can only happen when our one channel format is GL_RED */ return fbo->format == GL_RED; } /* Return whether 'picture' is storing alpha bits in the red channel */ static inline Bool glamor_picture_red_is_alpha(PicturePtr picture) { /* True when the picture is alpha only and the screen is using GL_RED for alpha pictures */ return glamor_picture_is_alpha(picture) && glamor_get_screen_private(picture->pDrawable->pScreen)->one_channel_format == GL_RED; } void glamor_bind_texture(glamor_screen_private *glamor_priv, GLenum texture, glamor_pixmap_fbo *fbo, Bool destination_red); glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv, int w, int h, GLenum format, int flag, int block_w, int block_h, glamor_pixmap_private *); void glamor_gldrawarrays_quads_using_indices(glamor_screen_private *glamor_priv, unsigned count); /* glamor_core.c */ Bool glamor_get_drawable_location(const DrawablePtr drawable); void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int *x, int *y); GLint glamor_compile_glsl_prog(GLenum type, const char *source); void glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4); void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, GLfloat *color); int glamor_set_destination_pixmap(PixmapPtr pixmap); int glamor_set_destination_pixmap_priv(glamor_screen_private *glamor_priv, PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv); void glamor_set_destination_pixmap_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *, int, int, int, int); /* nc means no check. caller must ensure this pixmap has valid fbo. * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. * */ void glamor_set_destination_pixmap_priv_nc(glamor_screen_private *glamor_priv, PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv); Bool glamor_set_alu(ScreenPtr screen, unsigned char alu); Bool glamor_set_planemask(int depth, unsigned long planemask); RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); void glamor_track_stipple(GCPtr gc); /* glamor_render.c */ Bool glamor_composite_clipped_region(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, PixmapPtr source_pixmap, PixmapPtr mask_pixmap, PixmapPtr dest_pixmap, RegionPtr region, int x_source, int y_source, int x_mask, int y_mask, int x_dest, int y_dest); void glamor_composite(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 glamor_composite_rects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect, xRectangle *rects); /* glamor_trapezoid.c */ void glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid *traps); /* glamor_gradient.c */ void glamor_init_gradient_shader(ScreenPtr screen); PicturePtr glamor_generate_linear_gradient_picture(ScreenPtr screen, PicturePtr src_picture, int x_source, int y_source, int width, int height, PictFormatShort format); PicturePtr glamor_generate_radial_gradient_picture(ScreenPtr screen, PicturePtr src_picture, int x_source, int y_source, int width, int height, PictFormatShort format); /* glamor_triangles.c */ void glamor_triangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris); /* glamor_pixmap.c */ void glamor_pixmap_init(ScreenPtr screen); void glamor_pixmap_fini(ScreenPtr screen); /* glamor_vbo.c */ void glamor_init_vbo(ScreenPtr screen); void glamor_fini_vbo(ScreenPtr screen); void * glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset); void glamor_put_vbo_space(ScreenPtr screen); /** * According to the flag, * if the flag is GLAMOR_CREATE_FBO_NO_FBO then just ensure * the fbo has a valid texture. Otherwise, it will ensure * the fbo has valid texture and attach to a valid fb. * If the fbo already has a valid glfbo then do nothing. */ Bool glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag); glamor_pixmap_clipped_regions * glamor_compute_clipped_regions(PixmapPtr pixmap, RegionPtr region, int *clipped_nbox, int repeat_type, int reverse, int upsidedown); glamor_pixmap_clipped_regions * glamor_compute_clipped_regions_ext(PixmapPtr pixmap, RegionPtr region, int *n_region, int inner_block_w, int inner_block_h, int reverse, int upsidedown); Bool glamor_composite_largepixmap_region(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, PixmapPtr source_pixmap, PixmapPtr mask_pixmap, PixmapPtr dest_pixmap, RegionPtr region, Bool force_clip, INT16 x_source, INT16 y_source, INT16 x_mask, INT16 y_mask, INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height); /** * Upload a picture to gl texture. Similar to the * glamor_upload_pixmap_to_texture. Used in rendering. **/ Bool glamor_upload_picture_to_texture(PicturePtr picture); void glamor_add_traps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap *traps); /* glamor_text.c */ int glamor_poly_text8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars); int glamor_poly_text16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars); void glamor_image_text8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars); void glamor_image_text16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars); /* glamor_spans.c */ void glamor_fill_spans(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr points, int *widths, int sorted); void glamor_get_spans(DrawablePtr drawable, int wmax, DDXPointPtr points, int *widths, int count, char *dst); void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int numPoints, int sorted); /* glamor_rects.c */ void glamor_poly_fill_rect(DrawablePtr drawable, GCPtr gc, int nrect, xRectangle *prect); /* glamor_image.c */ void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits); void glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); /* glamor_dash.c */ Bool glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points); Bool glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc, int nseg, xSegment *segs); /* glamor_lines.c */ void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points); /* glamor_segs.c */ void glamor_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg, xSegment *segs); /* glamor_copy.c */ void glamor_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); RegionPtr glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, int srcx, int srcy, int width, int height, int dstx, int dsty); RegionPtr glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc, int srcx, int srcy, int width, int height, int dstx, int dsty, unsigned long bitplane); /* glamor_glyphblt.c */ void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyphBase); void glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyphBase); void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y); void glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt); void glamor_composite_rectangles(CARD8 op, PicturePtr dst, xRenderColor *color, int num_rects, xRectangle *rects); /* glamor_composite_glyphs.c */ Bool glamor_composite_glyphs_init(ScreenPtr pScreen); void glamor_composite_glyphs_fini(ScreenPtr pScreen); void glamor_composite_glyphs(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr *glyphs); /* glamor_sync.c */ Bool glamor_sync_init(ScreenPtr screen); void glamor_sync_close(ScreenPtr screen); /* glamor_util.c */ void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, unsigned long fg_pixel); void glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, unsigned long fg_pixel); /* glamor_xv */ typedef struct { uint32_t transform_index; uint32_t gamma; /* gamma value x 1000 */ int brightness; int saturation; int hue; int contrast; DrawablePtr pDraw; PixmapPtr pPixmap; uint32_t src_pitch; uint8_t *src_addr; int src_w, src_h, dst_w, dst_h; int src_x, src_y, drw_x, drw_y; int w, h; RegionRec clip; PixmapPtr src_pix[3]; /* y, u, v for planar */ int src_pix_w, src_pix_h; } glamor_port_private; extern XvAttributeRec glamor_xv_attributes[]; extern int glamor_xv_num_attributes; extern XvImageRec glamor_xv_images[]; extern int glamor_xv_num_images; void glamor_xv_init_port(glamor_port_private *port_priv); void glamor_xv_stop_video(glamor_port_private *port_priv); int glamor_xv_set_port_attribute(glamor_port_private *port_priv, Atom attribute, INT32 value); int glamor_xv_get_port_attribute(glamor_port_private *port_priv, Atom attribute, INT32 *value); int glamor_xv_query_image_attributes(int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets); int glamor_xv_put_image(glamor_port_private *port_priv, DrawablePtr pDrawable, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, int id, unsigned char *buf, short width, short height, Bool sync, RegionPtr clipBoxes); void glamor_xv_core_init(ScreenPtr screen); void glamor_xv_render(glamor_port_private *port_priv); #include "glamor_utils.h" #if 0 #define MAX_FBO_SIZE 32 /* For test purpose only. */ #endif #include "glamor_font.h" #define GLAMOR_MIN_ALU_INSTRUCTIONS 128 /* Minimum required number of native ALU instructions */ #endif /* GLAMOR_PRIV_H */ xorg-server-1.20.13/glamor/glamor_pixmap.c0000644000175000017500000001174214100573756015363 00000000000000/* * Copyright © 2001 Keith Packard * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Eric Anholt * Zhigang Gong * */ #include #include "glamor_priv.h" /** * Sets the offsets to add to coordinates to make them address the same bits in * the backing drawable. These coordinates are nonzero only for redirected * windows. */ void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int *x, int *y) { #ifdef COMPOSITE if (drawable->type == DRAWABLE_WINDOW) { *x = -pixmap->screen_x; *y = -pixmap->screen_y; return; } #endif *x = 0; *y = 0; } void glamor_pixmap_init(ScreenPtr screen) { } void glamor_pixmap_fini(ScreenPtr screen) { } void glamor_set_destination_pixmap_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo, int x0, int y0, int width, int height) { glamor_make_current(glamor_priv); glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); glViewport(x0, y0, width, height); } void glamor_set_destination_pixmap_priv_nc(glamor_screen_private *glamor_priv, PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv) { int w, h; PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, pixmap_priv, w, h); glamor_set_destination_pixmap_fbo(glamor_priv, pixmap_priv->fbo, 0, 0, w, h); } int glamor_set_destination_pixmap_priv(glamor_screen_private *glamor_priv, PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv) { if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return -1; glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv); return 0; } int glamor_set_destination_pixmap(PixmapPtr pixmap) { int err; glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); err = glamor_set_destination_pixmap_priv(glamor_priv, pixmap, pixmap_priv); return err; } Bool glamor_set_planemask(int depth, unsigned long planemask) { if (glamor_pm_is_solid(depth, planemask)) { return GL_TRUE; } glamor_fallback("unsupported planemask %lx\n", planemask); return GL_FALSE; } Bool glamor_set_alu(ScreenPtr screen, unsigned char alu) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { if (alu != GXcopy) return FALSE; else return TRUE; } if (alu == GXcopy) { glDisable(GL_COLOR_LOGIC_OP); return TRUE; } glEnable(GL_COLOR_LOGIC_OP); switch (alu) { case GXclear: glLogicOp(GL_CLEAR); break; case GXand: glLogicOp(GL_AND); break; case GXandReverse: glLogicOp(GL_AND_REVERSE); break; case GXandInverted: glLogicOp(GL_AND_INVERTED); break; case GXnoop: glLogicOp(GL_NOOP); break; case GXxor: glLogicOp(GL_XOR); break; case GXor: glLogicOp(GL_OR); break; case GXnor: glLogicOp(GL_NOR); break; case GXequiv: glLogicOp(GL_EQUIV); break; case GXinvert: glLogicOp(GL_INVERT); break; case GXorReverse: glLogicOp(GL_OR_REVERSE); break; case GXcopyInverted: glLogicOp(GL_COPY_INVERTED); break; case GXorInverted: glLogicOp(GL_OR_INVERTED); break; case GXnand: glLogicOp(GL_NAND); break; case GXset: glLogicOp(GL_SET); break; default: glamor_fallback("unsupported alu %x\n", alu); return FALSE; } return TRUE; } xorg-server-1.20.13/glamor/glamor_largepixmap.c0000644000175000017500000017023214100573756016376 00000000000000#include #include /* For INT16_MAX */ #include "glamor_priv.h" static void glamor_get_transform_extent_from_box(struct pixman_box32 *box, struct pixman_transform *transform); static inline glamor_pixmap_private * __glamor_large(glamor_pixmap_private *pixmap_priv) { assert(glamor_pixmap_priv_is_large(pixmap_priv)); return pixmap_priv; } /** * Clip the boxes regards to each pixmap's block array. * * Should translate the region to relative coords to the pixmap, * start at (0,0). */ #if 0 //#define DEBUGF(str, ...) do {} while(0) #define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__) //#define DEBUGRegionPrint(x) do {} while (0) #define DEBUGRegionPrint RegionPrint #endif static glamor_pixmap_clipped_regions * __glamor_compute_clipped_regions(int block_w, int block_h, int block_stride, int x, int y, int w, int h, RegionPtr region, int *n_region, int reverse, int upsidedown) { glamor_pixmap_clipped_regions *clipped_regions; BoxPtr extent; int start_x, start_y, end_x, end_y; int start_block_x, start_block_y; int end_block_x, end_block_y; int loop_start_block_x, loop_start_block_y; int loop_end_block_x, loop_end_block_y; int loop_block_stride; int i, j, delta_i, delta_j; RegionRec temp_region; RegionPtr current_region; int block_idx; int k = 0; int temp_block_idx; extent = RegionExtents(region); start_x = MAX(x, extent->x1); start_y = MAX(y, extent->y1); end_x = MIN(x + w, extent->x2); end_y = MIN(y + h, extent->y2); DEBUGF("start compute clipped regions:\n"); DEBUGF("block w %d h %d x %d y %d w %d h %d, block_stride %d \n", block_w, block_h, x, y, w, h, block_stride); DEBUGRegionPrint(region); DEBUGF("start_x %d start_y %d end_x %d end_y %d \n", start_x, start_y, end_x, end_y); if (start_x >= end_x || start_y >= end_y) { *n_region = 0; return NULL; } start_block_x = (start_x - x) / block_w; start_block_y = (start_y - y) / block_h; end_block_x = (end_x - x) / block_w; end_block_y = (end_y - y) / block_h; clipped_regions = calloc((end_block_x - start_block_x + 1) * (end_block_y - start_block_y + 1), sizeof(*clipped_regions)); DEBUGF("startx %d starty %d endx %d endy %d \n", start_x, start_y, end_x, end_y); DEBUGF("start_block_x %d end_block_x %d \n", start_block_x, end_block_x); DEBUGF("start_block_y %d end_block_y %d \n", start_block_y, end_block_y); if (!reverse) { loop_start_block_x = start_block_x; loop_end_block_x = end_block_x + 1; delta_i = 1; } else { loop_start_block_x = end_block_x; loop_end_block_x = start_block_x - 1; delta_i = -1; } if (!upsidedown) { loop_start_block_y = start_block_y; loop_end_block_y = end_block_y + 1; delta_j = 1; } else { loop_start_block_y = end_block_y; loop_end_block_y = start_block_y - 1; delta_j = -1; } loop_block_stride = delta_j * block_stride; block_idx = (loop_start_block_y - delta_j) * block_stride; for (j = loop_start_block_y; j != loop_end_block_y; j += delta_j) { block_idx += loop_block_stride; temp_block_idx = block_idx + loop_start_block_x; for (i = loop_start_block_x; i != loop_end_block_x; i += delta_i, temp_block_idx += delta_i) { BoxRec temp_box; temp_box.x1 = x + i * block_w; temp_box.y1 = y + j * block_h; temp_box.x2 = MIN(temp_box.x1 + block_w, end_x); temp_box.y2 = MIN(temp_box.y1 + block_h, end_y); RegionInitBoxes(&temp_region, &temp_box, 1); DEBUGF("block idx %d \n", temp_block_idx); DEBUGRegionPrint(&temp_region); current_region = RegionCreate(NULL, 4); RegionIntersect(current_region, &temp_region, region); DEBUGF("i %d j %d region: \n", i, j); DEBUGRegionPrint(current_region); if (RegionNumRects(current_region)) { clipped_regions[k].region = current_region; clipped_regions[k].block_idx = temp_block_idx; k++; } else RegionDestroy(current_region); RegionUninit(&temp_region); } } *n_region = k; return clipped_regions; } /** * Do a two round clipping, * first is to clip the region regard to current pixmap's * block array. Then for each clipped region, do a inner * block clipping. This is to make sure the final result * will be shapped by inner_block_w and inner_block_h, and * the final region also will not cross the pixmap's block * boundary. * * This is mainly used by transformation support when do * compositing. */ glamor_pixmap_clipped_regions * glamor_compute_clipped_regions_ext(PixmapPtr pixmap, RegionPtr region, int *n_region, int inner_block_w, int inner_block_h, int reverse, int upsidedown) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_clipped_regions *clipped_regions, *inner_regions, *result_regions; int i, j, x, y, k, inner_n_regions; int width, height; BoxPtr box_array; BoxRec small_box; int block_w, block_h; DEBUGF("ext called \n"); if (glamor_pixmap_priv_is_small(pixmap_priv)) { clipped_regions = calloc(1, sizeof(*clipped_regions)); if (clipped_regions == NULL) { *n_region = 0; return NULL; } clipped_regions[0].region = RegionCreate(NULL, 1); clipped_regions[0].block_idx = 0; RegionCopy(clipped_regions[0].region, region); *n_region = 1; block_w = pixmap->drawable.width; block_h = pixmap->drawable.height; box_array = &small_box; small_box.x1 = small_box.y1 = 0; small_box.x2 = block_w; small_box.y2 = block_h; } else { glamor_pixmap_private *priv = __glamor_large(pixmap_priv); clipped_regions = __glamor_compute_clipped_regions(priv->block_w, priv->block_h, priv->block_wcnt, 0, 0, pixmap->drawable.width, pixmap->drawable.height, region, n_region, reverse, upsidedown); if (clipped_regions == NULL) { *n_region = 0; return NULL; } block_w = priv->block_w; block_h = priv->block_h; box_array = priv->box_array; } if (inner_block_w >= block_w && inner_block_h >= block_h) return clipped_regions; result_regions = calloc(*n_region * ((block_w + inner_block_w - 1) / inner_block_w) * ((block_h + inner_block_h - 1) / inner_block_h), sizeof(*result_regions)); k = 0; for (i = 0; i < *n_region; i++) { x = box_array[clipped_regions[i].block_idx].x1; y = box_array[clipped_regions[i].block_idx].y1; width = box_array[clipped_regions[i].block_idx].x2 - x; height = box_array[clipped_regions[i].block_idx].y2 - y; inner_regions = __glamor_compute_clipped_regions(inner_block_w, inner_block_h, 0, x, y, width, height, clipped_regions[i]. region, &inner_n_regions, reverse, upsidedown); for (j = 0; j < inner_n_regions; j++) { result_regions[k].region = inner_regions[j].region; result_regions[k].block_idx = clipped_regions[i].block_idx; k++; } free(inner_regions); } *n_region = k; free(clipped_regions); return result_regions; } /* * * For the repeat pad mode, we can simply convert the region and * let the out-of-box region can cover the needed edge of the source/mask * Then apply a normal clip we can get what we want. */ static RegionPtr _glamor_convert_pad_region(RegionPtr region, int w, int h) { RegionPtr pad_region; int nrect; BoxPtr box; int overlap; nrect = RegionNumRects(region); box = RegionRects(region); pad_region = RegionCreate(NULL, 4); if (pad_region == NULL) return NULL; while (nrect--) { BoxRec pad_box; RegionRec temp_region; pad_box = *box; if (pad_box.x1 < 0 && pad_box.x2 <= 0) pad_box.x2 = 1; else if (pad_box.x1 >= w && pad_box.x2 > w) pad_box.x1 = w - 1; if (pad_box.y1 < 0 && pad_box.y2 <= 0) pad_box.y2 = 1; else if (pad_box.y1 >= h && pad_box.y2 > h) pad_box.y1 = h - 1; RegionInitBoxes(&temp_region, &pad_box, 1); RegionAppend(pad_region, &temp_region); RegionUninit(&temp_region); box++; } RegionValidate(pad_region, &overlap); return pad_region; } /* * For one type of large pixmap, its one direction is not exceed the * size limitation, and in another word, on one direction it has only * one block. * * This case of reflect repeating, we can optimize it and avoid repeat * clip on that direction. We can just enlarge the repeat box and can * cover all the dest region on that direction. But latter, we need to * fixup the clipped result to get a correct coords for the subsequent * processing. This function is to do the coords correction. * * */ static void _glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh) { int odd1, odd2; int c1, c2; if (*xy2 - *xy1 > wh) { *xy1 = 0; *xy2 = wh; return; } modulus(*xy1, wh, c1); odd1 = ((*xy1 - c1) / wh) & 0x1; modulus(*xy2, wh, c2); odd2 = ((*xy2 - c2) / wh) & 0x1; if (odd1 && odd2) { *xy1 = wh - c2; *xy2 = wh - c1; } else if (odd1 && !odd2) { *xy1 = 0; *xy2 = MAX(c2, wh - c1); } else if (!odd1 && odd2) { *xy2 = wh; *xy1 = MIN(c1, wh - c2); } else { *xy1 = c1; *xy2 = c2; } } /** * Clip the boxes regards to each pixmap's block array. * * Should translate the region to relative coords to the pixmap, * start at (0,0). * * @is_transform: if it is set, it has a transform matrix. * */ static glamor_pixmap_clipped_regions * _glamor_compute_clipped_regions(PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv, RegionPtr region, int *n_region, int repeat_type, int is_transform, int reverse, int upsidedown) { glamor_pixmap_clipped_regions *clipped_regions; BoxPtr extent; int i, j; RegionPtr current_region; int pixmap_width, pixmap_height; int m; BoxRec repeat_box; RegionRec repeat_region; int right_shift = 0; int down_shift = 0; int x_center_shift = 0, y_center_shift = 0; glamor_pixmap_private *priv; DEBUGRegionPrint(region); if (glamor_pixmap_priv_is_small(pixmap_priv)) { clipped_regions = calloc(1, sizeof(*clipped_regions)); clipped_regions[0].region = RegionCreate(NULL, 1); clipped_regions[0].block_idx = 0; RegionCopy(clipped_regions[0].region, region); *n_region = 1; return clipped_regions; } priv = __glamor_large(pixmap_priv); pixmap_width = pixmap->drawable.width; pixmap_height = pixmap->drawable.height; if (repeat_type == 0 || repeat_type == RepeatPad) { RegionPtr saved_region = NULL; if (repeat_type == RepeatPad) { saved_region = region; region = _glamor_convert_pad_region(saved_region, pixmap_width, pixmap_height); if (region == NULL) { *n_region = 0; return NULL; } } clipped_regions = __glamor_compute_clipped_regions(priv->block_w, priv->block_h, priv->block_wcnt, 0, 0, pixmap->drawable.width, pixmap->drawable.height, region, n_region, reverse, upsidedown); if (saved_region) RegionDestroy(region); return clipped_regions; } extent = RegionExtents(region); x_center_shift = extent->x1 / pixmap_width; if (x_center_shift < 0) x_center_shift--; if (abs(x_center_shift) & 1) x_center_shift++; y_center_shift = extent->y1 / pixmap_height; if (y_center_shift < 0) y_center_shift--; if (abs(y_center_shift) & 1) y_center_shift++; if (extent->x1 < 0) right_shift = ((-extent->x1 + pixmap_width - 1) / pixmap_width); if (extent->y1 < 0) down_shift = ((-extent->y1 + pixmap_height - 1) / pixmap_height); if (right_shift != 0 || down_shift != 0) { if (repeat_type == RepeatReflect) { right_shift = (right_shift + 1) & ~1; down_shift = (down_shift + 1) & ~1; } RegionTranslate(region, right_shift * pixmap_width, down_shift * pixmap_height); } extent = RegionExtents(region); /* Tile a large pixmap to another large pixmap. * We can't use the target large pixmap as the * loop variable, instead we need to loop for all * the blocks in the tile pixmap. * * simulate repeat each single block to cover the * target's blocks. Two special case: * a block_wcnt == 1 or block_hcnt ==1, then we * only need to loop one direction as the other * direction is fully included in the first block. * * For the other cases, just need to start * from a proper shiftx/shifty, and then increase * y by tile_height each time to walk trhough the * target block and then walk trhough the target * at x direction by increate tile_width each time. * * This way, we can consolidate all the sub blocks * of the target boxes into one tile source's block. * * */ m = 0; clipped_regions = calloc(priv->block_wcnt * priv->block_hcnt, sizeof(*clipped_regions)); if (clipped_regions == NULL) { *n_region = 0; return NULL; } if (right_shift != 0 || down_shift != 0) { DEBUGF("region to be repeated shifted \n"); DEBUGRegionPrint(region); } DEBUGF("repeat pixmap width %d height %d \n", pixmap_width, pixmap_height); DEBUGF("extent x1 %d y1 %d x2 %d y2 %d \n", extent->x1, extent->y1, extent->x2, extent->y2); for (j = 0; j < priv->block_hcnt; j++) { for (i = 0; i < priv->block_wcnt; i++) { int dx = pixmap_width; int dy = pixmap_height; int idx; int shift_x; int shift_y; int saved_y1, saved_y2; int x_idx = 0, y_idx = 0, saved_y_idx = 0; RegionRec temp_region; BoxRec reflect_repeat_box; BoxPtr valid_repeat_box; shift_x = (extent->x1 / pixmap_width) * pixmap_width; shift_y = (extent->y1 / pixmap_height) * pixmap_height; idx = j * priv->block_wcnt + i; if (repeat_type == RepeatReflect) { x_idx = (extent->x1 / pixmap_width); y_idx = (extent->y1 / pixmap_height); } /* Construct a rect to clip the target region. */ repeat_box.x1 = shift_x + priv->box_array[idx].x1; repeat_box.y1 = shift_y + priv->box_array[idx].y1; if (priv->block_wcnt == 1) { repeat_box.x2 = extent->x2; dx = extent->x2 - repeat_box.x1; } else repeat_box.x2 = shift_x + priv->box_array[idx].x2; if (priv->block_hcnt == 1) { repeat_box.y2 = extent->y2; dy = extent->y2 - repeat_box.y1; } else repeat_box.y2 = shift_y + priv->box_array[idx].y2; current_region = RegionCreate(NULL, 4); RegionInit(&temp_region, NULL, 4); DEBUGF("init repeat box %d %d %d %d \n", repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2); if (repeat_type == RepeatNormal) { saved_y1 = repeat_box.y1; saved_y2 = repeat_box.y2; for (; repeat_box.x1 < extent->x2; repeat_box.x1 += dx, repeat_box.x2 += dx) { repeat_box.y1 = saved_y1; repeat_box.y2 = saved_y2; for (repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2; repeat_box.y1 < extent->y2; repeat_box.y1 += dy, repeat_box.y2 += dy) { RegionInitBoxes(&repeat_region, &repeat_box, 1); DEBUGF("Start to clip repeat region: \n"); DEBUGRegionPrint(&repeat_region); RegionIntersect(&temp_region, &repeat_region, region); DEBUGF("clip result:\n"); DEBUGRegionPrint(&temp_region); RegionAppend(current_region, &temp_region); RegionUninit(&repeat_region); } } } else if (repeat_type == RepeatReflect) { saved_y1 = repeat_box.y1; saved_y2 = repeat_box.y2; saved_y_idx = y_idx; for (;; repeat_box.x1 += dx, repeat_box.x2 += dx) { repeat_box.y1 = saved_y1; repeat_box.y2 = saved_y2; y_idx = saved_y_idx; reflect_repeat_box.x1 = (x_idx & 1) ? ((2 * x_idx + 1) * dx - repeat_box.x2) : repeat_box.x1; reflect_repeat_box.x2 = (x_idx & 1) ? ((2 * x_idx + 1) * dx - repeat_box.x1) : repeat_box.x2; valid_repeat_box = &reflect_repeat_box; if (valid_repeat_box->x1 >= extent->x2) break; for (repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2;; repeat_box.y1 += dy, repeat_box.y2 += dy) { DEBUGF("x_idx %d y_idx %d dx %d dy %d\n", x_idx, y_idx, dx, dy); DEBUGF("repeat box %d %d %d %d \n", repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2); if (priv->block_hcnt > 1) { reflect_repeat_box.y1 = (y_idx & 1) ? ((2 * y_idx + 1) * dy - repeat_box.y2) : repeat_box.y1; reflect_repeat_box.y2 = (y_idx & 1) ? ((2 * y_idx + 1) * dy - repeat_box.y1) : repeat_box.y2; } else { reflect_repeat_box.y1 = repeat_box.y1; reflect_repeat_box.y2 = repeat_box.y2; } DEBUGF("valid_repeat_box x1 %d y1 %d \n", valid_repeat_box->x1, valid_repeat_box->y1); if (valid_repeat_box->y1 >= extent->y2) break; RegionInitBoxes(&repeat_region, valid_repeat_box, 1); DEBUGF("start to clip repeat[reflect] region: \n"); DEBUGRegionPrint(&repeat_region); RegionIntersect(&temp_region, &repeat_region, region); DEBUGF("result:\n"); DEBUGRegionPrint(&temp_region); if (is_transform && RegionNumRects(&temp_region)) { BoxRec temp_box; BoxPtr temp_extent; temp_extent = RegionExtents(&temp_region); if (priv->block_wcnt > 1) { if (x_idx & 1) { temp_box.x1 = ((2 * x_idx + 1) * dx - temp_extent->x2); temp_box.x2 = ((2 * x_idx + 1) * dx - temp_extent->x1); } else { temp_box.x1 = temp_extent->x1; temp_box.x2 = temp_extent->x2; } modulus(temp_box.x1, pixmap_width, temp_box.x1); modulus(temp_box.x2, pixmap_width, temp_box.x2); if (temp_box.x2 == 0) temp_box.x2 = pixmap_width; } else { temp_box.x1 = temp_extent->x1; temp_box.x2 = temp_extent->x2; _glamor_largepixmap_reflect_fixup(&temp_box.x1, &temp_box.x2, pixmap_width); } if (priv->block_hcnt > 1) { if (y_idx & 1) { temp_box.y1 = ((2 * y_idx + 1) * dy - temp_extent->y2); temp_box.y2 = ((2 * y_idx + 1) * dy - temp_extent->y1); } else { temp_box.y1 = temp_extent->y1; temp_box.y2 = temp_extent->y2; } modulus(temp_box.y1, pixmap_height, temp_box.y1); modulus(temp_box.y2, pixmap_height, temp_box.y2); if (temp_box.y2 == 0) temp_box.y2 = pixmap_height; } else { temp_box.y1 = temp_extent->y1; temp_box.y2 = temp_extent->y2; _glamor_largepixmap_reflect_fixup(&temp_box.y1, &temp_box.y2, pixmap_height); } RegionInitBoxes(&temp_region, &temp_box, 1); RegionTranslate(&temp_region, x_center_shift * pixmap_width, y_center_shift * pixmap_height); DEBUGF("for transform result:\n"); DEBUGRegionPrint(&temp_region); } RegionAppend(current_region, &temp_region); RegionUninit(&repeat_region); y_idx++; } x_idx++; } } DEBUGF("dx %d dy %d \n", dx, dy); if (RegionNumRects(current_region)) { if ((right_shift != 0 || down_shift != 0) && !(is_transform && repeat_type == RepeatReflect)) RegionTranslate(current_region, -right_shift * pixmap_width, -down_shift * pixmap_height); clipped_regions[m].region = current_region; clipped_regions[m].block_idx = idx; m++; } else RegionDestroy(current_region); RegionUninit(&temp_region); } } if (right_shift != 0 || down_shift != 0) RegionTranslate(region, -right_shift * pixmap_width, -down_shift * pixmap_height); *n_region = m; return clipped_regions; } glamor_pixmap_clipped_regions * glamor_compute_clipped_regions(PixmapPtr pixmap, RegionPtr region, int *n_region, int repeat_type, int reverse, int upsidedown) { glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); return _glamor_compute_clipped_regions(pixmap, priv, region, n_region, repeat_type, 0, reverse, upsidedown); } /* XXX overflow still exist. maybe we need to change to use region32. * by default. Or just use region32 for repeat cases? **/ static glamor_pixmap_clipped_regions * glamor_compute_transform_clipped_regions(PixmapPtr pixmap, struct pixman_transform *transform, RegionPtr region, int *n_region, int dx, int dy, int repeat_type, int reverse, int upsidedown) { glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); BoxPtr temp_extent; struct pixman_box32 temp_box; struct pixman_box16 short_box; RegionPtr temp_region; glamor_pixmap_clipped_regions *ret; temp_region = RegionCreate(NULL, 4); temp_extent = RegionExtents(region); DEBUGF("dest region \n"); DEBUGRegionPrint(region); /* dx/dy may exceed MAX SHORT. we have to use * a box32 to represent it.*/ temp_box.x1 = temp_extent->x1 + dx; temp_box.x2 = temp_extent->x2 + dx; temp_box.y1 = temp_extent->y1 + dy; temp_box.y2 = temp_extent->y2 + dy; DEBUGF("source box %d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, temp_box.y2); if (transform) glamor_get_transform_extent_from_box(&temp_box, transform); if (repeat_type == RepeatNone) { if (temp_box.x1 < 0) temp_box.x1 = 0; if (temp_box.y1 < 0) temp_box.y1 = 0; temp_box.x2 = MIN(temp_box.x2, pixmap->drawable.width); temp_box.y2 = MIN(temp_box.y2, pixmap->drawable.height); } /* Now copy back the box32 to a box16 box, avoiding overflow. */ short_box.x1 = MIN(temp_box.x1, INT16_MAX); short_box.y1 = MIN(temp_box.y1, INT16_MAX); short_box.x2 = MIN(temp_box.x2, INT16_MAX); short_box.y2 = MIN(temp_box.y2, INT16_MAX); RegionInitBoxes(temp_region, &short_box, 1); DEBUGF("copy to temp source region \n"); DEBUGRegionPrint(temp_region); ret = _glamor_compute_clipped_regions(pixmap, priv, temp_region, n_region, repeat_type, 1, reverse, upsidedown); DEBUGF("n_regions = %d \n", *n_region); RegionDestroy(temp_region); return ret; } /* * As transform and repeatpad mode. * We may get a clipped result which in multipe regions. * It's not easy to do a 2nd round clipping just as we do * without transform/repeatPad. As it's not easy to reverse * the 2nd round clipping result with a transform/repeatPad mode, * or even impossible for some transformation. * * So we have to merge the fragmental region into one region * if the clipped result cross the region boundary. */ static void glamor_merge_clipped_regions(PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv, int repeat_type, glamor_pixmap_clipped_regions *clipped_regions, int *n_regions, int *need_clean_fbo) { BoxRec temp_box, copy_box; RegionPtr temp_region; glamor_pixmap_private *temp_priv; PixmapPtr temp_pixmap; int overlap; int i; int pixmap_width, pixmap_height; glamor_pixmap_private *priv; priv = __glamor_large(pixmap_priv); pixmap_width = pixmap->drawable.width; pixmap_height =pixmap->drawable.height; temp_region = RegionCreate(NULL, 4); for (i = 0; i < *n_regions; i++) { DEBUGF("Region %d:\n", i); DEBUGRegionPrint(clipped_regions[i].region); RegionAppend(temp_region, clipped_regions[i].region); } RegionValidate(temp_region, &overlap); DEBUGF("temp region: \n"); DEBUGRegionPrint(temp_region); temp_box = *RegionExtents(temp_region); DEBUGF("need copy region: \n"); DEBUGF("%d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, temp_box.y2); temp_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, temp_box.x2 - temp_box.x1, temp_box.y2 - temp_box.y1, pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_FIXUP); if (temp_pixmap == NULL) { assert(0); return; } temp_priv = glamor_get_pixmap_private(temp_pixmap); assert(glamor_pixmap_priv_is_small(temp_priv)); priv->box = temp_box; if (temp_box.x1 >= 0 && temp_box.x2 <= pixmap_width && temp_box.y1 >= 0 && temp_box.y2 <= pixmap_height) { int dx, dy; copy_box.x1 = 0; copy_box.y1 = 0; copy_box.x2 = temp_box.x2 - temp_box.x1; copy_box.y2 = temp_box.y2 - temp_box.y1; dx = temp_box.x1; dy = temp_box.y1; glamor_copy(&pixmap->drawable, &temp_pixmap->drawable, NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL); // glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width, // temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00); } else { for (i = 0; i < *n_regions; i++) { BoxPtr box; int nbox; box = REGION_RECTS(clipped_regions[i].region); nbox = REGION_NUM_RECTS(clipped_regions[i].region); while (nbox--) { int dx, dy, c, d; DEBUGF("box x1 %d y1 %d x2 %d y2 %d \n", box->x1, box->y1, box->x2, box->y2); modulus(box->x1, pixmap_width, c); dx = c - (box->x1 - temp_box.x1); copy_box.x1 = box->x1 - temp_box.x1; copy_box.x2 = box->x2 - temp_box.x1; modulus(box->y1, pixmap_height, d); dy = d - (box->y1 - temp_box.y1); copy_box.y1 = box->y1 - temp_box.y1; copy_box.y2 = box->y2 - temp_box.y1; DEBUGF("copying box %d %d %d %d, dx %d dy %d\n", copy_box.x1, copy_box.y1, copy_box.x2, copy_box.y2, dx, dy); glamor_copy(&pixmap->drawable, &temp_pixmap->drawable, NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL); box++; } } //glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width, // temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff); } /* The first region will be released at caller side. */ for (i = 1; i < *n_regions; i++) RegionDestroy(clipped_regions[i].region); RegionDestroy(temp_region); priv->box = temp_box; priv->fbo = glamor_pixmap_detach_fbo(temp_priv); DEBUGF("priv box x1 %d y1 %d x2 %d y2 %d \n", priv->box.x1, priv->box.y1, priv->box.x2, priv->box.y2); glamor_destroy_pixmap(temp_pixmap); *need_clean_fbo = 1; *n_regions = 1; } /** * Given an expected transformed block width and block height, * * This function calculate a new block width and height which * guarantee the transform result will not exceed the given * block width and height. * * For large block width and height (> 2048), we choose a * smaller new width and height and to reduce the cross region * boundary and can avoid some overhead. * **/ static Bool glamor_get_transform_block_size(struct pixman_transform *transform, int block_w, int block_h, int *transformed_block_w, int *transformed_block_h) { double a, b, c, d, e, f, g, h; double scale; int width, height; a = pixman_fixed_to_double(transform->matrix[0][0]); b = pixman_fixed_to_double(transform->matrix[0][1]); c = pixman_fixed_to_double(transform->matrix[1][0]); d = pixman_fixed_to_double(transform->matrix[1][1]); scale = pixman_fixed_to_double(transform->matrix[2][2]); if (block_w > 2048) { /* For large block size, we shrink it to smaller box, * thus latter we may get less cross boundary regions and * thus can avoid some extra copy. * **/ width = block_w / 4; height = block_h / 4; } else { width = block_w - 2; height = block_h - 2; } e = a + b; f = c + d; g = a - b; h = c - d; e = MIN(block_w, floor(width * scale) / MAX(fabs(e), fabs(g))); f = MIN(block_h, floor(height * scale) / MAX(fabs(f), fabs(h))); *transformed_block_w = MIN(e, f) - 1; *transformed_block_h = *transformed_block_w; if (*transformed_block_w <= 0 || *transformed_block_h <= 0) return FALSE; DEBUGF("original block_w/h %d %d, fixed %d %d \n", block_w, block_h, *transformed_block_w, *transformed_block_h); return TRUE; } #define VECTOR_FROM_POINT(p, x, y) do {\ p.v[0] = x; \ p.v[1] = y; \ p.v[2] = 1.0; } while (0) static void glamor_get_transform_extent_from_box(struct pixman_box32 *box, struct pixman_transform *transform) { struct pixman_f_vector p0, p1, p2, p3; float min_x, min_y, max_x, max_y; struct pixman_f_transform ftransform; VECTOR_FROM_POINT(p0, box->x1, box->y1); VECTOR_FROM_POINT(p1, box->x2, box->y1); VECTOR_FROM_POINT(p2, box->x2, box->y2); VECTOR_FROM_POINT(p3, box->x1, box->y2); pixman_f_transform_from_pixman_transform(&ftransform, transform); pixman_f_transform_point(&ftransform, &p0); pixman_f_transform_point(&ftransform, &p1); pixman_f_transform_point(&ftransform, &p2); pixman_f_transform_point(&ftransform, &p3); min_x = MIN(p0.v[0], p1.v[0]); min_x = MIN(min_x, p2.v[0]); min_x = MIN(min_x, p3.v[0]); min_y = MIN(p0.v[1], p1.v[1]); min_y = MIN(min_y, p2.v[1]); min_y = MIN(min_y, p3.v[1]); max_x = MAX(p0.v[0], p1.v[0]); max_x = MAX(max_x, p2.v[0]); max_x = MAX(max_x, p3.v[0]); max_y = MAX(p0.v[1], p1.v[1]); max_y = MAX(max_y, p2.v[1]); max_y = MAX(max_y, p3.v[1]); box->x1 = floor(min_x) - 1; box->y1 = floor(min_y) - 1; box->x2 = ceil(max_x) + 1; box->y2 = ceil(max_y) + 1; } static void _glamor_process_transformed_clipped_region(PixmapPtr pixmap, glamor_pixmap_private *priv, int repeat_type, glamor_pixmap_clipped_regions * clipped_regions, int *n_regions, int *need_clean_fbo) { int shift_x, shift_y; if (*n_regions != 1) { /* Merge all source regions into one region. */ glamor_merge_clipped_regions(pixmap, priv, repeat_type, clipped_regions, n_regions, need_clean_fbo); } else { glamor_set_pixmap_fbo_current(priv, clipped_regions[0].block_idx); if (repeat_type == RepeatReflect || repeat_type == RepeatNormal) { /* The required source areas are in one region, * we need to shift the corresponding box's coords to proper position, * thus we can calculate the relative coords correctly.*/ BoxPtr temp_box; int rem; temp_box = RegionExtents(clipped_regions[0].region); modulus(temp_box->x1, pixmap->drawable.width, rem); shift_x = (temp_box->x1 - rem) / pixmap->drawable.width; modulus(temp_box->y1, pixmap->drawable.height, rem); shift_y = (temp_box->y1 - rem) / pixmap->drawable.height; if (shift_x != 0) { __glamor_large(priv)->box.x1 += shift_x * pixmap->drawable.width; __glamor_large(priv)->box.x2 += shift_x * pixmap->drawable.width; } if (shift_y != 0) { __glamor_large(priv)->box.y1 += shift_y * pixmap->drawable.height; __glamor_large(priv)->box.y2 += shift_y * pixmap->drawable.height; } } } } Bool glamor_composite_largepixmap_region(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, PixmapPtr source_pixmap, PixmapPtr mask_pixmap, PixmapPtr dest_pixmap, RegionPtr region, Bool force_clip, INT16 x_source, INT16 y_source, INT16 x_mask, INT16 y_mask, INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height) { ScreenPtr screen = dest_pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); glamor_pixmap_private *mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); glamor_pixmap_private *dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); glamor_pixmap_clipped_regions *clipped_dest_regions; glamor_pixmap_clipped_regions *clipped_source_regions; glamor_pixmap_clipped_regions *clipped_mask_regions; int n_dest_regions; int n_mask_regions; int n_source_regions; int i, j, k; int need_clean_source_fbo = 0; int need_clean_mask_fbo = 0; int is_normal_source_fbo = 0; int is_normal_mask_fbo = 0; int fixed_block_width, fixed_block_height; int dest_block_width, dest_block_height; int null_source, null_mask; glamor_pixmap_private *need_free_source_pixmap_priv = NULL; glamor_pixmap_private *need_free_mask_pixmap_priv = NULL; int source_repeat_type = 0, mask_repeat_type = 0; int ok = TRUE; if (source_pixmap == dest_pixmap) { glamor_fallback("source and dest pixmaps are the same\n"); return FALSE; } if (mask_pixmap == dest_pixmap) { glamor_fallback("mask and dest pixmaps are the same\n"); return FALSE; } if (source->repeat) source_repeat_type = source->repeatType; else source_repeat_type = RepeatNone; if (mask && mask->repeat) mask_repeat_type = mask->repeatType; else mask_repeat_type = RepeatNone; if (glamor_pixmap_priv_is_large(dest_pixmap_priv)) { dest_block_width = __glamor_large(dest_pixmap_priv)->block_w; dest_block_height = __glamor_large(dest_pixmap_priv)->block_h; } else { dest_block_width = dest_pixmap->drawable.width; dest_block_height = dest_pixmap->drawable.height; } fixed_block_width = dest_block_width; fixed_block_height = dest_block_height; /* If we got an totally out-of-box region for a source or mask * region without repeat, we need to set it as null_source and * give it a solid color (0,0,0,0). */ null_source = 0; null_mask = 0; RegionTranslate(region, -dest->pDrawable->x, -dest->pDrawable->y); /* need to transform the dest region to the correct sourcei/mask region. * it's a little complex, as one single edge of the * target region may be transformed to cross a block boundary of the * source or mask. Then it's impossible to handle it as usual way. * We may have to split the original dest region to smaller region, and * make sure each region's transformed region can fit into one texture, * and then continue this loop again, and each time when a transformed region * cross the bound, we need to copy it to a single pixmap and do the composition * with the new pixmap. If the transformed region doesn't cross a source/mask's * boundary then we don't need to copy. * */ if (source_pixmap_priv && source->transform && glamor_pixmap_priv_is_large(source_pixmap_priv)) { int source_transformed_block_width, source_transformed_block_height; if (!glamor_get_transform_block_size(source->transform, __glamor_large(source_pixmap_priv)->block_w, __glamor_large(source_pixmap_priv)->block_h, &source_transformed_block_width, &source_transformed_block_height)) { DEBUGF("source block size less than 1, fallback.\n"); RegionTranslate(region, dest->pDrawable->x, dest->pDrawable->y); return FALSE; } fixed_block_width = min(fixed_block_width, source_transformed_block_width); fixed_block_height = min(fixed_block_height, source_transformed_block_height); DEBUGF("new source block size %d x %d \n", fixed_block_width, fixed_block_height); } if (mask_pixmap_priv && mask->transform && glamor_pixmap_priv_is_large(mask_pixmap_priv)) { int mask_transformed_block_width, mask_transformed_block_height; if (!glamor_get_transform_block_size(mask->transform, __glamor_large(mask_pixmap_priv)->block_w, __glamor_large(mask_pixmap_priv)->block_h, &mask_transformed_block_width, &mask_transformed_block_height)) { DEBUGF("mask block size less than 1, fallback.\n"); RegionTranslate(region, dest->pDrawable->x, dest->pDrawable->y); return FALSE; } fixed_block_width = min(fixed_block_width, mask_transformed_block_width); fixed_block_height = min(fixed_block_height, mask_transformed_block_height); DEBUGF("new mask block size %d x %d \n", fixed_block_width, fixed_block_height); } /*compute the correct block width and height whose transformed source/mask *region can fit into one texture.*/ if (force_clip || fixed_block_width < dest_block_width || fixed_block_height < dest_block_height) clipped_dest_regions = glamor_compute_clipped_regions_ext(dest_pixmap, region, &n_dest_regions, fixed_block_width, fixed_block_height, 0, 0); else clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap, region, &n_dest_regions, 0, 0, 0); DEBUGF("dest clipped result %d region: \n", n_dest_regions); if (source_pixmap_priv && (source_pixmap_priv == dest_pixmap_priv || source_pixmap_priv == mask_pixmap_priv) && glamor_pixmap_priv_is_large(source_pixmap_priv)) { /* XXX self-copy... */ need_free_source_pixmap_priv = source_pixmap_priv; source_pixmap_priv = malloc(sizeof(*source_pixmap_priv)); *source_pixmap_priv = *need_free_source_pixmap_priv; need_free_source_pixmap_priv = source_pixmap_priv; } assert(mask_pixmap_priv != dest_pixmap_priv); for (i = 0; i < n_dest_regions; i++) { DEBUGF("dest region %d idx %d\n", i, clipped_dest_regions[i].block_idx); DEBUGRegionPrint(clipped_dest_regions[i].region); glamor_set_pixmap_fbo_current(dest_pixmap_priv, clipped_dest_regions[i].block_idx); if (source_pixmap_priv && glamor_pixmap_priv_is_large(source_pixmap_priv)) { if (!source->transform && source_repeat_type != RepeatPad) { RegionTranslate(clipped_dest_regions[i].region, x_source - x_dest, y_source - y_dest); clipped_source_regions = glamor_compute_clipped_regions(source_pixmap, clipped_dest_regions[i]. region, &n_source_regions, source_repeat_type, 0, 0); is_normal_source_fbo = 1; } else { clipped_source_regions = glamor_compute_transform_clipped_regions(source_pixmap, source->transform, clipped_dest_regions [i].region, &n_source_regions, x_source - x_dest, y_source - y_dest, source_repeat_type, 0, 0); is_normal_source_fbo = 0; if (n_source_regions == 0) { /* Pad the out-of-box region to (0,0,0,0). */ null_source = 1; n_source_regions = 1; } else _glamor_process_transformed_clipped_region (source_pixmap, source_pixmap_priv, source_repeat_type, clipped_source_regions, &n_source_regions, &need_clean_source_fbo); } DEBUGF("source clipped result %d region: \n", n_source_regions); for (j = 0; j < n_source_regions; j++) { if (is_normal_source_fbo) glamor_set_pixmap_fbo_current(source_pixmap_priv, clipped_source_regions[j].block_idx); if (mask_pixmap_priv && glamor_pixmap_priv_is_large(mask_pixmap_priv)) { if (is_normal_mask_fbo && is_normal_source_fbo) { /* both mask and source are normal fbo box without transform or repeatpad. * The region is clipped against source and then we clip it against mask here.*/ DEBUGF("source region %d idx %d\n", j, clipped_source_regions[j].block_idx); DEBUGRegionPrint(clipped_source_regions[j].region); RegionTranslate(clipped_source_regions[j].region, -x_source + x_mask, -y_source + y_mask); clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap, clipped_source_regions [j].region, &n_mask_regions, mask_repeat_type, 0, 0); is_normal_mask_fbo = 1; } else if (is_normal_mask_fbo && !is_normal_source_fbo) { assert(n_source_regions == 1); /* The source fbo is not a normal fbo box, it has transform or repeatpad. * the valid clip region should be the clip dest region rather than the * clip source region.*/ RegionTranslate(clipped_dest_regions[i].region, -x_dest + x_mask, -y_dest + y_mask); clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap, clipped_dest_regions [i].region, &n_mask_regions, mask_repeat_type, 0, 0); is_normal_mask_fbo = 1; } else { /* This mask region has transform or repeatpad, we need clip it against the previous * valid region rather than the mask region. */ if (!is_normal_source_fbo) clipped_mask_regions = glamor_compute_transform_clipped_regions (mask_pixmap, mask->transform, clipped_dest_regions[i].region, &n_mask_regions, x_mask - x_dest, y_mask - y_dest, mask_repeat_type, 0, 0); else clipped_mask_regions = glamor_compute_transform_clipped_regions (mask_pixmap, mask->transform, clipped_source_regions[j].region, &n_mask_regions, x_mask - x_source, y_mask - y_source, mask_repeat_type, 0, 0); is_normal_mask_fbo = 0; if (n_mask_regions == 0) { /* Pad the out-of-box region to (0,0,0,0). */ null_mask = 1; n_mask_regions = 1; } else _glamor_process_transformed_clipped_region (mask_pixmap, mask_pixmap_priv, mask_repeat_type, clipped_mask_regions, &n_mask_regions, &need_clean_mask_fbo); } DEBUGF("mask clipped result %d region: \n", n_mask_regions); #define COMPOSITE_REGION(region) do { \ if (!glamor_composite_clipped_region(op, \ null_source ? NULL : source, \ null_mask ? NULL : mask, dest, \ null_source ? NULL : source_pixmap, \ null_mask ? NULL : mask_pixmap, \ dest_pixmap, region, \ x_source, y_source, x_mask, y_mask, \ x_dest, y_dest)) { \ assert(0); \ } \ } while(0) for (k = 0; k < n_mask_regions; k++) { DEBUGF("mask region %d idx %d\n", k, clipped_mask_regions[k].block_idx); DEBUGRegionPrint(clipped_mask_regions[k].region); if (is_normal_mask_fbo) { glamor_set_pixmap_fbo_current(mask_pixmap_priv, clipped_mask_regions[k]. block_idx); DEBUGF("mask fbo off %d %d \n", __glamor_large(mask_pixmap_priv)->box.x1, __glamor_large(mask_pixmap_priv)->box.y1); DEBUGF("start composite mask hasn't transform.\n"); RegionTranslate(clipped_mask_regions[k].region, x_dest - x_mask + dest->pDrawable->x, y_dest - y_mask + dest->pDrawable->y); COMPOSITE_REGION(clipped_mask_regions[k].region); } else if (!is_normal_mask_fbo && !is_normal_source_fbo) { DEBUGF ("start composite both mask and source have transform.\n"); RegionTranslate(clipped_dest_regions[i].region, dest->pDrawable->x, dest->pDrawable->y); COMPOSITE_REGION(clipped_dest_regions[i].region); } else { DEBUGF ("start composite only mask has transform.\n"); RegionTranslate(clipped_source_regions[j].region, x_dest - x_source + dest->pDrawable->x, y_dest - y_source + dest->pDrawable->y); COMPOSITE_REGION(clipped_source_regions[j].region); } RegionDestroy(clipped_mask_regions[k].region); } free(clipped_mask_regions); if (null_mask) null_mask = 0; if (need_clean_mask_fbo) { assert(is_normal_mask_fbo == 0); glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->fbo); mask_pixmap_priv->fbo = NULL; need_clean_mask_fbo = 0; } } else { if (is_normal_source_fbo) { RegionTranslate(clipped_source_regions[j].region, -x_source + x_dest + dest->pDrawable->x, -y_source + y_dest + dest->pDrawable->y); COMPOSITE_REGION(clipped_source_regions[j].region); } else { /* Source has transform or repeatPad. dest regions is the right * region to do the composite. */ RegionTranslate(clipped_dest_regions[i].region, dest->pDrawable->x, dest->pDrawable->y); COMPOSITE_REGION(clipped_dest_regions[i].region); } } if (clipped_source_regions && clipped_source_regions[j].region) RegionDestroy(clipped_source_regions[j].region); } free(clipped_source_regions); if (null_source) null_source = 0; if (need_clean_source_fbo) { assert(is_normal_source_fbo == 0); glamor_destroy_fbo(glamor_priv, source_pixmap_priv->fbo); source_pixmap_priv->fbo = NULL; need_clean_source_fbo = 0; } } else { if (mask_pixmap_priv && glamor_pixmap_priv_is_large(mask_pixmap_priv)) { if (!mask->transform && mask_repeat_type != RepeatPad) { RegionTranslate(clipped_dest_regions[i].region, x_mask - x_dest, y_mask - y_dest); clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap, clipped_dest_regions[i]. region, &n_mask_regions, mask_repeat_type, 0, 0); is_normal_mask_fbo = 1; } else { clipped_mask_regions = glamor_compute_transform_clipped_regions (mask_pixmap, mask->transform, clipped_dest_regions[i].region, &n_mask_regions, x_mask - x_dest, y_mask - y_dest, mask_repeat_type, 0, 0); is_normal_mask_fbo = 0; if (n_mask_regions == 0) { /* Pad the out-of-box region to (0,0,0,0). */ null_mask = 1; n_mask_regions = 1; } else _glamor_process_transformed_clipped_region (mask_pixmap, mask_pixmap_priv, mask_repeat_type, clipped_mask_regions, &n_mask_regions, &need_clean_mask_fbo); } for (k = 0; k < n_mask_regions; k++) { DEBUGF("mask region %d idx %d\n", k, clipped_mask_regions[k].block_idx); DEBUGRegionPrint(clipped_mask_regions[k].region); if (is_normal_mask_fbo) { glamor_set_pixmap_fbo_current(mask_pixmap_priv, clipped_mask_regions[k]. block_idx); RegionTranslate(clipped_mask_regions[k].region, x_dest - x_mask + dest->pDrawable->x, y_dest - y_mask + dest->pDrawable->y); COMPOSITE_REGION(clipped_mask_regions[k].region); } else { RegionTranslate(clipped_dest_regions[i].region, dest->pDrawable->x, dest->pDrawable->y); COMPOSITE_REGION(clipped_dest_regions[i].region); } RegionDestroy(clipped_mask_regions[k].region); } free(clipped_mask_regions); if (null_mask) null_mask = 0; if (need_clean_mask_fbo) { glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->fbo); mask_pixmap_priv->fbo = NULL; need_clean_mask_fbo = 0; } } else { RegionTranslate(clipped_dest_regions[i].region, dest->pDrawable->x, dest->pDrawable->y); COMPOSITE_REGION(clipped_dest_regions[i].region); } } RegionDestroy(clipped_dest_regions[i].region); } free(clipped_dest_regions); free(need_free_source_pixmap_priv); free(need_free_mask_pixmap_priv); ok = TRUE; return ok; } xorg-server-1.20.13/glamor/glamor_picture.c0000644000175000017500000002724114100573756015541 00000000000000/* * Copyright © 2016 Broadcom * Copyright © 2009 Intel Corporation * Copyright © 1998 Keith Packard * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ /** * @file glamor_picture.c * * Implements temporary uploads of GL_MEMORY Pixmaps to a texture that * is swizzled appropriately for a given Render picture format. * laid * * * This is important because GTK likes to use SHM Pixmaps for Render * blending operations, and we don't want a blend operation to fall * back to software (readback is more expensive than the upload we do * here, and you'd have to re-upload the fallback output anyway). */ #include #include "glamor_priv.h" #include "mipict.h" static void byte_swap_swizzle(GLenum *swizzle) { GLenum temp; temp = swizzle[0]; swizzle[0] = swizzle[3]; swizzle[3] = temp; temp = swizzle[1]; swizzle[1] = swizzle[2]; swizzle[2] = temp; } /** * Returns the GL format and type for uploading our bits to a given PictFormat. * * We may need to tell the caller to translate the bits to another * format, as in PICT_a1 (which GL doesn't support). We may also need * to tell the GL to swizzle the texture on sampling, because GLES3 * doesn't support the GL_UNSIGNED_INT_8_8_8_8{,_REV} types, so we * don't have enough channel reordering options at upload time without * it. */ static Bool glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen, PictFormatShort format, PictFormatShort *temp_format, GLenum *tex_format, GLenum *tex_type, GLenum *swizzle) { glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen); Bool is_little_endian = IMAGE_BYTE_ORDER == LSBFirst; *temp_format = format; swizzle[0] = GL_RED; swizzle[1] = GL_GREEN; swizzle[2] = GL_BLUE; swizzle[3] = GL_ALPHA; switch (format) { case PICT_a1: *tex_format = glamor_priv->one_channel_format; *tex_type = GL_UNSIGNED_BYTE; *temp_format = PICT_a8; break; case PICT_b8g8r8x8: case PICT_b8g8r8a8: if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { *tex_format = GL_BGRA; *tex_type = GL_UNSIGNED_INT_8_8_8_8; } else { *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_BYTE; swizzle[0] = GL_GREEN; swizzle[1] = GL_BLUE; swizzle[2] = GL_ALPHA; swizzle[3] = GL_RED; if (!is_little_endian) byte_swap_swizzle(swizzle); } break; case PICT_x8r8g8b8: case PICT_a8r8g8b8: if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { *tex_format = GL_BGRA; *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; } else { *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_BYTE; swizzle[0] = GL_BLUE; swizzle[2] = GL_RED; if (!is_little_endian) byte_swap_swizzle(swizzle); break; } break; case PICT_x8b8g8r8: case PICT_a8b8g8r8: *tex_format = GL_RGBA; if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; } else { *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_BYTE; if (!is_little_endian) byte_swap_swizzle(swizzle); } break; case PICT_x2r10g10b10: case PICT_a2r10g10b10: if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { *tex_format = GL_BGRA; *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; } else { return FALSE; } break; case PICT_x2b10g10r10: case PICT_a2b10g10r10: if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; } else { return FALSE; } break; case PICT_r5g6b5: *tex_format = GL_RGB; *tex_type = GL_UNSIGNED_SHORT_5_6_5; break; case PICT_b5g6r5: *tex_format = GL_RGB; if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV; } else { *tex_type = GL_UNSIGNED_SHORT_5_6_5; swizzle[0] = GL_BLUE; swizzle[2] = GL_RED; } break; case PICT_x1b5g5r5: case PICT_a1b5g5r5: *tex_format = GL_RGBA; if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; } else { return FALSE; } break; case PICT_x1r5g5b5: case PICT_a1r5g5b5: if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { *tex_format = GL_BGRA; *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; } else { return FALSE; } break; case PICT_a8: *tex_format = glamor_priv->one_channel_format; *tex_type = GL_UNSIGNED_BYTE; break; case PICT_x4r4g4b4: case PICT_a4r4g4b4: if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { *tex_format = GL_BGRA; *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; } else { /* XXX */ *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_SHORT_4_4_4_4; } break; case PICT_x4b4g4r4: case PICT_a4b4g4r4: if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; } else { /* XXX */ *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_SHORT_4_4_4_4; } break; default: return FALSE; } if (!PICT_FORMAT_A(format)) swizzle[3] = GL_ONE; return TRUE; } /** * Takes a set of source bits with a given format and returns an * in-memory pixman image of those bits in a destination format. */ static pixman_image_t * glamor_get_converted_image(PictFormatShort dst_format, PictFormatShort src_format, void *src_bits, int src_stride, int w, int h) { pixman_image_t *dst_image; pixman_image_t *src_image; dst_image = pixman_image_create_bits(dst_format, w, h, NULL, 0); if (dst_image == NULL) { return NULL; } src_image = pixman_image_create_bits(src_format, w, h, src_bits, src_stride); if (src_image == NULL) { pixman_image_unref(dst_image); return NULL; } pixman_image_composite(PictOpSrc, src_image, NULL, dst_image, 0, 0, 0, 0, 0, 0, w, h); pixman_image_unref(src_image); return dst_image; } /** * Uploads a picture based on a GLAMOR_MEMORY pixmap to a texture in a * temporary FBO. */ Bool glamor_upload_picture_to_texture(PicturePtr picture) { PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable); ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); PictFormatShort converted_format; void *bits = pixmap->devPrivate.ptr; int stride = pixmap->devKind; GLenum format, type; GLenum swizzle[4]; GLenum iformat; Bool ret = TRUE; Bool needs_swizzle; pixman_image_t *converted_image = NULL; assert(glamor_pixmap_is_memory(pixmap)); assert(!pixmap_priv->fbo); glamor_make_current(glamor_priv); /* No handling of large pixmap pictures here (would need to make * an FBO array and split the uploads across it). */ if (!glamor_check_fbo_size(glamor_priv, pixmap->drawable.width, pixmap->drawable.height)) { return FALSE; } if (!glamor_get_tex_format_type_from_pictformat(screen, picture->format, &converted_format, &format, &type, swizzle)) { glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth); return FALSE; } needs_swizzle = (swizzle[0] != GL_RED || swizzle[1] != GL_GREEN || swizzle[2] != GL_BLUE || swizzle[3] != GL_ALPHA); if (!glamor_priv->has_texture_swizzle && needs_swizzle) { glamor_fallback("Couldn't upload temporary picture due to missing " "GL_ARB_texture_swizzle.\n"); return FALSE; } if (converted_format != picture->format) { converted_image = glamor_get_converted_image(converted_format, picture->format, bits, stride, pixmap->drawable.width, pixmap->drawable.height); if (!converted_image) return FALSE; bits = pixman_image_get_data(converted_image); stride = pixman_image_get_stride(converted_image); } if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) iformat = gl_iformat_for_pixmap(pixmap); else iformat = format; if (!glamor_pixmap_ensure_fbo(pixmap, iformat, GLAMOR_CREATE_FBO_NO_FBO)) { ret = FALSE; goto fail; } glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glamor_priv->suppress_gl_out_of_memory_logging = true; /* We can't use glamor_pixmap_loop() because GLAMOR_MEMORY pixmaps * don't have initialized boxes. */ glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex); glTexImage2D(GL_TEXTURE_2D, 0, iformat, pixmap->drawable.width, pixmap->drawable.height, 0, format, type, bits); if (needs_swizzle) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, swizzle[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, swizzle[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, swizzle[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, swizzle[3]); } glamor_priv->suppress_gl_out_of_memory_logging = false; if (glGetError() == GL_OUT_OF_MEMORY) { ret = FALSE; } fail: if (converted_image) pixman_image_unref(converted_image); return ret; } xorg-server-1.20.13/glamor/glamor_vbo.c0000644000175000017500000001600414100573756014647 00000000000000/* * Copyright © 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ /** * @file glamor_vbo.c * * Helpers for managing streamed vertex bufffers used in glamor. */ #include "glamor_priv.h" /** Default size of the VBO, in bytes. * * If a single request is larger than this size, we'll resize the VBO * and return an appropriate mapping, but we'll resize back down after * that to avoid hogging that memory forever. We don't anticipate * normal usage actually requiring larger VBO sizes. */ #define GLAMOR_VBO_SIZE (512 * 1024) /** * Returns a pointer to @size bytes of VBO storage, which should be * accessed by the GL using vbo_offset within the VBO. */ void * glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); void *data; glamor_make_current(glamor_priv); glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); if (glamor_priv->has_buffer_storage) { if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) { if (glamor_priv->vbo_size) glUnmapBuffer(GL_ARRAY_BUFFER); if (size > glamor_priv->vbo_size) { glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size); /* We aren't allowed to resize glBufferStorage() * buffers, so we need to gen a new one. */ glDeleteBuffers(1, &glamor_priv->vbo); glGenBuffers(1, &glamor_priv->vbo); glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); assert(glGetError() == GL_NO_ERROR); glBufferStorage(GL_ARRAY_BUFFER, glamor_priv->vbo_size, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); if (glGetError() != GL_NO_ERROR) { /* If the driver failed our coherent mapping, fall * back to the ARB_mbr path. */ glamor_priv->has_buffer_storage = false; glamor_priv->vbo_size = 0; return glamor_get_vbo_space(screen, size, vbo_offset); } } glamor_priv->vbo_offset = 0; glamor_priv->vb = glMapBufferRange(GL_ARRAY_BUFFER, 0, glamor_priv->vbo_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); } *vbo_offset = (void *)(uintptr_t)glamor_priv->vbo_offset; data = glamor_priv->vb + glamor_priv->vbo_offset; glamor_priv->vbo_offset += size; } else if (glamor_priv->has_map_buffer_range) { /* Avoid GL errors on GL 4.5 / ES 3.0 with mapping size == 0, * which callers may sometimes pass us (for example, if * clipping leads to zero rectangles left). Prior to that * version, Mesa would sometimes throw errors on unmapping a * zero-size mapping. */ if (size == 0) return NULL; if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) { glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size); glamor_priv->vbo_offset = 0; glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_size, NULL, GL_STREAM_DRAW); } data = glMapBufferRange(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, size, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_RANGE_BIT); *vbo_offset = (char *)(uintptr_t)glamor_priv->vbo_offset; glamor_priv->vbo_offset += size; glamor_priv->vbo_mapped = TRUE; } else { /* Return a pointer to the statically allocated non-VBO * memory. We'll upload it through glBufferData() later. */ if (glamor_priv->vbo_size < size) { glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size); free(glamor_priv->vb); glamor_priv->vb = xnfalloc(glamor_priv->vbo_size); } *vbo_offset = NULL; /* We point to the start of glamor_priv->vb every time, and * the vbo_offset determines the size of the glBufferData(). */ glamor_priv->vbo_offset = size; data = glamor_priv->vb; } return data; } void glamor_put_vbo_space(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); if (glamor_priv->has_buffer_storage) { /* If we're in the ARB_buffer_storage path, we have a * persistent mapping, so we can leave it around until we * reach the end of the buffer. */ } else if (glamor_priv->has_map_buffer_range) { if (glamor_priv->vbo_mapped) { glUnmapBuffer(GL_ARRAY_BUFFER); glamor_priv->vbo_mapped = FALSE; } } else { glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb, GL_DYNAMIC_DRAW); } glBindBuffer(GL_ARRAY_BUFFER, 0); } void glamor_init_vbo(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); glGenBuffers(1, &glamor_priv->vbo); glGenVertexArrays(1, &glamor_priv->vao); glBindVertexArray(glamor_priv->vao); } void glamor_fini_vbo(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); glDeleteVertexArrays(1, &glamor_priv->vao); glamor_priv->vao = 0; if (!glamor_priv->has_map_buffer_range) free(glamor_priv->vb); } xorg-server-1.20.13/glamor/glamor_window.c0000644000175000017500000000463514100573756015377 00000000000000/* * Copyright © 2008 Intel Corporation * Copyright © 1998 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "glamor_priv.h" /** @file glamor_window.c * * Screen Change Window Attribute implementation. */ static void glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr *ppPixmap) { PixmapPtr pPixmap = *ppPixmap; glamor_pixmap_private *pixmap_priv; if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { pixmap_priv = glamor_get_pixmap_private(pPixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { glamor_fallback("pixmap %p has no fbo\n", pPixmap); goto fail; } glamor_debug_output(GLAMOR_DEBUG_UNIMPL, "To be implemented.\n"); } return; fail: GLAMOR_PANIC (" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile" " is broken for glamor. \n"); } Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask) { if (mask & CWBackPixmap) { if (pWin->backgroundState == BackgroundPixmap) glamor_fixup_window_pixmap(&pWin->drawable, &pWin->background.pixmap); } if (mask & CWBorderPixmap) { if (pWin->borderIsPixel == FALSE) glamor_fixup_window_pixmap(&pWin->drawable, &pWin->border.pixmap); } return TRUE; } xorg-server-1.20.13/glamor/glamor_fbo.c0000644000175000017500000002543214100573756014634 00000000000000/* * Copyright © 2009 Intel Corporation * Copyright © 1998 Keith Packard * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Zhigang Gong * */ #include #include "glamor_priv.h" void glamor_destroy_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo) { glamor_make_current(glamor_priv); if (fbo->fb) glDeleteFramebuffers(1, &fbo->fb); if (fbo->tex) glDeleteTextures(1, &fbo->tex); free(fbo); } static int glamor_pixmap_ensure_fb(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo) { int status, err = 0; glamor_make_current(glamor_priv); if (fbo->fb == 0) glGenFramebuffers(1, &fbo->fb); assert(fbo->tex != 0); glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->tex, 0); status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { const char *str; switch (status) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: str = "incomplete attachment"; break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: str = "incomplete/missing attachment"; break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: str = "incomplete draw buffer"; break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: str = "incomplete read buffer"; break; case GL_FRAMEBUFFER_UNSUPPORTED: str = "unsupported"; break; case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: str = "incomplete multiple"; break; default: str = "unknown error"; break; } glamor_fallback("glamor: Failed to create fbo, %s\n", str); err = -1; } return err; } glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv, int w, int h, GLenum format, GLint tex, int flag) { glamor_pixmap_fbo *fbo; fbo = calloc(1, sizeof(*fbo)); if (fbo == NULL) return NULL; fbo->tex = tex; fbo->width = w; fbo->height = h; fbo->format = format; if (flag != GLAMOR_CREATE_FBO_NO_FBO) { if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) { glamor_destroy_fbo(glamor_priv, fbo); fbo = NULL; } } return fbo; } static int _glamor_create_tex(glamor_screen_private *glamor_priv, int w, int h, GLenum format) { unsigned int tex; GLenum iformat = format; if (format == GL_RGB10_A2) format = GL_RGBA; glamor_make_current(glamor_priv); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (format == glamor_priv->one_channel_format && format == GL_RED) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); glamor_priv->suppress_gl_out_of_memory_logging = true; glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, GL_UNSIGNED_BYTE, NULL); glamor_priv->suppress_gl_out_of_memory_logging = false; if (glGetError() == GL_OUT_OF_MEMORY) { if (!glamor_priv->logged_any_fbo_allocation_failure) { LogMessageVerb(X_WARNING, 0, "glamor: Failed to allocate %dx%d " "FBO due to GL_OUT_OF_MEMORY.\n", w, h); LogMessageVerb(X_WARNING, 0, "glamor: Expect reduced performance.\n"); glamor_priv->logged_any_fbo_allocation_failure = true; } glDeleteTextures(1, &tex); return 0; } return tex; } glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv, int w, int h, GLenum format, int flag) { GLint tex = _glamor_create_tex(glamor_priv, w, h, format); if (!tex) /* Texture creation failed due to GL_OUT_OF_MEMORY */ return NULL; return glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag); } /** * Create storage for the w * h region, using FBOs of the GL's maximum * supported size. */ glamor_pixmap_fbo * glamor_create_fbo_array(glamor_screen_private *glamor_priv, int w, int h, GLenum format, int flag, int block_w, int block_h, glamor_pixmap_private *priv) { int block_wcnt; int block_hcnt; glamor_pixmap_fbo **fbo_array; BoxPtr box_array; int i, j; priv->block_w = block_w; priv->block_h = block_h; block_wcnt = (w + block_w - 1) / block_w; block_hcnt = (h + block_h - 1) / block_h; box_array = calloc(block_wcnt * block_hcnt, sizeof(box_array[0])); if (box_array == NULL) return NULL; fbo_array = calloc(block_wcnt * block_hcnt, sizeof(glamor_pixmap_fbo *)); if (fbo_array == NULL) { free(box_array); return FALSE; } for (i = 0; i < block_hcnt; i++) { int block_y1, block_y2; int fbo_w, fbo_h; block_y1 = i * block_h; block_y2 = (block_y1 + block_h) > h ? h : (block_y1 + block_h); fbo_h = block_y2 - block_y1; for (j = 0; j < block_wcnt; j++) { box_array[i * block_wcnt + j].x1 = j * block_w; box_array[i * block_wcnt + j].y1 = block_y1; box_array[i * block_wcnt + j].x2 = (j + 1) * block_w > w ? w : (j + 1) * block_w; box_array[i * block_wcnt + j].y2 = block_y2; fbo_w = box_array[i * block_wcnt + j].x2 - box_array[i * block_wcnt + j].x1; fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv, fbo_w, fbo_h, format, GLAMOR_CREATE_PIXMAP_FIXUP); if (fbo_array[i * block_wcnt + j] == NULL) goto cleanup; } } priv->box = box_array[0]; priv->box_array = box_array; priv->fbo_array = fbo_array; priv->block_wcnt = block_wcnt; priv->block_hcnt = block_hcnt; return fbo_array[0]; cleanup: for (i = 0; i < block_wcnt * block_hcnt; i++) if (fbo_array[i]) glamor_destroy_fbo(glamor_priv, fbo_array[i]); free(box_array); free(fbo_array); return NULL; } void glamor_pixmap_clear_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo) { glamor_make_current(glamor_priv); assert(fbo->fb != 0 && fbo->tex != 0); glamor_set_destination_pixmap_fbo(glamor_priv, fbo, 0, 0, fbo->width, fbo->height); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); } glamor_pixmap_fbo * glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv) { glamor_pixmap_fbo *fbo; if (pixmap_priv == NULL) return NULL; fbo = pixmap_priv->fbo; if (fbo == NULL) return NULL; pixmap_priv->fbo = NULL; return fbo; } /* The pixmap must not be attached to another fbo. */ void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo) { glamor_pixmap_private *pixmap_priv; pixmap_priv = glamor_get_pixmap_private(pixmap); if (pixmap_priv->fbo) return; pixmap_priv->fbo = fbo; switch (pixmap_priv->type) { case GLAMOR_TEXTURE_ONLY: case GLAMOR_TEXTURE_DRM: pixmap_priv->gl_fbo = GLAMOR_FBO_NORMAL; pixmap->devPrivate.ptr = NULL; default: break; } } void glamor_pixmap_destroy_fbo(PixmapPtr pixmap) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_fbo *fbo; if (glamor_pixmap_priv_is_large(priv)) { int i; for (i = 0; i < priv->block_wcnt * priv->block_hcnt; i++) glamor_destroy_fbo(glamor_priv, priv->fbo_array[i]); free(priv->fbo_array); priv->fbo_array = NULL; } else { fbo = glamor_pixmap_detach_fbo(priv); if (fbo) glamor_destroy_fbo(glamor_priv, fbo); } } Bool glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag) { glamor_screen_private *glamor_priv; glamor_pixmap_private *pixmap_priv; glamor_pixmap_fbo *fbo; glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); pixmap_priv = glamor_get_pixmap_private(pixmap); if (pixmap_priv->fbo == NULL) { fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width, pixmap->drawable.height, format, flag); if (fbo == NULL) return FALSE; glamor_pixmap_attach_fbo(pixmap, fbo); } else { /* We do have a fbo, but it may lack of fb or tex. */ if (!pixmap_priv->fbo->tex) pixmap_priv->fbo->tex = _glamor_create_tex(glamor_priv, pixmap->drawable.width, pixmap->drawable.height, format); if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0) if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->fbo) != 0) return FALSE; } return TRUE; } _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back) { glamor_pixmap_private *front_priv, *back_priv; glamor_pixmap_fbo *temp_fbo; front_priv = glamor_get_pixmap_private(front); back_priv = glamor_get_pixmap_private(back); temp_fbo = front_priv->fbo; front_priv->fbo = back_priv->fbo; back_priv->fbo = temp_fbo; } xorg-server-1.20.13/glamor/glamor_compositerects.c0000644000175000017500000002073114100573756017126 00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Zhigang Gong * * original author is Chris Wilson at sna. * */ #include "glamor_priv.h" #include "mipict.h" #include "damage.h" /** @file glamor_compositerects. * * compositeRects acceleration implementation */ static int16_t bound(int16_t a, uint16_t b) { int v = (int) a + (int) b; if (v > MAXSHORT) return MAXSHORT; return v; } static Bool _pixman_region_init_clipped_rectangles(pixman_region16_t * region, unsigned int num_rects, xRectangle *rects, int tx, int ty, BoxPtr extents) { pixman_box16_t stack_boxes[64], *boxes = stack_boxes; pixman_bool_t ret; unsigned int i, j; if (num_rects > ARRAY_SIZE(stack_boxes)) { boxes = xallocarray(num_rects, sizeof(pixman_box16_t)); if (boxes == NULL) return FALSE; } for (i = j = 0; i < num_rects; i++) { boxes[j].x1 = rects[i].x + tx; if (boxes[j].x1 < extents->x1) boxes[j].x1 = extents->x1; boxes[j].y1 = rects[i].y + ty; if (boxes[j].y1 < extents->y1) boxes[j].y1 = extents->y1; boxes[j].x2 = bound(rects[i].x + tx, rects[i].width); if (boxes[j].x2 > extents->x2) boxes[j].x2 = extents->x2; boxes[j].y2 = bound(rects[i].y + ty, rects[i].height); if (boxes[j].y2 > extents->y2) boxes[j].y2 = extents->y2; if (boxes[j].x2 > boxes[j].x1 && boxes[j].y2 > boxes[j].y1) j++; } ret = FALSE; if (j) ret = pixman_region_init_rects(region, boxes, j); if (boxes != stack_boxes) free(boxes); DEBUGF("%s: nrects=%d, region=(%d, %d), (%d, %d) x %d\n", __FUNCTION__, num_rects, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, j); return ret; } void glamor_composite_rectangles(CARD8 op, PicturePtr dst, xRenderColor * color, int num_rects, xRectangle *rects) { PixmapPtr pixmap; struct glamor_pixmap_private *priv; pixman_region16_t region; pixman_box16_t *boxes; int num_boxes; PicturePtr source = NULL; Bool need_free_region = FALSE; DEBUGF("%s(op=%d, %08x x %d [(%d, %d)x(%d, %d) ...])\n", __FUNCTION__, op, (color->alpha >> 8 << 24) | (color->red >> 8 << 16) | (color->green >> 8 << 8) | (color->blue >> 8 << 0), num_rects, rects[0].x, rects[0].y, rects[0].width, rects[0].height); if (!num_rects) return; if (RegionNil(dst->pCompositeClip)) { DEBUGF("%s: empty clip, skipping\n", __FUNCTION__); return; } if ((color->red | color->green | color->blue | color->alpha) <= 0x00ff) { switch (op) { case PictOpOver: case PictOpOutReverse: case PictOpAdd: return; case PictOpInReverse: case PictOpSrc: op = PictOpClear; break; case PictOpAtopReverse: op = PictOpOut; break; case PictOpXor: op = PictOpOverReverse; break; } } if (color->alpha <= 0x00ff) { switch (op) { case PictOpOver: case PictOpOutReverse: return; case PictOpInReverse: op = PictOpClear; break; case PictOpAtopReverse: op = PictOpOut; break; case PictOpXor: op = PictOpOverReverse; break; } } else if (color->alpha >= 0xff00) { switch (op) { case PictOpOver: op = PictOpSrc; break; case PictOpInReverse: return; case PictOpOutReverse: op = PictOpClear; break; case PictOpAtopReverse: op = PictOpOverReverse; break; case PictOpXor: op = PictOpOut; break; } } DEBUGF("%s: converted to op %d\n", __FUNCTION__, op); if (!_pixman_region_init_clipped_rectangles(®ion, num_rects, rects, dst->pDrawable->x, dst->pDrawable->y, &dst->pCompositeClip->extents)) { DEBUGF("%s: allocation failed for region\n", __FUNCTION__); return; } pixmap = glamor_get_drawable_pixmap(dst->pDrawable); priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) goto fallback; if (dst->alphaMap) { DEBUGF("%s: fallback, dst has an alpha-map\n", __FUNCTION__); goto fallback; } need_free_region = TRUE; DEBUGF("%s: drawable extents (%d, %d),(%d, %d) x %d\n", __FUNCTION__, RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, RegionExtents(®ion)->x2, RegionExtents(®ion)->y2, RegionNumRects(®ion)); if (dst->pCompositeClip->data && (!pixman_region_intersect(®ion, ®ion, dst->pCompositeClip) || RegionNil(®ion))) { DEBUGF("%s: zero-intersection between rectangles and clip\n", __FUNCTION__); pixman_region_fini(®ion); return; } DEBUGF("%s: clipped extents (%d, %d),(%d, %d) x %d\n", __FUNCTION__, RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, RegionExtents(®ion)->x2, RegionExtents(®ion)->y2, RegionNumRects(®ion)); boxes = pixman_region_rectangles(®ion, &num_boxes); if (op == PictOpSrc || op == PictOpClear) { CARD32 pixel; int dst_x, dst_y; glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y); pixman_region_translate(®ion, dst_x, dst_y); DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n", __FUNCTION__, dst_x, dst_y, RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, RegionExtents(®ion)->x2, RegionExtents(®ion)->y2); if (op == PictOpClear) pixel = 0; else miRenderColorToPixel(dst->pFormat, color, &pixel); glamor_solid_boxes(pixmap, boxes, num_boxes, pixel); goto done; } else { if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) { int error; source = CreateSolidPicture(0, color, &error); if (!source) goto done; if (glamor_composite_clipped_region(op, source, NULL, dst, NULL, NULL, pixmap, ®ion, 0, 0, 0, 0, 0, 0)) goto done; } } fallback: miCompositeRects(op, dst, color, num_rects, rects); done: /* XXX xserver-1.8: CompositeRects is not tracked by Damage, so we must * manually append the damaged regions ourselves. */ DamageRegionAppend(&pixmap->drawable, ®ion); DamageRegionProcessPending(&pixmap->drawable); if (need_free_region) pixman_region_fini(®ion); if (source) FreePicture(source, 0); return; } xorg-server-1.20.13/glamor/glamor_utils.c0000644000175000017500000000505414100573756015224 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" void glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, unsigned long fg_pixel) { DrawablePtr drawable = &pixmap->drawable; GCPtr gc; xRectangle *rect; int n; rect = xallocarray(nbox, sizeof(xRectangle)); if (!rect) return; for (n = 0; n < nbox; n++) { rect[n].x = box[n].x1; rect[n].y = box[n].y1; rect[n].width = box[n].x2 - box[n].x1; rect[n].height = box[n].y2 - box[n].y1; } gc = GetScratchGC(drawable->depth, drawable->pScreen); if (gc) { ChangeGCVal vals[1]; vals[0].val = fg_pixel; ChangeGC(NullClient, gc, GCForeground, vals); ValidateGC(drawable, gc); gc->ops->PolyFillRect(drawable, gc, nbox, rect); FreeScratchGC(gc); } free(rect); } void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, unsigned long fg_pixel) { DrawablePtr drawable = &pixmap->drawable; GCPtr gc; ChangeGCVal vals[1]; xRectangle rect; vals[0].val = fg_pixel; gc = GetScratchGC(drawable->depth, drawable->pScreen); if (!gc) return; ChangeGC(NullClient, gc, GCForeground, vals); ValidateGC(drawable, gc); rect.x = x; rect.y = y; rect.width = width; rect.height = height; gc->ops->PolyFillRect(drawable, gc, 1, &rect); FreeScratchGC(gc); } xorg-server-1.20.13/glamor/glamor_utils.h0000644000175000017500000006245214100573756015236 00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Zhigang Gong * */ #ifndef GLAMOR_PRIV_H #error This file can only be included by glamor_priv.h #endif #ifndef __GLAMOR_UTILS_H__ #define __GLAMOR_UTILS_H__ #include "glamor_prepare.h" #include "mipict.h" #define v_from_x_coord_x(_xscale_, _x_) ( 2 * (_x_) * (_xscale_) - 1.0) #define v_from_x_coord_y(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0) #define t_from_x_coord_x(_xscale_, _x_) ((_x_) * (_xscale_)) #define t_from_x_coord_y(_yscale_, _y_) ((_y_) * (_yscale_)) #define pixmap_priv_get_dest_scale(pixmap, _pixmap_priv_, _pxscale_, _pyscale_) \ do { \ int _w_,_h_; \ PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, _pixmap_priv_, _w_, _h_); \ *(_pxscale_) = 1.0 / _w_; \ *(_pyscale_) = 1.0 / _h_; \ } while(0) #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \ do { \ *(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width; \ *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height; \ } while(0) #define PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, w, h) \ do { \ if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \ w = priv->box.x2 - priv->box.x1; \ h = priv->box.y2 - priv->box.y1; \ } else { \ w = (pixmap)->drawable.width; \ h = (pixmap)->drawable.height; \ } \ } while(0) #define glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, priv) \ do { \ int actual_w, actual_h; \ PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, actual_w, actual_h); \ wh[0] = (float)priv->fbo->width / actual_w; \ wh[1] = (float)priv->fbo->height / actual_h; \ wh[2] = 1.0 / priv->fbo->width; \ wh[3] = 1.0 / priv->fbo->height; \ } while(0) #define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_) \ do { \ if (_X_UNLIKELY(_priv_ && glamor_pixmap_priv_is_large(_priv_))) { \ *(_xoff_) = - (_priv_)->box.x1; \ *(_yoff_) = - (_priv_)->box.y1; \ } else { \ *(_xoff_) = 0; \ *(_yoff_) = 0; \ } \ } while(0) #define xFixedToFloat(_val_) ((float)xFixedToInt(_val_) \ + ((float)xFixedFrac(_val_) / 65536.0)) #define glamor_picture_get_matrixf(_picture_, _matrix_) \ do { \ int _i_; \ if ((_picture_)->transform) \ { \ for(_i_ = 0; _i_ < 3; _i_++) \ { \ (_matrix_)[_i_ * 3 + 0] = \ xFixedToFloat((_picture_)->transform->matrix[_i_][0]); \ (_matrix_)[_i_ * 3 + 1] = \ xFixedToFloat((_picture_)->transform->matrix[_i_][1]); \ (_matrix_)[_i_ * 3 + 2] = \ xFixedToFloat((_picture_)->transform->matrix[_i_][2]); \ } \ } \ } while(0) #define fmod(x, w) (x - w * floor((float)x/w)) #define fmodulus(x, w, c) do {c = fmod(x, w); \ c = c >= 0 ? c : c + w;} \ while(0) /* @x: is current coord * @x2: is the right/bottom edge * @w: is current width or height * @odd: is output value, 0 means we are in an even region, 1 means we are in a * odd region. * @c: is output value, equal to x mod w. */ #define fodd_repeat_mod(x, x2, w, odd, c) \ do { \ float shift; \ fmodulus((x), w, c); \ shift = fabs((x) - (c)); \ shift = floor(fabs(round(shift)) / w); \ odd = (int)shift & 1; \ if (odd && (((x2 % w) == 0) && \ round(fabs(x)) == x2)) \ odd = 0; \ } while(0) /* @txy: output value, is the corrected coords. * @xy: input coords to be fixed up. * @cd: xy mod wh, is a input value. * @wh: current width or height. * @bxy1,bxy2: current box edge's x1/x2 or y1/y2 * * case 1: * ---------- * | * | * | | * ---------- * tx = (c - x1) mod w * * case 2: * --------- * * | | * | | * --------- * tx = - (c - (x1 mod w)) * * case 3: * * ---------- * | | * * | | * ---------- * tx = ((x2 mod x) - c) + (x2 - x1) **/ #define __glamor_repeat_reflect_fixup(txy, xy, \ cd, wh, bxy1, bxy2) \ do { \ cd = wh - cd; \ if ( xy >= bxy1 && xy < bxy2) { \ cd = cd - bxy1; \ fmodulus(cd, wh, txy); \ } else if (xy < bxy1) { \ float bxy1_mod; \ fmodulus(bxy1, wh, bxy1_mod); \ txy = -(cd - bxy1_mod); \ } \ else if (xy >= bxy2) { \ float bxy2_mod; \ fmodulus(bxy2, wh, bxy2_mod); \ if (bxy2_mod == 0) \ bxy2_mod = wh; \ txy = (bxy2_mod - cd) + bxy2 - bxy1; \ } else {assert(0); txy = 0;} \ } while(0) #define _glamor_repeat_reflect_fixup(txy, xy, cd, odd, \ wh, bxy1, bxy2) \ do { \ if (odd) { \ __glamor_repeat_reflect_fixup(txy, xy, \ cd, wh, bxy1, bxy2); \ } else \ txy = xy - bxy1; \ } while(0) #define _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \ tx1, ty1, \ _x1_, _y1_) \ do { \ int odd_x, odd_y; \ float c, d; \ fodd_repeat_mod(_x1_,priv->box.x2, \ (pixmap)->drawable.width, \ odd_x, c); \ fodd_repeat_mod(_y1_, priv->box.y2, \ (pixmap)->drawable.height, \ odd_y, d); \ DEBUGF("c %f d %f oddx %d oddy %d \n", \ c, d, odd_x, odd_y); \ DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2, \ priv->box.x1, priv->fbo->width); \ DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, \ priv->box.y1, priv->fbo->height); \ _glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x, \ (pixmap)->drawable.width, \ priv->box.x1, priv->box.x2); \ _glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y, \ (pixmap)->drawable.height, \ priv->box.y1, priv->box.y2); \ } while(0) #define _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, \ ty1, tx2, ty2, \ _x1_, _y1_, _x2_, \ _y2_, c, d, odd_x, odd_y) \ do { \ if (repeat_type == RepeatReflect) { \ DEBUGF("x1 y1 %d %d\n", \ _x1_, _y1_ ); \ DEBUGF("width %d box.x1 %d \n", \ (pixmap)->drawable.width, \ priv->box.x1); \ if (odd_x) { \ c = (pixmap)->drawable.width \ - c; \ tx1 = c - priv->box.x1; \ tx2 = tx1 - ((_x2_) - (_x1_)); \ } else { \ tx1 = c - priv->box.x1; \ tx2 = tx1 + ((_x2_) - (_x1_)); \ } \ if (odd_y){ \ d = (pixmap)->drawable.height\ - d; \ ty1 = d - priv->box.y1; \ ty2 = ty1 - ((_y2_) - (_y1_)); \ } else { \ ty1 = d - priv->box.y1; \ ty2 = ty1 + ((_y2_) - (_y1_)); \ } \ } else { /* RepeatNormal*/ \ tx1 = (c - priv->box.x1); \ ty1 = (d - priv->box.y1); \ tx2 = tx1 + ((_x2_) - (_x1_)); \ ty2 = ty1 + ((_y2_) - (_y1_)); \ } \ } while(0) /* _x1_ ... _y2_ may has fractional. */ #define glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, tx1, \ ty1, _x1_, _y1_) \ do { \ DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \ (pixmap)->drawable.width, \ priv->box.x1, priv->box.x2, priv->box.y1, \ priv->box.y2); \ DEBUGF("x1 %f y1 %f \n", _x1_, _y1_); \ if (repeat_type != RepeatReflect) { \ tx1 = _x1_ - priv->box.x1; \ ty1 = _y1_ - priv->box.y1; \ } else \ _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \ tx1, ty1, \ _x1_, _y1_); \ DEBUGF("tx1 %f ty1 %f \n", tx1, ty1); \ } while(0) /* _x1_ ... _y2_ must be integer. */ #define glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, \ ty1, tx2, ty2, _x1_, _y1_, _x2_, \ _y2_) \ do { \ int c, d; \ int odd_x = 0, odd_y = 0; \ DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \ (pixmap)->drawable.width, \ priv->box.x1, priv->box.x2, \ priv->box.y1, priv->box.y2); \ modulus((_x1_), (pixmap)->drawable.width, c); \ modulus((_y1_), (pixmap)->drawable.height, d); \ DEBUGF("c %d d %d \n", c, d); \ if (repeat_type == RepeatReflect) { \ odd_x = abs((_x1_ - c) \ / ((pixmap)->drawable.width)) & 1; \ odd_y = abs((_y1_ - d) \ / ((pixmap)->drawable.height)) & 1; \ } \ _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, ty1, tx2, ty2, \ _x1_, _y1_, _x2_, _y2_, c, d, \ odd_x, odd_y); \ } while(0) #define glamor_transform_point(matrix, tx, ty, x, y) \ do { \ int _i_; \ float _result_[4]; \ for (_i_ = 0; _i_ < 3; _i_++) { \ _result_[_i_] = (matrix)[_i_ * 3] * (x) + (matrix)[_i_ * 3 + 1] * (y) \ + (matrix)[_i_ * 3 + 2]; \ } \ tx = _result_[0] / _result_[2]; \ ty = _result_[1] / _result_[2]; \ } while(0) #define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_, \ texcoord) \ do { \ (texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \ (texcoord)[1] = t_from_x_coord_y(yscale, _ty_); \ DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \ (texcoord)[1]); \ } while(0) #define glamor_set_transformed_point(priv, matrix, xscale, \ yscale, texcoord, \ x, y) \ do { \ float tx, ty; \ int fbo_x_off, fbo_y_off; \ pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \ glamor_transform_point(matrix, tx, ty, x, y); \ DEBUGF("tx %f ty %f fbooff %d %d \n", \ tx, ty, fbo_x_off, fbo_y_off); \ \ tx += fbo_x_off; \ ty += fbo_y_off; \ (texcoord)[0] = t_from_x_coord_x(xscale, tx); \ (texcoord)[1] = t_from_x_coord_y(yscale, ty); \ DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \ } while(0) #define glamor_set_transformed_normalize_tcoords_ext( priv, \ matrix, \ xscale, \ yscale, \ tx1, ty1, tx2, ty2, \ texcoords, \ stride) \ do { \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ texcoords, tx1, ty1); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ texcoords + 1 * stride, tx2, ty1); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ texcoords + 2 * stride, tx2, ty2); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ texcoords + 3 * stride, tx1, ty2); \ } while (0) #define glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, \ repeat_type, \ matrix, \ xscale, \ yscale, \ _x1_, _y1_, \ _x2_, _y2_, \ texcoords, \ stride) \ do { \ if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) { \ glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \ yscale, _x1_, _y1_, \ _x2_, _y2_, \ texcoords, stride); \ } else { \ float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \ float ttx1, tty1, ttx2, tty2, ttx3, tty3, ttx4, tty4; \ DEBUGF("original coords %d %d %d %d\n", _x1_, _y1_, _x2_, _y2_); \ glamor_transform_point(matrix, tx1, ty1, _x1_, _y1_); \ glamor_transform_point(matrix, tx2, ty2, _x2_, _y1_); \ glamor_transform_point(matrix, tx3, ty3, _x2_, _y2_); \ glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_); \ DEBUGF("transformed %f %f %f %f %f %f %f %f\n", \ tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4); \ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \ ttx1, tty1, \ tx1, ty1); \ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \ ttx2, tty2, \ tx2, ty2); \ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \ ttx3, tty3, \ tx3, ty3); \ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \ ttx4, tty4, \ tx4, ty4); \ DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \ ttx2, tty2, ttx3, tty3, ttx4, tty4); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \ texcoords); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \ texcoords + 1 * stride); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \ texcoords + 2 * stride); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \ texcoords + 3 * stride); \ } \ } while (0) #define glamor_set_repeat_transformed_normalize_tcoords( pixmap, \ priv, \ repeat_type, \ matrix, \ xscale, \ yscale, \ _x1_, _y1_, \ _x2_, _y2_, \ texcoords) \ do { \ glamor_set_repeat_transformed_normalize_tcoords_ext( pixmap, \ priv, \ repeat_type, \ matrix, \ xscale, \ yscale, \ _x1_, _y1_, \ _x2_, _y2_, \ texcoords, \ 2); \ } while (0) #define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \ ty1, tx2, ty2, \ vertices, stride) \ do { \ /* vertices may be write-only, so we use following \ * temporary variable. */ \ float _t0_, _t1_, _t2_, _t5_; \ (vertices)[0] = _t0_ = t_from_x_coord_x(xscale, tx1); \ (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \ (vertices)[2 * stride] = _t2_; \ (vertices)[3 * stride] = _t0_; \ (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1); \ (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2); \ (vertices)[1 * stride + 1] = _t1_; \ (vertices)[3 * stride + 1] = _t5_; \ } while(0) #define glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \ x1, y1, x2, y2, \ vertices, stride) \ do { \ if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \ float tx1, tx2, ty1, ty2; \ int fbo_x_off, fbo_y_off; \ pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \ tx1 = x1 + fbo_x_off; \ tx2 = x2 + fbo_x_off; \ ty1 = y1 + fbo_y_off; \ ty2 = y2 + fbo_y_off; \ _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \ tx2, ty2, vertices, \ stride); \ } else \ _glamor_set_normalize_tcoords(xscale, yscale, x1, y1, \ x2, y2, vertices, stride); \ } while(0) #define glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type, \ xscale, yscale, \ _x1_, _y1_, _x2_, _y2_, \ vertices, stride) \ do { \ if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \ float tx1, tx2, ty1, ty2; \ if (repeat_type == RepeatPad) { \ tx1 = _x1_ - priv->box.x1; \ ty1 = _y1_ - priv->box.y1; \ tx2 = tx1 + ((_x2_) - (_x1_)); \ ty2 = ty1 + ((_y2_) - (_y1_)); \ } else { \ glamor_get_repeat_coords(pixmap, priv, repeat_type, \ tx1, ty1, tx2, ty2, \ _x1_, _y1_, _x2_, _y2_); \ } \ _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \ tx2, ty2, vertices, \ stride); \ } else \ _glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_, \ _x2_, _y2_, vertices, \ stride); \ } while(0) #define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale, \ x1, y1, x2, y2, \ vertices) \ do { \ (vertices)[0] = t_from_x_coord_x(xscale, x1); \ (vertices)[2] = t_from_x_coord_x(xscale, x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ (vertices)[1] = t_from_x_coord_y(yscale, y1); \ (vertices)[7] = t_from_x_coord_y(yscale, y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) #define glamor_set_tcoords_tri_strip(x1, y1, x2, y2, vertices) \ do { \ (vertices)[0] = (x1); \ (vertices)[2] = (x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ (vertices)[1] = (y1); \ (vertices)[7] = (y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) #define glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \ x1, y1, x2, y2, \ vertices, stride) \ do { \ int fbo_x_off, fbo_y_off; \ /* vertices may be write-only, so we use following \ * temporary variable. */ \ float _t0_, _t1_, _t2_, _t5_; \ pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \ (vertices)[0] = _t0_ = v_from_x_coord_x(xscale, x1 + fbo_x_off); \ (vertices)[1 * stride] = _t2_ = v_from_x_coord_x(xscale, \ x2 + fbo_x_off); \ (vertices)[2 * stride] = _t2_; \ (vertices)[3 * stride] = _t0_; \ (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off); \ (vertices)[2 * stride + 1] = _t5_ = \ v_from_x_coord_y(yscale, y2 + fbo_y_off); \ (vertices)[1 * stride + 1] = _t1_; \ (vertices)[3 * stride + 1] = _t5_; \ } while(0) #define glamor_set_normalize_vcoords_tri_strip(xscale, yscale, \ x1, y1, x2, y2, \ vertices) \ do { \ (vertices)[0] = v_from_x_coord_x(xscale, x1); \ (vertices)[2] = v_from_x_coord_x(xscale, x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ (vertices)[1] = v_from_x_coord_y(yscale, y1); \ (vertices)[7] = v_from_x_coord_y(yscale, y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) #define glamor_set_normalize_pt(xscale, yscale, x, y, \ pt) \ do { \ (pt)[0] = t_from_x_coord_x(xscale, x); \ (pt)[1] = t_from_x_coord_y(yscale, y); \ } while(0) #define glamor_set_circle_centre(width, height, x, y, \ c) \ do { \ (c)[0] = (float)x; \ (c)[1] = (float)y; \ } while(0) #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define glamor_check_fbo_size(_glamor_,_w_, _h_) ((_w_) > 0 && (_h_) > 0 \ && (_w_) <= _glamor_->max_fbo_size \ && (_h_) <= _glamor_->max_fbo_size) /* For 1bpp pixmap, we don't store it as texture. */ #define glamor_check_pixmap_fbo_depth(_depth_) ( \ _depth_ == 8 \ || _depth_ == 15 \ || _depth_ == 16 \ || _depth_ == 24 \ || _depth_ == 30 \ || _depth_ == 32) #define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL) /** * Borrow from uxa. */ static inline CARD32 format_for_depth(int depth) { switch (depth) { case 1: return PICT_a1; case 4: return PICT_a4; case 8: return PICT_a8; case 15: return PICT_x1r5g5b5; case 16: return PICT_r5g6b5; default: case 24: return PICT_x8r8g8b8; case 30: return PICT_x2r10g10b10; case 32: return PICT_a8r8g8b8; } } static inline GLenum gl_iformat_for_pixmap(PixmapPtr pixmap) { glamor_screen_private *glamor_priv = glamor_get_screen_private((pixmap)->drawable.pScreen); if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) { return glamor_priv->one_channel_format; } else if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && (pixmap)->drawable.depth == 30) { return GL_RGB10_A2; } else { return GL_RGBA; } } static inline CARD32 format_for_pixmap(PixmapPtr pixmap) { return format_for_depth((pixmap)->drawable.depth); } #define REVERT_NONE 0 #define REVERT_NORMAL 1 #define REVERT_UPLOADING_A1 3 #define SWAP_UPLOADING 2 #define SWAP_NONE_UPLOADING 3 /* borrowed from uxa */ static inline Bool glamor_get_rgba_from_pixel(CARD32 pixel, float *red, float *green, float *blue, float *alpha, CARD32 format) { int rbits, bbits, gbits, abits; int rshift, bshift, gshift, ashift; rbits = PICT_FORMAT_R(format); gbits = PICT_FORMAT_G(format); bbits = PICT_FORMAT_B(format); abits = PICT_FORMAT_A(format); if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { rshift = gshift = bshift = ashift = 0; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { bshift = 0; gshift = bbits; rshift = gshift + gbits; ashift = rshift + rbits; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { rshift = 0; gshift = rbits; bshift = gshift + gbits; ashift = bshift + bbits; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { ashift = 0; rshift = abits; if (abits == 0) rshift = PICT_FORMAT_BPP(format) - (rbits + gbits + bbits); gshift = rshift + rbits; bshift = gshift + gbits; } else { return FALSE; } #define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_) \ *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1)) \ / (float)((1<<(_bits_)) - 1) if (rbits) COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits); else *red = 0; if (gbits) COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits); else *green = 0; if (bbits) COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits); else *blue = 0; if (abits) COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits); else *alpha = 1; return TRUE; } static inline void glamor_get_rgba_from_color(const xRenderColor *color, float rgba[4]) { rgba[0] = color->red / (float)UINT16_MAX; rgba[1] = color->green / (float)UINT16_MAX; rgba[2] = color->blue / (float)UINT16_MAX; rgba[3] = color->alpha / (float)UINT16_MAX; } inline static Bool glamor_is_large_pixmap(PixmapPtr pixmap) { glamor_pixmap_private *priv; priv = glamor_get_pixmap_private(pixmap); return (glamor_pixmap_priv_is_large(priv)); } static inline void glamor_make_current(glamor_screen_private *glamor_priv) { if (lastGLContext != glamor_priv->ctx.ctx) { lastGLContext = glamor_priv->ctx.ctx; glamor_priv->ctx.make_current(&glamor_priv->ctx); } } static inline BoxRec glamor_no_rendering_bounds(void) { BoxRec bounds = { .x1 = 0, .y1 = 0, .x2 = MAXSHORT, .y2 = MAXSHORT, }; return bounds; } static inline BoxRec glamor_start_rendering_bounds(void) { BoxRec bounds = { .x1 = MAXSHORT, .y1 = MAXSHORT, .x2 = 0, .y2 = 0, }; return bounds; } static inline void glamor_bounds_union_rect(BoxPtr bounds, xRectangle *rect) { bounds->x1 = min(bounds->x1, rect->x); bounds->y1 = min(bounds->y1, rect->y); bounds->x2 = min(SHRT_MAX, max(bounds->x2, rect->x + rect->width)); bounds->y2 = min(SHRT_MAX, max(bounds->y2, rect->y + rect->height)); } static inline void glamor_bounds_union_box(BoxPtr bounds, BoxPtr box) { bounds->x1 = min(bounds->x1, box->x1); bounds->y1 = min(bounds->y1, box->y1); bounds->x2 = max(bounds->x2, box->x2); bounds->y2 = max(bounds->y2, box->y2); } /** * Helper function for implementing draws with GL_QUADS on GLES2, * where we don't have them. */ static inline void glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count) { if (glamor_priv->use_quads) { glDrawArrays(GL_QUADS, 0, count * 4); } else { glamor_gldrawarrays_quads_using_indices(glamor_priv, count); } } #endif xorg-server-1.20.13/glamor/glamor_sync.c0000644000175000017500000001003314100573756015031 00000000000000/* * Copyright © 2014 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "glamor_priv.h" #include "misyncshm.h" #include "misyncstr.h" #if XSYNC /* * This whole file exists to wrap a sync fence trigger operation so * that we can flush GL to provide serialization between the server * and the shm fence client */ static DevPrivateKeyRec glamor_sync_fence_key; struct glamor_sync_fence { SyncFenceSetTriggeredFunc set_triggered; }; static inline struct glamor_sync_fence * glamor_get_sync_fence(SyncFence *fence) { return (struct glamor_sync_fence *) dixLookupPrivate(&fence->devPrivates, &glamor_sync_fence_key); } static void glamor_sync_fence_set_triggered (SyncFence *fence) { ScreenPtr screen = fence->pScreen; glamor_screen_private *glamor = glamor_get_screen_private(screen); struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence); /* Flush pending rendering operations */ glamor_make_current(glamor); glFlush(); fence->funcs.SetTriggered = glamor_fence->set_triggered; fence->funcs.SetTriggered(fence); glamor_fence->set_triggered = fence->funcs.SetTriggered; fence->funcs.SetTriggered = glamor_sync_fence_set_triggered; } static void glamor_sync_create_fence(ScreenPtr screen, SyncFence *fence, Bool initially_triggered) { glamor_screen_private *glamor = glamor_get_screen_private(screen); SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence); screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence; screen_funcs->CreateFence(screen, fence, initially_triggered); glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence; screen_funcs->CreateFence = glamor_sync_create_fence; glamor_fence->set_triggered = fence->funcs.SetTriggered; fence->funcs.SetTriggered = glamor_sync_fence_set_triggered; } #endif Bool glamor_sync_init(ScreenPtr screen) { #if XSYNC glamor_screen_private *glamor = glamor_get_screen_private(screen); SyncScreenFuncsPtr screen_funcs; if (!dixPrivateKeyRegistered(&glamor_sync_fence_key)) { if (!dixRegisterPrivateKey(&glamor_sync_fence_key, PRIVATE_SYNC_FENCE, sizeof (struct glamor_sync_fence))) return FALSE; } #ifdef HAVE_XSHMFENCE if (!miSyncShmScreenInit(screen)) return FALSE; #else if (!miSyncSetup(screen)) return FALSE; #endif screen_funcs = miSyncGetScreenFuncs(screen); glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence; screen_funcs->CreateFence = glamor_sync_create_fence; #endif return TRUE; } void glamor_sync_close(ScreenPtr screen) { #if XSYNC glamor_screen_private *glamor = glamor_get_screen_private(screen); SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); if (screen_funcs) screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence; #endif } xorg-server-1.20.13/glamor/glamor_xv.c0000644000175000017500000004412314100573756014521 00000000000000/* * Copyright © 2013 Red Hat * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Dave Airlie * * some code is derived from the xf86-video-ati radeon driver, mainly * the calculations. */ /** @file glamor_xv.c * * Xv acceleration implementation */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glamor_priv.h" #include "glamor_transform.h" #include "glamor_transfer.h" #include #include "../hw/xfree86/common/fourcc.h" /* Reference color space transform data */ typedef struct tagREF_TRANSFORM { float RefLuma; float RefRCb; float RefRCr; float RefGCb; float RefGCr; float RefBCb; float RefBCr; } REF_TRANSFORM; #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0) #define RTFBrightness(a) (((a)*1.0)/2000.0) #define RTFIntensity(a) (((a)*1.0)/2000.0) #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0) #define RTFHue(a) (((a)*3.1416)/1000.0) static const glamor_facet glamor_facet_xv_planar = { .name = "xv_planar", .version = 120, .source_name = "v_texcoord0", .vs_vars = ("attribute vec2 position;\n" "attribute vec2 v_texcoord0;\n" "varying vec2 tcs;\n"), .vs_exec = (GLAMOR_POS(gl_Position, position) " tcs = v_texcoord0;\n"), .fs_vars = ("uniform sampler2D y_sampler;\n" "uniform sampler2D u_sampler;\n" "uniform sampler2D v_sampler;\n" "uniform vec4 offsetyco;\n" "uniform vec4 ucogamma;\n" "uniform vec4 vco;\n" "varying vec2 tcs;\n"), .fs_exec = ( " float sample;\n" " vec4 temp1;\n" " sample = texture2D(y_sampler, tcs).w;\n" " temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n" " sample = texture2D(u_sampler, tcs).w;\n" " temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n" " sample = texture2D(v_sampler, tcs).w;\n" " temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n" " temp1.w = 1.0;\n" " gl_FragColor = temp1;\n" ), }; #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) XvAttributeRec glamor_xv_attributes[] = { {XvSettable | XvGettable, -1000, 1000, (char *)"XV_BRIGHTNESS"}, {XvSettable | XvGettable, -1000, 1000, (char *)"XV_CONTRAST"}, {XvSettable | XvGettable, -1000, 1000, (char *)"XV_SATURATION"}, {XvSettable | XvGettable, -1000, 1000, (char *)"XV_HUE"}, {XvSettable | XvGettable, 0, 1, (char *)"XV_COLORSPACE"}, {0, 0, 0, NULL} }; int glamor_xv_num_attributes = ARRAY_SIZE(glamor_xv_attributes) - 1; Atom glamorBrightness, glamorContrast, glamorSaturation, glamorHue, glamorColorspace, glamorGamma; XvImageRec glamor_xv_images[] = { XVIMAGE_YV12, XVIMAGE_I420, }; int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images); static void glamor_init_xv_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); GLint sampler_loc; glamor_build_program(screen, &glamor_priv->xv_prog, &glamor_facet_xv_planar, NULL, NULL, NULL); glUseProgram(glamor_priv->xv_prog.prog); sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "y_sampler"); glUniform1i(sampler_loc, 0); sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "u_sampler"); glUniform1i(sampler_loc, 1); sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "v_sampler"); glUniform1i(sampler_loc, 2); } #define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v)) void glamor_xv_stop_video(glamor_port_private *port_priv) { } static void glamor_xv_free_port_data(glamor_port_private *port_priv) { int i; for (i = 0; i < 3; i++) { if (port_priv->src_pix[i]) { glamor_destroy_pixmap(port_priv->src_pix[i]); port_priv->src_pix[i] = NULL; } } RegionUninit(&port_priv->clip); RegionNull(&port_priv->clip); } int glamor_xv_set_port_attribute(glamor_port_private *port_priv, Atom attribute, INT32 value) { if (attribute == glamorBrightness) port_priv->brightness = ClipValue(value, -1000, 1000); else if (attribute == glamorHue) port_priv->hue = ClipValue(value, -1000, 1000); else if (attribute == glamorContrast) port_priv->contrast = ClipValue(value, -1000, 1000); else if (attribute == glamorSaturation) port_priv->saturation = ClipValue(value, -1000, 1000); else if (attribute == glamorGamma) port_priv->gamma = ClipValue(value, 100, 10000); else if (attribute == glamorColorspace) port_priv->transform_index = ClipValue(value, 0, 1); else return BadMatch; return Success; } int glamor_xv_get_port_attribute(glamor_port_private *port_priv, Atom attribute, INT32 *value) { if (attribute == glamorBrightness) *value = port_priv->brightness; else if (attribute == glamorHue) *value = port_priv->hue; else if (attribute == glamorContrast) *value = port_priv->contrast; else if (attribute == glamorSaturation) *value = port_priv->saturation; else if (attribute == glamorGamma) *value = port_priv->gamma; else if (attribute == glamorColorspace) *value = port_priv->transform_index; else return BadMatch; return Success; } int glamor_xv_query_image_attributes(int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets) { int size = 0, tmp; if (offsets) offsets[0] = 0; switch (id) { case FOURCC_YV12: case FOURCC_I420: *w = ALIGN(*w, 2); *h = ALIGN(*h, 2); size = ALIGN(*w, 4); if (pitches) pitches[0] = size; size *= *h; if (offsets) offsets[1] = size; tmp = ALIGN(*w >> 1, 4); if (pitches) pitches[1] = pitches[2] = tmp; tmp *= (*h >> 1); size += tmp; if (offsets) offsets[2] = size; size += tmp; break; } return size; } /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces note the difference to the parameters used in overlay are due to 10bit vs. float calcs */ static REF_TRANSFORM trans[2] = { {1.1643, 0.0, 1.5960, -0.3918, -0.8129, 2.0172, 0.0}, /* BT.601 */ {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */ }; void glamor_xv_render(glamor_port_private *port_priv) { ScreenPtr screen = port_priv->pPixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = port_priv->pPixmap; glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *src_pixmap_priv[3]; BoxPtr box = REGION_RECTS(&port_priv->clip); int nBox = REGION_NUM_RECTS(&port_priv->clip); GLfloat src_xscale[3], src_yscale[3]; int i; const float Loff = -0.0627; const float Coff = -0.502; float uvcosf, uvsinf; float yco; float uco[3], vco[3], off[3]; float bright, cont, gamma; int ref = port_priv->transform_index; GLint uloc; GLfloat *v; char *vbo_offset; int dst_box_index; if (!glamor_priv->xv_prog.prog) glamor_init_xv_shader(screen); cont = RTFContrast(port_priv->contrast); bright = RTFBrightness(port_priv->brightness); gamma = (float) port_priv->gamma / 1000.0; uvcosf = RTFSaturation(port_priv->saturation) * cos(RTFHue(port_priv->hue)); uvsinf = RTFSaturation(port_priv->saturation) * sin(RTFHue(port_priv->hue)); /* overlay video also does pre-gamma contrast/sat adjust, should we? */ yco = trans[ref].RefLuma * cont; uco[0] = -trans[ref].RefRCr * uvsinf; uco[1] = trans[ref].RefGCb * uvcosf - trans[ref].RefGCr * uvsinf; uco[2] = trans[ref].RefBCb * uvcosf; vco[0] = trans[ref].RefRCr * uvcosf; vco[1] = trans[ref].RefGCb * uvsinf + trans[ref].RefGCr * uvcosf; vco[2] = trans[ref].RefBCb * uvsinf; off[0] = Loff * yco + Coff * (uco[0] + vco[0]) + bright; off[1] = Loff * yco + Coff * (uco[1] + vco[1]) + bright; off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright; gamma = 1.0; glamor_set_alu(screen, GXcopy); for (i = 0; i < 3; i++) { if (port_priv->src_pix[i]) { src_pixmap_priv[i] = glamor_get_pixmap_private(port_priv->src_pix[i]); pixmap_priv_get_scale(src_pixmap_priv[i], &src_xscale[i], &src_yscale[i]); } } glamor_make_current(glamor_priv); glUseProgram(glamor_priv->xv_prog.prog); uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "offsetyco"); glUniform4f(uloc, off[0], off[1], off[2], yco); uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "ucogamma"); glUniform4f(uloc, uco[0], uco[1], uco[2], gamma); uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "vco"); glUniform4f(uloc, vco[0], vco[1], vco[2], 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glEnable(GL_SCISSOR_TEST); v = glamor_get_vbo_space(screen, 3 * 4 * sizeof(GLfloat), &vbo_offset); /* Set up a single primitive covering the area being drawn. We'll * clip it to port_priv->clip using GL scissors instead of just * emitting a GL_QUAD per box, because this way we hopefully avoid * diagonal tearing between the two trangles used to rasterize a * GL_QUAD. */ i = 0; v[i++] = port_priv->drw_x; v[i++] = port_priv->drw_y; v[i++] = port_priv->drw_x + port_priv->dst_w * 2; v[i++] = port_priv->drw_y; v[i++] = port_priv->drw_x; v[i++] = port_priv->drw_y + port_priv->dst_h * 2; v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x); v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y); v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x + port_priv->src_w * 2); v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y); v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x); v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y + port_priv->src_h * 2); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vbo_offset); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vbo_offset + 6 * sizeof(GLfloat)); glamor_put_vbo_space(screen); /* Now draw our big triangle, clipped to each of the clip boxes. */ glamor_pixmap_loop(pixmap_priv, dst_box_index) { int dst_off_x, dst_off_y; glamor_set_destination_drawable(port_priv->pDraw, dst_box_index, FALSE, FALSE, glamor_priv->xv_prog.matrix_uniform, &dst_off_x, &dst_off_y); for (i = 0; i < nBox; i++) { int dstx, dsty, dstw, dsth; dstx = box[i].x1 + dst_off_x; dsty = box[i].y1 + dst_off_y; dstw = box[i].x2 - box[i].x1; dsth = box[i].y2 - box[i].y1; glScissor(dstx, dsty, dstw, dsth); glDrawArrays(GL_TRIANGLE_FAN, 0, 3); } } glDisable(GL_SCISSOR_TEST); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); DamageDamageRegion(port_priv->pDraw, &port_priv->clip); glamor_xv_free_port_data(port_priv); } int glamor_xv_put_image(glamor_port_private *port_priv, DrawablePtr pDrawable, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, int id, unsigned char *buf, short width, short height, Bool sync, RegionPtr clipBoxes) { ScreenPtr pScreen = pDrawable->pScreen; int srcPitch, srcPitch2; int top, nlines; int s2offset, s3offset, tmp; BoxRec full_box, half_box; s2offset = s3offset = srcPitch2 = 0; if (!port_priv->src_pix[0] || (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) { int i; for (i = 0; i < 3; i++) if (port_priv->src_pix[i]) glamor_destroy_pixmap(port_priv->src_pix[i]); port_priv->src_pix[0] = glamor_create_pixmap(pScreen, width, height, 8, GLAMOR_CREATE_FBO_NO_FBO); port_priv->src_pix[1] = glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, GLAMOR_CREATE_FBO_NO_FBO); port_priv->src_pix[2] = glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, GLAMOR_CREATE_FBO_NO_FBO); port_priv->src_pix_w = width; port_priv->src_pix_h = height; if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || !port_priv->src_pix[2]) return BadAlloc; } top = (src_y) & ~1; nlines = (src_y + src_h) - top; switch (id) { case FOURCC_YV12: case FOURCC_I420: srcPitch = ALIGN(width, 4); srcPitch2 = ALIGN(width >> 1, 4); s2offset = srcPitch * height; s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1)); s2offset += ((top >> 1) * srcPitch2); s3offset += ((top >> 1) * srcPitch2); if (id == FOURCC_YV12) { tmp = s2offset; s2offset = s3offset; s3offset = tmp; } full_box.x1 = 0; full_box.y1 = 0; full_box.x2 = width; full_box.y2 = nlines; half_box.x1 = 0; half_box.y1 = 0; half_box.x2 = width >> 1; half_box.y2 = (nlines + 1) >> 1; glamor_upload_boxes(port_priv->src_pix[0], &full_box, 1, 0, 0, 0, 0, buf + (top * srcPitch), srcPitch); glamor_upload_boxes(port_priv->src_pix[1], &half_box, 1, 0, 0, 0, 0, buf + s2offset, srcPitch2); glamor_upload_boxes(port_priv->src_pix[2], &half_box, 1, 0, 0, 0, 0, buf + s3offset, srcPitch2); break; default: return BadMatch; } if (pDrawable->type == DRAWABLE_WINDOW) port_priv->pPixmap = pScreen->GetWindowPixmap((WindowPtr) pDrawable); else port_priv->pPixmap = (PixmapPtr) pDrawable; RegionCopy(&port_priv->clip, clipBoxes); port_priv->src_x = src_x; port_priv->src_y = src_y - top; port_priv->src_w = src_w; port_priv->src_h = src_h; port_priv->dst_w = drw_w; port_priv->dst_h = drw_h; port_priv->drw_x = drw_x; port_priv->drw_y = drw_y; port_priv->w = width; port_priv->h = height; port_priv->pDraw = pDrawable; glamor_xv_render(port_priv); return Success; } void glamor_xv_init_port(glamor_port_private *port_priv) { port_priv->brightness = 0; port_priv->contrast = 0; port_priv->saturation = 0; port_priv->hue = 0; port_priv->gamma = 1000; port_priv->transform_index = 0; REGION_NULL(pScreen, &port_priv->clip); } void glamor_xv_core_init(ScreenPtr screen) { glamorBrightness = MAKE_ATOM("XV_BRIGHTNESS"); glamorContrast = MAKE_ATOM("XV_CONTRAST"); glamorSaturation = MAKE_ATOM("XV_SATURATION"); glamorHue = MAKE_ATOM("XV_HUE"); glamorGamma = MAKE_ATOM("XV_GAMMA"); glamorColorspace = MAKE_ATOM("XV_COLORSPACE"); } xorg-server-1.20.13/glamor/glamor_egl_stubs.c0000644000175000017500000000360614100573756016054 00000000000000/* * Copyright © 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ /** @file glamor_egl_stubs.c * * Stubbed out glamor_egl.c functions for servers other than Xorg. */ #include "dix-config.h" #include "glamor.h" void glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) { } int glamor_egl_fd_name_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { return -1; } int glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, uint32_t *offsets, uint32_t *strides, uint64_t *modifier) { return 0; } int glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { return -1; } xorg-server-1.20.13/glamor/glamor_egl_ext.h0000644000175000017500000000600614100573756015516 00000000000000/* * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* Extensions used by Glamor, copied from Mesa's eglmesaext.h, */ #ifndef GLAMOR_EGL_EXT_H #define GLAMOR_EGL_EXT_H /* Define needed tokens from EGL_EXT_image_dma_buf_import extension * here to avoid having to add ifdefs everywhere.*/ #ifndef EGL_EXT_image_dma_buf_import #define EGL_LINUX_DMA_BUF_EXT 0x3270 #define EGL_LINUX_DRM_FOURCC_EXT 0x3271 #define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 #define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 #define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 #define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275 #define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276 #define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277 #define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278 #define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279 #define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A #endif /* Define tokens from EGL_EXT_image_dma_buf_import_modifiers */ #ifndef EGL_EXT_image_dma_buf_import_modifiers #define EGL_EXT_image_dma_buf_import_modifiers 1 #define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 #define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 #define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 #define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 #define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 #define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 #define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 #define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447 #define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448 #define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449 #define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); #endif #endif /* GLAMOR_EGL_EXT_H */ xorg-server-1.20.13/glamor/glamor_egl.h0000644000175000017500000000620414100573756014636 00000000000000/* * Copyright © 2016 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Adam Jackson */ #ifndef GLAMOR_EGL_H #define GLAMOR_EGL_H #define MESA_EGL_NO_X11_HEADERS #define EGL_NO_X11 #include #include #include /* * Create an EGLDisplay from a native display type. This is a little quirky * for a few reasons. * * 1: GetPlatformDisplayEXT and GetPlatformDisplay are the API you want to * use, but have different function signatures in the third argument; this * happens not to matter for us, at the moment, but it means epoxy won't alias * them together. * * 2: epoxy 1.3 and earlier don't understand EGL client extensions, which * means you can't call "eglGetPlatformDisplayEXT" directly, as the resolver * will crash. * * 3: You can't tell whether you have EGL 1.5 at this point, because * eglQueryString(EGL_VERSION) is a property of the display, which we don't * have yet. So you have to query for extensions no matter what. Fortunately * epoxy_has_egl_extension _does_ let you query for client extensions, so * we don't have to write our own extension string parsing. * * 4. There is no EGL_KHR_platform_base to complement the EXT one, thus one * needs to know EGL 1.5 is supported in order to use the eglGetPlatformDisplay * function pointer. * We can workaround this (circular dependency) by probing for the EGL 1.5 * platform extensions (EGL_KHR_platform_gbm and friends) yet it doesn't seem * like mesa will be able to adverise these (even though it can do EGL 1.5). */ static inline EGLDisplay glamor_egl_get_display(EGLint type, void *native) { /* In practise any EGL 1.5 implementation would support the EXT extension */ if (epoxy_has_egl_extension(NULL, "EGL_EXT_platform_base")) { PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplayEXT = (void *) eglGetProcAddress("eglGetPlatformDisplayEXT"); if (getPlatformDisplayEXT) return getPlatformDisplayEXT(type, native, NULL); } /* Welp, everything is awful. */ return eglGetDisplay(native); } #endif xorg-server-1.20.13/glamor/glamor_egl.c0000644000175000017500000007725014100573756014642 00000000000000/* * Copyright © 2010 Intel Corporation. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including * the next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Zhigang Gong * */ #include "dix-config.h" #define GLAMOR_FOR_XORG #include #include #include #include #include #include #include #define EGL_DISPLAY_NO_X_MESA #include #include #include "glamor_egl.h" #include "glamor.h" #include "glamor_priv.h" #include "dri3.h" struct glamor_egl_screen_private { EGLDisplay display; EGLContext context; char *device_path; CreateScreenResourcesProcPtr CreateScreenResources; CloseScreenProcPtr CloseScreen; int fd; struct gbm_device *gbm; int dmabuf_capable; CloseScreenProcPtr saved_close_screen; DestroyPixmapProcPtr saved_destroy_pixmap; xf86FreeScreenProc *saved_free_screen; }; int xf86GlamorEGLPrivateIndex = -1; static struct glamor_egl_screen_private * glamor_egl_get_screen_private(ScrnInfoPtr scrn) { return (struct glamor_egl_screen_private *) scrn->privates[xf86GlamorEGLPrivateIndex].ptr; } static void glamor_egl_make_current(struct glamor_context *glamor_ctx) { /* There's only a single global dispatch table in Mesa. EGL, GLX, * and AIGLX's direct dispatch table manipulation don't talk to * each other. We need to set the context to NULL first to avoid * EGL's no-op context change fast path when switching back to * EGL. */ eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); if (!eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_ctx->ctx)) { FatalError("Failed to make EGL context current\n"); } } static int glamor_get_flink_name(int fd, int handle, int *name) { struct drm_gem_flink flink; flink.handle = handle; if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { /* * Assume non-GEM kernels have names identical to the handle */ if (errno == ENODEV) { *name = handle; return TRUE; } else { return FALSE; } } *name = flink.name; return TRUE; } static Bool glamor_create_texture_from_image(ScreenPtr screen, EGLImageKHR image, GLuint * texture) { struct glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_make_current(glamor_priv); glGenTextures(1, texture); glBindTexture(GL_TEXTURE_2D, *texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); glBindTexture(GL_TEXTURE_2D, 0); return TRUE; } struct gbm_device * glamor_egl_get_gbm_device(ScreenPtr screen) { struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); return glamor_egl->gbm; } Bool glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); PixmapPtr screen_pixmap; screen_pixmap = screen->GetScreenPixmap(screen); if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create textured screen."); return FALSE; } return TRUE; } static void glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image, Bool used_modifiers) { struct glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); EGLImageKHR old; old = pixmap_priv->image; if (old) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); eglDestroyImageKHR(glamor_egl->display, old); } pixmap_priv->image = image; pixmap_priv->used_modifiers = used_modifiers; } Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); int ret, fd; /* GBM doesn't have an import path from handles, so we make a * dma-buf fd from it and then go through that. */ ret = drmPrimeHandleToFD(glamor_egl->fd, handle, O_CLOEXEC, &fd); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to make prime FD for handle: %d\n", errno); return FALSE; } if (!glamor_back_pixmap_from_fd(pixmap, fd, pixmap->drawable.width, pixmap->drawable.height, stride, pixmap->drawable.depth, pixmap->drawable.bitsPerPixel)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to make import prime FD as pixmap: %d\n", errno); close(fd); return FALSE; } close(fd); return TRUE; } Bool glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, struct gbm_bo *bo, Bool used_modifiers) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); struct glamor_egl_screen_private *glamor_egl; EGLImageKHR image; GLuint texture; Bool ret = FALSE; glamor_egl = glamor_egl_get_screen_private(scrn); glamor_make_current(glamor_priv); image = eglCreateImageKHR(glamor_egl->display, glamor_egl->context, EGL_NATIVE_PIXMAP_KHR, bo, NULL); if (image == EGL_NO_IMAGE_KHR) { glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY); goto done; } glamor_create_texture_from_image(screen, image, &texture); glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); glamor_set_pixmap_texture(pixmap, texture); glamor_egl_set_pixmap_image(pixmap, image, used_modifiers); ret = TRUE; done: return ret; } static void glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name) { union gbm_bo_handle handle; handle = gbm_bo_get_handle(bo); if (!glamor_get_flink_name(gbm_fd, handle.u32, name)) *name = -1; } static Bool glamor_make_pixmap_exportable(PixmapPtr pixmap, Bool modifiers_ok) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); struct glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); unsigned width = pixmap->drawable.width; unsigned height = pixmap->drawable.height; uint32_t format; struct gbm_bo *bo = NULL; Bool used_modifiers = FALSE; PixmapPtr exported; GCPtr scratch_gc; if (pixmap_priv->image && (modifiers_ok || !pixmap_priv->used_modifiers)) return TRUE; if (pixmap->drawable.bitsPerPixel != 32) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to make %dbpp pixmap exportable\n", pixmap->drawable.bitsPerPixel); return FALSE; } if (pixmap->drawable.depth == 30) format = GBM_FORMAT_ARGB2101010; else format = GBM_FORMAT_ARGB8888; #ifdef GBM_BO_WITH_MODIFIERS if (modifiers_ok && glamor_egl->dmabuf_capable) { uint32_t num_modifiers; uint64_t *modifiers = NULL; glamor_get_modifiers(screen, format, &num_modifiers, &modifiers); bo = gbm_bo_create_with_modifiers(glamor_egl->gbm, width, height, format, modifiers, num_modifiers); if (bo) used_modifiers = TRUE; free(modifiers); } #endif if (!bo) { bo = gbm_bo_create(glamor_egl->gbm, width, height, format, #ifdef GLAMOR_HAS_GBM_LINEAR (pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ? GBM_BO_USE_LINEAR : 0) | #endif GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT); } if (!bo) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to make %dx%dx%dbpp GBM bo\n", width, height, pixmap->drawable.bitsPerPixel); return FALSE; } exported = screen->CreatePixmap(screen, 0, 0, pixmap->drawable.depth, 0); screen->ModifyPixmapHeader(exported, width, height, 0, 0, gbm_bo_get_stride(bo), NULL); if (!glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo, used_modifiers)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to make %dx%dx%dbpp pixmap from GBM bo\n", width, height, pixmap->drawable.bitsPerPixel); screen->DestroyPixmap(exported); gbm_bo_destroy(bo); return FALSE; } gbm_bo_destroy(bo); scratch_gc = GetScratchGC(pixmap->drawable.depth, screen); ValidateGC(&pixmap->drawable, scratch_gc); scratch_gc->ops->CopyArea(&pixmap->drawable, &exported->drawable, scratch_gc, 0, 0, width, height, 0, 0); FreeScratchGC(scratch_gc); /* Now, swap the tex/gbm/EGLImage/etc. of the exported pixmap into * the original pixmap struct. */ glamor_egl_exchange_buffers(pixmap, exported); /* Swap the devKind into the original pixmap, reflecting the bo's stride */ screen->ModifyPixmapHeader(pixmap, 0, 0, 0, 0, exported->devKind, NULL); screen->DestroyPixmap(exported); return TRUE; } static struct gbm_bo * glamor_gbm_bo_from_pixmap_internal(ScreenPtr screen, PixmapPtr pixmap) { struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); struct glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); if (!pixmap_priv->image) return NULL; return gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, pixmap_priv->image, 0); } struct gbm_bo * glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap) { if (!glamor_make_pixmap_exportable(pixmap, TRUE)) return NULL; return glamor_gbm_bo_from_pixmap_internal(screen, pixmap); } int glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, uint32_t *strides, uint32_t *offsets, uint64_t *modifier) { #ifdef GLAMOR_HAS_GBM struct gbm_bo *bo; int num_fds; #ifdef GBM_BO_WITH_MODIFIERS int i; #endif if (!glamor_make_pixmap_exportable(pixmap, TRUE)) return 0; bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap); if (!bo) return 0; #ifdef GBM_BO_WITH_MODIFIERS num_fds = gbm_bo_get_plane_count(bo); for (i = 0; i < num_fds; i++) { fds[i] = gbm_bo_get_fd(bo); strides[i] = gbm_bo_get_stride_for_plane(bo, i); offsets[i] = gbm_bo_get_offset(bo, i); } *modifier = gbm_bo_get_modifier(bo); #else num_fds = 1; fds[0] = gbm_bo_get_fd(bo); strides[0] = gbm_bo_get_stride(bo); offsets[0] = 0; *modifier = DRM_FORMAT_MOD_INVALID; #endif gbm_bo_destroy(bo); return num_fds; #else return 0; #endif } _X_EXPORT int glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { #ifdef GLAMOR_HAS_GBM struct gbm_bo *bo; int fd; if (!glamor_make_pixmap_exportable(pixmap, FALSE)) return -1; bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap); if (!bo) return -1; fd = gbm_bo_get_fd(bo); *stride = gbm_bo_get_stride(bo); *size = *stride * gbm_bo_get_height(bo); gbm_bo_destroy(bo); return fd; #else return -1; #endif } int glamor_egl_fd_name_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { struct glamor_egl_screen_private *glamor_egl; struct gbm_bo *bo; int fd = -1; glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); if (!glamor_make_pixmap_exportable(pixmap, FALSE)) goto failure; bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap); if (!bo) goto failure; pixmap->devKind = gbm_bo_get_stride(bo); glamor_get_name_from_bo(glamor_egl->fd, bo, &fd); *stride = pixmap->devKind; *size = pixmap->devKind * gbm_bo_get_height(bo); gbm_bo_destroy(bo); failure: return fd; } _X_EXPORT Bool glamor_back_pixmap_from_fd(PixmapPtr pixmap, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl; struct gbm_bo *bo; struct gbm_import_fd_data import_data = { 0 }; Bool ret; glamor_egl = glamor_egl_get_screen_private(scrn); if (bpp != 32 || !(depth == 24 || depth == 32 || depth == 30) || width == 0 || height == 0) return FALSE; import_data.fd = fd; import_data.width = width; import_data.height = height; import_data.stride = stride; if (depth == 30) import_data.format = GBM_FORMAT_ARGB2101010; else import_data.format = GBM_FORMAT_ARGB8888; bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD, &import_data, 0); if (!bo) return FALSE; screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL); ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo, FALSE); gbm_bo_destroy(bo); return ret; } static uint32_t gbm_format_for_depth(CARD8 depth) { switch (depth) { case 16: return GBM_FORMAT_RGB565; case 24: return GBM_FORMAT_XRGB8888; case 30: return GBM_FORMAT_ARGB2101010; default: ErrorF("unexpected depth: %d\n", depth); case 32: return GBM_FORMAT_ARGB8888; } } _X_EXPORT PixmapPtr glamor_pixmap_from_fds(ScreenPtr screen, CARD8 num_fds, const int *fds, CARD16 width, CARD16 height, const CARD32 *strides, const CARD32 *offsets, CARD8 depth, CARD8 bpp, uint64_t modifier) { PixmapPtr pixmap; struct glamor_egl_screen_private *glamor_egl; Bool ret = FALSE; int i; glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0); #ifdef GBM_BO_WITH_MODIFIERS if (glamor_egl->dmabuf_capable && modifier != DRM_FORMAT_MOD_INVALID) { struct gbm_import_fd_modifier_data import_data = { 0 }; struct gbm_bo *bo; import_data.width = width; import_data.height = height; import_data.num_fds = num_fds; import_data.modifier = modifier; for (i = 0; i < num_fds; i++) { import_data.fds[i] = fds[i]; import_data.strides[i] = strides[i]; import_data.offsets[i] = offsets[i]; } import_data.format = gbm_format_for_depth(depth); bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD_MODIFIER, &import_data, 0); if (bo) { screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL); ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo, TRUE); gbm_bo_destroy(bo); } } else #endif { if (num_fds == 1) { ret = glamor_back_pixmap_from_fd(pixmap, fds[0], width, height, strides[0], depth, bpp); } } if (ret == FALSE) { screen->DestroyPixmap(pixmap); return NULL; } return pixmap; } _X_EXPORT PixmapPtr glamor_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) { PixmapPtr pixmap; Bool ret; pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0); ret = glamor_back_pixmap_from_fd(pixmap, fd, width, height, stride, depth, bpp); if (ret == FALSE) { screen->DestroyPixmap(pixmap); return NULL; } return pixmap; } _X_EXPORT Bool glamor_get_formats(ScreenPtr screen, CARD32 *num_formats, CARD32 **formats) { #ifdef GLAMOR_HAS_EGL_QUERY_DMABUF struct glamor_egl_screen_private *glamor_egl; EGLint num; /* Explicitly zero the count as the caller may ignore the return value */ *num_formats = 0; glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); if (!glamor_egl->dmabuf_capable) return TRUE; if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, 0, NULL, &num)) return FALSE; if (num == 0) return TRUE; *formats = calloc(num, sizeof(CARD32)); if (*formats == NULL) return FALSE; if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, num, (EGLint *) *formats, &num)) { free(*formats); return FALSE; } *num_formats = num; return TRUE; #else *num_formats = 0; return TRUE; #endif } _X_EXPORT Bool glamor_get_modifiers(ScreenPtr screen, uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers) { #ifdef GLAMOR_HAS_EGL_QUERY_DMABUF struct glamor_egl_screen_private *glamor_egl; EGLint num; /* Explicitly zero the count as the caller may ignore the return value */ *num_modifiers = 0; glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); if (!glamor_egl->dmabuf_capable) return FALSE; if (!eglQueryDmaBufModifiersEXT(glamor_egl->display, format, 0, NULL, NULL, &num)) return FALSE; if (num == 0) return TRUE; *modifiers = calloc(num, sizeof(uint64_t)); if (*modifiers == NULL) return FALSE; if (!eglQueryDmaBufModifiersEXT(glamor_egl->display, format, num, (EGLuint64KHR *) *modifiers, NULL, &num)) { free(*modifiers); return FALSE; } *num_modifiers = num; return TRUE; #else *num_modifiers = 0; return TRUE; #endif } _X_EXPORT const char * glamor_egl_get_driver_name(ScreenPtr screen) { #ifdef GLAMOR_HAS_EGL_QUERY_DRIVER struct glamor_egl_screen_private *glamor_egl; glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); if (epoxy_has_egl_extension(glamor_egl->display, "EGL_MESA_query_driver")) return eglGetDisplayDriverName(glamor_egl->display); #endif return NULL; } static Bool glamor_egl_destroy_pixmap(PixmapPtr pixmap) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); Bool ret; if (pixmap->refcnt == 1) { struct glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); if (pixmap_priv->image) eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image); } screen->DestroyPixmap = glamor_egl->saved_destroy_pixmap; ret = screen->DestroyPixmap(pixmap); glamor_egl->saved_destroy_pixmap = screen->DestroyPixmap; screen->DestroyPixmap = glamor_egl_destroy_pixmap; return ret; } _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back) { EGLImageKHR temp_img; Bool temp_mod; struct glamor_pixmap_private *front_priv = glamor_get_pixmap_private(front); struct glamor_pixmap_private *back_priv = glamor_get_pixmap_private(back); glamor_pixmap_exchange_fbos(front, back); temp_img = back_priv->image; temp_mod = back_priv->used_modifiers; back_priv->image = front_priv->image; back_priv->used_modifiers = front_priv->used_modifiers; front_priv->image = temp_img; front_priv->used_modifiers = temp_mod; glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM); glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM); } static Bool glamor_egl_close_screen(ScreenPtr screen) { ScrnInfoPtr scrn; struct glamor_egl_screen_private *glamor_egl; struct glamor_pixmap_private *pixmap_priv; PixmapPtr screen_pixmap; scrn = xf86ScreenToScrn(screen); glamor_egl = glamor_egl_get_screen_private(scrn); screen_pixmap = screen->GetScreenPixmap(screen); pixmap_priv = glamor_get_pixmap_private(screen_pixmap); eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image); pixmap_priv->image = NULL; screen->CloseScreen = glamor_egl->saved_close_screen; return screen->CloseScreen(screen); } #ifdef DRI3 static int glamor_dri3_open_client(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fdp) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); int fd; drm_magic_t magic; fd = open(glamor_egl->device_path, O_RDWR|O_CLOEXEC); if (fd < 0) return BadAlloc; /* Before FD passing in the X protocol with DRI3 (and increased * security of rendering with per-process address spaces on the * GPU), the kernel had to come up with a way to have the server * decide which clients got to access the GPU, which was done by * each client getting a unique (magic) number from the kernel, * passing it to the server, and the server then telling the * kernel which clients were authenticated for using the device. * * Now that we have FD passing, the server can just set up the * authentication on its own and hand the prepared FD off to the * client. */ if (drmGetMagic(fd, &magic) < 0) { if (errno == EACCES) { /* Assume that we're on a render node, and the fd is * already as authenticated as it should be. */ *fdp = fd; return Success; } else { close(fd); return BadMatch; } } if (drmAuthMagic(glamor_egl->fd, magic) < 0) { close(fd); return BadMatch; } *fdp = fd; return Success; } static const dri3_screen_info_rec glamor_dri3_info = { .version = 2, .open_client = glamor_dri3_open_client, .pixmap_from_fds = glamor_pixmap_from_fds, .fd_from_pixmap = glamor_egl_fd_from_pixmap, .fds_from_pixmap = glamor_egl_fds_from_pixmap, .get_formats = glamor_get_formats, .get_modifiers = glamor_get_modifiers, .get_drawable_modifiers = glamor_get_drawable_modifiers, }; #endif /* DRI3 */ void glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); #ifdef DRI3 glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); #endif glamor_egl->saved_close_screen = screen->CloseScreen; screen->CloseScreen = glamor_egl_close_screen; glamor_egl->saved_destroy_pixmap = screen->DestroyPixmap; screen->DestroyPixmap = glamor_egl_destroy_pixmap; glamor_ctx->ctx = glamor_egl->context; glamor_ctx->display = glamor_egl->display; glamor_ctx->make_current = glamor_egl_make_current; #ifdef DRI3 /* Tell the core that we have the interfaces for import/export * of pixmaps. */ glamor_enable_dri3(screen); /* If the driver wants to do its own auth dance (e.g. Xwayland * on pre-3.15 kernels that don't have render nodes and thus * has the wayland compositor as a master), then it needs us * to stay out of the way and let it init DRI3 on its own. */ if (!(glamor_priv->flags & GLAMOR_NO_DRI3)) { /* To do DRI3 device FD generation, we need to open a new fd * to the same device we were handed in originally. */ glamor_egl->device_path = drmGetDeviceNameFromFd2(glamor_egl->fd); if (!dri3_screen_init(screen, &glamor_dri3_info)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to initialize DRI3.\n"); } } #endif } static void glamor_egl_cleanup(struct glamor_egl_screen_private *glamor_egl) { if (glamor_egl->display != EGL_NO_DISPLAY) { eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); /* * Force the next glamor_make_current call to update the context * (on hot unplug another GPU may still be using glamor) */ lastGLContext = NULL; eglTerminate(glamor_egl->display); } if (glamor_egl->gbm) gbm_device_destroy(glamor_egl->gbm); free(glamor_egl->device_path); free(glamor_egl); } static void glamor_egl_free_screen(ScrnInfoPtr scrn) { struct glamor_egl_screen_private *glamor_egl; glamor_egl = glamor_egl_get_screen_private(scrn); if (glamor_egl != NULL) { scrn->FreeScreen = glamor_egl->saved_free_screen; glamor_egl_cleanup(glamor_egl); scrn->FreeScreen(scrn); } } Bool glamor_egl_init(ScrnInfoPtr scrn, int fd) { struct glamor_egl_screen_private *glamor_egl; const GLubyte *renderer; glamor_egl = calloc(sizeof(*glamor_egl), 1); if (glamor_egl == NULL) return FALSE; if (xf86GlamorEGLPrivateIndex == -1) xf86GlamorEGLPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl; glamor_egl->fd = fd; glamor_egl->gbm = gbm_create_device(glamor_egl->fd); if (glamor_egl->gbm == NULL) { ErrorF("couldn't get display device\n"); goto error; } glamor_egl->display = glamor_egl_get_display(EGL_PLATFORM_GBM_MESA, glamor_egl->gbm); if (!glamor_egl->display) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglGetDisplay() failed\n"); goto error; } if (!eglInitialize(glamor_egl->display, NULL, NULL)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglInitialize() failed\n"); glamor_egl->display = EGL_NO_DISPLAY; goto error; } #define GLAMOR_CHECK_EGL_EXTENSION(EXT) \ if (!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT)) { \ ErrorF("EGL_" #EXT " required.\n"); \ goto error; \ } #define GLAMOR_CHECK_EGL_EXTENSIONS(EXT1, EXT2) \ if (!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT1) && \ !epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT2)) { \ ErrorF("EGL_" #EXT1 " or EGL_" #EXT2 " required.\n"); \ goto error; \ } GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_context); if (eglBindAPI(EGL_OPENGL_API)) { static const EGLint config_attribs_core[] = { EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, EGL_CONTEXT_MAJOR_VERSION_KHR, GLAMOR_GL_CORE_VER_MAJOR, EGL_CONTEXT_MINOR_VERSION_KHR, GLAMOR_GL_CORE_VER_MINOR, EGL_NONE }; static const EGLint config_attribs[] = { EGL_NONE }; glamor_egl->context = eglCreateContext(glamor_egl->display, NULL, EGL_NO_CONTEXT, config_attribs_core); if (glamor_egl->context == EGL_NO_CONTEXT) glamor_egl->context = eglCreateContext(glamor_egl->display, NULL, EGL_NO_CONTEXT, config_attribs); } if (glamor_egl->context == EGL_NO_CONTEXT) { static const EGLint config_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; if (!eglBindAPI(EGL_OPENGL_ES_API)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "glamor: Failed to bind either GL or GLES APIs.\n"); goto error; } glamor_egl->context = eglCreateContext(glamor_egl->display, NULL, EGL_NO_CONTEXT, config_attribs); } if (glamor_egl->context == EGL_NO_CONTEXT) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "glamor: Failed to create GL or GLES2 contexts\n"); goto error; } if (!eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to make EGL context current\n"); goto error; } renderer = glGetString(GL_RENDERER); if (!renderer) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "glGetString() returned NULL, your GL is broken\n"); goto error; } if (strstr((const char *)renderer, "llvmpipe")) { xf86DrvMsg(scrn->scrnIndex, X_INFO, "Refusing to try glamor on llvmpipe\n"); goto error; } /* * Force the next glamor_make_current call to set the right context * (in case of multiple GPUs using glamor) */ lastGLContext = NULL; if (!epoxy_has_gl_extension("GL_OES_EGL_image")) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "glamor acceleration requires GL_OES_EGL_image\n"); goto error; } xf86DrvMsg(scrn->scrnIndex, X_INFO, "glamor X acceleration enabled on %s\n", renderer); #ifdef GBM_BO_WITH_MODIFIERS if (epoxy_has_egl_extension(glamor_egl->display, "EGL_EXT_image_dma_buf_import") && epoxy_has_egl_extension(glamor_egl->display, "EGL_EXT_image_dma_buf_import_modifiers")) { if (xf86Info.debug != NULL) glamor_egl->dmabuf_capable = !!strstr(xf86Info.debug, "dmabuf_capable"); else glamor_egl->dmabuf_capable = FALSE; } #endif glamor_egl->saved_free_screen = scrn->FreeScreen; scrn->FreeScreen = glamor_egl_free_screen; return TRUE; error: glamor_egl_cleanup(glamor_egl); return FALSE; } /** Stub to retain compatibility with pre-server-1.16 ABI. */ Bool glamor_egl_init_textured_pixmap(ScreenPtr screen) { return TRUE; } xorg-server-1.20.13/glamor/glamor_eglmodule.c0000644000175000017500000000374114100573756016042 00000000000000/* * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of the XFree86 Project shall * not be used in advertising or otherwise to promote the sale, use or other * dealings in this Software without prior written authorization from the * XFree86 Project. * * Authors: * Zhigang Gong */ #include "dix-config.h" #include #define GLAMOR_FOR_XORG #include #include "glamor.h" static XF86ModuleVersionInfo VersRec = { GLAMOR_EGL_MODULE_NAME, MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, XORG_VERSION_CURRENT, 1, 0, 1, /* version */ ABI_CLASS_ANSIC, /* Only need the ansic layer */ ABI_ANSIC_VERSION, MOD_CLASS_NONE, {0, 0, 0, 0} /* signature, to be patched into the file by a tool */ }; _X_EXPORT XF86ModuleData glamoreglModuleData = { &VersRec, NULL, NULL }; xorg-server-1.20.13/glx/0000755000175000017500000000000014100574020011725 500000000000000xorg-server-1.20.13/glx/meson.build0000644000175000017500000000331614100573756014031 00000000000000srcs_glx = [ 'indirect_dispatch.c', 'indirect_dispatch_swap.c', 'indirect_reqsize.c', 'indirect_size_get.c', 'indirect_table.c', 'clientinfo.c', 'createcontext.c', 'extension_string.c', 'indirect_util.c', 'indirect_program.c', 'indirect_texture_compression.c', 'glxcmds.c', 'glxcmdsswap.c', 'glxext.c', 'glxdriswrast.c', 'glxdricommon.c', 'glxscreens.c', 'render2.c', 'render2swap.c', 'renderpix.c', 'renderpixswap.c', 'rensize.c', 'single2.c', 'single2swap.c', 'singlepix.c', 'singlepixswap.c', 'singlesize.c', 'swap_interval.c', 'xfont.c', ] libxserver_glx = [] if build_glx libxserver_glx = static_library('libxserver_glx', srcs_glx, include_directories: inc, dependencies: [ common_dep, dl_dep, dependency('glproto', version: '>= 1.4.17'), dependency('gl', version: '>= 1.2'), ], c_args: [ glx_align64, # XXX: generated code includes an unused function '-Wno-unused-function', ] ) endif srcs_glxdri2 = [] if build_dri2 or build_dri3 srcs_glxdri2 = files('glxdri2.c') endif srcs_vnd = [ 'vndcmds.c', 'vndext.c', 'vndservermapping.c', 'vndservervendor.c', ] hdrs_vnd = [ 'vndserver.h', ] libglxvnd = '' if build_glx libglxvnd = static_library('libglxvnd', srcs_vnd, include_directories: inc, dependencies: [ common_dep, dl_dep, dependency('glproto', version: '>= 1.4.17'), dependency('gl', version: '>= 1.2'), ], ) install_data(hdrs_vnd, install_dir : xorgsdkdir) endif xorg-server-1.20.13/glx/Makefile.am0000644000175000017500000000370314100573756013723 00000000000000if DRI2 GLXDRI_LIBRARY = libglxdri.la endif noinst_LTLIBRARIES = libglx.la $(GLXDRI_LIBRARY) libglxvnd.la AM_CFLAGS = \ @DIX_CFLAGS@ \ @GL_CFLAGS@ \ @XLIB_CFLAGS@ \ @LIBDRM_CFLAGS@ \ @GLX_DEFINES@ \ @GLX_ARCH_DEFINES@ sdk_HEADERS = vndserver.h AM_CPPFLAGS = \ -I$(top_srcdir)/hw/xfree86/os-support \ -I$(top_srcdir)/hw/xfree86/os-support/bus \ -I$(top_srcdir)/hw/xfree86/common \ -I$(top_srcdir)/hw/xfree86/dri \ -I$(top_srcdir)/hw/xfree86/dri2 \ -I$(top_srcdir)/mi \ -I$(top_srcdir)/present indirect_sources = \ indirect_dispatch.c \ indirect_dispatch.h \ indirect_dispatch_swap.c \ indirect_reqsize.c \ indirect_reqsize.h \ indirect_size.h \ indirect_size_get.c \ indirect_size_get.h \ indirect_table.c libglxdri_la_SOURCES = if DRI2 libglxdri_la_SOURCES += glxdri2.c endif libglxdri_la_LIBADD = $(DLOPEN_LIBS) libglx_la_SOURCES = \ $(indirect_sources) \ clientinfo.c \ createcontext.c \ extension_string.c \ extension_string.h \ indirect_util.c \ indirect_util.h \ indirect_program.c \ indirect_table.h \ indirect_texture_compression.c \ glxbyteorder.h \ glxcmds.c \ glxcmdsswap.c \ glxcontext.h \ glxdrawable.h \ glxext.c \ glxext.h \ glxdriswrast.c \ glxdricommon.c \ glxdricommon.h \ glxscreens.c \ glxscreens.h \ glxserver.h \ glxutil.h \ render2.c \ render2swap.c \ renderpix.c \ renderpixswap.c \ rensize.c \ single2.c \ single2swap.c \ singlepix.c \ singlepixswap.c \ singlesize.c \ singlesize.h \ swap_interval.c \ unpack.h \ xfont.c libglx_la_LIBADD = $(DLOPEN_LIBS) $(top_builddir)/Xext/libhashtable.la libglxvnd_la_SOURCES = \ vndcmds.c \ vndext.c \ vndservermapping.c \ vndservervendor.h \ vndservervendor.c libglxvnd_la_LIBADD = $(top_builddir)/Xext/libhashtable.la EXTRA_DIST = vnd_dispatch_stubs.c xorg-server-1.20.13/glx/vndserver.h0000644000175000017500000000774714100573756014072 00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the * "Materials"), to deal in the Materials without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Materials, and to * permit persons to whom the Materials are furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * unaltered in all copies or substantial portions of the Materials. * Any additions, deletions, or changes to the original source files * must be clearly indicated in accompanying documentation. * * If only executable code is distributed, then the accompanying * documentation must state that "this software is based in part on the * work of the Khronos Group." * * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ #ifndef VNDSERVER_H #define VNDSERVER_H #include #include "glxvndabi.h" #define GLXContextID CARD32 #define GLXDrawable CARD32 #if defined(__cplusplus) extern "C" { #endif typedef struct GlxScreenPrivRec { GlxServerVendor *vendor; } GlxScreenPriv; typedef struct GlxContextTagInfoRec { GLXContextTag tag; ClientPtr client; GlxServerVendor *vendor; void *data; GLXContextID context; GLXDrawable drawable; GLXDrawable readdrawable; } GlxContextTagInfo; typedef struct GlxClientPrivRec { GlxContextTagInfo *contextTags; unsigned int contextTagCount; /** * The vendor handles for each screen. */ GlxServerVendor **vendors; } GlxClientPriv; extern int GlxErrorBase; extern RESTYPE idResource; extern ExtensionEntry *GlxExtensionEntry; Bool GlxDispatchInit(void); void GlxDispatchReset(void); /** * Handles a request from the client. * * This function will look up the correct handler function and forward the * request to it. */ int GlxDispatchRequest(ClientPtr client); /** * Looks up the GlxClientPriv struct for a client. If we don't have a * GlxClientPriv struct yet, then allocate one. */ GlxClientPriv *GlxGetClientData(ClientPtr client); /** * Frees any data that's specific to a client. This should be called when a * client disconnects. */ void GlxFreeClientData(ClientPtr client); Bool GlxAddXIDMap(XID id, GlxServerVendor *vendor); GlxServerVendor * GlxGetXIDMap(XID id); void GlxRemoveXIDMap(XID id); /** * Records the client that sent the current request. This is needed in * GlxGetXIDMap to know which client's (screen -> vendor) mapping to use for a * regular X window. */ void GlxSetRequestClient(ClientPtr client); GlxContextTagInfo *GlxAllocContextTag(ClientPtr client, GlxServerVendor *vendor); GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag); void GlxFreeContextTag(GlxContextTagInfo *tagInfo); Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor); Bool GlxSetClientScreenVendor(ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor); GlxScreenPriv *GlxGetScreen(ScreenPtr pScreen); GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen); static inline CARD32 GlxCheckSwap(ClientPtr client, CARD32 value) { if (client->swapped) { value = ((value & 0XFF000000) >> 24) | ((value & 0X00FF0000) >> 8) | ((value & 0X0000FF00) << 8) | ((value & 0X000000FF) << 24); } return value; } #if defined(__cplusplus) } #endif _X_EXPORT const GlxServerExports *glvndGetExports(void); #endif // VNDSERVER_H xorg-server-1.20.13/glx/Makefile.in0000644000175000017500000011341514100573775013737 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @DRI2_TRUE@am__append_1 = glxdri2.c subdir = glx ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(sdk_HEADERS) $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libglx_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(top_builddir)/Xext/libhashtable.la am__objects_1 = indirect_dispatch.lo indirect_dispatch_swap.lo \ indirect_reqsize.lo indirect_size_get.lo indirect_table.lo am_libglx_la_OBJECTS = $(am__objects_1) clientinfo.lo createcontext.lo \ extension_string.lo indirect_util.lo indirect_program.lo \ indirect_texture_compression.lo glxcmds.lo glxcmdsswap.lo \ glxext.lo glxdriswrast.lo glxdricommon.lo glxscreens.lo \ render2.lo render2swap.lo renderpix.lo renderpixswap.lo \ rensize.lo single2.lo single2swap.lo singlepix.lo \ singlepixswap.lo singlesize.lo swap_interval.lo xfont.lo libglx_la_OBJECTS = $(am_libglx_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libglxdri_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__libglxdri_la_SOURCES_DIST = glxdri2.c @DRI2_TRUE@am__objects_2 = glxdri2.lo am_libglxdri_la_OBJECTS = $(am__objects_2) libglxdri_la_OBJECTS = $(am_libglxdri_la_OBJECTS) @DRI2_TRUE@am_libglxdri_la_rpath = libglxvnd_la_DEPENDENCIES = $(top_builddir)/Xext/libhashtable.la am_libglxvnd_la_OBJECTS = vndcmds.lo vndext.lo vndservermapping.lo \ vndservervendor.lo libglxvnd_la_OBJECTS = $(am_libglxvnd_la_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/clientinfo.Plo \ ./$(DEPDIR)/createcontext.Plo ./$(DEPDIR)/extension_string.Plo \ ./$(DEPDIR)/glxcmds.Plo ./$(DEPDIR)/glxcmdsswap.Plo \ ./$(DEPDIR)/glxdri2.Plo ./$(DEPDIR)/glxdricommon.Plo \ ./$(DEPDIR)/glxdriswrast.Plo ./$(DEPDIR)/glxext.Plo \ ./$(DEPDIR)/glxscreens.Plo ./$(DEPDIR)/indirect_dispatch.Plo \ ./$(DEPDIR)/indirect_dispatch_swap.Plo \ ./$(DEPDIR)/indirect_program.Plo \ ./$(DEPDIR)/indirect_reqsize.Plo \ ./$(DEPDIR)/indirect_size_get.Plo \ ./$(DEPDIR)/indirect_table.Plo \ ./$(DEPDIR)/indirect_texture_compression.Plo \ ./$(DEPDIR)/indirect_util.Plo ./$(DEPDIR)/render2.Plo \ ./$(DEPDIR)/render2swap.Plo ./$(DEPDIR)/renderpix.Plo \ ./$(DEPDIR)/renderpixswap.Plo ./$(DEPDIR)/rensize.Plo \ ./$(DEPDIR)/single2.Plo ./$(DEPDIR)/single2swap.Plo \ ./$(DEPDIR)/singlepix.Plo ./$(DEPDIR)/singlepixswap.Plo \ ./$(DEPDIR)/singlesize.Plo ./$(DEPDIR)/swap_interval.Plo \ ./$(DEPDIR)/vndcmds.Plo ./$(DEPDIR)/vndext.Plo \ ./$(DEPDIR)/vndservermapping.Plo \ ./$(DEPDIR)/vndservervendor.Plo ./$(DEPDIR)/xfont.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libglx_la_SOURCES) $(libglxdri_la_SOURCES) \ $(libglxvnd_la_SOURCES) DIST_SOURCES = $(libglx_la_SOURCES) $(am__libglxdri_la_SOURCES_DIST) \ $(libglxvnd_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(sdkdir)" HEADERS = $(sdk_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @DRI2_TRUE@GLXDRI_LIBRARY = libglxdri.la noinst_LTLIBRARIES = libglx.la $(GLXDRI_LIBRARY) libglxvnd.la AM_CFLAGS = \ @DIX_CFLAGS@ \ @GL_CFLAGS@ \ @XLIB_CFLAGS@ \ @LIBDRM_CFLAGS@ \ @GLX_DEFINES@ \ @GLX_ARCH_DEFINES@ sdk_HEADERS = vndserver.h AM_CPPFLAGS = \ -I$(top_srcdir)/hw/xfree86/os-support \ -I$(top_srcdir)/hw/xfree86/os-support/bus \ -I$(top_srcdir)/hw/xfree86/common \ -I$(top_srcdir)/hw/xfree86/dri \ -I$(top_srcdir)/hw/xfree86/dri2 \ -I$(top_srcdir)/mi \ -I$(top_srcdir)/present indirect_sources = \ indirect_dispatch.c \ indirect_dispatch.h \ indirect_dispatch_swap.c \ indirect_reqsize.c \ indirect_reqsize.h \ indirect_size.h \ indirect_size_get.c \ indirect_size_get.h \ indirect_table.c libglxdri_la_SOURCES = $(am__append_1) libglxdri_la_LIBADD = $(DLOPEN_LIBS) libglx_la_SOURCES = \ $(indirect_sources) \ clientinfo.c \ createcontext.c \ extension_string.c \ extension_string.h \ indirect_util.c \ indirect_util.h \ indirect_program.c \ indirect_table.h \ indirect_texture_compression.c \ glxbyteorder.h \ glxcmds.c \ glxcmdsswap.c \ glxcontext.h \ glxdrawable.h \ glxext.c \ glxext.h \ glxdriswrast.c \ glxdricommon.c \ glxdricommon.h \ glxscreens.c \ glxscreens.h \ glxserver.h \ glxutil.h \ render2.c \ render2swap.c \ renderpix.c \ renderpixswap.c \ rensize.c \ single2.c \ single2swap.c \ singlepix.c \ singlepixswap.c \ singlesize.c \ singlesize.h \ swap_interval.c \ unpack.h \ xfont.c libglx_la_LIBADD = $(DLOPEN_LIBS) $(top_builddir)/Xext/libhashtable.la libglxvnd_la_SOURCES = \ vndcmds.c \ vndext.c \ vndservermapping.c \ vndservervendor.h \ vndservervendor.c libglxvnd_la_LIBADD = $(top_builddir)/Xext/libhashtable.la EXTRA_DIST = vnd_dispatch_stubs.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign glx/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign glx/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libglx.la: $(libglx_la_OBJECTS) $(libglx_la_DEPENDENCIES) $(EXTRA_libglx_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libglx_la_OBJECTS) $(libglx_la_LIBADD) $(LIBS) libglxdri.la: $(libglxdri_la_OBJECTS) $(libglxdri_la_DEPENDENCIES) $(EXTRA_libglxdri_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(am_libglxdri_la_rpath) $(libglxdri_la_OBJECTS) $(libglxdri_la_LIBADD) $(LIBS) libglxvnd.la: $(libglxvnd_la_OBJECTS) $(libglxvnd_la_DEPENDENCIES) $(EXTRA_libglxvnd_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libglxvnd_la_OBJECTS) $(libglxvnd_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clientinfo.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/createcontext.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extension_string.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glxcmds.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glxcmdsswap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glxdri2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glxdricommon.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glxdriswrast.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glxext.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glxscreens.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indirect_dispatch.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indirect_dispatch_swap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indirect_program.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indirect_reqsize.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indirect_size_get.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indirect_table.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indirect_texture_compression.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indirect_util.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render2swap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/renderpix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/renderpixswap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rensize.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/single2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/single2swap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/singlepix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/singlepixswap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/singlesize.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swap_interval.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vndcmds.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vndext.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vndservermapping.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vndservervendor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfont.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-sdkHEADERS: $(sdk_HEADERS) @$(NORMAL_INSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sdkdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sdkdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(sdkdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(sdkdir)" || exit $$?; \ done uninstall-sdkHEADERS: @$(NORMAL_UNINSTALL) @list='$(sdk_HEADERS)'; test -n "$(sdkdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(sdkdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/clientinfo.Plo -rm -f ./$(DEPDIR)/createcontext.Plo -rm -f ./$(DEPDIR)/extension_string.Plo -rm -f ./$(DEPDIR)/glxcmds.Plo -rm -f ./$(DEPDIR)/glxcmdsswap.Plo -rm -f ./$(DEPDIR)/glxdri2.Plo -rm -f ./$(DEPDIR)/glxdricommon.Plo -rm -f ./$(DEPDIR)/glxdriswrast.Plo -rm -f ./$(DEPDIR)/glxext.Plo -rm -f ./$(DEPDIR)/glxscreens.Plo -rm -f ./$(DEPDIR)/indirect_dispatch.Plo -rm -f ./$(DEPDIR)/indirect_dispatch_swap.Plo -rm -f ./$(DEPDIR)/indirect_program.Plo -rm -f ./$(DEPDIR)/indirect_reqsize.Plo -rm -f ./$(DEPDIR)/indirect_size_get.Plo -rm -f ./$(DEPDIR)/indirect_table.Plo -rm -f ./$(DEPDIR)/indirect_texture_compression.Plo -rm -f ./$(DEPDIR)/indirect_util.Plo -rm -f ./$(DEPDIR)/render2.Plo -rm -f ./$(DEPDIR)/render2swap.Plo -rm -f ./$(DEPDIR)/renderpix.Plo -rm -f ./$(DEPDIR)/renderpixswap.Plo -rm -f ./$(DEPDIR)/rensize.Plo -rm -f ./$(DEPDIR)/single2.Plo -rm -f ./$(DEPDIR)/single2swap.Plo -rm -f ./$(DEPDIR)/singlepix.Plo -rm -f ./$(DEPDIR)/singlepixswap.Plo -rm -f ./$(DEPDIR)/singlesize.Plo -rm -f ./$(DEPDIR)/swap_interval.Plo -rm -f ./$(DEPDIR)/vndcmds.Plo -rm -f ./$(DEPDIR)/vndext.Plo -rm -f ./$(DEPDIR)/vndservermapping.Plo -rm -f ./$(DEPDIR)/vndservervendor.Plo -rm -f ./$(DEPDIR)/xfont.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-sdkHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/clientinfo.Plo -rm -f ./$(DEPDIR)/createcontext.Plo -rm -f ./$(DEPDIR)/extension_string.Plo -rm -f ./$(DEPDIR)/glxcmds.Plo -rm -f ./$(DEPDIR)/glxcmdsswap.Plo -rm -f ./$(DEPDIR)/glxdri2.Plo -rm -f ./$(DEPDIR)/glxdricommon.Plo -rm -f ./$(DEPDIR)/glxdriswrast.Plo -rm -f ./$(DEPDIR)/glxext.Plo -rm -f ./$(DEPDIR)/glxscreens.Plo -rm -f ./$(DEPDIR)/indirect_dispatch.Plo -rm -f ./$(DEPDIR)/indirect_dispatch_swap.Plo -rm -f ./$(DEPDIR)/indirect_program.Plo -rm -f ./$(DEPDIR)/indirect_reqsize.Plo -rm -f ./$(DEPDIR)/indirect_size_get.Plo -rm -f ./$(DEPDIR)/indirect_table.Plo -rm -f ./$(DEPDIR)/indirect_texture_compression.Plo -rm -f ./$(DEPDIR)/indirect_util.Plo -rm -f ./$(DEPDIR)/render2.Plo -rm -f ./$(DEPDIR)/render2swap.Plo -rm -f ./$(DEPDIR)/renderpix.Plo -rm -f ./$(DEPDIR)/renderpixswap.Plo -rm -f ./$(DEPDIR)/rensize.Plo -rm -f ./$(DEPDIR)/single2.Plo -rm -f ./$(DEPDIR)/single2swap.Plo -rm -f ./$(DEPDIR)/singlepix.Plo -rm -f ./$(DEPDIR)/singlepixswap.Plo -rm -f ./$(DEPDIR)/singlesize.Plo -rm -f ./$(DEPDIR)/swap_interval.Plo -rm -f ./$(DEPDIR)/vndcmds.Plo -rm -f ./$(DEPDIR)/vndext.Plo -rm -f ./$(DEPDIR)/vndservermapping.Plo -rm -f ./$(DEPDIR)/vndservervendor.Plo -rm -f ./$(DEPDIR)/xfont.Plo -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 TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am 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 tags-am uninstall uninstall-am \ uninstall-sdkHEADERS .PRECIOUS: Makefile # 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: xorg-server-1.20.13/glx/indirect_dispatch.c0000644000175000017500000040146614100573756015523 00000000000000/* DO NOT EDIT - This file generated automatically by glX_proto_recv.py (from Mesa) script */ /* * (C) Copyright IBM Corporation 2005 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include "glxserver.h" #include "indirect_size.h" #include "indirect_size_get.h" #include "indirect_dispatch.h" #include "glxbyteorder.h" #include "indirect_util.h" #include "singlesize.h" #define __GLX_PAD(x) (((x) + 3) & ~3) typedef struct { __GLX_PIXEL_3D_HDR; } __GLXpixel3DHeader; extern GLboolean __glXErrorOccured(void); extern void __glXClearErrorOccured(void); static const unsigned dummy_answer[2] = { 0, 0 }; int __glXDisp_NewList(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { glNewList(*(GLuint *) (pc + 0), *(GLenum *) (pc + 4)); error = Success; } return error; } int __glXDisp_EndList(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { glEndList(); error = Success; } return error; } void __glXDisp_CallList(GLbyte * pc) { glCallList(*(GLuint *) (pc + 0)); } void __glXDisp_CallLists(GLbyte * pc) { const GLsizei n = *(GLsizei *) (pc + 0); const GLenum type = *(GLenum *) (pc + 4); const GLvoid *lists = (const GLvoid *) (pc + 8); lists = (const GLvoid *) (pc + 8); glCallLists(n, type, lists); } int __glXDisp_DeleteLists(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { glDeleteLists(*(GLuint *) (pc + 0), *(GLsizei *) (pc + 4)); error = Success; } return error; } int __glXDisp_GenLists(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLuint retval; retval = glGenLists(*(GLsizei *) (pc + 0)); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDisp_ListBase(GLbyte * pc) { glListBase(*(GLuint *) (pc + 0)); } void __glXDisp_Begin(GLbyte * pc) { glBegin(*(GLenum *) (pc + 0)); } void __glXDisp_Bitmap(GLbyte * pc) { const GLubyte *const bitmap = (const GLubyte *) ((pc + 44)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glBitmap(*(GLsizei *) (pc + 20), *(GLsizei *) (pc + 24), *(GLfloat *) (pc + 28), *(GLfloat *) (pc + 32), *(GLfloat *) (pc + 36), *(GLfloat *) (pc + 40), bitmap); } void __glXDisp_Color3bv(GLbyte * pc) { glColor3bv((const GLbyte *) (pc + 0)); } void __glXDisp_Color3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glColor3dv((const GLdouble *) (pc + 0)); } void __glXDisp_Color3fv(GLbyte * pc) { glColor3fv((const GLfloat *) (pc + 0)); } void __glXDisp_Color3iv(GLbyte * pc) { glColor3iv((const GLint *) (pc + 0)); } void __glXDisp_Color3sv(GLbyte * pc) { glColor3sv((const GLshort *) (pc + 0)); } void __glXDisp_Color3ubv(GLbyte * pc) { glColor3ubv((const GLubyte *) (pc + 0)); } void __glXDisp_Color3uiv(GLbyte * pc) { glColor3uiv((const GLuint *) (pc + 0)); } void __glXDisp_Color3usv(GLbyte * pc) { glColor3usv((const GLushort *) (pc + 0)); } void __glXDisp_Color4bv(GLbyte * pc) { glColor4bv((const GLbyte *) (pc + 0)); } void __glXDisp_Color4dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glColor4dv((const GLdouble *) (pc + 0)); } void __glXDisp_Color4fv(GLbyte * pc) { glColor4fv((const GLfloat *) (pc + 0)); } void __glXDisp_Color4iv(GLbyte * pc) { glColor4iv((const GLint *) (pc + 0)); } void __glXDisp_Color4sv(GLbyte * pc) { glColor4sv((const GLshort *) (pc + 0)); } void __glXDisp_Color4ubv(GLbyte * pc) { glColor4ubv((const GLubyte *) (pc + 0)); } void __glXDisp_Color4uiv(GLbyte * pc) { glColor4uiv((const GLuint *) (pc + 0)); } void __glXDisp_Color4usv(GLbyte * pc) { glColor4usv((const GLushort *) (pc + 0)); } void __glXDisp_EdgeFlagv(GLbyte * pc) { glEdgeFlagv((const GLboolean *) (pc + 0)); } void __glXDisp_End(GLbyte * pc) { glEnd(); } void __glXDisp_Indexdv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 8); pc -= 4; } #endif glIndexdv((const GLdouble *) (pc + 0)); } void __glXDisp_Indexfv(GLbyte * pc) { glIndexfv((const GLfloat *) (pc + 0)); } void __glXDisp_Indexiv(GLbyte * pc) { glIndexiv((const GLint *) (pc + 0)); } void __glXDisp_Indexsv(GLbyte * pc) { glIndexsv((const GLshort *) (pc + 0)); } void __glXDisp_Normal3bv(GLbyte * pc) { glNormal3bv((const GLbyte *) (pc + 0)); } void __glXDisp_Normal3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glNormal3dv((const GLdouble *) (pc + 0)); } void __glXDisp_Normal3fv(GLbyte * pc) { glNormal3fv((const GLfloat *) (pc + 0)); } void __glXDisp_Normal3iv(GLbyte * pc) { glNormal3iv((const GLint *) (pc + 0)); } void __glXDisp_Normal3sv(GLbyte * pc) { glNormal3sv((const GLshort *) (pc + 0)); } void __glXDisp_RasterPos2dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glRasterPos2dv((const GLdouble *) (pc + 0)); } void __glXDisp_RasterPos2fv(GLbyte * pc) { glRasterPos2fv((const GLfloat *) (pc + 0)); } void __glXDisp_RasterPos2iv(GLbyte * pc) { glRasterPos2iv((const GLint *) (pc + 0)); } void __glXDisp_RasterPos2sv(GLbyte * pc) { glRasterPos2sv((const GLshort *) (pc + 0)); } void __glXDisp_RasterPos3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glRasterPos3dv((const GLdouble *) (pc + 0)); } void __glXDisp_RasterPos3fv(GLbyte * pc) { glRasterPos3fv((const GLfloat *) (pc + 0)); } void __glXDisp_RasterPos3iv(GLbyte * pc) { glRasterPos3iv((const GLint *) (pc + 0)); } void __glXDisp_RasterPos3sv(GLbyte * pc) { glRasterPos3sv((const GLshort *) (pc + 0)); } void __glXDisp_RasterPos4dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glRasterPos4dv((const GLdouble *) (pc + 0)); } void __glXDisp_RasterPos4fv(GLbyte * pc) { glRasterPos4fv((const GLfloat *) (pc + 0)); } void __glXDisp_RasterPos4iv(GLbyte * pc) { glRasterPos4iv((const GLint *) (pc + 0)); } void __glXDisp_RasterPos4sv(GLbyte * pc) { glRasterPos4sv((const GLshort *) (pc + 0)); } void __glXDisp_Rectdv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glRectdv((const GLdouble *) (pc + 0), (const GLdouble *) (pc + 16)); } void __glXDisp_Rectfv(GLbyte * pc) { glRectfv((const GLfloat *) (pc + 0), (const GLfloat *) (pc + 8)); } void __glXDisp_Rectiv(GLbyte * pc) { glRectiv((const GLint *) (pc + 0), (const GLint *) (pc + 8)); } void __glXDisp_Rectsv(GLbyte * pc) { glRectsv((const GLshort *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_TexCoord1dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 8); pc -= 4; } #endif glTexCoord1dv((const GLdouble *) (pc + 0)); } void __glXDisp_TexCoord1fv(GLbyte * pc) { glTexCoord1fv((const GLfloat *) (pc + 0)); } void __glXDisp_TexCoord1iv(GLbyte * pc) { glTexCoord1iv((const GLint *) (pc + 0)); } void __glXDisp_TexCoord1sv(GLbyte * pc) { glTexCoord1sv((const GLshort *) (pc + 0)); } void __glXDisp_TexCoord2dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glTexCoord2dv((const GLdouble *) (pc + 0)); } void __glXDisp_TexCoord2fv(GLbyte * pc) { glTexCoord2fv((const GLfloat *) (pc + 0)); } void __glXDisp_TexCoord2iv(GLbyte * pc) { glTexCoord2iv((const GLint *) (pc + 0)); } void __glXDisp_TexCoord2sv(GLbyte * pc) { glTexCoord2sv((const GLshort *) (pc + 0)); } void __glXDisp_TexCoord3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glTexCoord3dv((const GLdouble *) (pc + 0)); } void __glXDisp_TexCoord3fv(GLbyte * pc) { glTexCoord3fv((const GLfloat *) (pc + 0)); } void __glXDisp_TexCoord3iv(GLbyte * pc) { glTexCoord3iv((const GLint *) (pc + 0)); } void __glXDisp_TexCoord3sv(GLbyte * pc) { glTexCoord3sv((const GLshort *) (pc + 0)); } void __glXDisp_TexCoord4dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glTexCoord4dv((const GLdouble *) (pc + 0)); } void __glXDisp_TexCoord4fv(GLbyte * pc) { glTexCoord4fv((const GLfloat *) (pc + 0)); } void __glXDisp_TexCoord4iv(GLbyte * pc) { glTexCoord4iv((const GLint *) (pc + 0)); } void __glXDisp_TexCoord4sv(GLbyte * pc) { glTexCoord4sv((const GLshort *) (pc + 0)); } void __glXDisp_Vertex2dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glVertex2dv((const GLdouble *) (pc + 0)); } void __glXDisp_Vertex2fv(GLbyte * pc) { glVertex2fv((const GLfloat *) (pc + 0)); } void __glXDisp_Vertex2iv(GLbyte * pc) { glVertex2iv((const GLint *) (pc + 0)); } void __glXDisp_Vertex2sv(GLbyte * pc) { glVertex2sv((const GLshort *) (pc + 0)); } void __glXDisp_Vertex3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glVertex3dv((const GLdouble *) (pc + 0)); } void __glXDisp_Vertex3fv(GLbyte * pc) { glVertex3fv((const GLfloat *) (pc + 0)); } void __glXDisp_Vertex3iv(GLbyte * pc) { glVertex3iv((const GLint *) (pc + 0)); } void __glXDisp_Vertex3sv(GLbyte * pc) { glVertex3sv((const GLshort *) (pc + 0)); } void __glXDisp_Vertex4dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glVertex4dv((const GLdouble *) (pc + 0)); } void __glXDisp_Vertex4fv(GLbyte * pc) { glVertex4fv((const GLfloat *) (pc + 0)); } void __glXDisp_Vertex4iv(GLbyte * pc) { glVertex4iv((const GLint *) (pc + 0)); } void __glXDisp_Vertex4sv(GLbyte * pc) { glVertex4sv((const GLshort *) (pc + 0)); } void __glXDisp_ClipPlane(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 36); pc -= 4; } #endif glClipPlane(*(GLenum *) (pc + 32), (const GLdouble *) (pc + 0)); } void __glXDisp_ColorMaterial(GLbyte * pc) { glColorMaterial(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4)); } void __glXDisp_CullFace(GLbyte * pc) { glCullFace(*(GLenum *) (pc + 0)); } void __glXDisp_Fogf(GLbyte * pc) { glFogf(*(GLenum *) (pc + 0), *(GLfloat *) (pc + 4)); } void __glXDisp_Fogfv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 0); const GLfloat *params; params = (const GLfloat *) (pc + 4); glFogfv(pname, params); } void __glXDisp_Fogi(GLbyte * pc) { glFogi(*(GLenum *) (pc + 0), *(GLint *) (pc + 4)); } void __glXDisp_Fogiv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 0); const GLint *params; params = (const GLint *) (pc + 4); glFogiv(pname, params); } void __glXDisp_FrontFace(GLbyte * pc) { glFrontFace(*(GLenum *) (pc + 0)); } void __glXDisp_Hint(GLbyte * pc) { glHint(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4)); } void __glXDisp_Lightf(GLbyte * pc) { glLightf(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLfloat *) (pc + 8)); } void __glXDisp_Lightfv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLfloat *params; params = (const GLfloat *) (pc + 8); glLightfv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_Lighti(GLbyte * pc) { glLighti(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLint *) (pc + 8)); } void __glXDisp_Lightiv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLint *params; params = (const GLint *) (pc + 8); glLightiv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_LightModelf(GLbyte * pc) { glLightModelf(*(GLenum *) (pc + 0), *(GLfloat *) (pc + 4)); } void __glXDisp_LightModelfv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 0); const GLfloat *params; params = (const GLfloat *) (pc + 4); glLightModelfv(pname, params); } void __glXDisp_LightModeli(GLbyte * pc) { glLightModeli(*(GLenum *) (pc + 0), *(GLint *) (pc + 4)); } void __glXDisp_LightModeliv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 0); const GLint *params; params = (const GLint *) (pc + 4); glLightModeliv(pname, params); } void __glXDisp_LineStipple(GLbyte * pc) { glLineStipple(*(GLint *) (pc + 0), *(GLushort *) (pc + 4)); } void __glXDisp_LineWidth(GLbyte * pc) { glLineWidth(*(GLfloat *) (pc + 0)); } void __glXDisp_Materialf(GLbyte * pc) { glMaterialf(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLfloat *) (pc + 8)); } void __glXDisp_Materialfv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLfloat *params; params = (const GLfloat *) (pc + 8); glMaterialfv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_Materiali(GLbyte * pc) { glMateriali(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLint *) (pc + 8)); } void __glXDisp_Materialiv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLint *params; params = (const GLint *) (pc + 8); glMaterialiv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_PointSize(GLbyte * pc) { glPointSize(*(GLfloat *) (pc + 0)); } void __glXDisp_PolygonMode(GLbyte * pc) { glPolygonMode(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4)); } void __glXDisp_PolygonStipple(GLbyte * pc) { const GLubyte *const mask = (const GLubyte *) ((pc + 20)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glPolygonStipple(mask); } void __glXDisp_Scissor(GLbyte * pc) { glScissor(*(GLint *) (pc + 0), *(GLint *) (pc + 4), *(GLsizei *) (pc + 8), *(GLsizei *) (pc + 12)); } void __glXDisp_ShadeModel(GLbyte * pc) { glShadeModel(*(GLenum *) (pc + 0)); } void __glXDisp_TexParameterf(GLbyte * pc) { glTexParameterf(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLfloat *) (pc + 8)); } void __glXDisp_TexParameterfv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLfloat *params; params = (const GLfloat *) (pc + 8); glTexParameterfv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_TexParameteri(GLbyte * pc) { glTexParameteri(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLint *) (pc + 8)); } void __glXDisp_TexParameteriv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLint *params; params = (const GLint *) (pc + 8); glTexParameteriv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_TexImage1D(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 52)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glTexImage1D(*(GLenum *) (pc + 20), *(GLint *) (pc + 24), *(GLint *) (pc + 28), *(GLsizei *) (pc + 32), *(GLint *) (pc + 40), *(GLenum *) (pc + 44), *(GLenum *) (pc + 48), pixels); } void __glXDisp_TexImage2D(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 52)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glTexImage2D(*(GLenum *) (pc + 20), *(GLint *) (pc + 24), *(GLint *) (pc + 28), *(GLsizei *) (pc + 32), *(GLsizei *) (pc + 36), *(GLint *) (pc + 40), *(GLenum *) (pc + 44), *(GLenum *) (pc + 48), pixels); } void __glXDisp_TexEnvf(GLbyte * pc) { glTexEnvf(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLfloat *) (pc + 8)); } void __glXDisp_TexEnvfv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLfloat *params; params = (const GLfloat *) (pc + 8); glTexEnvfv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_TexEnvi(GLbyte * pc) { glTexEnvi(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLint *) (pc + 8)); } void __glXDisp_TexEnviv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLint *params; params = (const GLint *) (pc + 8); glTexEnviv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_TexGend(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glTexGend(*(GLenum *) (pc + 8), *(GLenum *) (pc + 12), *(GLdouble *) (pc + 0)); } void __glXDisp_TexGendv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLdouble *params; #ifdef __GLX_ALIGN64 const GLuint compsize = __glTexGendv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 8)) - 4; if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, cmdlen); pc -= 4; } #endif params = (const GLdouble *) (pc + 8); glTexGendv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_TexGenf(GLbyte * pc) { glTexGenf(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLfloat *) (pc + 8)); } void __glXDisp_TexGenfv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLfloat *params; params = (const GLfloat *) (pc + 8); glTexGenfv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_TexGeni(GLbyte * pc) { glTexGeni(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLint *) (pc + 8)); } void __glXDisp_TexGeniv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLint *params; params = (const GLint *) (pc + 8); glTexGeniv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_InitNames(GLbyte * pc) { glInitNames(); } void __glXDisp_LoadName(GLbyte * pc) { glLoadName(*(GLuint *) (pc + 0)); } void __glXDisp_PassThrough(GLbyte * pc) { glPassThrough(*(GLfloat *) (pc + 0)); } void __glXDisp_PopName(GLbyte * pc) { glPopName(); } void __glXDisp_PushName(GLbyte * pc) { glPushName(*(GLuint *) (pc + 0)); } void __glXDisp_DrawBuffer(GLbyte * pc) { glDrawBuffer(*(GLenum *) (pc + 0)); } void __glXDisp_Clear(GLbyte * pc) { glClear(*(GLbitfield *) (pc + 0)); } void __glXDisp_ClearAccum(GLbyte * pc) { glClearAccum(*(GLfloat *) (pc + 0), *(GLfloat *) (pc + 4), *(GLfloat *) (pc + 8), *(GLfloat *) (pc + 12)); } void __glXDisp_ClearIndex(GLbyte * pc) { glClearIndex(*(GLfloat *) (pc + 0)); } void __glXDisp_ClearColor(GLbyte * pc) { glClearColor(*(GLclampf *) (pc + 0), *(GLclampf *) (pc + 4), *(GLclampf *) (pc + 8), *(GLclampf *) (pc + 12)); } void __glXDisp_ClearStencil(GLbyte * pc) { glClearStencil(*(GLint *) (pc + 0)); } void __glXDisp_ClearDepth(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 8); pc -= 4; } #endif glClearDepth(*(GLclampd *) (pc + 0)); } void __glXDisp_StencilMask(GLbyte * pc) { glStencilMask(*(GLuint *) (pc + 0)); } void __glXDisp_ColorMask(GLbyte * pc) { glColorMask(*(GLboolean *) (pc + 0), *(GLboolean *) (pc + 1), *(GLboolean *) (pc + 2), *(GLboolean *) (pc + 3)); } void __glXDisp_DepthMask(GLbyte * pc) { glDepthMask(*(GLboolean *) (pc + 0)); } void __glXDisp_IndexMask(GLbyte * pc) { glIndexMask(*(GLuint *) (pc + 0)); } void __glXDisp_Accum(GLbyte * pc) { glAccum(*(GLenum *) (pc + 0), *(GLfloat *) (pc + 4)); } void __glXDisp_Disable(GLbyte * pc) { glDisable(*(GLenum *) (pc + 0)); } void __glXDisp_Enable(GLbyte * pc) { glEnable(*(GLenum *) (pc + 0)); } void __glXDisp_PopAttrib(GLbyte * pc) { glPopAttrib(); } void __glXDisp_PushAttrib(GLbyte * pc) { glPushAttrib(*(GLbitfield *) (pc + 0)); } void __glXDisp_MapGrid1d(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 20); pc -= 4; } #endif glMapGrid1d(*(GLint *) (pc + 16), *(GLdouble *) (pc + 0), *(GLdouble *) (pc + 8)); } void __glXDisp_MapGrid1f(GLbyte * pc) { glMapGrid1f(*(GLint *) (pc + 0), *(GLfloat *) (pc + 4), *(GLfloat *) (pc + 8)); } void __glXDisp_MapGrid2d(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 40); pc -= 4; } #endif glMapGrid2d(*(GLint *) (pc + 32), *(GLdouble *) (pc + 0), *(GLdouble *) (pc + 8), *(GLint *) (pc + 36), *(GLdouble *) (pc + 16), *(GLdouble *) (pc + 24)); } void __glXDisp_MapGrid2f(GLbyte * pc) { glMapGrid2f(*(GLint *) (pc + 0), *(GLfloat *) (pc + 4), *(GLfloat *) (pc + 8), *(GLint *) (pc + 12), *(GLfloat *) (pc + 16), *(GLfloat *) (pc + 20)); } void __glXDisp_EvalCoord1dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 8); pc -= 4; } #endif glEvalCoord1dv((const GLdouble *) (pc + 0)); } void __glXDisp_EvalCoord1fv(GLbyte * pc) { glEvalCoord1fv((const GLfloat *) (pc + 0)); } void __glXDisp_EvalCoord2dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glEvalCoord2dv((const GLdouble *) (pc + 0)); } void __glXDisp_EvalCoord2fv(GLbyte * pc) { glEvalCoord2fv((const GLfloat *) (pc + 0)); } void __glXDisp_EvalMesh1(GLbyte * pc) { glEvalMesh1(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLint *) (pc + 8)); } void __glXDisp_EvalPoint1(GLbyte * pc) { glEvalPoint1(*(GLint *) (pc + 0)); } void __glXDisp_EvalMesh2(GLbyte * pc) { glEvalMesh2(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLint *) (pc + 16)); } void __glXDisp_EvalPoint2(GLbyte * pc) { glEvalPoint2(*(GLint *) (pc + 0), *(GLint *) (pc + 4)); } void __glXDisp_AlphaFunc(GLbyte * pc) { glAlphaFunc(*(GLenum *) (pc + 0), *(GLclampf *) (pc + 4)); } void __glXDisp_BlendFunc(GLbyte * pc) { glBlendFunc(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4)); } void __glXDisp_LogicOp(GLbyte * pc) { glLogicOp(*(GLenum *) (pc + 0)); } void __glXDisp_StencilFunc(GLbyte * pc) { glStencilFunc(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLuint *) (pc + 8)); } void __glXDisp_StencilOp(GLbyte * pc) { glStencilOp(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8)); } void __glXDisp_DepthFunc(GLbyte * pc) { glDepthFunc(*(GLenum *) (pc + 0)); } void __glXDisp_PixelZoom(GLbyte * pc) { glPixelZoom(*(GLfloat *) (pc + 0), *(GLfloat *) (pc + 4)); } void __glXDisp_PixelTransferf(GLbyte * pc) { glPixelTransferf(*(GLenum *) (pc + 0), *(GLfloat *) (pc + 4)); } void __glXDisp_PixelTransferi(GLbyte * pc) { glPixelTransferi(*(GLenum *) (pc + 0), *(GLint *) (pc + 4)); } int __glXDisp_PixelStoref(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { glPixelStoref(*(GLenum *) (pc + 0), *(GLfloat *) (pc + 4)); error = Success; } return error; } int __glXDisp_PixelStorei(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { glPixelStorei(*(GLenum *) (pc + 0), *(GLint *) (pc + 4)); error = Success; } return error; } void __glXDisp_PixelMapfv(GLbyte * pc) { const GLsizei mapsize = *(GLsizei *) (pc + 4); glPixelMapfv(*(GLenum *) (pc + 0), mapsize, (const GLfloat *) (pc + 8)); } void __glXDisp_PixelMapuiv(GLbyte * pc) { const GLsizei mapsize = *(GLsizei *) (pc + 4); glPixelMapuiv(*(GLenum *) (pc + 0), mapsize, (const GLuint *) (pc + 8)); } void __glXDisp_PixelMapusv(GLbyte * pc) { const GLsizei mapsize = *(GLsizei *) (pc + 4); glPixelMapusv(*(GLenum *) (pc + 0), mapsize, (const GLushort *) (pc + 8)); } void __glXDisp_ReadBuffer(GLbyte * pc) { glReadBuffer(*(GLenum *) (pc + 0)); } void __glXDisp_CopyPixels(GLbyte * pc) { glCopyPixels(*(GLint *) (pc + 0), *(GLint *) (pc + 4), *(GLsizei *) (pc + 8), *(GLsizei *) (pc + 12), *(GLenum *) (pc + 16)); } void __glXDisp_DrawPixels(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 36)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glDrawPixels(*(GLsizei *) (pc + 20), *(GLsizei *) (pc + 24), *(GLenum *) (pc + 28), *(GLenum *) (pc + 32), pixels); } int __glXDisp_GetBooleanv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 0); const GLuint compsize = __glGetBooleanv_size(pname); GLboolean answerBuffer[200]; GLboolean *params = __glXGetAnswerBuffer(cl, compsize, answerBuffer, sizeof(answerBuffer), 1); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetBooleanv(pname, params); __glXSendReply(cl->client, params, compsize, 1, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetClipPlane(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLdouble equation[4]; glGetClipPlane(*(GLenum *) (pc + 0), equation); __glXSendReply(cl->client, equation, 4, 8, GL_TRUE, 0); error = Success; } return error; } int __glXDisp_GetDoublev(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 0); const GLuint compsize = __glGetDoublev_size(pname); GLdouble answerBuffer[200]; GLdouble *params = __glXGetAnswerBuffer(cl, compsize * 8, answerBuffer, sizeof(answerBuffer), 8); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetDoublev(pname, params); __glXSendReply(cl->client, params, compsize, 8, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetError(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLenum retval; retval = glGetError(); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } int __glXDisp_GetFloatv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 0); const GLuint compsize = __glGetFloatv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetFloatv(pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetIntegerv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 0); const GLuint compsize = __glGetIntegerv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetIntegerv(pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetLightfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetLightfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetLightfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetLightiv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetLightiv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetLightiv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetMapdv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum target = *(GLenum *) (pc + 0); const GLenum query = *(GLenum *) (pc + 4); const GLuint compsize = __glGetMapdv_size(target, query); GLdouble answerBuffer[200]; GLdouble *v = __glXGetAnswerBuffer(cl, compsize * 8, answerBuffer, sizeof(answerBuffer), 8); if (v == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMapdv(target, query, v); __glXSendReply(cl->client, v, compsize, 8, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetMapfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum target = *(GLenum *) (pc + 0); const GLenum query = *(GLenum *) (pc + 4); const GLuint compsize = __glGetMapfv_size(target, query); GLfloat answerBuffer[200]; GLfloat *v = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (v == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMapfv(target, query, v); __glXSendReply(cl->client, v, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetMapiv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum target = *(GLenum *) (pc + 0); const GLenum query = *(GLenum *) (pc + 4); const GLuint compsize = __glGetMapiv_size(target, query); GLint answerBuffer[200]; GLint *v = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (v == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMapiv(target, query, v); __glXSendReply(cl->client, v, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetMaterialfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetMaterialfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMaterialfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetMaterialiv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetMaterialiv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMaterialiv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetPixelMapfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum map = *(GLenum *) (pc + 0); const GLuint compsize = __glGetPixelMapfv_size(map); GLfloat answerBuffer[200]; GLfloat *values = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (values == NULL) return BadAlloc; __glXClearErrorOccured(); glGetPixelMapfv(map, values); __glXSendReply(cl->client, values, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetPixelMapuiv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum map = *(GLenum *) (pc + 0); const GLuint compsize = __glGetPixelMapuiv_size(map); GLuint answerBuffer[200]; GLuint *values = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (values == NULL) return BadAlloc; __glXClearErrorOccured(); glGetPixelMapuiv(map, values); __glXSendReply(cl->client, values, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetPixelMapusv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum map = *(GLenum *) (pc + 0); const GLuint compsize = __glGetPixelMapusv_size(map); GLushort answerBuffer[200]; GLushort *values = __glXGetAnswerBuffer(cl, compsize * 2, answerBuffer, sizeof(answerBuffer), 2); if (values == NULL) return BadAlloc; __glXClearErrorOccured(); glGetPixelMapusv(map, values); __glXSendReply(cl->client, values, compsize, 2, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetTexEnvfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetTexEnvfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexEnvfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetTexEnviv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetTexEnviv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexEnviv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetTexGendv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetTexGendv_size(pname); GLdouble answerBuffer[200]; GLdouble *params = __glXGetAnswerBuffer(cl, compsize * 8, answerBuffer, sizeof(answerBuffer), 8); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexGendv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 8, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetTexGenfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetTexGenfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexGenfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetTexGeniv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetTexGeniv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexGeniv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetTexParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetTexParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexParameterfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetTexParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetTexParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexParameteriv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetTexLevelParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 8); const GLuint compsize = __glGetTexLevelParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexLevelParameterfv(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetTexLevelParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 8); const GLuint compsize = __glGetTexLevelParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexLevelParameteriv(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_IsEnabled(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = glIsEnabled(*(GLenum *) (pc + 0)); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } int __glXDisp_IsList(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = glIsList(*(GLuint *) (pc + 0)); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDisp_DepthRange(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glDepthRange(*(GLclampd *) (pc + 0), *(GLclampd *) (pc + 8)); } void __glXDisp_Frustum(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 48); pc -= 4; } #endif glFrustum(*(GLdouble *) (pc + 0), *(GLdouble *) (pc + 8), *(GLdouble *) (pc + 16), *(GLdouble *) (pc + 24), *(GLdouble *) (pc + 32), *(GLdouble *) (pc + 40)); } void __glXDisp_LoadIdentity(GLbyte * pc) { glLoadIdentity(); } void __glXDisp_LoadMatrixf(GLbyte * pc) { glLoadMatrixf((const GLfloat *) (pc + 0)); } void __glXDisp_LoadMatrixd(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 128); pc -= 4; } #endif glLoadMatrixd((const GLdouble *) (pc + 0)); } void __glXDisp_MatrixMode(GLbyte * pc) { glMatrixMode(*(GLenum *) (pc + 0)); } void __glXDisp_MultMatrixf(GLbyte * pc) { glMultMatrixf((const GLfloat *) (pc + 0)); } void __glXDisp_MultMatrixd(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 128); pc -= 4; } #endif glMultMatrixd((const GLdouble *) (pc + 0)); } void __glXDisp_Ortho(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 48); pc -= 4; } #endif glOrtho(*(GLdouble *) (pc + 0), *(GLdouble *) (pc + 8), *(GLdouble *) (pc + 16), *(GLdouble *) (pc + 24), *(GLdouble *) (pc + 32), *(GLdouble *) (pc + 40)); } void __glXDisp_PopMatrix(GLbyte * pc) { glPopMatrix(); } void __glXDisp_PushMatrix(GLbyte * pc) { glPushMatrix(); } void __glXDisp_Rotated(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glRotated(*(GLdouble *) (pc + 0), *(GLdouble *) (pc + 8), *(GLdouble *) (pc + 16), *(GLdouble *) (pc + 24)); } void __glXDisp_Rotatef(GLbyte * pc) { glRotatef(*(GLfloat *) (pc + 0), *(GLfloat *) (pc + 4), *(GLfloat *) (pc + 8), *(GLfloat *) (pc + 12)); } void __glXDisp_Scaled(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glScaled(*(GLdouble *) (pc + 0), *(GLdouble *) (pc + 8), *(GLdouble *) (pc + 16)); } void __glXDisp_Scalef(GLbyte * pc) { glScalef(*(GLfloat *) (pc + 0), *(GLfloat *) (pc + 4), *(GLfloat *) (pc + 8)); } void __glXDisp_Translated(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glTranslated(*(GLdouble *) (pc + 0), *(GLdouble *) (pc + 8), *(GLdouble *) (pc + 16)); } void __glXDisp_Translatef(GLbyte * pc) { glTranslatef(*(GLfloat *) (pc + 0), *(GLfloat *) (pc + 4), *(GLfloat *) (pc + 8)); } void __glXDisp_Viewport(GLbyte * pc) { glViewport(*(GLint *) (pc + 0), *(GLint *) (pc + 4), *(GLsizei *) (pc + 8), *(GLsizei *) (pc + 12)); } void __glXDisp_BindTexture(GLbyte * pc) { glBindTexture(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4)); } void __glXDisp_Indexubv(GLbyte * pc) { glIndexubv((const GLubyte *) (pc + 0)); } void __glXDisp_PolygonOffset(GLbyte * pc) { glPolygonOffset(*(GLfloat *) (pc + 0), *(GLfloat *) (pc + 4)); } int __glXDisp_AreTexturesResident(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); GLboolean retval; GLboolean answerBuffer[200]; GLboolean *residences = __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1); if (residences == NULL) return BadAlloc; retval = glAreTexturesResident(n, (const GLuint *) (pc + 4), residences); __glXSendReply(cl->client, residences, n, 1, GL_TRUE, retval); error = Success; } return error; } int __glXDisp_AreTexturesResidentEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); GLboolean retval; GLboolean answerBuffer[200]; GLboolean *residences = __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1); if (residences == NULL) return BadAlloc; retval = glAreTexturesResident(n, (const GLuint *) (pc + 4), residences); __glXSendReply(cl->client, residences, n, 1, GL_TRUE, retval); error = Success; } return error; } void __glXDisp_CopyTexImage1D(GLbyte * pc) { glCopyTexImage1D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLenum *) (pc + 8), *(GLint *) (pc + 12), *(GLint *) (pc + 16), *(GLsizei *) (pc + 20), *(GLint *) (pc + 24)); } void __glXDisp_CopyTexImage2D(GLbyte * pc) { glCopyTexImage2D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLenum *) (pc + 8), *(GLint *) (pc + 12), *(GLint *) (pc + 16), *(GLsizei *) (pc + 20), *(GLsizei *) (pc + 24), *(GLint *) (pc + 28)); } void __glXDisp_CopyTexSubImage1D(GLbyte * pc) { glCopyTexSubImage1D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLint *) (pc + 16), *(GLsizei *) (pc + 20)); } void __glXDisp_CopyTexSubImage2D(GLbyte * pc) { glCopyTexSubImage2D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLint *) (pc + 16), *(GLint *) (pc + 20), *(GLsizei *) (pc + 24), *(GLsizei *) (pc + 28)); } int __glXDisp_DeleteTextures(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); glDeleteTextures(n, (const GLuint *) (pc + 4)); error = Success; } return error; } int __glXDisp_DeleteTexturesEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); glDeleteTextures(n, (const GLuint *) (pc + 4)); error = Success; } return error; } int __glXDisp_GenTextures(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); GLuint answerBuffer[200]; GLuint *textures = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (textures == NULL) return BadAlloc; glGenTextures(n, textures); __glXSendReply(cl->client, textures, n, 4, GL_TRUE, 0); error = Success; } return error; } int __glXDisp_GenTexturesEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); GLuint answerBuffer[200]; GLuint *textures = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (textures == NULL) return BadAlloc; glGenTextures(n, textures); __glXSendReply(cl->client, textures, n, 4, GL_TRUE, 0); error = Success; } return error; } int __glXDisp_IsTexture(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = glIsTexture(*(GLuint *) (pc + 0)); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } int __glXDisp_IsTextureEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = glIsTexture(*(GLuint *) (pc + 0)); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDisp_PrioritizeTextures(GLbyte * pc) { const GLsizei n = *(GLsizei *) (pc + 0); glPrioritizeTextures(n, (const GLuint *) (pc + 4), (const GLclampf *) (pc + 4)); } void __glXDisp_TexSubImage1D(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 56)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glTexSubImage1D(*(GLenum *) (pc + 20), *(GLint *) (pc + 24), *(GLint *) (pc + 28), *(GLsizei *) (pc + 36), *(GLenum *) (pc + 44), *(GLenum *) (pc + 48), pixels); } void __glXDisp_TexSubImage2D(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 56)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glTexSubImage2D(*(GLenum *) (pc + 20), *(GLint *) (pc + 24), *(GLint *) (pc + 28), *(GLint *) (pc + 32), *(GLsizei *) (pc + 36), *(GLsizei *) (pc + 40), *(GLenum *) (pc + 44), *(GLenum *) (pc + 48), pixels); } void __glXDisp_BlendColor(GLbyte * pc) { glBlendColor(*(GLclampf *) (pc + 0), *(GLclampf *) (pc + 4), *(GLclampf *) (pc + 8), *(GLclampf *) (pc + 12)); } void __glXDisp_BlendEquation(GLbyte * pc) { glBlendEquation(*(GLenum *) (pc + 0)); } void __glXDisp_ColorTable(GLbyte * pc) { const GLvoid *const table = (const GLvoid *) ((pc + 40)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glColorTable(*(GLenum *) (pc + 20), *(GLenum *) (pc + 24), *(GLsizei *) (pc + 28), *(GLenum *) (pc + 32), *(GLenum *) (pc + 36), table); } void __glXDisp_ColorTableParameterfv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLfloat *params; params = (const GLfloat *) (pc + 8); glColorTableParameterfv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_ColorTableParameteriv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLint *params; params = (const GLint *) (pc + 8); glColorTableParameteriv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_CopyColorTable(GLbyte * pc) { glCopyColorTable(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLsizei *) (pc + 16)); } int __glXDisp_GetColorTableParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetColorTableParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetColorTableParameterfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetColorTableParameterfvSGI(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetColorTableParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetColorTableParameterfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetColorTableParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetColorTableParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetColorTableParameteriv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetColorTableParameterivSGI(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetColorTableParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetColorTableParameteriv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } void __glXDisp_ColorSubTable(GLbyte * pc) { const GLvoid *const data = (const GLvoid *) ((pc + 40)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glColorSubTable(*(GLenum *) (pc + 20), *(GLsizei *) (pc + 24), *(GLsizei *) (pc + 28), *(GLenum *) (pc + 32), *(GLenum *) (pc + 36), data); } void __glXDisp_CopyColorSubTable(GLbyte * pc) { glCopyColorSubTable(*(GLenum *) (pc + 0), *(GLsizei *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLsizei *) (pc + 16)); } void __glXDisp_ConvolutionFilter1D(GLbyte * pc) { const GLvoid *const image = (const GLvoid *) ((pc + 44)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glConvolutionFilter1D(*(GLenum *) (pc + 20), *(GLenum *) (pc + 24), *(GLsizei *) (pc + 28), *(GLenum *) (pc + 36), *(GLenum *) (pc + 40), image); } void __glXDisp_ConvolutionFilter2D(GLbyte * pc) { const GLvoid *const image = (const GLvoid *) ((pc + 44)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glConvolutionFilter2D(*(GLenum *) (pc + 20), *(GLenum *) (pc + 24), *(GLsizei *) (pc + 28), *(GLsizei *) (pc + 32), *(GLenum *) (pc + 36), *(GLenum *) (pc + 40), image); } void __glXDisp_ConvolutionParameterf(GLbyte * pc) { glConvolutionParameterf(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLfloat *) (pc + 8)); } void __glXDisp_ConvolutionParameterfv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLfloat *params; params = (const GLfloat *) (pc + 8); glConvolutionParameterfv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_ConvolutionParameteri(GLbyte * pc) { glConvolutionParameteri(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLint *) (pc + 8)); } void __glXDisp_ConvolutionParameteriv(GLbyte * pc) { const GLenum pname = *(GLenum *) (pc + 4); const GLint *params; params = (const GLint *) (pc + 8); glConvolutionParameteriv(*(GLenum *) (pc + 0), pname, params); } void __glXDisp_CopyConvolutionFilter1D(GLbyte * pc) { glCopyConvolutionFilter1D(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLsizei *) (pc + 16)); } void __glXDisp_CopyConvolutionFilter2D(GLbyte * pc) { glCopyConvolutionFilter2D(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLsizei *) (pc + 16), *(GLsizei *) (pc + 20)); } int __glXDisp_GetConvolutionParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetConvolutionParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetConvolutionParameterfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetConvolutionParameterfvEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetConvolutionParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetConvolutionParameterfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetConvolutionParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetConvolutionParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetConvolutionParameteriv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetConvolutionParameterivEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetConvolutionParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetConvolutionParameteriv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetHistogramParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetHistogramParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetHistogramParameterfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetHistogramParameterfvEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetHistogramParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetHistogramParameterfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetHistogramParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetHistogramParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetHistogramParameteriv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetHistogramParameterivEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetHistogramParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetHistogramParameteriv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetMinmaxParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetMinmaxParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMinmaxParameterfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetMinmaxParameterfvEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetMinmaxParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMinmaxParameterfv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetMinmaxParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetMinmaxParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMinmaxParameteriv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetMinmaxParameterivEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetMinmaxParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMinmaxParameteriv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } void __glXDisp_Histogram(GLbyte * pc) { glHistogram(*(GLenum *) (pc + 0), *(GLsizei *) (pc + 4), *(GLenum *) (pc + 8), *(GLboolean *) (pc + 12)); } void __glXDisp_Minmax(GLbyte * pc) { glMinmax(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLboolean *) (pc + 8)); } void __glXDisp_ResetHistogram(GLbyte * pc) { glResetHistogram(*(GLenum *) (pc + 0)); } void __glXDisp_ResetMinmax(GLbyte * pc) { glResetMinmax(*(GLenum *) (pc + 0)); } void __glXDisp_TexImage3D(GLbyte * pc) { const CARD32 ptr_is_null = *(CARD32 *) (pc + 76); const GLvoid *const pixels = (const GLvoid *) ((ptr_is_null != 0) ? NULL : (pc + 80)); __GLXpixel3DHeader *const hdr = (__GLXpixel3DHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (GLint) hdr->imageHeight); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_IMAGES, (GLint) hdr->skipImages); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glTexImage3D(*(GLenum *) (pc + 36), *(GLint *) (pc + 40), *(GLint *) (pc + 44), *(GLsizei *) (pc + 48), *(GLsizei *) (pc + 52), *(GLsizei *) (pc + 56), *(GLint *) (pc + 64), *(GLenum *) (pc + 68), *(GLenum *) (pc + 72), pixels); } void __glXDisp_TexSubImage3D(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 88)); __GLXpixel3DHeader *const hdr = (__GLXpixel3DHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (GLint) hdr->imageHeight); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_IMAGES, (GLint) hdr->skipImages); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment); glTexSubImage3D(*(GLenum *) (pc + 36), *(GLint *) (pc + 40), *(GLint *) (pc + 44), *(GLint *) (pc + 48), *(GLint *) (pc + 52), *(GLsizei *) (pc + 60), *(GLsizei *) (pc + 64), *(GLsizei *) (pc + 68), *(GLenum *) (pc + 76), *(GLenum *) (pc + 80), pixels); } void __glXDisp_CopyTexSubImage3D(GLbyte * pc) { glCopyTexSubImage3D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLint *) (pc + 16), *(GLint *) (pc + 20), *(GLint *) (pc + 24), *(GLsizei *) (pc + 28), *(GLsizei *) (pc + 32)); } void __glXDisp_ActiveTexture(GLbyte * pc) { glActiveTextureARB(*(GLenum *) (pc + 0)); } void __glXDisp_MultiTexCoord1dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 12); pc -= 4; } #endif glMultiTexCoord1dvARB(*(GLenum *) (pc + 8), (const GLdouble *) (pc + 0)); } void __glXDisp_MultiTexCoord1fvARB(GLbyte * pc) { glMultiTexCoord1fvARB(*(GLenum *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_MultiTexCoord1iv(GLbyte * pc) { glMultiTexCoord1ivARB(*(GLenum *) (pc + 0), (const GLint *) (pc + 4)); } void __glXDisp_MultiTexCoord1sv(GLbyte * pc) { glMultiTexCoord1svARB(*(GLenum *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_MultiTexCoord2dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 20); pc -= 4; } #endif glMultiTexCoord2dvARB(*(GLenum *) (pc + 16), (const GLdouble *) (pc + 0)); } void __glXDisp_MultiTexCoord2fvARB(GLbyte * pc) { glMultiTexCoord2fvARB(*(GLenum *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_MultiTexCoord2iv(GLbyte * pc) { glMultiTexCoord2ivARB(*(GLenum *) (pc + 0), (const GLint *) (pc + 4)); } void __glXDisp_MultiTexCoord2sv(GLbyte * pc) { glMultiTexCoord2svARB(*(GLenum *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_MultiTexCoord3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 28); pc -= 4; } #endif glMultiTexCoord3dvARB(*(GLenum *) (pc + 24), (const GLdouble *) (pc + 0)); } void __glXDisp_MultiTexCoord3fvARB(GLbyte * pc) { glMultiTexCoord3fvARB(*(GLenum *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_MultiTexCoord3iv(GLbyte * pc) { glMultiTexCoord3ivARB(*(GLenum *) (pc + 0), (const GLint *) (pc + 4)); } void __glXDisp_MultiTexCoord3sv(GLbyte * pc) { glMultiTexCoord3svARB(*(GLenum *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_MultiTexCoord4dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 36); pc -= 4; } #endif glMultiTexCoord4dvARB(*(GLenum *) (pc + 32), (const GLdouble *) (pc + 0)); } void __glXDisp_MultiTexCoord4fvARB(GLbyte * pc) { glMultiTexCoord4fvARB(*(GLenum *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_MultiTexCoord4iv(GLbyte * pc) { glMultiTexCoord4ivARB(*(GLenum *) (pc + 0), (const GLint *) (pc + 4)); } void __glXDisp_MultiTexCoord4sv(GLbyte * pc) { glMultiTexCoord4svARB(*(GLenum *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_CompressedTexImage1D(GLbyte * pc) { PFNGLCOMPRESSEDTEXIMAGE1DPROC CompressedTexImage1D = __glGetProcAddress("glCompressedTexImage1D"); const GLsizei imageSize = *(GLsizei *) (pc + 20); CompressedTexImage1D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLenum *) (pc + 8), *(GLsizei *) (pc + 12), *(GLint *) (pc + 16), imageSize, (const GLvoid *) (pc + 24)); } void __glXDisp_CompressedTexImage2D(GLbyte * pc) { PFNGLCOMPRESSEDTEXIMAGE2DPROC CompressedTexImage2D = __glGetProcAddress("glCompressedTexImage2D"); const GLsizei imageSize = *(GLsizei *) (pc + 24); CompressedTexImage2D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLenum *) (pc + 8), *(GLsizei *) (pc + 12), *(GLsizei *) (pc + 16), *(GLint *) (pc + 20), imageSize, (const GLvoid *) (pc + 28)); } void __glXDisp_CompressedTexImage3D(GLbyte * pc) { PFNGLCOMPRESSEDTEXIMAGE3DPROC CompressedTexImage3D = __glGetProcAddress("glCompressedTexImage3D"); const GLsizei imageSize = *(GLsizei *) (pc + 28); CompressedTexImage3D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLenum *) (pc + 8), *(GLsizei *) (pc + 12), *(GLsizei *) (pc + 16), *(GLsizei *) (pc + 20), *(GLint *) (pc + 24), imageSize, (const GLvoid *) (pc + 32)); } void __glXDisp_CompressedTexSubImage1D(GLbyte * pc) { PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC CompressedTexSubImage1D = __glGetProcAddress("glCompressedTexSubImage1D"); const GLsizei imageSize = *(GLsizei *) (pc + 20); CompressedTexSubImage1D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLint *) (pc + 8), *(GLsizei *) (pc + 12), *(GLenum *) (pc + 16), imageSize, (const GLvoid *) (pc + 24)); } void __glXDisp_CompressedTexSubImage2D(GLbyte * pc) { PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC CompressedTexSubImage2D = __glGetProcAddress("glCompressedTexSubImage2D"); const GLsizei imageSize = *(GLsizei *) (pc + 28); CompressedTexSubImage2D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLsizei *) (pc + 16), *(GLsizei *) (pc + 20), *(GLenum *) (pc + 24), imageSize, (const GLvoid *) (pc + 32)); } void __glXDisp_CompressedTexSubImage3D(GLbyte * pc) { PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC CompressedTexSubImage3D = __glGetProcAddress("glCompressedTexSubImage3D"); const GLsizei imageSize = *(GLsizei *) (pc + 36); CompressedTexSubImage3D(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLint *) (pc + 16), *(GLsizei *) (pc + 20), *(GLsizei *) (pc + 24), *(GLsizei *) (pc + 28), *(GLenum *) (pc + 32), imageSize, (const GLvoid *) (pc + 40)); } void __glXDisp_SampleCoverage(GLbyte * pc) { PFNGLSAMPLECOVERAGEPROC SampleCoverage = __glGetProcAddress("glSampleCoverage"); SampleCoverage(*(GLclampf *) (pc + 0), *(GLboolean *) (pc + 4)); } void __glXDisp_BlendFuncSeparate(GLbyte * pc) { PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate = __glGetProcAddress("glBlendFuncSeparate"); BlendFuncSeparate(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), *(GLenum *) (pc + 12)); } void __glXDisp_FogCoorddv(GLbyte * pc) { PFNGLFOGCOORDDVPROC FogCoorddv = __glGetProcAddress("glFogCoorddv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 8); pc -= 4; } #endif FogCoorddv((const GLdouble *) (pc + 0)); } void __glXDisp_PointParameterf(GLbyte * pc) { PFNGLPOINTPARAMETERFPROC PointParameterf = __glGetProcAddress("glPointParameterf"); PointParameterf(*(GLenum *) (pc + 0), *(GLfloat *) (pc + 4)); } void __glXDisp_PointParameterfv(GLbyte * pc) { PFNGLPOINTPARAMETERFVPROC PointParameterfv = __glGetProcAddress("glPointParameterfv"); const GLenum pname = *(GLenum *) (pc + 0); const GLfloat *params; params = (const GLfloat *) (pc + 4); PointParameterfv(pname, params); } void __glXDisp_PointParameteri(GLbyte * pc) { PFNGLPOINTPARAMETERIPROC PointParameteri = __glGetProcAddress("glPointParameteri"); PointParameteri(*(GLenum *) (pc + 0), *(GLint *) (pc + 4)); } void __glXDisp_PointParameteriv(GLbyte * pc) { PFNGLPOINTPARAMETERIVPROC PointParameteriv = __glGetProcAddress("glPointParameteriv"); const GLenum pname = *(GLenum *) (pc + 0); const GLint *params; params = (const GLint *) (pc + 4); PointParameteriv(pname, params); } void __glXDisp_SecondaryColor3bv(GLbyte * pc) { PFNGLSECONDARYCOLOR3BVPROC SecondaryColor3bv = __glGetProcAddress("glSecondaryColor3bv"); SecondaryColor3bv((const GLbyte *) (pc + 0)); } void __glXDisp_SecondaryColor3dv(GLbyte * pc) { PFNGLSECONDARYCOLOR3DVPROC SecondaryColor3dv = __glGetProcAddress("glSecondaryColor3dv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif SecondaryColor3dv((const GLdouble *) (pc + 0)); } void __glXDisp_SecondaryColor3iv(GLbyte * pc) { PFNGLSECONDARYCOLOR3IVPROC SecondaryColor3iv = __glGetProcAddress("glSecondaryColor3iv"); SecondaryColor3iv((const GLint *) (pc + 0)); } void __glXDisp_SecondaryColor3sv(GLbyte * pc) { PFNGLSECONDARYCOLOR3SVPROC SecondaryColor3sv = __glGetProcAddress("glSecondaryColor3sv"); SecondaryColor3sv((const GLshort *) (pc + 0)); } void __glXDisp_SecondaryColor3ubv(GLbyte * pc) { PFNGLSECONDARYCOLOR3UBVPROC SecondaryColor3ubv = __glGetProcAddress("glSecondaryColor3ubv"); SecondaryColor3ubv((const GLubyte *) (pc + 0)); } void __glXDisp_SecondaryColor3uiv(GLbyte * pc) { PFNGLSECONDARYCOLOR3UIVPROC SecondaryColor3uiv = __glGetProcAddress("glSecondaryColor3uiv"); SecondaryColor3uiv((const GLuint *) (pc + 0)); } void __glXDisp_SecondaryColor3usv(GLbyte * pc) { PFNGLSECONDARYCOLOR3USVPROC SecondaryColor3usv = __glGetProcAddress("glSecondaryColor3usv"); SecondaryColor3usv((const GLushort *) (pc + 0)); } void __glXDisp_WindowPos3fv(GLbyte * pc) { PFNGLWINDOWPOS3FVPROC WindowPos3fv = __glGetProcAddress("glWindowPos3fv"); WindowPos3fv((const GLfloat *) (pc + 0)); } void __glXDisp_BeginQuery(GLbyte * pc) { PFNGLBEGINQUERYPROC BeginQuery = __glGetProcAddress("glBeginQuery"); BeginQuery(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4)); } int __glXDisp_DeleteQueries(__GLXclientState * cl, GLbyte * pc) { PFNGLDELETEQUERIESPROC DeleteQueries = __glGetProcAddress("glDeleteQueries"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); DeleteQueries(n, (const GLuint *) (pc + 4)); error = Success; } return error; } void __glXDisp_EndQuery(GLbyte * pc) { PFNGLENDQUERYPROC EndQuery = __glGetProcAddress("glEndQuery"); EndQuery(*(GLenum *) (pc + 0)); } int __glXDisp_GenQueries(__GLXclientState * cl, GLbyte * pc) { PFNGLGENQUERIESPROC GenQueries = __glGetProcAddress("glGenQueries"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); GLuint answerBuffer[200]; GLuint *ids = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (ids == NULL) return BadAlloc; GenQueries(n, ids); __glXSendReply(cl->client, ids, n, 4, GL_TRUE, 0); error = Success; } return error; } int __glXDisp_GetQueryObjectiv(__GLXclientState * cl, GLbyte * pc) { PFNGLGETQUERYOBJECTIVPROC GetQueryObjectiv = __glGetProcAddress("glGetQueryObjectiv"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetQueryObjectiv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); GetQueryObjectiv(*(GLuint *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetQueryObjectuiv(__GLXclientState * cl, GLbyte * pc) { PFNGLGETQUERYOBJECTUIVPROC GetQueryObjectuiv = __glGetProcAddress("glGetQueryObjectuiv"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetQueryObjectuiv_size(pname); GLuint answerBuffer[200]; GLuint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); GetQueryObjectuiv(*(GLuint *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetQueryiv(__GLXclientState * cl, GLbyte * pc) { PFNGLGETQUERYIVPROC GetQueryiv = __glGetProcAddress("glGetQueryiv"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetQueryiv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); GetQueryiv(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_IsQuery(__GLXclientState * cl, GLbyte * pc) { PFNGLISQUERYPROC IsQuery = __glGetProcAddress("glIsQuery"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = IsQuery(*(GLuint *) (pc + 0)); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDisp_BlendEquationSeparate(GLbyte * pc) { PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate = __glGetProcAddress("glBlendEquationSeparate"); BlendEquationSeparate(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4)); } void __glXDisp_DrawBuffers(GLbyte * pc) { PFNGLDRAWBUFFERSPROC DrawBuffers = __glGetProcAddress("glDrawBuffers"); const GLsizei n = *(GLsizei *) (pc + 0); DrawBuffers(n, (const GLenum *) (pc + 4)); } void __glXDisp_VertexAttrib1dv(GLbyte * pc) { PFNGLVERTEXATTRIB1DVPROC VertexAttrib1dv = __glGetProcAddress("glVertexAttrib1dv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 12); pc -= 4; } #endif VertexAttrib1dv(*(GLuint *) (pc + 0), (const GLdouble *) (pc + 4)); } void __glXDisp_VertexAttrib1sv(GLbyte * pc) { PFNGLVERTEXATTRIB1SVPROC VertexAttrib1sv = __glGetProcAddress("glVertexAttrib1sv"); VertexAttrib1sv(*(GLuint *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_VertexAttrib2dv(GLbyte * pc) { PFNGLVERTEXATTRIB2DVPROC VertexAttrib2dv = __glGetProcAddress("glVertexAttrib2dv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 20); pc -= 4; } #endif VertexAttrib2dv(*(GLuint *) (pc + 0), (const GLdouble *) (pc + 4)); } void __glXDisp_VertexAttrib2sv(GLbyte * pc) { PFNGLVERTEXATTRIB2SVPROC VertexAttrib2sv = __glGetProcAddress("glVertexAttrib2sv"); VertexAttrib2sv(*(GLuint *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_VertexAttrib3dv(GLbyte * pc) { PFNGLVERTEXATTRIB3DVPROC VertexAttrib3dv = __glGetProcAddress("glVertexAttrib3dv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 28); pc -= 4; } #endif VertexAttrib3dv(*(GLuint *) (pc + 0), (const GLdouble *) (pc + 4)); } void __glXDisp_VertexAttrib3sv(GLbyte * pc) { PFNGLVERTEXATTRIB3SVPROC VertexAttrib3sv = __glGetProcAddress("glVertexAttrib3sv"); VertexAttrib3sv(*(GLuint *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_VertexAttrib4Nbv(GLbyte * pc) { PFNGLVERTEXATTRIB4NBVPROC VertexAttrib4Nbv = __glGetProcAddress("glVertexAttrib4Nbv"); VertexAttrib4Nbv(*(GLuint *) (pc + 0), (const GLbyte *) (pc + 4)); } void __glXDisp_VertexAttrib4Niv(GLbyte * pc) { PFNGLVERTEXATTRIB4NIVPROC VertexAttrib4Niv = __glGetProcAddress("glVertexAttrib4Niv"); VertexAttrib4Niv(*(GLuint *) (pc + 0), (const GLint *) (pc + 4)); } void __glXDisp_VertexAttrib4Nsv(GLbyte * pc) { PFNGLVERTEXATTRIB4NSVPROC VertexAttrib4Nsv = __glGetProcAddress("glVertexAttrib4Nsv"); VertexAttrib4Nsv(*(GLuint *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_VertexAttrib4Nubv(GLbyte * pc) { PFNGLVERTEXATTRIB4NUBVPROC VertexAttrib4Nubv = __glGetProcAddress("glVertexAttrib4Nubv"); VertexAttrib4Nubv(*(GLuint *) (pc + 0), (const GLubyte *) (pc + 4)); } void __glXDisp_VertexAttrib4Nuiv(GLbyte * pc) { PFNGLVERTEXATTRIB4NUIVPROC VertexAttrib4Nuiv = __glGetProcAddress("glVertexAttrib4Nuiv"); VertexAttrib4Nuiv(*(GLuint *) (pc + 0), (const GLuint *) (pc + 4)); } void __glXDisp_VertexAttrib4Nusv(GLbyte * pc) { PFNGLVERTEXATTRIB4NUSVPROC VertexAttrib4Nusv = __glGetProcAddress("glVertexAttrib4Nusv"); VertexAttrib4Nusv(*(GLuint *) (pc + 0), (const GLushort *) (pc + 4)); } void __glXDisp_VertexAttrib4bv(GLbyte * pc) { PFNGLVERTEXATTRIB4BVPROC VertexAttrib4bv = __glGetProcAddress("glVertexAttrib4bv"); VertexAttrib4bv(*(GLuint *) (pc + 0), (const GLbyte *) (pc + 4)); } void __glXDisp_VertexAttrib4dv(GLbyte * pc) { PFNGLVERTEXATTRIB4DVPROC VertexAttrib4dv = __glGetProcAddress("glVertexAttrib4dv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 36); pc -= 4; } #endif VertexAttrib4dv(*(GLuint *) (pc + 0), (const GLdouble *) (pc + 4)); } void __glXDisp_VertexAttrib4iv(GLbyte * pc) { PFNGLVERTEXATTRIB4IVPROC VertexAttrib4iv = __glGetProcAddress("glVertexAttrib4iv"); VertexAttrib4iv(*(GLuint *) (pc + 0), (const GLint *) (pc + 4)); } void __glXDisp_VertexAttrib4sv(GLbyte * pc) { PFNGLVERTEXATTRIB4SVPROC VertexAttrib4sv = __glGetProcAddress("glVertexAttrib4sv"); VertexAttrib4sv(*(GLuint *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_VertexAttrib4ubv(GLbyte * pc) { PFNGLVERTEXATTRIB4UBVPROC VertexAttrib4ubv = __glGetProcAddress("glVertexAttrib4ubv"); VertexAttrib4ubv(*(GLuint *) (pc + 0), (const GLubyte *) (pc + 4)); } void __glXDisp_VertexAttrib4uiv(GLbyte * pc) { PFNGLVERTEXATTRIB4UIVPROC VertexAttrib4uiv = __glGetProcAddress("glVertexAttrib4uiv"); VertexAttrib4uiv(*(GLuint *) (pc + 0), (const GLuint *) (pc + 4)); } void __glXDisp_VertexAttrib4usv(GLbyte * pc) { PFNGLVERTEXATTRIB4USVPROC VertexAttrib4usv = __glGetProcAddress("glVertexAttrib4usv"); VertexAttrib4usv(*(GLuint *) (pc + 0), (const GLushort *) (pc + 4)); } void __glXDisp_ClampColor(GLbyte * pc) { PFNGLCLAMPCOLORPROC ClampColor = __glGetProcAddress("glClampColor"); ClampColor(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4)); } void __glXDisp_BindProgramARB(GLbyte * pc) { PFNGLBINDPROGRAMARBPROC BindProgramARB = __glGetProcAddress("glBindProgramARB"); BindProgramARB(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4)); } int __glXDisp_DeleteProgramsARB(__GLXclientState * cl, GLbyte * pc) { PFNGLDELETEPROGRAMSARBPROC DeleteProgramsARB = __glGetProcAddress("glDeleteProgramsARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); DeleteProgramsARB(n, (const GLuint *) (pc + 4)); error = Success; } return error; } int __glXDisp_GenProgramsARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGENPROGRAMSARBPROC GenProgramsARB = __glGetProcAddress("glGenProgramsARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); GLuint answerBuffer[200]; GLuint *programs = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (programs == NULL) return BadAlloc; GenProgramsARB(n, programs); __glXSendReply(cl->client, programs, n, 4, GL_TRUE, 0); error = Success; } return error; } int __glXDisp_GetProgramEnvParameterdvARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGETPROGRAMENVPARAMETERDVARBPROC GetProgramEnvParameterdvARB = __glGetProcAddress("glGetProgramEnvParameterdvARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLdouble params[4]; GetProgramEnvParameterdvARB(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4), params); __glXSendReply(cl->client, params, 4, 8, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetProgramEnvParameterfvARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGETPROGRAMENVPARAMETERFVARBPROC GetProgramEnvParameterfvARB = __glGetProcAddress("glGetProgramEnvParameterfvARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLfloat params[4]; GetProgramEnvParameterfvARB(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4), params); __glXSendReply(cl->client, params, 4, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetProgramLocalParameterdvARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC GetProgramLocalParameterdvARB = __glGetProcAddress("glGetProgramLocalParameterdvARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLdouble params[4]; GetProgramLocalParameterdvARB(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4), params); __glXSendReply(cl->client, params, 4, 8, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetProgramLocalParameterfvARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC GetProgramLocalParameterfvARB = __glGetProcAddress("glGetProgramLocalParameterfvARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLfloat params[4]; GetProgramLocalParameterfvARB(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4), params); __glXSendReply(cl->client, params, 4, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetProgramivARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGETPROGRAMIVARBPROC GetProgramivARB = __glGetProcAddress("glGetProgramivARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = *(GLenum *) (pc + 4); const GLuint compsize = __glGetProgramivARB_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); GetProgramivARB(*(GLenum *) (pc + 0), pname, params); __glXSendReply(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_IsProgramARB(__GLXclientState * cl, GLbyte * pc) { PFNGLISPROGRAMARBPROC IsProgramARB = __glGetProcAddress("glIsProgramARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = IsProgramARB(*(GLuint *) (pc + 0)); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDisp_ProgramEnvParameter4dvARB(GLbyte * pc) { PFNGLPROGRAMENVPARAMETER4DVARBPROC ProgramEnvParameter4dvARB = __glGetProcAddress("glProgramEnvParameter4dvARB"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 40); pc -= 4; } #endif ProgramEnvParameter4dvARB(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4), (const GLdouble *) (pc + 8)); } void __glXDisp_ProgramEnvParameter4fvARB(GLbyte * pc) { PFNGLPROGRAMENVPARAMETER4FVARBPROC ProgramEnvParameter4fvARB = __glGetProcAddress("glProgramEnvParameter4fvARB"); ProgramEnvParameter4fvARB(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4), (const GLfloat *) (pc + 8)); } void __glXDisp_ProgramLocalParameter4dvARB(GLbyte * pc) { PFNGLPROGRAMLOCALPARAMETER4DVARBPROC ProgramLocalParameter4dvARB = __glGetProcAddress("glProgramLocalParameter4dvARB"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 40); pc -= 4; } #endif ProgramLocalParameter4dvARB(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4), (const GLdouble *) (pc + 8)); } void __glXDisp_ProgramLocalParameter4fvARB(GLbyte * pc) { PFNGLPROGRAMLOCALPARAMETER4FVARBPROC ProgramLocalParameter4fvARB = __glGetProcAddress("glProgramLocalParameter4fvARB"); ProgramLocalParameter4fvARB(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4), (const GLfloat *) (pc + 8)); } void __glXDisp_ProgramStringARB(GLbyte * pc) { PFNGLPROGRAMSTRINGARBPROC ProgramStringARB = __glGetProcAddress("glProgramStringARB"); const GLsizei len = *(GLsizei *) (pc + 8); ProgramStringARB(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), len, (const GLvoid *) (pc + 12)); } void __glXDisp_VertexAttrib1fvARB(GLbyte * pc) { PFNGLVERTEXATTRIB1FVARBPROC VertexAttrib1fvARB = __glGetProcAddress("glVertexAttrib1fvARB"); VertexAttrib1fvARB(*(GLuint *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_VertexAttrib2fvARB(GLbyte * pc) { PFNGLVERTEXATTRIB2FVARBPROC VertexAttrib2fvARB = __glGetProcAddress("glVertexAttrib2fvARB"); VertexAttrib2fvARB(*(GLuint *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_VertexAttrib3fvARB(GLbyte * pc) { PFNGLVERTEXATTRIB3FVARBPROC VertexAttrib3fvARB = __glGetProcAddress("glVertexAttrib3fvARB"); VertexAttrib3fvARB(*(GLuint *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_VertexAttrib4fvARB(GLbyte * pc) { PFNGLVERTEXATTRIB4FVARBPROC VertexAttrib4fvARB = __glGetProcAddress("glVertexAttrib4fvARB"); VertexAttrib4fvARB(*(GLuint *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_BindFramebuffer(GLbyte * pc) { PFNGLBINDFRAMEBUFFERPROC BindFramebuffer = __glGetProcAddress("glBindFramebuffer"); BindFramebuffer(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4)); } void __glXDisp_BindRenderbuffer(GLbyte * pc) { PFNGLBINDRENDERBUFFERPROC BindRenderbuffer = __glGetProcAddress("glBindRenderbuffer"); BindRenderbuffer(*(GLenum *) (pc + 0), *(GLuint *) (pc + 4)); } void __glXDisp_BlitFramebuffer(GLbyte * pc) { PFNGLBLITFRAMEBUFFERPROC BlitFramebuffer = __glGetProcAddress("glBlitFramebuffer"); BlitFramebuffer(*(GLint *) (pc + 0), *(GLint *) (pc + 4), *(GLint *) (pc + 8), *(GLint *) (pc + 12), *(GLint *) (pc + 16), *(GLint *) (pc + 20), *(GLint *) (pc + 24), *(GLint *) (pc + 28), *(GLbitfield *) (pc + 32), *(GLenum *) (pc + 36)); } int __glXDisp_CheckFramebufferStatus(__GLXclientState * cl, GLbyte * pc) { PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus = __glGetProcAddress("glCheckFramebufferStatus"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLenum retval; retval = CheckFramebufferStatus(*(GLenum *) (pc + 0)); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDisp_DeleteFramebuffers(GLbyte * pc) { PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers = __glGetProcAddress("glDeleteFramebuffers"); const GLsizei n = *(GLsizei *) (pc + 0); DeleteFramebuffers(n, (const GLuint *) (pc + 4)); } void __glXDisp_DeleteRenderbuffers(GLbyte * pc) { PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers = __glGetProcAddress("glDeleteRenderbuffers"); const GLsizei n = *(GLsizei *) (pc + 0); DeleteRenderbuffers(n, (const GLuint *) (pc + 4)); } void __glXDisp_FramebufferRenderbuffer(GLbyte * pc) { PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer = __glGetProcAddress("glFramebufferRenderbuffer"); FramebufferRenderbuffer(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), *(GLuint *) (pc + 12)); } void __glXDisp_FramebufferTexture1D(GLbyte * pc) { PFNGLFRAMEBUFFERTEXTURE1DPROC FramebufferTexture1D = __glGetProcAddress("glFramebufferTexture1D"); FramebufferTexture1D(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), *(GLuint *) (pc + 12), *(GLint *) (pc + 16)); } void __glXDisp_FramebufferTexture2D(GLbyte * pc) { PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D = __glGetProcAddress("glFramebufferTexture2D"); FramebufferTexture2D(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), *(GLuint *) (pc + 12), *(GLint *) (pc + 16)); } void __glXDisp_FramebufferTexture3D(GLbyte * pc) { PFNGLFRAMEBUFFERTEXTURE3DPROC FramebufferTexture3D = __glGetProcAddress("glFramebufferTexture3D"); FramebufferTexture3D(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), *(GLuint *) (pc + 12), *(GLint *) (pc + 16), *(GLint *) (pc + 20)); } void __glXDisp_FramebufferTextureLayer(GLbyte * pc) { PFNGLFRAMEBUFFERTEXTURELAYERPROC FramebufferTextureLayer = __glGetProcAddress("glFramebufferTextureLayer"); FramebufferTextureLayer(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLuint *) (pc + 8), *(GLint *) (pc + 12), *(GLint *) (pc + 16)); } int __glXDisp_GenFramebuffers(__GLXclientState * cl, GLbyte * pc) { PFNGLGENFRAMEBUFFERSPROC GenFramebuffers = __glGetProcAddress("glGenFramebuffers"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); GLuint answerBuffer[200]; GLuint *framebuffers = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (framebuffers == NULL) return BadAlloc; GenFramebuffers(n, framebuffers); __glXSendReply(cl->client, framebuffers, n, 4, GL_TRUE, 0); error = Success; } return error; } int __glXDisp_GenRenderbuffers(__GLXclientState * cl, GLbyte * pc) { PFNGLGENRENDERBUFFERSPROC GenRenderbuffers = __glGetProcAddress("glGenRenderbuffers"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = *(GLsizei *) (pc + 0); GLuint answerBuffer[200]; GLuint *renderbuffers = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (renderbuffers == NULL) return BadAlloc; GenRenderbuffers(n, renderbuffers); __glXSendReply(cl->client, renderbuffers, n, 4, GL_TRUE, 0); error = Success; } return error; } void __glXDisp_GenerateMipmap(GLbyte * pc) { PFNGLGENERATEMIPMAPPROC GenerateMipmap = __glGetProcAddress("glGenerateMipmap"); GenerateMipmap(*(GLenum *) (pc + 0)); } int __glXDisp_GetFramebufferAttachmentParameteriv(__GLXclientState * cl, GLbyte * pc) { PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetFramebufferAttachmentParameteriv = __glGetProcAddress("glGetFramebufferAttachmentParameteriv"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLint params[1]; GetFramebufferAttachmentParameteriv(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), params); __glXSendReply(cl->client, params, 1, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_GetRenderbufferParameteriv(__GLXclientState * cl, GLbyte * pc) { PFNGLGETRENDERBUFFERPARAMETERIVPROC GetRenderbufferParameteriv = __glGetProcAddress("glGetRenderbufferParameteriv"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLint params[1]; GetRenderbufferParameteriv(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), params); __glXSendReply(cl->client, params, 1, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDisp_IsFramebuffer(__GLXclientState * cl, GLbyte * pc) { PFNGLISFRAMEBUFFERPROC IsFramebuffer = __glGetProcAddress("glIsFramebuffer"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = IsFramebuffer(*(GLuint *) (pc + 0)); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } int __glXDisp_IsRenderbuffer(__GLXclientState * cl, GLbyte * pc) { PFNGLISRENDERBUFFERPROC IsRenderbuffer = __glGetProcAddress("glIsRenderbuffer"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = IsRenderbuffer(*(GLuint *) (pc + 0)); __glXSendReply(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDisp_RenderbufferStorage(GLbyte * pc) { PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage = __glGetProcAddress("glRenderbufferStorage"); RenderbufferStorage(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLsizei *) (pc + 8), *(GLsizei *) (pc + 12)); } void __glXDisp_RenderbufferStorageMultisample(GLbyte * pc) { PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC RenderbufferStorageMultisample = __glGetProcAddress("glRenderbufferStorageMultisample"); RenderbufferStorageMultisample(*(GLenum *) (pc + 0), *(GLsizei *) (pc + 4), *(GLenum *) (pc + 8), *(GLsizei *) (pc + 12), *(GLsizei *) (pc + 16)); } void __glXDisp_SecondaryColor3fvEXT(GLbyte * pc) { PFNGLSECONDARYCOLOR3FVEXTPROC SecondaryColor3fvEXT = __glGetProcAddress("glSecondaryColor3fvEXT"); SecondaryColor3fvEXT((const GLfloat *) (pc + 0)); } void __glXDisp_FogCoordfvEXT(GLbyte * pc) { PFNGLFOGCOORDFVEXTPROC FogCoordfvEXT = __glGetProcAddress("glFogCoordfvEXT"); FogCoordfvEXT((const GLfloat *) (pc + 0)); } void __glXDisp_VertexAttrib1dvNV(GLbyte * pc) { PFNGLVERTEXATTRIB1DVNVPROC VertexAttrib1dvNV = __glGetProcAddress("glVertexAttrib1dvNV"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 12); pc -= 4; } #endif VertexAttrib1dvNV(*(GLuint *) (pc + 0), (const GLdouble *) (pc + 4)); } void __glXDisp_VertexAttrib1fvNV(GLbyte * pc) { PFNGLVERTEXATTRIB1FVNVPROC VertexAttrib1fvNV = __glGetProcAddress("glVertexAttrib1fvNV"); VertexAttrib1fvNV(*(GLuint *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_VertexAttrib1svNV(GLbyte * pc) { PFNGLVERTEXATTRIB1SVNVPROC VertexAttrib1svNV = __glGetProcAddress("glVertexAttrib1svNV"); VertexAttrib1svNV(*(GLuint *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_VertexAttrib2dvNV(GLbyte * pc) { PFNGLVERTEXATTRIB2DVNVPROC VertexAttrib2dvNV = __glGetProcAddress("glVertexAttrib2dvNV"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 20); pc -= 4; } #endif VertexAttrib2dvNV(*(GLuint *) (pc + 0), (const GLdouble *) (pc + 4)); } void __glXDisp_VertexAttrib2fvNV(GLbyte * pc) { PFNGLVERTEXATTRIB2FVNVPROC VertexAttrib2fvNV = __glGetProcAddress("glVertexAttrib2fvNV"); VertexAttrib2fvNV(*(GLuint *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_VertexAttrib2svNV(GLbyte * pc) { PFNGLVERTEXATTRIB2SVNVPROC VertexAttrib2svNV = __glGetProcAddress("glVertexAttrib2svNV"); VertexAttrib2svNV(*(GLuint *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_VertexAttrib3dvNV(GLbyte * pc) { PFNGLVERTEXATTRIB3DVNVPROC VertexAttrib3dvNV = __glGetProcAddress("glVertexAttrib3dvNV"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 28); pc -= 4; } #endif VertexAttrib3dvNV(*(GLuint *) (pc + 0), (const GLdouble *) (pc + 4)); } void __glXDisp_VertexAttrib3fvNV(GLbyte * pc) { PFNGLVERTEXATTRIB3FVNVPROC VertexAttrib3fvNV = __glGetProcAddress("glVertexAttrib3fvNV"); VertexAttrib3fvNV(*(GLuint *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_VertexAttrib3svNV(GLbyte * pc) { PFNGLVERTEXATTRIB3SVNVPROC VertexAttrib3svNV = __glGetProcAddress("glVertexAttrib3svNV"); VertexAttrib3svNV(*(GLuint *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_VertexAttrib4dvNV(GLbyte * pc) { PFNGLVERTEXATTRIB4DVNVPROC VertexAttrib4dvNV = __glGetProcAddress("glVertexAttrib4dvNV"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 36); pc -= 4; } #endif VertexAttrib4dvNV(*(GLuint *) (pc + 0), (const GLdouble *) (pc + 4)); } void __glXDisp_VertexAttrib4fvNV(GLbyte * pc) { PFNGLVERTEXATTRIB4FVNVPROC VertexAttrib4fvNV = __glGetProcAddress("glVertexAttrib4fvNV"); VertexAttrib4fvNV(*(GLuint *) (pc + 0), (const GLfloat *) (pc + 4)); } void __glXDisp_VertexAttrib4svNV(GLbyte * pc) { PFNGLVERTEXATTRIB4SVNVPROC VertexAttrib4svNV = __glGetProcAddress("glVertexAttrib4svNV"); VertexAttrib4svNV(*(GLuint *) (pc + 0), (const GLshort *) (pc + 4)); } void __glXDisp_VertexAttrib4ubvNV(GLbyte * pc) { PFNGLVERTEXATTRIB4UBVNVPROC VertexAttrib4ubvNV = __glGetProcAddress("glVertexAttrib4ubvNV"); VertexAttrib4ubvNV(*(GLuint *) (pc + 0), (const GLubyte *) (pc + 4)); } void __glXDisp_VertexAttribs1dvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS1DVNVPROC VertexAttribs1dvNV = __glGetProcAddress("glVertexAttribs1dvNV"); const GLsizei n = *(GLsizei *) (pc + 4); #ifdef __GLX_ALIGN64 const GLuint cmdlen = 12 + __GLX_PAD((n * 8)) - 4; if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, cmdlen); pc -= 4; } #endif VertexAttribs1dvNV(*(GLuint *) (pc + 0), n, (const GLdouble *) (pc + 8)); } void __glXDisp_VertexAttribs1fvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS1FVNVPROC VertexAttribs1fvNV = __glGetProcAddress("glVertexAttribs1fvNV"); const GLsizei n = *(GLsizei *) (pc + 4); VertexAttribs1fvNV(*(GLuint *) (pc + 0), n, (const GLfloat *) (pc + 8)); } void __glXDisp_VertexAttribs1svNV(GLbyte * pc) { PFNGLVERTEXATTRIBS1SVNVPROC VertexAttribs1svNV = __glGetProcAddress("glVertexAttribs1svNV"); const GLsizei n = *(GLsizei *) (pc + 4); VertexAttribs1svNV(*(GLuint *) (pc + 0), n, (const GLshort *) (pc + 8)); } void __glXDisp_VertexAttribs2dvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS2DVNVPROC VertexAttribs2dvNV = __glGetProcAddress("glVertexAttribs2dvNV"); const GLsizei n = *(GLsizei *) (pc + 4); #ifdef __GLX_ALIGN64 const GLuint cmdlen = 12 + __GLX_PAD((n * 16)) - 4; if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, cmdlen); pc -= 4; } #endif VertexAttribs2dvNV(*(GLuint *) (pc + 0), n, (const GLdouble *) (pc + 8)); } void __glXDisp_VertexAttribs2fvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS2FVNVPROC VertexAttribs2fvNV = __glGetProcAddress("glVertexAttribs2fvNV"); const GLsizei n = *(GLsizei *) (pc + 4); VertexAttribs2fvNV(*(GLuint *) (pc + 0), n, (const GLfloat *) (pc + 8)); } void __glXDisp_VertexAttribs2svNV(GLbyte * pc) { PFNGLVERTEXATTRIBS2SVNVPROC VertexAttribs2svNV = __glGetProcAddress("glVertexAttribs2svNV"); const GLsizei n = *(GLsizei *) (pc + 4); VertexAttribs2svNV(*(GLuint *) (pc + 0), n, (const GLshort *) (pc + 8)); } void __glXDisp_VertexAttribs3dvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS3DVNVPROC VertexAttribs3dvNV = __glGetProcAddress("glVertexAttribs3dvNV"); const GLsizei n = *(GLsizei *) (pc + 4); #ifdef __GLX_ALIGN64 const GLuint cmdlen = 12 + __GLX_PAD((n * 24)) - 4; if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, cmdlen); pc -= 4; } #endif VertexAttribs3dvNV(*(GLuint *) (pc + 0), n, (const GLdouble *) (pc + 8)); } void __glXDisp_VertexAttribs3fvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS3FVNVPROC VertexAttribs3fvNV = __glGetProcAddress("glVertexAttribs3fvNV"); const GLsizei n = *(GLsizei *) (pc + 4); VertexAttribs3fvNV(*(GLuint *) (pc + 0), n, (const GLfloat *) (pc + 8)); } void __glXDisp_VertexAttribs3svNV(GLbyte * pc) { PFNGLVERTEXATTRIBS3SVNVPROC VertexAttribs3svNV = __glGetProcAddress("glVertexAttribs3svNV"); const GLsizei n = *(GLsizei *) (pc + 4); VertexAttribs3svNV(*(GLuint *) (pc + 0), n, (const GLshort *) (pc + 8)); } void __glXDisp_VertexAttribs4dvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS4DVNVPROC VertexAttribs4dvNV = __glGetProcAddress("glVertexAttribs4dvNV"); const GLsizei n = *(GLsizei *) (pc + 4); #ifdef __GLX_ALIGN64 const GLuint cmdlen = 12 + __GLX_PAD((n * 32)) - 4; if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, cmdlen); pc -= 4; } #endif VertexAttribs4dvNV(*(GLuint *) (pc + 0), n, (const GLdouble *) (pc + 8)); } void __glXDisp_VertexAttribs4fvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS4FVNVPROC VertexAttribs4fvNV = __glGetProcAddress("glVertexAttribs4fvNV"); const GLsizei n = *(GLsizei *) (pc + 4); VertexAttribs4fvNV(*(GLuint *) (pc + 0), n, (const GLfloat *) (pc + 8)); } void __glXDisp_VertexAttribs4svNV(GLbyte * pc) { PFNGLVERTEXATTRIBS4SVNVPROC VertexAttribs4svNV = __glGetProcAddress("glVertexAttribs4svNV"); const GLsizei n = *(GLsizei *) (pc + 4); VertexAttribs4svNV(*(GLuint *) (pc + 0), n, (const GLshort *) (pc + 8)); } void __glXDisp_VertexAttribs4ubvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS4UBVNVPROC VertexAttribs4ubvNV = __glGetProcAddress("glVertexAttribs4ubvNV"); const GLsizei n = *(GLsizei *) (pc + 4); VertexAttribs4ubvNV(*(GLuint *) (pc + 0), n, (const GLubyte *) (pc + 8)); } void __glXDisp_ActiveStencilFaceEXT(GLbyte * pc) { PFNGLACTIVESTENCILFACEEXTPROC ActiveStencilFaceEXT = __glGetProcAddress("glActiveStencilFaceEXT"); ActiveStencilFaceEXT(*(GLenum *) (pc + 0)); } xorg-server-1.20.13/glx/indirect_dispatch.h0000644000175000017500000025422014100573756015522 00000000000000/* DO NOT EDIT - This file generated automatically by glX_proto_recv.py (from Mesa) script */ /* * (C) Copyright IBM Corporation 2005 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #if !defined( _INDIRECT_DISPATCH_H_ ) #define _INDIRECT_DISPATCH_H_ #include struct __GLXclientStateRec; extern _X_HIDDEN void __glXDisp_MapGrid1d(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MapGrid1d(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MapGrid1f(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MapGrid1f(GLbyte * pc); extern _X_HIDDEN int __glXDisp_NewList(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_NewList(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_LoadIdentity(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LoadIdentity(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ConvolutionFilter1D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ConvolutionFilter1D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_RasterPos3dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos3dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord1iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord1iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord4sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord4sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib3dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib3dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4ubvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4ubvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Histogram(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Histogram(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetMapfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMapfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_RasterPos4dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos4dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PolygonStipple(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PolygonStipple(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord1dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord1dv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetPixelMapfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetPixelMapfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Color3uiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color3uiv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_IsEnabled(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_IsEnabled(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib4svNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4svNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_EvalCoord2fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_EvalCoord2fv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_DestroyPixmap(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DestroyPixmap(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_FramebufferTexture1D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_FramebufferTexture1D(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetMapiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMapiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_SwapBuffers(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_SwapBuffers(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Indexubv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Indexubv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_Render(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_Render(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_TexImage3D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexImage3D(GLbyte * pc); extern _X_HIDDEN int __glXDisp_MakeContextCurrent(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_MakeContextCurrent(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetFBConfigs(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetFBConfigs(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib1sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib1sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color3ubv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color3ubv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Vertex3dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex3dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_LightModeliv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LightModeliv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttribs1dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs1dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Normal3bv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Normal3bv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_VendorPrivate(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_VendorPrivate(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_TexGeniv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexGeniv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Vertex3iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex3iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_RenderbufferStorage(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RenderbufferStorage(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CopyConvolutionFilter1D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CopyConvolutionFilter1D(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GenQueries(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GenQueries(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_BlendColor(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BlendColor(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CompressedTexImage3D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CompressedTexImage3D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Scalef(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Scalef(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Normal3iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Normal3iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_SecondaryColor3dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_SecondaryColor3dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PassThrough(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PassThrough(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Viewport(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Viewport(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CopyTexSubImage2D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CopyTexSubImage2D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_DepthRange(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_DepthRange(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetQueryiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetQueryiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ResetHistogram(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ResetHistogram(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CompressedTexSubImage2D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CompressedTexSubImage2D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_SecondaryColor3uiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_SecondaryColor3uiv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord2sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord2sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Vertex4dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex4dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4Nbv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4Nbv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttribs2svNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs2svNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color3sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color3sv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetConvolutionParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetConvolutionParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetConvolutionParameterivEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetConvolutionParameterivEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Vertex2dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex2dv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetVisualConfigs(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetVisualConfigs(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_DeleteRenderbuffers(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_DeleteRenderbuffers(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord1fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord1fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord3iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord3iv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_CopyContext(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CopyContext(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib4usv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4usv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color3fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color3fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord4sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord4sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PointSize(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PointSize(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PopName(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PopName(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib2dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib2dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4Nusv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4Nusv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Vertex4sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex4sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ClampColor(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ClampColor(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetTexEnvfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetTexEnvfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_LineStipple(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LineStipple(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexEnvi(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexEnvi(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetClipPlane(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetClipPlane(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttribs3dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs3dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttribs4fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs4fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Scaled(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Scaled(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CallLists(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CallLists(GLbyte * pc); extern _X_HIDDEN void __glXDisp_AlphaFunc(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_AlphaFunc(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord2iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord2iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Rotated(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Rotated(GLbyte * pc); extern _X_HIDDEN int __glXDisp_ReadPixels(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_ReadPixels(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_EdgeFlagv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_EdgeFlagv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CompressedTexSubImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CompressedTexSubImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexParameterf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexParameterf(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexParameteri(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexParameteri(GLbyte * pc); extern _X_HIDDEN int __glXDisp_DestroyContext(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DestroyContext(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_DrawPixels(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_DrawPixels(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord3sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord3sv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GenLists(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GenLists(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_MapGrid2d(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MapGrid2d(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MapGrid2f(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MapGrid2f(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Scissor(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Scissor(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Fogf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Fogf(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexSubImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexSubImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color4usv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color4usv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Fogi(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Fogi(GLbyte * pc); extern _X_HIDDEN void __glXDisp_RasterPos3iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos3iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PixelMapfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PixelMapfv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color3usv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color3usv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord2iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord2iv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_AreTexturesResident(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_AreTexturesResident(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_AreTexturesResidentEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_AreTexturesResidentEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Color3bv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color3bv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib2fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib2fvARB(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetProgramLocalParameterfvARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetProgramLocalParameterfvARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ColorTable(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ColorTable(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Accum(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Accum(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetTexImage(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetTexImage(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ConvolutionFilter2D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ConvolutionFilter2D(GLbyte * pc); extern _X_HIDDEN int __glXDisp_Finish(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_Finish(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ClearStencil(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ClearStencil(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttribs4ubvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs4ubvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ConvolutionParameteriv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ConvolutionParameteriv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_RasterPos2fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos2fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord1fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord1fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord4dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord4dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ProgramEnvParameter4fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ProgramEnvParameter4fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDisp_RasterPos4fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos4fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ClearIndex(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ClearIndex(GLbyte * pc); extern _X_HIDDEN void __glXDisp_LoadMatrixd(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LoadMatrixd(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PushMatrix(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PushMatrix(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ConvolutionParameterfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ConvolutionParameterfv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetTexGendv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetTexGendv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_EndList(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_EndList(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_EvalCoord1fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_EvalCoord1fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_EvalMesh2(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_EvalMesh2(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Vertex4fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex4fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttribs3fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs3fvNV(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetProgramEnvParameterdvARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetProgramEnvParameterdvARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetFBConfigsSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetFBConfigsSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_BindFramebuffer(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BindFramebuffer(GLbyte * pc); extern _X_HIDDEN int __glXDisp_CreateNewContext(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CreateNewContext(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetMinmax(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMinmax(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetMinmaxEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMinmaxEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_BlendFuncSeparate(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BlendFuncSeparate(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Normal3fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Normal3fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ProgramEnvParameter4dvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ProgramEnvParameter4dvARB(GLbyte * pc); extern _X_HIDDEN void __glXDisp_End(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_End(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttribs3svNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs3svNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttribs2dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs2dvNV(GLbyte * pc); extern _X_HIDDEN int __glXDisp_CreateContextAttribsARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CreateContextAttribsARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_BindTexture(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BindTexture(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib2sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib2sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexSubImage2D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexSubImage2D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexGenfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexGenfv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_DrawBuffers(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_DrawBuffers(GLbyte * pc); extern _X_HIDDEN int __glXDisp_CreateContextWithConfigSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CreateContextWithConfigSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_CopySubBufferMESA(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CopySubBufferMESA(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_BlendEquation(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BlendEquation(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetError(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetError(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_TexCoord3dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord3dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Indexdv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Indexdv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PushName(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PushName(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib1dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib1dv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_CreateGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CreateGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_IsRenderbuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_IsRenderbuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_DepthMask(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_DepthMask(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color4iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color4iv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetMaterialiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMaterialiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_StencilOp(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_StencilOp(GLbyte * pc); extern _X_HIDDEN void __glXDisp_FramebufferTextureLayer(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_FramebufferTextureLayer(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Ortho(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Ortho(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexEnvfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexEnvfv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_QueryServerString(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_QueryServerString(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_LoadMatrixf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LoadMatrixf(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color4bv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color4bv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetCompressedTexImage(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetCompressedTexImage(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib2fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib2fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ProgramLocalParameter4dvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ProgramLocalParameter4dvARB(GLbyte * pc); extern _X_HIDDEN int __glXDisp_DeleteLists(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DeleteLists(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_LogicOp(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LogicOp(GLbyte * pc); extern _X_HIDDEN void __glXDisp_RenderbufferStorageMultisample(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RenderbufferStorageMultisample(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord4fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord4fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ActiveTexture(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ActiveTexture(GLbyte * pc); extern _X_HIDDEN void __glXDisp_SecondaryColor3bv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_SecondaryColor3bv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_WaitX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_WaitX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib1dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib1dvNV(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GenTextures(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GenTextures(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GenTexturesEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GenTexturesEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetDrawableAttributes(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetDrawableAttributes(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_RasterPos2sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos2sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color4ubv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color4ubv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_DrawBuffer(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_DrawBuffer(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord2fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord2fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord4iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord4iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord1sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord1sv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_CreateGLXPixmapWithConfigSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_DepthFunc(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_DepthFunc(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PixelMapusv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PixelMapusv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_BlendFunc(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BlendFunc(GLbyte * pc); extern _X_HIDDEN int __glXDisp_WaitGL(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_WaitGL(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_CompressedTexImage2D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CompressedTexImage2D(GLbyte * pc); extern _X_HIDDEN int __glXDisp_Flush(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_Flush(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Color4uiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color4uiv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord1sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord1sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_RasterPos3sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos3sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PushAttrib(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PushAttrib(GLbyte * pc); extern _X_HIDDEN int __glXDisp_DestroyPbuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DestroyPbuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_TexParameteriv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexParameteriv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_QueryExtensionsString(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_QueryExtensionsString(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_RasterPos3fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos3fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CopyTexSubImage3D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CopyTexSubImage3D(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetColorTable(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetColorTable(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetColorTableSGI(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetColorTableSGI(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Indexiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Indexiv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_CreateContext(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CreateContext(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_CopyColorTable(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CopyColorTable(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PointParameterfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PointParameterfv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetHistogramParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetHistogramParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetHistogramParameterfvEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetHistogramParameterfvEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Frustum(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Frustum(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetString(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetString(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_CreateGLXPixmap(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CreateGLXPixmap(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_TexEnvf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexEnvf(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GenProgramsARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GenProgramsARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_DeleteTextures(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DeleteTextures(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_DeleteTexturesEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DeleteTexturesEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetTexLevelParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetTexLevelParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ClearAccum(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ClearAccum(GLbyte * pc); extern _X_HIDDEN int __glXDisp_QueryVersion(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_QueryVersion(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_TexCoord4iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord4iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_FramebufferTexture3D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_FramebufferTexture3D(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ColorTableParameteriv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ColorTableParameteriv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CopyTexImage2D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CopyTexImage2D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord2dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord2dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Lightfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Lightfv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetFramebufferAttachmentParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetFramebufferAttachmentParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ClearDepth(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ClearDepth(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ColorSubTable(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ColorSubTable(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color4fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color4fv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_CreatePixmap(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CreatePixmap(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Lightiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Lightiv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetTexParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetTexParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib3sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib3sv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_IsQuery(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_IsQuery(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Rectdv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Rectdv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Materialiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Materialiv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_SecondaryColor3fvEXT(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_SecondaryColor3fvEXT(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PolygonMode(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PolygonMode(GLbyte * pc); extern _X_HIDDEN void __glXDisp_SecondaryColor3iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_SecondaryColor3iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4Niv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4Niv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetProgramStringARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetProgramStringARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_TexGeni(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexGeni(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexGenf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexGenf(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexGend(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexGend(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetPolygonStipple(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetPolygonStipple(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib2svNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib2svNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttribs1fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs1fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib2dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib2dvNV(GLbyte * pc); extern _X_HIDDEN int __glXDisp_DestroyWindow(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DestroyWindow(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Color4sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color4sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PixelZoom(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PixelZoom(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ColorTableParameterfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ColorTableParameterfv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PixelMapuiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PixelMapuiv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color3dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color3dv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_IsTexture(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_IsTexture(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_IsTextureEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_IsTextureEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib4fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_BeginQuery(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BeginQuery(GLbyte * pc); extern _X_HIDDEN int __glXDisp_SetClientInfo2ARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_SetClientInfo2ARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetMapdv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMapdv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_MultiTexCoord3iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord3iv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_DestroyGLXPixmap(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DestroyGLXPixmap(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_PixelStoref(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_PixelStoref(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_PrioritizeTextures(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PrioritizeTextures(GLbyte * pc); extern _X_HIDDEN int __glXDisp_PixelStorei(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_PixelStorei(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_DestroyGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DestroyGLXPbufferSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_EvalCoord2dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_EvalCoord2dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ColorMaterial(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ColorMaterial(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttribs1svNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs1svNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib1fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib1fvNV(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetSeparableFilter(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetSeparableFilter(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetSeparableFilterEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetSeparableFilterEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_FeedbackBuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_FeedbackBuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_RasterPos2iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos2iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_FrontFace(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_FrontFace(GLbyte * pc); extern _X_HIDDEN int __glXDisp_RenderLarge(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_RenderLarge(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_PolygonOffset(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PolygonOffset(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Normal3dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Normal3dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Lightf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Lightf(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MatrixMode(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MatrixMode(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetPixelMapusv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetPixelMapusv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Lighti(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Lighti(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GenFramebuffers(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GenFramebuffers(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_IsFramebuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_IsFramebuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_ChangeDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_ChangeDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_BlendEquationSeparate(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BlendEquationSeparate(GLbyte * pc); extern _X_HIDDEN int __glXDisp_CreatePbuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CreatePbuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetDoublev(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetDoublev(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_MultMatrixd(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultMatrixd(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultMatrixf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultMatrixf(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CompressedTexImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CompressedTexImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord4fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord4fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDisp_RasterPos4sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos4sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib3fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib3fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ClearColor(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ClearColor(GLbyte * pc); extern _X_HIDDEN int __glXDisp_IsDirect(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_IsDirect(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib1svNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib1svNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_SecondaryColor3ubv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_SecondaryColor3ubv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PointParameteri(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PointParameteri(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PointParameterf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PointParameterf(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexEnviv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexEnviv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexSubImage3D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexSubImage3D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4iv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_SwapIntervalSGI(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_SwapIntervalSGI(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetColorTableParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetColorTableParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetColorTableParameterfvSGI(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetColorTableParameterfvSGI(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_FramebufferTexture2D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_FramebufferTexture2D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Bitmap(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Bitmap(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetTexLevelParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetTexLevelParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_CheckFramebufferStatus(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CheckFramebufferStatus(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Vertex2sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex2sv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetIntegerv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetIntegerv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_BindProgramARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BindProgramARB(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetProgramEnvParameterfvARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetProgramEnvParameterfvARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib3svNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib3svNV(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetTexEnviv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetTexEnviv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_VendorPrivateWithReply(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_VendorPrivateWithReply(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_SeparableFilter2D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_SeparableFilter2D(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetQueryObjectuiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetQueryObjectuiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Map1d(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Map1d(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Map1f(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Map1f(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexImage2D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexImage2D(GLbyte * pc); extern _X_HIDDEN int __glXDisp_ChangeDrawableAttributes(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_ChangeDrawableAttributes(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetMinmaxParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMinmaxParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetMinmaxParameterivEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMinmaxParameterivEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_PixelTransferf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PixelTransferf(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CopyTexImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CopyTexImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_RasterPos2dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos2dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Fogiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Fogiv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_EndQuery(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_EndQuery(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord1dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord1dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PixelTransferi(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PixelTransferi(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib3fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib3fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Clear(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Clear(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ReadBuffer(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ReadBuffer(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ConvolutionParameteri(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ConvolutionParameteri(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_LightModeli(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LightModeli(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ListBase(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ListBase(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ConvolutionParameterf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ConvolutionParameterf(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetColorTableParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetColorTableParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetColorTableParameterivSGI(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetColorTableParameterivSGI(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_ReleaseTexImageEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_ReleaseTexImageEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_CallList(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CallList(GLbyte * pc); extern _X_HIDDEN void __glXDisp_GenerateMipmap(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_GenerateMipmap(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Rectiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Rectiv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord1iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord1iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Vertex2fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex2fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Vertex3sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex3sv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetQueryObjectiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetQueryObjectiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_SetClientInfoARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_SetClientInfoARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_BindTexImageEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_BindTexImageEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ProgramLocalParameter4fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ProgramLocalParameter4fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDisp_EvalMesh1(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_EvalMesh1(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CompressedTexSubImage3D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CompressedTexSubImage3D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Vertex2iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex2iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_LineWidth(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LineWidth(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexGendv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexGendv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ResetMinmax(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ResetMinmax(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetConvolutionParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetConvolutionParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetConvolutionParameterfvEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetConvolutionParameterfvEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetMaterialfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMaterialfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_WindowPos3fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_WindowPos3fv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_DeleteProgramsARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DeleteProgramsARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_UseXFont(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_UseXFont(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ShadeModel(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ShadeModel(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Materialfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Materialfv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord3fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord3fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_FogCoordfvEXT(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_FogCoordfvEXT(GLbyte * pc); extern _X_HIDDEN void __glXDisp_DrawArrays(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_DrawArrays(GLbyte * pc); extern _X_HIDDEN void __glXDisp_SampleCoverage(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_SampleCoverage(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color3iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color3iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4ubv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4ubv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetProgramLocalParameterdvARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetProgramLocalParameterdvARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetHistogramParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetHistogramParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetHistogramParameterivEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetHistogramParameterivEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_PointParameteriv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PointParameteriv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Rotatef(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Rotatef(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetProgramivARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetProgramivARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_BindRenderbuffer(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BindRenderbuffer(GLbyte * pc); extern _X_HIDDEN void __glXDisp_EvalPoint2(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_EvalPoint2(GLbyte * pc); extern _X_HIDDEN void __glXDisp_EvalPoint1(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_EvalPoint1(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PopMatrix(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PopMatrix(GLbyte * pc); extern _X_HIDDEN void __glXDisp_DeleteFramebuffers(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_DeleteFramebuffers(GLbyte * pc); extern _X_HIDDEN int __glXDisp_MakeCurrentReadSGI(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_MakeCurrentReadSGI(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetTexGeniv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetTexGeniv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_MakeCurrent(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_MakeCurrent(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_FramebufferRenderbuffer(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_FramebufferRenderbuffer(GLbyte * pc); extern _X_HIDDEN int __glXDisp_IsProgramARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_IsProgramARB(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib4uiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4uiv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4Nsv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4Nsv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Map2d(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Map2d(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Map2f(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Map2f(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ProgramStringARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ProgramStringARB(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4bv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4bv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetConvolutionFilter(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetConvolutionFilter(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetConvolutionFilterEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetConvolutionFilterEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttribs4dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs4dvNV(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetTexGenfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetTexGenfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetHistogram(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetHistogram(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetHistogramEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetHistogramEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ActiveStencilFaceEXT(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ActiveStencilFaceEXT(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Materialf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Materialf(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Materiali(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Materiali(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Indexsv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Indexsv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib1fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib1fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDisp_LightModelfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LightModelfv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord2dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord2dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_EvalCoord1dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_EvalCoord1dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Translated(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Translated(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Translatef(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Translatef(GLbyte * pc); extern _X_HIDDEN void __glXDisp_StencilMask(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_StencilMask(GLbyte * pc); extern _X_HIDDEN int __glXDisp_CreateWindow(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_CreateWindow(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetLightiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetLightiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_IsList(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_IsList(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_RenderMode(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_RenderMode(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_LoadName(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LoadName(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CopyTexSubImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CopyTexSubImage1D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CullFace(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CullFace(GLbyte * pc); extern _X_HIDDEN int __glXDisp_QueryContextInfoEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_QueryContextInfoEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttribs2fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs2fvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_StencilFunc(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_StencilFunc(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CopyPixels(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CopyPixels(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Rectsv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Rectsv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CopyConvolutionFilter2D(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CopyConvolutionFilter2D(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexParameterfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexParameterfv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib4Nubv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4Nubv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_ClipPlane(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ClipPlane(GLbyte * pc); extern _X_HIDDEN void __glXDisp_SecondaryColor3usv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_SecondaryColor3usv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord3dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord3dv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetPixelMapuiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetPixelMapuiv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Indexfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Indexfv(GLbyte * pc); extern _X_HIDDEN int __glXDisp_QueryContext(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_QueryContext(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_MultiTexCoord3fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord3fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDisp_BlitFramebuffer(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_BlitFramebuffer(GLbyte * pc); extern _X_HIDDEN void __glXDisp_IndexMask(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_IndexMask(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetFloatv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetFloatv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_TexCoord3sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord3sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_FogCoorddv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_FogCoorddv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_PopAttrib(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_PopAttrib(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Fogfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Fogfv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_InitNames(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_InitNames(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Normal3sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Normal3sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Minmax(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Minmax(GLbyte * pc); extern _X_HIDDEN int __glXDisp_DeleteQueries(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_DeleteQueries(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetBooleanv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetBooleanv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Hint(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Hint(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Color4dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Color4dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_CopyColorSubTable(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_CopyColorSubTable(GLbyte * pc); extern _X_HIDDEN void __glXDisp_VertexAttrib3dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib3dvNV(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Vertex4iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex4iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_TexCoord4dv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_TexCoord4dv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Begin(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Begin(GLbyte * pc); extern _X_HIDDEN int __glXDisp_ClientInfo(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_ClientInfo(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Rectfv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Rectfv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_LightModelf(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_LightModelf(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetTexParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetTexParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetLightfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetLightfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_Disable(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Disable(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord2fvARB(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord2fvARB(GLbyte * pc); extern _X_HIDDEN int __glXDisp_SelectBuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_SelectBuffer(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_ColorMask(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_ColorMask(GLbyte * pc); extern _X_HIDDEN void __glXDisp_RasterPos4iv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_RasterPos4iv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Enable(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Enable(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GetRenderbufferParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetRenderbufferParameteriv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttribs4svNV(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttribs4svNV(GLbyte * pc); extern _X_HIDDEN int __glXDisp_GenRenderbuffers(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GenRenderbuffers(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetMinmaxParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMinmaxParameterfv(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDisp_GetMinmaxParameterfvEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN int __glXDispSwap_GetMinmaxParameterfvEXT(struct __GLXclientStateRec *, GLbyte *); extern _X_HIDDEN void __glXDisp_VertexAttrib4Nuiv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_VertexAttrib4Nuiv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_Vertex3fv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_Vertex3fv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_SecondaryColor3sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_SecondaryColor3sv(GLbyte * pc); extern _X_HIDDEN void __glXDisp_MultiTexCoord2sv(GLbyte * pc); extern _X_HIDDEN void __glXDispSwap_MultiTexCoord2sv(GLbyte * pc); #endif /* !defined( _INDIRECT_DISPATCH_H_ ) */ xorg-server-1.20.13/glx/indirect_dispatch_swap.c0000644000175000017500000047611614100573756016561 00000000000000/* DO NOT EDIT - This file generated automatically by glX_proto_recv.py (from Mesa) script */ /* * (C) Copyright IBM Corporation 2005 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include "glxserver.h" #include "indirect_size.h" #include "indirect_size_get.h" #include "indirect_dispatch.h" #include "glxbyteorder.h" #include "indirect_util.h" #include "singlesize.h" #define __GLX_PAD(x) (((x) + 3) & ~3) typedef struct { __GLX_PIXEL_3D_HDR; } __GLXpixel3DHeader; extern GLboolean __glXErrorOccured(void); extern void __glXClearErrorOccured(void); static const unsigned dummy_answer[2] = { 0, 0 }; static GLsizei bswap_CARD32(const void *src) { union { uint32_t dst; GLsizei ret; } x; x.dst = bswap_32(*(uint32_t *) src); return x.ret; } static GLshort bswap_CARD16(const void *src) { union { uint16_t dst; GLshort ret; } x; x.dst = bswap_16(*(uint16_t *) src); return x.ret; } static GLenum bswap_ENUM(const void *src) { union { uint32_t dst; GLenum ret; } x; x.dst = bswap_32(*(uint32_t *) src); return x.ret; } static GLsync bswap_CARD64(const void *src) { union { uint64_t dst; GLsync ret; } x; x.dst = bswap_64(*(uint64_t *) src); return x.ret; } static GLdouble bswap_FLOAT64(const void *src) { union { uint64_t dst; GLdouble ret; } x; x.dst = bswap_64(*(uint64_t *) src); return x.ret; } static GLfloat bswap_FLOAT32(const void *src) { union { uint32_t dst; GLfloat ret; } x; x.dst = bswap_32(*(uint32_t *) src); return x.ret; } static void * bswap_16_array(uint16_t * src, unsigned count) { unsigned i; for (i = 0; i < count; i++) { uint16_t temp = bswap_16(src[i]); src[i] = temp; } return src; } static void * bswap_32_array(uint32_t * src, unsigned count) { unsigned i; for (i = 0; i < count; i++) { uint32_t temp = bswap_32(src[i]); src[i] = temp; } return src; } static void * bswap_64_array(uint64_t * src, unsigned count) { unsigned i; for (i = 0; i < count; i++) { uint64_t temp = bswap_64(src[i]); src[i] = temp; } return src; } int __glXDispSwap_NewList(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { glNewList((GLuint) bswap_CARD32(pc + 0), (GLenum) bswap_ENUM(pc + 4)); error = Success; } return error; } int __glXDispSwap_EndList(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { glEndList(); error = Success; } return error; } void __glXDispSwap_CallList(GLbyte * pc) { glCallList((GLuint) bswap_CARD32(pc + 0)); } void __glXDispSwap_CallLists(GLbyte * pc) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); const GLenum type = (GLenum) bswap_ENUM(pc + 4); const GLvoid *lists; switch (type) { case GL_BYTE: case GL_UNSIGNED_BYTE: case GL_2_BYTES: case GL_3_BYTES: case GL_4_BYTES: lists = (const GLvoid *) (pc + 8); break; case GL_SHORT: case GL_UNSIGNED_SHORT: lists = (const GLvoid *) bswap_16_array((uint16_t *) (pc + 8), n); break; case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: lists = (const GLvoid *) bswap_32_array((uint32_t *) (pc + 8), n); break; default: return; } glCallLists(n, type, lists); } int __glXDispSwap_DeleteLists(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { glDeleteLists((GLuint) bswap_CARD32(pc + 0), (GLsizei) bswap_CARD32(pc + 4)); error = Success; } return error; } int __glXDispSwap_GenLists(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLuint retval; retval = glGenLists((GLsizei) bswap_CARD32(pc + 0)); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDispSwap_ListBase(GLbyte * pc) { glListBase((GLuint) bswap_CARD32(pc + 0)); } void __glXDispSwap_Begin(GLbyte * pc) { glBegin((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_Bitmap(GLbyte * pc) { const GLubyte *const bitmap = (const GLubyte *) ((pc + 44)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glBitmap((GLsizei) bswap_CARD32(pc + 20), (GLsizei) bswap_CARD32(pc + 24), (GLfloat) bswap_FLOAT32(pc + 28), (GLfloat) bswap_FLOAT32(pc + 32), (GLfloat) bswap_FLOAT32(pc + 36), (GLfloat) bswap_FLOAT32(pc + 40), bitmap); } void __glXDispSwap_Color3bv(GLbyte * pc) { glColor3bv((const GLbyte *) (pc + 0)); } void __glXDispSwap_Color3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glColor3dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 3)); } void __glXDispSwap_Color3fv(GLbyte * pc) { glColor3fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_Color3iv(GLbyte * pc) { glColor3iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_Color3sv(GLbyte * pc) { glColor3sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 3)); } void __glXDispSwap_Color3ubv(GLbyte * pc) { glColor3ubv((const GLubyte *) (pc + 0)); } void __glXDispSwap_Color3uiv(GLbyte * pc) { glColor3uiv((const GLuint *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_Color3usv(GLbyte * pc) { glColor3usv((const GLushort *) bswap_16_array((uint16_t *) (pc + 0), 3)); } void __glXDispSwap_Color4bv(GLbyte * pc) { glColor4bv((const GLbyte *) (pc + 0)); } void __glXDispSwap_Color4dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glColor4dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 4)); } void __glXDispSwap_Color4fv(GLbyte * pc) { glColor4fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 4)); } void __glXDispSwap_Color4iv(GLbyte * pc) { glColor4iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 4)); } void __glXDispSwap_Color4sv(GLbyte * pc) { glColor4sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 4)); } void __glXDispSwap_Color4ubv(GLbyte * pc) { glColor4ubv((const GLubyte *) (pc + 0)); } void __glXDispSwap_Color4uiv(GLbyte * pc) { glColor4uiv((const GLuint *) bswap_32_array((uint32_t *) (pc + 0), 4)); } void __glXDispSwap_Color4usv(GLbyte * pc) { glColor4usv((const GLushort *) bswap_16_array((uint16_t *) (pc + 0), 4)); } void __glXDispSwap_EdgeFlagv(GLbyte * pc) { glEdgeFlagv((const GLboolean *) (pc + 0)); } void __glXDispSwap_End(GLbyte * pc) { glEnd(); } void __glXDispSwap_Indexdv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 8); pc -= 4; } #endif glIndexdv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 1)); } void __glXDispSwap_Indexfv(GLbyte * pc) { glIndexfv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 1)); } void __glXDispSwap_Indexiv(GLbyte * pc) { glIndexiv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 1)); } void __glXDispSwap_Indexsv(GLbyte * pc) { glIndexsv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 1)); } void __glXDispSwap_Normal3bv(GLbyte * pc) { glNormal3bv((const GLbyte *) (pc + 0)); } void __glXDispSwap_Normal3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glNormal3dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 3)); } void __glXDispSwap_Normal3fv(GLbyte * pc) { glNormal3fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_Normal3iv(GLbyte * pc) { glNormal3iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_Normal3sv(GLbyte * pc) { glNormal3sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 3)); } void __glXDispSwap_RasterPos2dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glRasterPos2dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 2)); } void __glXDispSwap_RasterPos2fv(GLbyte * pc) { glRasterPos2fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 2)); } void __glXDispSwap_RasterPos2iv(GLbyte * pc) { glRasterPos2iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 2)); } void __glXDispSwap_RasterPos2sv(GLbyte * pc) { glRasterPos2sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 2)); } void __glXDispSwap_RasterPos3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glRasterPos3dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 3)); } void __glXDispSwap_RasterPos3fv(GLbyte * pc) { glRasterPos3fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_RasterPos3iv(GLbyte * pc) { glRasterPos3iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_RasterPos3sv(GLbyte * pc) { glRasterPos3sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 3)); } void __glXDispSwap_RasterPos4dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glRasterPos4dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 4)); } void __glXDispSwap_RasterPos4fv(GLbyte * pc) { glRasterPos4fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 4)); } void __glXDispSwap_RasterPos4iv(GLbyte * pc) { glRasterPos4iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 4)); } void __glXDispSwap_RasterPos4sv(GLbyte * pc) { glRasterPos4sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 4)); } void __glXDispSwap_Rectdv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glRectdv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 2), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 16), 2)); } void __glXDispSwap_Rectfv(GLbyte * pc) { glRectfv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 2), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), 2)); } void __glXDispSwap_Rectiv(GLbyte * pc) { glRectiv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 2), (const GLint *) bswap_32_array((uint32_t *) (pc + 8), 2)); } void __glXDispSwap_Rectsv(GLbyte * pc) { glRectsv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 2), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 2)); } void __glXDispSwap_TexCoord1dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 8); pc -= 4; } #endif glTexCoord1dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 1)); } void __glXDispSwap_TexCoord1fv(GLbyte * pc) { glTexCoord1fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 1)); } void __glXDispSwap_TexCoord1iv(GLbyte * pc) { glTexCoord1iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 1)); } void __glXDispSwap_TexCoord1sv(GLbyte * pc) { glTexCoord1sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 1)); } void __glXDispSwap_TexCoord2dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glTexCoord2dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 2)); } void __glXDispSwap_TexCoord2fv(GLbyte * pc) { glTexCoord2fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 2)); } void __glXDispSwap_TexCoord2iv(GLbyte * pc) { glTexCoord2iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 2)); } void __glXDispSwap_TexCoord2sv(GLbyte * pc) { glTexCoord2sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 2)); } void __glXDispSwap_TexCoord3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glTexCoord3dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 3)); } void __glXDispSwap_TexCoord3fv(GLbyte * pc) { glTexCoord3fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_TexCoord3iv(GLbyte * pc) { glTexCoord3iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_TexCoord3sv(GLbyte * pc) { glTexCoord3sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 3)); } void __glXDispSwap_TexCoord4dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glTexCoord4dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 4)); } void __glXDispSwap_TexCoord4fv(GLbyte * pc) { glTexCoord4fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 4)); } void __glXDispSwap_TexCoord4iv(GLbyte * pc) { glTexCoord4iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 4)); } void __glXDispSwap_TexCoord4sv(GLbyte * pc) { glTexCoord4sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 4)); } void __glXDispSwap_Vertex2dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glVertex2dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 2)); } void __glXDispSwap_Vertex2fv(GLbyte * pc) { glVertex2fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 2)); } void __glXDispSwap_Vertex2iv(GLbyte * pc) { glVertex2iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 2)); } void __glXDispSwap_Vertex2sv(GLbyte * pc) { glVertex2sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 2)); } void __glXDispSwap_Vertex3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glVertex3dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 3)); } void __glXDispSwap_Vertex3fv(GLbyte * pc) { glVertex3fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_Vertex3iv(GLbyte * pc) { glVertex3iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_Vertex3sv(GLbyte * pc) { glVertex3sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 3)); } void __glXDispSwap_Vertex4dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glVertex4dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 4)); } void __glXDispSwap_Vertex4fv(GLbyte * pc) { glVertex4fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 4)); } void __glXDispSwap_Vertex4iv(GLbyte * pc) { glVertex4iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 4)); } void __glXDispSwap_Vertex4sv(GLbyte * pc) { glVertex4sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 4)); } void __glXDispSwap_ClipPlane(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 36); pc -= 4; } #endif glClipPlane((GLenum) bswap_ENUM(pc + 32), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 4)); } void __glXDispSwap_ColorMaterial(GLbyte * pc) { glColorMaterial((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4)); } void __glXDispSwap_CullFace(GLbyte * pc) { glCullFace((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_Fogf(GLbyte * pc) { glFogf((GLenum) bswap_ENUM(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4)); } void __glXDispSwap_Fogfv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 0); const GLfloat *params; params = (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), __glFogfv_size(pname)); glFogfv(pname, params); } void __glXDispSwap_Fogi(GLbyte * pc) { glFogi((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4)); } void __glXDispSwap_Fogiv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 0); const GLint *params; params = (const GLint *) bswap_32_array((uint32_t *) (pc + 4), __glFogiv_size(pname)); glFogiv(pname, params); } void __glXDispSwap_FrontFace(GLbyte * pc) { glFrontFace((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_Hint(GLbyte * pc) { glHint((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4)); } void __glXDispSwap_Lightf(GLbyte * pc) { glLightf((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8)); } void __glXDispSwap_Lightfv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLfloat *params; params = (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), __glLightfv_size(pname)); glLightfv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_Lighti(GLbyte * pc) { glLighti((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLint) bswap_CARD32(pc + 8)); } void __glXDispSwap_Lightiv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLint *params; params = (const GLint *) bswap_32_array((uint32_t *) (pc + 8), __glLightiv_size(pname)); glLightiv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_LightModelf(GLbyte * pc) { glLightModelf((GLenum) bswap_ENUM(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4)); } void __glXDispSwap_LightModelfv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 0); const GLfloat *params; params = (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), __glLightModelfv_size(pname)); glLightModelfv(pname, params); } void __glXDispSwap_LightModeli(GLbyte * pc) { glLightModeli((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4)); } void __glXDispSwap_LightModeliv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 0); const GLint *params; params = (const GLint *) bswap_32_array((uint32_t *) (pc + 4), __glLightModeliv_size(pname)); glLightModeliv(pname, params); } void __glXDispSwap_LineStipple(GLbyte * pc) { glLineStipple((GLint) bswap_CARD32(pc + 0), (GLushort) bswap_CARD16(pc + 4)); } void __glXDispSwap_LineWidth(GLbyte * pc) { glLineWidth((GLfloat) bswap_FLOAT32(pc + 0)); } void __glXDispSwap_Materialf(GLbyte * pc) { glMaterialf((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8)); } void __glXDispSwap_Materialfv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLfloat *params; params = (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), __glMaterialfv_size(pname)); glMaterialfv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_Materiali(GLbyte * pc) { glMateriali((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLint) bswap_CARD32(pc + 8)); } void __glXDispSwap_Materialiv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLint *params; params = (const GLint *) bswap_32_array((uint32_t *) (pc + 8), __glMaterialiv_size(pname)); glMaterialiv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_PointSize(GLbyte * pc) { glPointSize((GLfloat) bswap_FLOAT32(pc + 0)); } void __glXDispSwap_PolygonMode(GLbyte * pc) { glPolygonMode((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4)); } void __glXDispSwap_PolygonStipple(GLbyte * pc) { const GLubyte *const mask = (const GLubyte *) ((pc + 20)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glPolygonStipple(mask); } void __glXDispSwap_Scissor(GLbyte * pc) { glScissor((GLint) bswap_CARD32(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLsizei) bswap_CARD32(pc + 8), (GLsizei) bswap_CARD32(pc + 12)); } void __glXDispSwap_ShadeModel(GLbyte * pc) { glShadeModel((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_TexParameterf(GLbyte * pc) { glTexParameterf((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8)); } void __glXDispSwap_TexParameterfv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLfloat *params; params = (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), __glTexParameterfv_size(pname)); glTexParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_TexParameteri(GLbyte * pc) { glTexParameteri((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLint) bswap_CARD32(pc + 8)); } void __glXDispSwap_TexParameteriv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLint *params; params = (const GLint *) bswap_32_array((uint32_t *) (pc + 8), __glTexParameteriv_size(pname)); glTexParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_TexImage1D(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 52)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glTexImage1D((GLenum) bswap_ENUM(pc + 20), (GLint) bswap_CARD32(pc + 24), (GLint) bswap_CARD32(pc + 28), (GLsizei) bswap_CARD32(pc + 32), (GLint) bswap_CARD32(pc + 40), (GLenum) bswap_ENUM(pc + 44), (GLenum) bswap_ENUM(pc + 48), pixels); } void __glXDispSwap_TexImage2D(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 52)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glTexImage2D((GLenum) bswap_ENUM(pc + 20), (GLint) bswap_CARD32(pc + 24), (GLint) bswap_CARD32(pc + 28), (GLsizei) bswap_CARD32(pc + 32), (GLsizei) bswap_CARD32(pc + 36), (GLint) bswap_CARD32(pc + 40), (GLenum) bswap_ENUM(pc + 44), (GLenum) bswap_ENUM(pc + 48), pixels); } void __glXDispSwap_TexEnvf(GLbyte * pc) { glTexEnvf((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8)); } void __glXDispSwap_TexEnvfv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLfloat *params; params = (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), __glTexEnvfv_size(pname)); glTexEnvfv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_TexEnvi(GLbyte * pc) { glTexEnvi((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLint) bswap_CARD32(pc + 8)); } void __glXDispSwap_TexEnviv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLint *params; params = (const GLint *) bswap_32_array((uint32_t *) (pc + 8), __glTexEnviv_size(pname)); glTexEnviv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_TexGend(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glTexGend((GLenum) bswap_ENUM(pc + 8), (GLenum) bswap_ENUM(pc + 12), (GLdouble) bswap_FLOAT64(pc + 0)); } void __glXDispSwap_TexGendv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLdouble *params; #ifdef __GLX_ALIGN64 const GLuint compsize = __glTexGendv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 8)) - 4; if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, cmdlen); pc -= 4; } #endif params = (const GLdouble *) bswap_64_array((uint64_t *) (pc + 8), __glTexGendv_size(pname)); glTexGendv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_TexGenf(GLbyte * pc) { glTexGenf((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8)); } void __glXDispSwap_TexGenfv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLfloat *params; params = (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), __glTexGenfv_size(pname)); glTexGenfv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_TexGeni(GLbyte * pc) { glTexGeni((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLint) bswap_CARD32(pc + 8)); } void __glXDispSwap_TexGeniv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLint *params; params = (const GLint *) bswap_32_array((uint32_t *) (pc + 8), __glTexGeniv_size(pname)); glTexGeniv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_InitNames(GLbyte * pc) { glInitNames(); } void __glXDispSwap_LoadName(GLbyte * pc) { glLoadName((GLuint) bswap_CARD32(pc + 0)); } void __glXDispSwap_PassThrough(GLbyte * pc) { glPassThrough((GLfloat) bswap_FLOAT32(pc + 0)); } void __glXDispSwap_PopName(GLbyte * pc) { glPopName(); } void __glXDispSwap_PushName(GLbyte * pc) { glPushName((GLuint) bswap_CARD32(pc + 0)); } void __glXDispSwap_DrawBuffer(GLbyte * pc) { glDrawBuffer((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_Clear(GLbyte * pc) { glClear((GLbitfield) bswap_CARD32(pc + 0)); } void __glXDispSwap_ClearAccum(GLbyte * pc) { glClearAccum((GLfloat) bswap_FLOAT32(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8), (GLfloat) bswap_FLOAT32(pc + 12)); } void __glXDispSwap_ClearIndex(GLbyte * pc) { glClearIndex((GLfloat) bswap_FLOAT32(pc + 0)); } void __glXDispSwap_ClearColor(GLbyte * pc) { glClearColor((GLclampf) bswap_FLOAT32(pc + 0), (GLclampf) bswap_FLOAT32(pc + 4), (GLclampf) bswap_FLOAT32(pc + 8), (GLclampf) bswap_FLOAT32(pc + 12)); } void __glXDispSwap_ClearStencil(GLbyte * pc) { glClearStencil((GLint) bswap_CARD32(pc + 0)); } void __glXDispSwap_ClearDepth(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 8); pc -= 4; } #endif glClearDepth((GLclampd) bswap_FLOAT64(pc + 0)); } void __glXDispSwap_StencilMask(GLbyte * pc) { glStencilMask((GLuint) bswap_CARD32(pc + 0)); } void __glXDispSwap_ColorMask(GLbyte * pc) { glColorMask(*(GLboolean *) (pc + 0), *(GLboolean *) (pc + 1), *(GLboolean *) (pc + 2), *(GLboolean *) (pc + 3)); } void __glXDispSwap_DepthMask(GLbyte * pc) { glDepthMask(*(GLboolean *) (pc + 0)); } void __glXDispSwap_IndexMask(GLbyte * pc) { glIndexMask((GLuint) bswap_CARD32(pc + 0)); } void __glXDispSwap_Accum(GLbyte * pc) { glAccum((GLenum) bswap_ENUM(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4)); } void __glXDispSwap_Disable(GLbyte * pc) { glDisable((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_Enable(GLbyte * pc) { glEnable((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_PopAttrib(GLbyte * pc) { glPopAttrib(); } void __glXDispSwap_PushAttrib(GLbyte * pc) { glPushAttrib((GLbitfield) bswap_CARD32(pc + 0)); } void __glXDispSwap_MapGrid1d(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 20); pc -= 4; } #endif glMapGrid1d((GLint) bswap_CARD32(pc + 16), (GLdouble) bswap_FLOAT64(pc + 0), (GLdouble) bswap_FLOAT64(pc + 8)); } void __glXDispSwap_MapGrid1f(GLbyte * pc) { glMapGrid1f((GLint) bswap_CARD32(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8)); } void __glXDispSwap_MapGrid2d(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 40); pc -= 4; } #endif glMapGrid2d((GLint) bswap_CARD32(pc + 32), (GLdouble) bswap_FLOAT64(pc + 0), (GLdouble) bswap_FLOAT64(pc + 8), (GLint) bswap_CARD32(pc + 36), (GLdouble) bswap_FLOAT64(pc + 16), (GLdouble) bswap_FLOAT64(pc + 24)); } void __glXDispSwap_MapGrid2f(GLbyte * pc) { glMapGrid2f((GLint) bswap_CARD32(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLfloat) bswap_FLOAT32(pc + 16), (GLfloat) bswap_FLOAT32(pc + 20)); } void __glXDispSwap_EvalCoord1dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 8); pc -= 4; } #endif glEvalCoord1dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 1)); } void __glXDispSwap_EvalCoord1fv(GLbyte * pc) { glEvalCoord1fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 1)); } void __glXDispSwap_EvalCoord2dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glEvalCoord2dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 2)); } void __glXDispSwap_EvalCoord2fv(GLbyte * pc) { glEvalCoord2fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 2)); } void __glXDispSwap_EvalMesh1(GLbyte * pc) { glEvalMesh1((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLint) bswap_CARD32(pc + 8)); } void __glXDispSwap_EvalPoint1(GLbyte * pc) { glEvalPoint1((GLint) bswap_CARD32(pc + 0)); } void __glXDispSwap_EvalMesh2(GLbyte * pc) { glEvalMesh2((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16)); } void __glXDispSwap_EvalPoint2(GLbyte * pc) { glEvalPoint2((GLint) bswap_CARD32(pc + 0), (GLint) bswap_CARD32(pc + 4)); } void __glXDispSwap_AlphaFunc(GLbyte * pc) { glAlphaFunc((GLenum) bswap_ENUM(pc + 0), (GLclampf) bswap_FLOAT32(pc + 4)); } void __glXDispSwap_BlendFunc(GLbyte * pc) { glBlendFunc((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4)); } void __glXDispSwap_LogicOp(GLbyte * pc) { glLogicOp((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_StencilFunc(GLbyte * pc) { glStencilFunc((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLuint) bswap_CARD32(pc + 8)); } void __glXDispSwap_StencilOp(GLbyte * pc) { glStencilOp((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLenum) bswap_ENUM(pc + 8)); } void __glXDispSwap_DepthFunc(GLbyte * pc) { glDepthFunc((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_PixelZoom(GLbyte * pc) { glPixelZoom((GLfloat) bswap_FLOAT32(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4)); } void __glXDispSwap_PixelTransferf(GLbyte * pc) { glPixelTransferf((GLenum) bswap_ENUM(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4)); } void __glXDispSwap_PixelTransferi(GLbyte * pc) { glPixelTransferi((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4)); } int __glXDispSwap_PixelStoref(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { glPixelStoref((GLenum) bswap_ENUM(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4)); error = Success; } return error; } int __glXDispSwap_PixelStorei(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { glPixelStorei((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4)); error = Success; } return error; } void __glXDispSwap_PixelMapfv(GLbyte * pc) { const GLsizei mapsize = (GLsizei) bswap_CARD32(pc + 4); glPixelMapfv((GLenum) bswap_ENUM(pc + 0), mapsize, (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), 0)); } void __glXDispSwap_PixelMapuiv(GLbyte * pc) { const GLsizei mapsize = (GLsizei) bswap_CARD32(pc + 4); glPixelMapuiv((GLenum) bswap_ENUM(pc + 0), mapsize, (const GLuint *) bswap_32_array((uint32_t *) (pc + 8), 0)); } void __glXDispSwap_PixelMapusv(GLbyte * pc) { const GLsizei mapsize = (GLsizei) bswap_CARD32(pc + 4); glPixelMapusv((GLenum) bswap_ENUM(pc + 0), mapsize, (const GLushort *) bswap_16_array((uint16_t *) (pc + 8), 0)); } void __glXDispSwap_ReadBuffer(GLbyte * pc) { glReadBuffer((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_CopyPixels(GLbyte * pc) { glCopyPixels((GLint) bswap_CARD32(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLsizei) bswap_CARD32(pc + 8), (GLsizei) bswap_CARD32(pc + 12), (GLenum) bswap_ENUM(pc + 16)); } void __glXDispSwap_DrawPixels(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 36)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glDrawPixels((GLsizei) bswap_CARD32(pc + 20), (GLsizei) bswap_CARD32(pc + 24), (GLenum) bswap_ENUM(pc + 28), (GLenum) bswap_ENUM(pc + 32), pixels); } int __glXDispSwap_GetBooleanv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 0); const GLuint compsize = __glGetBooleanv_size(pname); GLboolean answerBuffer[200]; GLboolean *params = __glXGetAnswerBuffer(cl, compsize, answerBuffer, sizeof(answerBuffer), 1); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetBooleanv(pname, params); __glXSendReplySwap(cl->client, params, compsize, 1, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetClipPlane(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLdouble equation[4]; glGetClipPlane((GLenum) bswap_ENUM(pc + 0), equation); (void) bswap_64_array((uint64_t *) equation, 4); __glXSendReplySwap(cl->client, equation, 4, 8, GL_TRUE, 0); error = Success; } return error; } int __glXDispSwap_GetDoublev(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 0); const GLuint compsize = __glGetDoublev_size(pname); GLdouble answerBuffer[200]; GLdouble *params = __glXGetAnswerBuffer(cl, compsize * 8, answerBuffer, sizeof(answerBuffer), 8); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetDoublev(pname, params); (void) bswap_64_array((uint64_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 8, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetError(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLenum retval; retval = glGetError(); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } int __glXDispSwap_GetFloatv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 0); const GLuint compsize = __glGetFloatv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetFloatv(pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetIntegerv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 0); const GLuint compsize = __glGetIntegerv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetIntegerv(pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetLightfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetLightfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetLightfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetLightiv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetLightiv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetLightiv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetMapdv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum target = (GLenum) bswap_ENUM(pc + 0); const GLenum query = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetMapdv_size(target, query); GLdouble answerBuffer[200]; GLdouble *v = __glXGetAnswerBuffer(cl, compsize * 8, answerBuffer, sizeof(answerBuffer), 8); if (v == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMapdv(target, query, v); (void) bswap_64_array((uint64_t *) v, compsize); __glXSendReplySwap(cl->client, v, compsize, 8, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetMapfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum target = (GLenum) bswap_ENUM(pc + 0); const GLenum query = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetMapfv_size(target, query); GLfloat answerBuffer[200]; GLfloat *v = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (v == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMapfv(target, query, v); (void) bswap_32_array((uint32_t *) v, compsize); __glXSendReplySwap(cl->client, v, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetMapiv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum target = (GLenum) bswap_ENUM(pc + 0); const GLenum query = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetMapiv_size(target, query); GLint answerBuffer[200]; GLint *v = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (v == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMapiv(target, query, v); (void) bswap_32_array((uint32_t *) v, compsize); __glXSendReplySwap(cl->client, v, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetMaterialfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetMaterialfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMaterialfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetMaterialiv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetMaterialiv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMaterialiv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetPixelMapfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum map = (GLenum) bswap_ENUM(pc + 0); const GLuint compsize = __glGetPixelMapfv_size(map); GLfloat answerBuffer[200]; GLfloat *values = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (values == NULL) return BadAlloc; __glXClearErrorOccured(); glGetPixelMapfv(map, values); (void) bswap_32_array((uint32_t *) values, compsize); __glXSendReplySwap(cl->client, values, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetPixelMapuiv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum map = (GLenum) bswap_ENUM(pc + 0); const GLuint compsize = __glGetPixelMapuiv_size(map); GLuint answerBuffer[200]; GLuint *values = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (values == NULL) return BadAlloc; __glXClearErrorOccured(); glGetPixelMapuiv(map, values); (void) bswap_32_array((uint32_t *) values, compsize); __glXSendReplySwap(cl->client, values, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetPixelMapusv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum map = (GLenum) bswap_ENUM(pc + 0); const GLuint compsize = __glGetPixelMapusv_size(map); GLushort answerBuffer[200]; GLushort *values = __glXGetAnswerBuffer(cl, compsize * 2, answerBuffer, sizeof(answerBuffer), 2); if (values == NULL) return BadAlloc; __glXClearErrorOccured(); glGetPixelMapusv(map, values); (void) bswap_16_array((uint16_t *) values, compsize); __glXSendReplySwap(cl->client, values, compsize, 2, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetTexEnvfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetTexEnvfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexEnvfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetTexEnviv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetTexEnviv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexEnviv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetTexGendv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetTexGendv_size(pname); GLdouble answerBuffer[200]; GLdouble *params = __glXGetAnswerBuffer(cl, compsize * 8, answerBuffer, sizeof(answerBuffer), 8); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexGendv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_64_array((uint64_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 8, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetTexGenfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetTexGenfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexGenfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetTexGeniv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetTexGeniv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexGeniv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetTexParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetTexParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetTexParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetTexParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetTexLevelParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 8); const GLuint compsize = __glGetTexLevelParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexLevelParameterfv((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetTexLevelParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 8); const GLuint compsize = __glGetTexLevelParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetTexLevelParameteriv((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_IsEnabled(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = glIsEnabled((GLenum) bswap_ENUM(pc + 0)); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } int __glXDispSwap_IsList(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = glIsList((GLuint) bswap_CARD32(pc + 0)); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDispSwap_DepthRange(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 16); pc -= 4; } #endif glDepthRange((GLclampd) bswap_FLOAT64(pc + 0), (GLclampd) bswap_FLOAT64(pc + 8)); } void __glXDispSwap_Frustum(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 48); pc -= 4; } #endif glFrustum((GLdouble) bswap_FLOAT64(pc + 0), (GLdouble) bswap_FLOAT64(pc + 8), (GLdouble) bswap_FLOAT64(pc + 16), (GLdouble) bswap_FLOAT64(pc + 24), (GLdouble) bswap_FLOAT64(pc + 32), (GLdouble) bswap_FLOAT64(pc + 40)); } void __glXDispSwap_LoadIdentity(GLbyte * pc) { glLoadIdentity(); } void __glXDispSwap_LoadMatrixf(GLbyte * pc) { glLoadMatrixf((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 16)); } void __glXDispSwap_LoadMatrixd(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 128); pc -= 4; } #endif glLoadMatrixd((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 16)); } void __glXDispSwap_MatrixMode(GLbyte * pc) { glMatrixMode((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_MultMatrixf(GLbyte * pc) { glMultMatrixf((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 16)); } void __glXDispSwap_MultMatrixd(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 128); pc -= 4; } #endif glMultMatrixd((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 16)); } void __glXDispSwap_Ortho(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 48); pc -= 4; } #endif glOrtho((GLdouble) bswap_FLOAT64(pc + 0), (GLdouble) bswap_FLOAT64(pc + 8), (GLdouble) bswap_FLOAT64(pc + 16), (GLdouble) bswap_FLOAT64(pc + 24), (GLdouble) bswap_FLOAT64(pc + 32), (GLdouble) bswap_FLOAT64(pc + 40)); } void __glXDispSwap_PopMatrix(GLbyte * pc) { glPopMatrix(); } void __glXDispSwap_PushMatrix(GLbyte * pc) { glPushMatrix(); } void __glXDispSwap_Rotated(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 32); pc -= 4; } #endif glRotated((GLdouble) bswap_FLOAT64(pc + 0), (GLdouble) bswap_FLOAT64(pc + 8), (GLdouble) bswap_FLOAT64(pc + 16), (GLdouble) bswap_FLOAT64(pc + 24)); } void __glXDispSwap_Rotatef(GLbyte * pc) { glRotatef((GLfloat) bswap_FLOAT32(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8), (GLfloat) bswap_FLOAT32(pc + 12)); } void __glXDispSwap_Scaled(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glScaled((GLdouble) bswap_FLOAT64(pc + 0), (GLdouble) bswap_FLOAT64(pc + 8), (GLdouble) bswap_FLOAT64(pc + 16)); } void __glXDispSwap_Scalef(GLbyte * pc) { glScalef((GLfloat) bswap_FLOAT32(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8)); } void __glXDispSwap_Translated(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif glTranslated((GLdouble) bswap_FLOAT64(pc + 0), (GLdouble) bswap_FLOAT64(pc + 8), (GLdouble) bswap_FLOAT64(pc + 16)); } void __glXDispSwap_Translatef(GLbyte * pc) { glTranslatef((GLfloat) bswap_FLOAT32(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8)); } void __glXDispSwap_Viewport(GLbyte * pc) { glViewport((GLint) bswap_CARD32(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLsizei) bswap_CARD32(pc + 8), (GLsizei) bswap_CARD32(pc + 12)); } void __glXDispSwap_BindTexture(GLbyte * pc) { glBindTexture((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4)); } void __glXDispSwap_Indexubv(GLbyte * pc) { glIndexubv((const GLubyte *) (pc + 0)); } void __glXDispSwap_PolygonOffset(GLbyte * pc) { glPolygonOffset((GLfloat) bswap_FLOAT32(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4)); } int __glXDispSwap_AreTexturesResident(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); GLboolean retval; GLboolean answerBuffer[200]; GLboolean *residences = __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1); if (residences == NULL) return BadAlloc; retval = glAreTexturesResident(n, (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 0), residences); __glXSendReplySwap(cl->client, residences, n, 1, GL_TRUE, retval); error = Success; } return error; } int __glXDispSwap_AreTexturesResidentEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); GLboolean retval; GLboolean answerBuffer[200]; GLboolean *residences = __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1); if (residences == NULL) return BadAlloc; retval = glAreTexturesResident(n, (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 0), residences); __glXSendReplySwap(cl->client, residences, n, 1, GL_TRUE, retval); error = Success; } return error; } void __glXDispSwap_CopyTexImage1D(GLbyte * pc) { glCopyTexImage1D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16), (GLsizei) bswap_CARD32(pc + 20), (GLint) bswap_CARD32(pc + 24)); } void __glXDispSwap_CopyTexImage2D(GLbyte * pc) { glCopyTexImage2D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16), (GLsizei) bswap_CARD32(pc + 20), (GLsizei) bswap_CARD32(pc + 24), (GLint) bswap_CARD32(pc + 28)); } void __glXDispSwap_CopyTexSubImage1D(GLbyte * pc) { glCopyTexSubImage1D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16), (GLsizei) bswap_CARD32(pc + 20)); } void __glXDispSwap_CopyTexSubImage2D(GLbyte * pc) { glCopyTexSubImage2D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16), (GLint) bswap_CARD32(pc + 20), (GLsizei) bswap_CARD32(pc + 24), (GLsizei) bswap_CARD32(pc + 28)); } int __glXDispSwap_DeleteTextures(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); glDeleteTextures(n, (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 0)); error = Success; } return error; } int __glXDispSwap_DeleteTexturesEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); glDeleteTextures(n, (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 0)); error = Success; } return error; } int __glXDispSwap_GenTextures(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); GLuint answerBuffer[200]; GLuint *textures = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (textures == NULL) return BadAlloc; glGenTextures(n, textures); (void) bswap_32_array((uint32_t *) textures, n); __glXSendReplySwap(cl->client, textures, n, 4, GL_TRUE, 0); error = Success; } return error; } int __glXDispSwap_GenTexturesEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); GLuint answerBuffer[200]; GLuint *textures = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (textures == NULL) return BadAlloc; glGenTextures(n, textures); (void) bswap_32_array((uint32_t *) textures, n); __glXSendReplySwap(cl->client, textures, n, 4, GL_TRUE, 0); error = Success; } return error; } int __glXDispSwap_IsTexture(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = glIsTexture((GLuint) bswap_CARD32(pc + 0)); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } int __glXDispSwap_IsTextureEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = glIsTexture((GLuint) bswap_CARD32(pc + 0)); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDispSwap_PrioritizeTextures(GLbyte * pc) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); glPrioritizeTextures(n, (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 0), (const GLclampf *) bswap_32_array((uint32_t *) (pc + 4), 0)); } void __glXDispSwap_TexSubImage1D(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 56)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glTexSubImage1D((GLenum) bswap_ENUM(pc + 20), (GLint) bswap_CARD32(pc + 24), (GLint) bswap_CARD32(pc + 28), (GLsizei) bswap_CARD32(pc + 36), (GLenum) bswap_ENUM(pc + 44), (GLenum) bswap_ENUM(pc + 48), pixels); } void __glXDispSwap_TexSubImage2D(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 56)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glTexSubImage2D((GLenum) bswap_ENUM(pc + 20), (GLint) bswap_CARD32(pc + 24), (GLint) bswap_CARD32(pc + 28), (GLint) bswap_CARD32(pc + 32), (GLsizei) bswap_CARD32(pc + 36), (GLsizei) bswap_CARD32(pc + 40), (GLenum) bswap_ENUM(pc + 44), (GLenum) bswap_ENUM(pc + 48), pixels); } void __glXDispSwap_BlendColor(GLbyte * pc) { glBlendColor((GLclampf) bswap_FLOAT32(pc + 0), (GLclampf) bswap_FLOAT32(pc + 4), (GLclampf) bswap_FLOAT32(pc + 8), (GLclampf) bswap_FLOAT32(pc + 12)); } void __glXDispSwap_BlendEquation(GLbyte * pc) { glBlendEquation((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_ColorTable(GLbyte * pc) { const GLvoid *const table = (const GLvoid *) ((pc + 40)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glColorTable((GLenum) bswap_ENUM(pc + 20), (GLenum) bswap_ENUM(pc + 24), (GLsizei) bswap_CARD32(pc + 28), (GLenum) bswap_ENUM(pc + 32), (GLenum) bswap_ENUM(pc + 36), table); } void __glXDispSwap_ColorTableParameterfv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLfloat *params; params = (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), __glColorTableParameterfv_size(pname)); glColorTableParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_ColorTableParameteriv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLint *params; params = (const GLint *) bswap_32_array((uint32_t *) (pc + 8), __glColorTableParameteriv_size(pname)); glColorTableParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_CopyColorTable(GLbyte * pc) { glCopyColorTable((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLsizei) bswap_CARD32(pc + 16)); } int __glXDispSwap_GetColorTableParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetColorTableParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetColorTableParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetColorTableParameterfvSGI(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetColorTableParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetColorTableParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetColorTableParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetColorTableParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetColorTableParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetColorTableParameterivSGI(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetColorTableParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetColorTableParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } void __glXDispSwap_ColorSubTable(GLbyte * pc) { const GLvoid *const data = (const GLvoid *) ((pc + 40)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glColorSubTable((GLenum) bswap_ENUM(pc + 20), (GLsizei) bswap_CARD32(pc + 24), (GLsizei) bswap_CARD32(pc + 28), (GLenum) bswap_ENUM(pc + 32), (GLenum) bswap_ENUM(pc + 36), data); } void __glXDispSwap_CopyColorSubTable(GLbyte * pc) { glCopyColorSubTable((GLenum) bswap_ENUM(pc + 0), (GLsizei) bswap_CARD32(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLsizei) bswap_CARD32(pc + 16)); } void __glXDispSwap_ConvolutionFilter1D(GLbyte * pc) { const GLvoid *const image = (const GLvoid *) ((pc + 44)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glConvolutionFilter1D((GLenum) bswap_ENUM(pc + 20), (GLenum) bswap_ENUM(pc + 24), (GLsizei) bswap_CARD32(pc + 28), (GLenum) bswap_ENUM(pc + 36), (GLenum) bswap_ENUM(pc + 40), image); } void __glXDispSwap_ConvolutionFilter2D(GLbyte * pc) { const GLvoid *const image = (const GLvoid *) ((pc + 44)); __GLXpixelHeader *const hdr = (__GLXpixelHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glConvolutionFilter2D((GLenum) bswap_ENUM(pc + 20), (GLenum) bswap_ENUM(pc + 24), (GLsizei) bswap_CARD32(pc + 28), (GLsizei) bswap_CARD32(pc + 32), (GLenum) bswap_ENUM(pc + 36), (GLenum) bswap_ENUM(pc + 40), image); } void __glXDispSwap_ConvolutionParameterf(GLbyte * pc) { glConvolutionParameterf((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLfloat) bswap_FLOAT32(pc + 8)); } void __glXDispSwap_ConvolutionParameterfv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLfloat *params; params = (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), __glConvolutionParameterfv_size (pname)); glConvolutionParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_ConvolutionParameteri(GLbyte * pc) { glConvolutionParameteri((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLint) bswap_CARD32(pc + 8)); } void __glXDispSwap_ConvolutionParameteriv(GLbyte * pc) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLint *params; params = (const GLint *) bswap_32_array((uint32_t *) (pc + 8), __glConvolutionParameteriv_size(pname)); glConvolutionParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); } void __glXDispSwap_CopyConvolutionFilter1D(GLbyte * pc) { glCopyConvolutionFilter1D((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLsizei) bswap_CARD32(pc + 16)); } void __glXDispSwap_CopyConvolutionFilter2D(GLbyte * pc) { glCopyConvolutionFilter2D((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLsizei) bswap_CARD32(pc + 16), (GLsizei) bswap_CARD32(pc + 20)); } int __glXDispSwap_GetConvolutionParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetConvolutionParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetConvolutionParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetConvolutionParameterfvEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetConvolutionParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetConvolutionParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetConvolutionParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetConvolutionParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetConvolutionParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetConvolutionParameterivEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetConvolutionParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetConvolutionParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetHistogramParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetHistogramParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetHistogramParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetHistogramParameterfvEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetHistogramParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetHistogramParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetHistogramParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetHistogramParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetHistogramParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetHistogramParameterivEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetHistogramParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetHistogramParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetMinmaxParameterfv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetMinmaxParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMinmaxParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetMinmaxParameterfvEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetMinmaxParameterfv_size(pname); GLfloat answerBuffer[200]; GLfloat *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMinmaxParameterfv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetMinmaxParameteriv(__GLXclientState * cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetMinmaxParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMinmaxParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetMinmaxParameterivEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetMinmaxParameteriv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); glGetMinmaxParameteriv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } void __glXDispSwap_Histogram(GLbyte * pc) { glHistogram((GLenum) bswap_ENUM(pc + 0), (GLsizei) bswap_CARD32(pc + 4), (GLenum) bswap_ENUM(pc + 8), *(GLboolean *) (pc + 12)); } void __glXDispSwap_Minmax(GLbyte * pc) { glMinmax((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), *(GLboolean *) (pc + 8)); } void __glXDispSwap_ResetHistogram(GLbyte * pc) { glResetHistogram((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_ResetMinmax(GLbyte * pc) { glResetMinmax((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_TexImage3D(GLbyte * pc) { const CARD32 ptr_is_null = *(CARD32 *) (pc + 76); const GLvoid *const pixels = (const GLvoid *) ((ptr_is_null != 0) ? NULL : (pc + 80)); __GLXpixel3DHeader *const hdr = (__GLXpixel3DHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (GLint) bswap_CARD32(&hdr->imageHeight)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_IMAGES, (GLint) bswap_CARD32(&hdr->skipImages)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glTexImage3D((GLenum) bswap_ENUM(pc + 36), (GLint) bswap_CARD32(pc + 40), (GLint) bswap_CARD32(pc + 44), (GLsizei) bswap_CARD32(pc + 48), (GLsizei) bswap_CARD32(pc + 52), (GLsizei) bswap_CARD32(pc + 56), (GLint) bswap_CARD32(pc + 64), (GLenum) bswap_ENUM(pc + 68), (GLenum) bswap_ENUM(pc + 72), pixels); } void __glXDispSwap_TexSubImage3D(GLbyte * pc) { const GLvoid *const pixels = (const GLvoid *) ((pc + 88)); __GLXpixel3DHeader *const hdr = (__GLXpixel3DHeader *) (pc); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) bswap_CARD32(&hdr->rowLength)); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (GLint) bswap_CARD32(&hdr->imageHeight)); glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) bswap_CARD32(&hdr->skipRows)); glPixelStorei(GL_UNPACK_SKIP_IMAGES, (GLint) bswap_CARD32(&hdr->skipImages)); glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) bswap_CARD32(&hdr->skipPixels)); glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) bswap_CARD32(&hdr->alignment)); glTexSubImage3D((GLenum) bswap_ENUM(pc + 36), (GLint) bswap_CARD32(pc + 40), (GLint) bswap_CARD32(pc + 44), (GLint) bswap_CARD32(pc + 48), (GLint) bswap_CARD32(pc + 52), (GLsizei) bswap_CARD32(pc + 60), (GLsizei) bswap_CARD32(pc + 64), (GLsizei) bswap_CARD32(pc + 68), (GLenum) bswap_ENUM(pc + 76), (GLenum) bswap_ENUM(pc + 80), pixels); } void __glXDispSwap_CopyTexSubImage3D(GLbyte * pc) { glCopyTexSubImage3D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16), (GLint) bswap_CARD32(pc + 20), (GLint) bswap_CARD32(pc + 24), (GLsizei) bswap_CARD32(pc + 28), (GLsizei) bswap_CARD32(pc + 32)); } void __glXDispSwap_ActiveTexture(GLbyte * pc) { glActiveTextureARB((GLenum) bswap_ENUM(pc + 0)); } void __glXDispSwap_MultiTexCoord1dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 12); pc -= 4; } #endif glMultiTexCoord1dvARB((GLenum) bswap_ENUM(pc + 8), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 1)); } void __glXDispSwap_MultiTexCoord1fvARB(GLbyte * pc) { glMultiTexCoord1fvARB((GLenum) bswap_ENUM(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 1)); } void __glXDispSwap_MultiTexCoord1iv(GLbyte * pc) { glMultiTexCoord1ivARB((GLenum) bswap_ENUM(pc + 0), (const GLint *) bswap_32_array((uint32_t *) (pc + 4), 1)); } void __glXDispSwap_MultiTexCoord1sv(GLbyte * pc) { glMultiTexCoord1svARB((GLenum) bswap_ENUM(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 1)); } void __glXDispSwap_MultiTexCoord2dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 20); pc -= 4; } #endif glMultiTexCoord2dvARB((GLenum) bswap_ENUM(pc + 16), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 2)); } void __glXDispSwap_MultiTexCoord2fvARB(GLbyte * pc) { glMultiTexCoord2fvARB((GLenum) bswap_ENUM(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 2)); } void __glXDispSwap_MultiTexCoord2iv(GLbyte * pc) { glMultiTexCoord2ivARB((GLenum) bswap_ENUM(pc + 0), (const GLint *) bswap_32_array((uint32_t *) (pc + 4), 2)); } void __glXDispSwap_MultiTexCoord2sv(GLbyte * pc) { glMultiTexCoord2svARB((GLenum) bswap_ENUM(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 2)); } void __glXDispSwap_MultiTexCoord3dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 28); pc -= 4; } #endif glMultiTexCoord3dvARB((GLenum) bswap_ENUM(pc + 24), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 3)); } void __glXDispSwap_MultiTexCoord3fvARB(GLbyte * pc) { glMultiTexCoord3fvARB((GLenum) bswap_ENUM(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 3)); } void __glXDispSwap_MultiTexCoord3iv(GLbyte * pc) { glMultiTexCoord3ivARB((GLenum) bswap_ENUM(pc + 0), (const GLint *) bswap_32_array((uint32_t *) (pc + 4), 3)); } void __glXDispSwap_MultiTexCoord3sv(GLbyte * pc) { glMultiTexCoord3svARB((GLenum) bswap_ENUM(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 3)); } void __glXDispSwap_MultiTexCoord4dv(GLbyte * pc) { #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 36); pc -= 4; } #endif glMultiTexCoord4dvARB((GLenum) bswap_ENUM(pc + 32), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 4)); } void __glXDispSwap_MultiTexCoord4fvARB(GLbyte * pc) { glMultiTexCoord4fvARB((GLenum) bswap_ENUM(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 4)); } void __glXDispSwap_MultiTexCoord4iv(GLbyte * pc) { glMultiTexCoord4ivARB((GLenum) bswap_ENUM(pc + 0), (const GLint *) bswap_32_array((uint32_t *) (pc + 4), 4)); } void __glXDispSwap_MultiTexCoord4sv(GLbyte * pc) { glMultiTexCoord4svARB((GLenum) bswap_ENUM(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 4)); } void __glXDispSwap_CompressedTexImage1D(GLbyte * pc) { PFNGLCOMPRESSEDTEXIMAGE1DPROC CompressedTexImage1D = __glGetProcAddress("glCompressedTexImage1D"); const GLsizei imageSize = (GLsizei) bswap_CARD32(pc + 20); CompressedTexImage1D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLsizei) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16), imageSize, (const GLvoid *) (pc + 24)); } void __glXDispSwap_CompressedTexImage2D(GLbyte * pc) { PFNGLCOMPRESSEDTEXIMAGE2DPROC CompressedTexImage2D = __glGetProcAddress("glCompressedTexImage2D"); const GLsizei imageSize = (GLsizei) bswap_CARD32(pc + 24); CompressedTexImage2D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLsizei) bswap_CARD32(pc + 12), (GLsizei) bswap_CARD32(pc + 16), (GLint) bswap_CARD32(pc + 20), imageSize, (const GLvoid *) (pc + 28)); } void __glXDispSwap_CompressedTexImage3D(GLbyte * pc) { PFNGLCOMPRESSEDTEXIMAGE3DPROC CompressedTexImage3D = __glGetProcAddress("glCompressedTexImage3D"); const GLsizei imageSize = (GLsizei) bswap_CARD32(pc + 28); CompressedTexImage3D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLsizei) bswap_CARD32(pc + 12), (GLsizei) bswap_CARD32(pc + 16), (GLsizei) bswap_CARD32(pc + 20), (GLint) bswap_CARD32(pc + 24), imageSize, (const GLvoid *) (pc + 32)); } void __glXDispSwap_CompressedTexSubImage1D(GLbyte * pc) { PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC CompressedTexSubImage1D = __glGetProcAddress("glCompressedTexSubImage1D"); const GLsizei imageSize = (GLsizei) bswap_CARD32(pc + 20); CompressedTexSubImage1D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLsizei) bswap_CARD32(pc + 12), (GLenum) bswap_ENUM(pc + 16), imageSize, (const GLvoid *) (pc + 24)); } void __glXDispSwap_CompressedTexSubImage2D(GLbyte * pc) { PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC CompressedTexSubImage2D = __glGetProcAddress("glCompressedTexSubImage2D"); const GLsizei imageSize = (GLsizei) bswap_CARD32(pc + 28); CompressedTexSubImage2D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLsizei) bswap_CARD32(pc + 16), (GLsizei) bswap_CARD32(pc + 20), (GLenum) bswap_ENUM(pc + 24), imageSize, (const GLvoid *) (pc + 32)); } void __glXDispSwap_CompressedTexSubImage3D(GLbyte * pc) { PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC CompressedTexSubImage3D = __glGetProcAddress("glCompressedTexSubImage3D"); const GLsizei imageSize = (GLsizei) bswap_CARD32(pc + 36); CompressedTexSubImage3D((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16), (GLsizei) bswap_CARD32(pc + 20), (GLsizei) bswap_CARD32(pc + 24), (GLsizei) bswap_CARD32(pc + 28), (GLenum) bswap_ENUM(pc + 32), imageSize, (const GLvoid *) (pc + 40)); } void __glXDispSwap_SampleCoverage(GLbyte * pc) { PFNGLSAMPLECOVERAGEPROC SampleCoverage = __glGetProcAddress("glSampleCoverage"); SampleCoverage((GLclampf) bswap_FLOAT32(pc + 0), *(GLboolean *) (pc + 4)); } void __glXDispSwap_BlendFuncSeparate(GLbyte * pc) { PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate = __glGetProcAddress("glBlendFuncSeparate"); BlendFuncSeparate((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLenum) bswap_ENUM(pc + 12)); } void __glXDispSwap_FogCoorddv(GLbyte * pc) { PFNGLFOGCOORDDVPROC FogCoorddv = __glGetProcAddress("glFogCoorddv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 8); pc -= 4; } #endif FogCoorddv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 1)); } void __glXDispSwap_PointParameterf(GLbyte * pc) { PFNGLPOINTPARAMETERFPROC PointParameterf = __glGetProcAddress("glPointParameterf"); PointParameterf((GLenum) bswap_ENUM(pc + 0), (GLfloat) bswap_FLOAT32(pc + 4)); } void __glXDispSwap_PointParameterfv(GLbyte * pc) { PFNGLPOINTPARAMETERFVPROC PointParameterfv = __glGetProcAddress("glPointParameterfv"); const GLenum pname = (GLenum) bswap_ENUM(pc + 0); const GLfloat *params; params = (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), __glPointParameterfv_size(pname)); PointParameterfv(pname, params); } void __glXDispSwap_PointParameteri(GLbyte * pc) { PFNGLPOINTPARAMETERIPROC PointParameteri = __glGetProcAddress("glPointParameteri"); PointParameteri((GLenum) bswap_ENUM(pc + 0), (GLint) bswap_CARD32(pc + 4)); } void __glXDispSwap_PointParameteriv(GLbyte * pc) { PFNGLPOINTPARAMETERIVPROC PointParameteriv = __glGetProcAddress("glPointParameteriv"); const GLenum pname = (GLenum) bswap_ENUM(pc + 0); const GLint *params; params = (const GLint *) bswap_32_array((uint32_t *) (pc + 4), __glPointParameteriv_size(pname)); PointParameteriv(pname, params); } void __glXDispSwap_SecondaryColor3bv(GLbyte * pc) { PFNGLSECONDARYCOLOR3BVPROC SecondaryColor3bv = __glGetProcAddress("glSecondaryColor3bv"); SecondaryColor3bv((const GLbyte *) (pc + 0)); } void __glXDispSwap_SecondaryColor3dv(GLbyte * pc) { PFNGLSECONDARYCOLOR3DVPROC SecondaryColor3dv = __glGetProcAddress("glSecondaryColor3dv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 24); pc -= 4; } #endif SecondaryColor3dv((const GLdouble *) bswap_64_array((uint64_t *) (pc + 0), 3)); } void __glXDispSwap_SecondaryColor3iv(GLbyte * pc) { PFNGLSECONDARYCOLOR3IVPROC SecondaryColor3iv = __glGetProcAddress("glSecondaryColor3iv"); SecondaryColor3iv((const GLint *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_SecondaryColor3sv(GLbyte * pc) { PFNGLSECONDARYCOLOR3SVPROC SecondaryColor3sv = __glGetProcAddress("glSecondaryColor3sv"); SecondaryColor3sv((const GLshort *) bswap_16_array((uint16_t *) (pc + 0), 3)); } void __glXDispSwap_SecondaryColor3ubv(GLbyte * pc) { PFNGLSECONDARYCOLOR3UBVPROC SecondaryColor3ubv = __glGetProcAddress("glSecondaryColor3ubv"); SecondaryColor3ubv((const GLubyte *) (pc + 0)); } void __glXDispSwap_SecondaryColor3uiv(GLbyte * pc) { PFNGLSECONDARYCOLOR3UIVPROC SecondaryColor3uiv = __glGetProcAddress("glSecondaryColor3uiv"); SecondaryColor3uiv((const GLuint *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_SecondaryColor3usv(GLbyte * pc) { PFNGLSECONDARYCOLOR3USVPROC SecondaryColor3usv = __glGetProcAddress("glSecondaryColor3usv"); SecondaryColor3usv((const GLushort *) bswap_16_array((uint16_t *) (pc + 0), 3)); } void __glXDispSwap_WindowPos3fv(GLbyte * pc) { PFNGLWINDOWPOS3FVPROC WindowPos3fv = __glGetProcAddress("glWindowPos3fv"); WindowPos3fv((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_BeginQuery(GLbyte * pc) { PFNGLBEGINQUERYPROC BeginQuery = __glGetProcAddress("glBeginQuery"); BeginQuery((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4)); } int __glXDispSwap_DeleteQueries(__GLXclientState * cl, GLbyte * pc) { PFNGLDELETEQUERIESPROC DeleteQueries = __glGetProcAddress("glDeleteQueries"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); DeleteQueries(n, (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 0)); error = Success; } return error; } void __glXDispSwap_EndQuery(GLbyte * pc) { PFNGLENDQUERYPROC EndQuery = __glGetProcAddress("glEndQuery"); EndQuery((GLenum) bswap_ENUM(pc + 0)); } int __glXDispSwap_GenQueries(__GLXclientState * cl, GLbyte * pc) { PFNGLGENQUERIESPROC GenQueries = __glGetProcAddress("glGenQueries"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); GLuint answerBuffer[200]; GLuint *ids = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (ids == NULL) return BadAlloc; GenQueries(n, ids); (void) bswap_32_array((uint32_t *) ids, n); __glXSendReplySwap(cl->client, ids, n, 4, GL_TRUE, 0); error = Success; } return error; } int __glXDispSwap_GetQueryObjectiv(__GLXclientState * cl, GLbyte * pc) { PFNGLGETQUERYOBJECTIVPROC GetQueryObjectiv = __glGetProcAddress("glGetQueryObjectiv"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetQueryObjectiv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); GetQueryObjectiv((GLuint) bswap_CARD32(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetQueryObjectuiv(__GLXclientState * cl, GLbyte * pc) { PFNGLGETQUERYOBJECTUIVPROC GetQueryObjectuiv = __glGetProcAddress("glGetQueryObjectuiv"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetQueryObjectuiv_size(pname); GLuint answerBuffer[200]; GLuint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); GetQueryObjectuiv((GLuint) bswap_CARD32(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetQueryiv(__GLXclientState * cl, GLbyte * pc) { PFNGLGETQUERYIVPROC GetQueryiv = __glGetProcAddress("glGetQueryiv"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetQueryiv_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); GetQueryiv((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_IsQuery(__GLXclientState * cl, GLbyte * pc) { PFNGLISQUERYPROC IsQuery = __glGetProcAddress("glIsQuery"); xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = IsQuery((GLuint) bswap_CARD32(pc + 0)); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDispSwap_BlendEquationSeparate(GLbyte * pc) { PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate = __glGetProcAddress("glBlendEquationSeparate"); BlendEquationSeparate((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4)); } void __glXDispSwap_DrawBuffers(GLbyte * pc) { PFNGLDRAWBUFFERSPROC DrawBuffers = __glGetProcAddress("glDrawBuffers"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); DrawBuffers(n, (const GLenum *) bswap_32_array((uint32_t *) (pc + 4), 0)); } void __glXDispSwap_VertexAttrib1dv(GLbyte * pc) { PFNGLVERTEXATTRIB1DVPROC VertexAttrib1dv = __glGetProcAddress("glVertexAttrib1dv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 12); pc -= 4; } #endif VertexAttrib1dv((GLuint) bswap_CARD32(pc + 0), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 4), 1)); } void __glXDispSwap_VertexAttrib1sv(GLbyte * pc) { PFNGLVERTEXATTRIB1SVPROC VertexAttrib1sv = __glGetProcAddress("glVertexAttrib1sv"); VertexAttrib1sv((GLuint) bswap_CARD32(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 1)); } void __glXDispSwap_VertexAttrib2dv(GLbyte * pc) { PFNGLVERTEXATTRIB2DVPROC VertexAttrib2dv = __glGetProcAddress("glVertexAttrib2dv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 20); pc -= 4; } #endif VertexAttrib2dv((GLuint) bswap_CARD32(pc + 0), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 4), 2)); } void __glXDispSwap_VertexAttrib2sv(GLbyte * pc) { PFNGLVERTEXATTRIB2SVPROC VertexAttrib2sv = __glGetProcAddress("glVertexAttrib2sv"); VertexAttrib2sv((GLuint) bswap_CARD32(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 2)); } void __glXDispSwap_VertexAttrib3dv(GLbyte * pc) { PFNGLVERTEXATTRIB3DVPROC VertexAttrib3dv = __glGetProcAddress("glVertexAttrib3dv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 28); pc -= 4; } #endif VertexAttrib3dv((GLuint) bswap_CARD32(pc + 0), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 4), 3)); } void __glXDispSwap_VertexAttrib3sv(GLbyte * pc) { PFNGLVERTEXATTRIB3SVPROC VertexAttrib3sv = __glGetProcAddress("glVertexAttrib3sv"); VertexAttrib3sv((GLuint) bswap_CARD32(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 3)); } void __glXDispSwap_VertexAttrib4Nbv(GLbyte * pc) { PFNGLVERTEXATTRIB4NBVPROC VertexAttrib4Nbv = __glGetProcAddress("glVertexAttrib4Nbv"); VertexAttrib4Nbv((GLuint) bswap_CARD32(pc + 0), (const GLbyte *) (pc + 4)); } void __glXDispSwap_VertexAttrib4Niv(GLbyte * pc) { PFNGLVERTEXATTRIB4NIVPROC VertexAttrib4Niv = __glGetProcAddress("glVertexAttrib4Niv"); VertexAttrib4Niv((GLuint) bswap_CARD32(pc + 0), (const GLint *) bswap_32_array((uint32_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4Nsv(GLbyte * pc) { PFNGLVERTEXATTRIB4NSVPROC VertexAttrib4Nsv = __glGetProcAddress("glVertexAttrib4Nsv"); VertexAttrib4Nsv((GLuint) bswap_CARD32(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4Nubv(GLbyte * pc) { PFNGLVERTEXATTRIB4NUBVPROC VertexAttrib4Nubv = __glGetProcAddress("glVertexAttrib4Nubv"); VertexAttrib4Nubv((GLuint) bswap_CARD32(pc + 0), (const GLubyte *) (pc + 4)); } void __glXDispSwap_VertexAttrib4Nuiv(GLbyte * pc) { PFNGLVERTEXATTRIB4NUIVPROC VertexAttrib4Nuiv = __glGetProcAddress("glVertexAttrib4Nuiv"); VertexAttrib4Nuiv((GLuint) bswap_CARD32(pc + 0), (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4Nusv(GLbyte * pc) { PFNGLVERTEXATTRIB4NUSVPROC VertexAttrib4Nusv = __glGetProcAddress("glVertexAttrib4Nusv"); VertexAttrib4Nusv((GLuint) bswap_CARD32(pc + 0), (const GLushort *) bswap_16_array((uint16_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4bv(GLbyte * pc) { PFNGLVERTEXATTRIB4BVPROC VertexAttrib4bv = __glGetProcAddress("glVertexAttrib4bv"); VertexAttrib4bv((GLuint) bswap_CARD32(pc + 0), (const GLbyte *) (pc + 4)); } void __glXDispSwap_VertexAttrib4dv(GLbyte * pc) { PFNGLVERTEXATTRIB4DVPROC VertexAttrib4dv = __glGetProcAddress("glVertexAttrib4dv"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 36); pc -= 4; } #endif VertexAttrib4dv((GLuint) bswap_CARD32(pc + 0), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4iv(GLbyte * pc) { PFNGLVERTEXATTRIB4IVPROC VertexAttrib4iv = __glGetProcAddress("glVertexAttrib4iv"); VertexAttrib4iv((GLuint) bswap_CARD32(pc + 0), (const GLint *) bswap_32_array((uint32_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4sv(GLbyte * pc) { PFNGLVERTEXATTRIB4SVPROC VertexAttrib4sv = __glGetProcAddress("glVertexAttrib4sv"); VertexAttrib4sv((GLuint) bswap_CARD32(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4ubv(GLbyte * pc) { PFNGLVERTEXATTRIB4UBVPROC VertexAttrib4ubv = __glGetProcAddress("glVertexAttrib4ubv"); VertexAttrib4ubv((GLuint) bswap_CARD32(pc + 0), (const GLubyte *) (pc + 4)); } void __glXDispSwap_VertexAttrib4uiv(GLbyte * pc) { PFNGLVERTEXATTRIB4UIVPROC VertexAttrib4uiv = __glGetProcAddress("glVertexAttrib4uiv"); VertexAttrib4uiv((GLuint) bswap_CARD32(pc + 0), (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4usv(GLbyte * pc) { PFNGLVERTEXATTRIB4USVPROC VertexAttrib4usv = __glGetProcAddress("glVertexAttrib4usv"); VertexAttrib4usv((GLuint) bswap_CARD32(pc + 0), (const GLushort *) bswap_16_array((uint16_t *) (pc + 4), 4)); } void __glXDispSwap_ClampColor(GLbyte * pc) { PFNGLCLAMPCOLORPROC ClampColor = __glGetProcAddress("glClampColor"); ClampColor((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4)); } void __glXDispSwap_BindProgramARB(GLbyte * pc) { PFNGLBINDPROGRAMARBPROC BindProgramARB = __glGetProcAddress("glBindProgramARB"); BindProgramARB((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4)); } int __glXDispSwap_DeleteProgramsARB(__GLXclientState * cl, GLbyte * pc) { PFNGLDELETEPROGRAMSARBPROC DeleteProgramsARB = __glGetProcAddress("glDeleteProgramsARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); DeleteProgramsARB(n, (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 0)); error = Success; } return error; } int __glXDispSwap_GenProgramsARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGENPROGRAMSARBPROC GenProgramsARB = __glGetProcAddress("glGenProgramsARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); GLuint answerBuffer[200]; GLuint *programs = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (programs == NULL) return BadAlloc; GenProgramsARB(n, programs); (void) bswap_32_array((uint32_t *) programs, n); __glXSendReplySwap(cl->client, programs, n, 4, GL_TRUE, 0); error = Success; } return error; } int __glXDispSwap_GetProgramEnvParameterdvARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGETPROGRAMENVPARAMETERDVARBPROC GetProgramEnvParameterdvARB = __glGetProcAddress("glGetProgramEnvParameterdvARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLdouble params[4]; GetProgramEnvParameterdvARB((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4), params); (void) bswap_64_array((uint64_t *) params, 4); __glXSendReplySwap(cl->client, params, 4, 8, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetProgramEnvParameterfvARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGETPROGRAMENVPARAMETERFVARBPROC GetProgramEnvParameterfvARB = __glGetProcAddress("glGetProgramEnvParameterfvARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLfloat params[4]; GetProgramEnvParameterfvARB((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4), params); (void) bswap_32_array((uint32_t *) params, 4); __glXSendReplySwap(cl->client, params, 4, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetProgramLocalParameterdvARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC GetProgramLocalParameterdvARB = __glGetProcAddress("glGetProgramLocalParameterdvARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLdouble params[4]; GetProgramLocalParameterdvARB((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4), params); (void) bswap_64_array((uint64_t *) params, 4); __glXSendReplySwap(cl->client, params, 4, 8, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetProgramLocalParameterfvARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC GetProgramLocalParameterfvARB = __glGetProcAddress("glGetProgramLocalParameterfvARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLfloat params[4]; GetProgramLocalParameterfvARB((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4), params); (void) bswap_32_array((uint32_t *) params, 4); __glXSendReplySwap(cl->client, params, 4, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetProgramivARB(__GLXclientState * cl, GLbyte * pc) { PFNGLGETPROGRAMIVARBPROC GetProgramivARB = __glGetProcAddress("glGetProgramivARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLenum pname = (GLenum) bswap_ENUM(pc + 4); const GLuint compsize = __glGetProgramivARB_size(pname); GLint answerBuffer[200]; GLint *params = __glXGetAnswerBuffer(cl, compsize * 4, answerBuffer, sizeof(answerBuffer), 4); if (params == NULL) return BadAlloc; __glXClearErrorOccured(); GetProgramivARB((GLenum) bswap_ENUM(pc + 0), pname, params); (void) bswap_32_array((uint32_t *) params, compsize); __glXSendReplySwap(cl->client, params, compsize, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_IsProgramARB(__GLXclientState * cl, GLbyte * pc) { PFNGLISPROGRAMARBPROC IsProgramARB = __glGetProcAddress("glIsProgramARB"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = IsProgramARB((GLuint) bswap_CARD32(pc + 0)); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDispSwap_ProgramEnvParameter4dvARB(GLbyte * pc) { PFNGLPROGRAMENVPARAMETER4DVARBPROC ProgramEnvParameter4dvARB = __glGetProcAddress("glProgramEnvParameter4dvARB"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 40); pc -= 4; } #endif ProgramEnvParameter4dvARB((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 8), 4)); } void __glXDispSwap_ProgramEnvParameter4fvARB(GLbyte * pc) { PFNGLPROGRAMENVPARAMETER4FVARBPROC ProgramEnvParameter4fvARB = __glGetProcAddress("glProgramEnvParameter4fvARB"); ProgramEnvParameter4fvARB((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), 4)); } void __glXDispSwap_ProgramLocalParameter4dvARB(GLbyte * pc) { PFNGLPROGRAMLOCALPARAMETER4DVARBPROC ProgramLocalParameter4dvARB = __glGetProcAddress("glProgramLocalParameter4dvARB"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 40); pc -= 4; } #endif ProgramLocalParameter4dvARB((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 8), 4)); } void __glXDispSwap_ProgramLocalParameter4fvARB(GLbyte * pc) { PFNGLPROGRAMLOCALPARAMETER4FVARBPROC ProgramLocalParameter4fvARB = __glGetProcAddress("glProgramLocalParameter4fvARB"); ProgramLocalParameter4fvARB((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), 4)); } void __glXDispSwap_ProgramStringARB(GLbyte * pc) { PFNGLPROGRAMSTRINGARBPROC ProgramStringARB = __glGetProcAddress("glProgramStringARB"); const GLsizei len = (GLsizei) bswap_CARD32(pc + 8); ProgramStringARB((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), len, (const GLvoid *) (pc + 12)); } void __glXDispSwap_VertexAttrib1fvARB(GLbyte * pc) { PFNGLVERTEXATTRIB1FVARBPROC VertexAttrib1fvARB = __glGetProcAddress("glVertexAttrib1fvARB"); VertexAttrib1fvARB((GLuint) bswap_CARD32(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 1)); } void __glXDispSwap_VertexAttrib2fvARB(GLbyte * pc) { PFNGLVERTEXATTRIB2FVARBPROC VertexAttrib2fvARB = __glGetProcAddress("glVertexAttrib2fvARB"); VertexAttrib2fvARB((GLuint) bswap_CARD32(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 2)); } void __glXDispSwap_VertexAttrib3fvARB(GLbyte * pc) { PFNGLVERTEXATTRIB3FVARBPROC VertexAttrib3fvARB = __glGetProcAddress("glVertexAttrib3fvARB"); VertexAttrib3fvARB((GLuint) bswap_CARD32(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 3)); } void __glXDispSwap_VertexAttrib4fvARB(GLbyte * pc) { PFNGLVERTEXATTRIB4FVARBPROC VertexAttrib4fvARB = __glGetProcAddress("glVertexAttrib4fvARB"); VertexAttrib4fvARB((GLuint) bswap_CARD32(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 4)); } void __glXDispSwap_BindFramebuffer(GLbyte * pc) { PFNGLBINDFRAMEBUFFERPROC BindFramebuffer = __glGetProcAddress("glBindFramebuffer"); BindFramebuffer((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4)); } void __glXDispSwap_BindRenderbuffer(GLbyte * pc) { PFNGLBINDRENDERBUFFERPROC BindRenderbuffer = __glGetProcAddress("glBindRenderbuffer"); BindRenderbuffer((GLenum) bswap_ENUM(pc + 0), (GLuint) bswap_CARD32(pc + 4)); } void __glXDispSwap_BlitFramebuffer(GLbyte * pc) { PFNGLBLITFRAMEBUFFERPROC BlitFramebuffer = __glGetProcAddress("glBlitFramebuffer"); BlitFramebuffer((GLint) bswap_CARD32(pc + 0), (GLint) bswap_CARD32(pc + 4), (GLint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16), (GLint) bswap_CARD32(pc + 20), (GLint) bswap_CARD32(pc + 24), (GLint) bswap_CARD32(pc + 28), (GLbitfield) bswap_CARD32(pc + 32), (GLenum) bswap_ENUM(pc + 36)); } int __glXDispSwap_CheckFramebufferStatus(__GLXclientState * cl, GLbyte * pc) { PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus = __glGetProcAddress("glCheckFramebufferStatus"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLenum retval; retval = CheckFramebufferStatus((GLenum) bswap_ENUM(pc + 0)); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDispSwap_DeleteFramebuffers(GLbyte * pc) { PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers = __glGetProcAddress("glDeleteFramebuffers"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); DeleteFramebuffers(n, (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 0)); } void __glXDispSwap_DeleteRenderbuffers(GLbyte * pc) { PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers = __glGetProcAddress("glDeleteRenderbuffers"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); DeleteRenderbuffers(n, (const GLuint *) bswap_32_array((uint32_t *) (pc + 4), 0)); } void __glXDispSwap_FramebufferRenderbuffer(GLbyte * pc) { PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer = __glGetProcAddress("glFramebufferRenderbuffer"); FramebufferRenderbuffer((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLuint) bswap_CARD32(pc + 12)); } void __glXDispSwap_FramebufferTexture1D(GLbyte * pc) { PFNGLFRAMEBUFFERTEXTURE1DPROC FramebufferTexture1D = __glGetProcAddress("glFramebufferTexture1D"); FramebufferTexture1D((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLuint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16)); } void __glXDispSwap_FramebufferTexture2D(GLbyte * pc) { PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D = __glGetProcAddress("glFramebufferTexture2D"); FramebufferTexture2D((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLuint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16)); } void __glXDispSwap_FramebufferTexture3D(GLbyte * pc) { PFNGLFRAMEBUFFERTEXTURE3DPROC FramebufferTexture3D = __glGetProcAddress("glFramebufferTexture3D"); FramebufferTexture3D((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLuint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16), (GLint) bswap_CARD32(pc + 20)); } void __glXDispSwap_FramebufferTextureLayer(GLbyte * pc) { PFNGLFRAMEBUFFERTEXTURELAYERPROC FramebufferTextureLayer = __glGetProcAddress("glFramebufferTextureLayer"); FramebufferTextureLayer((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLuint) bswap_CARD32(pc + 8), (GLint) bswap_CARD32(pc + 12), (GLint) bswap_CARD32(pc + 16)); } int __glXDispSwap_GenFramebuffers(__GLXclientState * cl, GLbyte * pc) { PFNGLGENFRAMEBUFFERSPROC GenFramebuffers = __glGetProcAddress("glGenFramebuffers"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); GLuint answerBuffer[200]; GLuint *framebuffers = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (framebuffers == NULL) return BadAlloc; GenFramebuffers(n, framebuffers); (void) bswap_32_array((uint32_t *) framebuffers, n); __glXSendReplySwap(cl->client, framebuffers, n, 4, GL_TRUE, 0); error = Success; } return error; } int __glXDispSwap_GenRenderbuffers(__GLXclientState * cl, GLbyte * pc) { PFNGLGENRENDERBUFFERSPROC GenRenderbuffers = __glGetProcAddress("glGenRenderbuffers"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { const GLsizei n = (GLsizei) bswap_CARD32(pc + 0); GLuint answerBuffer[200]; GLuint *renderbuffers = __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), 4); if (renderbuffers == NULL) return BadAlloc; GenRenderbuffers(n, renderbuffers); (void) bswap_32_array((uint32_t *) renderbuffers, n); __glXSendReplySwap(cl->client, renderbuffers, n, 4, GL_TRUE, 0); error = Success; } return error; } void __glXDispSwap_GenerateMipmap(GLbyte * pc) { PFNGLGENERATEMIPMAPPROC GenerateMipmap = __glGetProcAddress("glGenerateMipmap"); GenerateMipmap((GLenum) bswap_ENUM(pc + 0)); } int __glXDispSwap_GetFramebufferAttachmentParameteriv(__GLXclientState * cl, GLbyte * pc) { PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetFramebufferAttachmentParameteriv = __glGetProcAddress("glGetFramebufferAttachmentParameteriv"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLint params[1]; GetFramebufferAttachmentParameteriv((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLenum) bswap_ENUM(pc + 8), params); (void) bswap_32_array((uint32_t *) params, 1); __glXSendReplySwap(cl->client, params, 1, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_GetRenderbufferParameteriv(__GLXclientState * cl, GLbyte * pc) { PFNGLGETRENDERBUFFERPARAMETERIVPROC GetRenderbufferParameteriv = __glGetProcAddress("glGetRenderbufferParameteriv"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLint params[1]; GetRenderbufferParameteriv((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), params); (void) bswap_32_array((uint32_t *) params, 1); __glXSendReplySwap(cl->client, params, 1, 4, GL_FALSE, 0); error = Success; } return error; } int __glXDispSwap_IsFramebuffer(__GLXclientState * cl, GLbyte * pc) { PFNGLISFRAMEBUFFERPROC IsFramebuffer = __glGetProcAddress("glIsFramebuffer"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = IsFramebuffer((GLuint) bswap_CARD32(pc + 0)); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } int __glXDispSwap_IsRenderbuffer(__GLXclientState * cl, GLbyte * pc) { PFNGLISRENDERBUFFERPROC IsRenderbuffer = __glGetProcAddress("glIsRenderbuffer"); xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_CARD32(&req->contextTag), &error); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLboolean retval; retval = IsRenderbuffer((GLuint) bswap_CARD32(pc + 0)); __glXSendReplySwap(cl->client, dummy_answer, 0, 0, GL_FALSE, retval); error = Success; } return error; } void __glXDispSwap_RenderbufferStorage(GLbyte * pc) { PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage = __glGetProcAddress("glRenderbufferStorage"); RenderbufferStorage((GLenum) bswap_ENUM(pc + 0), (GLenum) bswap_ENUM(pc + 4), (GLsizei) bswap_CARD32(pc + 8), (GLsizei) bswap_CARD32(pc + 12)); } void __glXDispSwap_RenderbufferStorageMultisample(GLbyte * pc) { PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC RenderbufferStorageMultisample = __glGetProcAddress("glRenderbufferStorageMultisample"); RenderbufferStorageMultisample((GLenum) bswap_ENUM(pc + 0), (GLsizei) bswap_CARD32(pc + 4), (GLenum) bswap_ENUM(pc + 8), (GLsizei) bswap_CARD32(pc + 12), (GLsizei) bswap_CARD32(pc + 16)); } void __glXDispSwap_SecondaryColor3fvEXT(GLbyte * pc) { PFNGLSECONDARYCOLOR3FVEXTPROC SecondaryColor3fvEXT = __glGetProcAddress("glSecondaryColor3fvEXT"); SecondaryColor3fvEXT((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 3)); } void __glXDispSwap_FogCoordfvEXT(GLbyte * pc) { PFNGLFOGCOORDFVEXTPROC FogCoordfvEXT = __glGetProcAddress("glFogCoordfvEXT"); FogCoordfvEXT((const GLfloat *) bswap_32_array((uint32_t *) (pc + 0), 1)); } void __glXDispSwap_VertexAttrib1dvNV(GLbyte * pc) { PFNGLVERTEXATTRIB1DVNVPROC VertexAttrib1dvNV = __glGetProcAddress("glVertexAttrib1dvNV"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 12); pc -= 4; } #endif VertexAttrib1dvNV((GLuint) bswap_CARD32(pc + 0), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 4), 1)); } void __glXDispSwap_VertexAttrib1fvNV(GLbyte * pc) { PFNGLVERTEXATTRIB1FVNVPROC VertexAttrib1fvNV = __glGetProcAddress("glVertexAttrib1fvNV"); VertexAttrib1fvNV((GLuint) bswap_CARD32(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 1)); } void __glXDispSwap_VertexAttrib1svNV(GLbyte * pc) { PFNGLVERTEXATTRIB1SVNVPROC VertexAttrib1svNV = __glGetProcAddress("glVertexAttrib1svNV"); VertexAttrib1svNV((GLuint) bswap_CARD32(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 1)); } void __glXDispSwap_VertexAttrib2dvNV(GLbyte * pc) { PFNGLVERTEXATTRIB2DVNVPROC VertexAttrib2dvNV = __glGetProcAddress("glVertexAttrib2dvNV"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 20); pc -= 4; } #endif VertexAttrib2dvNV((GLuint) bswap_CARD32(pc + 0), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 4), 2)); } void __glXDispSwap_VertexAttrib2fvNV(GLbyte * pc) { PFNGLVERTEXATTRIB2FVNVPROC VertexAttrib2fvNV = __glGetProcAddress("glVertexAttrib2fvNV"); VertexAttrib2fvNV((GLuint) bswap_CARD32(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 2)); } void __glXDispSwap_VertexAttrib2svNV(GLbyte * pc) { PFNGLVERTEXATTRIB2SVNVPROC VertexAttrib2svNV = __glGetProcAddress("glVertexAttrib2svNV"); VertexAttrib2svNV((GLuint) bswap_CARD32(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 2)); } void __glXDispSwap_VertexAttrib3dvNV(GLbyte * pc) { PFNGLVERTEXATTRIB3DVNVPROC VertexAttrib3dvNV = __glGetProcAddress("glVertexAttrib3dvNV"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 28); pc -= 4; } #endif VertexAttrib3dvNV((GLuint) bswap_CARD32(pc + 0), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 4), 3)); } void __glXDispSwap_VertexAttrib3fvNV(GLbyte * pc) { PFNGLVERTEXATTRIB3FVNVPROC VertexAttrib3fvNV = __glGetProcAddress("glVertexAttrib3fvNV"); VertexAttrib3fvNV((GLuint) bswap_CARD32(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 3)); } void __glXDispSwap_VertexAttrib3svNV(GLbyte * pc) { PFNGLVERTEXATTRIB3SVNVPROC VertexAttrib3svNV = __glGetProcAddress("glVertexAttrib3svNV"); VertexAttrib3svNV((GLuint) bswap_CARD32(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 3)); } void __glXDispSwap_VertexAttrib4dvNV(GLbyte * pc) { PFNGLVERTEXATTRIB4DVNVPROC VertexAttrib4dvNV = __glGetProcAddress("glVertexAttrib4dvNV"); #ifdef __GLX_ALIGN64 if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, 36); pc -= 4; } #endif VertexAttrib4dvNV((GLuint) bswap_CARD32(pc + 0), (const GLdouble *) bswap_64_array((uint64_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4fvNV(GLbyte * pc) { PFNGLVERTEXATTRIB4FVNVPROC VertexAttrib4fvNV = __glGetProcAddress("glVertexAttrib4fvNV"); VertexAttrib4fvNV((GLuint) bswap_CARD32(pc + 0), (const GLfloat *) bswap_32_array((uint32_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4svNV(GLbyte * pc) { PFNGLVERTEXATTRIB4SVNVPROC VertexAttrib4svNV = __glGetProcAddress("glVertexAttrib4svNV"); VertexAttrib4svNV((GLuint) bswap_CARD32(pc + 0), (const GLshort *) bswap_16_array((uint16_t *) (pc + 4), 4)); } void __glXDispSwap_VertexAttrib4ubvNV(GLbyte * pc) { PFNGLVERTEXATTRIB4UBVNVPROC VertexAttrib4ubvNV = __glGetProcAddress("glVertexAttrib4ubvNV"); VertexAttrib4ubvNV((GLuint) bswap_CARD32(pc + 0), (const GLubyte *) (pc + 4)); } void __glXDispSwap_VertexAttribs1dvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS1DVNVPROC VertexAttribs1dvNV = __glGetProcAddress("glVertexAttribs1dvNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); #ifdef __GLX_ALIGN64 const GLuint cmdlen = 12 + __GLX_PAD((n * 8)) - 4; if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, cmdlen); pc -= 4; } #endif VertexAttribs1dvNV((GLuint) bswap_CARD32(pc + 0), n, (const GLdouble *) bswap_64_array((uint64_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs1fvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS1FVNVPROC VertexAttribs1fvNV = __glGetProcAddress("glVertexAttribs1fvNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); VertexAttribs1fvNV((GLuint) bswap_CARD32(pc + 0), n, (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs1svNV(GLbyte * pc) { PFNGLVERTEXATTRIBS1SVNVPROC VertexAttribs1svNV = __glGetProcAddress("glVertexAttribs1svNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); VertexAttribs1svNV((GLuint) bswap_CARD32(pc + 0), n, (const GLshort *) bswap_16_array((uint16_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs2dvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS2DVNVPROC VertexAttribs2dvNV = __glGetProcAddress("glVertexAttribs2dvNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); #ifdef __GLX_ALIGN64 const GLuint cmdlen = 12 + __GLX_PAD((n * 16)) - 4; if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, cmdlen); pc -= 4; } #endif VertexAttribs2dvNV((GLuint) bswap_CARD32(pc + 0), n, (const GLdouble *) bswap_64_array((uint64_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs2fvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS2FVNVPROC VertexAttribs2fvNV = __glGetProcAddress("glVertexAttribs2fvNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); VertexAttribs2fvNV((GLuint) bswap_CARD32(pc + 0), n, (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs2svNV(GLbyte * pc) { PFNGLVERTEXATTRIBS2SVNVPROC VertexAttribs2svNV = __glGetProcAddress("glVertexAttribs2svNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); VertexAttribs2svNV((GLuint) bswap_CARD32(pc + 0), n, (const GLshort *) bswap_16_array((uint16_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs3dvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS3DVNVPROC VertexAttribs3dvNV = __glGetProcAddress("glVertexAttribs3dvNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); #ifdef __GLX_ALIGN64 const GLuint cmdlen = 12 + __GLX_PAD((n * 24)) - 4; if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, cmdlen); pc -= 4; } #endif VertexAttribs3dvNV((GLuint) bswap_CARD32(pc + 0), n, (const GLdouble *) bswap_64_array((uint64_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs3fvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS3FVNVPROC VertexAttribs3fvNV = __glGetProcAddress("glVertexAttribs3fvNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); VertexAttribs3fvNV((GLuint) bswap_CARD32(pc + 0), n, (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs3svNV(GLbyte * pc) { PFNGLVERTEXATTRIBS3SVNVPROC VertexAttribs3svNV = __glGetProcAddress("glVertexAttribs3svNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); VertexAttribs3svNV((GLuint) bswap_CARD32(pc + 0), n, (const GLshort *) bswap_16_array((uint16_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs4dvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS4DVNVPROC VertexAttribs4dvNV = __glGetProcAddress("glVertexAttribs4dvNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); #ifdef __GLX_ALIGN64 const GLuint cmdlen = 12 + __GLX_PAD((n * 32)) - 4; if ((unsigned long) (pc) & 7) { (void) memmove(pc - 4, pc, cmdlen); pc -= 4; } #endif VertexAttribs4dvNV((GLuint) bswap_CARD32(pc + 0), n, (const GLdouble *) bswap_64_array((uint64_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs4fvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS4FVNVPROC VertexAttribs4fvNV = __glGetProcAddress("glVertexAttribs4fvNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); VertexAttribs4fvNV((GLuint) bswap_CARD32(pc + 0), n, (const GLfloat *) bswap_32_array((uint32_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs4svNV(GLbyte * pc) { PFNGLVERTEXATTRIBS4SVNVPROC VertexAttribs4svNV = __glGetProcAddress("glVertexAttribs4svNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); VertexAttribs4svNV((GLuint) bswap_CARD32(pc + 0), n, (const GLshort *) bswap_16_array((uint16_t *) (pc + 8), 0)); } void __glXDispSwap_VertexAttribs4ubvNV(GLbyte * pc) { PFNGLVERTEXATTRIBS4UBVNVPROC VertexAttribs4ubvNV = __glGetProcAddress("glVertexAttribs4ubvNV"); const GLsizei n = (GLsizei) bswap_CARD32(pc + 4); VertexAttribs4ubvNV((GLuint) bswap_CARD32(pc + 0), n, (const GLubyte *) (pc + 8)); } void __glXDispSwap_ActiveStencilFaceEXT(GLbyte * pc) { PFNGLACTIVESTENCILFACEEXTPROC ActiveStencilFaceEXT = __glGetProcAddress("glActiveStencilFaceEXT"); ActiveStencilFaceEXT((GLenum) bswap_ENUM(pc + 0)); } xorg-server-1.20.13/glx/indirect_reqsize.c0000644000175000017500000005212414100573756015377 00000000000000/* DO NOT EDIT - This file generated automatically by glX_proto_size.py (from Mesa) script */ /* * (C) Copyright IBM Corporation 2005 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include "glxserver.h" #include "glxbyteorder.h" #include "indirect_size.h" #include "indirect_reqsize.h" #if defined(__CYGWIN__) || defined(__MINGW32__) #undef HAVE_ALIAS #endif #ifdef HAVE_ALIAS #define ALIAS2(from,to) \ GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \ __attribute__ ((alias( # to ))); #define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize ) #else #define ALIAS(from,to) \ GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \ { return __glX ## to ## ReqSize( pc, swap, reqlen ); } #endif int __glXCallListsReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei n = *(GLsizei *) (pc + 0); GLenum type = *(GLenum *) (pc + 4); GLsizei compsize; if (swap) { n = bswap_32(n); type = bswap_32(type); } compsize = __glCallLists_size(type); return safe_pad(safe_mul(compsize, n)); } int __glXBitmapReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); GLsizei width = *(GLsizei *) (pc + 20); GLsizei height = *(GLsizei *) (pc + 24); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); width = bswap_32(width); height = bswap_32(height); } return __glXImageSize(GL_COLOR_INDEX, GL_BITMAP, 0, width, height, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXFogfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 0); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glFogfv_size(pname); return safe_pad(safe_mul(compsize, 4)); } int __glXLightfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 4); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glLightfv_size(pname); return safe_pad(safe_mul(compsize, 4)); } int __glXLightModelfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 0); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glLightModelfv_size(pname); return safe_pad(safe_mul(compsize, 4)); } int __glXMaterialfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 4); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glMaterialfv_size(pname); return safe_pad(safe_mul(compsize, 4)); } int __glXPolygonStippleReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); } return __glXImageSize(GL_COLOR_INDEX, GL_BITMAP, 0, 32, 32, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXTexParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 4); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glTexParameterfv_size(pname); return safe_pad(safe_mul(compsize, 4)); } int __glXTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); GLenum target = *(GLenum *) (pc + 20); GLsizei width = *(GLsizei *) (pc + 32); GLenum format = *(GLenum *) (pc + 44); GLenum type = *(GLenum *) (pc + 48); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); target = bswap_32(target); width = bswap_32(width); format = bswap_32(format); type = bswap_32(type); } return __glXImageSize(format, type, target, width, 1, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); GLenum target = *(GLenum *) (pc + 20); GLsizei width = *(GLsizei *) (pc + 32); GLsizei height = *(GLsizei *) (pc + 36); GLenum format = *(GLenum *) (pc + 44); GLenum type = *(GLenum *) (pc + 48); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); target = bswap_32(target); width = bswap_32(width); height = bswap_32(height); format = bswap_32(format); type = bswap_32(type); } return __glXImageSize(format, type, target, width, height, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 4); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glTexEnvfv_size(pname); return safe_pad(safe_mul(compsize, 4)); } int __glXTexGendvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 4); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glTexGendv_size(pname); return safe_pad(safe_mul(compsize, 8)); } int __glXTexGenfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 4); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glTexGenfv_size(pname); return safe_pad(safe_mul(compsize, 4)); } int __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei mapsize = *(GLsizei *) (pc + 4); if (swap) { mapsize = bswap_32(mapsize); } return safe_pad(safe_mul(mapsize, 4)); } int __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei mapsize = *(GLsizei *) (pc + 4); if (swap) { mapsize = bswap_32(mapsize); } return safe_pad(safe_mul(mapsize, 2)); } int __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); GLsizei width = *(GLsizei *) (pc + 20); GLsizei height = *(GLsizei *) (pc + 24); GLenum format = *(GLenum *) (pc + 28); GLenum type = *(GLenum *) (pc + 32); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); width = bswap_32(width); height = bswap_32(height); format = bswap_32(format); type = bswap_32(type); } return __glXImageSize(format, type, 0, width, height, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei n = *(GLsizei *) (pc + 0); if (swap) { n = bswap_32(n); } return safe_pad(safe_add(safe_mul(n, 4), safe_mul(n, 4))); } int __glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); GLenum target = *(GLenum *) (pc + 20); GLsizei width = *(GLsizei *) (pc + 36); GLenum format = *(GLenum *) (pc + 44); GLenum type = *(GLenum *) (pc + 48); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); target = bswap_32(target); width = bswap_32(width); format = bswap_32(format); type = bswap_32(type); } return __glXImageSize(format, type, target, width, 1, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); GLenum target = *(GLenum *) (pc + 20); GLsizei width = *(GLsizei *) (pc + 36); GLsizei height = *(GLsizei *) (pc + 40); GLenum format = *(GLenum *) (pc + 44); GLenum type = *(GLenum *) (pc + 48); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); target = bswap_32(target); width = bswap_32(width); height = bswap_32(height); format = bswap_32(format); type = bswap_32(type); } return __glXImageSize(format, type, target, width, height, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXColorTableReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); GLenum target = *(GLenum *) (pc + 20); GLsizei width = *(GLsizei *) (pc + 28); GLenum format = *(GLenum *) (pc + 32); GLenum type = *(GLenum *) (pc + 36); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); target = bswap_32(target); width = bswap_32(width); format = bswap_32(format); type = bswap_32(type); } return __glXImageSize(format, type, target, width, 1, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 4); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glColorTableParameterfv_size(pname); return safe_pad(safe_mul(compsize, 4)); } int __glXColorSubTableReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); GLenum target = *(GLenum *) (pc + 20); GLsizei count = *(GLsizei *) (pc + 28); GLenum format = *(GLenum *) (pc + 32); GLenum type = *(GLenum *) (pc + 36); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); target = bswap_32(target); count = bswap_32(count); format = bswap_32(format); type = bswap_32(type); } return __glXImageSize(format, type, target, count, 1, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); GLenum target = *(GLenum *) (pc + 20); GLsizei width = *(GLsizei *) (pc + 28); GLenum format = *(GLenum *) (pc + 36); GLenum type = *(GLenum *) (pc + 40); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); target = bswap_32(target); width = bswap_32(width); format = bswap_32(format); type = bswap_32(type); } return __glXImageSize(format, type, target, width, 1, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = 0; GLint skip_images = 0; GLint skip_rows = *(GLint *) (pc + 8); GLint alignment = *(GLint *) (pc + 16); GLenum target = *(GLenum *) (pc + 20); GLsizei width = *(GLsizei *) (pc + 28); GLsizei height = *(GLsizei *) (pc + 32); GLenum format = *(GLenum *) (pc + 36); GLenum type = *(GLenum *) (pc + 40); if (swap) { row_length = bswap_32(row_length); skip_rows = bswap_32(skip_rows); alignment = bswap_32(alignment); target = bswap_32(target); width = bswap_32(width); height = bswap_32(height); format = bswap_32(format); type = bswap_32(type); } return __glXImageSize(format, type, target, width, height, 1, image_height, row_length, skip_images, skip_rows, alignment); } int __glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 4); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glConvolutionParameterfv_size(pname); return safe_pad(safe_mul(compsize, 4)); } int __glXTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = *(GLint *) (pc + 8); GLint skip_rows = *(GLint *) (pc + 16); GLint skip_images = *(GLint *) (pc + 20); GLint alignment = *(GLint *) (pc + 32); GLenum target = *(GLenum *) (pc + 36); GLsizei width = *(GLsizei *) (pc + 48); GLsizei height = *(GLsizei *) (pc + 52); GLsizei depth = *(GLsizei *) (pc + 56); GLenum format = *(GLenum *) (pc + 68); GLenum type = *(GLenum *) (pc + 72); if (swap) { row_length = bswap_32(row_length); image_height = bswap_32(image_height); skip_rows = bswap_32(skip_rows); skip_images = bswap_32(skip_images); alignment = bswap_32(alignment); target = bswap_32(target); width = bswap_32(width); height = bswap_32(height); depth = bswap_32(depth); format = bswap_32(format); type = bswap_32(type); } if (*(CARD32 *) (pc + 76)) return 0; return __glXImageSize(format, type, target, width, height, depth, image_height, row_length, skip_images, skip_rows, alignment); } int __glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLint row_length = *(GLint *) (pc + 4); GLint image_height = *(GLint *) (pc + 8); GLint skip_rows = *(GLint *) (pc + 16); GLint skip_images = *(GLint *) (pc + 20); GLint alignment = *(GLint *) (pc + 32); GLenum target = *(GLenum *) (pc + 36); GLsizei width = *(GLsizei *) (pc + 60); GLsizei height = *(GLsizei *) (pc + 64); GLsizei depth = *(GLsizei *) (pc + 68); GLenum format = *(GLenum *) (pc + 76); GLenum type = *(GLenum *) (pc + 80); if (swap) { row_length = bswap_32(row_length); image_height = bswap_32(image_height); skip_rows = bswap_32(skip_rows); skip_images = bswap_32(skip_images); alignment = bswap_32(alignment); target = bswap_32(target); width = bswap_32(width); height = bswap_32(height); depth = bswap_32(depth); format = bswap_32(format); type = bswap_32(type); } return __glXImageSize(format, type, target, width, height, depth, image_height, row_length, skip_images, skip_rows, alignment); } int __glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei imageSize = *(GLsizei *) (pc + 20); if (swap) { imageSize = bswap_32(imageSize); } return safe_pad(imageSize); } int __glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei imageSize = *(GLsizei *) (pc + 24); if (swap) { imageSize = bswap_32(imageSize); } return safe_pad(imageSize); } int __glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei imageSize = *(GLsizei *) (pc + 28); if (swap) { imageSize = bswap_32(imageSize); } return safe_pad(imageSize); } int __glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei imageSize = *(GLsizei *) (pc + 36); if (swap) { imageSize = bswap_32(imageSize); } return safe_pad(imageSize); } int __glXPointParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum pname = *(GLenum *) (pc + 0); GLsizei compsize; if (swap) { pname = bswap_32(pname); } compsize = __glPointParameterfv_size(pname); return safe_pad(safe_mul(compsize, 4)); } int __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei n = *(GLsizei *) (pc + 0); if (swap) { n = bswap_32(n); } return safe_pad(safe_mul(n, 4)); } int __glXProgramStringARBReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei len = *(GLsizei *) (pc + 8); if (swap) { len = bswap_32(len); } return safe_pad(len); } int __glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei n = *(GLsizei *) (pc + 4); if (swap) { n = bswap_32(n); } return safe_pad(safe_mul(n, 8)); } int __glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei n = *(GLsizei *) (pc + 4); if (swap) { n = bswap_32(n); } return safe_pad(safe_mul(n, 16)); } int __glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei n = *(GLsizei *) (pc + 4); if (swap) { n = bswap_32(n); } return safe_pad(safe_mul(n, 24)); } int __glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei n = *(GLsizei *) (pc + 4); if (swap) { n = bswap_32(n); } return safe_pad(safe_mul(n, 12)); } int __glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei n = *(GLsizei *) (pc + 4); if (swap) { n = bswap_32(n); } return safe_pad(safe_mul(n, 6)); } int __glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLsizei n = *(GLsizei *) (pc + 4); if (swap) { n = bswap_32(n); } return safe_pad(safe_mul(n, 32)); } ALIAS(Fogiv, Fogfv) ALIAS(Lightiv, Lightfv) ALIAS(LightModeliv, LightModelfv) ALIAS(Materialiv, Materialfv) ALIAS(TexParameteriv, TexParameterfv) ALIAS(TexEnviv, TexEnvfv) ALIAS(TexGeniv, TexGenfv) ALIAS(PixelMapuiv, PixelMapfv) ALIAS(ColorTableParameteriv, ColorTableParameterfv) ALIAS(ConvolutionParameteriv, ConvolutionParameterfv) ALIAS(CompressedTexSubImage1D, CompressedTexImage1D) ALIAS(CompressedTexSubImage2D, CompressedTexImage3D) ALIAS(PointParameteriv, PointParameterfv) ALIAS(DeleteFramebuffers, DrawBuffers) ALIAS(DeleteRenderbuffers, DrawBuffers) ALIAS(VertexAttribs1fvNV, PixelMapfv) ALIAS(VertexAttribs1svNV, PixelMapusv) ALIAS(VertexAttribs2fvNV, VertexAttribs1dvNV) ALIAS(VertexAttribs2svNV, PixelMapfv) ALIAS(VertexAttribs4fvNV, VertexAttribs2dvNV) ALIAS(VertexAttribs4svNV, VertexAttribs1dvNV) ALIAS(VertexAttribs4ubvNV, PixelMapfv) xorg-server-1.20.13/glx/indirect_reqsize.h0000644000175000017500000003040714100573756015404 00000000000000/* DO NOT EDIT - This file generated automatically by glX_proto_size.py (from Mesa) script */ /* * (C) Copyright IBM Corporation 2005 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #if !defined( _INDIRECT_REQSIZE_H_ ) #define _INDIRECT_REQSIZE_H_ #include #if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) #define PURE __attribute__((pure)) #else #define PURE #endif extern PURE _X_HIDDEN int __glXCallListsReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXBitmapReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXFogfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXFogivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXLightfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXLightivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXLightModelfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXLightModelivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXMaterialfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXMaterialivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXPolygonStippleReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexParameterivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexEnvivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexGendvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexGenfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexGenivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXMap1dReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXMap1fReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXMap2dReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXMap2fReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXPixelMapuivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXColorTableReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXColorTableParameterivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXColorSubTableReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXConvolutionParameterivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXCompressedTexSubImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXCompressedTexSubImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXPointParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXPointParameterivReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXProgramStringARBReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXDeleteFramebuffersReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXDeleteRenderbuffersReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs1fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs1svNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs2fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs2svNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs4fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs4svNVReqSize(const GLbyte * pc, Bool swap, int reqlen); extern PURE _X_HIDDEN int __glXVertexAttribs4ubvNVReqSize(const GLbyte * pc, Bool swap, int reqlen); #undef PURE #endif /* !defined( _INDIRECT_REQSIZE_H_ ) */ xorg-server-1.20.13/glx/indirect_size.h0000644000175000017500000000716614100573756014702 00000000000000/* DO NOT EDIT - This file generated automatically by glX_proto_size.py (from Mesa) script */ /* * (C) Copyright IBM Corporation 2004 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #if !defined( _INDIRECT_SIZE_H_ ) #define _INDIRECT_SIZE_H_ /** * \file * Prototypes for functions used to determine the number of data elements in * various GLX protocol messages. * * \author Ian Romanick */ #include #if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) #define PURE __attribute__((pure)) #else #define PURE #endif #if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__) #define FASTCALL __attribute__((fastcall)) #else #define FASTCALL #endif extern _X_INTERNAL PURE FASTCALL GLint __glCallLists_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glFogfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glFogiv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glLightfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glLightiv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glLightModelfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glLightModeliv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glMaterialfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glMaterialiv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glTexParameterfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glTexParameteriv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glTexEnvfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glTexEnviv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glTexGendv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glTexGenfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glTexGeniv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glMap1d_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glMap1f_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glMap2d_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glMap2f_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glColorTableParameterfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glColorTableParameteriv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glConvolutionParameterfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glConvolutionParameteriv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glPointParameterfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glPointParameteriv_size(GLenum); #undef PURE #undef FASTCALL #endif /* !defined( _INDIRECT_SIZE_H_ ) */ xorg-server-1.20.13/glx/indirect_size_get.c0000644000175000017500000010717114100573756015531 00000000000000/* DO NOT EDIT - This file generated automatically by glX_proto_size.py (from Mesa) script */ /* * (C) Copyright IBM Corporation 2004 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include "indirect_size_get.h" #include "glxserver.h" #include "indirect_util.h" #include "indirect_size.h" #if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) #define PURE __attribute__((pure)) #else #define PURE #endif #if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__) #define FASTCALL __attribute__((fastcall)) #else #define FASTCALL #endif #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(GLX_USE_APPLEGL) #undef HAVE_ALIAS #endif #ifdef HAVE_ALIAS #define ALIAS2(from,to) \ _X_INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \ __attribute__ ((alias( # to ))); #define ALIAS(from,to) ALIAS2( from, __gl ## to ## _size ) #else #define ALIAS(from,to) \ _X_INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \ { return __gl ## to ## _size( e ); } #endif _X_INTERNAL PURE FASTCALL GLint __glCallLists_size(GLenum e) { switch (e) { case GL_BYTE: case GL_UNSIGNED_BYTE: return 1; case GL_SHORT: case GL_UNSIGNED_SHORT: case GL_2_BYTES: case GL_HALF_FLOAT: return 2; case GL_3_BYTES: return 3; case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: case GL_4_BYTES: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glFogfv_size(GLenum e) { switch (e) { case GL_FOG_INDEX: case GL_FOG_DENSITY: case GL_FOG_START: case GL_FOG_END: case GL_FOG_MODE: case GL_FOG_OFFSET_VALUE_SGIX: case GL_FOG_DISTANCE_MODE_NV: return 1; case GL_FOG_COLOR: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glLightfv_size(GLenum e) { switch (e) { case GL_SPOT_EXPONENT: case GL_SPOT_CUTOFF: case GL_CONSTANT_ATTENUATION: case GL_LINEAR_ATTENUATION: case GL_QUADRATIC_ATTENUATION: return 1; case GL_SPOT_DIRECTION: return 3; case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_POSITION: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glLightModelfv_size(GLenum e) { switch (e) { case GL_LIGHT_MODEL_LOCAL_VIEWER: case GL_LIGHT_MODEL_TWO_SIDE: case GL_LIGHT_MODEL_COLOR_CONTROL: /* case GL_LIGHT_MODEL_COLOR_CONTROL_EXT:*/ return 1; case GL_LIGHT_MODEL_AMBIENT: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glMaterialfv_size(GLenum e) { switch (e) { case GL_SHININESS: return 1; case GL_COLOR_INDEXES: return 3; case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_EMISSION: case GL_AMBIENT_AND_DIFFUSE: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glTexParameterfv_size(GLenum e) { switch (e) { case GL_TEXTURE_MAG_FILTER: case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: case GL_TEXTURE_PRIORITY: case GL_TEXTURE_WRAP_R: case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: /* case GL_SHADOW_AMBIENT_SGIX:*/ case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_CLIPMAP_FRAME_SGIX: case GL_TEXTURE_LOD_BIAS_S_SGIX: case GL_TEXTURE_LOD_BIAS_T_SGIX: case GL_TEXTURE_LOD_BIAS_R_SGIX: case GL_GENERATE_MIPMAP: /* case GL_GENERATE_MIPMAP_SGIS:*/ case GL_TEXTURE_COMPARE_SGIX: case GL_TEXTURE_COMPARE_OPERATOR_SGIX: case GL_TEXTURE_MAX_CLAMP_S_SGIX: case GL_TEXTURE_MAX_CLAMP_T_SGIX: case GL_TEXTURE_MAX_CLAMP_R_SGIX: case GL_TEXTURE_MAX_ANISOTROPY_EXT: case GL_TEXTURE_LOD_BIAS: /* case GL_TEXTURE_LOD_BIAS_EXT:*/ case GL_TEXTURE_STORAGE_HINT_APPLE: case GL_STORAGE_PRIVATE_APPLE: case GL_STORAGE_CACHED_APPLE: case GL_STORAGE_SHARED_APPLE: case GL_DEPTH_TEXTURE_MODE: /* case GL_DEPTH_TEXTURE_MODE_ARB:*/ case GL_TEXTURE_COMPARE_MODE: /* case GL_TEXTURE_COMPARE_MODE_ARB:*/ case GL_TEXTURE_COMPARE_FUNC: /* case GL_TEXTURE_COMPARE_FUNC_ARB:*/ case GL_TEXTURE_UNSIGNED_REMAP_MODE_NV: return 1; case GL_TEXTURE_CLIPMAP_CENTER_SGIX: case GL_TEXTURE_CLIPMAP_OFFSET_SGIX: return 2; case GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX: return 3; case GL_TEXTURE_BORDER_COLOR: case GL_POST_TEXTURE_FILTER_BIAS_SGIX: case GL_POST_TEXTURE_FILTER_SCALE_SGIX: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glTexEnvfv_size(GLenum e) { switch (e) { case GL_ALPHA_SCALE: case GL_TEXTURE_ENV_MODE: case GL_TEXTURE_LOD_BIAS: case GL_COMBINE_RGB: case GL_COMBINE_ALPHA: case GL_RGB_SCALE: case GL_SOURCE0_RGB: case GL_SOURCE1_RGB: case GL_SOURCE2_RGB: case GL_SOURCE3_RGB_NV: case GL_SOURCE0_ALPHA: case GL_SOURCE1_ALPHA: case GL_SOURCE2_ALPHA: case GL_SOURCE3_ALPHA_NV: case GL_OPERAND0_RGB: case GL_OPERAND1_RGB: case GL_OPERAND2_RGB: case GL_OPERAND3_RGB_NV: case GL_OPERAND0_ALPHA: case GL_OPERAND1_ALPHA: case GL_OPERAND2_ALPHA: case GL_OPERAND3_ALPHA_NV: case GL_BUMP_TARGET_ATI: case GL_COORD_REPLACE_ARB: /* case GL_COORD_REPLACE_NV:*/ return 1; case GL_TEXTURE_ENV_COLOR: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glTexGendv_size(GLenum e) { switch (e) { case GL_TEXTURE_GEN_MODE: return 1; case GL_OBJECT_PLANE: case GL_EYE_PLANE: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glMap1d_size(GLenum e) { switch (e) { case GL_MAP1_INDEX: case GL_MAP1_TEXTURE_COORD_1: return 1; case GL_MAP1_TEXTURE_COORD_2: return 2; case GL_MAP1_NORMAL: case GL_MAP1_TEXTURE_COORD_3: case GL_MAP1_VERTEX_3: return 3; case GL_MAP1_COLOR_4: case GL_MAP1_TEXTURE_COORD_4: case GL_MAP1_VERTEX_4: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glMap2d_size(GLenum e) { switch (e) { case GL_MAP2_INDEX: case GL_MAP2_TEXTURE_COORD_1: return 1; case GL_MAP2_TEXTURE_COORD_2: return 2; case GL_MAP2_NORMAL: case GL_MAP2_TEXTURE_COORD_3: case GL_MAP2_VERTEX_3: return 3; case GL_MAP2_COLOR_4: case GL_MAP2_TEXTURE_COORD_4: case GL_MAP2_VERTEX_4: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetBooleanv_size(GLenum e) { switch (e) { case GL_CURRENT_INDEX: case GL_CURRENT_RASTER_INDEX: case GL_CURRENT_RASTER_POSITION_VALID: case GL_CURRENT_RASTER_DISTANCE: case GL_POINT_SMOOTH: case GL_POINT_SIZE: case GL_SMOOTH_POINT_SIZE_GRANULARITY: case GL_LINE_SMOOTH: case GL_LINE_WIDTH: case GL_LINE_WIDTH_GRANULARITY: case GL_LINE_STIPPLE: case GL_LINE_STIPPLE_PATTERN: case GL_LINE_STIPPLE_REPEAT: case GL_LIST_MODE: case GL_MAX_LIST_NESTING: case GL_LIST_BASE: case GL_LIST_INDEX: case GL_POLYGON_SMOOTH: case GL_POLYGON_STIPPLE: case GL_EDGE_FLAG: case GL_CULL_FACE: case GL_CULL_FACE_MODE: case GL_FRONT_FACE: case GL_LIGHTING: case GL_LIGHT_MODEL_LOCAL_VIEWER: case GL_LIGHT_MODEL_TWO_SIDE: case GL_SHADE_MODEL: case GL_COLOR_MATERIAL_FACE: case GL_COLOR_MATERIAL_PARAMETER: case GL_COLOR_MATERIAL: case GL_FOG: case GL_FOG_INDEX: case GL_FOG_DENSITY: case GL_FOG_START: case GL_FOG_END: case GL_FOG_MODE: case GL_DEPTH_TEST: case GL_DEPTH_WRITEMASK: case GL_DEPTH_CLEAR_VALUE: case GL_DEPTH_FUNC: case GL_STENCIL_TEST: case GL_STENCIL_CLEAR_VALUE: case GL_STENCIL_FUNC: case GL_STENCIL_VALUE_MASK: case GL_STENCIL_FAIL: case GL_STENCIL_PASS_DEPTH_FAIL: case GL_STENCIL_PASS_DEPTH_PASS: case GL_STENCIL_REF: case GL_STENCIL_WRITEMASK: case GL_MATRIX_MODE: case GL_NORMALIZE: case GL_MODELVIEW_STACK_DEPTH: case GL_PROJECTION_STACK_DEPTH: case GL_TEXTURE_STACK_DEPTH: case GL_ATTRIB_STACK_DEPTH: case GL_CLIENT_ATTRIB_STACK_DEPTH: case GL_ALPHA_TEST: case GL_ALPHA_TEST_FUNC: case GL_ALPHA_TEST_REF: case GL_DITHER: case GL_BLEND_DST: case GL_BLEND_SRC: case GL_BLEND: case GL_LOGIC_OP_MODE: case GL_LOGIC_OP: case GL_AUX_BUFFERS: case GL_DRAW_BUFFER: case GL_READ_BUFFER: case GL_SCISSOR_TEST: case GL_INDEX_CLEAR_VALUE: case GL_INDEX_WRITEMASK: case GL_INDEX_MODE: case GL_RGBA_MODE: case GL_DOUBLEBUFFER: case GL_STEREO: case GL_RENDER_MODE: case GL_PERSPECTIVE_CORRECTION_HINT: case GL_POINT_SMOOTH_HINT: case GL_LINE_SMOOTH_HINT: case GL_POLYGON_SMOOTH_HINT: case GL_FOG_HINT: case GL_TEXTURE_GEN_S: case GL_TEXTURE_GEN_T: case GL_TEXTURE_GEN_R: case GL_TEXTURE_GEN_Q: case GL_PIXEL_MAP_I_TO_I: case GL_PIXEL_MAP_I_TO_I_SIZE: case GL_PIXEL_MAP_S_TO_S_SIZE: case GL_PIXEL_MAP_I_TO_R_SIZE: case GL_PIXEL_MAP_I_TO_G_SIZE: case GL_PIXEL_MAP_I_TO_B_SIZE: case GL_PIXEL_MAP_I_TO_A_SIZE: case GL_PIXEL_MAP_R_TO_R_SIZE: case GL_PIXEL_MAP_G_TO_G_SIZE: case GL_PIXEL_MAP_B_TO_B_SIZE: case GL_PIXEL_MAP_A_TO_A_SIZE: case GL_UNPACK_SWAP_BYTES: case GL_UNPACK_LSB_FIRST: case GL_UNPACK_ROW_LENGTH: case GL_UNPACK_SKIP_ROWS: case GL_UNPACK_SKIP_PIXELS: case GL_UNPACK_ALIGNMENT: case GL_PACK_SWAP_BYTES: case GL_PACK_LSB_FIRST: case GL_PACK_ROW_LENGTH: case GL_PACK_SKIP_ROWS: case GL_PACK_SKIP_PIXELS: case GL_PACK_ALIGNMENT: case GL_MAP_COLOR: case GL_MAP_STENCIL: case GL_INDEX_SHIFT: case GL_INDEX_OFFSET: case GL_RED_SCALE: case GL_RED_BIAS: case GL_ZOOM_X: case GL_ZOOM_Y: case GL_GREEN_SCALE: case GL_GREEN_BIAS: case GL_BLUE_SCALE: case GL_BLUE_BIAS: case GL_ALPHA_SCALE: case GL_ALPHA_BIAS: case GL_DEPTH_SCALE: case GL_DEPTH_BIAS: case GL_MAX_EVAL_ORDER: case GL_MAX_LIGHTS: case GL_MAX_CLIP_PLANES: case GL_MAX_TEXTURE_SIZE: case GL_MAX_PIXEL_MAP_TABLE: case GL_MAX_ATTRIB_STACK_DEPTH: case GL_MAX_MODELVIEW_STACK_DEPTH: case GL_MAX_NAME_STACK_DEPTH: case GL_MAX_PROJECTION_STACK_DEPTH: case GL_MAX_TEXTURE_STACK_DEPTH: case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: case GL_SUBPIXEL_BITS: case GL_INDEX_BITS: case GL_RED_BITS: case GL_GREEN_BITS: case GL_BLUE_BITS: case GL_ALPHA_BITS: case GL_DEPTH_BITS: case GL_STENCIL_BITS: case GL_ACCUM_RED_BITS: case GL_ACCUM_GREEN_BITS: case GL_ACCUM_BLUE_BITS: case GL_ACCUM_ALPHA_BITS: case GL_NAME_STACK_DEPTH: case GL_AUTO_NORMAL: case GL_MAP1_COLOR_4: case GL_MAP1_INDEX: case GL_MAP1_NORMAL: case GL_MAP1_TEXTURE_COORD_1: case GL_MAP1_TEXTURE_COORD_2: case GL_MAP1_TEXTURE_COORD_3: case GL_MAP1_TEXTURE_COORD_4: case GL_MAP1_VERTEX_3: case GL_MAP1_VERTEX_4: case GL_MAP2_COLOR_4: case GL_MAP2_INDEX: case GL_MAP2_NORMAL: case GL_MAP2_TEXTURE_COORD_1: case GL_MAP2_TEXTURE_COORD_2: case GL_MAP2_TEXTURE_COORD_3: case GL_MAP2_TEXTURE_COORD_4: case GL_MAP2_VERTEX_3: case GL_MAP2_VERTEX_4: case GL_MAP1_GRID_SEGMENTS: case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_POLYGON_OFFSET_UNITS: case GL_CLIP_PLANE0: case GL_CLIP_PLANE1: case GL_CLIP_PLANE2: case GL_CLIP_PLANE3: case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: case GL_LIGHT0: case GL_LIGHT1: case GL_LIGHT2: case GL_LIGHT3: case GL_LIGHT4: case GL_LIGHT5: case GL_LIGHT6: case GL_LIGHT7: case GL_BLEND_EQUATION: /* case GL_BLEND_EQUATION_EXT:*/ case GL_CONVOLUTION_1D: case GL_CONVOLUTION_2D: case GL_SEPARABLE_2D: case GL_MAX_CONVOLUTION_WIDTH: /* case GL_MAX_CONVOLUTION_WIDTH_EXT:*/ case GL_MAX_CONVOLUTION_HEIGHT: /* case GL_MAX_CONVOLUTION_HEIGHT_EXT:*/ case GL_POST_CONVOLUTION_RED_SCALE: /* case GL_POST_CONVOLUTION_RED_SCALE_EXT:*/ case GL_POST_CONVOLUTION_GREEN_SCALE: /* case GL_POST_CONVOLUTION_GREEN_SCALE_EXT:*/ case GL_POST_CONVOLUTION_BLUE_SCALE: /* case GL_POST_CONVOLUTION_BLUE_SCALE_EXT:*/ case GL_POST_CONVOLUTION_ALPHA_SCALE: /* case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT:*/ case GL_POST_CONVOLUTION_RED_BIAS: /* case GL_POST_CONVOLUTION_RED_BIAS_EXT:*/ case GL_POST_CONVOLUTION_GREEN_BIAS: /* case GL_POST_CONVOLUTION_GREEN_BIAS_EXT:*/ case GL_POST_CONVOLUTION_BLUE_BIAS: /* case GL_POST_CONVOLUTION_BLUE_BIAS_EXT:*/ case GL_POST_CONVOLUTION_ALPHA_BIAS: /* case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT:*/ case GL_HISTOGRAM: case GL_MINMAX: case GL_POLYGON_OFFSET_FACTOR: case GL_RESCALE_NORMAL: /* case GL_RESCALE_NORMAL_EXT:*/ case GL_TEXTURE_BINDING_1D: case GL_TEXTURE_BINDING_2D: case GL_TEXTURE_BINDING_3D: case GL_PACK_SKIP_IMAGES: case GL_PACK_IMAGE_HEIGHT: case GL_UNPACK_SKIP_IMAGES: case GL_UNPACK_IMAGE_HEIGHT: case GL_TEXTURE_3D: case GL_MAX_3D_TEXTURE_SIZE: case GL_VERTEX_ARRAY: case GL_NORMAL_ARRAY: case GL_COLOR_ARRAY: case GL_INDEX_ARRAY: case GL_TEXTURE_COORD_ARRAY: case GL_EDGE_FLAG_ARRAY: case GL_VERTEX_ARRAY_SIZE: case GL_VERTEX_ARRAY_TYPE: case GL_VERTEX_ARRAY_STRIDE: case GL_NORMAL_ARRAY_TYPE: case GL_NORMAL_ARRAY_STRIDE: case GL_COLOR_ARRAY_SIZE: case GL_COLOR_ARRAY_TYPE: case GL_COLOR_ARRAY_STRIDE: case GL_INDEX_ARRAY_TYPE: case GL_INDEX_ARRAY_STRIDE: case GL_TEXTURE_COORD_ARRAY_SIZE: case GL_TEXTURE_COORD_ARRAY_TYPE: case GL_TEXTURE_COORD_ARRAY_STRIDE: case GL_EDGE_FLAG_ARRAY_STRIDE: case GL_MULTISAMPLE: /* case GL_MULTISAMPLE_ARB:*/ case GL_SAMPLE_ALPHA_TO_COVERAGE: /* case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:*/ case GL_SAMPLE_ALPHA_TO_ONE: /* case GL_SAMPLE_ALPHA_TO_ONE_ARB:*/ case GL_SAMPLE_COVERAGE: /* case GL_SAMPLE_COVERAGE_ARB:*/ case GL_SAMPLE_BUFFERS: /* case GL_SAMPLE_BUFFERS_ARB:*/ case GL_SAMPLES: /* case GL_SAMPLES_ARB:*/ case GL_SAMPLE_COVERAGE_VALUE: /* case GL_SAMPLE_COVERAGE_VALUE_ARB:*/ case GL_SAMPLE_COVERAGE_INVERT: /* case GL_SAMPLE_COVERAGE_INVERT_ARB:*/ case GL_COLOR_MATRIX_STACK_DEPTH: case GL_MAX_COLOR_MATRIX_STACK_DEPTH: case GL_POST_COLOR_MATRIX_RED_SCALE: case GL_POST_COLOR_MATRIX_GREEN_SCALE: case GL_POST_COLOR_MATRIX_BLUE_SCALE: case GL_POST_COLOR_MATRIX_ALPHA_SCALE: case GL_POST_COLOR_MATRIX_RED_BIAS: case GL_POST_COLOR_MATRIX_GREEN_BIAS: case GL_POST_COLOR_MATRIX_BLUE_BIAS: case GL_POST_COLOR_MATRIX_ALPHA_BIAS: case GL_BLEND_DST_RGB: case GL_BLEND_SRC_RGB: case GL_BLEND_DST_ALPHA: case GL_BLEND_SRC_ALPHA: case GL_COLOR_TABLE: case GL_POST_CONVOLUTION_COLOR_TABLE: case GL_POST_COLOR_MATRIX_COLOR_TABLE: case GL_MAX_ELEMENTS_VERTICES: case GL_MAX_ELEMENTS_INDICES: case GL_CLIP_VOLUME_CLIPPING_HINT_EXT: case GL_POINT_SIZE_MIN: case GL_POINT_SIZE_MAX: case GL_POINT_FADE_THRESHOLD_SIZE: case GL_OCCLUSION_TEST_HP: case GL_OCCLUSION_TEST_RESULT_HP: case GL_LIGHT_MODEL_COLOR_CONTROL: case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB: case GL_RESET_NOTIFICATION_STRATEGY_ARB: case GL_CURRENT_FOG_COORD: case GL_FOG_COORDINATE_ARRAY_TYPE: case GL_FOG_COORDINATE_ARRAY_STRIDE: case GL_FOG_COORD_ARRAY: case GL_COLOR_SUM_ARB: case GL_SECONDARY_COLOR_ARRAY_SIZE: case GL_SECONDARY_COLOR_ARRAY_TYPE: case GL_SECONDARY_COLOR_ARRAY_STRIDE: case GL_SECONDARY_COLOR_ARRAY: case GL_ACTIVE_TEXTURE: /* case GL_ACTIVE_TEXTURE_ARB:*/ case GL_CLIENT_ACTIVE_TEXTURE: /* case GL_CLIENT_ACTIVE_TEXTURE_ARB:*/ case GL_MAX_TEXTURE_UNITS: /* case GL_MAX_TEXTURE_UNITS_ARB:*/ case GL_MAX_RENDERBUFFER_SIZE: /* case GL_MAX_RENDERBUFFER_SIZE_EXT:*/ case GL_TEXTURE_COMPRESSION_HINT: /* case GL_TEXTURE_COMPRESSION_HINT_ARB:*/ case GL_TEXTURE_RECTANGLE_ARB: /* case GL_TEXTURE_RECTANGLE_NV:*/ case GL_TEXTURE_BINDING_RECTANGLE_ARB: /* case GL_TEXTURE_BINDING_RECTANGLE_NV:*/ case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB: /* case GL_MAX_RECTANGLE_TEXTURE_SIZE_NV:*/ case GL_MAX_TEXTURE_LOD_BIAS: case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: case GL_MAX_SHININESS_NV: case GL_MAX_SPOT_EXPONENT_NV: case GL_TEXTURE_CUBE_MAP: /* case GL_TEXTURE_CUBE_MAP_ARB:*/ case GL_TEXTURE_BINDING_CUBE_MAP: /* case GL_TEXTURE_BINDING_CUBE_MAP_ARB:*/ case GL_MAX_CUBE_MAP_TEXTURE_SIZE: /* case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB:*/ case GL_MULTISAMPLE_FILTER_HINT_NV: case GL_FOG_DISTANCE_MODE_NV: case GL_VERTEX_PROGRAM_ARB: case GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB: case GL_MAX_PROGRAM_MATRICES_ARB: case GL_CURRENT_MATRIX_STACK_DEPTH_ARB: case GL_VERTEX_PROGRAM_POINT_SIZE_ARB: case GL_VERTEX_PROGRAM_TWO_SIDE_ARB: case GL_PROGRAM_ERROR_POSITION_ARB: case GL_DEPTH_CLAMP: /* case GL_DEPTH_CLAMP_NV:*/ case GL_NUM_COMPRESSED_TEXTURE_FORMATS: /* case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB:*/ case GL_MAX_VERTEX_UNITS_ARB: case GL_ACTIVE_VERTEX_UNITS_ARB: case GL_WEIGHT_SUM_UNITY_ARB: case GL_VERTEX_BLEND_ARB: case GL_CURRENT_WEIGHT_ARB: case GL_WEIGHT_ARRAY_TYPE_ARB: case GL_WEIGHT_ARRAY_STRIDE_ARB: case GL_WEIGHT_ARRAY_SIZE_ARB: case GL_WEIGHT_ARRAY_ARB: case GL_PACK_INVERT_MESA: case GL_STENCIL_BACK_FUNC_ATI: case GL_STENCIL_BACK_FAIL_ATI: case GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI: case GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI: case GL_FRAGMENT_PROGRAM_ARB: case GL_MAX_DRAW_BUFFERS_ARB: /* case GL_MAX_DRAW_BUFFERS_ATI:*/ case GL_DRAW_BUFFER0_ARB: /* case GL_DRAW_BUFFER0_ATI:*/ case GL_DRAW_BUFFER1_ARB: /* case GL_DRAW_BUFFER1_ATI:*/ case GL_DRAW_BUFFER2_ARB: /* case GL_DRAW_BUFFER2_ATI:*/ case GL_DRAW_BUFFER3_ARB: /* case GL_DRAW_BUFFER3_ATI:*/ case GL_DRAW_BUFFER4_ARB: /* case GL_DRAW_BUFFER4_ATI:*/ case GL_DRAW_BUFFER5_ARB: /* case GL_DRAW_BUFFER5_ATI:*/ case GL_DRAW_BUFFER6_ARB: /* case GL_DRAW_BUFFER6_ATI:*/ case GL_DRAW_BUFFER7_ARB: /* case GL_DRAW_BUFFER7_ATI:*/ case GL_DRAW_BUFFER8_ARB: /* case GL_DRAW_BUFFER8_ATI:*/ case GL_DRAW_BUFFER9_ARB: /* case GL_DRAW_BUFFER9_ATI:*/ case GL_DRAW_BUFFER10_ARB: /* case GL_DRAW_BUFFER10_ATI:*/ case GL_DRAW_BUFFER11_ARB: /* case GL_DRAW_BUFFER11_ATI:*/ case GL_DRAW_BUFFER12_ARB: /* case GL_DRAW_BUFFER12_ATI:*/ case GL_DRAW_BUFFER13_ARB: /* case GL_DRAW_BUFFER13_ATI:*/ case GL_DRAW_BUFFER14_ARB: /* case GL_DRAW_BUFFER14_ATI:*/ case GL_DRAW_BUFFER15_ARB: /* case GL_DRAW_BUFFER15_ATI:*/ case GL_BLEND_EQUATION_ALPHA_EXT: case GL_MATRIX_PALETTE_ARB: case GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB: case GL_MAX_PALETTE_MATRICES_ARB: case GL_CURRENT_PALETTE_MATRIX_ARB: case GL_MATRIX_INDEX_ARRAY_ARB: case GL_CURRENT_MATRIX_INDEX_ARB: case GL_MATRIX_INDEX_ARRAY_SIZE_ARB: case GL_MATRIX_INDEX_ARRAY_TYPE_ARB: case GL_MATRIX_INDEX_ARRAY_STRIDE_ARB: case GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT: case GL_TEXTURE_CUBE_MAP_SEAMLESS: case GL_POINT_SPRITE_ARB: /* case GL_POINT_SPRITE_NV:*/ case GL_POINT_SPRITE_R_MODE_NV: case GL_MAX_VERTEX_ATTRIBS_ARB: case GL_MAX_TEXTURE_COORDS_ARB: case GL_MAX_TEXTURE_IMAGE_UNITS_ARB: case GL_DEPTH_BOUNDS_TEST_EXT: case GL_ARRAY_BUFFER_BINDING_ARB: case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB: case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB: case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB: case GL_COLOR_ARRAY_BUFFER_BINDING_ARB: case GL_INDEX_ARRAY_BUFFER_BINDING_ARB: case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB: case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB: case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB: case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB: case GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB: case GL_MAX_ARRAY_TEXTURE_LAYERS_EXT: case GL_STENCIL_TEST_TWO_SIDE_EXT: case GL_ACTIVE_STENCIL_FACE_EXT: case GL_SAMPLER_BINDING: case GL_TEXTURE_BINDING_1D_ARRAY_EXT: case GL_TEXTURE_BINDING_2D_ARRAY_EXT: case GL_FRAMEBUFFER_BINDING: /* case GL_DRAW_FRAMEBUFFER_BINDING_EXT:*/ case GL_RENDERBUFFER_BINDING: /* case GL_RENDERBUFFER_BINDING_EXT:*/ case GL_READ_FRAMEBUFFER_BINDING: /* case GL_READ_FRAMEBUFFER_BINDING_EXT:*/ case GL_MAX_COLOR_ATTACHMENTS: /* case GL_MAX_COLOR_ATTACHMENTS_EXT:*/ case GL_MAX_SAMPLES: /* case GL_MAX_SAMPLES_EXT:*/ case GL_MAX_SERVER_WAIT_TIMEOUT: case GL_MAX_DEBUG_MESSAGE_LENGTH_ARB: case GL_MAX_DEBUG_LOGGED_MESSAGES_ARB: case GL_DEBUG_LOGGED_MESSAGES_ARB: case GL_RASTER_POSITION_UNCLIPPED_IBM: return 1; case GL_SMOOTH_POINT_SIZE_RANGE: case GL_LINE_WIDTH_RANGE: case GL_POLYGON_MODE: case GL_DEPTH_RANGE: case GL_MAX_VIEWPORT_DIMS: case GL_MAP1_GRID_DOMAIN: case GL_MAP2_GRID_SEGMENTS: case GL_ALIASED_POINT_SIZE_RANGE: case GL_ALIASED_LINE_WIDTH_RANGE: case GL_DEPTH_BOUNDS_EXT: return 2; case GL_CURRENT_NORMAL: case GL_POINT_DISTANCE_ATTENUATION: return 3; case GL_CURRENT_COLOR: case GL_CURRENT_TEXTURE_COORDS: case GL_CURRENT_RASTER_COLOR: case GL_CURRENT_RASTER_TEXTURE_COORDS: case GL_CURRENT_RASTER_POSITION: case GL_LIGHT_MODEL_AMBIENT: case GL_FOG_COLOR: case GL_ACCUM_CLEAR_VALUE: case GL_VIEWPORT: case GL_SCISSOR_BOX: case GL_COLOR_CLEAR_VALUE: case GL_COLOR_WRITEMASK: case GL_MAP2_GRID_DOMAIN: case GL_BLEND_COLOR: /* case GL_BLEND_COLOR_EXT:*/ case GL_CURRENT_SECONDARY_COLOR: return 4; case GL_MODELVIEW_MATRIX: case GL_PROJECTION_MATRIX: case GL_TEXTURE_MATRIX: case GL_MODELVIEW0_ARB: case GL_COLOR_MATRIX: case GL_MODELVIEW1_ARB: case GL_CURRENT_MATRIX_ARB: case GL_MODELVIEW2_ARB: case GL_MODELVIEW3_ARB: case GL_MODELVIEW4_ARB: case GL_MODELVIEW5_ARB: case GL_MODELVIEW6_ARB: case GL_MODELVIEW7_ARB: case GL_MODELVIEW8_ARB: case GL_MODELVIEW9_ARB: case GL_MODELVIEW10_ARB: case GL_MODELVIEW11_ARB: case GL_MODELVIEW12_ARB: case GL_MODELVIEW13_ARB: case GL_MODELVIEW14_ARB: case GL_MODELVIEW15_ARB: case GL_MODELVIEW16_ARB: case GL_MODELVIEW17_ARB: case GL_MODELVIEW18_ARB: case GL_MODELVIEW19_ARB: case GL_MODELVIEW20_ARB: case GL_MODELVIEW21_ARB: case GL_MODELVIEW22_ARB: case GL_MODELVIEW23_ARB: case GL_MODELVIEW24_ARB: case GL_MODELVIEW25_ARB: case GL_MODELVIEW26_ARB: case GL_MODELVIEW27_ARB: case GL_MODELVIEW28_ARB: case GL_MODELVIEW29_ARB: case GL_MODELVIEW30_ARB: case GL_MODELVIEW31_ARB: case GL_TRANSPOSE_CURRENT_MATRIX_ARB: return 16; case GL_FOG_COORDINATE_SOURCE: case GL_COMPRESSED_TEXTURE_FORMATS: case GL_RGBA_INTEGER_MODE_EXT: return __glGetBooleanv_variable_size(e); default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetTexParameterfv_size(GLenum e) { switch (e) { case GL_TEXTURE_MAG_FILTER: case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: case GL_TEXTURE_PRIORITY: case GL_TEXTURE_RESIDENT: case GL_TEXTURE_WRAP_R: case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: /* case GL_SHADOW_AMBIENT_SGIX:*/ case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_CLIPMAP_FRAME_SGIX: case GL_TEXTURE_LOD_BIAS_S_SGIX: case GL_TEXTURE_LOD_BIAS_T_SGIX: case GL_TEXTURE_LOD_BIAS_R_SGIX: case GL_GENERATE_MIPMAP: /* case GL_GENERATE_MIPMAP_SGIS:*/ case GL_TEXTURE_COMPARE_SGIX: case GL_TEXTURE_COMPARE_OPERATOR_SGIX: case GL_TEXTURE_MAX_CLAMP_S_SGIX: case GL_TEXTURE_MAX_CLAMP_T_SGIX: case GL_TEXTURE_MAX_CLAMP_R_SGIX: case GL_TEXTURE_MAX_ANISOTROPY_EXT: case GL_TEXTURE_LOD_BIAS: /* case GL_TEXTURE_LOD_BIAS_EXT:*/ case GL_TEXTURE_RANGE_LENGTH_APPLE: case GL_TEXTURE_STORAGE_HINT_APPLE: case GL_DEPTH_TEXTURE_MODE: /* case GL_DEPTH_TEXTURE_MODE_ARB:*/ case GL_TEXTURE_COMPARE_MODE: /* case GL_TEXTURE_COMPARE_MODE_ARB:*/ case GL_TEXTURE_COMPARE_FUNC: /* case GL_TEXTURE_COMPARE_FUNC_ARB:*/ case GL_TEXTURE_UNSIGNED_REMAP_MODE_NV: return 1; case GL_TEXTURE_CLIPMAP_CENTER_SGIX: case GL_TEXTURE_CLIPMAP_OFFSET_SGIX: return 2; case GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX: return 3; case GL_TEXTURE_BORDER_COLOR: case GL_POST_TEXTURE_FILTER_BIAS_SGIX: case GL_POST_TEXTURE_FILTER_SCALE_SGIX: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetTexLevelParameterfv_size(GLenum e) { switch (e) { case GL_TEXTURE_WIDTH: case GL_TEXTURE_HEIGHT: case GL_TEXTURE_COMPONENTS: case GL_TEXTURE_BORDER: case GL_TEXTURE_RED_SIZE: /* case GL_TEXTURE_RED_SIZE_EXT:*/ case GL_TEXTURE_GREEN_SIZE: /* case GL_TEXTURE_GREEN_SIZE_EXT:*/ case GL_TEXTURE_BLUE_SIZE: /* case GL_TEXTURE_BLUE_SIZE_EXT:*/ case GL_TEXTURE_ALPHA_SIZE: /* case GL_TEXTURE_ALPHA_SIZE_EXT:*/ case GL_TEXTURE_LUMINANCE_SIZE: /* case GL_TEXTURE_LUMINANCE_SIZE_EXT:*/ case GL_TEXTURE_INTENSITY_SIZE: /* case GL_TEXTURE_INTENSITY_SIZE_EXT:*/ case GL_TEXTURE_DEPTH: case GL_TEXTURE_INDEX_SIZE_EXT: case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: /* case GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB:*/ case GL_TEXTURE_COMPRESSED: /* case GL_TEXTURE_COMPRESSED_ARB:*/ case GL_TEXTURE_DEPTH_SIZE: /* case GL_TEXTURE_DEPTH_SIZE_ARB:*/ case GL_TEXTURE_STENCIL_SIZE: /* case GL_TEXTURE_STENCIL_SIZE_EXT:*/ return 1; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetPointerv_size(GLenum e) { switch (e) { case GL_DEBUG_CALLBACK_FUNCTION_ARB: case GL_DEBUG_CALLBACK_USER_PARAM_ARB: return 1; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glColorTableParameterfv_size(GLenum e) { switch (e) { case GL_COLOR_TABLE_SCALE: case GL_COLOR_TABLE_BIAS: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetColorTableParameterfv_size(GLenum e) { switch (e) { case GL_COLOR_TABLE_FORMAT: /* case GL_COLOR_TABLE_FORMAT_EXT:*/ case GL_COLOR_TABLE_WIDTH: /* case GL_COLOR_TABLE_WIDTH_EXT:*/ case GL_COLOR_TABLE_RED_SIZE: /* case GL_COLOR_TABLE_RED_SIZE_EXT:*/ case GL_COLOR_TABLE_GREEN_SIZE: /* case GL_COLOR_TABLE_GREEN_SIZE_EXT:*/ case GL_COLOR_TABLE_BLUE_SIZE: /* case GL_COLOR_TABLE_BLUE_SIZE_EXT:*/ case GL_COLOR_TABLE_ALPHA_SIZE: /* case GL_COLOR_TABLE_ALPHA_SIZE_EXT:*/ case GL_COLOR_TABLE_LUMINANCE_SIZE: /* case GL_COLOR_TABLE_LUMINANCE_SIZE_EXT:*/ case GL_COLOR_TABLE_INTENSITY_SIZE: /* case GL_COLOR_TABLE_INTENSITY_SIZE_EXT:*/ return 1; case GL_COLOR_TABLE_SCALE: case GL_COLOR_TABLE_BIAS: return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glConvolutionParameterfv_size(GLenum e) { switch (e) { case GL_CONVOLUTION_BORDER_MODE: /* case GL_CONVOLUTION_BORDER_MODE_EXT:*/ return 1; case GL_CONVOLUTION_FILTER_SCALE: /* case GL_CONVOLUTION_FILTER_SCALE_EXT:*/ case GL_CONVOLUTION_FILTER_BIAS: /* case GL_CONVOLUTION_FILTER_BIAS_EXT:*/ case GL_CONVOLUTION_BORDER_COLOR: /* case GL_CONVOLUTION_BORDER_COLOR_HP:*/ return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetConvolutionParameterfv_size(GLenum e) { switch (e) { case GL_CONVOLUTION_BORDER_MODE: /* case GL_CONVOLUTION_BORDER_MODE_EXT:*/ case GL_CONVOLUTION_FORMAT: /* case GL_CONVOLUTION_FORMAT_EXT:*/ case GL_CONVOLUTION_WIDTH: /* case GL_CONVOLUTION_WIDTH_EXT:*/ case GL_CONVOLUTION_HEIGHT: /* case GL_CONVOLUTION_HEIGHT_EXT:*/ case GL_MAX_CONVOLUTION_WIDTH: /* case GL_MAX_CONVOLUTION_WIDTH_EXT:*/ case GL_MAX_CONVOLUTION_HEIGHT: /* case GL_MAX_CONVOLUTION_HEIGHT_EXT:*/ return 1; case GL_CONVOLUTION_FILTER_SCALE: /* case GL_CONVOLUTION_FILTER_SCALE_EXT:*/ case GL_CONVOLUTION_FILTER_BIAS: /* case GL_CONVOLUTION_FILTER_BIAS_EXT:*/ case GL_CONVOLUTION_BORDER_COLOR: /* case GL_CONVOLUTION_BORDER_COLOR_HP:*/ return 4; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetHistogramParameterfv_size(GLenum e) { switch (e) { case GL_HISTOGRAM_WIDTH: case GL_HISTOGRAM_FORMAT: case GL_HISTOGRAM_RED_SIZE: case GL_HISTOGRAM_GREEN_SIZE: case GL_HISTOGRAM_BLUE_SIZE: case GL_HISTOGRAM_ALPHA_SIZE: case GL_HISTOGRAM_LUMINANCE_SIZE: case GL_HISTOGRAM_SINK: return 1; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetMinmaxParameterfv_size(GLenum e) { switch (e) { case GL_MINMAX_FORMAT: case GL_MINMAX_SINK: return 1; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glPointParameterfv_size(GLenum e) { switch (e) { case GL_POINT_SIZE_MIN: /* case GL_POINT_SIZE_MIN_ARB:*/ /* case GL_POINT_SIZE_MIN_SGIS:*/ case GL_POINT_SIZE_MAX: /* case GL_POINT_SIZE_MAX_ARB:*/ /* case GL_POINT_SIZE_MAX_SGIS:*/ case GL_POINT_FADE_THRESHOLD_SIZE: /* case GL_POINT_FADE_THRESHOLD_SIZE_ARB:*/ /* case GL_POINT_FADE_THRESHOLD_SIZE_SGIS:*/ case GL_POINT_SPRITE_R_MODE_NV: case GL_POINT_SPRITE_COORD_ORIGIN: return 1; case GL_POINT_DISTANCE_ATTENUATION: /* case GL_POINT_DISTANCE_ATTENUATION_ARB:*/ /* case GL_POINT_DISTANCE_ATTENUATION_SGIS:*/ return 3; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetQueryObjectiv_size(GLenum e) { switch (e) { case GL_QUERY_RESULT_ARB: case GL_QUERY_RESULT_AVAILABLE_ARB: return 1; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetQueryiv_size(GLenum e) { switch (e) { case GL_QUERY_COUNTER_BITS_ARB: case GL_CURRENT_QUERY_ARB: case GL_ANY_SAMPLES_PASSED: return 1; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetProgramivARB_size(GLenum e) { switch (e) { case GL_PROGRAM_LENGTH_ARB: case GL_PROGRAM_BINDING_ARB: case GL_PROGRAM_ALU_INSTRUCTIONS_ARB: case GL_PROGRAM_TEX_INSTRUCTIONS_ARB: case GL_PROGRAM_TEX_INDIRECTIONS_ARB: case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB: case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB: case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB: case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: case GL_PROGRAM_FORMAT_ARB: case GL_PROGRAM_INSTRUCTIONS_ARB: case GL_MAX_PROGRAM_INSTRUCTIONS_ARB: case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB: case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB: case GL_PROGRAM_TEMPORARIES_ARB: case GL_MAX_PROGRAM_TEMPORARIES_ARB: case GL_PROGRAM_NATIVE_TEMPORARIES_ARB: case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB: case GL_PROGRAM_PARAMETERS_ARB: case GL_MAX_PROGRAM_PARAMETERS_ARB: case GL_PROGRAM_NATIVE_PARAMETERS_ARB: case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB: case GL_PROGRAM_ATTRIBS_ARB: case GL_MAX_PROGRAM_ATTRIBS_ARB: case GL_PROGRAM_NATIVE_ATTRIBS_ARB: case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB: case GL_PROGRAM_ADDRESS_REGISTERS_ARB: case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB: case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB: case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB: case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB: case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB: case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB: case GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV: case GL_MAX_PROGRAM_CALL_DEPTH_NV: case GL_MAX_PROGRAM_IF_DEPTH_NV: case GL_MAX_PROGRAM_LOOP_DEPTH_NV: case GL_MAX_PROGRAM_LOOP_COUNT_NV: return 1; default: return 0; } } _X_INTERNAL PURE FASTCALL GLint __glGetFramebufferAttachmentParameteriv_size(GLenum e) { switch (e) { case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: /* case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:*/ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: /* case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:*/ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: /* case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:*/ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: /* case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:*/ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT: return 1; default: return 0; } } ALIAS(Fogiv, Fogfv) ALIAS(Lightiv, Lightfv) ALIAS(LightModeliv, LightModelfv) ALIAS(Materialiv, Materialfv) ALIAS(TexParameteriv, TexParameterfv) ALIAS(TexEnviv, TexEnvfv) ALIAS(TexGenfv, TexGendv) ALIAS(TexGeniv, TexGendv) ALIAS(Map1f, Map1d) ALIAS(Map2f, Map2d) ALIAS(GetDoublev, GetBooleanv) ALIAS(GetFloatv, GetBooleanv) ALIAS(GetIntegerv, GetBooleanv) ALIAS(GetLightfv, Lightfv) ALIAS(GetLightiv, Lightfv) ALIAS(GetMaterialfv, Materialfv) ALIAS(GetMaterialiv, Materialfv) ALIAS(GetTexEnvfv, TexEnvfv) ALIAS(GetTexEnviv, TexEnvfv) ALIAS(GetTexGendv, TexGendv) ALIAS(GetTexGenfv, TexGendv) ALIAS(GetTexGeniv, TexGendv) ALIAS(GetTexParameteriv, GetTexParameterfv) ALIAS(GetTexLevelParameteriv, GetTexLevelParameterfv) ALIAS(ColorTableParameteriv, ColorTableParameterfv) ALIAS(GetColorTableParameteriv, GetColorTableParameterfv) ALIAS(ConvolutionParameteriv, ConvolutionParameterfv) ALIAS(GetConvolutionParameteriv, GetConvolutionParameterfv) ALIAS(GetHistogramParameteriv, GetHistogramParameterfv) ALIAS(GetMinmaxParameteriv, GetMinmaxParameterfv) ALIAS(PointParameteriv, PointParameterfv) ALIAS(GetQueryObjectuiv, GetQueryObjectiv) #undef PURE #undef FASTCALL xorg-server-1.20.13/glx/indirect_size_get.h0000644000175000017500000001023614100573756015531 00000000000000/* DO NOT EDIT - This file generated automatically by glX_proto_size.py (from Mesa) script */ /* * (C) Copyright IBM Corporation 2004 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #if !defined( _INDIRECT_SIZE_GET_H_ ) #define _INDIRECT_SIZE_GET_H_ /** * \file * Prototypes for functions used to determine the number of data elements in * various GLX protocol messages. * * \author Ian Romanick */ #include #if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) #define PURE __attribute__((pure)) #else #define PURE #endif #if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__) #define FASTCALL __attribute__((fastcall)) #else #define FASTCALL #endif extern _X_INTERNAL PURE FASTCALL GLint __glGetBooleanv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetDoublev_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetFloatv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetIntegerv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetLightfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetLightiv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetMaterialfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetMaterialiv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetTexEnvfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetTexEnviv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetTexGendv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetTexGenfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetTexGeniv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetTexParameterfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetTexParameteriv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetTexLevelParameterfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetTexLevelParameteriv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetPointerv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetColorTableParameterfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetColorTableParameteriv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetConvolutionParameterfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetConvolutionParameteriv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetHistogramParameterfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetHistogramParameteriv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetMinmaxParameterfv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetMinmaxParameteriv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetQueryObjectiv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetQueryObjectuiv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetQueryiv_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetProgramivARB_size(GLenum); extern _X_INTERNAL PURE FASTCALL GLint __glGetFramebufferAttachmentParameteriv_size(GLenum); #undef PURE #undef FASTCALL #endif /* !defined( _INDIRECT_SIZE_GET_H_ ) */ xorg-server-1.20.13/glx/indirect_table.c0000644000175000017500000022454314100573756015012 00000000000000/* DO NOT EDIT - This file generated automatically by glX_server_table.py (from Mesa) script */ /* * (C) Copyright IBM Corporation 2005, 2006 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include "glxserver.h" #include "glxext.h" #include "indirect_dispatch.h" #include "indirect_reqsize.h" #include "indirect_table.h" /*****************************************************************/ /* tree depth = 3 */ static const int_fast16_t Single_dispatch_tree[24] = { /* [0] -> opcode range [0, 256], node depth 1 */ 2, 5, 13, 16, EMPTY_LEAF, /* [5] -> opcode range [0, 64], node depth 2 */ 2, LEAF(0), LEAF(16), 10, EMPTY_LEAF, /* [10] -> opcode range [32, 48], node depth 3 */ 1, LEAF(32), EMPTY_LEAF, /* [13] -> opcode range [64, 128], node depth 2 */ 1, EMPTY_LEAF, LEAF(40), /* [16] -> opcode range [128, 192], node depth 2 */ 2, LEAF(72), LEAF(88), 21, EMPTY_LEAF, /* [21] -> opcode range [160, 176], node depth 3 */ 1, LEAF(104), EMPTY_LEAF, }; static const void *Single_function_table[112][2] = { /* [ 0] = 0 */ {NULL, NULL}, /* [ 1] = 1 */ {__glXDisp_Render, __glXDispSwap_Render}, /* [ 2] = 2 */ {__glXDisp_RenderLarge, __glXDispSwap_RenderLarge}, /* [ 3] = 3 */ {__glXDisp_CreateContext, __glXDispSwap_CreateContext}, /* [ 4] = 4 */ {__glXDisp_DestroyContext, __glXDispSwap_DestroyContext}, /* [ 5] = 5 */ {__glXDisp_MakeCurrent, __glXDispSwap_MakeCurrent}, /* [ 6] = 6 */ {__glXDisp_IsDirect, __glXDispSwap_IsDirect}, /* [ 7] = 7 */ {__glXDisp_QueryVersion, __glXDispSwap_QueryVersion}, /* [ 8] = 8 */ {__glXDisp_WaitGL, __glXDispSwap_WaitGL}, /* [ 9] = 9 */ {__glXDisp_WaitX, __glXDispSwap_WaitX}, /* [ 10] = 10 */ {__glXDisp_CopyContext, __glXDispSwap_CopyContext}, /* [ 11] = 11 */ {__glXDisp_SwapBuffers, __glXDispSwap_SwapBuffers}, /* [ 12] = 12 */ {__glXDisp_UseXFont, __glXDispSwap_UseXFont}, /* [ 13] = 13 */ {__glXDisp_CreateGLXPixmap, __glXDispSwap_CreateGLXPixmap}, /* [ 14] = 14 */ {__glXDisp_GetVisualConfigs, __glXDispSwap_GetVisualConfigs}, /* [ 15] = 15 */ {__glXDisp_DestroyGLXPixmap, __glXDispSwap_DestroyGLXPixmap}, /* [ 16] = 16 */ {__glXDisp_VendorPrivate, __glXDispSwap_VendorPrivate}, /* [ 17] = 17 */ {__glXDisp_VendorPrivateWithReply, __glXDispSwap_VendorPrivateWithReply}, /* [ 18] = 18 */ {__glXDisp_QueryExtensionsString, __glXDispSwap_QueryExtensionsString}, /* [ 19] = 19 */ {__glXDisp_QueryServerString, __glXDispSwap_QueryServerString}, /* [ 20] = 20 */ {__glXDisp_ClientInfo, __glXDispSwap_ClientInfo}, /* [ 21] = 21 */ {__glXDisp_GetFBConfigs, __glXDispSwap_GetFBConfigs}, /* [ 22] = 22 */ {__glXDisp_CreatePixmap, __glXDispSwap_CreatePixmap}, /* [ 23] = 23 */ {__glXDisp_DestroyPixmap, __glXDispSwap_DestroyPixmap}, /* [ 24] = 24 */ {__glXDisp_CreateNewContext, __glXDispSwap_CreateNewContext}, /* [ 25] = 25 */ {__glXDisp_QueryContext, __glXDispSwap_QueryContext}, /* [ 26] = 26 */ {__glXDisp_MakeContextCurrent, __glXDispSwap_MakeContextCurrent}, /* [ 27] = 27 */ {__glXDisp_CreatePbuffer, __glXDispSwap_CreatePbuffer}, /* [ 28] = 28 */ {__glXDisp_DestroyPbuffer, __glXDispSwap_DestroyPbuffer}, /* [ 29] = 29 */ {__glXDisp_GetDrawableAttributes, __glXDispSwap_GetDrawableAttributes}, /* [ 30] = 30 */ {__glXDisp_ChangeDrawableAttributes, __glXDispSwap_ChangeDrawableAttributes}, /* [ 31] = 31 */ {__glXDisp_CreateWindow, __glXDispSwap_CreateWindow}, /* [ 32] = 32 */ {__glXDisp_DestroyWindow, __glXDispSwap_DestroyWindow}, /* [ 33] = 33 */ {__glXDisp_SetClientInfoARB, __glXDispSwap_SetClientInfoARB}, /* [ 34] = 34 */ {__glXDisp_CreateContextAttribsARB, __glXDispSwap_CreateContextAttribsARB}, /* [ 35] = 35 */ {__glXDisp_SetClientInfo2ARB, __glXDispSwap_SetClientInfo2ARB}, /* [ 36] = 36 */ {NULL, NULL}, /* [ 37] = 37 */ {NULL, NULL}, /* [ 38] = 38 */ {NULL, NULL}, /* [ 39] = 39 */ {NULL, NULL}, /* [ 40] = 96 */ {NULL, NULL}, /* [ 41] = 97 */ {NULL, NULL}, /* [ 42] = 98 */ {NULL, NULL}, /* [ 43] = 99 */ {NULL, NULL}, /* [ 44] = 100 */ {NULL, NULL}, /* [ 45] = 101 */ {__glXDisp_NewList, __glXDispSwap_NewList}, /* [ 46] = 102 */ {__glXDisp_EndList, __glXDispSwap_EndList}, /* [ 47] = 103 */ {__glXDisp_DeleteLists, __glXDispSwap_DeleteLists}, /* [ 48] = 104 */ {__glXDisp_GenLists, __glXDispSwap_GenLists}, /* [ 49] = 105 */ {__glXDisp_FeedbackBuffer, __glXDispSwap_FeedbackBuffer}, /* [ 50] = 106 */ {__glXDisp_SelectBuffer, __glXDispSwap_SelectBuffer}, /* [ 51] = 107 */ {__glXDisp_RenderMode, __glXDispSwap_RenderMode}, /* [ 52] = 108 */ {__glXDisp_Finish, __glXDispSwap_Finish}, /* [ 53] = 109 */ {__glXDisp_PixelStoref, __glXDispSwap_PixelStoref}, /* [ 54] = 110 */ {__glXDisp_PixelStorei, __glXDispSwap_PixelStorei}, /* [ 55] = 111 */ {__glXDisp_ReadPixels, __glXDispSwap_ReadPixels}, /* [ 56] = 112 */ {__glXDisp_GetBooleanv, __glXDispSwap_GetBooleanv}, /* [ 57] = 113 */ {__glXDisp_GetClipPlane, __glXDispSwap_GetClipPlane}, /* [ 58] = 114 */ {__glXDisp_GetDoublev, __glXDispSwap_GetDoublev}, /* [ 59] = 115 */ {__glXDisp_GetError, __glXDispSwap_GetError}, /* [ 60] = 116 */ {__glXDisp_GetFloatv, __glXDispSwap_GetFloatv}, /* [ 61] = 117 */ {__glXDisp_GetIntegerv, __glXDispSwap_GetIntegerv}, /* [ 62] = 118 */ {__glXDisp_GetLightfv, __glXDispSwap_GetLightfv}, /* [ 63] = 119 */ {__glXDisp_GetLightiv, __glXDispSwap_GetLightiv}, /* [ 64] = 120 */ {__glXDisp_GetMapdv, __glXDispSwap_GetMapdv}, /* [ 65] = 121 */ {__glXDisp_GetMapfv, __glXDispSwap_GetMapfv}, /* [ 66] = 122 */ {__glXDisp_GetMapiv, __glXDispSwap_GetMapiv}, /* [ 67] = 123 */ {__glXDisp_GetMaterialfv, __glXDispSwap_GetMaterialfv}, /* [ 68] = 124 */ {__glXDisp_GetMaterialiv, __glXDispSwap_GetMaterialiv}, /* [ 69] = 125 */ {__glXDisp_GetPixelMapfv, __glXDispSwap_GetPixelMapfv}, /* [ 70] = 126 */ {__glXDisp_GetPixelMapuiv, __glXDispSwap_GetPixelMapuiv}, /* [ 71] = 127 */ {__glXDisp_GetPixelMapusv, __glXDispSwap_GetPixelMapusv}, /* [ 72] = 128 */ {__glXDisp_GetPolygonStipple, __glXDispSwap_GetPolygonStipple}, /* [ 73] = 129 */ {__glXDisp_GetString, __glXDispSwap_GetString}, /* [ 74] = 130 */ {__glXDisp_GetTexEnvfv, __glXDispSwap_GetTexEnvfv}, /* [ 75] = 131 */ {__glXDisp_GetTexEnviv, __glXDispSwap_GetTexEnviv}, /* [ 76] = 132 */ {__glXDisp_GetTexGendv, __glXDispSwap_GetTexGendv}, /* [ 77] = 133 */ {__glXDisp_GetTexGenfv, __glXDispSwap_GetTexGenfv}, /* [ 78] = 134 */ {__glXDisp_GetTexGeniv, __glXDispSwap_GetTexGeniv}, /* [ 79] = 135 */ {__glXDisp_GetTexImage, __glXDispSwap_GetTexImage}, /* [ 80] = 136 */ {__glXDisp_GetTexParameterfv, __glXDispSwap_GetTexParameterfv}, /* [ 81] = 137 */ {__glXDisp_GetTexParameteriv, __glXDispSwap_GetTexParameteriv}, /* [ 82] = 138 */ {__glXDisp_GetTexLevelParameterfv, __glXDispSwap_GetTexLevelParameterfv}, /* [ 83] = 139 */ {__glXDisp_GetTexLevelParameteriv, __glXDispSwap_GetTexLevelParameteriv}, /* [ 84] = 140 */ {__glXDisp_IsEnabled, __glXDispSwap_IsEnabled}, /* [ 85] = 141 */ {__glXDisp_IsList, __glXDispSwap_IsList}, /* [ 86] = 142 */ {__glXDisp_Flush, __glXDispSwap_Flush}, /* [ 87] = 143 */ {__glXDisp_AreTexturesResident, __glXDispSwap_AreTexturesResident}, /* [ 88] = 144 */ {__glXDisp_DeleteTextures, __glXDispSwap_DeleteTextures}, /* [ 89] = 145 */ {__glXDisp_GenTextures, __glXDispSwap_GenTextures}, /* [ 90] = 146 */ {__glXDisp_IsTexture, __glXDispSwap_IsTexture}, /* [ 91] = 147 */ {__glXDisp_GetColorTable, __glXDispSwap_GetColorTable}, /* [ 92] = 148 */ {__glXDisp_GetColorTableParameterfv, __glXDispSwap_GetColorTableParameterfv}, /* [ 93] = 149 */ {__glXDisp_GetColorTableParameteriv, __glXDispSwap_GetColorTableParameteriv}, /* [ 94] = 150 */ {__glXDisp_GetConvolutionFilter, __glXDispSwap_GetConvolutionFilter}, /* [ 95] = 151 */ {__glXDisp_GetConvolutionParameterfv, __glXDispSwap_GetConvolutionParameterfv}, /* [ 96] = 152 */ {__glXDisp_GetConvolutionParameteriv, __glXDispSwap_GetConvolutionParameteriv}, /* [ 97] = 153 */ {__glXDisp_GetSeparableFilter, __glXDispSwap_GetSeparableFilter}, /* [ 98] = 154 */ {__glXDisp_GetHistogram, __glXDispSwap_GetHistogram}, /* [ 99] = 155 */ {__glXDisp_GetHistogramParameterfv, __glXDispSwap_GetHistogramParameterfv}, /* [ 100] = 156 */ {__glXDisp_GetHistogramParameteriv, __glXDispSwap_GetHistogramParameteriv}, /* [ 101] = 157 */ {__glXDisp_GetMinmax, __glXDispSwap_GetMinmax}, /* [ 102] = 158 */ {__glXDisp_GetMinmaxParameterfv, __glXDispSwap_GetMinmaxParameterfv}, /* [ 103] = 159 */ {__glXDisp_GetMinmaxParameteriv, __glXDispSwap_GetMinmaxParameteriv}, /* [ 104] = 160 */ {__glXDisp_GetCompressedTexImage, __glXDispSwap_GetCompressedTexImage}, /* [ 105] = 161 */ {__glXDisp_DeleteQueries, __glXDispSwap_DeleteQueries}, /* [ 106] = 162 */ {__glXDisp_GenQueries, __glXDispSwap_GenQueries}, /* [ 107] = 163 */ {__glXDisp_IsQuery, __glXDispSwap_IsQuery}, /* [ 108] = 164 */ {__glXDisp_GetQueryiv, __glXDispSwap_GetQueryiv}, /* [ 109] = 165 */ {__glXDisp_GetQueryObjectiv, __glXDispSwap_GetQueryObjectiv}, /* [ 110] = 166 */ {__glXDisp_GetQueryObjectuiv, __glXDispSwap_GetQueryObjectuiv}, /* [ 111] = 167 */ {NULL, NULL}, }; const struct __glXDispatchInfo Single_dispatch_info = { 8, Single_dispatch_tree, Single_function_table, NULL, NULL }; /*****************************************************************/ /* tree depth = 8 */ static const int_fast16_t Render_dispatch_tree[92] = { /* [0] -> opcode range [0, 8192], node depth 1 */ 2, 5, 31, 54, EMPTY_LEAF, /* [5] -> opcode range [0, 2048], node depth 2 */ 1, 8, EMPTY_LEAF, /* [8] -> opcode range [0, 1024], node depth 3 */ 1, 11, EMPTY_LEAF, /* [11] -> opcode range [0, 512], node depth 4 */ 1, 14, EMPTY_LEAF, /* [14] -> opcode range [0, 256], node depth 5 */ 4, LEAF(0), LEAF(16), LEAF(32), LEAF(48), LEAF(64), LEAF(80), LEAF(96), LEAF(112), LEAF(128), LEAF(144), LEAF(160), LEAF(176), LEAF(192), LEAF(208), LEAF(224), EMPTY_LEAF, /* [31] -> opcode range [2048, 4096], node depth 2 */ 1, 34, EMPTY_LEAF, /* [34] -> opcode range [2048, 3072], node depth 3 */ 1, 37, EMPTY_LEAF, /* [37] -> opcode range [2048, 2560], node depth 4 */ 1, 40, EMPTY_LEAF, /* [40] -> opcode range [2048, 2304], node depth 5 */ 1, 43, EMPTY_LEAF, /* [43] -> opcode range [2048, 2176], node depth 6 */ 1, 46, EMPTY_LEAF, /* [46] -> opcode range [2048, 2112], node depth 7 */ 1, 49, EMPTY_LEAF, /* [49] -> opcode range [2048, 2080], node depth 8 */ 2, LEAF(240), LEAF(248), LEAF(256), EMPTY_LEAF, /* [54] -> opcode range [4096, 6144], node depth 2 */ 1, 57, EMPTY_LEAF, /* [57] -> opcode range [4096, 5120], node depth 3 */ 1, 60, EMPTY_LEAF, /* [60] -> opcode range [4096, 4608], node depth 4 */ 1, 63, EMPTY_LEAF, /* [63] -> opcode range [4096, 4352], node depth 5 */ 4, LEAF(264), LEAF(280), 80, EMPTY_LEAF, EMPTY_LEAF, LEAF(296), LEAF(312), LEAF(328), LEAF(344), EMPTY_LEAF, 83, 86, EMPTY_LEAF, 89, LEAF(360), EMPTY_LEAF, /* [80] -> opcode range [4128, 4144], node depth 6 */ 1, LEAF(376), EMPTY_LEAF, /* [83] -> opcode range [4256, 4272], node depth 6 */ 1, EMPTY_LEAF, LEAF(384), /* [86] -> opcode range [4272, 4288], node depth 6 */ 1, LEAF(392), EMPTY_LEAF, /* [89] -> opcode range [4304, 4320], node depth 6 */ 1, EMPTY_LEAF, LEAF(400), }; static const void *Render_function_table[408][2] = { /* [ 0] = 0 */ {NULL, NULL}, /* [ 1] = 1 */ {__glXDisp_CallList, __glXDispSwap_CallList}, /* [ 2] = 2 */ {__glXDisp_CallLists, __glXDispSwap_CallLists}, /* [ 3] = 3 */ {__glXDisp_ListBase, __glXDispSwap_ListBase}, /* [ 4] = 4 */ {__glXDisp_Begin, __glXDispSwap_Begin}, /* [ 5] = 5 */ {__glXDisp_Bitmap, __glXDispSwap_Bitmap}, /* [ 6] = 6 */ {__glXDisp_Color3bv, __glXDispSwap_Color3bv}, /* [ 7] = 7 */ {__glXDisp_Color3dv, __glXDispSwap_Color3dv}, /* [ 8] = 8 */ {__glXDisp_Color3fv, __glXDispSwap_Color3fv}, /* [ 9] = 9 */ {__glXDisp_Color3iv, __glXDispSwap_Color3iv}, /* [ 10] = 10 */ {__glXDisp_Color3sv, __glXDispSwap_Color3sv}, /* [ 11] = 11 */ {__glXDisp_Color3ubv, __glXDispSwap_Color3ubv}, /* [ 12] = 12 */ {__glXDisp_Color3uiv, __glXDispSwap_Color3uiv}, /* [ 13] = 13 */ {__glXDisp_Color3usv, __glXDispSwap_Color3usv}, /* [ 14] = 14 */ {__glXDisp_Color4bv, __glXDispSwap_Color4bv}, /* [ 15] = 15 */ {__glXDisp_Color4dv, __glXDispSwap_Color4dv}, /* [ 16] = 16 */ {__glXDisp_Color4fv, __glXDispSwap_Color4fv}, /* [ 17] = 17 */ {__glXDisp_Color4iv, __glXDispSwap_Color4iv}, /* [ 18] = 18 */ {__glXDisp_Color4sv, __glXDispSwap_Color4sv}, /* [ 19] = 19 */ {__glXDisp_Color4ubv, __glXDispSwap_Color4ubv}, /* [ 20] = 20 */ {__glXDisp_Color4uiv, __glXDispSwap_Color4uiv}, /* [ 21] = 21 */ {__glXDisp_Color4usv, __glXDispSwap_Color4usv}, /* [ 22] = 22 */ {__glXDisp_EdgeFlagv, __glXDispSwap_EdgeFlagv}, /* [ 23] = 23 */ {__glXDisp_End, __glXDispSwap_End}, /* [ 24] = 24 */ {__glXDisp_Indexdv, __glXDispSwap_Indexdv}, /* [ 25] = 25 */ {__glXDisp_Indexfv, __glXDispSwap_Indexfv}, /* [ 26] = 26 */ {__glXDisp_Indexiv, __glXDispSwap_Indexiv}, /* [ 27] = 27 */ {__glXDisp_Indexsv, __glXDispSwap_Indexsv}, /* [ 28] = 28 */ {__glXDisp_Normal3bv, __glXDispSwap_Normal3bv}, /* [ 29] = 29 */ {__glXDisp_Normal3dv, __glXDispSwap_Normal3dv}, /* [ 30] = 30 */ {__glXDisp_Normal3fv, __glXDispSwap_Normal3fv}, /* [ 31] = 31 */ {__glXDisp_Normal3iv, __glXDispSwap_Normal3iv}, /* [ 32] = 32 */ {__glXDisp_Normal3sv, __glXDispSwap_Normal3sv}, /* [ 33] = 33 */ {__glXDisp_RasterPos2dv, __glXDispSwap_RasterPos2dv}, /* [ 34] = 34 */ {__glXDisp_RasterPos2fv, __glXDispSwap_RasterPos2fv}, /* [ 35] = 35 */ {__glXDisp_RasterPos2iv, __glXDispSwap_RasterPos2iv}, /* [ 36] = 36 */ {__glXDisp_RasterPos2sv, __glXDispSwap_RasterPos2sv}, /* [ 37] = 37 */ {__glXDisp_RasterPos3dv, __glXDispSwap_RasterPos3dv}, /* [ 38] = 38 */ {__glXDisp_RasterPos3fv, __glXDispSwap_RasterPos3fv}, /* [ 39] = 39 */ {__glXDisp_RasterPos3iv, __glXDispSwap_RasterPos3iv}, /* [ 40] = 40 */ {__glXDisp_RasterPos3sv, __glXDispSwap_RasterPos3sv}, /* [ 41] = 41 */ {__glXDisp_RasterPos4dv, __glXDispSwap_RasterPos4dv}, /* [ 42] = 42 */ {__glXDisp_RasterPos4fv, __glXDispSwap_RasterPos4fv}, /* [ 43] = 43 */ {__glXDisp_RasterPos4iv, __glXDispSwap_RasterPos4iv}, /* [ 44] = 44 */ {__glXDisp_RasterPos4sv, __glXDispSwap_RasterPos4sv}, /* [ 45] = 45 */ {__glXDisp_Rectdv, __glXDispSwap_Rectdv}, /* [ 46] = 46 */ {__glXDisp_Rectfv, __glXDispSwap_Rectfv}, /* [ 47] = 47 */ {__glXDisp_Rectiv, __glXDispSwap_Rectiv}, /* [ 48] = 48 */ {__glXDisp_Rectsv, __glXDispSwap_Rectsv}, /* [ 49] = 49 */ {__glXDisp_TexCoord1dv, __glXDispSwap_TexCoord1dv}, /* [ 50] = 50 */ {__glXDisp_TexCoord1fv, __glXDispSwap_TexCoord1fv}, /* [ 51] = 51 */ {__glXDisp_TexCoord1iv, __glXDispSwap_TexCoord1iv}, /* [ 52] = 52 */ {__glXDisp_TexCoord1sv, __glXDispSwap_TexCoord1sv}, /* [ 53] = 53 */ {__glXDisp_TexCoord2dv, __glXDispSwap_TexCoord2dv}, /* [ 54] = 54 */ {__glXDisp_TexCoord2fv, __glXDispSwap_TexCoord2fv}, /* [ 55] = 55 */ {__glXDisp_TexCoord2iv, __glXDispSwap_TexCoord2iv}, /* [ 56] = 56 */ {__glXDisp_TexCoord2sv, __glXDispSwap_TexCoord2sv}, /* [ 57] = 57 */ {__glXDisp_TexCoord3dv, __glXDispSwap_TexCoord3dv}, /* [ 58] = 58 */ {__glXDisp_TexCoord3fv, __glXDispSwap_TexCoord3fv}, /* [ 59] = 59 */ {__glXDisp_TexCoord3iv, __glXDispSwap_TexCoord3iv}, /* [ 60] = 60 */ {__glXDisp_TexCoord3sv, __glXDispSwap_TexCoord3sv}, /* [ 61] = 61 */ {__glXDisp_TexCoord4dv, __glXDispSwap_TexCoord4dv}, /* [ 62] = 62 */ {__glXDisp_TexCoord4fv, __glXDispSwap_TexCoord4fv}, /* [ 63] = 63 */ {__glXDisp_TexCoord4iv, __glXDispSwap_TexCoord4iv}, /* [ 64] = 64 */ {__glXDisp_TexCoord4sv, __glXDispSwap_TexCoord4sv}, /* [ 65] = 65 */ {__glXDisp_Vertex2dv, __glXDispSwap_Vertex2dv}, /* [ 66] = 66 */ {__glXDisp_Vertex2fv, __glXDispSwap_Vertex2fv}, /* [ 67] = 67 */ {__glXDisp_Vertex2iv, __glXDispSwap_Vertex2iv}, /* [ 68] = 68 */ {__glXDisp_Vertex2sv, __glXDispSwap_Vertex2sv}, /* [ 69] = 69 */ {__glXDisp_Vertex3dv, __glXDispSwap_Vertex3dv}, /* [ 70] = 70 */ {__glXDisp_Vertex3fv, __glXDispSwap_Vertex3fv}, /* [ 71] = 71 */ {__glXDisp_Vertex3iv, __glXDispSwap_Vertex3iv}, /* [ 72] = 72 */ {__glXDisp_Vertex3sv, __glXDispSwap_Vertex3sv}, /* [ 73] = 73 */ {__glXDisp_Vertex4dv, __glXDispSwap_Vertex4dv}, /* [ 74] = 74 */ {__glXDisp_Vertex4fv, __glXDispSwap_Vertex4fv}, /* [ 75] = 75 */ {__glXDisp_Vertex4iv, __glXDispSwap_Vertex4iv}, /* [ 76] = 76 */ {__glXDisp_Vertex4sv, __glXDispSwap_Vertex4sv}, /* [ 77] = 77 */ {__glXDisp_ClipPlane, __glXDispSwap_ClipPlane}, /* [ 78] = 78 */ {__glXDisp_ColorMaterial, __glXDispSwap_ColorMaterial}, /* [ 79] = 79 */ {__glXDisp_CullFace, __glXDispSwap_CullFace}, /* [ 80] = 80 */ {__glXDisp_Fogf, __glXDispSwap_Fogf}, /* [ 81] = 81 */ {__glXDisp_Fogfv, __glXDispSwap_Fogfv}, /* [ 82] = 82 */ {__glXDisp_Fogi, __glXDispSwap_Fogi}, /* [ 83] = 83 */ {__glXDisp_Fogiv, __glXDispSwap_Fogiv}, /* [ 84] = 84 */ {__glXDisp_FrontFace, __glXDispSwap_FrontFace}, /* [ 85] = 85 */ {__glXDisp_Hint, __glXDispSwap_Hint}, /* [ 86] = 86 */ {__glXDisp_Lightf, __glXDispSwap_Lightf}, /* [ 87] = 87 */ {__glXDisp_Lightfv, __glXDispSwap_Lightfv}, /* [ 88] = 88 */ {__glXDisp_Lighti, __glXDispSwap_Lighti}, /* [ 89] = 89 */ {__glXDisp_Lightiv, __glXDispSwap_Lightiv}, /* [ 90] = 90 */ {__glXDisp_LightModelf, __glXDispSwap_LightModelf}, /* [ 91] = 91 */ {__glXDisp_LightModelfv, __glXDispSwap_LightModelfv}, /* [ 92] = 92 */ {__glXDisp_LightModeli, __glXDispSwap_LightModeli}, /* [ 93] = 93 */ {__glXDisp_LightModeliv, __glXDispSwap_LightModeliv}, /* [ 94] = 94 */ {__glXDisp_LineStipple, __glXDispSwap_LineStipple}, /* [ 95] = 95 */ {__glXDisp_LineWidth, __glXDispSwap_LineWidth}, /* [ 96] = 96 */ {__glXDisp_Materialf, __glXDispSwap_Materialf}, /* [ 97] = 97 */ {__glXDisp_Materialfv, __glXDispSwap_Materialfv}, /* [ 98] = 98 */ {__glXDisp_Materiali, __glXDispSwap_Materiali}, /* [ 99] = 99 */ {__glXDisp_Materialiv, __glXDispSwap_Materialiv}, /* [ 100] = 100 */ {__glXDisp_PointSize, __glXDispSwap_PointSize}, /* [ 101] = 101 */ {__glXDisp_PolygonMode, __glXDispSwap_PolygonMode}, /* [ 102] = 102 */ {__glXDisp_PolygonStipple, __glXDispSwap_PolygonStipple}, /* [ 103] = 103 */ {__glXDisp_Scissor, __glXDispSwap_Scissor}, /* [ 104] = 104 */ {__glXDisp_ShadeModel, __glXDispSwap_ShadeModel}, /* [ 105] = 105 */ {__glXDisp_TexParameterf, __glXDispSwap_TexParameterf}, /* [ 106] = 106 */ {__glXDisp_TexParameterfv, __glXDispSwap_TexParameterfv}, /* [ 107] = 107 */ {__glXDisp_TexParameteri, __glXDispSwap_TexParameteri}, /* [ 108] = 108 */ {__glXDisp_TexParameteriv, __glXDispSwap_TexParameteriv}, /* [ 109] = 109 */ {__glXDisp_TexImage1D, __glXDispSwap_TexImage1D}, /* [ 110] = 110 */ {__glXDisp_TexImage2D, __glXDispSwap_TexImage2D}, /* [ 111] = 111 */ {__glXDisp_TexEnvf, __glXDispSwap_TexEnvf}, /* [ 112] = 112 */ {__glXDisp_TexEnvfv, __glXDispSwap_TexEnvfv}, /* [ 113] = 113 */ {__glXDisp_TexEnvi, __glXDispSwap_TexEnvi}, /* [ 114] = 114 */ {__glXDisp_TexEnviv, __glXDispSwap_TexEnviv}, /* [ 115] = 115 */ {__glXDisp_TexGend, __glXDispSwap_TexGend}, /* [ 116] = 116 */ {__glXDisp_TexGendv, __glXDispSwap_TexGendv}, /* [ 117] = 117 */ {__glXDisp_TexGenf, __glXDispSwap_TexGenf}, /* [ 118] = 118 */ {__glXDisp_TexGenfv, __glXDispSwap_TexGenfv}, /* [ 119] = 119 */ {__glXDisp_TexGeni, __glXDispSwap_TexGeni}, /* [ 120] = 120 */ {__glXDisp_TexGeniv, __glXDispSwap_TexGeniv}, /* [ 121] = 121 */ {__glXDisp_InitNames, __glXDispSwap_InitNames}, /* [ 122] = 122 */ {__glXDisp_LoadName, __glXDispSwap_LoadName}, /* [ 123] = 123 */ {__glXDisp_PassThrough, __glXDispSwap_PassThrough}, /* [ 124] = 124 */ {__glXDisp_PopName, __glXDispSwap_PopName}, /* [ 125] = 125 */ {__glXDisp_PushName, __glXDispSwap_PushName}, /* [ 126] = 126 */ {__glXDisp_DrawBuffer, __glXDispSwap_DrawBuffer}, /* [ 127] = 127 */ {__glXDisp_Clear, __glXDispSwap_Clear}, /* [ 128] = 128 */ {__glXDisp_ClearAccum, __glXDispSwap_ClearAccum}, /* [ 129] = 129 */ {__glXDisp_ClearIndex, __glXDispSwap_ClearIndex}, /* [ 130] = 130 */ {__glXDisp_ClearColor, __glXDispSwap_ClearColor}, /* [ 131] = 131 */ {__glXDisp_ClearStencil, __glXDispSwap_ClearStencil}, /* [ 132] = 132 */ {__glXDisp_ClearDepth, __glXDispSwap_ClearDepth}, /* [ 133] = 133 */ {__glXDisp_StencilMask, __glXDispSwap_StencilMask}, /* [ 134] = 134 */ {__glXDisp_ColorMask, __glXDispSwap_ColorMask}, /* [ 135] = 135 */ {__glXDisp_DepthMask, __glXDispSwap_DepthMask}, /* [ 136] = 136 */ {__glXDisp_IndexMask, __glXDispSwap_IndexMask}, /* [ 137] = 137 */ {__glXDisp_Accum, __glXDispSwap_Accum}, /* [ 138] = 138 */ {__glXDisp_Disable, __glXDispSwap_Disable}, /* [ 139] = 139 */ {__glXDisp_Enable, __glXDispSwap_Enable}, /* [ 140] = 140 */ {NULL, NULL}, /* [ 141] = 141 */ {__glXDisp_PopAttrib, __glXDispSwap_PopAttrib}, /* [ 142] = 142 */ {__glXDisp_PushAttrib, __glXDispSwap_PushAttrib}, /* [ 143] = 143 */ {__glXDisp_Map1d, __glXDispSwap_Map1d}, /* [ 144] = 144 */ {__glXDisp_Map1f, __glXDispSwap_Map1f}, /* [ 145] = 145 */ {__glXDisp_Map2d, __glXDispSwap_Map2d}, /* [ 146] = 146 */ {__glXDisp_Map2f, __glXDispSwap_Map2f}, /* [ 147] = 147 */ {__glXDisp_MapGrid1d, __glXDispSwap_MapGrid1d}, /* [ 148] = 148 */ {__glXDisp_MapGrid1f, __glXDispSwap_MapGrid1f}, /* [ 149] = 149 */ {__glXDisp_MapGrid2d, __glXDispSwap_MapGrid2d}, /* [ 150] = 150 */ {__glXDisp_MapGrid2f, __glXDispSwap_MapGrid2f}, /* [ 151] = 151 */ {__glXDisp_EvalCoord1dv, __glXDispSwap_EvalCoord1dv}, /* [ 152] = 152 */ {__glXDisp_EvalCoord1fv, __glXDispSwap_EvalCoord1fv}, /* [ 153] = 153 */ {__glXDisp_EvalCoord2dv, __glXDispSwap_EvalCoord2dv}, /* [ 154] = 154 */ {__glXDisp_EvalCoord2fv, __glXDispSwap_EvalCoord2fv}, /* [ 155] = 155 */ {__glXDisp_EvalMesh1, __glXDispSwap_EvalMesh1}, /* [ 156] = 156 */ {__glXDisp_EvalPoint1, __glXDispSwap_EvalPoint1}, /* [ 157] = 157 */ {__glXDisp_EvalMesh2, __glXDispSwap_EvalMesh2}, /* [ 158] = 158 */ {__glXDisp_EvalPoint2, __glXDispSwap_EvalPoint2}, /* [ 159] = 159 */ {__glXDisp_AlphaFunc, __glXDispSwap_AlphaFunc}, /* [ 160] = 160 */ {__glXDisp_BlendFunc, __glXDispSwap_BlendFunc}, /* [ 161] = 161 */ {__glXDisp_LogicOp, __glXDispSwap_LogicOp}, /* [ 162] = 162 */ {__glXDisp_StencilFunc, __glXDispSwap_StencilFunc}, /* [ 163] = 163 */ {__glXDisp_StencilOp, __glXDispSwap_StencilOp}, /* [ 164] = 164 */ {__glXDisp_DepthFunc, __glXDispSwap_DepthFunc}, /* [ 165] = 165 */ {__glXDisp_PixelZoom, __glXDispSwap_PixelZoom}, /* [ 166] = 166 */ {__glXDisp_PixelTransferf, __glXDispSwap_PixelTransferf}, /* [ 167] = 167 */ {__glXDisp_PixelTransferi, __glXDispSwap_PixelTransferi}, /* [ 168] = 168 */ {__glXDisp_PixelMapfv, __glXDispSwap_PixelMapfv}, /* [ 169] = 169 */ {__glXDisp_PixelMapuiv, __glXDispSwap_PixelMapuiv}, /* [ 170] = 170 */ {__glXDisp_PixelMapusv, __glXDispSwap_PixelMapusv}, /* [ 171] = 171 */ {__glXDisp_ReadBuffer, __glXDispSwap_ReadBuffer}, /* [ 172] = 172 */ {__glXDisp_CopyPixels, __glXDispSwap_CopyPixels}, /* [ 173] = 173 */ {__glXDisp_DrawPixels, __glXDispSwap_DrawPixels}, /* [ 174] = 174 */ {__glXDisp_DepthRange, __glXDispSwap_DepthRange}, /* [ 175] = 175 */ {__glXDisp_Frustum, __glXDispSwap_Frustum}, /* [ 176] = 176 */ {__glXDisp_LoadIdentity, __glXDispSwap_LoadIdentity}, /* [ 177] = 177 */ {__glXDisp_LoadMatrixf, __glXDispSwap_LoadMatrixf}, /* [ 178] = 178 */ {__glXDisp_LoadMatrixd, __glXDispSwap_LoadMatrixd}, /* [ 179] = 179 */ {__glXDisp_MatrixMode, __glXDispSwap_MatrixMode}, /* [ 180] = 180 */ {__glXDisp_MultMatrixf, __glXDispSwap_MultMatrixf}, /* [ 181] = 181 */ {__glXDisp_MultMatrixd, __glXDispSwap_MultMatrixd}, /* [ 182] = 182 */ {__glXDisp_Ortho, __glXDispSwap_Ortho}, /* [ 183] = 183 */ {__glXDisp_PopMatrix, __glXDispSwap_PopMatrix}, /* [ 184] = 184 */ {__glXDisp_PushMatrix, __glXDispSwap_PushMatrix}, /* [ 185] = 185 */ {__glXDisp_Rotated, __glXDispSwap_Rotated}, /* [ 186] = 186 */ {__glXDisp_Rotatef, __glXDispSwap_Rotatef}, /* [ 187] = 187 */ {__glXDisp_Scaled, __glXDispSwap_Scaled}, /* [ 188] = 188 */ {__glXDisp_Scalef, __glXDispSwap_Scalef}, /* [ 189] = 189 */ {__glXDisp_Translated, __glXDispSwap_Translated}, /* [ 190] = 190 */ {__glXDisp_Translatef, __glXDispSwap_Translatef}, /* [ 191] = 191 */ {__glXDisp_Viewport, __glXDispSwap_Viewport}, /* [ 192] = 192 */ {__glXDisp_PolygonOffset, __glXDispSwap_PolygonOffset}, /* [ 193] = 193 */ {__glXDisp_DrawArrays, __glXDispSwap_DrawArrays}, /* [ 194] = 194 */ {__glXDisp_Indexubv, __glXDispSwap_Indexubv}, /* [ 195] = 195 */ {__glXDisp_ColorSubTable, __glXDispSwap_ColorSubTable}, /* [ 196] = 196 */ {__glXDisp_CopyColorSubTable, __glXDispSwap_CopyColorSubTable}, /* [ 197] = 197 */ {__glXDisp_ActiveTexture, __glXDispSwap_ActiveTexture}, /* [ 198] = 198 */ {__glXDisp_MultiTexCoord1dv, __glXDispSwap_MultiTexCoord1dv}, /* [ 199] = 199 */ {__glXDisp_MultiTexCoord1fvARB, __glXDispSwap_MultiTexCoord1fvARB}, /* [ 200] = 200 */ {__glXDisp_MultiTexCoord1iv, __glXDispSwap_MultiTexCoord1iv}, /* [ 201] = 201 */ {__glXDisp_MultiTexCoord1sv, __glXDispSwap_MultiTexCoord1sv}, /* [ 202] = 202 */ {__glXDisp_MultiTexCoord2dv, __glXDispSwap_MultiTexCoord2dv}, /* [ 203] = 203 */ {__glXDisp_MultiTexCoord2fvARB, __glXDispSwap_MultiTexCoord2fvARB}, /* [ 204] = 204 */ {__glXDisp_MultiTexCoord2iv, __glXDispSwap_MultiTexCoord2iv}, /* [ 205] = 205 */ {__glXDisp_MultiTexCoord2sv, __glXDispSwap_MultiTexCoord2sv}, /* [ 206] = 206 */ {__glXDisp_MultiTexCoord3dv, __glXDispSwap_MultiTexCoord3dv}, /* [ 207] = 207 */ {__glXDisp_MultiTexCoord3fvARB, __glXDispSwap_MultiTexCoord3fvARB}, /* [ 208] = 208 */ {__glXDisp_MultiTexCoord3iv, __glXDispSwap_MultiTexCoord3iv}, /* [ 209] = 209 */ {__glXDisp_MultiTexCoord3sv, __glXDispSwap_MultiTexCoord3sv}, /* [ 210] = 210 */ {__glXDisp_MultiTexCoord4dv, __glXDispSwap_MultiTexCoord4dv}, /* [ 211] = 211 */ {__glXDisp_MultiTexCoord4fvARB, __glXDispSwap_MultiTexCoord4fvARB}, /* [ 212] = 212 */ {__glXDisp_MultiTexCoord4iv, __glXDispSwap_MultiTexCoord4iv}, /* [ 213] = 213 */ {__glXDisp_MultiTexCoord4sv, __glXDispSwap_MultiTexCoord4sv}, /* [ 214] = 214 */ {__glXDisp_CompressedTexImage1D, __glXDispSwap_CompressedTexImage1D}, /* [ 215] = 215 */ {__glXDisp_CompressedTexImage2D, __glXDispSwap_CompressedTexImage2D}, /* [ 216] = 216 */ {__glXDisp_CompressedTexImage3D, __glXDispSwap_CompressedTexImage3D}, /* [ 217] = 217 */ {__glXDisp_CompressedTexSubImage1D, __glXDispSwap_CompressedTexSubImage1D}, /* [ 218] = 218 */ {__glXDisp_CompressedTexSubImage2D, __glXDispSwap_CompressedTexSubImage2D}, /* [ 219] = 219 */ {__glXDisp_CompressedTexSubImage3D, __glXDispSwap_CompressedTexSubImage3D}, /* [ 220] = 220 */ {NULL, NULL}, /* [ 221] = 221 */ {NULL, NULL}, /* [ 222] = 222 */ {NULL, NULL}, /* [ 223] = 223 */ {NULL, NULL}, /* [ 224] = 224 */ {NULL, NULL}, /* [ 225] = 225 */ {NULL, NULL}, /* [ 226] = 226 */ {NULL, NULL}, /* [ 227] = 227 */ {NULL, NULL}, /* [ 228] = 228 */ {NULL, NULL}, /* [ 229] = 229 */ {__glXDisp_SampleCoverage, __glXDispSwap_SampleCoverage}, /* [ 230] = 230 */ {__glXDisp_WindowPos3fv, __glXDispSwap_WindowPos3fv}, /* [ 231] = 231 */ {__glXDisp_BeginQuery, __glXDispSwap_BeginQuery}, /* [ 232] = 232 */ {__glXDisp_EndQuery, __glXDispSwap_EndQuery}, /* [ 233] = 233 */ {__glXDisp_DrawBuffers, __glXDispSwap_DrawBuffers}, /* [ 234] = 234 */ {__glXDisp_ClampColor, __glXDispSwap_ClampColor}, /* [ 235] = 235 */ {NULL, NULL}, /* [ 236] = 236 */ {NULL, NULL}, /* [ 237] = 237 */ {__glXDisp_FramebufferTextureLayer, __glXDispSwap_FramebufferTextureLayer}, /* [ 238] = 238 */ {NULL, NULL}, /* [ 239] = 239 */ {NULL, NULL}, /* [ 240] = 2048 */ {NULL, NULL}, /* [ 241] = 2049 */ {NULL, NULL}, /* [ 242] = 2050 */ {NULL, NULL}, /* [ 243] = 2051 */ {NULL, NULL}, /* [ 244] = 2052 */ {NULL, NULL}, /* [ 245] = 2053 */ {__glXDisp_ColorTable, __glXDispSwap_ColorTable}, /* [ 246] = 2054 */ {__glXDisp_ColorTableParameterfv, __glXDispSwap_ColorTableParameterfv}, /* [ 247] = 2055 */ {__glXDisp_ColorTableParameteriv, __glXDispSwap_ColorTableParameteriv}, /* [ 248] = 2056 */ {__glXDisp_CopyColorTable, __glXDispSwap_CopyColorTable}, /* [ 249] = 2057 */ {NULL, NULL}, /* [ 250] = 2058 */ {NULL, NULL}, /* [ 251] = 2059 */ {NULL, NULL}, /* [ 252] = 2060 */ {NULL, NULL}, /* [ 253] = 2061 */ {NULL, NULL}, /* [ 254] = 2062 */ {NULL, NULL}, /* [ 255] = 2063 */ {NULL, NULL}, /* [ 256] = 2064 */ {NULL, NULL}, /* [ 257] = 2065 */ {__glXDisp_PointParameterf, __glXDispSwap_PointParameterf}, /* [ 258] = 2066 */ {__glXDisp_PointParameterfv, __glXDispSwap_PointParameterfv}, /* [ 259] = 2067 */ {NULL, NULL}, /* [ 260] = 2068 */ {NULL, NULL}, /* [ 261] = 2069 */ {NULL, NULL}, /* [ 262] = 2070 */ {NULL, NULL}, /* [ 263] = 2071 */ {NULL, NULL}, /* [ 264] = 4096 */ {__glXDisp_BlendColor, __glXDispSwap_BlendColor}, /* [ 265] = 4097 */ {__glXDisp_BlendEquation, __glXDispSwap_BlendEquation}, /* [ 266] = 4098 */ {NULL, NULL}, /* [ 267] = 4099 */ {__glXDisp_TexSubImage1D, __glXDispSwap_TexSubImage1D}, /* [ 268] = 4100 */ {__glXDisp_TexSubImage2D, __glXDispSwap_TexSubImage2D}, /* [ 269] = 4101 */ {__glXDisp_ConvolutionFilter1D, __glXDispSwap_ConvolutionFilter1D}, /* [ 270] = 4102 */ {__glXDisp_ConvolutionFilter2D, __glXDispSwap_ConvolutionFilter2D}, /* [ 271] = 4103 */ {__glXDisp_ConvolutionParameterf, __glXDispSwap_ConvolutionParameterf}, /* [ 272] = 4104 */ {__glXDisp_ConvolutionParameterfv, __glXDispSwap_ConvolutionParameterfv}, /* [ 273] = 4105 */ {__glXDisp_ConvolutionParameteri, __glXDispSwap_ConvolutionParameteri}, /* [ 274] = 4106 */ {__glXDisp_ConvolutionParameteriv, __glXDispSwap_ConvolutionParameteriv}, /* [ 275] = 4107 */ {__glXDisp_CopyConvolutionFilter1D, __glXDispSwap_CopyConvolutionFilter1D}, /* [ 276] = 4108 */ {__glXDisp_CopyConvolutionFilter2D, __glXDispSwap_CopyConvolutionFilter2D}, /* [ 277] = 4109 */ {__glXDisp_SeparableFilter2D, __glXDispSwap_SeparableFilter2D}, /* [ 278] = 4110 */ {__glXDisp_Histogram, __glXDispSwap_Histogram}, /* [ 279] = 4111 */ {__glXDisp_Minmax, __glXDispSwap_Minmax}, /* [ 280] = 4112 */ {__glXDisp_ResetHistogram, __glXDispSwap_ResetHistogram}, /* [ 281] = 4113 */ {__glXDisp_ResetMinmax, __glXDispSwap_ResetMinmax}, /* [ 282] = 4114 */ {__glXDisp_TexImage3D, __glXDispSwap_TexImage3D}, /* [ 283] = 4115 */ {__glXDisp_TexSubImage3D, __glXDispSwap_TexSubImage3D}, /* [ 284] = 4116 */ {NULL, NULL}, /* [ 285] = 4117 */ {__glXDisp_BindTexture, __glXDispSwap_BindTexture}, /* [ 286] = 4118 */ {__glXDisp_PrioritizeTextures, __glXDispSwap_PrioritizeTextures}, /* [ 287] = 4119 */ {__glXDisp_CopyTexImage1D, __glXDispSwap_CopyTexImage1D}, /* [ 288] = 4120 */ {__glXDisp_CopyTexImage2D, __glXDispSwap_CopyTexImage2D}, /* [ 289] = 4121 */ {__glXDisp_CopyTexSubImage1D, __glXDispSwap_CopyTexSubImage1D}, /* [ 290] = 4122 */ {__glXDisp_CopyTexSubImage2D, __glXDispSwap_CopyTexSubImage2D}, /* [ 291] = 4123 */ {__glXDisp_CopyTexSubImage3D, __glXDispSwap_CopyTexSubImage3D}, /* [ 292] = 4124 */ {__glXDisp_FogCoordfvEXT, __glXDispSwap_FogCoordfvEXT}, /* [ 293] = 4125 */ {__glXDisp_FogCoorddv, __glXDispSwap_FogCoorddv}, /* [ 294] = 4126 */ {__glXDisp_SecondaryColor3bv, __glXDispSwap_SecondaryColor3bv}, /* [ 295] = 4127 */ {__glXDisp_SecondaryColor3sv, __glXDispSwap_SecondaryColor3sv}, /* [ 296] = 4176 */ {NULL, NULL}, /* [ 297] = 4177 */ {NULL, NULL}, /* [ 298] = 4178 */ {NULL, NULL}, /* [ 299] = 4179 */ {NULL, NULL}, /* [ 300] = 4180 */ {__glXDisp_BindProgramARB, __glXDispSwap_BindProgramARB}, /* [ 301] = 4181 */ {NULL, NULL}, /* [ 302] = 4182 */ {NULL, NULL}, /* [ 303] = 4183 */ {NULL, NULL}, /* [ 304] = 4184 */ {__glXDisp_ProgramEnvParameter4fvARB, __glXDispSwap_ProgramEnvParameter4fvARB}, /* [ 305] = 4185 */ {__glXDisp_ProgramEnvParameter4dvARB, __glXDispSwap_ProgramEnvParameter4dvARB}, /* [ 306] = 4186 */ {NULL, NULL}, /* [ 307] = 4187 */ {NULL, NULL}, /* [ 308] = 4188 */ {NULL, NULL}, /* [ 309] = 4189 */ {__glXDisp_VertexAttrib1sv, __glXDispSwap_VertexAttrib1sv}, /* [ 310] = 4190 */ {__glXDisp_VertexAttrib2sv, __glXDispSwap_VertexAttrib2sv}, /* [ 311] = 4191 */ {__glXDisp_VertexAttrib3sv, __glXDispSwap_VertexAttrib3sv}, /* [ 312] = 4192 */ {__glXDisp_VertexAttrib4sv, __glXDispSwap_VertexAttrib4sv}, /* [ 313] = 4193 */ {__glXDisp_VertexAttrib1fvARB, __glXDispSwap_VertexAttrib1fvARB}, /* [ 314] = 4194 */ {__glXDisp_VertexAttrib2fvARB, __glXDispSwap_VertexAttrib2fvARB}, /* [ 315] = 4195 */ {__glXDisp_VertexAttrib3fvARB, __glXDispSwap_VertexAttrib3fvARB}, /* [ 316] = 4196 */ {__glXDisp_VertexAttrib4fvARB, __glXDispSwap_VertexAttrib4fvARB}, /* [ 317] = 4197 */ {__glXDisp_VertexAttrib1dv, __glXDispSwap_VertexAttrib1dv}, /* [ 318] = 4198 */ {__glXDisp_VertexAttrib2dv, __glXDispSwap_VertexAttrib2dv}, /* [ 319] = 4199 */ {__glXDisp_VertexAttrib3dv, __glXDispSwap_VertexAttrib3dv}, /* [ 320] = 4200 */ {__glXDisp_VertexAttrib4dv, __glXDispSwap_VertexAttrib4dv}, /* [ 321] = 4201 */ {__glXDisp_VertexAttrib4Nubv, __glXDispSwap_VertexAttrib4Nubv}, /* [ 322] = 4202 */ {__glXDisp_VertexAttribs1svNV, __glXDispSwap_VertexAttribs1svNV}, /* [ 323] = 4203 */ {__glXDisp_VertexAttribs2svNV, __glXDispSwap_VertexAttribs2svNV}, /* [ 324] = 4204 */ {__glXDisp_VertexAttribs3svNV, __glXDispSwap_VertexAttribs3svNV}, /* [ 325] = 4205 */ {__glXDisp_VertexAttribs4svNV, __glXDispSwap_VertexAttribs4svNV}, /* [ 326] = 4206 */ {__glXDisp_VertexAttribs1fvNV, __glXDispSwap_VertexAttribs1fvNV}, /* [ 327] = 4207 */ {__glXDisp_VertexAttribs2fvNV, __glXDispSwap_VertexAttribs2fvNV}, /* [ 328] = 4208 */ {__glXDisp_VertexAttribs3fvNV, __glXDispSwap_VertexAttribs3fvNV}, /* [ 329] = 4209 */ {__glXDisp_VertexAttribs4fvNV, __glXDispSwap_VertexAttribs4fvNV}, /* [ 330] = 4210 */ {__glXDisp_VertexAttribs1dvNV, __glXDispSwap_VertexAttribs1dvNV}, /* [ 331] = 4211 */ {__glXDisp_VertexAttribs2dvNV, __glXDispSwap_VertexAttribs2dvNV}, /* [ 332] = 4212 */ {__glXDisp_VertexAttribs3dvNV, __glXDispSwap_VertexAttribs3dvNV}, /* [ 333] = 4213 */ {__glXDisp_VertexAttribs4dvNV, __glXDispSwap_VertexAttribs4dvNV}, /* [ 334] = 4214 */ {__glXDisp_VertexAttribs4ubvNV, __glXDispSwap_VertexAttribs4ubvNV}, /* [ 335] = 4215 */ {__glXDisp_ProgramLocalParameter4fvARB, __glXDispSwap_ProgramLocalParameter4fvARB}, /* [ 336] = 4216 */ {__glXDisp_ProgramLocalParameter4dvARB, __glXDispSwap_ProgramLocalParameter4dvARB}, /* [ 337] = 4217 */ {__glXDisp_ProgramStringARB, __glXDispSwap_ProgramStringARB}, /* [ 338] = 4218 */ {NULL, NULL}, /* [ 339] = 4219 */ {NULL, NULL}, /* [ 340] = 4220 */ {__glXDisp_ActiveStencilFaceEXT, __glXDispSwap_ActiveStencilFaceEXT}, /* [ 341] = 4221 */ {__glXDisp_PointParameteri, __glXDispSwap_PointParameteri}, /* [ 342] = 4222 */ {__glXDisp_PointParameteriv, __glXDispSwap_PointParameteriv}, /* [ 343] = 4223 */ {NULL, NULL}, /* [ 344] = 4224 */ {NULL, NULL}, /* [ 345] = 4225 */ {NULL, NULL}, /* [ 346] = 4226 */ {NULL, NULL}, /* [ 347] = 4227 */ {NULL, NULL}, /* [ 348] = 4228 */ {__glXDisp_BlendEquationSeparate, __glXDispSwap_BlendEquationSeparate}, /* [ 349] = 4229 */ {NULL, NULL}, /* [ 350] = 4230 */ {__glXDisp_VertexAttrib4bv, __glXDispSwap_VertexAttrib4bv}, /* [ 351] = 4231 */ {__glXDisp_VertexAttrib4iv, __glXDispSwap_VertexAttrib4iv}, /* [ 352] = 4232 */ {__glXDisp_VertexAttrib4ubv, __glXDispSwap_VertexAttrib4ubv}, /* [ 353] = 4233 */ {__glXDisp_VertexAttrib4usv, __glXDispSwap_VertexAttrib4usv}, /* [ 354] = 4234 */ {__glXDisp_VertexAttrib4uiv, __glXDispSwap_VertexAttrib4uiv}, /* [ 355] = 4235 */ {__glXDisp_VertexAttrib4Nbv, __glXDispSwap_VertexAttrib4Nbv}, /* [ 356] = 4236 */ {__glXDisp_VertexAttrib4Nsv, __glXDispSwap_VertexAttrib4Nsv}, /* [ 357] = 4237 */ {__glXDisp_VertexAttrib4Niv, __glXDispSwap_VertexAttrib4Niv}, /* [ 358] = 4238 */ {__glXDisp_VertexAttrib4Nusv, __glXDispSwap_VertexAttrib4Nusv}, /* [ 359] = 4239 */ {__glXDisp_VertexAttrib4Nuiv, __glXDispSwap_VertexAttrib4Nuiv}, /* [ 360] = 4320 */ {__glXDisp_DeleteFramebuffers, __glXDispSwap_DeleteFramebuffers}, /* [ 361] = 4321 */ {__glXDisp_FramebufferTexture1D, __glXDispSwap_FramebufferTexture1D}, /* [ 362] = 4322 */ {__glXDisp_FramebufferTexture2D, __glXDispSwap_FramebufferTexture2D}, /* [ 363] = 4323 */ {__glXDisp_FramebufferTexture3D, __glXDispSwap_FramebufferTexture3D}, /* [ 364] = 4324 */ {__glXDisp_FramebufferRenderbuffer, __glXDispSwap_FramebufferRenderbuffer}, /* [ 365] = 4325 */ {__glXDisp_GenerateMipmap, __glXDispSwap_GenerateMipmap}, /* [ 366] = 4326 */ {NULL, NULL}, /* [ 367] = 4327 */ {NULL, NULL}, /* [ 368] = 4328 */ {NULL, NULL}, /* [ 369] = 4329 */ {NULL, NULL}, /* [ 370] = 4330 */ {__glXDisp_BlitFramebuffer, __glXDispSwap_BlitFramebuffer}, /* [ 371] = 4331 */ {__glXDisp_RenderbufferStorageMultisample, __glXDispSwap_RenderbufferStorageMultisample}, /* [ 372] = 4332 */ {NULL, NULL}, /* [ 373] = 4333 */ {NULL, NULL}, /* [ 374] = 4334 */ {NULL, NULL}, /* [ 375] = 4335 */ {NULL, NULL}, /* [ 376] = 4128 */ {__glXDisp_SecondaryColor3iv, __glXDispSwap_SecondaryColor3iv}, /* [ 377] = 4129 */ {__glXDisp_SecondaryColor3fvEXT, __glXDispSwap_SecondaryColor3fvEXT}, /* [ 378] = 4130 */ {__glXDisp_SecondaryColor3dv, __glXDispSwap_SecondaryColor3dv}, /* [ 379] = 4131 */ {__glXDisp_SecondaryColor3ubv, __glXDispSwap_SecondaryColor3ubv}, /* [ 380] = 4132 */ {__glXDisp_SecondaryColor3usv, __glXDispSwap_SecondaryColor3usv}, /* [ 381] = 4133 */ {__glXDisp_SecondaryColor3uiv, __glXDispSwap_SecondaryColor3uiv}, /* [ 382] = 4134 */ {__glXDisp_BlendFuncSeparate, __glXDispSwap_BlendFuncSeparate}, /* [ 383] = 4135 */ {NULL, NULL}, /* [ 384] = 4264 */ {NULL, NULL}, /* [ 385] = 4265 */ {__glXDisp_VertexAttrib1svNV, __glXDispSwap_VertexAttrib1svNV}, /* [ 386] = 4266 */ {__glXDisp_VertexAttrib2svNV, __glXDispSwap_VertexAttrib2svNV}, /* [ 387] = 4267 */ {__glXDisp_VertexAttrib3svNV, __glXDispSwap_VertexAttrib3svNV}, /* [ 388] = 4268 */ {__glXDisp_VertexAttrib4svNV, __glXDispSwap_VertexAttrib4svNV}, /* [ 389] = 4269 */ {__glXDisp_VertexAttrib1fvNV, __glXDispSwap_VertexAttrib1fvNV}, /* [ 390] = 4270 */ {__glXDisp_VertexAttrib2fvNV, __glXDispSwap_VertexAttrib2fvNV}, /* [ 391] = 4271 */ {__glXDisp_VertexAttrib3fvNV, __glXDispSwap_VertexAttrib3fvNV}, /* [ 392] = 4272 */ {__glXDisp_VertexAttrib4fvNV, __glXDispSwap_VertexAttrib4fvNV}, /* [ 393] = 4273 */ {__glXDisp_VertexAttrib1dvNV, __glXDispSwap_VertexAttrib1dvNV}, /* [ 394] = 4274 */ {__glXDisp_VertexAttrib2dvNV, __glXDispSwap_VertexAttrib2dvNV}, /* [ 395] = 4275 */ {__glXDisp_VertexAttrib3dvNV, __glXDispSwap_VertexAttrib3dvNV}, /* [ 396] = 4276 */ {__glXDisp_VertexAttrib4dvNV, __glXDispSwap_VertexAttrib4dvNV}, /* [ 397] = 4277 */ {__glXDisp_VertexAttrib4ubvNV, __glXDispSwap_VertexAttrib4ubvNV}, /* [ 398] = 4278 */ {NULL, NULL}, /* [ 399] = 4279 */ {NULL, NULL}, /* [ 400] = 4312 */ {NULL, NULL}, /* [ 401] = 4313 */ {NULL, NULL}, /* [ 402] = 4314 */ {NULL, NULL}, /* [ 403] = 4315 */ {NULL, NULL}, /* [ 404] = 4316 */ {__glXDisp_BindRenderbuffer, __glXDispSwap_BindRenderbuffer}, /* [ 405] = 4317 */ {__glXDisp_DeleteRenderbuffers, __glXDispSwap_DeleteRenderbuffers}, /* [ 406] = 4318 */ {__glXDisp_RenderbufferStorage, __glXDispSwap_RenderbufferStorage}, /* [ 407] = 4319 */ {__glXDisp_BindFramebuffer, __glXDispSwap_BindFramebuffer}, }; static const int_fast16_t Render_size_table[408][2] = { /* [ 0] = 0 */ {0, ~0}, /* [ 1] = 1 */ {8, ~0}, /* [ 2] = 2 */ {12, 0}, /* [ 3] = 3 */ {8, ~0}, /* [ 4] = 4 */ {8, ~0}, /* [ 5] = 5 */ {48, 1}, /* [ 6] = 6 */ {8, ~0}, /* [ 7] = 7 */ {28, ~0}, /* [ 8] = 8 */ {16, ~0}, /* [ 9] = 9 */ {16, ~0}, /* [ 10] = 10 */ {12, ~0}, /* [ 11] = 11 */ {8, ~0}, /* [ 12] = 12 */ {16, ~0}, /* [ 13] = 13 */ {12, ~0}, /* [ 14] = 14 */ {8, ~0}, /* [ 15] = 15 */ {36, ~0}, /* [ 16] = 16 */ {20, ~0}, /* [ 17] = 17 */ {20, ~0}, /* [ 18] = 18 */ {12, ~0}, /* [ 19] = 19 */ {8, ~0}, /* [ 20] = 20 */ {20, ~0}, /* [ 21] = 21 */ {12, ~0}, /* [ 22] = 22 */ {8, ~0}, /* [ 23] = 23 */ {4, ~0}, /* [ 24] = 24 */ {12, ~0}, /* [ 25] = 25 */ {8, ~0}, /* [ 26] = 26 */ {8, ~0}, /* [ 27] = 27 */ {8, ~0}, /* [ 28] = 28 */ {8, ~0}, /* [ 29] = 29 */ {28, ~0}, /* [ 30] = 30 */ {16, ~0}, /* [ 31] = 31 */ {16, ~0}, /* [ 32] = 32 */ {12, ~0}, /* [ 33] = 33 */ {20, ~0}, /* [ 34] = 34 */ {12, ~0}, /* [ 35] = 35 */ {12, ~0}, /* [ 36] = 36 */ {8, ~0}, /* [ 37] = 37 */ {28, ~0}, /* [ 38] = 38 */ {16, ~0}, /* [ 39] = 39 */ {16, ~0}, /* [ 40] = 40 */ {12, ~0}, /* [ 41] = 41 */ {36, ~0}, /* [ 42] = 42 */ {20, ~0}, /* [ 43] = 43 */ {20, ~0}, /* [ 44] = 44 */ {12, ~0}, /* [ 45] = 45 */ {36, ~0}, /* [ 46] = 46 */ {20, ~0}, /* [ 47] = 47 */ {20, ~0}, /* [ 48] = 48 */ {12, ~0}, /* [ 49] = 49 */ {12, ~0}, /* [ 50] = 50 */ {8, ~0}, /* [ 51] = 51 */ {8, ~0}, /* [ 52] = 52 */ {8, ~0}, /* [ 53] = 53 */ {20, ~0}, /* [ 54] = 54 */ {12, ~0}, /* [ 55] = 55 */ {12, ~0}, /* [ 56] = 56 */ {8, ~0}, /* [ 57] = 57 */ {28, ~0}, /* [ 58] = 58 */ {16, ~0}, /* [ 59] = 59 */ {16, ~0}, /* [ 60] = 60 */ {12, ~0}, /* [ 61] = 61 */ {36, ~0}, /* [ 62] = 62 */ {20, ~0}, /* [ 63] = 63 */ {20, ~0}, /* [ 64] = 64 */ {12, ~0}, /* [ 65] = 65 */ {20, ~0}, /* [ 66] = 66 */ {12, ~0}, /* [ 67] = 67 */ {12, ~0}, /* [ 68] = 68 */ {8, ~0}, /* [ 69] = 69 */ {28, ~0}, /* [ 70] = 70 */ {16, ~0}, /* [ 71] = 71 */ {16, ~0}, /* [ 72] = 72 */ {12, ~0}, /* [ 73] = 73 */ {36, ~0}, /* [ 74] = 74 */ {20, ~0}, /* [ 75] = 75 */ {20, ~0}, /* [ 76] = 76 */ {12, ~0}, /* [ 77] = 77 */ {40, ~0}, /* [ 78] = 78 */ {12, ~0}, /* [ 79] = 79 */ {8, ~0}, /* [ 80] = 80 */ {12, ~0}, /* [ 81] = 81 */ {8, 2}, /* [ 82] = 82 */ {12, ~0}, /* [ 83] = 83 */ {8, 3}, /* [ 84] = 84 */ {8, ~0}, /* [ 85] = 85 */ {12, ~0}, /* [ 86] = 86 */ {16, ~0}, /* [ 87] = 87 */ {12, 4}, /* [ 88] = 88 */ {16, ~0}, /* [ 89] = 89 */ {12, 5}, /* [ 90] = 90 */ {12, ~0}, /* [ 91] = 91 */ {8, 6}, /* [ 92] = 92 */ {12, ~0}, /* [ 93] = 93 */ {8, 7}, /* [ 94] = 94 */ {12, ~0}, /* [ 95] = 95 */ {8, ~0}, /* [ 96] = 96 */ {16, ~0}, /* [ 97] = 97 */ {12, 8}, /* [ 98] = 98 */ {16, ~0}, /* [ 99] = 99 */ {12, 9}, /* [100] = 100 */ {8, ~0}, /* [101] = 101 */ {12, ~0}, /* [102] = 102 */ {24, 10}, /* [103] = 103 */ {20, ~0}, /* [104] = 104 */ {8, ~0}, /* [105] = 105 */ {16, ~0}, /* [106] = 106 */ {12, 11}, /* [107] = 107 */ {16, ~0}, /* [108] = 108 */ {12, 12}, /* [109] = 109 */ {56, 13}, /* [110] = 110 */ {56, 14}, /* [111] = 111 */ {16, ~0}, /* [112] = 112 */ {12, 15}, /* [113] = 113 */ {16, ~0}, /* [114] = 114 */ {12, 16}, /* [115] = 115 */ {20, ~0}, /* [116] = 116 */ {12, 17}, /* [117] = 117 */ {16, ~0}, /* [118] = 118 */ {12, 18}, /* [119] = 119 */ {16, ~0}, /* [120] = 120 */ {12, 19}, /* [121] = 121 */ {4, ~0}, /* [122] = 122 */ {8, ~0}, /* [123] = 123 */ {8, ~0}, /* [124] = 124 */ {4, ~0}, /* [125] = 125 */ {8, ~0}, /* [126] = 126 */ {8, ~0}, /* [127] = 127 */ {8, ~0}, /* [128] = 128 */ {20, ~0}, /* [129] = 129 */ {8, ~0}, /* [130] = 130 */ {20, ~0}, /* [131] = 131 */ {8, ~0}, /* [132] = 132 */ {12, ~0}, /* [133] = 133 */ {8, ~0}, /* [134] = 134 */ {8, ~0}, /* [135] = 135 */ {8, ~0}, /* [136] = 136 */ {8, ~0}, /* [137] = 137 */ {12, ~0}, /* [138] = 138 */ {8, ~0}, /* [139] = 139 */ {8, ~0}, /* [140] = 140 */ {0, ~0}, /* [141] = 141 */ {4, ~0}, /* [142] = 142 */ {8, ~0}, /* [143] = 143 */ {28, 20}, /* [144] = 144 */ {20, 21}, /* [145] = 145 */ {48, 22}, /* [146] = 146 */ {32, 23}, /* [147] = 147 */ {24, ~0}, /* [148] = 148 */ {16, ~0}, /* [149] = 149 */ {44, ~0}, /* [150] = 150 */ {28, ~0}, /* [151] = 151 */ {12, ~0}, /* [152] = 152 */ {8, ~0}, /* [153] = 153 */ {20, ~0}, /* [154] = 154 */ {12, ~0}, /* [155] = 155 */ {16, ~0}, /* [156] = 156 */ {8, ~0}, /* [157] = 157 */ {24, ~0}, /* [158] = 158 */ {12, ~0}, /* [159] = 159 */ {12, ~0}, /* [160] = 160 */ {12, ~0}, /* [161] = 161 */ {8, ~0}, /* [162] = 162 */ {16, ~0}, /* [163] = 163 */ {16, ~0}, /* [164] = 164 */ {8, ~0}, /* [165] = 165 */ {12, ~0}, /* [166] = 166 */ {12, ~0}, /* [167] = 167 */ {12, ~0}, /* [168] = 168 */ {12, 24}, /* [169] = 169 */ {12, 25}, /* [170] = 170 */ {12, 26}, /* [171] = 171 */ {8, ~0}, /* [172] = 172 */ {24, ~0}, /* [173] = 173 */ {40, 27}, /* [174] = 174 */ {20, ~0}, /* [175] = 175 */ {52, ~0}, /* [176] = 176 */ {4, ~0}, /* [177] = 177 */ {68, ~0}, /* [178] = 178 */ {132, ~0}, /* [179] = 179 */ {8, ~0}, /* [180] = 180 */ {68, ~0}, /* [181] = 181 */ {132, ~0}, /* [182] = 182 */ {52, ~0}, /* [183] = 183 */ {4, ~0}, /* [184] = 184 */ {4, ~0}, /* [185] = 185 */ {36, ~0}, /* [186] = 186 */ {20, ~0}, /* [187] = 187 */ {28, ~0}, /* [188] = 188 */ {16, ~0}, /* [189] = 189 */ {28, ~0}, /* [190] = 190 */ {16, ~0}, /* [191] = 191 */ {20, ~0}, /* [192] = 192 */ {12, ~0}, /* [193] = 193 */ {16, 28}, /* [194] = 194 */ {8, ~0}, /* [195] = 195 */ {44, 29}, /* [196] = 196 */ {24, ~0}, /* [197] = 197 */ {8, ~0}, /* [198] = 198 */ {16, ~0}, /* [199] = 199 */ {12, ~0}, /* [200] = 200 */ {12, ~0}, /* [201] = 201 */ {12, ~0}, /* [202] = 202 */ {24, ~0}, /* [203] = 203 */ {16, ~0}, /* [204] = 204 */ {16, ~0}, /* [205] = 205 */ {12, ~0}, /* [206] = 206 */ {32, ~0}, /* [207] = 207 */ {20, ~0}, /* [208] = 208 */ {20, ~0}, /* [209] = 209 */ {16, ~0}, /* [210] = 210 */ {40, ~0}, /* [211] = 211 */ {24, ~0}, /* [212] = 212 */ {24, ~0}, /* [213] = 213 */ {16, ~0}, /* [214] = 214 */ {28, 30}, /* [215] = 215 */ {32, 31}, /* [216] = 216 */ {36, 32}, /* [217] = 217 */ {28, 33}, /* [218] = 218 */ {36, 34}, /* [219] = 219 */ {44, 35}, /* [220] = 220 */ {0, ~0}, /* [221] = 221 */ {0, ~0}, /* [222] = 222 */ {0, ~0}, /* [223] = 223 */ {0, ~0}, /* [224] = 224 */ {0, ~0}, /* [225] = 225 */ {0, ~0}, /* [226] = 226 */ {0, ~0}, /* [227] = 227 */ {0, ~0}, /* [228] = 228 */ {0, ~0}, /* [229] = 229 */ {12, ~0}, /* [230] = 230 */ {16, ~0}, /* [231] = 231 */ {12, ~0}, /* [232] = 232 */ {8, ~0}, /* [233] = 233 */ {8, 36}, /* [234] = 234 */ {12, ~0}, /* [235] = 235 */ {0, ~0}, /* [236] = 236 */ {0, ~0}, /* [237] = 237 */ {24, ~0}, /* [238] = 238 */ {0, ~0}, /* [239] = 239 */ {0, ~0}, /* [240] = 2048 */ {0, ~0}, /* [241] = 2049 */ {0, ~0}, /* [242] = 2050 */ {0, ~0}, /* [243] = 2051 */ {0, ~0}, /* [244] = 2052 */ {0, ~0}, /* [245] = 2053 */ {44, 37}, /* [246] = 2054 */ {12, 38}, /* [247] = 2055 */ {12, 39}, /* [248] = 2056 */ {24, ~0}, /* [249] = 2057 */ {0, ~0}, /* [250] = 2058 */ {0, ~0}, /* [251] = 2059 */ {0, ~0}, /* [252] = 2060 */ {0, ~0}, /* [253] = 2061 */ {0, ~0}, /* [254] = 2062 */ {0, ~0}, /* [255] = 2063 */ {0, ~0}, /* [256] = 2064 */ {0, ~0}, /* [257] = 2065 */ {12, ~0}, /* [258] = 2066 */ {8, 40}, /* [259] = 2067 */ {0, ~0}, /* [260] = 2068 */ {0, ~0}, /* [261] = 2069 */ {0, ~0}, /* [262] = 2070 */ {0, ~0}, /* [263] = 2071 */ {0, ~0}, /* [264] = 4096 */ {20, ~0}, /* [265] = 4097 */ {8, ~0}, /* [266] = 4098 */ {0, ~0}, /* [267] = 4099 */ {60, 41}, /* [268] = 4100 */ {60, 42}, /* [269] = 4101 */ {48, 43}, /* [270] = 4102 */ {48, 44}, /* [271] = 4103 */ {16, ~0}, /* [272] = 4104 */ {12, 45}, /* [273] = 4105 */ {16, ~0}, /* [274] = 4106 */ {12, 46}, /* [275] = 4107 */ {24, ~0}, /* [276] = 4108 */ {28, ~0}, /* [277] = 4109 */ {32, 47}, /* [278] = 4110 */ {20, ~0}, /* [279] = 4111 */ {16, ~0}, /* [280] = 4112 */ {8, ~0}, /* [281] = 4113 */ {8, ~0}, /* [282] = 4114 */ {84, 48}, /* [283] = 4115 */ {92, 49}, /* [284] = 4116 */ {0, ~0}, /* [285] = 4117 */ {12, ~0}, /* [286] = 4118 */ {8, 50}, /* [287] = 4119 */ {32, ~0}, /* [288] = 4120 */ {36, ~0}, /* [289] = 4121 */ {28, ~0}, /* [290] = 4122 */ {36, ~0}, /* [291] = 4123 */ {40, ~0}, /* [292] = 4124 */ {8, ~0}, /* [293] = 4125 */ {12, ~0}, /* [294] = 4126 */ {8, ~0}, /* [295] = 4127 */ {12, ~0}, /* [296] = 4176 */ {0, ~0}, /* [297] = 4177 */ {0, ~0}, /* [298] = 4178 */ {0, ~0}, /* [299] = 4179 */ {0, ~0}, /* [300] = 4180 */ {12, ~0}, /* [301] = 4181 */ {0, ~0}, /* [302] = 4182 */ {0, ~0}, /* [303] = 4183 */ {0, ~0}, /* [304] = 4184 */ {28, ~0}, /* [305] = 4185 */ {44, ~0}, /* [306] = 4186 */ {0, ~0}, /* [307] = 4187 */ {0, ~0}, /* [308] = 4188 */ {0, ~0}, /* [309] = 4189 */ {12, ~0}, /* [310] = 4190 */ {12, ~0}, /* [311] = 4191 */ {16, ~0}, /* [312] = 4192 */ {16, ~0}, /* [313] = 4193 */ {12, ~0}, /* [314] = 4194 */ {16, ~0}, /* [315] = 4195 */ {20, ~0}, /* [316] = 4196 */ {24, ~0}, /* [317] = 4197 */ {16, ~0}, /* [318] = 4198 */ {24, ~0}, /* [319] = 4199 */ {32, ~0}, /* [320] = 4200 */ {40, ~0}, /* [321] = 4201 */ {12, ~0}, /* [322] = 4202 */ {12, 51}, /* [323] = 4203 */ {12, 52}, /* [324] = 4204 */ {12, 53}, /* [325] = 4205 */ {12, 54}, /* [326] = 4206 */ {12, 55}, /* [327] = 4207 */ {12, 56}, /* [328] = 4208 */ {12, 57}, /* [329] = 4209 */ {12, 58}, /* [330] = 4210 */ {12, 59}, /* [331] = 4211 */ {12, 60}, /* [332] = 4212 */ {12, 61}, /* [333] = 4213 */ {12, 62}, /* [334] = 4214 */ {12, 63}, /* [335] = 4215 */ {28, ~0}, /* [336] = 4216 */ {44, ~0}, /* [337] = 4217 */ {16, 64}, /* [338] = 4218 */ {0, ~0}, /* [339] = 4219 */ {0, ~0}, /* [340] = 4220 */ {8, ~0}, /* [341] = 4221 */ {12, ~0}, /* [342] = 4222 */ {8, 65}, /* [343] = 4223 */ {0, ~0}, /* [344] = 4224 */ {0, ~0}, /* [345] = 4225 */ {0, ~0}, /* [346] = 4226 */ {0, ~0}, /* [347] = 4227 */ {0, ~0}, /* [348] = 4228 */ {12, ~0}, /* [349] = 4229 */ {0, ~0}, /* [350] = 4230 */ {12, ~0}, /* [351] = 4231 */ {24, ~0}, /* [352] = 4232 */ {12, ~0}, /* [353] = 4233 */ {16, ~0}, /* [354] = 4234 */ {24, ~0}, /* [355] = 4235 */ {12, ~0}, /* [356] = 4236 */ {16, ~0}, /* [357] = 4237 */ {24, ~0}, /* [358] = 4238 */ {16, ~0}, /* [359] = 4239 */ {24, ~0}, /* [360] = 4320 */ {8, 66}, /* [361] = 4321 */ {24, ~0}, /* [362] = 4322 */ {24, ~0}, /* [363] = 4323 */ {28, ~0}, /* [364] = 4324 */ {20, ~0}, /* [365] = 4325 */ {8, ~0}, /* [366] = 4326 */ {0, ~0}, /* [367] = 4327 */ {0, ~0}, /* [368] = 4328 */ {0, ~0}, /* [369] = 4329 */ {0, ~0}, /* [370] = 4330 */ {44, ~0}, /* [371] = 4331 */ {24, ~0}, /* [372] = 4332 */ {0, ~0}, /* [373] = 4333 */ {0, ~0}, /* [374] = 4334 */ {0, ~0}, /* [375] = 4335 */ {0, ~0}, /* [376] = 4128 */ {16, ~0}, /* [377] = 4129 */ {16, ~0}, /* [378] = 4130 */ {28, ~0}, /* [379] = 4131 */ {8, ~0}, /* [380] = 4132 */ {12, ~0}, /* [381] = 4133 */ {16, ~0}, /* [382] = 4134 */ {20, ~0}, /* [383] = 4135 */ {0, ~0}, /* [384] = 4264 */ {0, ~0}, /* [385] = 4265 */ {12, ~0}, /* [386] = 4266 */ {12, ~0}, /* [387] = 4267 */ {16, ~0}, /* [388] = 4268 */ {16, ~0}, /* [389] = 4269 */ {12, ~0}, /* [390] = 4270 */ {16, ~0}, /* [391] = 4271 */ {20, ~0}, /* [392] = 4272 */ {24, ~0}, /* [393] = 4273 */ {16, ~0}, /* [394] = 4274 */ {24, ~0}, /* [395] = 4275 */ {32, ~0}, /* [396] = 4276 */ {40, ~0}, /* [397] = 4277 */ {12, ~0}, /* [398] = 4278 */ {0, ~0}, /* [399] = 4279 */ {0, ~0}, /* [400] = 4312 */ {0, ~0}, /* [401] = 4313 */ {0, ~0}, /* [402] = 4314 */ {0, ~0}, /* [403] = 4315 */ {0, ~0}, /* [404] = 4316 */ {12, ~0}, /* [405] = 4317 */ {8, 67}, /* [406] = 4318 */ {20, ~0}, /* [407] = 4319 */ {12, ~0}, }; static const gl_proto_size_func Render_size_func_table[68] = { __glXCallListsReqSize, __glXBitmapReqSize, __glXFogfvReqSize, __glXFogivReqSize, __glXLightfvReqSize, __glXLightivReqSize, __glXLightModelfvReqSize, __glXLightModelivReqSize, __glXMaterialfvReqSize, __glXMaterialivReqSize, __glXPolygonStippleReqSize, __glXTexParameterfvReqSize, __glXTexParameterivReqSize, __glXTexImage1DReqSize, __glXTexImage2DReqSize, __glXTexEnvfvReqSize, __glXTexEnvivReqSize, __glXTexGendvReqSize, __glXTexGenfvReqSize, __glXTexGenivReqSize, __glXMap1dReqSize, __glXMap1fReqSize, __glXMap2dReqSize, __glXMap2fReqSize, __glXPixelMapfvReqSize, __glXPixelMapuivReqSize, __glXPixelMapusvReqSize, __glXDrawPixelsReqSize, __glXDrawArraysReqSize, __glXColorSubTableReqSize, __glXCompressedTexImage1DReqSize, __glXCompressedTexImage2DReqSize, __glXCompressedTexImage3DReqSize, __glXCompressedTexSubImage1DReqSize, __glXCompressedTexSubImage2DReqSize, __glXCompressedTexSubImage3DReqSize, __glXDrawBuffersReqSize, __glXColorTableReqSize, __glXColorTableParameterfvReqSize, __glXColorTableParameterivReqSize, __glXPointParameterfvReqSize, __glXTexSubImage1DReqSize, __glXTexSubImage2DReqSize, __glXConvolutionFilter1DReqSize, __glXConvolutionFilter2DReqSize, __glXConvolutionParameterfvReqSize, __glXConvolutionParameterivReqSize, __glXSeparableFilter2DReqSize, __glXTexImage3DReqSize, __glXTexSubImage3DReqSize, __glXPrioritizeTexturesReqSize, __glXVertexAttribs1svNVReqSize, __glXVertexAttribs2svNVReqSize, __glXVertexAttribs3svNVReqSize, __glXVertexAttribs4svNVReqSize, __glXVertexAttribs1fvNVReqSize, __glXVertexAttribs2fvNVReqSize, __glXVertexAttribs3fvNVReqSize, __glXVertexAttribs4fvNVReqSize, __glXVertexAttribs1dvNVReqSize, __glXVertexAttribs2dvNVReqSize, __glXVertexAttribs3dvNVReqSize, __glXVertexAttribs4dvNVReqSize, __glXVertexAttribs4ubvNVReqSize, __glXProgramStringARBReqSize, __glXPointParameterivReqSize, __glXDeleteFramebuffersReqSize, __glXDeleteRenderbuffersReqSize, }; const struct __glXDispatchInfo Render_dispatch_info = { 13, Render_dispatch_tree, Render_function_table, Render_size_table, Render_size_func_table }; /*****************************************************************/ /* tree depth = 12 */ static const int_fast16_t VendorPriv_dispatch_tree[152] = { /* [0] -> opcode range [0, 131072], node depth 1 */ 2, 5, EMPTY_LEAF, 119, EMPTY_LEAF, /* [5] -> opcode range [0, 32768], node depth 2 */ 1, 8, EMPTY_LEAF, /* [8] -> opcode range [0, 16384], node depth 3 */ 1, 11, EMPTY_LEAF, /* [11] -> opcode range [0, 8192], node depth 4 */ 2, 16, EMPTY_LEAF, 78, EMPTY_LEAF, /* [16] -> opcode range [0, 2048], node depth 5 */ 2, 21, EMPTY_LEAF, 36, EMPTY_LEAF, /* [21] -> opcode range [0, 512], node depth 6 */ 1, 24, EMPTY_LEAF, /* [24] -> opcode range [0, 256], node depth 7 */ 1, 27, EMPTY_LEAF, /* [27] -> opcode range [0, 128], node depth 8 */ 1, 30, EMPTY_LEAF, /* [30] -> opcode range [0, 64], node depth 9 */ 1, 33, EMPTY_LEAF, /* [33] -> opcode range [0, 32], node depth 10 */ 1, LEAF(0), EMPTY_LEAF, /* [36] -> opcode range [1024, 1536], node depth 6 */ 2, 41, EMPTY_LEAF, 53, 67, /* [41] -> opcode range [1024, 1152], node depth 7 */ 1, 44, EMPTY_LEAF, /* [44] -> opcode range [1024, 1088], node depth 8 */ 1, 47, EMPTY_LEAF, /* [47] -> opcode range [1024, 1056], node depth 9 */ 1, 50, EMPTY_LEAF, /* [50] -> opcode range [1024, 1040], node depth 10 */ 1, LEAF(16), EMPTY_LEAF, /* [53] -> opcode range [1280, 1408], node depth 7 */ 1, 56, EMPTY_LEAF, /* [56] -> opcode range [1280, 1344], node depth 8 */ 2, 61, LEAF(24), EMPTY_LEAF, 64, /* [61] -> opcode range [1280, 1296], node depth 9 */ 1, EMPTY_LEAF, LEAF(40), /* [64] -> opcode range [1328, 1344], node depth 9 */ 1, LEAF(48), EMPTY_LEAF, /* [67] -> opcode range [1408, 1536], node depth 7 */ 1, 70, EMPTY_LEAF, /* [70] -> opcode range [1408, 1472], node depth 8 */ 1, 73, EMPTY_LEAF, /* [73] -> opcode range [1408, 1440], node depth 9 */ 2, EMPTY_LEAF, LEAF(56), LEAF(64), EMPTY_LEAF, /* [78] -> opcode range [4096, 6144], node depth 5 */ 2, 83, EMPTY_LEAF, 101, EMPTY_LEAF, /* [83] -> opcode range [4096, 4608], node depth 6 */ 1, 86, EMPTY_LEAF, /* [86] -> opcode range [4096, 4352], node depth 7 */ 1, 89, EMPTY_LEAF, /* [89] -> opcode range [4096, 4224], node depth 8 */ 1, 92, EMPTY_LEAF, /* [92] -> opcode range [4096, 4160], node depth 9 */ 1, 95, EMPTY_LEAF, /* [95] -> opcode range [4096, 4128], node depth 10 */ 1, 98, EMPTY_LEAF, /* [98] -> opcode range [4096, 4112], node depth 11 */ 1, LEAF(72), EMPTY_LEAF, /* [101] -> opcode range [5120, 5632], node depth 6 */ 1, 104, EMPTY_LEAF, /* [104] -> opcode range [5120, 5376], node depth 7 */ 1, 107, EMPTY_LEAF, /* [107] -> opcode range [5120, 5248], node depth 8 */ 1, 110, EMPTY_LEAF, /* [110] -> opcode range [5120, 5184], node depth 9 */ 1, EMPTY_LEAF, 113, /* [113] -> opcode range [5152, 5184], node depth 10 */ 1, 116, EMPTY_LEAF, /* [116] -> opcode range [5152, 5168], node depth 11 */ 1, LEAF(80), EMPTY_LEAF, /* [119] -> opcode range [65536, 98304], node depth 2 */ 1, 122, EMPTY_LEAF, /* [122] -> opcode range [65536, 81920], node depth 3 */ 1, 125, EMPTY_LEAF, /* [125] -> opcode range [65536, 73728], node depth 4 */ 1, 128, EMPTY_LEAF, /* [128] -> opcode range [65536, 69632], node depth 5 */ 1, 131, EMPTY_LEAF, /* [131] -> opcode range [65536, 67584], node depth 6 */ 1, 134, EMPTY_LEAF, /* [134] -> opcode range [65536, 66560], node depth 7 */ 1, 137, EMPTY_LEAF, /* [137] -> opcode range [65536, 66048], node depth 8 */ 1, 140, EMPTY_LEAF, /* [140] -> opcode range [65536, 65792], node depth 9 */ 1, 143, EMPTY_LEAF, /* [143] -> opcode range [65536, 65664], node depth 10 */ 1, 146, EMPTY_LEAF, /* [146] -> opcode range [65536, 65600], node depth 11 */ 1, 149, EMPTY_LEAF, /* [149] -> opcode range [65536, 65568], node depth 12 */ 1, LEAF(88), EMPTY_LEAF, }; static const void *VendorPriv_function_table[104][2] = { /* [ 0] = 0 */ {NULL, NULL}, /* [ 1] = 1 */ {__glXDisp_GetConvolutionFilterEXT, __glXDispSwap_GetConvolutionFilterEXT}, /* [ 2] = 2 */ {__glXDisp_GetConvolutionParameterfvEXT, __glXDispSwap_GetConvolutionParameterfvEXT}, /* [ 3] = 3 */ {__glXDisp_GetConvolutionParameterivEXT, __glXDispSwap_GetConvolutionParameterivEXT}, /* [ 4] = 4 */ {__glXDisp_GetSeparableFilterEXT, __glXDispSwap_GetSeparableFilterEXT}, /* [ 5] = 5 */ {__glXDisp_GetHistogramEXT, __glXDispSwap_GetHistogramEXT}, /* [ 6] = 6 */ {__glXDisp_GetHistogramParameterfvEXT, __glXDispSwap_GetHistogramParameterfvEXT}, /* [ 7] = 7 */ {__glXDisp_GetHistogramParameterivEXT, __glXDispSwap_GetHistogramParameterivEXT}, /* [ 8] = 8 */ {__glXDisp_GetMinmaxEXT, __glXDispSwap_GetMinmaxEXT}, /* [ 9] = 9 */ {__glXDisp_GetMinmaxParameterfvEXT, __glXDispSwap_GetMinmaxParameterfvEXT}, /* [ 10] = 10 */ {__glXDisp_GetMinmaxParameterivEXT, __glXDispSwap_GetMinmaxParameterivEXT}, /* [ 11] = 11 */ {__glXDisp_AreTexturesResidentEXT, __glXDispSwap_AreTexturesResidentEXT}, /* [ 12] = 12 */ {__glXDisp_DeleteTexturesEXT, __glXDispSwap_DeleteTexturesEXT}, /* [ 13] = 13 */ {__glXDisp_GenTexturesEXT, __glXDispSwap_GenTexturesEXT}, /* [ 14] = 14 */ {__glXDisp_IsTextureEXT, __glXDispSwap_IsTextureEXT}, /* [ 15] = 15 */ {NULL, NULL}, /* [ 16] = 1024 */ {__glXDisp_QueryContextInfoEXT, __glXDispSwap_QueryContextInfoEXT}, /* [ 17] = 1025 */ {NULL, NULL}, /* [ 18] = 1026 */ {NULL, NULL}, /* [ 19] = 1027 */ {NULL, NULL}, /* [ 20] = 1028 */ {NULL, NULL}, /* [ 21] = 1029 */ {NULL, NULL}, /* [ 22] = 1030 */ {NULL, NULL}, /* [ 23] = 1031 */ {NULL, NULL}, /* [ 24] = 1296 */ {__glXDisp_GetProgramEnvParameterfvARB, __glXDispSwap_GetProgramEnvParameterfvARB}, /* [ 25] = 1297 */ {__glXDisp_GetProgramEnvParameterdvARB, __glXDispSwap_GetProgramEnvParameterdvARB}, /* [ 26] = 1298 */ {NULL, NULL}, /* [ 27] = 1299 */ {NULL, NULL}, /* [ 28] = 1300 */ {NULL, NULL}, /* [ 29] = 1301 */ {NULL, NULL}, /* [ 30] = 1302 */ {NULL, NULL}, /* [ 31] = 1303 */ {NULL, NULL}, /* [ 32] = 1304 */ {__glXDisp_IsProgramARB, __glXDispSwap_IsProgramARB}, /* [ 33] = 1305 */ {__glXDisp_GetProgramLocalParameterfvARB, __glXDispSwap_GetProgramLocalParameterfvARB}, /* [ 34] = 1306 */ {__glXDisp_GetProgramLocalParameterdvARB, __glXDispSwap_GetProgramLocalParameterdvARB}, /* [ 35] = 1307 */ {__glXDisp_GetProgramivARB, __glXDispSwap_GetProgramivARB}, /* [ 36] = 1308 */ {__glXDisp_GetProgramStringARB, __glXDispSwap_GetProgramStringARB}, /* [ 37] = 1309 */ {NULL, NULL}, /* [ 38] = 1310 */ {NULL, NULL}, /* [ 39] = 1311 */ {NULL, NULL}, /* [ 40] = 1288 */ {NULL, NULL}, /* [ 41] = 1289 */ {NULL, NULL}, /* [ 42] = 1290 */ {NULL, NULL}, /* [ 43] = 1291 */ {NULL, NULL}, /* [ 44] = 1292 */ {NULL, NULL}, /* [ 45] = 1293 */ {NULL, NULL}, /* [ 46] = 1294 */ {__glXDisp_DeleteProgramsARB, __glXDispSwap_DeleteProgramsARB}, /* [ 47] = 1295 */ {__glXDisp_GenProgramsARB, __glXDispSwap_GenProgramsARB}, /* [ 48] = 1328 */ {NULL, NULL}, /* [ 49] = 1329 */ {NULL, NULL}, /* [ 50] = 1330 */ {__glXDisp_BindTexImageEXT, __glXDispSwap_BindTexImageEXT}, /* [ 51] = 1331 */ {__glXDisp_ReleaseTexImageEXT, __glXDispSwap_ReleaseTexImageEXT}, /* [ 52] = 1332 */ {NULL, NULL}, /* [ 53] = 1333 */ {NULL, NULL}, /* [ 54] = 1334 */ {NULL, NULL}, /* [ 55] = 1335 */ {NULL, NULL}, /* [ 56] = 1416 */ {NULL, NULL}, /* [ 57] = 1417 */ {NULL, NULL}, /* [ 58] = 1418 */ {NULL, NULL}, /* [ 59] = 1419 */ {NULL, NULL}, /* [ 60] = 1420 */ {NULL, NULL}, /* [ 61] = 1421 */ {NULL, NULL}, /* [ 62] = 1422 */ {__glXDisp_IsRenderbuffer, __glXDispSwap_IsRenderbuffer}, /* [ 63] = 1423 */ {__glXDisp_GenRenderbuffers, __glXDispSwap_GenRenderbuffers}, /* [ 64] = 1424 */ {__glXDisp_GetRenderbufferParameteriv, __glXDispSwap_GetRenderbufferParameteriv}, /* [ 65] = 1425 */ {__glXDisp_IsFramebuffer, __glXDispSwap_IsFramebuffer}, /* [ 66] = 1426 */ {__glXDisp_GenFramebuffers, __glXDispSwap_GenFramebuffers}, /* [ 67] = 1427 */ {__glXDisp_CheckFramebufferStatus, __glXDispSwap_CheckFramebufferStatus}, /* [ 68] = 1428 */ {__glXDisp_GetFramebufferAttachmentParameteriv, __glXDispSwap_GetFramebufferAttachmentParameteriv}, /* [ 69] = 1429 */ {NULL, NULL}, /* [ 70] = 1430 */ {NULL, NULL}, /* [ 71] = 1431 */ {NULL, NULL}, /* [ 72] = 4096 */ {NULL, NULL}, /* [ 73] = 4097 */ {NULL, NULL}, /* [ 74] = 4098 */ {__glXDisp_GetColorTableSGI, __glXDispSwap_GetColorTableSGI}, /* [ 75] = 4099 */ {__glXDisp_GetColorTableParameterfvSGI, __glXDispSwap_GetColorTableParameterfvSGI}, /* [ 76] = 4100 */ {__glXDisp_GetColorTableParameterivSGI, __glXDispSwap_GetColorTableParameterivSGI}, /* [ 77] = 4101 */ {NULL, NULL}, /* [ 78] = 4102 */ {NULL, NULL}, /* [ 79] = 4103 */ {NULL, NULL}, /* [ 80] = 5152 */ {NULL, NULL}, /* [ 81] = 5153 */ {NULL, NULL}, /* [ 82] = 5154 */ {__glXDisp_CopySubBufferMESA, __glXDispSwap_CopySubBufferMESA}, /* [ 83] = 5155 */ {NULL, NULL}, /* [ 84] = 5156 */ {NULL, NULL}, /* [ 85] = 5157 */ {NULL, NULL}, /* [ 86] = 5158 */ {NULL, NULL}, /* [ 87] = 5159 */ {NULL, NULL}, /* [ 88] = 65536 */ {__glXDisp_SwapIntervalSGI, __glXDispSwap_SwapIntervalSGI}, /* [ 89] = 65537 */ {__glXDisp_MakeCurrentReadSGI, __glXDispSwap_MakeCurrentReadSGI}, /* [ 90] = 65538 */ {NULL, NULL}, /* [ 91] = 65539 */ {NULL, NULL}, /* [ 92] = 65540 */ {__glXDisp_GetFBConfigsSGIX, __glXDispSwap_GetFBConfigsSGIX}, /* [ 93] = 65541 */ {__glXDisp_CreateContextWithConfigSGIX, __glXDispSwap_CreateContextWithConfigSGIX}, /* [ 94] = 65542 */ {__glXDisp_CreateGLXPixmapWithConfigSGIX, __glXDispSwap_CreateGLXPixmapWithConfigSGIX}, /* [ 95] = 65543 */ {__glXDisp_CreateGLXPbufferSGIX, __glXDispSwap_CreateGLXPbufferSGIX}, /* [ 96] = 65544 */ {__glXDisp_DestroyGLXPbufferSGIX, __glXDispSwap_DestroyGLXPbufferSGIX}, /* [ 97] = 65545 */ {__glXDisp_ChangeDrawableAttributesSGIX, __glXDispSwap_ChangeDrawableAttributesSGIX}, /* [ 98] = 65546 */ {__glXDisp_GetDrawableAttributesSGIX, __glXDispSwap_GetDrawableAttributesSGIX}, /* [ 99] = 65547 */ {NULL, NULL}, /* [ 100] = 65548 */ {NULL, NULL}, /* [ 101] = 65549 */ {NULL, NULL}, /* [ 102] = 65550 */ {NULL, NULL}, /* [ 103] = 65551 */ {NULL, NULL}, }; const struct __glXDispatchInfo VendorPriv_dispatch_info = { 17, VendorPriv_dispatch_tree, VendorPriv_function_table, NULL, NULL }; xorg-server-1.20.13/glx/clientinfo.c0000644000175000017500000001012014100573756014154 00000000000000/* * Copyright © 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "indirect_dispatch.h" #include "glxbyteorder.h" #include "unpack.h" static int set_client_info(__GLXclientState * cl, xGLXSetClientInfoARBReq * req, unsigned bytes_per_version) { ClientPtr client = cl->client; char *gl_extensions; char *glx_extensions; int size; REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); /* Verify that the size of the packet matches the size inferred from the * sizes specified for the various fields. */ size = sz_xGLXSetClientInfoARBReq; size = safe_add(size, safe_mul(req->numVersions, bytes_per_version)); size = safe_add(size, safe_pad(req->numGLExtensionBytes)); size = safe_add(size, safe_pad(req->numGLXExtensionBytes)); if (size < 0 || req->length != (size / 4)) return BadLength; /* Verify that the actual length of the GL extension string matches what's * encoded in protocol packet. */ gl_extensions = (char *) (req + 1) + (req->numVersions * bytes_per_version); if (req->numGLExtensionBytes != 0 && memchr(gl_extensions, 0, __GLX_PAD(req->numGLExtensionBytes)) == NULL) return BadLength; /* Verify that the actual length of the GLX extension string matches * what's encoded in protocol packet. */ glx_extensions = gl_extensions + __GLX_PAD(req->numGLExtensionBytes); if (req->numGLXExtensionBytes != 0 && memchr(glx_extensions, 0, __GLX_PAD(req->numGLXExtensionBytes)) == NULL) return BadLength; free(cl->GLClientextensions); cl->GLClientextensions = strdup(gl_extensions); return 0; } int __glXDisp_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc) { return set_client_info(cl, (xGLXSetClientInfoARBReq *) pc, 8); } int __glXDispSwap_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc; REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); req->length = bswap_16(req->length); req->numVersions = bswap_32(req->numVersions); req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes); req->numGLXExtensionBytes = bswap_32(req->numGLXExtensionBytes); return __glXDisp_SetClientInfoARB(cl, pc); } int __glXDisp_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc) { return set_client_info(cl, (xGLXSetClientInfoARBReq *) pc, 12); } int __glXDispSwap_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc; REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); req->length = bswap_16(req->length); req->numVersions = bswap_32(req->numVersions); req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes); req->numGLXExtensionBytes = bswap_32(req->numGLXExtensionBytes); return __glXDisp_SetClientInfo2ARB(cl, pc); } xorg-server-1.20.13/glx/createcontext.c0000644000175000017500000003020214100573756014675 00000000000000/* * Copyright © 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "glxserver.h" #include "glxext.h" #include "indirect_dispatch.h" #include "opaque.h" #define ALL_VALID_FLAGS \ (GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB \ | GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB) static Bool validate_GL_version(int major_version, int minor_version) { if (major_version <= 0 || minor_version < 0) return FALSE; switch (major_version) { case 1: if (minor_version > 5) return FALSE; break; case 2: if (minor_version > 1) return FALSE; break; case 3: if (minor_version > 3) return FALSE; break; default: break; } return TRUE; } static Bool validate_render_type(uint32_t render_type) { switch (render_type) { case GLX_RGBA_TYPE: case GLX_COLOR_INDEX_TYPE: case GLX_RGBA_FLOAT_TYPE_ARB: case GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT: return TRUE; default: return FALSE; } } int __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreateContextAttribsARBReq *req = (xGLXCreateContextAttribsARBReq *) pc; int32_t *attribs = (req->numAttribs != 0) ? (int32_t *) (req + 1) : NULL; unsigned i; int major_version = 1; int minor_version = 0; uint32_t flags = 0; uint32_t render_type = GLX_RGBA_TYPE; #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB uint32_t flush = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB; #endif __GLXcontext *ctx = NULL; __GLXcontext *shareCtx = NULL; __GLXscreen *glxScreen; __GLXconfig *config = NULL; int err; /* The GLX_ARB_create_context_robustness spec says: * * "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB * is GLX_NO_RESET_NOTIFICATION_ARB." */ int reset = GLX_NO_RESET_NOTIFICATION_ARB; /* The GLX_ARB_create_context_profile spec says: * * "The default value for GLX_CONTEXT_PROFILE_MASK_ARB is * GLX_CONTEXT_CORE_PROFILE_BIT_ARB." * * The core profile only makes sense for OpenGL versions 3.2 and later. * If the version ultimately specified is less than 3.2, the core profile * bit is cleared (see below). */ int profile = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; /* Verify that the size of the packet matches the size inferred from the * sizes specified for the various fields. */ const unsigned expected_size = (sz_xGLXCreateContextAttribsARBReq + (req->numAttribs * 8)) / 4; if (req->length != expected_size) return BadLength; /* The GLX_ARB_create_context spec says: * * "* If is not a valid GLXFBConfig, GLXBadFBConfig is * generated." * * On the client, the screen comes from the FBConfig, so GLXBadFBConfig * should be issued if the screen is nonsense. */ if (!validGlxScreen(client, req->screen, &glxScreen, &err)) return __glXError(GLXBadFBConfig); if (req->fbconfig) { if (!validGlxFBConfig(client, glxScreen, req->fbconfig, &config, &err)) return __glXError(GLXBadFBConfig); } /* Validate the context with which the new context should share resources. */ if (req->shareList != None) { if (!validGlxContext(client, req->shareList, DixReadAccess, &shareCtx, &err)) return err; /* The crazy condition is because C doesn't have a logical XOR * operator. Comparing directly for equality may fail if one is 1 and * the other is 2 even though both are logically true. */ if (!!req->isDirect != !!shareCtx->isDirect) { client->errorValue = req->shareList; return BadMatch; } /* The GLX_ARB_create_context spec says: * * "* If the server context state for ...was * created on a different screen than the one referenced by * ...BadMatch is generated." */ if (glxScreen != shareCtx->pGlxScreen) { client->errorValue = shareCtx->pGlxScreen->pScreen->myNum; return BadMatch; } } for (i = 0; i < req->numAttribs; i++) { switch (attribs[i * 2]) { case GLX_CONTEXT_MAJOR_VERSION_ARB: major_version = attribs[2 * i + 1]; break; case GLX_CONTEXT_MINOR_VERSION_ARB: minor_version = attribs[2 * i + 1]; break; case GLX_CONTEXT_FLAGS_ARB: flags = attribs[2 * i + 1]; break; case GLX_RENDER_TYPE: /* Not valid for GLX_EXT_no_config_context */ if (!req->fbconfig) return BadValue; render_type = attribs[2 * i + 1]; break; case GLX_CONTEXT_PROFILE_MASK_ARB: profile = attribs[2 * i + 1]; break; case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB: reset = attribs[2 * i + 1]; if (reset != GLX_NO_RESET_NOTIFICATION_ARB && reset != GLX_LOSE_CONTEXT_ON_RESET_ARB) return BadValue; break; #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB case GLX_CONTEXT_RELEASE_BEHAVIOR_ARB: flush = attribs[2 * i + 1]; if (flush != GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB && flush != GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB) return BadValue; break; #endif case GLX_SCREEN: /* Only valid for GLX_EXT_no_config_context */ if (req->fbconfig) return BadValue; /* Must match the value in the request header */ if (attribs[2 * i + 1] != req->screen) return BadValue; break; case GLX_CONTEXT_OPENGL_NO_ERROR_ARB: /* ignore */ break; default: if (!req->isDirect) return BadValue; break; } } /* The GLX_ARB_create_context spec says: * * "If attributes GLX_CONTEXT_MAJOR_VERSION_ARB and * GLX_CONTEXT_MINOR_VERSION_ARB, when considered together * with attributes GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB and * GLX_RENDER_TYPE, specify an OpenGL version and feature set * that are not defined, BadMatch is generated. * * ...Feature deprecation was introduced with OpenGL 3.0, so * forward-compatible contexts may only be requested for * OpenGL 3.0 and above. Thus, examples of invalid * combinations of attributes include: * * - Major version < 1 or > 3 * - Major version == 1 and minor version < 0 or > 5 * - Major version == 2 and minor version < 0 or > 1 * - Major version == 3 and minor version > 2 * - Forward-compatible flag set and major version < 3 * - Color index rendering and major version >= 3" */ if (!validate_GL_version(major_version, minor_version)) return BadMatch; if (major_version < 3 && ((flags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) != 0)) return BadMatch; if (major_version >= 3 && render_type == GLX_COLOR_INDEX_TYPE) return BadMatch; if (!validate_render_type(render_type)) return BadValue; if ((flags & ~ALL_VALID_FLAGS) != 0) return BadValue; /* The GLX_ARB_create_context_profile spec says: * * "* If attribute GLX_CONTEXT_PROFILE_MASK_ARB has no bits set; has * any bits set other than GLX_CONTEXT_CORE_PROFILE_BIT_ARB and * GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; has more than one of * these bits set; or if the implementation does not support the * requested profile, then GLXBadProfileARB is generated." * * The GLX_EXT_create_context_es2_profile spec doesn't exactly say what * is supposed to happen if an invalid version is set, but it doesn't * much matter as support for GLES contexts is only defined for direct * contexts (at the moment anyway) so we can leave it up to the driver * to validate. */ switch (profile) { case GLX_CONTEXT_CORE_PROFILE_BIT_ARB: case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: case GLX_CONTEXT_ES2_PROFILE_BIT_EXT: break; default: return __glXError(GLXBadProfileARB); } /* The GLX_ARB_create_context_robustness spec says: * * "* If the reset notification behavior of and the * newly created context are different, BadMatch is generated." */ if (shareCtx != NULL && shareCtx->resetNotificationStrategy != reset) return BadMatch; /* There is no GLX protocol for desktop OpenGL versions after 1.4. There * is no GLX protocol for any version of OpenGL ES. If the application is * requested an indirect rendering context for a version that cannot be * satisfied, reject it. * * The GLX_ARB_create_context spec says: * * "* If does not support compatible OpenGL contexts * providing the requested API major and minor version, * forward-compatible flag, and debug context flag, GLXBadFBConfig * is generated." */ if (!req->isDirect && (major_version > 1 || minor_version > 4 || profile == GLX_CONTEXT_ES2_PROFILE_BIT_EXT)) { return __glXError(GLXBadFBConfig); } /* Allocate memory for the new context */ if (req->isDirect) { ctx = __glXdirectContextCreate(glxScreen, config, shareCtx); err = BadAlloc; } else { /* Only allow creating indirect GLX contexts if allowed by * server command line. Indirect GLX is of limited use (since * it's only GL 1.4), it's slower than direct contexts, and * it's a massive attack surface for buffer overflow type * errors. */ if (!enableIndirectGLX) { client->errorValue = req->isDirect; return BadValue; } ctx = glxScreen->createContext(glxScreen, config, shareCtx, req->numAttribs, (uint32_t *) attribs, &err); } if (ctx == NULL) return err; ctx->pGlxScreen = glxScreen; ctx->config = config; ctx->id = req->context; ctx->share_id = req->shareList; ctx->idExists = TRUE; ctx->isDirect = req->isDirect; ctx->renderMode = GL_RENDER; ctx->resetNotificationStrategy = reset; #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB ctx->releaseBehavior = flush; #endif /* Add the new context to the various global tables of GLX contexts. */ if (!__glXAddContext(ctx)) { (*ctx->destroy) (ctx); client->errorValue = req->context; return BadAlloc; } return Success; } int __glXDispSwap_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc) { return BadRequest; } xorg-server-1.20.13/glx/extension_string.c0000644000175000017500000001461614100573756015442 00000000000000/* * (C) Copyright IBM Corporation 2002-2006 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** * \file extension_string.c * Routines to manage the GLX extension string and GLX version for AIGLX * drivers. This code is loosely based on src/glx/x11/glxextensions.c from * Mesa. * * \author Ian Romanick */ #include #include "extension_string.h" #define SET_BIT(m,b) (m[ (b) / 8 ] |= (1U << ((b) % 8))) #define CLR_BIT(m,b) (m[ (b) / 8 ] &= ~(1U << ((b) % 8))) #define IS_SET(m,b) ((m[ (b) / 8 ] & (1U << ((b) % 8))) != 0) #define CONCAT(a,b) a ## b #define GLX(n) "GLX_" # n, 4 + sizeof( # n ) - 1, CONCAT(n,_bit) #define VER(a,b) a, b #define Y 1 #define N 0 #define EXT_ENABLED(bit,supported) (IS_SET(supported, bit)) struct extension_info { const char *const name; unsigned name_len; unsigned char bit; /** * This is the lowest version of GLX that "requires" this extension. * For example, GLX 1.3 requires SGIX_fbconfig, SGIX_pbuffer, and * SGI_make_current_read. If the extension is not required by any known * version of GLX, use 0, 0. */ unsigned char version_major; unsigned char version_minor; /** * Is driver support forced by the ABI? */ unsigned char driver_support; }; /** * List of known GLX Extensions. * The last Y/N switch informs whether the support of this extension is always enabled. */ static const struct extension_info known_glx_extensions[] = { /* GLX_ARB_get_proc_address is implemented on the client. */ /* *INDENT-OFF* */ { GLX(ARB_context_flush_control), VER(0,0), N, }, { GLX(ARB_create_context), VER(0,0), N, }, { GLX(ARB_create_context_no_error), VER(0,0), N, }, { GLX(ARB_create_context_profile), VER(0,0), N, }, { GLX(ARB_create_context_robustness), VER(0,0), N, }, { GLX(ARB_fbconfig_float), VER(0,0), N, }, { GLX(ARB_framebuffer_sRGB), VER(0,0), N, }, { GLX(ARB_multisample), VER(1,4), Y, }, { GLX(EXT_create_context_es_profile), VER(0,0), N, }, { GLX(EXT_create_context_es2_profile), VER(0,0), N, }, { GLX(EXT_fbconfig_packed_float), VER(0,0), N, }, { GLX(EXT_framebuffer_sRGB), VER(0,0), N, }, { GLX(EXT_import_context), VER(0,0), Y, }, { GLX(EXT_libglvnd), VER(0,0), N, }, { GLX(EXT_no_config_context), VER(0,0), N, }, { GLX(EXT_stereo_tree), VER(0,0), N, }, { GLX(EXT_texture_from_pixmap), VER(0,0), N, }, { GLX(EXT_visual_info), VER(0,0), Y, }, { GLX(EXT_visual_rating), VER(0,0), Y, }, { GLX(MESA_copy_sub_buffer), VER(0,0), N, }, { GLX(OML_swap_method), VER(0,0), Y, }, { GLX(SGI_make_current_read), VER(1,3), Y, }, { GLX(SGI_swap_control), VER(0,0), N, }, { GLX(SGIS_multisample), VER(0,0), Y, }, { GLX(SGIX_fbconfig), VER(1,3), Y, }, { GLX(SGIX_pbuffer), VER(1,3), Y, }, { GLX(SGIX_visual_select_group), VER(0,0), Y, }, { GLX(INTEL_swap_event), VER(0,0), N, }, { NULL } /* *INDENT-ON* */ }; /** * Create a GLX extension string for a set of enable bits. * * Creates a GLX extension string for the set of bit in \c enable_bits. This * string is then stored in \c buffer if buffer is not \c NULL. This allows * two-pass operation. On the first pass the caller passes \c NULL for * \c buffer, and the function determines how much space is required to store * the extension string. The caller allocates the buffer and calls the * function again. * * \param enable_bits Bits representing the enabled extensions. * \param buffer Buffer to store the extension string. May be \c NULL. * * \return * The number of characters in \c buffer that were written to. If \c buffer * is \c NULL, this is the size of buffer that must be allocated by the * caller. */ int __glXGetExtensionString(const unsigned char *enable_bits, char *buffer) { unsigned i; int length = 0; for (i = 0; known_glx_extensions[i].name != NULL; i++) { const unsigned bit = known_glx_extensions[i].bit; const size_t len = known_glx_extensions[i].name_len; if (EXT_ENABLED(bit, enable_bits)) { if (buffer != NULL) { (void) memcpy(&buffer[length], known_glx_extensions[i].name, len); buffer[length + len + 0] = ' '; buffer[length + len + 1] = '\0'; } length += len + 1; } } return length + 1; } void __glXEnableExtension(unsigned char *enable_bits, const char *ext) { const size_t ext_name_len = strlen(ext); unsigned i; for (i = 0; known_glx_extensions[i].name != NULL; i++) { if ((ext_name_len == known_glx_extensions[i].name_len) && (memcmp(ext, known_glx_extensions[i].name, ext_name_len) == 0)) { SET_BIT(enable_bits, known_glx_extensions[i].bit); break; } } } void __glXInitExtensionEnableBits(unsigned char *enable_bits) { unsigned i; (void) memset(enable_bits, 0, __GLX_EXT_BYTES); for (i = 0; known_glx_extensions[i].name != NULL; i++) { if (known_glx_extensions[i].driver_support) { SET_BIT(enable_bits, known_glx_extensions[i].bit); } } } xorg-server-1.20.13/glx/extension_string.h0000644000175000017500000000565514100573756015452 00000000000000/* * (C) Copyright IBM Corporation 2002-2006 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** * \file extension_string.h * Routines to manage the GLX extension string and GLX version for AIGLX * drivers. This code is loosely based on src/glx/x11/glxextensions.c from * Mesa. * * \author Ian Romanick */ #ifndef GLX_EXTENSION_STRING_H #define GLX_EXTENSION_STRING_H enum { /* GLX_ARB_get_proc_address is implemented on the client. */ ARB_context_flush_control_bit = 0, ARB_create_context_bit, ARB_create_context_no_error_bit, ARB_create_context_profile_bit, ARB_create_context_robustness_bit, ARB_fbconfig_float_bit, ARB_framebuffer_sRGB_bit, ARB_multisample_bit, EXT_create_context_es_profile_bit, EXT_create_context_es2_profile_bit, EXT_fbconfig_packed_float_bit, EXT_import_context_bit, EXT_libglvnd_bit, EXT_no_config_context_bit, EXT_stereo_tree_bit, EXT_texture_from_pixmap_bit, EXT_visual_info_bit, EXT_visual_rating_bit, MESA_copy_sub_buffer_bit, OML_swap_method_bit, SGI_make_current_read_bit, SGI_swap_control_bit, SGI_video_sync_bit, SGIS_multisample_bit, SGIX_fbconfig_bit, SGIX_pbuffer_bit, SGIX_visual_select_group_bit, INTEL_swap_event_bit, __NUM_GLX_EXTS, }; /* For extensions which have identical ARB and EXT implementation * in GLX area, use one enabling bit for both. */ #define EXT_framebuffer_sRGB_bit ARB_framebuffer_sRGB_bit #define __GLX_EXT_BYTES ((__NUM_GLX_EXTS + 7) / 8) extern int __glXGetExtensionString(const unsigned char *enable_bits, char *buffer); extern void __glXEnableExtension(unsigned char *enable_bits, const char *ext); extern void __glXInitExtensionEnableBits(unsigned char *enable_bits); #endif /* GLX_EXTENSION_STRING_H */ xorg-server-1.20.13/glx/indirect_util.c0000644000175000017500000002161014100573756014666 00000000000000/* * (C) Copyright IBM Corporation 2005 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include #include "indirect_size.h" #include "indirect_size_get.h" #include "indirect_dispatch.h" #include "glxserver.h" #include "glxbyteorder.h" #include "singlesize.h" #include "glxext.h" #include "indirect_table.h" #include "indirect_util.h" #define __GLX_PAD(a) (((a)+3)&~3) GLint __glGetBooleanv_variable_size(GLenum e) { if (e == GL_COMPRESSED_TEXTURE_FORMATS) { GLint temp; glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &temp); return temp; } else { return 0; } } /** * Get a properly aligned buffer to hold reply data. * * \warning * This function assumes that \c local_buffer is already properly aligned. * It also assumes that \c alignment is a power of two. */ void * __glXGetAnswerBuffer(__GLXclientState * cl, size_t required_size, void *local_buffer, size_t local_size, unsigned alignment) { void *buffer = local_buffer; const intptr_t mask = alignment - 1; if (local_size < required_size) { size_t worst_case_size; intptr_t temp_buf; if (required_size < SIZE_MAX - alignment) worst_case_size = required_size + alignment; else return NULL; if (cl->returnBufSize < worst_case_size) { void *temp = realloc(cl->returnBuf, worst_case_size); if (temp == NULL) { return NULL; } cl->returnBuf = temp; cl->returnBufSize = worst_case_size; } temp_buf = (intptr_t) cl->returnBuf; temp_buf = (temp_buf + mask) & ~mask; buffer = (void *) temp_buf; } return buffer; } /** * Send a GLX reply to the client. * * Technically speaking, there are several different ways to encode a GLX * reply. The primary difference is whether or not certain fields (e.g., * retval, size, and "pad3") are set. This function gets around that by * always setting all of the fields to "reasonable" values. This does no * harm to clients, but it does make the server-side code much more compact. */ void __glXSendReply(ClientPtr client, const void *data, size_t elements, size_t element_size, GLboolean always_array, CARD32 retval) { size_t reply_ints = 0; xGLXSingleReply reply = { 0, }; if (__glXErrorOccured()) { elements = 0; } else if ((elements > 1) || always_array) { reply_ints = bytes_to_int32(elements * element_size); } reply.length = reply_ints; reply.type = X_Reply; reply.sequenceNumber = client->sequence; reply.size = elements; reply.retval = retval; /* It is faster on almost always every architecture to just copy the 8 * bytes, even when not necessary, than check to see of the value of * elements requires it. Copying the data when not needed will do no * harm. */ (void) memcpy(&reply.pad3, data, 8); WriteToClient(client, sz_xGLXSingleReply, &reply); if (reply_ints != 0) { WriteToClient(client, reply_ints * 4, data); } } /** * Send a GLX reply to the client. * * Technically speaking, there are several different ways to encode a GLX * reply. The primary difference is whether or not certain fields (e.g., * retval, size, and "pad3") are set. This function gets around that by * always setting all of the fields to "reasonable" values. This does no * harm to clients, but it does make the server-side code much more compact. * * \warning * This function assumes that values stored in \c data will be byte-swapped * by the caller if necessary. */ void __glXSendReplySwap(ClientPtr client, const void *data, size_t elements, size_t element_size, GLboolean always_array, CARD32 retval) { size_t reply_ints = 0; xGLXSingleReply reply = { 0, }; if (__glXErrorOccured()) { elements = 0; } else if ((elements > 1) || always_array) { reply_ints = bytes_to_int32(elements * element_size); } reply.length = bswap_32(reply_ints); reply.type = X_Reply; reply.sequenceNumber = bswap_16(client->sequence); reply.size = bswap_32(elements); reply.retval = bswap_32(retval); /* It is faster on almost always every architecture to just copy the 8 * bytes, even when not necessary, than check to see of the value of * elements requires it. Copying the data when not needed will do no * harm. */ (void) memcpy(&reply.pad3, data, 8); WriteToClient(client, sz_xGLXSingleReply, &reply); if (reply_ints != 0) { WriteToClient(client, reply_ints * 4, data); } } static int get_decode_index(const struct __glXDispatchInfo *dispatch_info, unsigned opcode) { int remaining_bits; int next_remain; const int_fast16_t *const tree = dispatch_info->dispatch_tree; int_fast16_t index; remaining_bits = dispatch_info->bits; if (opcode >= (1U << remaining_bits)) { return -1; } index = 0; for ( /* empty */ ; remaining_bits > 0; remaining_bits = next_remain) { unsigned mask; unsigned child_index; /* Calculate the slice of bits used by this node. * * If remaining_bits = 8 and tree[index] = 3, the mask of just the * remaining bits is 0x00ff and the mask for the remaining bits after * this node is 0x001f. By taking 0x00ff & ~0x001f, we get 0x00e0. * This masks the 3 bits that we would want for this node. */ next_remain = remaining_bits - tree[index]; mask = ((1 << remaining_bits) - 1) & ~((1 << next_remain) - 1); /* Using the mask, calculate the index of the opcode in the node. * With that index, fetch the index of the next node. */ child_index = (opcode & mask) >> next_remain; index = tree[index + 1 + child_index]; /* If the next node is an empty leaf, the opcode is for a non-existant * function. We're done. * * If the next node is a non-empty leaf, look up the function pointer * and return it. */ if (index == EMPTY_LEAF) { return -1; } else if (IS_LEAF_INDEX(index)) { unsigned func_index; /* The value stored in the tree for a leaf node is the base of * the function pointers for that leaf node. The offset for the * function for a particular opcode is the remaining bits in the * opcode. */ func_index = -index; func_index += opcode & ((1 << next_remain) - 1); return func_index; } } /* We should *never* get here!!! */ return -1; } void * __glXGetProtocolDecodeFunction(const struct __glXDispatchInfo *dispatch_info, int opcode, int swapped_version) { const int func_index = get_decode_index(dispatch_info, opcode); return (func_index < 0) ? NULL : (void *) dispatch_info-> dispatch_functions[func_index][swapped_version]; } int __glXGetProtocolSizeData(const struct __glXDispatchInfo *dispatch_info, int opcode, __GLXrenderSizeData * data) { if (dispatch_info->size_table != NULL) { const int func_index = get_decode_index(dispatch_info, opcode); if ((func_index >= 0) && (dispatch_info->size_table[func_index][0] != 0)) { const int var_offset = dispatch_info->size_table[func_index][1]; data->bytes = dispatch_info->size_table[func_index][0]; data->varsize = (var_offset != ~0) ? dispatch_info->size_func_table[var_offset] : NULL; return 0; } } return -1; } xorg-server-1.20.13/glx/indirect_util.h0000644000175000017500000000455414100573756014703 00000000000000/* * (C) Copyright IBM Corporation 2005 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef __GLX_INDIRECT_UTIL_H__ #define __GLX_INDIRECT_UTIL_H__ extern GLint __glGetBooleanv_variable_size(GLenum e); extern void *__glXGetAnswerBuffer(__GLXclientState * cl, size_t required_size, void *local_buffer, size_t local_size, unsigned alignment); extern void __glXSendReply(ClientPtr client, const void *data, size_t elements, size_t element_size, GLboolean always_array, CARD32 retval); extern void __glXSendReplySwap(ClientPtr client, const void *data, size_t elements, size_t element_size, GLboolean always_array, CARD32 retval); struct __glXDispatchInfo; extern void *__glXGetProtocolDecodeFunction(const struct __glXDispatchInfo *dispatch_info, int opcode, int swapped_version); extern int __glXGetProtocolSizeData(const struct __glXDispatchInfo *dispatch_info, int opcode, __GLXrenderSizeData * data); #endif /* __GLX_INDIRECT_UTIL_H__ */ xorg-server-1.20.13/glx/indirect_program.c0000644000175000017500000001007514100573756015363 00000000000000/* * (C) Copyright IBM Corporation 2005, 2006 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS, THE AUTHORS, AND/OR THEIR SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** * \file indirect_program.c * Hand-coded routines needed to support programmable pipeline extensions. * * \author Ian Romanick */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "glxbyteorder.h" #include "glxext.h" #include "singlesize.h" #include "unpack.h" #include "indirect_size_get.h" #include "indirect_dispatch.h" /** * Handle both types of glGetProgramString calls. */ static int DoGetProgramString(struct __GLXclientStateRec *cl, GLbyte * pc, PFNGLGETPROGRAMIVARBPROC get_programiv, PFNGLGETPROGRAMSTRINGARBPROC get_program_string, Bool do_swap) { xGLXVendorPrivateWithReplyReq *const req = (xGLXVendorPrivateWithReplyReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateWithReplyReq, 8); pc += __GLX_VENDPRIV_HDR_SIZE; if (cx != NULL) { GLenum target; GLenum pname; GLint compsize = 0; char *answer = NULL, answerBuffer[200]; xGLXSingleReply reply = { 0, }; if (do_swap) { target = (GLenum) bswap_32(*(int *) (pc + 0)); pname = (GLenum) bswap_32(*(int *) (pc + 4)); } else { target = *(GLenum *) (pc + 0); pname = *(GLuint *) (pc + 4); } /* The value of the GL_PROGRAM_LENGTH_ARB and GL_PROGRAM_LENGTH_NV * enumerants is the same. */ get_programiv(target, GL_PROGRAM_LENGTH_ARB, &compsize); if (compsize != 0) { __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); get_program_string(target, pname, (GLubyte *) answer); } if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); ((xGLXGetTexImageReply *) &reply)->width = compsize; __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } error = Success; } return error; } int __glXDisp_GetProgramStringARB(struct __GLXclientStateRec *cl, GLbyte * pc) { PFNGLGETPROGRAMIVARBPROC get_program = __glGetProcAddress("glGetProgramivARB"); PFNGLGETPROGRAMSTRINGARBPROC get_program_string = __glGetProcAddress("glGetProgramStringARB"); return DoGetProgramString(cl, pc, get_program, get_program_string, FALSE); } int __glXDispSwap_GetProgramStringARB(struct __GLXclientStateRec *cl, GLbyte * pc) { PFNGLGETPROGRAMIVARBPROC get_program = __glGetProcAddress("glGetProgramivARB"); PFNGLGETPROGRAMSTRINGARBPROC get_program_string = __glGetProcAddress("glGetProgramStringARB"); return DoGetProgramString(cl, pc, get_program, get_program_string, TRUE); } xorg-server-1.20.13/glx/indirect_table.h0000644000175000017500000000655614100573756015021 00000000000000/* * (C) Copyright IBM Corporation 2005, 2006 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /** * \file indirect_table.h * * \author Ian Romanick */ #ifndef INDIRECT_TABLE_H #define INDIRECT_TABLE_H #include /** */ struct __glXDispatchInfo { /** * Number of significant bits in the protocol opcode. Opcodes with values * larger than ((1 << bits) - 1) are invalid. */ unsigned bits; /** */ const int_fast16_t *dispatch_tree; /** * Array of protocol decode and dispatch functions index by the opcode * search tree (i.e., \c dispatch_tree). The first element in each pair * is the non-byte-swapped version, and the second element is the * byte-swapped version. */ const void *(*dispatch_functions)[2]; /** * Pointer to size validation data. This table is indexed with the same * value as ::dispatch_functions. * * The first element in the pair is the size, in bytes, of the fixed-size * portion of the protocol. * * For opcodes that have a variable-size portion, the second value is an * index in \c size_func_table to calculate that size. If there is no * variable-size portion, this index will be ~0. * * \note * If size checking is not to be performed on this type of protocol * data, this pointer will be \c NULL. */ const int_fast16_t(*size_table)[2]; /** * Array of functions used to calculate the variable-size portion of * protocol messages. Indexed by the second element of the entries * in \c ::size_table. * * \note * If size checking is not to be performed on this type of protocol * data, this pointer will be \c NULL. */ const gl_proto_size_func *size_func_table; }; /** * Sentinel value for an empty leaf in the \c dispatch_tree. */ #define EMPTY_LEAF INT_FAST16_MIN /** * Declare the index \c x as a leaf index. */ #define LEAF(x) -x /** * Determine if an index is a leaf index. */ #define IS_LEAF_INDEX(x) ((x) <= 0) extern const struct __glXDispatchInfo Single_dispatch_info; extern const struct __glXDispatchInfo Render_dispatch_info; extern const struct __glXDispatchInfo VendorPriv_dispatch_info; #endif /* INDIRECT_TABLE_H */ xorg-server-1.20.13/glx/indirect_texture_compression.c0000644000175000017500000001033614100573756020035 00000000000000/* * (C) Copyright IBM Corporation 2005, 2006 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * IBM, * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "glxbyteorder.h" #include "glxext.h" #include "singlesize.h" #include "unpack.h" #include "indirect_size_get.h" #include "indirect_dispatch.h" int __glXDisp_GetCompressedTexImage(struct __GLXclientStateRec *cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 8); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum target = *(GLenum *) (pc + 0); const GLint level = *(GLint *) (pc + 4); GLint compsize = 0; char *answer = NULL, answerBuffer[200]; xGLXSingleReply reply = { 0, }; glGetTexLevelParameteriv(target, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compsize); if (compsize != 0) { PFNGLGETCOMPRESSEDTEXIMAGEARBPROC GetCompressedTexImageARB = __glGetProcAddress("glGetCompressedTexImageARB"); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); GetCompressedTexImageARB(target, level, answer); } if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); ((xGLXGetTexImageReply *) &reply)->width = compsize; __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } error = Success; } return error; } int __glXDispSwap_GetCompressedTexImage(struct __GLXclientStateRec *cl, GLbyte * pc) { xGLXSingleReq *const req = (xGLXSingleReq *) pc; int error; __GLXcontext *const cx = __glXForceCurrent(cl, bswap_32(req->contextTag), &error); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 8); pc += __GLX_SINGLE_HDR_SIZE; if (cx != NULL) { const GLenum target = (GLenum) bswap_32(*(int *) (pc + 0)); const GLint level = (GLint) bswap_32(*(int *) (pc + 4)); GLint compsize = 0; char *answer = NULL, answerBuffer[200]; xGLXSingleReply reply = { 0, }; glGetTexLevelParameteriv(target, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compsize); if (compsize != 0) { PFNGLGETCOMPRESSEDTEXIMAGEARBPROC GetCompressedTexImageARB = __glGetProcAddress("glGetCompressedTexImageARB"); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); GetCompressedTexImageARB(target, level, answer); } if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); ((xGLXGetTexImageReply *) &reply)->width = compsize; __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } error = Success; } return error; } xorg-server-1.20.13/glx/glxbyteorder.h0000644000175000017500000000303214100573756014545 00000000000000/* * (C) Copyright IBM Corporation 2006, 2007 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS, THE AUTHORS, AND/OR THEIR SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** * \file glxbyteorder.h * Platform glue for handling byte-ordering issues in GLX protocol. * * \author Ian Romanick */ #if !defined(__GLXBYTEORDER_H__) #define __GLXBYTEORDER_H__ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "misc.h" #endif /* !defined(__GLXBYTEORDER_H__) */ xorg-server-1.20.13/glx/glxcmds.c0000644000175000017500000022602014100573756013473 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include "glxserver.h" #include #include #include #include #include #include "glxutil.h" #include "glxext.h" #include "indirect_dispatch.h" #include "indirect_table.h" #include "indirect_util.h" #include "protocol-versions.h" #include "glxvndabi.h" static char GLXServerVendorName[] = "SGI"; _X_HIDDEN int validGlxScreen(ClientPtr client, int screen, __GLXscreen ** pGlxScreen, int *err) { /* ** Check if screen exists. */ if (screen < 0 || screen >= screenInfo.numScreens) { client->errorValue = screen; *err = BadValue; return FALSE; } *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); return TRUE; } _X_HIDDEN int validGlxFBConfig(ClientPtr client, __GLXscreen * pGlxScreen, XID id, __GLXconfig ** config, int *err) { __GLXconfig *m; for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) if (m->fbconfigID == id) { *config = m; return TRUE; } client->errorValue = id; *err = __glXError(GLXBadFBConfig); return FALSE; } static int validGlxVisual(ClientPtr client, __GLXscreen * pGlxScreen, XID id, __GLXconfig ** config, int *err) { int i; for (i = 0; i < pGlxScreen->numVisuals; i++) if (pGlxScreen->visuals[i]->visualID == id) { *config = pGlxScreen->visuals[i]; return TRUE; } client->errorValue = id; *err = BadValue; return FALSE; } static int validGlxFBConfigForWindow(ClientPtr client, __GLXconfig * config, DrawablePtr pDraw, int *err) { ScreenPtr pScreen = pDraw->pScreen; VisualPtr pVisual = NULL; XID vid; int i; vid = wVisual((WindowPtr) pDraw); for (i = 0; i < pScreen->numVisuals; i++) { if (pScreen->visuals[i].vid == vid) { pVisual = &pScreen->visuals[i]; break; } } /* FIXME: What exactly should we check here... */ if (pVisual->class != glxConvertToXVisualType(config->visualType) || !(config->drawableType & GLX_WINDOW_BIT)) { client->errorValue = pDraw->id; *err = BadMatch; return FALSE; } return TRUE; } _X_HIDDEN int validGlxContext(ClientPtr client, XID id, int access_mode, __GLXcontext ** context, int *err) { /* no ghost contexts */ if (id & SERVER_BIT) { *err = __glXError(GLXBadContext); return FALSE; } *err = dixLookupResourceByType((void **) context, id, __glXContextRes, client, access_mode); if (*err != Success || (*context)->idExists == GL_FALSE) { client->errorValue = id; if (*err == BadValue || *err == Success) *err = __glXError(GLXBadContext); return FALSE; } return TRUE; } int validGlxDrawable(ClientPtr client, XID id, int type, int access_mode, __GLXdrawable ** drawable, int *err) { int rc; rc = dixLookupResourceByType((void **) drawable, id, __glXDrawableRes, client, access_mode); if (rc != Success && rc != BadValue) { *err = rc; client->errorValue = id; return FALSE; } /* If the ID of the glx drawable we looked up doesn't match the id * we looked for, it's because we looked it up under the X * drawable ID (see DoCreateGLXDrawable). */ if (rc == BadValue || (*drawable)->drawId != id || (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) { client->errorValue = id; switch (type) { case GLX_DRAWABLE_WINDOW: *err = __glXError(GLXBadWindow); return FALSE; case GLX_DRAWABLE_PIXMAP: *err = __glXError(GLXBadPixmap); return FALSE; case GLX_DRAWABLE_PBUFFER: *err = __glXError(GLXBadPbuffer); return FALSE; case GLX_DRAWABLE_ANY: *err = __glXError(GLXBadDrawable); return FALSE; } } return TRUE; } void __glXContextDestroy(__GLXcontext * context) { lastGLContext = NULL; } static void __glXdirectContextDestroy(__GLXcontext * context) { __glXContextDestroy(context); free(context); } static int __glXdirectContextLoseCurrent(__GLXcontext * context) { return GL_TRUE; } _X_HIDDEN __GLXcontext * __glXdirectContextCreate(__GLXscreen * screen, __GLXconfig * modes, __GLXcontext * shareContext) { __GLXcontext *context; context = calloc(1, sizeof(__GLXcontext)); if (context == NULL) return NULL; context->config = modes; context->destroy = __glXdirectContextDestroy; context->loseCurrent = __glXdirectContextLoseCurrent; return context; } /** * Create a GL context with the given properties. This routine is used * to implement \c glXCreateContext, \c glXCreateNewContext, and * \c glXCreateContextWithConfigSGIX. This works because of the hack way * that GLXFBConfigs are implemented. Basically, the FBConfigID is the * same as the VisualID. */ static int DoCreateContext(__GLXclientState * cl, GLXContextID gcId, GLXContextID shareList, __GLXconfig * config, __GLXscreen * pGlxScreen, GLboolean isDirect) { ClientPtr client = cl->client; __GLXcontext *glxc, *shareglxc; int err; /* ** Find the display list space that we want to share. ** ** NOTE: In a multithreaded X server, we would need to keep a reference ** count for each display list so that if one client detroyed a list that ** another client was using, the list would not really be freed until it ** was no longer in use. Since this sample implementation has no support ** for multithreaded servers, we don't do this. */ if (shareList == None) { shareglxc = 0; } else { if (!validGlxContext(client, shareList, DixReadAccess, &shareglxc, &err)) return err; /* Page 26 (page 32 of the PDF) of the GLX 1.4 spec says: * * "The server context state for all sharing contexts must exist * in a single address space or a BadMatch error is generated." * * If the share context is indirect, force the new context to also be * indirect. If the shard context is direct but the new context * cannot be direct, generate BadMatch. */ if (shareglxc->isDirect && !isDirect) { client->errorValue = shareList; return BadMatch; } else if (!shareglxc->isDirect) { /* ** Create an indirect context regardless of what the client asked ** for; this way we can share display list space with shareList. */ isDirect = GL_FALSE; } } /* ** Allocate memory for the new context */ if (!isDirect) { /* Only allow creating indirect GLX contexts if allowed by * server command line. Indirect GLX is of limited use (since * it's only GL 1.4), it's slower than direct contexts, and * it's a massive attack surface for buffer overflow type * errors. */ if (!enableIndirectGLX) { client->errorValue = isDirect; return BadValue; } /* Without any attributes, the only error that the driver should be * able to generate is BadAlloc. As result, just drop the error * returned from the driver on the floor. */ glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc, 0, NULL, &err); } else glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc); if (!glxc) { return BadAlloc; } /* Initialize the GLXcontext structure. */ glxc->pGlxScreen = pGlxScreen; glxc->config = config; glxc->id = gcId; glxc->share_id = shareList; glxc->idExists = GL_TRUE; glxc->isDirect = isDirect; glxc->renderMode = GL_RENDER; /* The GLX_ARB_create_context_robustness spec says: * * "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB * is GLX_NO_RESET_NOTIFICATION_ARB." * * Without using glXCreateContextAttribsARB, there is no way to specify a * non-default reset notification strategy. */ glxc->resetNotificationStrategy = GLX_NO_RESET_NOTIFICATION_ARB; #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB /* The GLX_ARB_context_flush_control spec says: * * "The default value [for GLX_CONTEXT_RELEASE_BEHAVIOR] is * CONTEXT_RELEASE_BEHAVIOR_FLUSH, and may in some cases be changed * using platform-specific context creation extensions." * * Without using glXCreateContextAttribsARB, there is no way to specify a * non-default release behavior. */ glxc->releaseBehavior = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB; #endif /* Add the new context to the various global tables of GLX contexts. */ if (!__glXAddContext(glxc)) { (*glxc->destroy) (glxc); client->errorValue = gcId; return BadAlloc; } return Success; } int __glXDisp_CreateContext(__GLXclientState * cl, GLbyte * pc) { xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; __GLXconfig *config; __GLXscreen *pGlxScreen; int err; if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) return err; if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) return err; return DoCreateContext(cl, req->context, req->shareList, config, pGlxScreen, req->isDirect); } int __glXDisp_CreateNewContext(__GLXclientState * cl, GLbyte * pc) { xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; __GLXconfig *config; __GLXscreen *pGlxScreen; int err; if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) return err; if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) return err; return DoCreateContext(cl, req->context, req->shareList, config, pGlxScreen, req->isDirect); } int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; __GLXconfig *config; __GLXscreen *pGlxScreen; int err; REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq); if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) return err; if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) return err; return DoCreateContext(cl, req->context, req->shareList, config, pGlxScreen, req->isDirect); } int __glXDisp_DestroyContext(__GLXclientState * cl, GLbyte * pc) { xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; __GLXcontext *glxc; int err; if (!validGlxContext(cl->client, req->context, DixDestroyAccess, &glxc, &err)) return err; glxc->idExists = GL_FALSE; if (glxc->currentClient) { XID ghost = FakeClientID(glxc->currentClient->index); if (!AddResource(ghost, __glXContextRes, glxc)) return BadAlloc; ChangeResourceValue(glxc->id, __glXContextRes, NULL); glxc->id = ghost; } FreeResourceByType(req->context, __glXContextRes, FALSE); return Success; } __GLXcontext * __glXLookupContextByTag(__GLXclientState * cl, GLXContextTag tag) { return glxServer.getContextTagPrivate(cl->client, tag); } static __GLXconfig * inferConfigForWindow(__GLXscreen *pGlxScreen, WindowPtr pWin) { int i, vid = wVisual(pWin); for (i = 0; i < pGlxScreen->numVisuals; i++) if (pGlxScreen->visuals[i]->visualID == vid) return pGlxScreen->visuals[i]; return NULL; } /** * This is a helper function to handle the legacy (pre GLX 1.3) cases * where passing an X window to glXMakeCurrent is valid. Given a * resource ID, look up the GLX drawable if available, otherwise, make * sure it's an X window and create a GLX drawable one the fly. */ static __GLXdrawable * __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client, int *error) { DrawablePtr pDraw; __GLXdrawable *pGlxDraw; __GLXconfig *config; __GLXscreen *pGlxScreen; int rc; rc = dixLookupResourceByType((void **)&pGlxDraw, drawId, __glXDrawableRes, client, DixWriteAccess); if (rc == Success && /* If pGlxDraw->drawId == drawId, drawId is a valid GLX drawable. * Otherwise, if pGlxDraw->type == GLX_DRAWABLE_WINDOW, drawId is * an X window, but the client has already created a GLXWindow * associated with it, so we don't want to create another one. */ (pGlxDraw->drawId == drawId || pGlxDraw->type == GLX_DRAWABLE_WINDOW)) { if (glxc != NULL && glxc->config != NULL && glxc->config != pGlxDraw->config) { client->errorValue = drawId; *error = BadMatch; return NULL; } return pGlxDraw; } /* No active context and an unknown drawable, bail. */ if (glxc == NULL) { client->errorValue = drawId; *error = BadMatch; return NULL; } /* The drawId wasn't a GLX drawable. Make sure it's a window and * create a GLXWindow for it. Check that the drawable screen * matches the context screen and that the context fbconfig is * compatible with the window visual. */ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); if (rc != Success || pDraw->type != DRAWABLE_WINDOW) { client->errorValue = drawId; *error = __glXError(GLXBadDrawable); return NULL; } pGlxScreen = glxc->pGlxScreen; if (pDraw->pScreen != pGlxScreen->pScreen) { client->errorValue = pDraw->pScreen->myNum; *error = BadMatch; return NULL; } config = glxc->config; if (!config) config = inferConfigForWindow(pGlxScreen, (WindowPtr)pDraw); if (!config) { /* * If we get here, we've tried to bind a no-config context to a * window without a corresponding fbconfig, presumably because * we don't support GL on it (PseudoColor perhaps). From GLX Section * 3.3.7 "Rendering Contexts": * * "If draw or read are not compatible with ctx a BadMatch error * is generated." */ *error = BadMatch; return NULL; } if (!validGlxFBConfigForWindow(client, config, pDraw, error)) return NULL; pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, drawId, GLX_DRAWABLE_WINDOW, drawId, config); if (!pGlxDraw) { *error = BadAlloc; return NULL; } /* since we are creating the drawablePrivate, drawId should be new */ if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { *error = BadAlloc; return NULL; } return pGlxDraw; } /*****************************************************************************/ /* ** Make an OpenGL context and drawable current. */ int xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId, XID contextId, GLXContextTag newContextTag) { __GLXclientState *cl = glxGetClient(client); __GLXcontext *glxc = NULL, *prevglxc = NULL; __GLXdrawable *drawPriv = NULL; __GLXdrawable *readPriv = NULL; int error; /* Drawables but no context makes no sense */ if (!contextId && (drawId || readId)) return BadMatch; /* If either drawable is null, the other must be too */ if ((drawId == None) != (readId == None)) return BadMatch; /* Look up old context. If we have one, it must be in a usable state. */ if (tag != 0) { prevglxc = glxServer.getContextTagPrivate(client, tag); if (prevglxc && prevglxc->renderMode != GL_RENDER) { /* Oops. Not in render mode render. */ client->errorValue = prevglxc->id; return __glXError(GLXBadContextState); } } /* Look up new context. It must not be current for someone else. */ if (contextId != None) { int status; if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error)) return error; if ((glxc != prevglxc) && glxc->currentClient) return BadAccess; if (drawId) { drawPriv = __glXGetDrawable(glxc, drawId, client, &status); if (drawPriv == NULL) return status; } if (readId) { readPriv = __glXGetDrawable(glxc, readId, client, &status); if (readPriv == NULL) return status; } } if (prevglxc) { /* Flush the previous context if needed. */ Bool need_flush = !prevglxc->isDirect; #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB if (prevglxc->releaseBehavior == GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB) need_flush = GL_FALSE; #endif if (need_flush) { if (!__glXForceCurrent(cl, tag, (int *) &error)) return error; glFlush(); } /* Make the previous context not current. */ if (!(*prevglxc->loseCurrent) (prevglxc)) return __glXError(GLXBadContext); lastGLContext = NULL; if (!prevglxc->isDirect) { prevglxc->drawPriv = NULL; prevglxc->readPriv = NULL; } } if (glxc && !glxc->isDirect) { glxc->drawPriv = drawPriv; glxc->readPriv = readPriv; /* make the context current */ lastGLContext = glxc; if (!(*glxc->makeCurrent) (glxc)) { lastGLContext = NULL; glxc->drawPriv = NULL; glxc->readPriv = NULL; return __glXError(GLXBadContext); } } glxServer.setContextTagPrivate(client, newContextTag, glxc); if (glxc) glxc->currentClient = client; if (prevglxc) { prevglxc->currentClient = NULL; if (!prevglxc->idExists) { FreeResourceByType(prevglxc->id, __glXContextRes, FALSE); } } return Success; } int __glXDisp_MakeCurrent(__GLXclientState * cl, GLbyte * pc) { return BadImplementation; } int __glXDisp_MakeContextCurrent(__GLXclientState * cl, GLbyte * pc) { return BadImplementation; } int __glXDisp_MakeCurrentReadSGI(__GLXclientState * cl, GLbyte * pc) { return BadImplementation; } int __glXDisp_IsDirect(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; xGLXIsDirectReply reply; __GLXcontext *glxc; int err; if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err)) return err; reply = (xGLXIsDirectReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .isDirect = glxc->isDirect }; if (client->swapped) { __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); } WriteToClient(client, sz_xGLXIsDirectReply, &reply); return Success; } int __glXDisp_QueryVersion(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; xGLXQueryVersionReply reply; GLuint major, minor; REQUEST_SIZE_MATCH(xGLXQueryVersionReq); major = req->majorVersion; minor = req->minorVersion; (void) major; (void) minor; /* ** Server should take into consideration the version numbers sent by the ** client if it wants to work with older clients; however, in this ** implementation the server just returns its version number. */ reply = (xGLXQueryVersionReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .majorVersion = SERVER_GLX_MAJOR_VERSION, .minorVersion = SERVER_GLX_MINOR_VERSION }; if (client->swapped) { __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.majorVersion); __GLX_SWAP_INT(&reply.minorVersion); } WriteToClient(client, sz_xGLXQueryVersionReply, &reply); return Success; } int __glXDisp_WaitGL(__GLXclientState * cl, GLbyte * pc) { xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc; GLXContextTag tag; __GLXcontext *glxc = NULL; int error; tag = req->contextTag; if (tag) { glxc = __glXLookupContextByTag(cl, tag); if (!glxc) return __glXError(GLXBadContextTag); if (!__glXForceCurrent(cl, req->contextTag, &error)) return error; glFinish(); } if (glxc && glxc->drawPriv->waitGL) (*glxc->drawPriv->waitGL) (glxc->drawPriv); return Success; } int __glXDisp_WaitX(__GLXclientState * cl, GLbyte * pc) { xGLXWaitXReq *req = (xGLXWaitXReq *) pc; GLXContextTag tag; __GLXcontext *glxc = NULL; int error; tag = req->contextTag; if (tag) { glxc = __glXLookupContextByTag(cl, tag); if (!glxc) return __glXError(GLXBadContextTag); if (!__glXForceCurrent(cl, req->contextTag, &error)) return error; } if (glxc && glxc->drawPriv->waitX) (*glxc->drawPriv->waitX) (glxc->drawPriv); return Success; } int __glXDisp_CopyContext(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; GLXContextID source; GLXContextID dest; GLXContextTag tag; unsigned long mask; __GLXcontext *src, *dst; int error; source = req->source; dest = req->dest; tag = req->contextTag; mask = req->mask; if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error)) return error; if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error)) return error; /* ** They must be in the same address space, and same screen. ** NOTE: no support for direct rendering contexts here. */ if (src->isDirect || dst->isDirect || (src->pGlxScreen != dst->pGlxScreen)) { client->errorValue = source; return BadMatch; } /* ** The destination context must not be current for any client. */ if (dst->currentClient) { client->errorValue = dest; return BadAccess; } if (tag) { __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag); if (!tagcx) { return __glXError(GLXBadContextTag); } if (tagcx != src) { /* ** This would be caused by a faulty implementation of the client ** library. */ return BadMatch; } /* ** In this case, glXCopyContext is in both GL and X streams, in terms ** of sequentiality. */ if (__glXForceCurrent(cl, tag, &error)) { /* ** Do whatever is needed to make sure that all preceding requests ** in both streams are completed before the copy is executed. */ glFinish(); } else { return error; } } /* ** Issue copy. The only reason for failure is a bad mask. */ if (!(*dst->copy) (dst, src, mask)) { client->errorValue = mask; return BadValue; } return Success; } enum { GLX_VIS_CONFIG_UNPAIRED = 18, GLX_VIS_CONFIG_PAIRED = 22 }; enum { GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED }; int __glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc) { xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; ClientPtr client = cl->client; xGLXGetVisualConfigsReply reply; __GLXscreen *pGlxScreen; __GLXconfig *modes; CARD32 buf[GLX_VIS_CONFIG_TOTAL]; int p, i, err; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) return err; reply = (xGLXGetVisualConfigsReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = (pGlxScreen->numVisuals * __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2, .numVisuals = pGlxScreen->numVisuals, .numProps = GLX_VIS_CONFIG_TOTAL }; if (client->swapped) { __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.numVisuals); __GLX_SWAP_INT(&reply.numProps); } WriteToClient(client, sz_xGLXGetVisualConfigsReply, &reply); for (i = 0; i < pGlxScreen->numVisuals; i++) { modes = pGlxScreen->visuals[i]; p = 0; buf[p++] = modes->visualID; buf[p++] = glxConvertToXVisualType(modes->visualType); buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE; buf[p++] = modes->redBits; buf[p++] = modes->greenBits; buf[p++] = modes->blueBits; buf[p++] = modes->alphaBits; buf[p++] = modes->accumRedBits; buf[p++] = modes->accumGreenBits; buf[p++] = modes->accumBlueBits; buf[p++] = modes->accumAlphaBits; buf[p++] = modes->doubleBufferMode; buf[p++] = modes->stereoMode; buf[p++] = modes->rgbBits; buf[p++] = modes->depthBits; buf[p++] = modes->stencilBits; buf[p++] = modes->numAuxBuffers; buf[p++] = modes->level; assert(p == GLX_VIS_CONFIG_UNPAIRED); /* ** Add token/value pairs for extensions. */ buf[p++] = GLX_VISUAL_CAVEAT_EXT; buf[p++] = modes->visualRating; buf[p++] = GLX_TRANSPARENT_TYPE; buf[p++] = modes->transparentPixel; buf[p++] = GLX_TRANSPARENT_RED_VALUE; buf[p++] = modes->transparentRed; buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; buf[p++] = modes->transparentGreen; buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; buf[p++] = modes->transparentBlue; buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; buf[p++] = modes->transparentAlpha; buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; buf[p++] = modes->transparentIndex; buf[p++] = GLX_SAMPLES_SGIS; buf[p++] = modes->samples; buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; buf[p++] = modes->sampleBuffers; buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; buf[p++] = modes->visualSelectGroup; /* Add attribute only if its value is not default. */ if (modes->sRGBCapable != GL_FALSE) { buf[p++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT; buf[p++] = modes->sRGBCapable; } /* Pad with zeroes, so that attributes count is constant. */ while (p < GLX_VIS_CONFIG_TOTAL) { buf[p++] = 0; buf[p++] = 0; } assert(p == GLX_VIS_CONFIG_TOTAL); if (client->swapped) { __GLX_SWAP_INT_ARRAY(buf, p); } WriteToClient(client, __GLX_SIZE_CARD32 * p, buf); } return Success; } #define __GLX_TOTAL_FBCONFIG_ATTRIBS (44) #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) /** * Send the set of GLXFBConfigs to the client. There is not currently * and interface into the driver on the server-side to get GLXFBConfigs, * so we "invent" some based on the \c __GLXvisualConfig structures that * the driver does supply. * * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX * is the same, so this routine pulls double duty. */ static int DoGetFBConfigs(__GLXclientState * cl, unsigned screen) { ClientPtr client = cl->client; xGLXGetFBConfigsReply reply; __GLXscreen *pGlxScreen; CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH]; int p, err; __GLXconfig *modes; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err)) return err; reply = (xGLXGetFBConfigsReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = __GLX_FBCONFIG_ATTRIBS_LENGTH * pGlxScreen->numFBConfigs, .numFBConfigs = pGlxScreen->numFBConfigs, .numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS }; if (client->swapped) { __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.numFBConfigs); __GLX_SWAP_INT(&reply.numAttribs); } WriteToClient(client, sz_xGLXGetFBConfigsReply, &reply); for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) { p = 0; #define WRITE_PAIR(tag,value) \ do { buf[p++] = tag ; buf[p++] = value ; } while( 0 ) WRITE_PAIR(GLX_VISUAL_ID, modes->visualID); WRITE_PAIR(GLX_FBCONFIG_ID, modes->fbconfigID); WRITE_PAIR(GLX_X_RENDERABLE, (modes->drawableType & (GLX_WINDOW_BIT | GLX_PIXMAP_BIT) ? GL_TRUE : GL_FALSE)); WRITE_PAIR(GLX_RGBA, (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE); WRITE_PAIR(GLX_RENDER_TYPE, modes->renderType); WRITE_PAIR(GLX_DOUBLEBUFFER, modes->doubleBufferMode); WRITE_PAIR(GLX_STEREO, modes->stereoMode); WRITE_PAIR(GLX_BUFFER_SIZE, modes->rgbBits); WRITE_PAIR(GLX_LEVEL, modes->level); WRITE_PAIR(GLX_AUX_BUFFERS, modes->numAuxBuffers); WRITE_PAIR(GLX_RED_SIZE, modes->redBits); WRITE_PAIR(GLX_GREEN_SIZE, modes->greenBits); WRITE_PAIR(GLX_BLUE_SIZE, modes->blueBits); WRITE_PAIR(GLX_ALPHA_SIZE, modes->alphaBits); WRITE_PAIR(GLX_ACCUM_RED_SIZE, modes->accumRedBits); WRITE_PAIR(GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits); WRITE_PAIR(GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits); WRITE_PAIR(GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits); WRITE_PAIR(GLX_DEPTH_SIZE, modes->depthBits); WRITE_PAIR(GLX_STENCIL_SIZE, modes->stencilBits); WRITE_PAIR(GLX_X_VISUAL_TYPE, modes->visualType); WRITE_PAIR(GLX_CONFIG_CAVEAT, modes->visualRating); WRITE_PAIR(GLX_TRANSPARENT_TYPE, modes->transparentPixel); WRITE_PAIR(GLX_TRANSPARENT_RED_VALUE, modes->transparentRed); WRITE_PAIR(GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen); WRITE_PAIR(GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue); WRITE_PAIR(GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha); WRITE_PAIR(GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex); WRITE_PAIR(GLX_SWAP_METHOD_OML, modes->swapMethod); WRITE_PAIR(GLX_SAMPLES_SGIS, modes->samples); WRITE_PAIR(GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers); WRITE_PAIR(GLX_VISUAL_SELECT_GROUP_SGIX, modes->visualSelectGroup); WRITE_PAIR(GLX_DRAWABLE_TYPE, modes->drawableType); WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb); WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba); WRITE_PAIR(GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture); WRITE_PAIR(GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets); /* can't report honestly until mesa is fixed */ WRITE_PAIR(GLX_Y_INVERTED_EXT, GLX_DONT_CARE); if (modes->drawableType & GLX_PBUFFER_BIT) { WRITE_PAIR(GLX_MAX_PBUFFER_WIDTH, modes->maxPbufferWidth); WRITE_PAIR(GLX_MAX_PBUFFER_HEIGHT, modes->maxPbufferHeight); WRITE_PAIR(GLX_MAX_PBUFFER_PIXELS, modes->maxPbufferPixels); WRITE_PAIR(GLX_OPTIMAL_PBUFFER_WIDTH_SGIX, modes->optimalPbufferWidth); WRITE_PAIR(GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX, modes->optimalPbufferHeight); } /* Add attribute only if its value is not default. */ if (modes->sRGBCapable != GL_FALSE) { WRITE_PAIR(GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, modes->sRGBCapable); } /* Pad the remaining place with zeroes, so that attributes count is constant. */ while (p < __GLX_FBCONFIG_ATTRIBS_LENGTH) { WRITE_PAIR(0, 0); } assert(p == __GLX_FBCONFIG_ATTRIBS_LENGTH); if (client->swapped) { __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH); } WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH, (char *) buf); } return Success; } int __glXDisp_GetFBConfigs(__GLXclientState * cl, GLbyte * pc) { xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; return DoGetFBConfigs(cl, req->screen); } int __glXDisp_GetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc; /* work around mesa bug, don't use REQUEST_SIZE_MATCH */ REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq); return DoGetFBConfigs(cl, req->screen); } GLboolean __glXDrawableInit(__GLXdrawable * drawable, __GLXscreen * screen, DrawablePtr pDraw, int type, XID drawId, __GLXconfig * config) { drawable->pDraw = pDraw; drawable->type = type; drawable->drawId = drawId; drawable->config = config; drawable->eventMask = 0; return GL_TRUE; } void __glXDrawableRelease(__GLXdrawable * drawable) { } static int DoCreateGLXDrawable(ClientPtr client, __GLXscreen * pGlxScreen, __GLXconfig * config, DrawablePtr pDraw, XID drawableId, XID glxDrawableId, int type) { __GLXdrawable *pGlxDraw; if (pGlxScreen->pScreen != pDraw->pScreen) return BadMatch; pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, drawableId, type, glxDrawableId, config); if (pGlxDraw == NULL) return BadAlloc; if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) return BadAlloc; /* * Windows aren't refcounted, so track both the X and the GLX window * so we get called regardless of destruction order. */ if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW && !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) return BadAlloc; return Success; } static int DoCreateGLXPixmap(ClientPtr client, __GLXscreen * pGlxScreen, __GLXconfig * config, XID drawableId, XID glxDrawableId) { DrawablePtr pDraw; int err; err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess); if (err != Success) { client->errorValue = drawableId; return err; } if (pDraw->type != DRAWABLE_PIXMAP) { client->errorValue = drawableId; return BadPixmap; } err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId, glxDrawableId, GLX_DRAWABLE_PIXMAP); if (err == Success) ((PixmapPtr) pDraw)->refcnt++; return err; } static void determineTextureTarget(ClientPtr client, XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs) { GLenum target = 0; GLenum format = 0; int i, err; __GLXdrawable *pGlxDraw; if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP, DixWriteAccess, &pGlxDraw, &err)) /* We just added it in CreatePixmap, so we should never get here. */ return; for (i = 0; i < numAttribs; i++) { if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) { switch (attribs[2 * i + 1]) { case GLX_TEXTURE_2D_EXT: target = GL_TEXTURE_2D; break; case GLX_TEXTURE_RECTANGLE_EXT: target = GL_TEXTURE_RECTANGLE_ARB; break; } } if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT) format = attribs[2 * i + 1]; } if (!target) { int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height; if (h & (h - 1) || w & (w - 1)) target = GL_TEXTURE_RECTANGLE_ARB; else target = GL_TEXTURE_2D; } pGlxDraw->target = target; pGlxDraw->format = format; } int __glXDisp_CreateGLXPixmap(__GLXclientState * cl, GLbyte * pc) { xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; __GLXconfig *config; __GLXscreen *pGlxScreen; int err; if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) return err; if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) return err; return DoCreateGLXPixmap(cl->client, pGlxScreen, config, req->pixmap, req->glxpixmap); } int __glXDisp_CreatePixmap(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; __GLXconfig *config; __GLXscreen *pGlxScreen; int err; REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq); if (req->numAttribs > (UINT32_MAX >> 3)) { client->errorValue = req->numAttribs; return BadValue; } REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3); if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) return err; if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) return err; err = DoCreateGLXPixmap(cl->client, pGlxScreen, config, req->pixmap, req->glxpixmap); if (err != Success) return err; determineTextureTarget(cl->client, req->glxpixmap, (CARD32 *) (req + 1), req->numAttribs); return Success; } int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreateGLXPixmapWithConfigSGIXReq *req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; __GLXconfig *config; __GLXscreen *pGlxScreen; int err; REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq); if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) return err; if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) return err; return DoCreateGLXPixmap(cl->client, pGlxScreen, config, req->pixmap, req->glxpixmap); } static int DoDestroyDrawable(__GLXclientState * cl, XID glxdrawable, int type) { __GLXdrawable *pGlxDraw; int err; if (!validGlxDrawable(cl->client, glxdrawable, type, DixDestroyAccess, &pGlxDraw, &err)) return err; FreeResource(glxdrawable, FALSE); return Success; } int __glXDisp_DestroyGLXPixmap(__GLXclientState * cl, GLbyte * pc) { xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP); } int __glXDisp_DestroyPixmap(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc; /* should be REQUEST_SIZE_MATCH, but mesa's glXDestroyPixmap used to set * length to 3 instead of 2 */ REQUEST_AT_LEAST_SIZE(xGLXDestroyPixmapReq); return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP); } static int DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, int width, int height, XID glxDrawableId) { __GLXconfig *config; __GLXscreen *pGlxScreen; PixmapPtr pPixmap; int err; if (!validGlxScreen(client, screenNum, &pGlxScreen, &err)) return err; if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err)) return err; pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen, width, height, config->rgbBits, 0); if (!pPixmap) return BadAlloc; /* Assign the pixmap the same id as the pbuffer and add it as a * resource so it and the DRI2 drawable will be reclaimed when the * pbuffer is destroyed. */ pPixmap->drawable.id = glxDrawableId; if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap)) return BadAlloc; return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, glxDrawableId, glxDrawableId, GLX_DRAWABLE_PBUFFER); } int __glXDisp_CreatePbuffer(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc; CARD32 *attrs; int width, height, i; REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq); if (req->numAttribs > (UINT32_MAX >> 3)) { client->errorValue = req->numAttribs; return BadValue; } REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3); attrs = (CARD32 *) (req + 1); width = 0; height = 0; for (i = 0; i < req->numAttribs; i++) { switch (attrs[i * 2]) { case GLX_PBUFFER_WIDTH: width = attrs[i * 2 + 1]; break; case GLX_PBUFFER_HEIGHT: height = attrs[i * 2 + 1]; break; case GLX_LARGEST_PBUFFER: /* FIXME: huh... */ break; } } return DoCreatePbuffer(cl->client, req->screen, req->fbconfig, width, height, req->pbuffer); } int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc; REQUEST_AT_LEAST_SIZE(xGLXCreateGLXPbufferSGIXReq); /* * We should really handle attributes correctly, but this extension * is so rare I have difficulty caring. */ return DoCreatePbuffer(cl->client, req->screen, req->fbconfig, req->width, req->height, req->pbuffer); } int __glXDisp_DestroyPbuffer(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq); return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER); } int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc; REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq); return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER); } static int DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable, int numAttribs, CARD32 *attribs) { __GLXdrawable *pGlxDraw; int i, err; if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY, DixSetAttrAccess, &pGlxDraw, &err)) return err; for (i = 0; i < numAttribs; i++) { switch (attribs[i * 2]) { case GLX_EVENT_MASK: /* All we do is to record the event mask so we can send it * back when queried. We never actually clobber the * pbuffers, so we never need to send out the event. */ pGlxDraw->eventMask = attribs[i * 2 + 1]; break; } } return Success; } int __glXDisp_ChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *) pc; REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq); if (req->numAttribs > (UINT32_MAX >> 3)) { client->errorValue = req->numAttribs; return BadValue; } #if 0 /* mesa sends an additional 8 bytes */ REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3); #else if (((sizeof(xGLXChangeDrawableAttributesReq) + (req->numAttribs << 3)) >> 2) < client->req_len) return BadLength; #endif return DoChangeDrawableAttributes(cl->client, req->drawable, req->numAttribs, (CARD32 *) (req + 1)); } int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXChangeDrawableAttributesSGIXReq *req = (xGLXChangeDrawableAttributesSGIXReq *) pc; REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq); if (req->numAttribs > (UINT32_MAX >> 3)) { client->errorValue = req->numAttribs; return BadValue; } REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq, req->numAttribs << 3); return DoChangeDrawableAttributes(cl->client, req->drawable, req->numAttribs, (CARD32 *) (req + 1)); } int __glXDisp_CreateWindow(__GLXclientState * cl, GLbyte * pc) { xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; __GLXconfig *config; __GLXscreen *pGlxScreen; ClientPtr client = cl->client; DrawablePtr pDraw; int err; REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq); if (req->numAttribs > (UINT32_MAX >> 3)) { client->errorValue = req->numAttribs; return BadValue; } REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3); if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) return err; if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err)) return err; err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess); if (err != Success || pDraw->type != DRAWABLE_WINDOW) { client->errorValue = req->window; return BadWindow; } if (!validGlxFBConfigForWindow(client, config, pDraw, &err)) return err; return DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, req->window, req->glxwindow, GLX_DRAWABLE_WINDOW); } int __glXDisp_DestroyWindow(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; /* mesa's glXDestroyWindow used to set length to 3 instead of 2 */ REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq); return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW); } /*****************************************************************************/ /* ** NOTE: There is no portable implementation for swap buffers as of ** this time that is of value. Consequently, this code must be ** implemented by somebody other than SGI. */ int __glXDisp_SwapBuffers(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; GLXContextTag tag; XID drawId; __GLXcontext *glxc = NULL; __GLXdrawable *pGlxDraw; int error; tag = req->contextTag; drawId = req->drawable; if (tag) { glxc = __glXLookupContextByTag(cl, tag); if (!glxc) { return __glXError(GLXBadContextTag); } /* ** The calling thread is swapping its current drawable. In this case, ** glxSwapBuffers is in both GL and X streams, in terms of ** sequentiality. */ if (__glXForceCurrent(cl, tag, &error)) { /* ** Do whatever is needed to make sure that all preceding requests ** in both streams are completed before the swap is executed. */ glFinish(); } else { return error; } } pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error); if (pGlxDraw == NULL) return error; if (pGlxDraw->type == DRAWABLE_WINDOW && (*pGlxDraw->swapBuffers) (cl->client, pGlxDraw) == GL_FALSE) return __glXError(GLXBadDrawable); return Success; } static int DoQueryContext(__GLXclientState * cl, GLXContextID gcId) { ClientPtr client = cl->client; __GLXcontext *ctx; xGLXQueryContextInfoEXTReply reply; int nProps = 5; int sendBuf[nProps * 2]; int nReplyBytes; int err; if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err)) return err; reply = (xGLXQueryContextInfoEXTReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = nProps << 1, .n = nProps }; nReplyBytes = reply.length << 2; sendBuf[0] = GLX_SHARE_CONTEXT_EXT; sendBuf[1] = (int) (ctx->share_id); sendBuf[2] = GLX_VISUAL_ID_EXT; sendBuf[3] = (int) (ctx->config ? ctx->config->visualID : 0); sendBuf[4] = GLX_SCREEN_EXT; sendBuf[5] = (int) (ctx->pGlxScreen->pScreen->myNum); sendBuf[6] = GLX_FBCONFIG_ID; sendBuf[7] = (int) (ctx->config ? ctx->config->fbconfigID : 0); sendBuf[8] = GLX_RENDER_TYPE; sendBuf[9] = (int) (ctx->config ? ctx->config->renderType : GLX_DONT_CARE); if (client->swapped) { int length = reply.length; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.n); WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply); __GLX_SWAP_INT_ARRAY((int *) sendBuf, length); WriteToClient(client, length << 2, sendBuf); } else { WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply); WriteToClient(client, nReplyBytes, sendBuf); } return Success; } int __glXDisp_QueryContextInfoEXT(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc; REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq); return DoQueryContext(cl, req->context); } int __glXDisp_QueryContext(__GLXclientState * cl, GLbyte * pc) { xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc; return DoQueryContext(cl, req->context); } int __glXDisp_BindTexImageEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; ClientPtr client = cl->client; __GLXcontext *context; __GLXdrawable *pGlxDraw; GLXDrawable drawId; int buffer; int error; CARD32 num_attribs; if ((sizeof(xGLXVendorPrivateReq) + 12) >> 2 > client->req_len) return BadLength; pc += __GLX_VENDPRIV_HDR_SIZE; drawId = *((CARD32 *) (pc)); buffer = *((INT32 *) (pc + 4)); num_attribs = *((CARD32 *) (pc + 8)); if (num_attribs > (UINT32_MAX >> 3)) { client->errorValue = num_attribs; return BadValue; } REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 12 + (num_attribs << 3)); if (buffer != GLX_FRONT_LEFT_EXT) return __glXError(GLXBadPixmap); context = __glXForceCurrent(cl, req->contextTag, &error); if (!context) return error; if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, DixReadAccess, &pGlxDraw, &error)) return error; if (!context->bindTexImage) return __glXError(GLXUnsupportedPrivateRequest); return context->bindTexImage(context, buffer, pGlxDraw); } int __glXDisp_ReleaseTexImageEXT(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; ClientPtr client = cl->client; __GLXdrawable *pGlxDraw; __GLXcontext *context; GLXDrawable drawId; int buffer; int error; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); pc += __GLX_VENDPRIV_HDR_SIZE; drawId = *((CARD32 *) (pc)); buffer = *((INT32 *) (pc + 4)); context = __glXForceCurrent(cl, req->contextTag, &error); if (!context) return error; if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, DixReadAccess, &pGlxDraw, &error)) return error; if (!context->releaseTexImage) return __glXError(GLXUnsupportedPrivateRequest); return context->releaseTexImage(context, buffer, pGlxDraw); } int __glXDisp_CopySubBufferMESA(__GLXclientState * cl, GLbyte * pc) { xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; GLXContextTag tag = req->contextTag; __GLXcontext *glxc = NULL; __GLXdrawable *pGlxDraw; ClientPtr client = cl->client; GLXDrawable drawId; int error; int x, y, width, height; (void) client; (void) req; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20); pc += __GLX_VENDPRIV_HDR_SIZE; drawId = *((CARD32 *) (pc)); x = *((INT32 *) (pc + 4)); y = *((INT32 *) (pc + 8)); width = *((INT32 *) (pc + 12)); height = *((INT32 *) (pc + 16)); if (tag) { glxc = __glXLookupContextByTag(cl, tag); if (!glxc) { return __glXError(GLXBadContextTag); } /* ** The calling thread is swapping its current drawable. In this case, ** glxSwapBuffers is in both GL and X streams, in terms of ** sequentiality. */ if (__glXForceCurrent(cl, tag, &error)) { /* ** Do whatever is needed to make sure that all preceding requests ** in both streams are completed before the swap is executed. */ glFinish(); } else { return error; } } pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error); if (!pGlxDraw) return error; if (pGlxDraw == NULL || pGlxDraw->type != GLX_DRAWABLE_WINDOW || pGlxDraw->copySubBuffer == NULL) return __glXError(GLXBadDrawable); (*pGlxDraw->copySubBuffer) (pGlxDraw, x, y, width, height); return Success; } /* hack for old glxext.h */ #ifndef GLX_STEREO_TREE_EXT #define GLX_STEREO_TREE_EXT 0x20F5 #endif /* ** Get drawable attributes */ static int DoGetDrawableAttributes(__GLXclientState * cl, XID drawId) { ClientPtr client = cl->client; xGLXGetDrawableAttributesReply reply; __GLXdrawable *pGlxDraw = NULL; DrawablePtr pDraw; CARD32 attributes[18]; int num = 0, error; if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, DixGetAttrAccess, &pGlxDraw, &error)) { /* hack for GLX 1.2 naked windows */ int err = dixLookupWindow((WindowPtr *)&pDraw, drawId, client, DixGetAttrAccess); if (err != Success) return error; } if (pGlxDraw) pDraw = pGlxDraw->pDraw; #define ATTRIB(a, v) do { \ attributes[2*num] = (a); \ attributes[2*num+1] = (v); \ num++; \ } while (0) ATTRIB(GLX_Y_INVERTED_EXT, GL_FALSE); ATTRIB(GLX_WIDTH, pDraw->width); ATTRIB(GLX_HEIGHT, pDraw->height); ATTRIB(GLX_SCREEN, pDraw->pScreen->myNum); if (pGlxDraw) { ATTRIB(GLX_TEXTURE_TARGET_EXT, pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT : GLX_TEXTURE_RECTANGLE_EXT); ATTRIB(GLX_EVENT_MASK, pGlxDraw->eventMask); ATTRIB(GLX_FBCONFIG_ID, pGlxDraw->config->fbconfigID); if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) { ATTRIB(GLX_PRESERVED_CONTENTS, GL_TRUE); } if (pGlxDraw->type == GLX_DRAWABLE_WINDOW) { ATTRIB(GLX_STEREO_TREE_EXT, 0); } } #undef ATTRIB reply = (xGLXGetDrawableAttributesReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = num << 1, .numAttribs = num }; if (client->swapped) { int length = reply.length; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.numAttribs); WriteToClient(client, sz_xGLXGetDrawableAttributesReply, &reply); __GLX_SWAP_INT_ARRAY((int *) attributes, length); WriteToClient(client, length << 2, attributes); } else { WriteToClient(client, sz_xGLXGetDrawableAttributesReply, &reply); WriteToClient(client, reply.length * sizeof(CARD32), attributes); } return Success; } int __glXDisp_GetDrawableAttributes(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *) pc; /* this should be REQUEST_SIZE_MATCH, but mesa sends an additional 4 bytes */ REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq); return DoGetDrawableAttributes(cl, req->drawable); } int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXGetDrawableAttributesSGIXReq *req = (xGLXGetDrawableAttributesSGIXReq *) pc; REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq); return DoGetDrawableAttributes(cl, req->drawable); } /************************************************************************/ /* ** Render and Renderlarge are not in the GLX API. They are used by the GLX ** client library to send batches of GL rendering commands. */ /* ** Reset state used to keep track of large (multi-request) commands. */ static void ResetLargeCommandStatus(__GLXcontext *cx) { cx->largeCmdBytesSoFar = 0; cx->largeCmdBytesTotal = 0; cx->largeCmdRequestsSoFar = 0; cx->largeCmdRequestsTotal = 0; } /* ** Execute all the drawing commands in a request. */ int __glXDisp_Render(__GLXclientState * cl, GLbyte * pc) { xGLXRenderReq *req; ClientPtr client = cl->client; int left, cmdlen, error; int commandsDone; CARD16 opcode; __GLXrenderHeader *hdr; __GLXcontext *glxc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXRenderReq); req = (xGLXRenderReq *) pc; if (client->swapped) { __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->contextTag); } glxc = __glXForceCurrent(cl, req->contextTag, &error); if (!glxc) { return error; } commandsDone = 0; pc += sz_xGLXRenderReq; left = (req->length << 2) - sz_xGLXRenderReq; while (left > 0) { __GLXrenderSizeData entry; int extra = 0; __GLXdispatchRenderProcPtr proc; int err; if (left < sizeof(__GLXrenderHeader)) return BadLength; /* ** Verify that the header length and the overall length agree. ** Also, each command must be word aligned. */ hdr = (__GLXrenderHeader *) pc; if (client->swapped) { __GLX_SWAP_SHORT(&hdr->length); __GLX_SWAP_SHORT(&hdr->opcode); } cmdlen = hdr->length; opcode = hdr->opcode; if (left < cmdlen) return BadLength; /* ** Check for core opcodes and grab entry data. */ err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry); proc = (__GLXdispatchRenderProcPtr) __glXGetProtocolDecodeFunction(&Render_dispatch_info, opcode, client->swapped); if ((err < 0) || (proc == NULL)) { client->errorValue = commandsDone; return __glXError(GLXBadRenderRequest); } if (cmdlen < entry.bytes) { return BadLength; } if (entry.varsize) { /* variable size command */ extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE, client->swapped, left - __GLX_RENDER_HDR_SIZE); if (extra < 0) { return BadLength; } } if (cmdlen != safe_pad(safe_add(entry.bytes, extra))) { return BadLength; } /* ** Skip over the header and execute the command. We allow the ** caller to trash the command memory. This is useful especially ** for things that require double alignment - they can just shift ** the data towards lower memory (trashing the header) by 4 bytes ** and achieve the required alignment. */ (*proc) (pc + __GLX_RENDER_HDR_SIZE); pc += cmdlen; left -= cmdlen; commandsDone++; } return Success; } /* ** Execute a large rendering request (one that spans multiple X requests). */ int __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) { xGLXRenderLargeReq *req; ClientPtr client = cl->client; size_t dataBytes; __GLXrenderLargeHeader *hdr; __GLXcontext *glxc; int error; CARD16 opcode; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq); req = (xGLXRenderLargeReq *) pc; if (client->swapped) { __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->contextTag); __GLX_SWAP_INT(&req->dataBytes); __GLX_SWAP_SHORT(&req->requestNumber); __GLX_SWAP_SHORT(&req->requestTotal); } glxc = __glXForceCurrent(cl, req->contextTag, &error); if (!glxc) { return error; } if (safe_pad(req->dataBytes) < 0) return BadLength; dataBytes = req->dataBytes; /* ** Check the request length. */ if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) { client->errorValue = req->length; /* Reset in case this isn't 1st request. */ ResetLargeCommandStatus(glxc); return BadLength; } pc += sz_xGLXRenderLargeReq; if (glxc->largeCmdRequestsSoFar == 0) { __GLXrenderSizeData entry; int extra = 0; int left = (req->length << 2) - sz_xGLXRenderLargeReq; int cmdlen; int err; /* ** This is the first request of a multi request command. ** Make enough space in the buffer, then copy the entire request. */ if (req->requestNumber != 1) { client->errorValue = req->requestNumber; return __glXError(GLXBadLargeRequest); } if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE) return BadLength; hdr = (__GLXrenderLargeHeader *) pc; if (client->swapped) { __GLX_SWAP_INT(&hdr->length); __GLX_SWAP_INT(&hdr->opcode); } opcode = hdr->opcode; if ((cmdlen = safe_pad(hdr->length)) < 0) return BadLength; /* ** Check for core opcodes and grab entry data. */ err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry); if (err < 0) { client->errorValue = opcode; return __glXError(GLXBadLargeRequest); } if (entry.varsize) { /* ** If it's a variable-size command (a command whose length must ** be computed from its parameters), all the parameters needed ** will be in the 1st request, so it's okay to do this. */ extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE, client->swapped, left - __GLX_RENDER_LARGE_HDR_SIZE); if (extra < 0) { return BadLength; } } /* the +4 is safe because we know entry.bytes is small */ if (cmdlen != safe_pad(safe_add(entry.bytes + 4, extra))) { return BadLength; } /* ** Make enough space in the buffer, then copy the entire request. */ if (glxc->largeCmdBufSize < cmdlen) { GLbyte *newbuf = glxc->largeCmdBuf; if (!(newbuf = realloc(newbuf, cmdlen))) return BadAlloc; glxc->largeCmdBuf = newbuf; glxc->largeCmdBufSize = cmdlen; } memcpy(glxc->largeCmdBuf, pc, dataBytes); glxc->largeCmdBytesSoFar = dataBytes; glxc->largeCmdBytesTotal = cmdlen; glxc->largeCmdRequestsSoFar = 1; glxc->largeCmdRequestsTotal = req->requestTotal; return Success; } else { /* ** We are receiving subsequent (i.e. not the first) requests of a ** multi request command. */ int bytesSoFar; /* including this packet */ /* ** Check the request number and the total request count. */ if (req->requestNumber != glxc->largeCmdRequestsSoFar + 1) { client->errorValue = req->requestNumber; ResetLargeCommandStatus(glxc); return __glXError(GLXBadLargeRequest); } if (req->requestTotal != glxc->largeCmdRequestsTotal) { client->errorValue = req->requestTotal; ResetLargeCommandStatus(glxc); return __glXError(GLXBadLargeRequest); } /* ** Check that we didn't get too much data. */ if ((bytesSoFar = safe_add(glxc->largeCmdBytesSoFar, dataBytes)) < 0) { client->errorValue = dataBytes; ResetLargeCommandStatus(glxc); return __glXError(GLXBadLargeRequest); } if (bytesSoFar > glxc->largeCmdBytesTotal) { client->errorValue = dataBytes; ResetLargeCommandStatus(glxc); return __glXError(GLXBadLargeRequest); } memcpy(glxc->largeCmdBuf + glxc->largeCmdBytesSoFar, pc, dataBytes); glxc->largeCmdBytesSoFar += dataBytes; glxc->largeCmdRequestsSoFar++; if (req->requestNumber == glxc->largeCmdRequestsTotal) { __GLXdispatchRenderProcPtr proc; /* ** This is the last request; it must have enough bytes to complete ** the command. */ /* NOTE: the pad macro below is needed because the client library ** pads the total byte count, but not the per-request byte counts. ** The Protocol Encoding says the total byte count should not be ** padded, so a proposal will be made to the ARB to relax the ** padding constraint on the total byte count, thus preserving ** backward compatibility. Meanwhile, the padding done below ** fixes a bug that did not allow large commands of odd sizes to ** be accepted by the server. */ if (safe_pad(glxc->largeCmdBytesSoFar) != glxc->largeCmdBytesTotal) { client->errorValue = dataBytes; ResetLargeCommandStatus(glxc); return __glXError(GLXBadLargeRequest); } hdr = (__GLXrenderLargeHeader *) glxc->largeCmdBuf; /* ** The opcode and length field in the header had already been ** swapped when the first request was received. ** ** Use the opcode to index into the procedure table. */ opcode = hdr->opcode; proc = (__GLXdispatchRenderProcPtr) __glXGetProtocolDecodeFunction(&Render_dispatch_info, opcode, client->swapped); if (proc == NULL) { client->errorValue = opcode; return __glXError(GLXBadLargeRequest); } /* ** Skip over the header and execute the command. */ (*proc) (glxc->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE); /* ** Reset for the next RenderLarge series. */ ResetLargeCommandStatus(glxc); } else { /* ** This is neither the first nor the last request. */ } return Success; } } /************************************************************************/ /* ** No support is provided for the vendor-private requests other than ** allocating the entry points in the dispatch table. */ int __glXDisp_VendorPrivate(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; GLint vendorcode = req->vendorCode; __GLXdispatchVendorPrivProcPtr proc; REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); proc = (__GLXdispatchVendorPrivProcPtr) __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info, vendorcode, 0); if (proc != NULL) { return (*proc) (cl, (GLbyte *) req); } cl->client->errorValue = req->vendorCode; return __glXError(GLXUnsupportedPrivateRequest); } int __glXDisp_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; GLint vendorcode = req->vendorCode; __GLXdispatchVendorPrivProcPtr proc; REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); proc = (__GLXdispatchVendorPrivProcPtr) __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info, vendorcode, 0); if (proc != NULL) { return (*proc) (cl, (GLbyte *) req); } cl->client->errorValue = vendorcode; return __glXError(GLXUnsupportedPrivateRequest); } int __glXDisp_QueryExtensionsString(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; xGLXQueryExtensionsStringReply reply; __GLXscreen *pGlxScreen; size_t n, length; char *buf; int err; if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) return err; n = strlen(pGlxScreen->GLXextensions) + 1; length = __GLX_PAD(n) >> 2; reply = (xGLXQueryExtensionsStringReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = length, .n = n }; /* Allocate buffer to make sure it's a multiple of 4 bytes big. */ buf = calloc(length, 4); if (buf == NULL) return BadAlloc; memcpy(buf, pGlxScreen->GLXextensions, n); if (client->swapped) { __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.n); WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply); __GLX_SWAP_INT_ARRAY((int *) buf, length); WriteToClient(client, length << 2, buf); } else { WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply); WriteToClient(client, (int) (length << 2), buf); } free(buf); return Success; } #ifndef GLX_VENDOR_NAMES_EXT #define GLX_VENDOR_NAMES_EXT 0x20F6 #endif int __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; xGLXQueryServerStringReply reply; size_t n, length; const char *ptr; char *buf; __GLXscreen *pGlxScreen; int err; if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) return err; switch (req->name) { case GLX_VENDOR: ptr = GLXServerVendorName; break; case GLX_VERSION: ptr = "1.4"; break; case GLX_EXTENSIONS: ptr = pGlxScreen->GLXextensions; break; case GLX_VENDOR_NAMES_EXT: if (pGlxScreen->glvnd) { ptr = pGlxScreen->glvnd; break; } /* else fall through */ default: return BadValue; } n = strlen(ptr) + 1; length = __GLX_PAD(n) >> 2; reply = (xGLXQueryServerStringReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = length, .n = n }; buf = calloc(length, 4); if (buf == NULL) { return BadAlloc; } memcpy(buf, ptr, n); if (client->swapped) { __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.n); WriteToClient(client, sz_xGLXQueryServerStringReply, &reply); /** no swap is needed for an array of chars **/ /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */ WriteToClient(client, length << 2, buf); } else { WriteToClient(client, sz_xGLXQueryServerStringReply, &reply); WriteToClient(client, (int) (length << 2), buf); } free(buf); return Success; } int __glXDisp_ClientInfo(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; const char *buf; REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq); buf = (const char *) (req + 1); if (!memchr(buf, 0, (client->req_len << 2) - sizeof(xGLXClientInfoReq))) return BadLength; free(cl->GLClientextensions); cl->GLClientextensions = strdup(buf); return Success; } #include void __glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust, CARD64 msc, CARD32 sbc) { ClientPtr client = clients[CLIENT_ID(drawable->drawId)]; xGLXBufferSwapComplete2 wire = { .type = __glXEventBase + GLX_BufferSwapComplete }; if (!client) return; if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK)) return; wire.event_type = type; wire.drawable = drawable->drawId; wire.ust_hi = ust >> 32; wire.ust_lo = ust & 0xffffffff; wire.msc_hi = msc >> 32; wire.msc_lo = msc & 0xffffffff; wire.sbc = sbc; WriteEventsToClient(client, 1, (xEvent *) &wire); } #if PRESENT static void __glXpresentCompleteNotify(WindowPtr window, CARD8 present_kind, CARD8 present_mode, CARD32 serial, uint64_t ust, uint64_t msc) { __GLXdrawable *drawable; int glx_type; int rc; if (present_kind != PresentCompleteKindPixmap) return; rc = dixLookupResourceByType((void **) &drawable, window->drawable.id, __glXDrawableRes, serverClient, DixGetAttrAccess); if (rc != Success) return; if (present_mode == PresentCompleteModeFlip) glx_type = GLX_FLIP_COMPLETE_INTEL; else glx_type = GLX_BLIT_COMPLETE_INTEL; __glXsendSwapEvent(drawable, glx_type, ust, msc, serial); } #include void __glXregisterPresentCompleteNotify(void) { present_register_complete_notify(__glXpresentCompleteNotify); } #endif xorg-server-1.20.13/glx/glxcmdsswap.c0000644000175000017500000005177214100573756014400 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "glxserver.h" #include "glxutil.h" #include #include #include #include #include "glxext.h" #include "indirect_dispatch.h" #include "indirect_table.h" #include "indirect_util.h" /************************************************************************/ /* ** Byteswapping versions of GLX commands. In most cases they just swap ** the incoming arguments and then call the unswapped routine. For commands ** that have replies, a separate swapping routine for the reply is provided; ** it is called at the end of the unswapped routine. */ int __glXDispSwap_CreateContext(__GLXclientState * cl, GLbyte * pc) { xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->context); __GLX_SWAP_INT(&req->visual); __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->shareList); return __glXDisp_CreateContext(cl, pc); } int __glXDispSwap_CreateNewContext(__GLXclientState * cl, GLbyte * pc) { xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->context); __GLX_SWAP_INT(&req->fbconfig); __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->renderType); __GLX_SWAP_INT(&req->shareList); return __glXDisp_CreateNewContext(cl, pc); } int __glXDispSwap_CreateContextWithConfigSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq); __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->context); __GLX_SWAP_INT(&req->fbconfig); __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->renderType); __GLX_SWAP_INT(&req->shareList); return __glXDisp_CreateContextWithConfigSGIX(cl, pc); } int __glXDispSwap_DestroyContext(__GLXclientState * cl, GLbyte * pc) { xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->context); return __glXDisp_DestroyContext(cl, pc); } int __glXDispSwap_MakeCurrent(__GLXclientState * cl, GLbyte * pc) { return BadImplementation; } int __glXDispSwap_MakeContextCurrent(__GLXclientState * cl, GLbyte * pc) { return BadImplementation; } int __glXDispSwap_MakeCurrentReadSGI(__GLXclientState * cl, GLbyte * pc) { return BadImplementation; } int __glXDispSwap_IsDirect(__GLXclientState * cl, GLbyte * pc) { xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->context); return __glXDisp_IsDirect(cl, pc); } int __glXDispSwap_QueryVersion(__GLXclientState * cl, GLbyte * pc) { xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->majorVersion); __GLX_SWAP_INT(&req->minorVersion); return __glXDisp_QueryVersion(cl, pc); } int __glXDispSwap_WaitGL(__GLXclientState * cl, GLbyte * pc) { xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->contextTag); return __glXDisp_WaitGL(cl, pc); } int __glXDispSwap_WaitX(__GLXclientState * cl, GLbyte * pc) { xGLXWaitXReq *req = (xGLXWaitXReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->contextTag); return __glXDisp_WaitX(cl, pc); } int __glXDispSwap_CopyContext(__GLXclientState * cl, GLbyte * pc) { xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->source); __GLX_SWAP_INT(&req->dest); __GLX_SWAP_INT(&req->mask); return __glXDisp_CopyContext(cl, pc); } int __glXDispSwap_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc) { xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_INT(&req->screen); return __glXDisp_GetVisualConfigs(cl, pc); } int __glXDispSwap_GetFBConfigs(__GLXclientState * cl, GLbyte * pc) { xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_INT(&req->screen); return __glXDisp_GetFBConfigs(cl, pc); } int __glXDispSwap_GetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq); __GLX_SWAP_INT(&req->screen); return __glXDisp_GetFBConfigsSGIX(cl, pc); } int __glXDispSwap_CreateGLXPixmap(__GLXclientState * cl, GLbyte * pc) { xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->visual); __GLX_SWAP_INT(&req->pixmap); __GLX_SWAP_INT(&req->glxpixmap); return __glXDisp_CreateGLXPixmap(cl, pc); } int __glXDispSwap_CreatePixmap(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; CARD32 *attribs; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq); __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->fbconfig); __GLX_SWAP_INT(&req->pixmap); __GLX_SWAP_INT(&req->glxpixmap); __GLX_SWAP_INT(&req->numAttribs); if (req->numAttribs > (UINT32_MAX >> 3)) { client->errorValue = req->numAttribs; return BadValue; } REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3); attribs = (CARD32 *) (req + 1); __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); return __glXDisp_CreatePixmap(cl, pc); } int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreateGLXPixmapWithConfigSGIXReq *req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq); __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->fbconfig); __GLX_SWAP_INT(&req->pixmap); __GLX_SWAP_INT(&req->glxpixmap); return __glXDisp_CreateGLXPixmapWithConfigSGIX(cl, pc); } int __glXDispSwap_DestroyGLXPixmap(__GLXclientState * cl, GLbyte * pc) { xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->glxpixmap); return __glXDisp_DestroyGLXPixmap(cl, pc); } int __glXDispSwap_DestroyPixmap(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXDestroyGLXPixmapReq); __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->glxpixmap); return __glXDisp_DestroyGLXPixmap(cl, pc); } int __glXDispSwap_QueryContext(__GLXclientState * cl, GLbyte * pc) { xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_INT(&req->context); return __glXDisp_QueryContext(cl, pc); } int __glXDispSwap_CreatePbuffer(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; CARD32 *attribs; REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq); __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->fbconfig); __GLX_SWAP_INT(&req->pbuffer); __GLX_SWAP_INT(&req->numAttribs); if (req->numAttribs > (UINT32_MAX >> 3)) { client->errorValue = req->numAttribs; return BadValue; } REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3); attribs = (CARD32 *) (req + 1); __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); return __glXDisp_CreatePbuffer(cl, pc); } int __glXDispSwap_CreateGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXCreateGLXPbufferSGIXReq); __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->fbconfig); __GLX_SWAP_INT(&req->pbuffer); __GLX_SWAP_INT(&req->width); __GLX_SWAP_INT(&req->height); return __glXDisp_CreateGLXPbufferSGIX(cl, pc); } int __glXDispSwap_DestroyPbuffer(__GLXclientState * cl, GLbyte * pc) { xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_INT(&req->pbuffer); return __glXDisp_DestroyPbuffer(cl, pc); } int __glXDispSwap_DestroyGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq); __GLX_SWAP_INT(&req->pbuffer); return __glXDisp_DestroyGLXPbufferSGIX(cl, pc); } int __glXDispSwap_ChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; CARD32 *attribs; REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq); __GLX_SWAP_INT(&req->drawable); __GLX_SWAP_INT(&req->numAttribs); if (req->numAttribs > (UINT32_MAX >> 3)) { client->errorValue = req->numAttribs; return BadValue; } if (((sizeof(xGLXChangeDrawableAttributesReq) + (req->numAttribs << 3)) >> 2) < client->req_len) return BadLength; attribs = (CARD32 *) (req + 1); __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); return __glXDisp_ChangeDrawableAttributes(cl, pc); } int __glXDispSwap_ChangeDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXChangeDrawableAttributesSGIXReq *req = (xGLXChangeDrawableAttributesSGIXReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; CARD32 *attribs; REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq); __GLX_SWAP_INT(&req->drawable); __GLX_SWAP_INT(&req->numAttribs); if (req->numAttribs > (UINT32_MAX >> 3)) { client->errorValue = req->numAttribs; return BadValue; } REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq, req->numAttribs << 3); attribs = (CARD32 *) (req + 1); __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); return __glXDisp_ChangeDrawableAttributesSGIX(cl, pc); } int __glXDispSwap_CreateWindow(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; CARD32 *attribs; REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq); __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->fbconfig); __GLX_SWAP_INT(&req->window); __GLX_SWAP_INT(&req->glxwindow); __GLX_SWAP_INT(&req->numAttribs); if (req->numAttribs > (UINT32_MAX >> 3)) { client->errorValue = req->numAttribs; return BadValue; } REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3); attribs = (CARD32 *) (req + 1); __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); return __glXDisp_CreateWindow(cl, pc); } int __glXDispSwap_DestroyWindow(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq); __GLX_SWAP_INT(&req->glxwindow); return __glXDisp_DestroyWindow(cl, pc); } int __glXDispSwap_SwapBuffers(__GLXclientState * cl, GLbyte * pc) { xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->contextTag); __GLX_SWAP_INT(&req->drawable); return __glXDisp_SwapBuffers(cl, pc); } int __glXDispSwap_UseXFont(__GLXclientState * cl, GLbyte * pc) { xGLXUseXFontReq *req = (xGLXUseXFontReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->contextTag); __GLX_SWAP_INT(&req->font); __GLX_SWAP_INT(&req->first); __GLX_SWAP_INT(&req->count); __GLX_SWAP_INT(&req->listBase); return __glXDisp_UseXFont(cl, pc); } int __glXDispSwap_QueryExtensionsString(__GLXclientState * cl, GLbyte * pc) { xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->screen); return __glXDisp_QueryExtensionsString(cl, pc); } int __glXDispSwap_QueryServerString(__GLXclientState * cl, GLbyte * pc) { xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->name); return __glXDisp_QueryServerString(cl, pc); } int __glXDispSwap_ClientInfo(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq); __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->major); __GLX_SWAP_INT(&req->minor); __GLX_SWAP_INT(&req->numbytes); return __glXDisp_ClientInfo(cl, pc); } int __glXDispSwap_QueryContextInfoEXT(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq); __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->context); return __glXDisp_QueryContextInfoEXT(cl, pc); } int __glXDispSwap_BindTexImageEXT(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; GLXDrawable *drawId; int *buffer; CARD32 *num_attribs; __GLX_DECLARE_SWAP_VARIABLES; if ((sizeof(xGLXVendorPrivateReq) + 12) >> 2 > client->req_len) return BadLength; pc += __GLX_VENDPRIV_HDR_SIZE; drawId = ((GLXDrawable *) (pc)); buffer = ((int *) (pc + 4)); num_attribs = ((CARD32 *) (pc + 8)); __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->contextTag); __GLX_SWAP_INT(drawId); __GLX_SWAP_INT(buffer); __GLX_SWAP_INT(num_attribs); return __glXDisp_BindTexImageEXT(cl, (GLbyte *) pc); } int __glXDispSwap_ReleaseTexImageEXT(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; GLXDrawable *drawId; int *buffer; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); pc += __GLX_VENDPRIV_HDR_SIZE; drawId = ((GLXDrawable *) (pc)); buffer = ((int *) (pc + 4)); __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->contextTag); __GLX_SWAP_INT(drawId); __GLX_SWAP_INT(buffer); return __glXDisp_ReleaseTexImageEXT(cl, (GLbyte *) pc); } int __glXDispSwap_CopySubBufferMESA(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; GLXDrawable *drawId; int *buffer; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20); (void) drawId; (void) buffer; pc += __GLX_VENDPRIV_HDR_SIZE; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->contextTag); __GLX_SWAP_INT(pc); __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + 8); __GLX_SWAP_INT(pc + 12); __GLX_SWAP_INT(pc + 16); return __glXDisp_CopySubBufferMESA(cl, pc); } int __glXDispSwap_GetDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXVendorPrivateWithReplyReq *req = (xGLXVendorPrivateWithReplyReq *) pc; CARD32 *data; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq); data = (CARD32 *) (req + 1); __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->contextTag); __GLX_SWAP_INT(data); return __glXDisp_GetDrawableAttributesSGIX(cl, pc); } int __glXDispSwap_GetDrawableAttributes(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq); __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->drawable); return __glXDisp_GetDrawableAttributes(cl, pc); } /************************************************************************/ /* ** Render and Renderlarge are not in the GLX API. They are used by the GLX ** client library to send batches of GL rendering commands. */ int __glXDispSwap_Render(__GLXclientState * cl, GLbyte * pc) { return __glXDisp_Render(cl, pc); } /* ** Execute a large rendering request (one that spans multiple X requests). */ int __glXDispSwap_RenderLarge(__GLXclientState * cl, GLbyte * pc) { return __glXDisp_RenderLarge(cl, pc); } /************************************************************************/ /* ** No support is provided for the vendor-private requests other than ** allocating these entry points in the dispatch table. */ int __glXDispSwap_VendorPrivate(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXVendorPrivateReq *req; GLint vendorcode; __GLXdispatchVendorPrivProcPtr proc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); req = (xGLXVendorPrivateReq *) pc; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->vendorCode); vendorcode = req->vendorCode; proc = (__GLXdispatchVendorPrivProcPtr) __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info, vendorcode, 1); if (proc != NULL) { return (*proc) (cl, (GLbyte *) req); } cl->client->errorValue = req->vendorCode; return __glXError(GLXUnsupportedPrivateRequest); } int __glXDispSwap_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXVendorPrivateWithReplyReq *req; GLint vendorcode; __GLXdispatchVendorPrivProcPtr proc; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateWithReplyReq); req = (xGLXVendorPrivateWithReplyReq *) pc; __GLX_SWAP_SHORT(&req->length); __GLX_SWAP_INT(&req->vendorCode); vendorcode = req->vendorCode; proc = (__GLXdispatchVendorPrivProcPtr) __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info, vendorcode, 1); if (proc != NULL) { return (*proc) (cl, (GLbyte *) req); } cl->client->errorValue = req->vendorCode; return __glXError(GLXUnsupportedPrivateRequest); } xorg-server-1.20.13/glx/glxcontext.h0000644000175000017500000001132414100573756014235 00000000000000#ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef _GLX_context_h_ #define _GLX_context_h_ /* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ struct __GLXcontext { void (*destroy) (__GLXcontext * context); int (*makeCurrent) (__GLXcontext * context); int (*loseCurrent) (__GLXcontext * context); int (*copy) (__GLXcontext * dst, __GLXcontext * src, unsigned long mask); Bool (*wait) (__GLXcontext * context, __GLXclientState * cl, int *error); /* EXT_texture_from_pixmap */ int (*bindTexImage) (__GLXcontext * baseContext, int buffer, __GLXdrawable * pixmap); int (*releaseTexImage) (__GLXcontext * baseContext, int buffer, __GLXdrawable * pixmap); /* ** list of context structs */ __GLXcontext *next; /* ** config struct for this context */ __GLXconfig *config; /* ** Pointer to screen info data for this context. This is set ** when the context is created. */ __GLXscreen *pGlxScreen; /* ** If this context is current for a client, this will be that client */ ClientPtr currentClient; /* ** The XID of this context. */ XID id; /* ** The XID of the shareList context. */ XID share_id; /* ** Whether this context's ID still exists. */ GLboolean idExists; /* ** Whether this context is a direct rendering context. */ GLboolean isDirect; /* ** Current rendering mode for this context. */ GLenum renderMode; /** * Reset notification strategy used when a GPU reset occurs. */ GLenum resetNotificationStrategy; /** * Context release behavior */ GLenum releaseBehavior; /* ** Buffers for feedback and selection. */ GLfloat *feedbackBuf; GLint feedbackBufSize; /* number of elements allocated */ GLuint *selectBuf; GLint selectBufSize; /* number of elements allocated */ /* ** Keep track of large rendering commands, which span multiple requests. */ GLint largeCmdBytesSoFar; /* bytes received so far */ GLint largeCmdBytesTotal; /* total bytes expected */ GLint largeCmdRequestsSoFar; /* requests received so far */ GLint largeCmdRequestsTotal; /* total requests expected */ GLbyte *largeCmdBuf; GLint largeCmdBufSize; /* ** The drawable private this context is bound to */ __GLXdrawable *drawPriv; __GLXdrawable *readPriv; }; void __glXContextDestroy(__GLXcontext * context); extern int validGlxScreen(ClientPtr client, int screen, __GLXscreen ** pGlxScreen, int *err); extern int validGlxFBConfig(ClientPtr client, __GLXscreen * pGlxScreen, XID id, __GLXconfig ** config, int *err); extern int validGlxContext(ClientPtr client, XID id, int access_mode, __GLXcontext ** context, int *err); extern __GLXcontext *__glXdirectContextCreate(__GLXscreen * screen, __GLXconfig * modes, __GLXcontext * shareContext); #endif /* !__GLX_context_h__ */ xorg-server-1.20.13/glx/glxdrawable.h0000644000175000017500000000530314100573756014332 00000000000000#ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef _GLX_drawable_h_ #define _GLX_drawable_h_ /* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ /* We just need to avoid clashing with DRAWABLE_{WINDOW,PIXMAP} */ enum { GLX_DRAWABLE_WINDOW, GLX_DRAWABLE_PIXMAP, GLX_DRAWABLE_PBUFFER, GLX_DRAWABLE_ANY }; struct __GLXdrawable { void (*destroy) (__GLXdrawable * private); GLboolean(*swapBuffers) (ClientPtr client, __GLXdrawable *); void (*copySubBuffer) (__GLXdrawable * drawable, int x, int y, int w, int h); void (*waitX) (__GLXdrawable *); void (*waitGL) (__GLXdrawable *); DrawablePtr pDraw; XID drawId; /* ** Either GLX_DRAWABLE_PIXMAP, GLX_DRAWABLE_WINDOW or ** GLX_DRAWABLE_PBUFFER. */ int type; /* ** Configuration of the visual to which this drawable was created. */ __GLXconfig *config; GLenum target; GLenum format; /* ** Event mask */ unsigned long eventMask; }; extern int validGlxDrawable(ClientPtr client, XID id, int type, int access_mode, __GLXdrawable **drawable, int *err); #endif /* !__GLX_drawable_h__ */ xorg-server-1.20.13/glx/glxext.c0000644000175000017500000004734314100573756013356 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "glxserver.h" #include #include #include #include "privates.h" #include #include "extinit.h" #include "glx_extinit.h" #include "unpack.h" #include "glxutil.h" #include "glxext.h" #include "indirect_table.h" #include "indirect_util.h" #include "glxvndabi.h" /* ** X resources. */ static int glxGeneration; RESTYPE __glXContextRes; RESTYPE __glXDrawableRes; static DevPrivateKeyRec glxClientPrivateKeyRec; static GlxServerVendor *glvnd_vendor = NULL; #define glxClientPrivateKey (&glxClientPrivateKeyRec) /* ** Forward declarations. */ static int __glXDispatch(ClientPtr); static GLboolean __glXFreeContext(__GLXcontext * cx); /* * This procedure is called when the client who created the context goes away * OR when glXDestroyContext is called. If the context is current for a client * the dispatch layer will have moved the context struct to a fake resource ID * and cx here will be NULL. Otherwise we really free the context. */ static int ContextGone(__GLXcontext * cx, XID id) { if (!cx) return TRUE; if (!cx->currentClient) __glXFreeContext(cx); return TRUE; } static __GLXcontext *glxPendingDestroyContexts; static __GLXcontext *glxAllContexts; static int glxBlockClients; /* ** Destroy routine that gets called when a drawable is freed. A drawable ** contains the ancillary buffers needed for rendering. */ static Bool DrawableGone(__GLXdrawable * glxPriv, XID xid) { __GLXcontext *c, *next; if (glxPriv->type == GLX_DRAWABLE_WINDOW) { /* If this was created by glXCreateWindow, free the matching resource */ if (glxPriv->drawId != glxPriv->pDraw->id) { if (xid == glxPriv->drawId) FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE); else FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE); } /* otherwise this window was implicitly created by MakeCurrent */ } for (c = glxAllContexts; c; c = next) { next = c->next; if (c->currentClient && (c->drawPriv == glxPriv || c->readPriv == glxPriv)) { /* flush the context */ glFlush(); /* just force a re-bind the next time through */ (*c->loseCurrent) (c); lastGLContext = NULL; } if (c->drawPriv == glxPriv) c->drawPriv = NULL; if (c->readPriv == glxPriv) c->readPriv = NULL; } /* drop our reference to any backing pixmap */ if (glxPriv->type == GLX_DRAWABLE_PIXMAP) glxPriv->pDraw->pScreen->DestroyPixmap((PixmapPtr) glxPriv->pDraw); glxPriv->destroy(glxPriv); return TRUE; } Bool __glXAddContext(__GLXcontext * cx) { /* Register this context as a resource. */ if (!AddResource(cx->id, __glXContextRes, (void *)cx)) { return FALSE; } cx->next = glxAllContexts; glxAllContexts = cx; return TRUE; } static void __glXRemoveFromContextList(__GLXcontext * cx) { __GLXcontext *c, *prev; if (cx == glxAllContexts) glxAllContexts = cx->next; else { prev = glxAllContexts; for (c = glxAllContexts; c; c = c->next) { if (c == cx) prev->next = c->next; prev = c; } } } /* ** Free a context. */ static GLboolean __glXFreeContext(__GLXcontext * cx) { if (cx->idExists || cx->currentClient) return GL_FALSE; __glXRemoveFromContextList(cx); free(cx->feedbackBuf); free(cx->selectBuf); free(cx->largeCmdBuf); if (cx == lastGLContext) { lastGLContext = NULL; } /* We can get here through both regular dispatching from * __glXDispatch() or as a callback from the resource manager. In * the latter case we need to lift the DRI lock manually. */ if (!glxBlockClients) { cx->destroy(cx); } else { cx->next = glxPendingDestroyContexts; glxPendingDestroyContexts = cx; } return GL_TRUE; } /************************************************************************/ /* ** These routines can be used to check whether a particular GL command ** has caused an error. Specifically, we use them to check whether a ** given query has caused an error, in which case a zero-length data ** reply is sent to the client. */ static GLboolean errorOccured = GL_FALSE; /* ** The GL was will call this routine if an error occurs. */ void __glXErrorCallBack(GLenum code) { errorOccured = GL_TRUE; } /* ** Clear the error flag before calling the GL command. */ void __glXClearErrorOccured(void) { errorOccured = GL_FALSE; } /* ** Check if the GL command caused an error. */ GLboolean __glXErrorOccured(void) { return errorOccured; } static int __glXErrorBase; int __glXEventBase; int __glXError(int error) { return __glXErrorBase + error; } __GLXclientState * glxGetClient(ClientPtr pClient) { return dixLookupPrivate(&pClient->devPrivates, glxClientPrivateKey); } static void glxClientCallback(CallbackListPtr *list, void *closure, void *data) { NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; ClientPtr pClient = clientinfo->client; __GLXclientState *cl = glxGetClient(pClient); switch (pClient->clientState) { case ClientStateGone: free(cl->returnBuf); free(cl->GLClientextensions); cl->returnBuf = NULL; cl->GLClientextensions = NULL; break; default: break; } } /************************************************************************/ static __GLXprovider *__glXProviderStack = &__glXDRISWRastProvider; void GlxPushProvider(__GLXprovider * provider) { provider->next = __glXProviderStack; __glXProviderStack = provider; } static Bool checkScreenVisuals(void) { int i, j; for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr screen = screenInfo.screens[i]; for (j = 0; j < screen->numVisuals; j++) { if ((screen->visuals[j].class == TrueColor || screen->visuals[j].class == DirectColor) && screen->visuals[j].nplanes > 12) return TRUE; } } return FALSE; } static void GetGLXDrawableBytes(void *value, XID id, ResourceSizePtr size) { __GLXdrawable *draw = value; size->resourceSize = 0; size->pixmapRefSize = 0; size->refCnt = 1; if (draw->type == GLX_DRAWABLE_PIXMAP) { SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); ResourceSizeRec pixmapSize = { 0, }; pixmapSizeFunc((PixmapPtr)draw->pDraw, draw->pDraw->id, &pixmapSize); size->pixmapRefSize += pixmapSize.pixmapRefSize; } } static void xorgGlxCloseExtension(const ExtensionEntry *extEntry) { if (glvnd_vendor != NULL) { glxServer.destroyVendor(glvnd_vendor); glvnd_vendor = NULL; } lastGLContext = NULL; } static int xorgGlxHandleRequest(ClientPtr client) { return __glXDispatch(client); } static ScreenPtr screenNumToScreen(int screen) { if (screen < 0 || screen >= screenInfo.numScreens) return NULL; return screenInfo.screens[screen]; } static int maybe_swap32(ClientPtr client, int x) { return client->swapped ? bswap_32(x) : x; } static GlxServerVendor * vendorForScreen(ClientPtr client, int screen) { screen = maybe_swap32(client, screen); return glxServer.getVendorForScreen(client, screenNumToScreen(screen)); } /* this ought to be generated */ static int xorgGlxThunkRequest(ClientPtr client) { REQUEST(xGLXVendorPrivateReq); CARD32 vendorCode = maybe_swap32(client, stuff->vendorCode); GlxServerVendor *vendor = NULL; XID resource = 0; int ret; switch (vendorCode) { case X_GLXvop_QueryContextInfoEXT: { xGLXQueryContextInfoEXTReq *req = (void *)stuff; REQUEST_AT_LEAST_SIZE(*req); if (!(vendor = glxServer.getXIDMap(maybe_swap32(client, req->context)))) return __glXError(GLXBadContext); break; } case X_GLXvop_GetFBConfigsSGIX: { xGLXGetFBConfigsSGIXReq *req = (void *)stuff; REQUEST_AT_LEAST_SIZE(*req); if (!(vendor = vendorForScreen(client, req->screen))) return BadValue; break; } case X_GLXvop_CreateContextWithConfigSGIX: { xGLXCreateContextWithConfigSGIXReq *req = (void *)stuff; REQUEST_AT_LEAST_SIZE(*req); resource = maybe_swap32(client, req->context); if (!(vendor = vendorForScreen(client, req->screen))) return BadValue; break; } case X_GLXvop_CreateGLXPixmapWithConfigSGIX: { xGLXCreateGLXPixmapWithConfigSGIXReq *req = (void *)stuff; REQUEST_AT_LEAST_SIZE(*req); resource = maybe_swap32(client, req->glxpixmap); if (!(vendor = vendorForScreen(client, req->screen))) return BadValue; break; } case X_GLXvop_CreateGLXPbufferSGIX: { xGLXCreateGLXPbufferSGIXReq *req = (void *)stuff; REQUEST_AT_LEAST_SIZE(*req); resource = maybe_swap32(client, req->pbuffer); if (!(vendor = vendorForScreen(client, req->screen))) return BadValue; break; } /* same offset for the drawable for these three */ case X_GLXvop_DestroyGLXPbufferSGIX: case X_GLXvop_ChangeDrawableAttributesSGIX: case X_GLXvop_GetDrawableAttributesSGIX: { xGLXGetDrawableAttributesSGIXReq *req = (void *)stuff; REQUEST_AT_LEAST_SIZE(*req); if (!(vendor = glxServer.getXIDMap(maybe_swap32(client, req->drawable)))) return __glXError(GLXBadDrawable); break; } /* most things just use the standard context tag */ default: { /* size checked by vnd layer already */ GLXContextTag tag = maybe_swap32(client, stuff->contextTag); vendor = glxServer.getContextTag(client, tag); if (!vendor) return __glXError(GLXBadContextTag); break; } } /* If we're creating a resource, add the map now */ if (resource) { LEGAL_NEW_RESOURCE(resource, client); if (!glxServer.addXIDMap(resource, vendor)) return BadAlloc; } ret = glxServer.forwardRequest(vendor, client); if (ret == Success && vendorCode == X_GLXvop_DestroyGLXPbufferSGIX) { xGLXDestroyGLXPbufferSGIXReq *req = (void *)stuff; glxServer.removeXIDMap(maybe_swap32(client, req->pbuffer)); } if (ret != Success) glxServer.removeXIDMap(resource); return ret; } static GlxServerDispatchProc xorgGlxGetDispatchAddress(CARD8 minorOpcode, CARD32 vendorCode) { /* we don't support any other GLX opcodes */ if (minorOpcode != X_GLXVendorPrivate && minorOpcode != X_GLXVendorPrivateWithReply) return NULL; /* we only support some vendor private requests */ if (!__glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info, vendorCode, FALSE)) return NULL; return xorgGlxThunkRequest; } static Bool xorgGlxServerPreInit(const ExtensionEntry *extEntry) { if (glxGeneration != serverGeneration) { /* Mesa requires at least one True/DirectColor visual */ if (!checkScreenVisuals()) return FALSE; __glXContextRes = CreateNewResourceType((DeleteType) ContextGone, "GLXContext"); __glXDrawableRes = CreateNewResourceType((DeleteType) DrawableGone, "GLXDrawable"); if (!__glXContextRes || !__glXDrawableRes) return FALSE; if (!dixRegisterPrivateKey (&glxClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(__GLXclientState))) return FALSE; if (!AddCallback(&ClientStateCallback, glxClientCallback, 0)) return FALSE; __glXErrorBase = extEntry->errorBase; __glXEventBase = extEntry->eventBase; SetResourceTypeSizeFunc(__glXDrawableRes, GetGLXDrawableBytes); #if PRESENT __glXregisterPresentCompleteNotify(); #endif glxGeneration = serverGeneration; } return glxGeneration == serverGeneration; } static void xorgGlxInitGLVNDVendor(void) { if (glvnd_vendor == NULL) { GlxServerImports *imports = NULL; imports = glxServer.allocateServerImports(); if (imports != NULL) { imports->extensionCloseDown = xorgGlxCloseExtension; imports->handleRequest = xorgGlxHandleRequest; imports->getDispatchAddress = xorgGlxGetDispatchAddress; imports->makeCurrent = xorgGlxMakeCurrent; glvnd_vendor = glxServer.createVendor(imports); glxServer.freeServerImports(imports); } } } static void xorgGlxServerInit(CallbackListPtr *pcbl, void *param, void *ext) { const ExtensionEntry *extEntry = ext; int i; if (!xorgGlxServerPreInit(extEntry)) { return; } xorgGlxInitGLVNDVendor(); if (!glvnd_vendor) { return; } for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr pScreen = screenInfo.screens[i]; __GLXprovider *p; if (glxServer.getVendorForScreen(NULL, pScreen) != NULL) { // There's already a vendor registered. LogMessage(X_INFO, "GLX: Another vendor is already registered for screen %d\n", i); continue; } for (p = __glXProviderStack; p != NULL; p = p->next) { __GLXscreen *glxScreen = p->screenProbe(pScreen); if (glxScreen != NULL) { LogMessage(X_INFO, "GLX: Initialized %s GL provider for screen %d\n", p->name, i); break; } } if (p) { glxServer.setScreenVendor(pScreen, glvnd_vendor); } else { LogMessage(X_INFO, "GLX: no usable GL providers found for screen %d\n", i); } } } Bool xorgGlxCreateVendor(void) { return AddCallback(glxServer.extensionInitCallback, xorgGlxServerInit, NULL); } /************************************************************************/ /* ** Make a context the current one for the GL (in this implementation, there ** is only one instance of the GL, and we use it to serve all GL clients by ** switching it between different contexts). While we are at it, look up ** a context by its tag and return its (__GLXcontext *). */ __GLXcontext * __glXForceCurrent(__GLXclientState * cl, GLXContextTag tag, int *error) { ClientPtr client = cl->client; REQUEST(xGLXSingleReq); __GLXcontext *cx; /* ** See if the context tag is legal; it is managed by the extension, ** so if it's invalid, we have an implementation error. */ cx = __glXLookupContextByTag(cl, tag); if (!cx) { cl->client->errorValue = tag; *error = __glXError(GLXBadContextTag); return 0; } /* If we're expecting a glXRenderLarge request, this better be one. */ if (cx->largeCmdRequestsSoFar != 0 && stuff->glxCode != X_GLXRenderLarge) { client->errorValue = stuff->glxCode; *error = __glXError(GLXBadLargeRequest); return 0; } if (!cx->isDirect) { if (cx->drawPriv == NULL) { /* ** The drawable has vanished. It must be a window, because only ** windows can be destroyed from under us; GLX pixmaps are ** refcounted and don't go away until no one is using them. */ *error = __glXError(GLXBadCurrentWindow); return 0; } } if (cx->wait && (*cx->wait) (cx, cl, error)) return NULL; if (cx == lastGLContext) { /* No need to re-bind */ return cx; } /* Make this context the current one for the GL. */ if (!cx->isDirect) { /* * If it is being forced, it means that this context was already made * current. So it cannot just be made current again without decrementing * refcount's */ (*cx->loseCurrent) (cx); lastGLContext = cx; if (!(*cx->makeCurrent) (cx)) { /* Bind failed, and set the error code. Bummer */ lastGLContext = NULL; cl->client->errorValue = cx->id; *error = __glXError(GLXBadContextState); return 0; } } return cx; } /************************************************************************/ void glxSuspendClients(void) { int i; for (i = 1; i < currentMaxClients; i++) { if (clients[i] && glxGetClient(clients[i])->client) IgnoreClient(clients[i]); } glxBlockClients = TRUE; } void glxResumeClients(void) { __GLXcontext *cx, *next; int i; glxBlockClients = FALSE; for (i = 1; i < currentMaxClients; i++) { if (clients[i] && glxGetClient(clients[i])->client) AttendClient(clients[i]); } for (cx = glxPendingDestroyContexts; cx != NULL; cx = next) { next = cx->next; cx->destroy(cx); } glxPendingDestroyContexts = NULL; } static glx_gpa_proc _get_proc_address; void __glXsetGetProcAddress(glx_gpa_proc get_proc_address) { _get_proc_address = get_proc_address; } void *__glGetProcAddress(const char *proc) { void *ret = (void *) _get_proc_address(proc); return ret ? ret : (void *) NoopDDA; } /* ** Top level dispatcher; all commands are executed from here down. */ static int __glXDispatch(ClientPtr client) { REQUEST(xGLXSingleReq); CARD8 opcode; __GLXdispatchSingleProcPtr proc; __GLXclientState *cl; int retval = BadRequest; opcode = stuff->glxCode; cl = glxGetClient(client); if (!cl->client) cl->client = client; /* If we're currently blocking GLX clients, just put this guy to * sleep, reset the request and return. */ if (glxBlockClients) { ResetCurrentRequest(client); client->sequence--; IgnoreClient(client); return Success; } /* ** Use the opcode to index into the procedure table. */ proc = __glXGetProtocolDecodeFunction(&Single_dispatch_info, opcode, client->swapped); if (proc != NULL) retval = (*proc) (cl, (GLbyte *) stuff); return retval; } xorg-server-1.20.13/glx/glxext.h0000644000175000017500000000525014100573756013352 00000000000000#ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef _glxext_h_ #define _glxext_h_ /* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ /* doing #include & #include could cause problems * with overlapping definitions, so let's use the easy way */ #ifndef GLX_RGBA_FLOAT_BIT_ARB #define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 #endif #ifndef GLX_RGBA_FLOAT_TYPE_ARB #define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 #endif #ifndef GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT #define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 #endif #ifndef GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT #define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 #endif extern void __glXFlushContextCache(void); extern Bool __glXAddContext(__GLXcontext * cx); extern void __glXErrorCallBack(GLenum code); extern void __glXClearErrorOccured(void); extern GLboolean __glXErrorOccured(void); extern const char GLServerVersion[]; extern int DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap); extern int xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId, XID contextId, GLXContextTag newContextTag); #endif /* _glxext_h_ */ xorg-server-1.20.13/glx/glxdriswrast.c0000644000175000017500000003526514100573756014600 00000000000000/* * Copyright © 2008 George Sapountzis * Copyright © 2008 Red Hat, 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 the * copyright holders not be used in advertising or publicity * pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include "scrnintstr.h" #include "pixmapstr.h" #include "gcstruct.h" #include "os.h" #include "glxserver.h" #include "glxutil.h" #include "glxdricommon.h" #include "extension_string.h" /* RTLD_LOCAL is not defined on Cygwin */ #ifdef __CYGWIN__ #ifndef RTLD_LOCAL #define RTLD_LOCAL 0 #endif #endif typedef struct __GLXDRIscreen __GLXDRIscreen; typedef struct __GLXDRIcontext __GLXDRIcontext; typedef struct __GLXDRIdrawable __GLXDRIdrawable; struct __GLXDRIscreen { __GLXscreen base; __DRIscreen *driScreen; void *driver; const __DRIcoreExtension *core; const __DRIswrastExtension *swrast; const __DRIcopySubBufferExtension *copySubBuffer; const __DRItexBufferExtension *texBuffer; const __DRIconfig **driConfigs; }; struct __GLXDRIcontext { __GLXcontext base; __DRIcontext *driContext; }; struct __GLXDRIdrawable { __GLXdrawable base; __DRIdrawable *driDrawable; __GLXDRIscreen *screen; }; /* white lie */ extern glx_func_ptr glXGetProcAddressARB(const char *); static void __glXDRIdrawableDestroy(__GLXdrawable * drawable) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; const __DRIcoreExtension *core = private->screen->core; (*core->destroyDrawable) (private->driDrawable); __glXDrawableRelease(drawable); free(private); } static GLboolean __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable * drawable) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; const __DRIcoreExtension *core = private->screen->core; (*core->swapBuffers) (private->driDrawable); return TRUE; } static void __glXDRIdrawableCopySubBuffer(__GLXdrawable * basePrivate, int x, int y, int w, int h) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; const __DRIcopySubBufferExtension *copySubBuffer = private->screen->copySubBuffer; if (copySubBuffer) (*copySubBuffer->copySubBuffer) (private->driDrawable, x, y, w, h); } static void __glXDRIcontextDestroy(__GLXcontext * baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; (*screen->core->destroyContext) (context->driContext); __glXContextDestroy(&context->base); free(context); } static int __glXDRIcontextMakeCurrent(__GLXcontext * baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; return (*screen->core->bindContext) (context->driContext, draw->driDrawable, read->driDrawable); } static int __glXDRIcontextLoseCurrent(__GLXcontext * baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; return (*screen->core->unbindContext) (context->driContext); } static int __glXDRIcontextCopy(__GLXcontext * baseDst, __GLXcontext * baseSrc, unsigned long mask) { __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst; __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc; __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen; return (*screen->core->copyContext) (dst->driContext, src->driContext, mask); } static int __glXDRIbindTexImage(__GLXcontext * baseContext, int buffer, __GLXdrawable * glxPixmap) { __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap; const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer; __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; if (texBuffer == NULL) return Success; #if __DRI_TEX_BUFFER_VERSION >= 2 if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) { (*texBuffer->setTexBuffer2) (context->driContext, glxPixmap->target, glxPixmap->format, drawable->driDrawable); } else #endif texBuffer->setTexBuffer(context->driContext, glxPixmap->target, drawable->driDrawable); return Success; } static int __glXDRIreleaseTexImage(__GLXcontext * baseContext, int buffer, __GLXdrawable * pixmap) { /* FIXME: Just unbind the texture? */ return Success; } static __GLXcontext * __glXDRIscreenCreateContext(__GLXscreen * baseScreen, __GLXconfig * glxConfig, __GLXcontext * baseShareContext, unsigned num_attribs, const uint32_t *attribs, int *error) { __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; __GLXDRIcontext *context, *shareContext; __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; const __DRIconfig *driConfig = config ? config->driConfig : NULL; const __DRIcoreExtension *core = screen->core; __DRIcontext *driShare; /* DRISWRAST won't support createContextAttribs, so these parameters will * never be used. */ (void) num_attribs; (void) attribs; (void) error; shareContext = (__GLXDRIcontext *) baseShareContext; if (shareContext) driShare = shareContext->driContext; else driShare = NULL; context = calloc(1, sizeof *context); if (context == NULL) return NULL; context->base.config = glxConfig; context->base.destroy = __glXDRIcontextDestroy; context->base.makeCurrent = __glXDRIcontextMakeCurrent; context->base.loseCurrent = __glXDRIcontextLoseCurrent; context->base.copy = __glXDRIcontextCopy; context->base.bindTexImage = __glXDRIbindTexImage; context->base.releaseTexImage = __glXDRIreleaseTexImage; context->driContext = (*core->createNewContext) (screen->driScreen, driConfig, driShare, context); return &context->base; } static __GLXdrawable * __glXDRIscreenCreateDrawable(ClientPtr client, __GLXscreen * screen, DrawablePtr pDraw, XID drawId, int type, XID glxDrawId, __GLXconfig * glxConfig) { __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; __GLXDRIdrawable *private; private = calloc(1, sizeof *private); if (private == NULL) return NULL; private->screen = driScreen; if (!__glXDrawableInit(&private->base, screen, pDraw, type, glxDrawId, glxConfig)) { free(private); return NULL; } private->base.destroy = __glXDRIdrawableDestroy; private->base.swapBuffers = __glXDRIdrawableSwapBuffers; private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; private->driDrawable = (*driScreen->swrast->createNewDrawable) (driScreen->driScreen, config->driConfig, private); return &private->base; } static void swrastGetDrawableInfo(__DRIdrawable * draw, int *x, int *y, int *w, int *h, void *loaderPrivate) { __GLXDRIdrawable *drawable = loaderPrivate; DrawablePtr pDraw = drawable->base.pDraw; *x = pDraw->x; *y = pDraw->y; *w = pDraw->width; *h = pDraw->height; } static void swrastPutImage(__DRIdrawable * draw, int op, int x, int y, int w, int h, char *data, void *loaderPrivate) { __GLXDRIdrawable *drawable = loaderPrivate; DrawablePtr pDraw = drawable->base.pDraw; GCPtr gc; __GLXcontext *cx = lastGLContext; if ((gc = GetScratchGC(pDraw->depth, pDraw->pScreen))) { ValidateGC(pDraw, gc); gc->ops->PutImage(pDraw, gc, pDraw->depth, x, y, w, h, 0, ZPixmap, data); FreeScratchGC(gc); } if (cx != lastGLContext) { lastGLContext = cx; cx->makeCurrent(cx); } } static void swrastGetImage(__DRIdrawable * draw, int x, int y, int w, int h, char *data, void *loaderPrivate) { __GLXDRIdrawable *drawable = loaderPrivate; DrawablePtr pDraw = drawable->base.pDraw; ScreenPtr pScreen = pDraw->pScreen; __GLXcontext *cx = lastGLContext; pScreen->SourceValidate(pDraw, x, y, w, h, IncludeInferiors); pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data); if (cx != lastGLContext) { lastGLContext = cx; cx->makeCurrent(cx); } } static const __DRIswrastLoaderExtension swrastLoaderExtension = { {__DRI_SWRAST_LOADER, 1}, swrastGetDrawableInfo, swrastPutImage, swrastGetImage }; static const __DRIextension *loader_extensions[] = { &swrastLoaderExtension.base, NULL }; static void initializeExtensions(__GLXscreen * screen) { const __DRIextension **extensions; __GLXDRIscreen *dri = (__GLXDRIscreen *)screen; int i; __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_no_config_context"); if (dri->swrast->base.version >= 3) { __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context"); __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_no_error"); __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_profile"); __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_create_context_es_profile"); __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_create_context_es2_profile"); } /* these are harmless to enable unconditionally */ __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_framebuffer_sRGB"); __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_fbconfig_float"); __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_fbconfig_packed_float"); __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); extensions = dri->core->getExtensions(dri->driScreen); for (i = 0; extensions[i]; i++) { if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { dri->copySubBuffer = (const __DRIcopySubBufferExtension *) extensions[i]; } if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { dri->texBuffer = (const __DRItexBufferExtension *) extensions[i]; } #ifdef __DRI2_FLUSH_CONTROL if (strcmp(extensions[i]->name, __DRI2_FLUSH_CONTROL) == 0) { __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_context_flush_control"); } #endif } } static void __glXDRIscreenDestroy(__GLXscreen * baseScreen) { int i; __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; (*screen->core->destroyScreen) (screen->driScreen); dlclose(screen->driver); __glXScreenDestroy(baseScreen); if (screen->driConfigs) { for (i = 0; screen->driConfigs[i] != NULL; i++) free((__DRIconfig **) screen->driConfigs[i]); free(screen->driConfigs); } free(screen); } static __GLXscreen * __glXDRIscreenProbe(ScreenPtr pScreen) { const char *driverName = "swrast"; __GLXDRIscreen *screen; screen = calloc(1, sizeof *screen); if (screen == NULL) return NULL; screen->base.destroy = __glXDRIscreenDestroy; screen->base.createContext = __glXDRIscreenCreateContext; screen->base.createDrawable = __glXDRIscreenCreateDrawable; screen->base.swapInterval = NULL; screen->base.pScreen = pScreen; __glXInitExtensionEnableBits(screen->base.glx_enable_bits); screen->driver = glxProbeDriver(driverName, (void **) &screen->core, __DRI_CORE, 1, (void **) &screen->swrast, __DRI_SWRAST, 1); if (screen->driver == NULL) { goto handle_error; } screen->driScreen = (*screen->swrast->createNewScreen) (pScreen->myNum, loader_extensions, &screen->driConfigs, screen); if (screen->driScreen == NULL) { LogMessage(X_ERROR, "IGLX error: Calling driver entry point failed\n"); goto handle_error; } initializeExtensions(&screen->base); screen->base.fbconfigs = glxConvertConfigs(screen->core, screen->driConfigs); #if !defined(XQUARTZ) && !defined(WIN32) screen->base.glvnd = strdup("mesa"); #endif __glXScreenInit(&screen->base, pScreen); __glXsetGetProcAddress(glXGetProcAddressARB); LogMessage(X_INFO, "IGLX: Loaded and initialized %s\n", driverName); return &screen->base; handle_error: if (screen->driver) dlclose(screen->driver); free(screen); LogMessage(X_ERROR, "GLX: could not load software renderer\n"); return NULL; } __GLXprovider __glXDRISWRastProvider = { __glXDRIscreenProbe, "DRISWRAST", NULL }; xorg-server-1.20.13/glx/glxdricommon.c0000644000175000017500000003164514100573756014543 00000000000000/* * Copyright © 2008 Red Hat, 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 the * copyright holders not be used in advertising or publicity * pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include "extinit.h" #include "glxserver.h" #include "glxext.h" #include "glxcontext.h" #include "glxscreens.h" #include "glxdricommon.h" #define __ATTRIB(attrib, field) \ { attrib, offsetof(__GLXconfig, field) } static const struct { unsigned int attrib, offset; } attribMap[] = { __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), __ATTRIB(__DRI_ATTRIB_LEVEL, level), __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable), }; static void setScalar(__GLXconfig * config, unsigned int attrib, unsigned int value) { int i; for (i = 0; i < ARRAY_SIZE(attribMap); i++) if (attribMap[i].attrib == attrib) { *(unsigned int *) ((char *) config + attribMap[i].offset) = value; return; } } static Bool render_type_is_pbuffer_only(unsigned renderType) { /* The GL_ARB_color_buffer_float spec says: * * "Note that floating point rendering is only supported for * GLXPbuffer drawables. The GLX_DRAWABLE_TYPE attribute of the * GLXFBConfig must have the GLX_PBUFFER_BIT bit set and the * GLX_RENDER_TYPE attribute must have the GLX_RGBA_FLOAT_BIT set." */ return !!(renderType & (__DRI_ATTRIB_UNSIGNED_FLOAT_BIT | __DRI_ATTRIB_FLOAT_BIT)); } static __GLXconfig * createModeFromConfig(const __DRIcoreExtension * core, const __DRIconfig * driConfig, unsigned int visualType, GLboolean duplicateForComp) { __GLXDRIconfig *config; GLint renderType = 0; unsigned int attrib, value, drawableType = GLX_PBUFFER_BIT; int i; config = calloc(1, sizeof *config); config->driConfig = driConfig; i = 0; while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) { switch (attrib) { case __DRI_ATTRIB_RENDER_TYPE: if (value & __DRI_ATTRIB_RGBA_BIT) renderType |= GLX_RGBA_BIT; if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) renderType |= GLX_COLOR_INDEX_BIT; if (value & __DRI_ATTRIB_FLOAT_BIT) renderType |= GLX_RGBA_FLOAT_BIT_ARB; if (value & __DRI_ATTRIB_UNSIGNED_FLOAT_BIT) renderType |= GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT; break; case __DRI_ATTRIB_CONFIG_CAVEAT: if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) config->config.visualRating = GLX_NON_CONFORMANT_CONFIG; else if (value & __DRI_ATTRIB_SLOW_BIT) config->config.visualRating = GLX_SLOW_CONFIG; else config->config.visualRating = GLX_NONE; break; case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS: config->config.bindToTextureTargets = 0; if (value & __DRI_ATTRIB_TEXTURE_1D_BIT) config->config.bindToTextureTargets |= GLX_TEXTURE_1D_BIT_EXT; if (value & __DRI_ATTRIB_TEXTURE_2D_BIT) config->config.bindToTextureTargets |= GLX_TEXTURE_2D_BIT_EXT; if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT) config->config.bindToTextureTargets |= GLX_TEXTURE_RECTANGLE_BIT_EXT; break; case __DRI_ATTRIB_SWAP_METHOD: /* Workaround for broken dri drivers */ if (value != GLX_SWAP_UNDEFINED_OML && value != GLX_SWAP_COPY_OML && value != GLX_SWAP_EXCHANGE_OML) value = GLX_SWAP_UNDEFINED_OML; /* Fall through. */ default: setScalar(&config->config, attrib, value); break; } } if (!render_type_is_pbuffer_only(renderType)) drawableType |= GLX_WINDOW_BIT | GLX_PIXMAP_BIT; config->config.next = NULL; config->config.visualType = visualType; config->config.renderType = renderType; config->config.drawableType = drawableType; config->config.yInverted = GL_TRUE; #ifdef COMPOSITE if (!noCompositeExtension) { /* * Here we decide what fbconfigs will be duplicated for compositing. * fgbconfigs marked with duplicatedForConf will be reserved for * compositing visuals. * It might look strange to do this decision this late when translation * from a __DRIConfig is already done, but using the __DRIConfig * accessor function becomes worse both with respect to code complexity * and CPU usage. */ if (duplicateForComp && (render_type_is_pbuffer_only(renderType) || config->config.rgbBits != 32 || config->config.redBits != 8 || config->config.greenBits != 8 || config->config.blueBits != 8 || config->config.visualRating != GLX_NONE || config->config.sampleBuffers != 0)) { free(config); return NULL; } config->config.duplicatedForComp = duplicateForComp; } #endif return &config->config; } __GLXconfig * glxConvertConfigs(const __DRIcoreExtension * core, const __DRIconfig ** configs) { __GLXconfig head, *tail; int i; tail = &head; head.next = NULL; for (i = 0; configs[i]; i++) { tail->next = createModeFromConfig(core, configs[i], GLX_TRUE_COLOR, GL_FALSE); if (tail->next == NULL) break; tail = tail->next; } for (i = 0; configs[i]; i++) { tail->next = createModeFromConfig(core, configs[i], GLX_DIRECT_COLOR, GL_FALSE); if (tail->next == NULL) break; tail = tail->next; } #ifdef COMPOSITE if (!noCompositeExtension) { /* Duplicate fbconfigs for use with compositing visuals */ for (i = 0; configs[i]; i++) { tail->next = createModeFromConfig(core, configs[i], GLX_TRUE_COLOR, GL_TRUE); if (tail->next == NULL) continue; tail = tail->next; } } #endif return head.next; } static const char dri_driver_path[] = DRI_DRIVER_PATH; /* Temporary define to allow building without a dri_interface.h from * updated Mesa. Some day when we don't care about Mesa that old any * more this can be removed. */ #ifndef __DRI_DRIVER_GET_EXTENSIONS #define __DRI_DRIVER_GET_EXTENSIONS "__driDriverGetExtensions" #endif void * glxProbeDriver(const char *driverName, void **coreExt, const char *coreName, int coreVersion, void **renderExt, const char *renderName, int renderVersion) { int i; void *driver; char filename[PATH_MAX]; char *get_extensions_name; const __DRIextension **extensions = NULL; const char *path = NULL; /* Search in LIBGL_DRIVERS_PATH if we're not setuid. */ if (!PrivsElevated()) path = getenv("LIBGL_DRIVERS_PATH"); if (!path) path = dri_driver_path; do { const char *next; int path_len; next = strchr(path, ':'); if (next) { path_len = next - path; next++; } else { path_len = strlen(path); next = NULL; } snprintf(filename, sizeof filename, "%.*s/%s_dri.so", path_len, path, driverName); driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); if (driver != NULL) break; LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n", filename, dlerror()); path = next; } while (path); if (driver == NULL) { LogMessage(X_ERROR, "AIGLX error: unable to load driver %s\n", driverName); goto cleanup_failure; } if (asprintf(&get_extensions_name, "%s_%s", __DRI_DRIVER_GET_EXTENSIONS, driverName) != -1) { const __DRIextension **(*get_extensions)(void); for (i = 0; i < strlen(get_extensions_name); i++) { /* Replace all non-alphanumeric characters with underscore, * since they are not allowed in C symbol names. That fixes up * symbol name for drivers with '-drm' suffix */ if (!isalnum(get_extensions_name[i])) get_extensions_name[i] = '_'; } get_extensions = dlsym(driver, get_extensions_name); if (get_extensions) extensions = get_extensions(); free(get_extensions_name); } if (!extensions) extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS); if (extensions == NULL) { LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", driverName, dlerror()); goto cleanup_failure; } for (i = 0; extensions[i]; i++) { if (strcmp(extensions[i]->name, coreName) == 0 && extensions[i]->version >= coreVersion) { *coreExt = (void *) extensions[i]; } if (strcmp(extensions[i]->name, renderName) == 0 && extensions[i]->version >= renderVersion) { *renderExt = (void *) extensions[i]; } } if (*coreExt == NULL || *renderExt == NULL) { LogMessage(X_ERROR, "AIGLX error: %s does not export required DRI extension\n", driverName); goto cleanup_failure; } return driver; cleanup_failure: if (driver) dlclose(driver); *coreExt = *renderExt = NULL; return NULL; } xorg-server-1.20.13/glx/glxdricommon.h0000644000175000017500000000331214100573756014536 00000000000000/* * Copyright © 2008 Red Hat, 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 the * copyright holders not be used in advertising or publicity * pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #ifndef _GLX_dri_common_h #define _GLX_dri_common_h typedef struct __GLXDRIconfig __GLXDRIconfig; struct __GLXDRIconfig { __GLXconfig config; const __DRIconfig *driConfig; }; __GLXconfig *glxConvertConfigs(const __DRIcoreExtension * core, const __DRIconfig ** configs); void *glxProbeDriver(const char *name, void **coreExt, const char *coreName, int coreVersion, void **renderExt, const char *renderName, int renderVersion); #endif xorg-server-1.20.13/glx/glxscreens.c0000644000175000017500000003320414100573756014207 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include #include #include "extinit.h" #include "privates.h" #include "glxserver.h" #include "glxutil.h" #include "glxext.h" #include "protocol-versions.h" #ifdef COMPOSITE #include "compositeext.h" #endif static DevPrivateKeyRec glxScreenPrivateKeyRec; #define glxScreenPrivateKey (&glxScreenPrivateKeyRec) const char GLServerVersion[] = "1.4"; static const char GLServerExtensions[] = "GL_ARB_depth_texture " "GL_ARB_draw_buffers " "GL_ARB_fragment_program " "GL_ARB_fragment_program_shadow " "GL_ARB_imaging " "GL_ARB_multisample " "GL_ARB_multitexture " "GL_ARB_occlusion_query " "GL_ARB_point_parameters " "GL_ARB_point_sprite " "GL_ARB_shadow " "GL_ARB_shadow_ambient " "GL_ARB_texture_border_clamp " "GL_ARB_texture_compression " "GL_ARB_texture_cube_map " "GL_ARB_texture_env_add " "GL_ARB_texture_env_combine " "GL_ARB_texture_env_crossbar " "GL_ARB_texture_env_dot3 " "GL_ARB_texture_mirrored_repeat " "GL_ARB_texture_non_power_of_two " "GL_ARB_transpose_matrix " "GL_ARB_vertex_program " "GL_ARB_window_pos " "GL_EXT_abgr " "GL_EXT_bgra " "GL_EXT_blend_color " "GL_EXT_blend_equation_separate " "GL_EXT_blend_func_separate " "GL_EXT_blend_logic_op " "GL_EXT_blend_minmax " "GL_EXT_blend_subtract " "GL_EXT_clip_volume_hint " "GL_EXT_copy_texture " "GL_EXT_draw_range_elements " "GL_EXT_fog_coord " "GL_EXT_framebuffer_object " "GL_EXT_multi_draw_arrays " "GL_EXT_packed_pixels " "GL_EXT_paletted_texture " "GL_EXT_point_parameters " "GL_EXT_polygon_offset " "GL_EXT_rescale_normal " "GL_EXT_secondary_color " "GL_EXT_separate_specular_color " "GL_EXT_shadow_funcs " "GL_EXT_shared_texture_palette " "GL_EXT_stencil_two_side " "GL_EXT_stencil_wrap " "GL_EXT_subtexture " "GL_EXT_texture " "GL_EXT_texture3D " "GL_EXT_texture_compression_dxt1 " "GL_EXT_texture_compression_s3tc " "GL_EXT_texture_edge_clamp " "GL_EXT_texture_env_add " "GL_EXT_texture_env_combine " "GL_EXT_texture_env_dot3 " "GL_EXT_texture_filter_anisotropic " "GL_EXT_texture_lod " "GL_EXT_texture_lod_bias " "GL_EXT_texture_mirror_clamp " "GL_EXT_texture_object " "GL_EXT_texture_rectangle " "GL_EXT_vertex_array " "GL_3DFX_texture_compression_FXT1 " "GL_APPLE_packed_pixels " "GL_ATI_draw_buffers " "GL_ATI_texture_env_combine3 " "GL_ATI_texture_mirror_once " "GL_HP_occlusion_test " "GL_IBM_texture_mirrored_repeat " "GL_INGR_blend_func_separate " "GL_MESA_pack_invert " "GL_MESA_ycbcr_texture " "GL_NV_blend_square " "GL_NV_depth_clamp " "GL_NV_fog_distance " "GL_NV_fragment_program_option " "GL_NV_fragment_program2 " "GL_NV_light_max_exponent " "GL_NV_multisample_filter_hint " "GL_NV_point_sprite " "GL_NV_texgen_reflection " "GL_NV_texture_compression_vtc " "GL_NV_texture_env_combine4 " "GL_NV_texture_expand_normal " "GL_NV_texture_rectangle " "GL_NV_vertex_program2_option " "GL_NV_vertex_program3 " "GL_OES_compressed_paletted_texture " "GL_SGI_color_matrix " "GL_SGI_color_table " "GL_SGIS_generate_mipmap " "GL_SGIS_multisample " "GL_SGIS_point_parameters " "GL_SGIS_texture_border_clamp " "GL_SGIS_texture_edge_clamp " "GL_SGIS_texture_lod " "GL_SGIX_depth_texture " "GL_SGIX_shadow " "GL_SGIX_shadow_ambient " "GL_SUN_slice_accum "; static Bool glxCloseScreen(ScreenPtr pScreen) { __GLXscreen *pGlxScreen = glxGetScreen(pScreen); pScreen->CloseScreen = pGlxScreen->CloseScreen; pGlxScreen->destroy(pGlxScreen); return pScreen->CloseScreen(pScreen); } __GLXscreen * glxGetScreen(ScreenPtr pScreen) { return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey); } GLint glxConvertToXVisualType(int visualType) { static const int x_visual_types[] = { TrueColor, DirectColor, PseudoColor, StaticColor, GrayScale, StaticGray }; return ((unsigned) (visualType - GLX_TRUE_COLOR) < 6) ? x_visual_types[visualType - GLX_TRUE_COLOR] : -1; } /* This code inspired by composite/compinit.c. We could move this to * mi/ and share it with composite.*/ static VisualPtr AddScreenVisuals(ScreenPtr pScreen, int count, int d) { int i; DepthPtr depth; depth = NULL; for (i = 0; i < pScreen->numDepths; i++) { if (pScreen->allowedDepths[i].depth == d) { depth = &pScreen->allowedDepths[i]; break; } } if (depth == NULL) return NULL; if (ResizeVisualArray(pScreen, count, depth) == FALSE) return NULL; /* Return a pointer to the first of the added visuals. */ return pScreen->visuals + pScreen->numVisuals - count; } static int findFirstSet(unsigned int v) { int i; for (i = 0; i < 32; i++) if (v & (1 << i)) return i; return -1; } static void initGlxVisual(VisualPtr visual, __GLXconfig * config) { int maxBits; maxBits = max(config->redBits, max(config->greenBits, config->blueBits)); config->visualID = visual->vid; visual->class = glxConvertToXVisualType(config->visualType); visual->bitsPerRGBValue = maxBits; visual->ColormapEntries = 1 << maxBits; visual->nplanes = config->redBits + config->greenBits + config->blueBits; visual->redMask = config->redMask; visual->greenMask = config->greenMask; visual->blueMask = config->blueMask; visual->offsetRed = findFirstSet(config->redMask); visual->offsetGreen = findFirstSet(config->greenMask); visual->offsetBlue = findFirstSet(config->blueMask); } static __GLXconfig * pickFBConfig(__GLXscreen * pGlxScreen, VisualPtr visual) { __GLXconfig *best = NULL, *config; int best_score = 0; for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { int score = 0; if (config->redMask != visual->redMask || config->greenMask != visual->greenMask || config->blueMask != visual->blueMask) continue; if (config->visualRating != GLX_NONE) continue; /* Ignore multisampled configs */ if (config->sampleBuffers) continue; if (glxConvertToXVisualType(config->visualType) != visual->class) continue; /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */ if (visual->nplanes == 32 && config->rgbBits != 32) continue; /* If it's the 32-bit RGBA visual, do not pick sRGB capable config. * This can cause issues with compositors that are not sRGB aware. */ if (visual->nplanes == 32 && config->sRGBCapable == GL_TRUE) continue; /* Can't use the same FBconfig for multiple X visuals. I think. */ if (config->visualID != 0) continue; #ifdef COMPOSITE if (!noCompositeExtension) { /* Use only duplicated configs for compIsAlternateVisuals */ if (!!compIsAlternateVisual(pGlxScreen->pScreen, visual->vid) != !!config->duplicatedForComp) continue; } #endif /* * If possible, use the same swapmethod for all built-in visual * fbconfigs, to avoid getting the 32-bit composite visual when * requesting, for example, a SWAP_COPY fbconfig. */ if (config->swapMethod == GLX_SWAP_UNDEFINED_OML) score += 32; if (config->swapMethod == GLX_SWAP_EXCHANGE_OML) score += 16; if (config->doubleBufferMode > 0) score += 8; if (config->depthBits > 0) score += 4; if (config->stencilBits > 0) score += 2; if (config->alphaBits > 0) score++; if (score > best_score) { best = config; best_score = score; } } return best; } void __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen) { __GLXconfig *m; __GLXconfig *config; int i; if (!dixRegisterPrivateKey(&glxScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) return; pGlxScreen->pScreen = pScreen; pGlxScreen->GLextensions = strdup(GLServerExtensions); pGlxScreen->GLXextensions = NULL; pGlxScreen->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = glxCloseScreen; i = 0; for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) { m->fbconfigID = FakeClientID(0); m->visualID = 0; i++; } pGlxScreen->numFBConfigs = i; pGlxScreen->visuals = calloc(pGlxScreen->numFBConfigs, sizeof(__GLXconfig *)); /* First, try to choose featureful FBconfigs for the existing X visuals. * Note that if multiple X visuals end up with the same FBconfig being * chosen, the later X visuals don't get GLX visuals (because we want to * prioritize the root visual being GLX). */ for (i = 0; i < pScreen->numVisuals; i++) { VisualPtr visual = &pScreen->visuals[i]; config = pickFBConfig(pGlxScreen, visual); if (config) { pGlxScreen->visuals[pGlxScreen->numVisuals++] = config; config->visualID = visual->vid; #ifdef COMPOSITE if (!noCompositeExtension) { if (compIsAlternateVisual(pScreen, visual->vid)) config->visualSelectGroup++; } #endif } } /* Then, add new visuals corresponding to all FBconfigs that didn't have * an existing, appropriate visual. */ for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { int depth; VisualPtr visual; if (config->visualID != 0) continue; /* Only count RGB bits and not alpha, as we're not trying to create * visuals for compositing (that's what the 32-bit composite visual * set up above is for. */ depth = config->redBits + config->greenBits + config->blueBits; #ifdef COMPOSITE if (!noCompositeExtension) { if (config->duplicatedForComp) { depth += config->alphaBits; config->visualSelectGroup++; } } #endif /* Make sure that our FBconfig's depth can actually be displayed * (corresponds to an existing visual). */ for (i = 0; i < pScreen->numVisuals; i++) { if (depth == pScreen->visuals[i].nplanes) break; } /* if it can't, fix up the fbconfig to not advertise window support */ if (i == pScreen->numVisuals) config->drawableType &= ~(GLX_WINDOW_BIT); /* fbconfig must support window drawables */ if (!(config->drawableType & GLX_WINDOW_BIT)) { config->visualID = 0; continue; } /* Create a new X visual for our FBconfig. */ visual = AddScreenVisuals(pScreen, 1, depth); if (visual == NULL) continue; #ifdef COMPOSITE if (!noCompositeExtension) { if (config->duplicatedForComp) (void) CompositeRegisterAlternateVisuals(pScreen, &visual->vid, 1); } #endif pGlxScreen->visuals[pGlxScreen->numVisuals++] = config; initGlxVisual(visual, config); } dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen); if (pGlxScreen->glvnd) __glXEnableExtension(pGlxScreen->glx_enable_bits, "GLX_EXT_libglvnd"); i = __glXGetExtensionString(pGlxScreen->glx_enable_bits, NULL); if (i > 0) { pGlxScreen->GLXextensions = xnfalloc(i); (void) __glXGetExtensionString(pGlxScreen->glx_enable_bits, pGlxScreen->GLXextensions); } } void __glXScreenDestroy(__GLXscreen * screen) { __GLXconfig *config, *next; free(screen->glvnd); free(screen->GLXextensions); free(screen->GLextensions); free(screen->visuals); for (config = screen->fbconfigs; config != NULL; config = next) { next = config->next; free(config); } } xorg-server-1.20.13/glx/glxscreens.h0000644000175000017500000001221414100573756014212 00000000000000#ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef _GLX_screens_h_ #define _GLX_screens_h_ /* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #include "extension_string.h" #include "glxvndabi.h" typedef struct __GLXconfig __GLXconfig; struct __GLXconfig { /* Management */ __GLXconfig *next; #ifdef COMPOSITE GLboolean duplicatedForComp; #endif GLuint doubleBufferMode; GLuint stereoMode; GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ GLuint redMask, greenMask, blueMask, alphaMask; GLint rgbBits; /* total bits for rgb */ GLint indexBits; /* total bits for colorindex */ GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; GLint depthBits; GLint stencilBits; GLint numAuxBuffers; GLint level; /* GLX */ GLint visualID; GLint visualType; /**< One of the GLX X visual types. (i.e., * \c GLX_TRUE_COLOR, etc.) */ /* EXT_visual_rating / GLX 1.2 */ GLint visualRating; /* EXT_visual_info / GLX 1.2 */ GLint transparentPixel; /* colors are floats scaled to ints */ GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha; GLint transparentIndex; /* ARB_multisample / SGIS_multisample */ GLint sampleBuffers; GLint samples; /* SGIX_fbconfig / GLX 1.3 */ GLint drawableType; GLint renderType; GLint fbconfigID; /* SGIX_pbuffer / GLX 1.3 */ GLint maxPbufferWidth; GLint maxPbufferHeight; GLint maxPbufferPixels; GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */ GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */ /* SGIX_visual_select_group */ GLint visualSelectGroup; /* OML_swap_method */ GLint swapMethod; /* EXT_texture_from_pixmap */ GLint bindToTextureRgb; GLint bindToTextureRgba; GLint bindToMipmapTexture; GLint bindToTextureTargets; GLint yInverted; /* ARB_framebuffer_sRGB */ GLint sRGBCapable; }; GLint glxConvertToXVisualType(int visualType); /* ** Screen dependent data. These methods are the interface between the DIX ** and DDX layers of the GLX server extension. The methods provide an ** interface for context management on a screen. */ typedef struct __GLXscreen __GLXscreen; struct __GLXscreen { void (*destroy) (__GLXscreen * screen); __GLXcontext *(*createContext) (__GLXscreen * screen, __GLXconfig * modes, __GLXcontext * shareContext, unsigned num_attribs, const uint32_t *attribs, int *error); __GLXdrawable *(*createDrawable) (ClientPtr client, __GLXscreen * context, DrawablePtr pDraw, XID drawId, int type, XID glxDrawId, __GLXconfig * modes); int (*swapInterval) (__GLXdrawable * drawable, int interval); ScreenPtr pScreen; /* Linked list of valid fbconfigs for this screen. */ __GLXconfig *fbconfigs; int numFBConfigs; /* Subset of fbconfigs that are exposed as GLX visuals. */ __GLXconfig **visuals; GLint numVisuals; char *GLextensions; char *GLXextensions; char *glvnd; unsigned char glx_enable_bits[__GLX_EXT_BYTES]; Bool (*CloseScreen) (ScreenPtr pScreen); }; void __glXScreenInit(__GLXscreen * screen, ScreenPtr pScreen); void __glXScreenDestroy(__GLXscreen * screen); #endif /* !__GLX_screens_h__ */ xorg-server-1.20.13/glx/glxserver.h0000644000175000017500000001266014100573756014063 00000000000000#ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef _GLX_server_h_ #define _GLX_server_h_ /* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef GLX_CONTEXT_OPENGL_NO_ERROR_ARB #define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 #endif /* ** GLX resources. */ typedef XID GLXContextID; typedef XID GLXDrawable; typedef struct __GLXclientStateRec __GLXclientState; typedef struct __GLXdrawable __GLXdrawable; typedef struct __GLXcontext __GLXcontext; #include "glxscreens.h" #include "glxdrawable.h" #include "glxcontext.h" #include "glx_extinit.h" extern __GLXscreen *glxGetScreen(ScreenPtr pScreen); extern __GLXclientState *glxGetClient(ClientPtr pClient); /************************************************************************/ void __glXScreenInitVisuals(__GLXscreen * screen); /* ** The last context used (from the server's persective) is cached. */ extern __GLXcontext *__glXForceCurrent(__GLXclientState *, GLXContextTag, int *); int __glXError(int error); /************************************************************************/ enum { GLX_MINIMAL_VISUALS, GLX_TYPICAL_VISUALS, GLX_ALL_VISUALS }; void glxSuspendClients(void); void glxResumeClients(void); typedef void (*glx_func_ptr)(void); typedef glx_func_ptr (*glx_gpa_proc)(const char *); void __glXsetGetProcAddress(glx_gpa_proc get_proc_address); void *__glGetProcAddress(const char *); void __glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust, CARD64 msc, CARD32 sbc); #if PRESENT void __glXregisterPresentCompleteNotify(void); #endif /* ** State kept per client. */ struct __GLXclientStateRec { /* ** Buffer for returned data. */ GLbyte *returnBuf; GLint returnBufSize; /* Back pointer to X client record */ ClientPtr client; char *GLClientextensions; }; /************************************************************************/ /* ** Dispatch tables. */ typedef void (*__GLXdispatchRenderProcPtr) (GLbyte *); typedef int (*__GLXdispatchSingleProcPtr) (__GLXclientState *, GLbyte *); typedef int (*__GLXdispatchVendorPrivProcPtr) (__GLXclientState *, GLbyte *); /* * Tables for computing the size of each rendering command. */ typedef int (*gl_proto_size_func) (const GLbyte *, Bool, int); typedef struct { int bytes; gl_proto_size_func varsize; } __GLXrenderSizeData; /************************************************************************/ /* ** X resources. */ extern RESTYPE __glXContextRes; extern RESTYPE __glXClientRes; extern RESTYPE __glXDrawableRes; /************************************************************************/ /* * Routines for computing the size of variably-sized rendering commands. */ static _X_INLINE int safe_add(int a, int b) { if (a < 0 || b < 0) return -1; if (INT_MAX - a < b) return -1; return a + b; } static _X_INLINE int safe_mul(int a, int b) { if (a < 0 || b < 0) return -1; if (a == 0 || b == 0) return 0; if (a > INT_MAX / b) return -1; return a * b; } static _X_INLINE int safe_pad(int a) { int ret; if (a < 0) return -1; if ((ret = safe_add(a, 3)) < 0) return -1; return ret & (GLuint)~3; } extern int __glXTypeSize(GLenum enm); extern int __glXImageSize(GLenum format, GLenum type, GLenum target, GLsizei w, GLsizei h, GLsizei d, GLint imageHeight, GLint rowLength, GLint skipImages, GLint skipRows, GLint alignment); extern unsigned glxMajorVersion; extern unsigned glxMinorVersion; extern int __glXEventBase; #endif /* !__GLX_server_h__ */ xorg-server-1.20.13/glx/glxutil.h0000644000175000017500000000431614100573756013531 00000000000000#ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef _glxcmds_h_ #define _glxcmds_h_ /* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ extern GLboolean __glXDrawableInit(__GLXdrawable * drawable, __GLXscreen * screen, DrawablePtr pDraw, int type, XID drawID, __GLXconfig * config); extern void __glXDrawableRelease(__GLXdrawable * drawable); /* context helper routines */ extern __GLXcontext *__glXLookupContextByTag(__GLXclientState *, GLXContextTag); /* init helper routines */ extern void *__glXglDDXScreenInfo(void); extern void *__glXglDDXExtensionInfo(void); #endif /* _glxcmds_h_ */ xorg-server-1.20.13/glx/render2.c0000644000175000017500000001735614100573756013405 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "unpack.h" #include "indirect_size.h" #include "indirect_dispatch.h" void __glXDisp_Map1f(GLbyte * pc) { GLint order, k; GLfloat u1, u2, *points; GLenum target; target = *(GLenum *) (pc + 0); order = *(GLint *) (pc + 12); u1 = *(GLfloat *) (pc + 4); u2 = *(GLfloat *) (pc + 8); points = (GLfloat *) (pc + 16); k = __glMap1f_size(target); glMap1f(target, u1, u2, k, order, points); } void __glXDisp_Map2f(GLbyte * pc) { GLint uorder, vorder, ustride, vstride, k; GLfloat u1, u2, v1, v2, *points; GLenum target; target = *(GLenum *) (pc + 0); uorder = *(GLint *) (pc + 12); vorder = *(GLint *) (pc + 24); u1 = *(GLfloat *) (pc + 4); u2 = *(GLfloat *) (pc + 8); v1 = *(GLfloat *) (pc + 16); v2 = *(GLfloat *) (pc + 20); points = (GLfloat *) (pc + 28); k = __glMap2f_size(target); ustride = vorder * k; vstride = k; glMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); } void __glXDisp_Map1d(GLbyte * pc) { GLint order, k; #ifdef __GLX_ALIGN64 GLint compsize; #endif GLenum target; GLdouble u1, u2, *points; target = *(GLenum *) (pc + 16); order = *(GLint *) (pc + 20); k = __glMap1d_size(target); #ifdef __GLX_ALIGN64 if (order < 0 || k < 0) { compsize = 0; } else { compsize = order * k; } #endif __GLX_GET_DOUBLE(u1, pc); __GLX_GET_DOUBLE(u2, pc + 8); pc += 24; #ifdef __GLX_ALIGN64 if (((unsigned long) pc) & 7) { /* ** Copy the doubles up 4 bytes, trashing the command but aligning ** the data in the process */ __GLX_MEM_COPY(pc - 4, pc, compsize * 8); points = (GLdouble *) (pc - 4); } else { points = (GLdouble *) pc; } #else points = (GLdouble *) pc; #endif glMap1d(target, u1, u2, k, order, points); } void __glXDisp_Map2d(GLbyte * pc) { GLdouble u1, u2, v1, v2, *points; GLint uorder, vorder, ustride, vstride, k; #ifdef __GLX_ALIGN64 GLint compsize; #endif GLenum target; target = *(GLenum *) (pc + 32); uorder = *(GLint *) (pc + 36); vorder = *(GLint *) (pc + 40); k = __glMap2d_size(target); #ifdef __GLX_ALIGN64 if (vorder < 0 || uorder < 0 || k < 0) { compsize = 0; } else { compsize = uorder * vorder * k; } #endif __GLX_GET_DOUBLE(u1, pc); __GLX_GET_DOUBLE(u2, pc + 8); __GLX_GET_DOUBLE(v1, pc + 16); __GLX_GET_DOUBLE(v2, pc + 24); pc += 44; ustride = vorder * k; vstride = k; #ifdef __GLX_ALIGN64 if (((unsigned long) pc) & 7) { /* ** Copy the doubles up 4 bytes, trashing the command but aligning ** the data in the process */ __GLX_MEM_COPY(pc - 4, pc, compsize * 8); points = (GLdouble *) (pc - 4); } else { points = (GLdouble *) pc; } #else points = (GLdouble *) pc; #endif glMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); } void __glXDisp_DrawArrays(GLbyte * pc) { __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc; __GLXdispatchDrawArraysComponentHeader *compHeader; GLint numVertexes = hdr->numVertexes; GLint numComponents = hdr->numComponents; GLenum primType = hdr->primType; GLint stride = 0; int i; pc += sizeof(__GLXdispatchDrawArraysHeader); compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc; /* compute stride (same for all component arrays) */ for (i = 0; i < numComponents; i++) { GLenum datatype = compHeader[i].datatype; GLint numVals = compHeader[i].numVals; stride += __GLX_PAD(numVals * __glXTypeSize(datatype)); } pc += numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader); /* set up component arrays */ for (i = 0; i < numComponents; i++) { GLenum datatype = compHeader[i].datatype; GLint numVals = compHeader[i].numVals; GLenum component = compHeader[i].component; switch (component) { case GL_VERTEX_ARRAY: glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(numVals, datatype, stride, pc); break; case GL_NORMAL_ARRAY: glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(datatype, stride, pc); break; case GL_COLOR_ARRAY: glEnableClientState(GL_COLOR_ARRAY); glColorPointer(numVals, datatype, stride, pc); break; case GL_INDEX_ARRAY: glEnableClientState(GL_INDEX_ARRAY); glIndexPointer(datatype, stride, pc); break; case GL_TEXTURE_COORD_ARRAY: glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(numVals, datatype, stride, pc); break; case GL_EDGE_FLAG_ARRAY: glEnableClientState(GL_EDGE_FLAG_ARRAY); glEdgeFlagPointer(stride, (const GLboolean *) pc); break; case GL_SECONDARY_COLOR_ARRAY: { PFNGLSECONDARYCOLORPOINTERPROC SecondaryColorPointerEXT = __glGetProcAddress("glSecondaryColorPointerEXT"); glEnableClientState(GL_SECONDARY_COLOR_ARRAY); SecondaryColorPointerEXT(numVals, datatype, stride, pc); break; } case GL_FOG_COORD_ARRAY: { PFNGLFOGCOORDPOINTERPROC FogCoordPointerEXT = __glGetProcAddress("glFogCoordPointerEXT"); glEnableClientState(GL_FOG_COORD_ARRAY); FogCoordPointerEXT(datatype, stride, pc); break; } default: break; } pc += __GLX_PAD(numVals * __glXTypeSize(datatype)); } glDrawArrays(primType, 0, numVertexes); /* turn off anything we might have turned on */ glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_INDEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_EDGE_FLAG_ARRAY); glDisableClientState(GL_SECONDARY_COLOR_ARRAY); glDisableClientState(GL_FOG_COORD_ARRAY); } xorg-server-1.20.13/glx/render2swap.c0000644000175000017500000002575114100573756014276 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "unpack.h" #include "indirect_size.h" #include "indirect_dispatch.h" void __glXDispSwap_Map1f(GLbyte * pc) { GLint order, k; GLfloat u1, u2, *points; GLenum target; GLint compsize; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 12); __GLX_SWAP_FLOAT(pc + 4); __GLX_SWAP_FLOAT(pc + 8); target = *(GLenum *) (pc + 0); order = *(GLint *) (pc + 12); u1 = *(GLfloat *) (pc + 4); u2 = *(GLfloat *) (pc + 8); points = (GLfloat *) (pc + 16); k = __glMap1f_size(target); if (order <= 0 || k < 0) { /* Erroneous command. */ compsize = 0; } else { compsize = order * k; } __GLX_SWAP_FLOAT_ARRAY(points, compsize); glMap1f(target, u1, u2, k, order, points); } void __glXDispSwap_Map2f(GLbyte * pc) { GLint uorder, vorder, ustride, vstride, k; GLfloat u1, u2, v1, v2, *points; GLenum target; GLint compsize; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 12); __GLX_SWAP_INT(pc + 24); __GLX_SWAP_FLOAT(pc + 4); __GLX_SWAP_FLOAT(pc + 8); __GLX_SWAP_FLOAT(pc + 16); __GLX_SWAP_FLOAT(pc + 20); target = *(GLenum *) (pc + 0); uorder = *(GLint *) (pc + 12); vorder = *(GLint *) (pc + 24); u1 = *(GLfloat *) (pc + 4); u2 = *(GLfloat *) (pc + 8); v1 = *(GLfloat *) (pc + 16); v2 = *(GLfloat *) (pc + 20); points = (GLfloat *) (pc + 28); k = __glMap2f_size(target); ustride = vorder * k; vstride = k; if (vorder <= 0 || uorder <= 0 || k < 0) { /* Erroneous command. */ compsize = 0; } else { compsize = uorder * vorder * k; } __GLX_SWAP_FLOAT_ARRAY(points, compsize); glMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); } void __glXDispSwap_Map1d(GLbyte * pc) { GLint order, k, compsize; GLenum target; GLdouble u1, u2, *points; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_SWAP_DOUBLE(pc + 0); __GLX_SWAP_DOUBLE(pc + 8); __GLX_SWAP_INT(pc + 16); __GLX_SWAP_INT(pc + 20); target = *(GLenum *) (pc + 16); order = *(GLint *) (pc + 20); k = __glMap1d_size(target); if (order <= 0 || k < 0) { /* Erroneous command. */ compsize = 0; } else { compsize = order * k; } __GLX_GET_DOUBLE(u1, pc); __GLX_GET_DOUBLE(u2, pc + 8); __GLX_SWAP_DOUBLE_ARRAY(pc + 24, compsize); pc += 24; #ifdef __GLX_ALIGN64 if (((unsigned long) pc) & 7) { /* ** Copy the doubles up 4 bytes, trashing the command but aligning ** the data in the process */ __GLX_MEM_COPY(pc - 4, pc, compsize * 8); points = (GLdouble *) (pc - 4); } else { points = (GLdouble *) pc; } #else points = (GLdouble *) pc; #endif glMap1d(target, u1, u2, k, order, points); } void __glXDispSwap_Map2d(GLbyte * pc) { GLdouble u1, u2, v1, v2, *points; GLint uorder, vorder, ustride, vstride, k, compsize; GLenum target; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_SWAP_DOUBLE(pc + 0); __GLX_SWAP_DOUBLE(pc + 8); __GLX_SWAP_DOUBLE(pc + 16); __GLX_SWAP_DOUBLE(pc + 24); __GLX_SWAP_INT(pc + 32); __GLX_SWAP_INT(pc + 36); __GLX_SWAP_INT(pc + 40); target = *(GLenum *) (pc + 32); uorder = *(GLint *) (pc + 36); vorder = *(GLint *) (pc + 40); k = __glMap2d_size(target); if (vorder <= 0 || uorder <= 0 || k < 0) { /* Erroneous command. */ compsize = 0; } else { compsize = uorder * vorder * k; } __GLX_GET_DOUBLE(u1, pc); __GLX_GET_DOUBLE(u2, pc + 8); __GLX_GET_DOUBLE(v1, pc + 16); __GLX_GET_DOUBLE(v2, pc + 24); __GLX_SWAP_DOUBLE_ARRAY(pc + 44, compsize); pc += 44; ustride = vorder * k; vstride = k; #ifdef __GLX_ALIGN64 if (((unsigned long) pc) & 7) { /* ** Copy the doubles up 4 bytes, trashing the command but aligning ** the data in the process */ __GLX_MEM_COPY(pc - 4, pc, compsize * 8); points = (GLdouble *) (pc - 4); } else { points = (GLdouble *) pc; } #else points = (GLdouble *) pc; #endif glMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); } static void swapArray(GLint numVals, GLenum datatype, GLint stride, GLint numVertexes, GLbyte * pc) { int i, j; __GLX_DECLARE_SWAP_VARIABLES; switch (datatype) { case GL_BYTE: case GL_UNSIGNED_BYTE: /* don't need to swap */ return; case GL_SHORT: case GL_UNSIGNED_SHORT: for (i = 0; i < numVertexes; i++) { GLshort *pVal = (GLshort *) pc; for (j = 0; j < numVals; j++) { __GLX_SWAP_SHORT(&pVal[j]); } pc += stride; } break; case GL_INT: case GL_UNSIGNED_INT: for (i = 0; i < numVertexes; i++) { GLint *pVal = (GLint *) pc; for (j = 0; j < numVals; j++) { __GLX_SWAP_INT(&pVal[j]); } pc += stride; } break; case GL_FLOAT: for (i = 0; i < numVertexes; i++) { GLfloat *pVal = (GLfloat *) pc; for (j = 0; j < numVals; j++) { __GLX_SWAP_FLOAT(&pVal[j]); } pc += stride; } break; case GL_DOUBLE: for (i = 0; i < numVertexes; i++) { GLdouble *pVal = (GLdouble *) pc; for (j = 0; j < numVals; j++) { __GLX_SWAP_DOUBLE(&pVal[j]); } pc += stride; } break; default: return; } } void __glXDispSwap_DrawArrays(GLbyte * pc) { __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc; __GLXdispatchDrawArraysComponentHeader *compHeader; GLint numVertexes = hdr->numVertexes; GLint numComponents = hdr->numComponents; GLenum primType = hdr->primType; GLint stride = 0; int i; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_INT(&numVertexes); __GLX_SWAP_INT(&numComponents); __GLX_SWAP_INT(&primType); pc += sizeof(__GLXdispatchDrawArraysHeader); compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc; /* compute stride (same for all component arrays) */ for (i = 0; i < numComponents; i++) { GLenum datatype = compHeader[i].datatype; GLint numVals = compHeader[i].numVals; GLenum component = compHeader[i].component; __GLX_SWAP_INT(&datatype); __GLX_SWAP_INT(&numVals); __GLX_SWAP_INT(&component); stride += __GLX_PAD(numVals * __glXTypeSize(datatype)); } pc += numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader); /* set up component arrays */ for (i = 0; i < numComponents; i++) { GLenum datatype = compHeader[i].datatype; GLint numVals = compHeader[i].numVals; GLenum component = compHeader[i].component; __GLX_SWAP_INT(&datatype); __GLX_SWAP_INT(&numVals); __GLX_SWAP_INT(&component); swapArray(numVals, datatype, stride, numVertexes, pc); switch (component) { case GL_VERTEX_ARRAY: glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(numVals, datatype, stride, pc); break; case GL_NORMAL_ARRAY: glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(datatype, stride, pc); break; case GL_COLOR_ARRAY: glEnableClientState(GL_COLOR_ARRAY); glColorPointer(numVals, datatype, stride, pc); break; case GL_INDEX_ARRAY: glEnableClientState(GL_INDEX_ARRAY); glIndexPointer(datatype, stride, pc); break; case GL_TEXTURE_COORD_ARRAY: glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(numVals, datatype, stride, pc); break; case GL_EDGE_FLAG_ARRAY: glEnableClientState(GL_EDGE_FLAG_ARRAY); glEdgeFlagPointer(stride, (const GLboolean *) pc); break; case GL_SECONDARY_COLOR_ARRAY: { PFNGLSECONDARYCOLORPOINTERPROC SecondaryColorPointerEXT = __glGetProcAddress("glSecondaryColorPointerEXT"); glEnableClientState(GL_SECONDARY_COLOR_ARRAY); SecondaryColorPointerEXT(numVals, datatype, stride, pc); break; } case GL_FOG_COORD_ARRAY: { PFNGLFOGCOORDPOINTERPROC FogCoordPointerEXT = __glGetProcAddress("glFogCoordPointerEXT"); glEnableClientState(GL_FOG_COORD_ARRAY); FogCoordPointerEXT(datatype, stride, pc); break; } default: break; } pc += __GLX_PAD(numVals * __glXTypeSize(datatype)); } glDrawArrays(primType, 0, numVertexes); /* turn off anything we might have turned on */ glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_INDEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_EDGE_FLAG_ARRAY); glDisableClientState(GL_SECONDARY_COLOR_ARRAY); glDisableClientState(GL_FOG_COORD_ARRAY); } xorg-server-1.20.13/glx/renderpix.c0000644000175000017500000000547014100573756014036 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "unpack.h" #include "indirect_dispatch.h" void __glXDisp_SeparableFilter2D(GLbyte * pc) { __GLXdispatchConvolutionFilterHeader *hdr = (__GLXdispatchConvolutionFilterHeader *) pc; GLint hdrlen, image1len; hdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_DISPATCH_HDR_SIZE); glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment); /* XXX check this usage - internal code called ** a version without the packing parameters */ image1len = __glXImageSize(hdr->format, hdr->type, 0, hdr->width, 1, 1, 0, hdr->rowLength, 0, hdr->skipRows, hdr->alignment); image1len = __GLX_PAD(image1len); glSeparableFilter2D(hdr->target, hdr->internalformat, hdr->width, hdr->height, hdr->format, hdr->type, ((GLubyte *) hdr + hdrlen), ((GLubyte *) hdr + hdrlen + image1len)); } xorg-server-1.20.13/glx/renderpixswap.c0000644000175000017500000000664214100573756014733 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "unpack.h" #include "indirect_dispatch.h" void __glXDispSwap_SeparableFilter2D(GLbyte * pc) { __GLXdispatchConvolutionFilterHeader *hdr = (__GLXdispatchConvolutionFilterHeader *) pc; GLint hdrlen, image1len; __GLX_DECLARE_SWAP_VARIABLES; hdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_HDR_SIZE); __GLX_SWAP_INT((GLbyte *) &hdr->rowLength); __GLX_SWAP_INT((GLbyte *) &hdr->skipRows); __GLX_SWAP_INT((GLbyte *) &hdr->skipPixels); __GLX_SWAP_INT((GLbyte *) &hdr->alignment); __GLX_SWAP_INT((GLbyte *) &hdr->target); __GLX_SWAP_INT((GLbyte *) &hdr->internalformat); __GLX_SWAP_INT((GLbyte *) &hdr->width); __GLX_SWAP_INT((GLbyte *) &hdr->height); __GLX_SWAP_INT((GLbyte *) &hdr->format); __GLX_SWAP_INT((GLbyte *) &hdr->type); /* ** Just invert swapBytes flag; the GL will figure out if it needs to swap ** the pixel data. */ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes); glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength); glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels); glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment); /* XXX check this usage - internal code called ** a version without the packing parameters */ image1len = __glXImageSize(hdr->format, hdr->type, 0, hdr->width, 1, 1, 0, hdr->rowLength, 0, hdr->skipRows, hdr->alignment); image1len = __GLX_PAD(image1len); glSeparableFilter2D(hdr->target, hdr->internalformat, hdr->width, hdr->height, hdr->format, hdr->type, ((GLubyte *) hdr + hdrlen), ((GLubyte *) hdr + hdrlen + image1len)); } xorg-server-1.20.13/glx/rensize.c0000644000175000017500000003472314100573756013520 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "glxserver.h" #include "GL/glxproto.h" #include "unpack.h" #include "indirect_size.h" #include "indirect_reqsize.h" #define SWAPL(a) \ (((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \ ((a & 0xff00U)<<8) | ((a & 0xffU)<<24)) int __glXMap1dReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum target; GLint order; target = *(GLenum *) (pc + 16); order = *(GLint *) (pc + 20); if (swap) { target = SWAPL(target); order = SWAPL(order); } if (order < 1) return -1; return safe_mul(8, safe_mul(__glMap1d_size(target), order)); } int __glXMap1fReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum target; GLint order; target = *(GLenum *) (pc + 0); order = *(GLint *) (pc + 12); if (swap) { target = SWAPL(target); order = SWAPL(order); } if (order < 1) return -1; return safe_mul(4, safe_mul(__glMap1f_size(target), order)); } static int Map2Size(int k, int majorOrder, int minorOrder) { if (majorOrder < 1 || minorOrder < 1) return -1; return safe_mul(k, safe_mul(majorOrder, minorOrder)); } int __glXMap2dReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum target; GLint uorder, vorder; target = *(GLenum *) (pc + 32); uorder = *(GLint *) (pc + 36); vorder = *(GLint *) (pc + 40); if (swap) { target = SWAPL(target); uorder = SWAPL(uorder); vorder = SWAPL(vorder); } return safe_mul(8, Map2Size(__glMap2d_size(target), uorder, vorder)); } int __glXMap2fReqSize(const GLbyte * pc, Bool swap, int reqlen) { GLenum target; GLint uorder, vorder; target = *(GLenum *) (pc + 0); uorder = *(GLint *) (pc + 12); vorder = *(GLint *) (pc + 24); if (swap) { target = SWAPL(target); uorder = SWAPL(uorder); vorder = SWAPL(vorder); } return safe_mul(4, Map2Size(__glMap2f_size(target), uorder, vorder)); } /** * Calculate the size of an image. * * The size of an image sent to the server from the client or sent from the * server to the client is calculated. The size is based on the dimensions * of the image, the type of pixel data, padding in the image, and the * alignment requirements of the image. * * \param format Format of the pixels. Same as the \c format parameter * to \c glTexImage1D * \param type Type of the pixel data. Same as the \c type parameter * to \c glTexImage1D * \param target Typically the texture target of the image. If the * target is one of \c GL_PROXY_*, the size returned is * always zero. For uses that do not have a texture target * (e.g, glDrawPixels), zero should be specified. * \param w Width of the image data. Must be >= 1. * \param h Height of the image data. Must be >= 1, even for 1D * images. * \param d Depth of the image data. Must be >= 1, even for 1D or * 2D images. * \param imageHeight If non-zero, defines the true height of a volumetric * image. This value will be used instead of \c h for * calculating the size of the image. * \param rowLength If non-zero, defines the true width of an image. This * value will be used instead of \c w for calculating the * size of the image. * \param skipImages Number of extra layers of image data in a volumtric * image that are to be skipped before the real data. * \param skipRows Number of extra rows of image data in an image that are * to be skipped before the real data. * \param alignment Specifies the alignment for the start of each pixel row * in memory. This value must be one of 1, 2, 4, or 8. * * \returns * The size of the image is returned. If the specified \c format and \c type * are invalid, -1 is returned. If \c target is one of \c GL_PROXY_*, zero * is returned. */ int __glXImageSize(GLenum format, GLenum type, GLenum target, GLsizei w, GLsizei h, GLsizei d, GLint imageHeight, GLint rowLength, GLint skipImages, GLint skipRows, GLint alignment) { GLint bytesPerElement, elementsPerGroup, groupsPerRow; GLint groupSize, rowSize, padding, imageSize; if (w == 0 || h == 0 || d == 0) return 0; if (w < 0 || h < 0 || d < 0 || (type == GL_BITMAP && (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) { return -1; } /* proxy targets have no data */ switch (target) { case GL_PROXY_TEXTURE_1D: case GL_PROXY_TEXTURE_2D: case GL_PROXY_TEXTURE_3D: case GL_PROXY_TEXTURE_4D_SGIS: case GL_PROXY_TEXTURE_CUBE_MAP: case GL_PROXY_TEXTURE_RECTANGLE_ARB: case GL_PROXY_HISTOGRAM: case GL_PROXY_COLOR_TABLE: case GL_PROXY_TEXTURE_COLOR_TABLE_SGI: case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: case GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP: return 0; } /* real data has to have real sizes */ if (imageHeight < 0 || rowLength < 0 || skipImages < 0 || skipRows < 0) return -1; if (alignment != 1 && alignment != 2 && alignment != 4 && alignment != 8) return -1; if (type == GL_BITMAP) { if (rowLength > 0) { groupsPerRow = rowLength; } else { groupsPerRow = w; } rowSize = bits_to_bytes(groupsPerRow); if (rowSize < 0) return -1; padding = (rowSize % alignment); if (padding) { rowSize += alignment - padding; } return safe_mul(safe_add(h, skipRows), rowSize); } else { switch (format) { case GL_COLOR_INDEX: case GL_STENCIL_INDEX: case GL_DEPTH_COMPONENT: case GL_RED: case GL_GREEN: case GL_BLUE: case GL_ALPHA: case GL_LUMINANCE: case GL_INTENSITY: case GL_RED_INTEGER_EXT: case GL_GREEN_INTEGER_EXT: case GL_BLUE_INTEGER_EXT: case GL_ALPHA_INTEGER_EXT: case GL_LUMINANCE_INTEGER_EXT: elementsPerGroup = 1; break; case GL_422_EXT: case GL_422_REV_EXT: case GL_422_AVERAGE_EXT: case GL_422_REV_AVERAGE_EXT: case GL_DEPTH_STENCIL_NV: case GL_DEPTH_STENCIL_MESA: case GL_YCBCR_422_APPLE: case GL_YCBCR_MESA: case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA_INTEGER_EXT: elementsPerGroup = 2; break; case GL_RGB: case GL_BGR: case GL_RGB_INTEGER_EXT: case GL_BGR_INTEGER_EXT: elementsPerGroup = 3; break; case GL_RGBA: case GL_BGRA: case GL_RGBA_INTEGER_EXT: case GL_BGRA_INTEGER_EXT: case GL_ABGR_EXT: elementsPerGroup = 4; break; default: return -1; } switch (type) { case GL_UNSIGNED_BYTE: case GL_BYTE: bytesPerElement = 1; break; case GL_UNSIGNED_BYTE_3_3_2: case GL_UNSIGNED_BYTE_2_3_3_REV: bytesPerElement = 1; elementsPerGroup = 1; break; case GL_UNSIGNED_SHORT: case GL_SHORT: bytesPerElement = 2; break; case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_5_6_5_REV: case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4_REV: case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_1_5_5_5_REV: case GL_UNSIGNED_SHORT_8_8_APPLE: case GL_UNSIGNED_SHORT_8_8_REV_APPLE: case GL_UNSIGNED_SHORT_15_1_MESA: case GL_UNSIGNED_SHORT_1_15_REV_MESA: bytesPerElement = 2; elementsPerGroup = 1; break; case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: bytesPerElement = 4; break; case GL_UNSIGNED_INT_8_8_8_8: case GL_UNSIGNED_INT_8_8_8_8_REV: case GL_UNSIGNED_INT_10_10_10_2: case GL_UNSIGNED_INT_2_10_10_10_REV: case GL_UNSIGNED_INT_24_8_NV: case GL_UNSIGNED_INT_24_8_MESA: case GL_UNSIGNED_INT_8_24_REV_MESA: bytesPerElement = 4; elementsPerGroup = 1; break; default: return -1; } /* known safe by the switches above, not checked */ groupSize = bytesPerElement * elementsPerGroup; if (rowLength > 0) { groupsPerRow = rowLength; } else { groupsPerRow = w; } if ((rowSize = safe_mul(groupsPerRow, groupSize)) < 0) return -1; padding = (rowSize % alignment); if (padding) { rowSize += alignment - padding; } if (imageHeight > 0) h = imageHeight; h = safe_add(h, skipRows); imageSize = safe_mul(h, rowSize); return safe_mul(safe_add(d, skipImages), imageSize); } } /* XXX this is used elsewhere - should it be exported from glxserver.h? */ int __glXTypeSize(GLenum enm) { switch (enm) { case GL_BYTE: return sizeof(GLbyte); case GL_UNSIGNED_BYTE: return sizeof(GLubyte); case GL_SHORT: return sizeof(GLshort); case GL_UNSIGNED_SHORT: return sizeof(GLushort); case GL_INT: return sizeof(GLint); case GL_UNSIGNED_INT: return sizeof(GLint); case GL_FLOAT: return sizeof(GLfloat); case GL_DOUBLE: return sizeof(GLdouble); default: return -1; } } int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap, int reqlen) { __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc; __GLXdispatchDrawArraysComponentHeader *compHeader; GLint numVertexes = hdr->numVertexes; GLint numComponents = hdr->numComponents; GLint arrayElementSize = 0; GLint x, size; int i; if (swap) { numVertexes = SWAPL(numVertexes); numComponents = SWAPL(numComponents); } pc += sizeof(__GLXdispatchDrawArraysHeader); reqlen -= sizeof(__GLXdispatchDrawArraysHeader); size = safe_mul(sizeof(__GLXdispatchDrawArraysComponentHeader), numComponents); if (size < 0 || reqlen < 0 || reqlen < size) return -1; compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc; for (i = 0; i < numComponents; i++) { GLenum datatype = compHeader[i].datatype; GLint numVals = compHeader[i].numVals; GLint component = compHeader[i].component; if (swap) { datatype = SWAPL(datatype); numVals = SWAPL(numVals); component = SWAPL(component); } switch (component) { case GL_VERTEX_ARRAY: case GL_COLOR_ARRAY: case GL_TEXTURE_COORD_ARRAY: break; case GL_SECONDARY_COLOR_ARRAY: case GL_NORMAL_ARRAY: if (numVals != 3) { /* bad size */ return -1; } break; case GL_FOG_COORD_ARRAY: case GL_INDEX_ARRAY: if (numVals != 1) { /* bad size */ return -1; } break; case GL_EDGE_FLAG_ARRAY: if ((numVals != 1) && (datatype != GL_UNSIGNED_BYTE)) { /* bad size or bad type */ return -1; } break; default: /* unknown component type */ return -1; } x = safe_pad(safe_mul(numVals, __glXTypeSize(datatype))); if ((arrayElementSize = safe_add(arrayElementSize, x)) < 0) return -1; pc += sizeof(__GLXdispatchDrawArraysComponentHeader); } return safe_add(size, safe_mul(numVertexes, arrayElementSize)); } int __glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen) { __GLXdispatchConvolutionFilterHeader *hdr = (__GLXdispatchConvolutionFilterHeader *) pc; GLint image1size, image2size; GLenum format = hdr->format; GLenum type = hdr->type; GLint w = hdr->width; GLint h = hdr->height; GLint rowLength = hdr->rowLength; GLint alignment = hdr->alignment; if (swap) { format = SWAPL(format); type = SWAPL(type); w = SWAPL(w); h = SWAPL(h); rowLength = SWAPL(rowLength); alignment = SWAPL(alignment); } /* XXX Should rowLength be used for either or both image? */ image1size = __glXImageSize(format, type, 0, w, 1, 1, 0, rowLength, 0, 0, alignment); image2size = __glXImageSize(format, type, 0, h, 1, 1, 0, rowLength, 0, 0, alignment); return safe_add(safe_pad(image1size), image2size); } xorg-server-1.20.13/glx/single2.c0000644000175000017500000002563414100573756013405 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include #include "glxserver.h" #include "glxutil.h" #include "glxext.h" #include "indirect_dispatch.h" #include "unpack.h" int __glXDisp_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; GLsizei size; GLenum type; __GLXcontext *cx; int error; REQUEST_FIXED_SIZE(xGLXSingleReq, 8); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; size = *(GLsizei *) (pc + 0); type = *(GLenum *) (pc + 4); if (cx->feedbackBufSize < size) { cx->feedbackBuf = reallocarray(cx->feedbackBuf, (size_t) size, __GLX_SIZE_FLOAT32); if (!cx->feedbackBuf) { cl->client->errorValue = size; return BadAlloc; } cx->feedbackBufSize = size; } glFeedbackBuffer(size, type, cx->feedbackBuf); return Success; } int __glXDisp_SelectBuffer(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; __GLXcontext *cx; GLsizei size; int error; REQUEST_FIXED_SIZE(xGLXSingleReq, 4); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; size = *(GLsizei *) (pc + 0); if (cx->selectBufSize < size) { cx->selectBuf = reallocarray(cx->selectBuf, (size_t) size, __GLX_SIZE_CARD32); if (!cx->selectBuf) { cl->client->errorValue = size; return BadAlloc; } cx->selectBufSize = size; } glSelectBuffer(size, cx->selectBuf); return Success; } int __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXRenderModeReply reply; __GLXcontext *cx; GLint nitems = 0, retBytes = 0, retval, newModeCheck; GLubyte *retBuffer = NULL; GLenum newMode; int error; REQUEST_FIXED_SIZE(xGLXSingleReq, 4); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; newMode = *(GLenum *) pc; retval = glRenderMode(newMode); /* Check that render mode worked */ glGetIntegerv(GL_RENDER_MODE, &newModeCheck); if (newModeCheck != newMode) { /* Render mode change failed. Bail */ newMode = newModeCheck; goto noChangeAllowed; } /* ** Render mode might have still failed if we get here. But in this ** case we can't really tell, nor does it matter. If it did fail, it ** will return 0, and thus we won't send any data across the wire. */ switch (cx->renderMode) { case GL_RENDER: cx->renderMode = newMode; break; case GL_FEEDBACK: if (retval < 0) { /* Overflow happened. Copy the entire buffer */ nitems = cx->feedbackBufSize; } else { nitems = retval; } retBytes = nitems * __GLX_SIZE_FLOAT32; retBuffer = (GLubyte *) cx->feedbackBuf; cx->renderMode = newMode; break; case GL_SELECT: if (retval < 0) { /* Overflow happened. Copy the entire buffer */ nitems = cx->selectBufSize; } else { GLuint *bp = cx->selectBuf; GLint i; /* ** Figure out how many bytes of data need to be sent. Parse ** the selection buffer to determine this fact as the ** return value is the number of hits, not the number of ** items in the buffer. */ nitems = 0; i = retval; while (--i >= 0) { GLuint n; /* Parse select data for this hit */ n = *bp; bp += 3 + n; } nitems = bp - cx->selectBuf; } retBytes = nitems * __GLX_SIZE_CARD32; retBuffer = (GLubyte *) cx->selectBuf; cx->renderMode = newMode; break; } /* ** First reply is the number of elements returned in the feedback or ** selection array, as per the API for glRenderMode itself. */ noChangeAllowed:; reply = (xGLXRenderModeReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = nitems, .retval = retval, .size = nitems, .newMode = newMode }; WriteToClient(client, sz_xGLXRenderModeReply, &reply); if (retBytes) { WriteToClient(client, retBytes, retBuffer); } return Success; } int __glXDisp_Flush(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; __GLXcontext *cx; int error; REQUEST_SIZE_MATCH(xGLXSingleReq); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } glFlush(); return Success; } int __glXDisp_Finish(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; __GLXcontext *cx; int error; xGLXSingleReply reply = { 0, }; REQUEST_SIZE_MATCH(xGLXSingleReq); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } /* Do a local glFinish */ glFinish(); /* Send empty reply packet to indicate finish is finished */ client = cl->client; __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); return Success; } #define SEPARATOR " " static char * __glXcombine_strings(const char *cext_string, const char *sext_string) { size_t clen, slen; char *combo_string, *token, *s1; const char *s2, *end; /* safeguard to prevent potentially fatal errors in the string functions */ if (!cext_string) cext_string = ""; if (!sext_string) sext_string = ""; /* ** String can't be longer than min(cstring, sstring) ** pull tokens out of shortest string ** include space in combo_string for final separator and null terminator */ clen = strlen(cext_string); slen = strlen(sext_string); if (clen > slen) { combo_string = (char *) malloc(slen + 2); s1 = (char *) malloc(slen + 2); if (s1) strcpy(s1, sext_string); s2 = cext_string; } else { combo_string = (char *) malloc(clen + 2); s1 = (char *) malloc(clen + 2); if (s1) strcpy(s1, cext_string); s2 = sext_string; } if (!combo_string || !s1) { free(combo_string); free(s1); return NULL; } combo_string[0] = '\0'; /* Get first extension token */ token = strtok(s1, SEPARATOR); while (token != NULL) { /* ** if token in second string then save it ** beware of extension names which are prefixes of other extension names */ const char *p = s2; end = p + strlen(p); while (p < end) { size_t n = strcspn(p, SEPARATOR); if ((strlen(token) == n) && (strncmp(token, p, n) == 0)) { combo_string = strcat(combo_string, token); combo_string = strcat(combo_string, SEPARATOR); } p += (n + 1); } /* Get next extension token */ token = strtok(NULL, SEPARATOR); } free(s1); return combo_string; } int DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap) { ClientPtr client = cl->client; __GLXcontext *cx; GLenum name; const char *string; xGLXSingleReply reply = { 0, }; __GLX_DECLARE_SWAP_VARIABLES; int error; char *buf = NULL, *buf1 = NULL; GLint length = 0; REQUEST_FIXED_SIZE(xGLXSingleReq, 4); /* If the client has the opposite byte order, swap the contextTag and * the name. */ if (need_swap) { __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + __GLX_SINGLE_HDR_SIZE); } cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; name = *(GLenum *) (pc + 0); string = (const char *) glGetString(name); if (string == NULL) string = ""; /* ** Restrict extensions to those that are supported by both the ** implementation and the connection. That is, return the ** intersection of client, server, and core extension strings. */ if (name == GL_EXTENSIONS) { buf1 = __glXcombine_strings(string, cl->GLClientextensions); buf = __glXcombine_strings(buf1, cx->pGlxScreen->GLextensions); free(buf1); string = buf; } else if (name == GL_VERSION) { if (atof(string) > atof(GLServerVersion)) { if (asprintf(&buf, "%s (%s)", GLServerVersion, string) == -1) { string = GLServerVersion; } else { string = buf; } } } if (string) { length = strlen((const char *) string) + 1; } __GLX_BEGIN_REPLY(length); __GLX_PUT_SIZE(length); if (need_swap) { __GLX_SWAP_REPLY_SIZE(); __GLX_SWAP_REPLY_HEADER(); } __GLX_SEND_HEADER(); WriteToClient(client, length, string); free(buf); return Success; } int __glXDisp_GetString(__GLXclientState * cl, GLbyte * pc) { return DoGetString(cl, pc, GL_FALSE); } xorg-server-1.20.13/glx/single2swap.c0000644000175000017500000002005514100573756014270 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "glxutil.h" #include "glxext.h" #include "indirect_dispatch.h" #include "unpack.h" int __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; GLsizei size; GLenum type; __GLX_DECLARE_SWAP_VARIABLES; __GLXcontext *cx; int error; REQUEST_FIXED_SIZE(xGLXSingleReq, 8); __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 4); size = *(GLsizei *) (pc + 0); type = *(GLenum *) (pc + 4); if (cx->feedbackBufSize < size) { cx->feedbackBuf = reallocarray(cx->feedbackBuf, (size_t) size, __GLX_SIZE_FLOAT32); if (!cx->feedbackBuf) { cl->client->errorValue = size; return BadAlloc; } cx->feedbackBufSize = size; } glFeedbackBuffer(size, type, cx->feedbackBuf); return Success; } int __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; __GLXcontext *cx; GLsizei size; __GLX_DECLARE_SWAP_VARIABLES; int error; REQUEST_FIXED_SIZE(xGLXSingleReq, 4); __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; __GLX_SWAP_INT(pc + 0); size = *(GLsizei *) (pc + 0); if (cx->selectBufSize < size) { cx->selectBuf = reallocarray(cx->selectBuf, (size_t) size, __GLX_SIZE_CARD32); if (!cx->selectBuf) { cl->client->errorValue = size; return BadAlloc; } cx->selectBufSize = size; } glSelectBuffer(size, cx->selectBuf); return Success; } int __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; __GLXcontext *cx; xGLXRenderModeReply reply; GLint nitems = 0, retBytes = 0, retval, newModeCheck; GLubyte *retBuffer = NULL; GLenum newMode; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; int error; REQUEST_FIXED_SIZE(xGLXSingleReq, 4); __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; __GLX_SWAP_INT(pc); newMode = *(GLenum *) pc; retval = glRenderMode(newMode); /* Check that render mode worked */ glGetIntegerv(GL_RENDER_MODE, &newModeCheck); if (newModeCheck != newMode) { /* Render mode change failed. Bail */ newMode = newModeCheck; goto noChangeAllowed; } /* ** Render mode might have still failed if we get here. But in this ** case we can't really tell, nor does it matter. If it did fail, it ** will return 0, and thus we won't send any data across the wire. */ switch (cx->renderMode) { case GL_RENDER: cx->renderMode = newMode; break; case GL_FEEDBACK: if (retval < 0) { /* Overflow happened. Copy the entire buffer */ nitems = cx->feedbackBufSize; } else { nitems = retval; } retBytes = nitems * __GLX_SIZE_FLOAT32; retBuffer = (GLubyte *) cx->feedbackBuf; __GLX_SWAP_FLOAT_ARRAY((GLbyte *) retBuffer, nitems); cx->renderMode = newMode; break; case GL_SELECT: if (retval < 0) { /* Overflow happened. Copy the entire buffer */ nitems = cx->selectBufSize; } else { GLuint *bp = cx->selectBuf; GLint i; /* ** Figure out how many bytes of data need to be sent. Parse ** the selection buffer to determine this fact as the ** return value is the number of hits, not the number of ** items in the buffer. */ nitems = 0; i = retval; while (--i >= 0) { GLuint n; /* Parse select data for this hit */ n = *bp; bp += 3 + n; } nitems = bp - cx->selectBuf; } retBytes = nitems * __GLX_SIZE_CARD32; retBuffer = (GLubyte *) cx->selectBuf; __GLX_SWAP_INT_ARRAY((GLbyte *) retBuffer, nitems); cx->renderMode = newMode; break; } /* ** First reply is the number of elements returned in the feedback or ** selection array, as per the API for glRenderMode itself. */ noChangeAllowed:; reply = (xGLXRenderModeReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = nitems, .retval = retval, .size = nitems, .newMode = newMode }; __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.retval); __GLX_SWAP_INT(&reply.size); __GLX_SWAP_INT(&reply.newMode); WriteToClient(client, sz_xGLXRenderModeReply, &reply); if (retBytes) { WriteToClient(client, retBytes, retBuffer); } return Success; } int __glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; __GLXcontext *cx; int error; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_SIZE_MATCH(xGLXSingleReq); __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } glFlush(); return Success; } int __glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; __GLXcontext *cx; int error; xGLXSingleReply reply = { 0, }; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_SIZE_MATCH(xGLXSingleReq); __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } /* Do a local glFinish */ glFinish(); /* Send empty reply packet to indicate finish is finished */ __GLX_BEGIN_REPLY(0); __GLX_PUT_RETVAL(0); __GLX_SWAP_REPLY_HEADER(); __GLX_SEND_HEADER(); return Success; } int __glXDispSwap_GetString(__GLXclientState * cl, GLbyte * pc) { return DoGetString(cl, pc, GL_TRUE); } xorg-server-1.20.13/glx/singlepix.c0000644000175000017500000004054714100573756014044 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "glxext.h" #include "singlesize.h" #include "unpack.h" #include "indirect_size_get.h" #include "indirect_dispatch.h" int __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc) { GLsizei width, height; GLenum format, type; GLboolean swapBytes, lsbFirst; GLint compsize; __GLXcontext *cx; ClientPtr client = cl->client; int error; char *answer, answerBuffer[200]; xGLXSingleReply reply = { 0, }; REQUEST_FIXED_SIZE(xGLXSingleReq, 28); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; width = *(GLsizei *) (pc + 8); height = *(GLsizei *) (pc + 12); format = *(GLenum *) (pc + 16); type = *(GLenum *) (pc + 20); swapBytes = *(GLboolean *) (pc + 24); lsbFirst = *(GLboolean *) (pc + 25); compsize = __glReadPixels_size(format, type, width, height); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glReadPixels(*(GLint *) (pc + 0), *(GLint *) (pc + 4), *(GLsizei *) (pc + 8), *(GLsizei *) (pc + 12), *(GLenum *) (pc + 16), *(GLenum *) (pc + 20), answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc) { GLint level, compsize; GLenum format, type, target; GLboolean swapBytes; __GLXcontext *cx; ClientPtr client = cl->client; int error; char *answer, answerBuffer[200]; GLint width = 0, height = 0, depth = 1; xGLXSingleReply reply = { 0, }; REQUEST_FIXED_SIZE(xGLXSingleReq, 20); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; level = *(GLint *) (pc + 4); format = *(GLenum *) (pc + 8); type = *(GLenum *) (pc + 12); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 16); glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); if (target == GL_TEXTURE_3D) { glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth); } /* * The three queries above might fail if we're in a state where queries * are illegal, but then width, height, and depth would still be zero anyway. */ compsize = __glGetTexImage_size(target, level, format, type, width, height, depth); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glGetTexImage(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLenum *) (pc + 8), *(GLenum *) (pc + 12), answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); ((xGLXGetTexImageReply *) &reply)->width = width; ((xGLXGetTexImageReply *) &reply)->height = height; ((xGLXGetTexImageReply *) &reply)->depth = depth; __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDisp_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc) { GLboolean lsbFirst; __GLXcontext *cx; ClientPtr client = cl->client; int error; GLubyte answerBuffer[200]; char *answer; xGLXSingleReply reply = { 0, }; REQUEST_FIXED_SIZE(xGLXSingleReq, 4); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; lsbFirst = *(GLboolean *) (pc + 0); glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst); __GLX_GET_ANSWER_BUFFER(answer, cl, 128, 1); __glXClearErrorOccured(); glGetPolygonStipple((GLubyte *) answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(128); __GLX_SEND_HEADER(); __GLX_SEND_BYTE_ARRAY(128); } return Success; } static int GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize, compsize2; GLenum format, type, target; GLboolean swapBytes; __GLXcontext *cx; ClientPtr client = cl->client; int error; char *answer, answerBuffer[200]; GLint width = 0, height = 0; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 12); /* target must be SEPARABLE_2D, however I guess we can let the GL barf on this one.... */ glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width); glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height); /* * The two queries above might fail if we're in a state where queries * are illegal, but then width and height would still be zero anyway. */ compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); if ((compsize = safe_pad(compsize)) < 0) return BadLength; if ((compsize2 = safe_pad(compsize2)) < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1); __glXClearErrorOccured(); glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), answer, answer + compsize, NULL); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize + compsize2); ((xGLXGetSeparableFilterReply *) &reply)->width = width; ((xGLXGetSeparableFilterReply *) &reply)->height = height; __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize + compsize2); } return Success; } int __glXDisp_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 16); return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); } int __glXDisp_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); } static int GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize; GLenum format, type, target; GLboolean swapBytes; __GLXcontext *cx; ClientPtr client = cl->client; int error; char *answer, answerBuffer[200]; GLint width = 0, height = 0; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 12); glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width); if (target == GL_CONVOLUTION_1D) { height = 1; } else { glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height); } /* * The two queries above might fail if we're in a state where queries * are illegal, but then width and height would still be zero anyway. */ compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glGetConvolutionFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); ((xGLXGetConvolutionFilterReply *) &reply)->width = width; ((xGLXGetConvolutionFilterReply *) &reply)->height = height; __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDisp_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 16); return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); } int __glXDisp_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); } static int GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize; GLenum format, type, target; GLboolean swapBytes, reset; __GLXcontext *cx; ClientPtr client = cl->client; int error; char *answer, answerBuffer[200]; GLint width = 0; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 12); reset = *(GLboolean *) (pc + 13); glGetHistogramParameteriv(target, GL_HISTOGRAM_WIDTH, &width); /* * The one query above might fail if we're in a state where queries * are illegal, but then width would still be zero anyway. */ compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glGetHistogram(target, reset, format, type, answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); ((xGLXGetHistogramReply *) &reply)->width = width; __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDisp_GetHistogram(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 16); return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); } int __glXDisp_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); } static int GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize; GLenum format, type, target; GLboolean swapBytes, reset; __GLXcontext *cx; ClientPtr client = cl->client; int error; char *answer, answerBuffer[200]; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 12); reset = *(GLboolean *) (pc + 13); compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glGetMinmax(target, reset, format, type, answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDisp_GetMinmax(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 16); return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); } int __glXDisp_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); } static int GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize; GLenum format, type, target; GLboolean swapBytes; __GLXcontext *cx; ClientPtr client = cl->client; int error; char *answer, answerBuffer[200]; GLint width = 0; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } target = *(GLenum *) (pc + 0); format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); swapBytes = *(GLboolean *) (pc + 12); glGetColorTableParameteriv(target, GL_COLOR_TABLE_WIDTH, &width); /* * The one query above might fail if we're in a state where queries * are illegal, but then width would still be zero anyway. */ compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glGetColorTable(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); ((xGLXGetColorTableReply *) &reply)->width = width; __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDisp_GetColorTable(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 16); return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); } int __glXDisp_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); } xorg-server-1.20.13/glx/singlepixswap.c0000644000175000017500000004414514100573756014735 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "glxext.h" #include "singlesize.h" #include "unpack.h" #include "indirect_dispatch.h" #include "indirect_size_get.h" int __glXDispSwap_ReadPixels(__GLXclientState * cl, GLbyte * pc) { GLsizei width, height; GLenum format, type; GLboolean swapBytes, lsbFirst; GLint compsize; __GLX_DECLARE_SWAP_VARIABLES; __GLXcontext *cx; ClientPtr client = cl->client; int error; char *answer, answerBuffer[200]; xGLXSingleReply reply = { 0, }; REQUEST_FIXED_SIZE(xGLXSingleReq, 28); __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + 8); __GLX_SWAP_INT(pc + 12); __GLX_SWAP_INT(pc + 16); __GLX_SWAP_INT(pc + 20); width = *(GLsizei *) (pc + 8); height = *(GLsizei *) (pc + 12); format = *(GLenum *) (pc + 16); type = *(GLenum *) (pc + 20); swapBytes = *(GLboolean *) (pc + 24); lsbFirst = *(GLboolean *) (pc + 25); compsize = __glReadPixels_size(format, type, width, height); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glReadPixels(*(GLint *) (pc + 0), *(GLint *) (pc + 4), *(GLsizei *) (pc + 8), *(GLsizei *) (pc + 12), *(GLenum *) (pc + 16), *(GLenum *) (pc + 20), answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SWAP_REPLY_HEADER(); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); __GLX_SWAP_REPLY_HEADER(); __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc) { GLint level, compsize; GLenum format, type, target; GLboolean swapBytes; __GLX_DECLARE_SWAP_VARIABLES; __GLXcontext *cx; ClientPtr client = cl->client; int error; char *answer, answerBuffer[200]; GLint width = 0, height = 0, depth = 1; xGLXSingleReply reply = { 0, }; REQUEST_FIXED_SIZE(xGLXSingleReq, 20); __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + 8); __GLX_SWAP_INT(pc + 12); level = *(GLint *) (pc + 4); format = *(GLenum *) (pc + 8); type = *(GLenum *) (pc + 12); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 16); glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); if (target == GL_TEXTURE_3D) { glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth); } /* * The three queries above might fail if we're in a state where queries * are illegal, but then width, height, and depth would still be zero anyway. */ compsize = __glGetTexImage_size(target, level, format, type, width, height, depth); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glGetTexImage(*(GLenum *) (pc + 0), *(GLint *) (pc + 4), *(GLenum *) (pc + 8), *(GLenum *) (pc + 12), answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SWAP_REPLY_HEADER(); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); __GLX_SWAP_REPLY_HEADER(); __GLX_SWAP_INT(&width); __GLX_SWAP_INT(&height); __GLX_SWAP_INT(&depth); ((xGLXGetTexImageReply *) &reply)->width = width; ((xGLXGetTexImageReply *) &reply)->height = height; ((xGLXGetTexImageReply *) &reply)->depth = depth; __GLX_SEND_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDispSwap_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc) { GLboolean lsbFirst; __GLXcontext *cx; ClientPtr client = cl->client; int error; GLubyte answerBuffer[200]; char *answer; xGLXSingleReply reply = { 0, }; __GLX_DECLARE_SWAP_VARIABLES; REQUEST_FIXED_SIZE(xGLXSingleReq, 4); __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; lsbFirst = *(GLboolean *) (pc + 0); glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst); __GLX_GET_ANSWER_BUFFER(answer, cl, 128, 1); __glXClearErrorOccured(); glGetPolygonStipple((GLubyte *) answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SWAP_REPLY_HEADER(); __GLX_SEND_HEADER(); } else { __GLX_BEGIN_REPLY(128); __GLX_SWAP_REPLY_HEADER(); __GLX_SEND_HEADER(); __GLX_SEND_BYTE_ARRAY(128); } return Success; } static int GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize, compsize2; GLenum format, type, target; GLboolean swapBytes; __GLXcontext *cx; ClientPtr client = cl->client; int error; __GLX_DECLARE_SWAP_VARIABLES; char *answer, answerBuffer[200]; GLint width = 0, height = 0; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + 8); format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 12); /* target must be SEPARABLE_2D, however I guess we can let the GL barf on this one.... */ glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width); glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height); /* * The two queries above might fail if we're in a state where queries * are illegal, but then width and height would still be zero anyway. */ compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); if ((compsize = safe_pad(compsize)) < 0) return BadLength; if ((compsize2 = safe_pad(compsize2)) < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1); __glXClearErrorOccured(); glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), answer, answer + compsize, NULL); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SWAP_REPLY_HEADER(); } else { __GLX_BEGIN_REPLY(compsize + compsize2); __GLX_SWAP_REPLY_HEADER(); __GLX_SWAP_INT(&width); __GLX_SWAP_INT(&height); ((xGLXGetSeparableFilterReply *) &reply)->width = width; ((xGLXGetSeparableFilterReply *) &reply)->height = height; __GLX_SEND_VOID_ARRAY(compsize + compsize2); } return Success; } int __glXDispSwap_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 16); return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); } int __glXDispSwap_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); } static int GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize; GLenum format, type, target; GLboolean swapBytes; __GLXcontext *cx; ClientPtr client = cl->client; int error; __GLX_DECLARE_SWAP_VARIABLES; char *answer, answerBuffer[200]; GLint width = 0, height = 0; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + 8); format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 12); glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width); if (target == GL_CONVOLUTION_2D) { height = 1; } else { glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height); } /* * The two queries above might fail if we're in a state where queries * are illegal, but then width and height would still be zero anyway. */ compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glGetConvolutionFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SWAP_REPLY_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); __GLX_SWAP_REPLY_HEADER(); __GLX_SWAP_INT(&width); __GLX_SWAP_INT(&height); ((xGLXGetConvolutionFilterReply *) &reply)->width = width; ((xGLXGetConvolutionFilterReply *) &reply)->height = height; __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDispSwap_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 16); return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); } int __glXDispSwap_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); } static int GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize; GLenum format, type, target; GLboolean swapBytes, reset; __GLXcontext *cx; ClientPtr client = cl->client; int error; __GLX_DECLARE_SWAP_VARIABLES; char *answer, answerBuffer[200]; GLint width = 0; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + 8); format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 12); reset = *(GLboolean *) (pc + 13); glGetHistogramParameteriv(target, GL_HISTOGRAM_WIDTH, &width); /* * The one query above might fail if we're in a state where queries * are illegal, but then width would still be zero anyway. */ compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glGetHistogram(target, reset, format, type, answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SWAP_REPLY_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); __GLX_SWAP_REPLY_HEADER(); __GLX_SWAP_INT(&width); ((xGLXGetHistogramReply *) &reply)->width = width; __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDispSwap_GetHistogram(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 16); return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); } int __glXDispSwap_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); } static int GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize; GLenum format, type, target; GLboolean swapBytes, reset; __GLXcontext *cx; ClientPtr client = cl->client; int error; __GLX_DECLARE_SWAP_VARIABLES; char *answer, answerBuffer[200]; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + 8); format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 12); reset = *(GLboolean *) (pc + 13); compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glGetMinmax(target, reset, format, type, answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SWAP_REPLY_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); __GLX_SWAP_REPLY_HEADER(); __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDispSwap_GetMinmax(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 16); return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); } int __glXDispSwap_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); } static int GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) { GLint compsize; GLenum format, type, target; GLboolean swapBytes; __GLXcontext *cx; ClientPtr client = cl->client; int error; __GLX_DECLARE_SWAP_VARIABLES; char *answer, answerBuffer[200]; GLint width = 0; xGLXSingleReply reply = { 0, }; cx = __glXForceCurrent(cl, tag, &error); if (!cx) { return error; } __GLX_SWAP_INT(pc + 0); __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + 8); format = *(GLenum *) (pc + 4); type = *(GLenum *) (pc + 8); target = *(GLenum *) (pc + 0); swapBytes = *(GLboolean *) (pc + 12); glGetColorTableParameteriv(target, GL_COLOR_TABLE_WIDTH, &width); /* * The one query above might fail if we're in a state where queries * are illegal, but then width would still be zero anyway. */ compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); if (compsize < 0) return BadLength; glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); __glXClearErrorOccured(); glGetColorTable(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), *(GLenum *) (pc + 8), answer); if (__glXErrorOccured()) { __GLX_BEGIN_REPLY(0); __GLX_SWAP_REPLY_HEADER(); } else { __GLX_BEGIN_REPLY(compsize); __GLX_SWAP_REPLY_HEADER(); __GLX_SWAP_INT(&width); ((xGLXGetColorTableReply *) &reply)->width = width; __GLX_SEND_VOID_ARRAY(compsize); } return Success; } int __glXDispSwap_GetColorTable(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXSingleReq, 16); return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); } int __glXDispSwap_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc) { const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ClientPtr client = cl->client; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); } xorg-server-1.20.13/glx/singlesize.c0000644000175000017500000001300014100573756014176 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "glxserver.h" #include "singlesize.h" #include "indirect_size_get.h" /* ** These routines compute the size of variable-size returned parameters. ** Unlike the similar routines that do the same thing for variable-size ** incoming parameters, the samplegl library itself doesn't use these routines. ** Hence, they are located here, in the GLX extension library. */ GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h) { return __glXImageSize(format, type, 0, w, h, 1, 0, 0, 0, 0, 4); } GLint __glGetMap_size(GLenum target, GLenum query) { GLint k, order = 0, majorMinor[2]; /* ** Assume target and query are both valid. */ switch (target) { case GL_MAP1_COLOR_4: case GL_MAP1_NORMAL: case GL_MAP1_INDEX: case GL_MAP1_TEXTURE_COORD_1: case GL_MAP1_TEXTURE_COORD_2: case GL_MAP1_TEXTURE_COORD_3: case GL_MAP1_TEXTURE_COORD_4: case GL_MAP1_VERTEX_3: case GL_MAP1_VERTEX_4: switch (query) { case GL_COEFF: k = __glMap1d_size(target); glGetMapiv(target, GL_ORDER, &order); /* ** The query above might fail, but then order will be zero anyway. */ return order * k; case GL_DOMAIN: return 2; case GL_ORDER: return 1; } break; case GL_MAP2_COLOR_4: case GL_MAP2_NORMAL: case GL_MAP2_INDEX: case GL_MAP2_TEXTURE_COORD_1: case GL_MAP2_TEXTURE_COORD_2: case GL_MAP2_TEXTURE_COORD_3: case GL_MAP2_TEXTURE_COORD_4: case GL_MAP2_VERTEX_3: case GL_MAP2_VERTEX_4: switch (query) { case GL_COEFF: k = __glMap2d_size(target); majorMinor[0] = majorMinor[1] = 0; glGetMapiv(target, GL_ORDER, majorMinor); /* ** The query above might fail, but then majorMinor will be zeroes */ return majorMinor[0] * majorMinor[1] * k; case GL_DOMAIN: return 4; case GL_ORDER: return 2; } break; } return -1; } GLint __glGetMapdv_size(GLenum target, GLenum query) { return __glGetMap_size(target, query); } GLint __glGetMapfv_size(GLenum target, GLenum query) { return __glGetMap_size(target, query); } GLint __glGetMapiv_size(GLenum target, GLenum query) { return __glGetMap_size(target, query); } GLint __glGetPixelMap_size(GLenum map) { GLint size; GLenum query; switch (map) { case GL_PIXEL_MAP_I_TO_I: query = GL_PIXEL_MAP_I_TO_I_SIZE; break; case GL_PIXEL_MAP_S_TO_S: query = GL_PIXEL_MAP_S_TO_S_SIZE; break; case GL_PIXEL_MAP_I_TO_R: query = GL_PIXEL_MAP_I_TO_R_SIZE; break; case GL_PIXEL_MAP_I_TO_G: query = GL_PIXEL_MAP_I_TO_G_SIZE; break; case GL_PIXEL_MAP_I_TO_B: query = GL_PIXEL_MAP_I_TO_B_SIZE; break; case GL_PIXEL_MAP_I_TO_A: query = GL_PIXEL_MAP_I_TO_A_SIZE; break; case GL_PIXEL_MAP_R_TO_R: query = GL_PIXEL_MAP_R_TO_R_SIZE; break; case GL_PIXEL_MAP_G_TO_G: query = GL_PIXEL_MAP_G_TO_G_SIZE; break; case GL_PIXEL_MAP_B_TO_B: query = GL_PIXEL_MAP_B_TO_B_SIZE; break; case GL_PIXEL_MAP_A_TO_A: query = GL_PIXEL_MAP_A_TO_A_SIZE; break; default: return -1; } glGetIntegerv(query, &size); return size; } GLint __glGetPixelMapfv_size(GLenum map) { return __glGetPixelMap_size(map); } GLint __glGetPixelMapuiv_size(GLenum map) { return __glGetPixelMap_size(map); } GLint __glGetPixelMapusv_size(GLenum map) { return __glGetPixelMap_size(map); } GLint __glGetTexImage_size(GLenum target, GLint level, GLenum format, GLenum type, GLint width, GLint height, GLint depth) { return __glXImageSize(format, type, target, width, height, depth, 0, 0, 0, 0, 4); } xorg-server-1.20.13/glx/singlesize.h0000644000175000017500000000472014100573756014214 00000000000000#ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef _singlesize_h_ #define _singlesize_h_ /* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #include "indirect_size.h" extern GLint __glReadPixels_size(GLenum format, GLenum type, GLint width, GLint height); extern GLint __glGetMap_size(GLenum pname, GLenum query); extern GLint __glGetMapdv_size(GLenum target, GLenum query); extern GLint __glGetMapfv_size(GLenum target, GLenum query); extern GLint __glGetMapiv_size(GLenum target, GLenum query); extern GLint __glGetPixelMap_size(GLenum map); extern GLint __glGetPixelMapfv_size(GLenum map); extern GLint __glGetPixelMapuiv_size(GLenum map); extern GLint __glGetPixelMapusv_size(GLenum map); extern GLint __glGetTexImage_size(GLenum target, GLint level, GLenum format, GLenum type, GLint width, GLint height, GLint depth); #endif /* _singlesize_h_ */ xorg-server-1.20.13/glx/swap_interval.c0000644000175000017500000000541714100573756014715 00000000000000/* * (C) Copyright IBM Corporation 2006 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "glxutil.h" #include "glxext.h" #include "singlesize.h" #include "unpack.h" #include "indirect_size_get.h" #include "indirect_dispatch.h" #include "glxbyteorder.h" static int DoSwapInterval(__GLXclientState * cl, GLbyte * pc, int do_swap); int DoSwapInterval(__GLXclientState * cl, GLbyte * pc, int do_swap) { xGLXVendorPrivateReq *const req = (xGLXVendorPrivateReq *) pc; ClientPtr client = cl->client; const GLXContextTag tag = req->contextTag; __GLXcontext *cx; GLint interval; REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 4); cx = __glXLookupContextByTag(cl, tag); if ((cx == NULL) || (cx->pGlxScreen == NULL)) { client->errorValue = tag; return __glXError(GLXBadContext); } if (cx->pGlxScreen->swapInterval == NULL) { LogMessage(X_ERROR, "AIGLX: cx->pGlxScreen->swapInterval == NULL\n"); client->errorValue = tag; return __glXError(GLXUnsupportedPrivateRequest); } if (cx->drawPriv == NULL) { client->errorValue = tag; return BadValue; } pc += __GLX_VENDPRIV_HDR_SIZE; interval = (do_swap) ? bswap_32(*(int *) (pc + 0)) : *(int *) (pc + 0); if (interval <= 0) return BadValue; (void) (*cx->pGlxScreen->swapInterval) (cx->drawPriv, interval); return Success; } int __glXDisp_SwapIntervalSGI(__GLXclientState * cl, GLbyte * pc) { return DoSwapInterval(cl, pc, 0); } int __glXDispSwap_SwapIntervalSGI(__GLXclientState * cl, GLbyte * pc) { return DoSwapInterval(cl, pc, 1); } xorg-server-1.20.13/glx/unpack.h0000644000175000017500000001554614100573756013331 00000000000000#ifdef HAVE_DIX_CONFIG_H #include #endif #ifndef __GLX_unpack_h__ #define __GLX_unpack_h__ /* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #define __GLX_PAD(s) (((s)+3) & (GLuint)~3) /* ** Fetch the context-id out of a SingleReq request pointed to by pc. */ #define __GLX_GET_SINGLE_CONTEXT_TAG(pc) (((xGLXSingleReq*)pc)->contextTag) #define __GLX_GET_VENDPRIV_CONTEXT_TAG(pc) (((xGLXVendorPrivateReq*)pc)->contextTag) /* ** Fetch a double from potentially unaligned memory. */ #ifdef __GLX_ALIGN64 #define __GLX_MEM_COPY(dst,src,n) memmove(dst,src,n) #define __GLX_GET_DOUBLE(dst,src) __GLX_MEM_COPY(&dst,src,8) #else #define __GLX_GET_DOUBLE(dst,src) (dst) = *((GLdouble*)(src)) #endif #define __GLX_BEGIN_REPLY(size) \ reply.length = __GLX_PAD(size) >> 2; \ reply.type = X_Reply; \ reply.sequenceNumber = client->sequence; #define __GLX_SEND_HEADER() \ WriteToClient (client, sz_xGLXSingleReply, &reply); #define __GLX_PUT_RETVAL(a) \ reply.retval = (a); #define __GLX_PUT_SIZE(a) \ reply.size = (a); /* ** Get a buffer to hold returned data, with the given alignment. If we have ** to realloc, allocate size+align, in case the pointer has to be bumped for ** alignment. The answerBuffer should already be aligned. ** ** NOTE: the cast (long)res below assumes a long is large enough to hold a ** pointer. */ #define __GLX_GET_ANSWER_BUFFER(res,cl,size,align) \ if (size < 0) return BadLength; \ else if ((size) > sizeof(answerBuffer)) { \ int bump; \ if ((cl)->returnBufSize < (size)+(align)) { \ (cl)->returnBuf = (GLbyte*)realloc((cl)->returnBuf, \ (size)+(align)); \ if (!(cl)->returnBuf) { \ return BadAlloc; \ } \ (cl)->returnBufSize = (size)+(align); \ } \ res = (char*)cl->returnBuf; \ bump = (long)(res) % (align); \ if (bump) res += (align) - (bump); \ } else { \ res = (char *)answerBuffer; \ } #define __GLX_SEND_BYTE_ARRAY(len) \ WriteToClient(client, __GLX_PAD((len)*__GLX_SIZE_INT8), answer) #define __GLX_SEND_SHORT_ARRAY(len) \ WriteToClient(client, __GLX_PAD((len)*__GLX_SIZE_INT16), answer) #define __GLX_SEND_INT_ARRAY(len) \ WriteToClient(client, (len)*__GLX_SIZE_INT32, answer) #define __GLX_SEND_FLOAT_ARRAY(len) \ WriteToClient(client, (len)*__GLX_SIZE_FLOAT32, answer) #define __GLX_SEND_DOUBLE_ARRAY(len) \ WriteToClient(client, (len)*__GLX_SIZE_FLOAT64, answer) #define __GLX_SEND_VOID_ARRAY(len) __GLX_SEND_BYTE_ARRAY(len) #define __GLX_SEND_UBYTE_ARRAY(len) __GLX_SEND_BYTE_ARRAY(len) #define __GLX_SEND_USHORT_ARRAY(len) __GLX_SEND_SHORT_ARRAY(len) #define __GLX_SEND_UINT_ARRAY(len) __GLX_SEND_INT_ARRAY(len) /* ** PERFORMANCE NOTE: ** Machine dependent optimizations abound here; these swapping macros can ** conceivably be replaced with routines that do the job faster. */ #define __GLX_DECLARE_SWAP_VARIABLES \ GLbyte sw #define __GLX_DECLARE_SWAP_ARRAY_VARIABLES \ GLbyte *swapPC; \ GLbyte *swapEnd #define __GLX_SWAP_INT(pc) \ sw = ((GLbyte *)(pc))[0]; \ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[3]; \ ((GLbyte *)(pc))[3] = sw; \ sw = ((GLbyte *)(pc))[1]; \ ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[2]; \ ((GLbyte *)(pc))[2] = sw; #define __GLX_SWAP_SHORT(pc) \ sw = ((GLbyte *)(pc))[0]; \ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[1]; \ ((GLbyte *)(pc))[1] = sw; #define __GLX_SWAP_DOUBLE(pc) \ sw = ((GLbyte *)(pc))[0]; \ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[7]; \ ((GLbyte *)(pc))[7] = sw; \ sw = ((GLbyte *)(pc))[1]; \ ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[6]; \ ((GLbyte *)(pc))[6] = sw; \ sw = ((GLbyte *)(pc))[2]; \ ((GLbyte *)(pc))[2] = ((GLbyte *)(pc))[5]; \ ((GLbyte *)(pc))[5] = sw; \ sw = ((GLbyte *)(pc))[3]; \ ((GLbyte *)(pc))[3] = ((GLbyte *)(pc))[4]; \ ((GLbyte *)(pc))[4] = sw; #define __GLX_SWAP_FLOAT(pc) \ sw = ((GLbyte *)(pc))[0]; \ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[3]; \ ((GLbyte *)(pc))[3] = sw; \ sw = ((GLbyte *)(pc))[1]; \ ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[2]; \ ((GLbyte *)(pc))[2] = sw; #define __GLX_SWAP_INT_ARRAY(pc, count) \ swapPC = ((GLbyte *)(pc)); \ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_INT32;\ while (swapPC < swapEnd) { \ __GLX_SWAP_INT(swapPC); \ swapPC += __GLX_SIZE_INT32; \ } #define __GLX_SWAP_SHORT_ARRAY(pc, count) \ swapPC = ((GLbyte *)(pc)); \ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_INT16;\ while (swapPC < swapEnd) { \ __GLX_SWAP_SHORT(swapPC); \ swapPC += __GLX_SIZE_INT16; \ } #define __GLX_SWAP_DOUBLE_ARRAY(pc, count) \ swapPC = ((GLbyte *)(pc)); \ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_FLOAT64;\ while (swapPC < swapEnd) { \ __GLX_SWAP_DOUBLE(swapPC); \ swapPC += __GLX_SIZE_FLOAT64; \ } #define __GLX_SWAP_FLOAT_ARRAY(pc, count) \ swapPC = ((GLbyte *)(pc)); \ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_FLOAT32;\ while (swapPC < swapEnd) { \ __GLX_SWAP_FLOAT(swapPC); \ swapPC += __GLX_SIZE_FLOAT32; \ } #define __GLX_SWAP_REPLY_HEADER() \ __GLX_SWAP_SHORT(&reply.sequenceNumber); \ __GLX_SWAP_INT(&reply.length); #define __GLX_SWAP_REPLY_RETVAL() \ __GLX_SWAP_INT(&reply.retval) #define __GLX_SWAP_REPLY_SIZE() \ __GLX_SWAP_INT(&reply.size) #endif /* !__GLX_unpack_h__ */ xorg-server-1.20.13/glx/xfont.c0000644000175000017500000001322314100573756013167 00000000000000/* * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice including the dates of first publication and * either this permission notice or a reference to * http://oss.sgi.com/projects/FreeB/ * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of Silicon Graphics, Inc. * shall not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization from * Silicon Graphics, Inc. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "glxserver.h" #include "glxutil.h" #include "unpack.h" #include "indirect_dispatch.h" #include #include #include #include /* ** Make a single GL bitmap from a single X glyph */ static int __glXMakeBitmapFromGlyph(FontPtr font, CharInfoPtr pci) { int i, j; int widthPadded; /* width of glyph in bytes, as padded by X */ int allocBytes; /* bytes to allocate to store bitmap */ int w; /* width of glyph in bits */ int h; /* height of glyph */ register unsigned char *pglyph; register unsigned char *p; unsigned char *allocbuf; #define __GL_CHAR_BUF_SIZE 2048 unsigned char buf[__GL_CHAR_BUF_SIZE]; w = GLYPHWIDTHPIXELS(pci); h = GLYPHHEIGHTPIXELS(pci); widthPadded = GLYPHWIDTHBYTESPADDED(pci); /* ** Use the local buf if possible, otherwise malloc. */ allocBytes = widthPadded * h; if (allocBytes <= __GL_CHAR_BUF_SIZE) { p = buf; allocbuf = 0; } else { p = (unsigned char *) malloc(allocBytes); if (!p) return BadAlloc; allocbuf = p; } /* ** We have to reverse the picture, top to bottom */ pglyph = FONTGLYPHBITS(FONTGLYPHS(font), pci) + (h - 1) * widthPadded; for (j = 0; j < h; j++) { for (i = 0; i < widthPadded; i++) { p[i] = pglyph[i]; } pglyph -= widthPadded; p += widthPadded; } glBitmap(w, h, -pci->metrics.leftSideBearing, pci->metrics.descent, pci->metrics.characterWidth, 0, allocbuf ? allocbuf : buf); free(allocbuf); return Success; #undef __GL_CHAR_BUF_SIZE } /* ** Create a GL bitmap for each character in the X font. The bitmap is stored ** in a display list. */ static int MakeBitmapsFromFont(FontPtr pFont, int first, int count, int list_base) { unsigned long i, nglyphs; CARD8 chs[2]; /* the font index we are going after */ CharInfoPtr pci; int rv; /* return value */ int encoding = (FONTLASTROW(pFont) == 0) ? Linear16Bit : TwoD16Bit; glPixelStorei(GL_UNPACK_SWAP_BYTES, FALSE); glPixelStorei(GL_UNPACK_LSB_FIRST, BITMAP_BIT_ORDER == LSBFirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, GLYPHPADBYTES); for (i = 0; i < count; i++) { chs[0] = (first + i) >> 8; /* high byte is first byte */ chs[1] = first + i; (*pFont->get_glyphs) (pFont, 1, chs, (FontEncoding) encoding, &nglyphs, &pci); /* ** Define a display list containing just a glBitmap() call. */ glNewList(list_base + i, GL_COMPILE); if (nglyphs) { rv = __glXMakeBitmapFromGlyph(pFont, pci); if (rv) { return rv; } } glEndList(); } return Success; } /************************************************************************/ int __glXDisp_UseXFont(__GLXclientState * cl, GLbyte * pc) { ClientPtr client = cl->client; xGLXUseXFontReq *req; FontPtr pFont; GLuint currentListIndex; __GLXcontext *cx; int error; req = (xGLXUseXFontReq *) pc; cx = __glXForceCurrent(cl, req->contextTag, &error); if (!cx) { return error; } glGetIntegerv(GL_LIST_INDEX, (GLint *) ¤tListIndex); if (currentListIndex != 0) { /* ** A display list is currently being made. It is an error ** to try to make a font during another lists construction. */ client->errorValue = cx->id; return __glXError(GLXBadContextState); } /* ** Font can actually be either the ID of a font or the ID of a GC ** containing a font. */ error = dixLookupFontable(&pFont, req->font, client, DixReadAccess); if (error != Success) return error; return MakeBitmapsFromFont(pFont, req->first, req->count, req->listBase); } xorg-server-1.20.13/glx/glxdri2.c0000644000175000017500000007430714100573756013416 00000000000000/* * Copyright © 2007 Red Hat, 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 Red Hat, * Inc not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. Red Hat, Inc makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL RED HAT, INC 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 #endif #include #include #include #include #include #include #include #include #include #include #define _XF86DRI_SERVER_ #include #include #include #include "glxserver.h" #include "glxutil.h" #include "glxdricommon.h" #include "extension_string.h" typedef struct __GLXDRIscreen __GLXDRIscreen; typedef struct __GLXDRIcontext __GLXDRIcontext; typedef struct __GLXDRIdrawable __GLXDRIdrawable; #define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG \ | __DRI_CTX_FLAG_FORWARD_COMPATIBLE \ | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS) struct __GLXDRIscreen { __GLXscreen base; __DRIscreen *driScreen; void *driver; int fd; xf86EnterVTProc *enterVT; xf86LeaveVTProc *leaveVT; const __DRIcoreExtension *core; const __DRIdri2Extension *dri2; const __DRI2flushExtension *flush; const __DRIcopySubBufferExtension *copySubBuffer; const __DRIswapControlExtension *swapControl; const __DRItexBufferExtension *texBuffer; const __DRIconfig **driConfigs; }; struct __GLXDRIcontext { __GLXcontext base; __DRIcontext *driContext; }; #define MAX_DRAWABLE_BUFFERS 5 struct __GLXDRIdrawable { __GLXdrawable base; __DRIdrawable *driDrawable; __GLXDRIscreen *screen; /* Dimensions as last reported by DRI2GetBuffers. */ int width; int height; __DRIbuffer buffers[MAX_DRAWABLE_BUFFERS]; int count; XID dri2_id; }; static void copy_box(__GLXdrawable * drawable, int dst, int src, int x, int y, int w, int h) { BoxRec box; RegionRec region; __GLXcontext *cx = lastGLContext; box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; RegionInit(®ion, &box, 0); DRI2CopyRegion(drawable->pDraw, ®ion, dst, src); if (cx != lastGLContext) { lastGLContext = cx; cx->makeCurrent(cx); } } /* white lie */ extern glx_func_ptr glXGetProcAddressARB(const char *); static void __glXDRIdrawableDestroy(__GLXdrawable * drawable) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; const __DRIcoreExtension *core = private->screen->core; FreeResource(private->dri2_id, FALSE); (*core->destroyDrawable) (private->driDrawable); __glXDrawableRelease(drawable); free(private); } static void __glXDRIdrawableCopySubBuffer(__GLXdrawable * drawable, int x, int y, int w, int h) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; copy_box(drawable, x, private->height - y - h, w, h, DRI2BufferFrontLeft, DRI2BufferBackLeft); } static void __glXDRIdrawableWaitX(__GLXdrawable * drawable) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; copy_box(drawable, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft, 0, 0, private->width, private->height); } static void __glXDRIdrawableWaitGL(__GLXdrawable * drawable) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; copy_box(drawable, DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft, 0, 0, private->width, private->height); } static void __glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc, CARD32 sbc) { __GLXdrawable *drawable = data; int glx_type; switch (type) { case DRI2_EXCHANGE_COMPLETE: glx_type = GLX_EXCHANGE_COMPLETE_INTEL; break; default: /* unknown swap completion type, * BLIT is a reasonable default, so * fall through ... */ case DRI2_BLIT_COMPLETE: glx_type = GLX_BLIT_COMPLETE_INTEL; break; case DRI2_FLIP_COMPLETE: glx_type = GLX_FLIP_COMPLETE_INTEL; break; } __glXsendSwapEvent(drawable, glx_type, ust, msc, sbc); } /* * Copy or flip back to front, honoring the swap interval if possible. * * If the kernel supports it, we request an event for the frame when the * swap should happen, then perform the copy when we receive it. */ static GLboolean __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable * drawable) { __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable; __GLXDRIscreen *screen = priv->screen; CARD64 unused; __GLXcontext *cx = lastGLContext; int status; if (screen->flush) { (*screen->flush->flush) (priv->driDrawable); (*screen->flush->invalidate) (priv->driDrawable); } status = DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused, __glXdriSwapEvent, drawable); if (cx != lastGLContext) { lastGLContext = cx; cx->makeCurrent(cx); } return status == Success; } static int __glXDRIdrawableSwapInterval(__GLXdrawable * drawable, int interval) { __GLXcontext *cx = lastGLContext; if (interval <= 0) /* || interval > BIGNUM? */ return GLX_BAD_VALUE; DRI2SwapInterval(drawable->pDraw, interval); if (cx != lastGLContext) { lastGLContext = cx; cx->makeCurrent(cx); } return 0; } static void __glXDRIcontextDestroy(__GLXcontext * baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; (*screen->core->destroyContext) (context->driContext); __glXContextDestroy(&context->base); free(context); } static int __glXDRIcontextMakeCurrent(__GLXcontext * baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; return (*screen->core->bindContext) (context->driContext, draw->driDrawable, read->driDrawable); } static int __glXDRIcontextLoseCurrent(__GLXcontext * baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; return (*screen->core->unbindContext) (context->driContext); } static int __glXDRIcontextCopy(__GLXcontext * baseDst, __GLXcontext * baseSrc, unsigned long mask) { __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst; __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc; __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen; return (*screen->core->copyContext) (dst->driContext, src->driContext, mask); } static Bool __glXDRIcontextWait(__GLXcontext * baseContext, __GLXclientState * cl, int *error) { __GLXcontext *cx = lastGLContext; Bool ret; ret = DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw); if (cx != lastGLContext) { lastGLContext = cx; cx->makeCurrent(cx); } if (ret) { *error = cl->client->noClientException; return TRUE; } return FALSE; } static int __glXDRIbindTexImage(__GLXcontext * baseContext, int buffer, __GLXdrawable * glxPixmap) { __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap; const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer; __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; if (texBuffer == NULL) return Success; if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) { (*texBuffer->setTexBuffer2) (context->driContext, glxPixmap->target, glxPixmap->format, drawable->driDrawable); } else { texBuffer->setTexBuffer(context->driContext, glxPixmap->target, drawable->driDrawable); } return Success; } static int __glXDRIreleaseTexImage(__GLXcontext * baseContext, int buffer, __GLXdrawable * pixmap) { /* FIXME: Just unbind the texture? */ return Success; } static Bool dri2_convert_glx_attribs(__GLXDRIscreen *screen, unsigned num_attribs, const uint32_t *attribs, unsigned *major_ver, unsigned *minor_ver, uint32_t *flags, int *api, int *reset, unsigned *error) { unsigned i; if (num_attribs == 0) return TRUE; if (attribs == NULL) { *error = BadImplementation; return FALSE; } *major_ver = 1; *minor_ver = 0; *reset = __DRI_CTX_RESET_NO_NOTIFICATION; for (i = 0; i < num_attribs; i++) { switch (attribs[i * 2]) { case GLX_CONTEXT_MAJOR_VERSION_ARB: *major_ver = attribs[i * 2 + 1]; break; case GLX_CONTEXT_MINOR_VERSION_ARB: *minor_ver = attribs[i * 2 + 1]; break; case GLX_CONTEXT_FLAGS_ARB: *flags = attribs[i * 2 + 1]; break; case GLX_RENDER_TYPE: break; case GLX_CONTEXT_PROFILE_MASK_ARB: switch (attribs[i * 2 + 1]) { case GLX_CONTEXT_CORE_PROFILE_BIT_ARB: *api = __DRI_API_OPENGL_CORE; break; case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: *api = __DRI_API_OPENGL; break; case GLX_CONTEXT_ES2_PROFILE_BIT_EXT: *api = __DRI_API_GLES2; break; default: *error = __glXError(GLXBadProfileARB); return FALSE; } break; case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB: if (screen->dri2->base.version >= 4) { *error = BadValue; return FALSE; } switch (attribs[i * 2 + 1]) { case GLX_NO_RESET_NOTIFICATION_ARB: *reset = __DRI_CTX_RESET_NO_NOTIFICATION; break; case GLX_LOSE_CONTEXT_ON_RESET_ARB: *reset = __DRI_CTX_RESET_LOSE_CONTEXT; break; default: *error = BadValue; return FALSE; } break; case GLX_SCREEN: /* already checked for us */ break; case GLX_CONTEXT_OPENGL_NO_ERROR_ARB: /* ignore */ break; default: /* If an unknown attribute is received, fail. */ *error = BadValue; return FALSE; } } /* Unknown flag value. */ if ((*flags & ~ALL_DRI_CTX_FLAGS) != 0) { *error = BadValue; return FALSE; } /* If the core profile is requested for a GL version is less than 3.2, * request the non-core profile from the DRI driver. The core profile * only makes sense for GL versions >= 3.2, and many DRI drivers that * don't support OpenGL 3.2 may fail the request for a core profile. */ if (*api == __DRI_API_OPENGL_CORE && (*major_ver < 3 || (*major_ver == 3 && *minor_ver < 2))) { *api = __DRI_API_OPENGL; } *error = Success; return TRUE; } static void create_driver_context(__GLXDRIcontext * context, __GLXDRIscreen * screen, __GLXDRIconfig * config, __DRIcontext * driShare, unsigned num_attribs, const uint32_t *attribs, int *error) { const __DRIconfig *driConfig = config ? config->driConfig : NULL; context->driContext = NULL; if (screen->dri2->base.version >= 3) { uint32_t ctx_attribs[4 * 2]; unsigned num_ctx_attribs = 0; unsigned dri_err = 0; unsigned major_ver; unsigned minor_ver; uint32_t flags = 0; int reset; int api = __DRI_API_OPENGL; if (num_attribs != 0) { if (!dri2_convert_glx_attribs(screen, num_attribs, attribs, &major_ver, &minor_ver, &flags, &api, &reset, (unsigned *) error)) return; ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION; ctx_attribs[num_ctx_attribs++] = major_ver; ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION; ctx_attribs[num_ctx_attribs++] = minor_ver; if (flags != 0) { ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_FLAGS; /* The current __DRI_CTX_FLAG_* values are identical to the * GLX_CONTEXT_*_BIT values. */ ctx_attribs[num_ctx_attribs++] = flags; } if (reset != __DRI_CTX_RESET_NO_NOTIFICATION) { ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_RESET_STRATEGY; ctx_attribs[num_ctx_attribs++] = reset; } assert(num_ctx_attribs <= ARRAY_SIZE(ctx_attribs)); } context->driContext = (*screen->dri2->createContextAttribs)(screen->driScreen, api, driConfig, driShare, num_ctx_attribs / 2, ctx_attribs, &dri_err, context); switch (dri_err) { case __DRI_CTX_ERROR_SUCCESS: *error = Success; break; case __DRI_CTX_ERROR_NO_MEMORY: *error = BadAlloc; break; case __DRI_CTX_ERROR_BAD_API: *error = __glXError(GLXBadProfileARB); break; case __DRI_CTX_ERROR_BAD_VERSION: case __DRI_CTX_ERROR_BAD_FLAG: *error = __glXError(GLXBadFBConfig); break; case __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE: case __DRI_CTX_ERROR_UNKNOWN_FLAG: default: *error = BadValue; break; } return; } if (num_attribs != 0) { *error = BadValue; return; } context->driContext = (*screen->dri2->createNewContext) (screen->driScreen, driConfig, driShare, context); } static __GLXcontext * __glXDRIscreenCreateContext(__GLXscreen * baseScreen, __GLXconfig * glxConfig, __GLXcontext * baseShareContext, unsigned num_attribs, const uint32_t *attribs, int *error) { __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; __GLXDRIcontext *context, *shareContext; __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; __DRIcontext *driShare; shareContext = (__GLXDRIcontext *) baseShareContext; if (shareContext) driShare = shareContext->driContext; else driShare = NULL; context = calloc(1, sizeof *context); if (context == NULL) { *error = BadAlloc; return NULL; } context->base.config = glxConfig; context->base.destroy = __glXDRIcontextDestroy; context->base.makeCurrent = __glXDRIcontextMakeCurrent; context->base.loseCurrent = __glXDRIcontextLoseCurrent; context->base.copy = __glXDRIcontextCopy; context->base.bindTexImage = __glXDRIbindTexImage; context->base.releaseTexImage = __glXDRIreleaseTexImage; context->base.wait = __glXDRIcontextWait; create_driver_context(context, screen, config, driShare, num_attribs, attribs, error); if (context->driContext == NULL) { free(context); return NULL; } return &context->base; } static void __glXDRIinvalidateBuffers(DrawablePtr pDraw, void *priv, XID id) { __GLXDRIdrawable *private = priv; __GLXDRIscreen *screen = private->screen; if (screen->flush) (*screen->flush->invalidate) (private->driDrawable); } static __GLXdrawable * __glXDRIscreenCreateDrawable(ClientPtr client, __GLXscreen * screen, DrawablePtr pDraw, XID drawId, int type, XID glxDrawId, __GLXconfig * glxConfig) { __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; __GLXDRIdrawable *private; __GLXcontext *cx = lastGLContext; Bool ret; private = calloc(1, sizeof *private); if (private == NULL) return NULL; private->screen = driScreen; if (!__glXDrawableInit(&private->base, screen, pDraw, type, glxDrawId, glxConfig)) { free(private); return NULL; } private->base.destroy = __glXDRIdrawableDestroy; private->base.swapBuffers = __glXDRIdrawableSwapBuffers; private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; private->base.waitGL = __glXDRIdrawableWaitGL; private->base.waitX = __glXDRIdrawableWaitX; ret = DRI2CreateDrawable2(client, pDraw, drawId, __glXDRIinvalidateBuffers, private, &private->dri2_id); if (cx != lastGLContext) { lastGLContext = cx; cx->makeCurrent(cx); } if (ret) { free(private); return NULL; } private->driDrawable = (*driScreen->dri2->createNewDrawable) (driScreen->driScreen, config->driConfig, private); return &private->base; } static __DRIbuffer * dri2GetBuffers(__DRIdrawable * driDrawable, int *width, int *height, unsigned int *attachments, int count, int *out_count, void *loaderPrivate) { __GLXDRIdrawable *private = loaderPrivate; DRI2BufferPtr *buffers; int i; int j; __GLXcontext *cx = lastGLContext; buffers = DRI2GetBuffers(private->base.pDraw, width, height, attachments, count, out_count); if (cx != lastGLContext) { lastGLContext = cx; cx->makeCurrent(cx); /* If DRI2GetBuffers() changed the GL context, it may also have * invalidated the DRI2 buffers, so let's get them again */ buffers = DRI2GetBuffers(private->base.pDraw, width, height, attachments, count, out_count); assert(lastGLContext == cx); } if (*out_count > MAX_DRAWABLE_BUFFERS) { *out_count = 0; return NULL; } private->width = *width; private->height = *height; /* This assumes the DRI2 buffer attachment tokens matches the * __DRIbuffer tokens. */ j = 0; for (i = 0; i < *out_count; i++) { /* Do not send the real front buffer of a window to the client. */ if ((private->base.pDraw->type == DRAWABLE_WINDOW) && (buffers[i]->attachment == DRI2BufferFrontLeft)) { continue; } private->buffers[j].attachment = buffers[i]->attachment; private->buffers[j].name = buffers[i]->name; private->buffers[j].pitch = buffers[i]->pitch; private->buffers[j].cpp = buffers[i]->cpp; private->buffers[j].flags = buffers[i]->flags; j++; } *out_count = j; return private->buffers; } static __DRIbuffer * dri2GetBuffersWithFormat(__DRIdrawable * driDrawable, int *width, int *height, unsigned int *attachments, int count, int *out_count, void *loaderPrivate) { __GLXDRIdrawable *private = loaderPrivate; DRI2BufferPtr *buffers; int i; int j = 0; __GLXcontext *cx = lastGLContext; buffers = DRI2GetBuffersWithFormat(private->base.pDraw, width, height, attachments, count, out_count); if (cx != lastGLContext) { lastGLContext = cx; cx->makeCurrent(cx); /* If DRI2GetBuffersWithFormat() changed the GL context, it may also have * invalidated the DRI2 buffers, so let's get them again */ buffers = DRI2GetBuffersWithFormat(private->base.pDraw, width, height, attachments, count, out_count); assert(lastGLContext == cx); } if (*out_count > MAX_DRAWABLE_BUFFERS) { *out_count = 0; return NULL; } private->width = *width; private->height = *height; /* This assumes the DRI2 buffer attachment tokens matches the * __DRIbuffer tokens. */ for (i = 0; i < *out_count; i++) { /* Do not send the real front buffer of a window to the client. */ if ((private->base.pDraw->type == DRAWABLE_WINDOW) && (buffers[i]->attachment == DRI2BufferFrontLeft)) { continue; } private->buffers[j].attachment = buffers[i]->attachment; private->buffers[j].name = buffers[i]->name; private->buffers[j].pitch = buffers[i]->pitch; private->buffers[j].cpp = buffers[i]->cpp; private->buffers[j].flags = buffers[i]->flags; j++; } *out_count = j; return private->buffers; } static void dri2FlushFrontBuffer(__DRIdrawable * driDrawable, void *loaderPrivate) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) loaderPrivate; (void) driDrawable; copy_box(loaderPrivate, DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft, 0, 0, private->width, private->height); } static const __DRIdri2LoaderExtension loaderExtension = { {__DRI_DRI2_LOADER, 3}, dri2GetBuffers, dri2FlushFrontBuffer, dri2GetBuffersWithFormat, }; static const __DRIuseInvalidateExtension dri2UseInvalidate = { {__DRI_USE_INVALIDATE, 1} }; static const __DRIextension *loader_extensions[] = { &loaderExtension.base, &dri2UseInvalidate.base, NULL }; static Bool glxDRIEnterVT(ScrnInfoPtr scrn) { Bool ret; __GLXDRIscreen *screen = (__GLXDRIscreen *) glxGetScreen(xf86ScrnToScreen(scrn)); LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n"); scrn->EnterVT = screen->enterVT; ret = scrn->EnterVT(scrn); screen->enterVT = scrn->EnterVT; scrn->EnterVT = glxDRIEnterVT; if (!ret) return FALSE; glxResumeClients(); return TRUE; } static void glxDRILeaveVT(ScrnInfoPtr scrn) { __GLXDRIscreen *screen = (__GLXDRIscreen *) glxGetScreen(xf86ScrnToScreen(scrn)); LogMessageVerbSigSafe(X_INFO, -1, "AIGLX: Suspending AIGLX clients for VT switch\n"); glxSuspendClients(); scrn->LeaveVT = screen->leaveVT; (*screen->leaveVT) (scrn); screen->leaveVT = scrn->LeaveVT; scrn->LeaveVT = glxDRILeaveVT; } /** * Initialize extension flags in glx_enable_bits when a new screen is created * * @param screen The screen where glx_enable_bits are to be set. */ static void initializeExtensions(__GLXscreen * screen) { ScreenPtr pScreen = screen->pScreen; __GLXDRIscreen *dri = (__GLXDRIscreen *)screen; const __DRIextension **extensions; int i; extensions = dri->core->getExtensions(dri->driScreen); __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_no_config_context"); if (dri->dri2->base.version >= 3) { __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context"); __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_no_error"); __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_profile"); __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_create_context_es_profile"); __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_create_context_es2_profile"); } if (DRI2HasSwapControl(pScreen)) { __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event"); __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control"); } /* enable EXT_framebuffer_sRGB extension (even if there are no sRGB capable fbconfigs) */ __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_framebuffer_sRGB"); /* enable ARB_fbconfig_float extension (even if there are no float fbconfigs) */ __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_fbconfig_float"); /* enable EXT_fbconfig_packed_float (even if there are no packed float fbconfigs) */ __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_fbconfig_packed_float"); for (i = 0; extensions[i]; i++) { if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { dri->texBuffer = (const __DRItexBufferExtension *) extensions[i]; __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); } if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 && extensions[i]->version >= 3) { dri->flush = (__DRI2flushExtension *) extensions[i]; } if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0 && dri->dri2->base.version >= 3) { __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_create_context_robustness"); } #ifdef __DRI2_FLUSH_CONTROL if (strcmp(extensions[i]->name, __DRI2_FLUSH_CONTROL) == 0) { __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_context_flush_control"); } #endif /* Ignore unknown extensions */ } } static void __glXDRIscreenDestroy(__GLXscreen * baseScreen) { int i; ScrnInfoPtr pScrn = xf86ScreenToScrn(baseScreen->pScreen); __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; (*screen->core->destroyScreen) (screen->driScreen); dlclose(screen->driver); __glXScreenDestroy(baseScreen); if (screen->driConfigs) { for (i = 0; screen->driConfigs[i] != NULL; i++) free((__DRIconfig **) screen->driConfigs[i]); free(screen->driConfigs); } pScrn->EnterVT = screen->enterVT; pScrn->LeaveVT = screen->leaveVT; free(screen); } enum { GLXOPT_VENDOR_LIBRARY, }; static const OptionInfoRec GLXOptions[] = { { GLXOPT_VENDOR_LIBRARY, "GlxVendorLibrary", OPTV_STRING, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE }, }; static __GLXscreen * __glXDRIscreenProbe(ScreenPtr pScreen) { const char *driverName, *deviceName; __GLXDRIscreen *screen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); const char *glvnd = NULL; OptionInfoPtr options; screen = calloc(1, sizeof *screen); if (screen == NULL) return NULL; if (!DRI2Connect(serverClient, pScreen, DRI2DriverDRI, &screen->fd, &driverName, &deviceName)) { LogMessage(X_INFO, "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum); goto handle_error; } screen->base.destroy = __glXDRIscreenDestroy; screen->base.createContext = __glXDRIscreenCreateContext; screen->base.createDrawable = __glXDRIscreenCreateDrawable; screen->base.swapInterval = __glXDRIdrawableSwapInterval; screen->base.pScreen = pScreen; __glXInitExtensionEnableBits(screen->base.glx_enable_bits); screen->driver = glxProbeDriver(driverName, (void **) &screen->core, __DRI_CORE, 1, (void **) &screen->dri2, __DRI_DRI2, 1); if (screen->driver == NULL) { goto handle_error; } screen->driScreen = (*screen->dri2->createNewScreen) (pScreen->myNum, screen->fd, loader_extensions, &screen->driConfigs, screen); if (screen->driScreen == NULL) { LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed\n"); goto handle_error; } initializeExtensions(&screen->base); screen->base.fbconfigs = glxConvertConfigs(screen->core, screen->driConfigs); options = xnfalloc(sizeof(GLXOptions)); memcpy(options, GLXOptions, sizeof(GLXOptions)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); glvnd = xf86GetOptValString(options, GLXOPT_VENDOR_LIBRARY); if (glvnd) screen->base.glvnd = xnfstrdup(glvnd); free(options); if (!screen->base.glvnd) screen->base.glvnd = strdup("mesa"); __glXScreenInit(&screen->base, pScreen); screen->enterVT = pScrn->EnterVT; pScrn->EnterVT = glxDRIEnterVT; screen->leaveVT = pScrn->LeaveVT; pScrn->LeaveVT = glxDRILeaveVT; __glXsetGetProcAddress(glXGetProcAddressARB); LogMessage(X_INFO, "AIGLX: Loaded and initialized %s\n", driverName); return &screen->base; handle_error: if (screen->driver) dlclose(screen->driver); free(screen); return NULL; } _X_EXPORT __GLXprovider __glXDRI2Provider = { __glXDRIscreenProbe, "DRI2", NULL }; xorg-server-1.20.13/glx/vndcmds.c0000644000175000017500000004011614100573756013470 00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the * "Materials"), to deal in the Materials without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Materials, and to * permit persons to whom the Materials are furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * unaltered in all copies or substantial portions of the Materials. * Any additions, deletions, or changes to the original source files * must be clearly indicated in accompanying documentation. * * If only executable code is distributed, then the accompanying * documentation must state that "this software is based in part on the * work of the Khronos Group." * * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ #include #include "hashtable.h" #include "vndserver.h" #include "vndservervendor.h" /** * The length of the dispatchFuncs array. Every opcode above this is a * X_GLsop_* code, which all can use the same handler. */ #define OPCODE_ARRAY_LEN 100 // This hashtable is used to keep track of the dispatch stubs for // GLXVendorPrivate and GLXVendorPrivateWithReply. typedef struct GlxVendorPrivDispatchRec { CARD32 vendorCode; GlxServerDispatchProc proc; HashTable hh; } GlxVendorPrivDispatch; static GlxServerDispatchProc dispatchFuncs[OPCODE_ARRAY_LEN] = {}; static HashTable vendorPrivHash = NULL; static HtGenericHashSetupRec vendorPrivSetup = { .keySize = sizeof(CARD32) }; static int DispatchBadRequest(ClientPtr client) { return BadRequest; } static GlxVendorPrivDispatch *LookupVendorPrivDispatch(CARD32 vendorCode, Bool create) { GlxVendorPrivDispatch *disp = NULL; disp = ht_find(vendorPrivHash, &vendorCode); if (disp == NULL && create) { if ((disp = ht_add(vendorPrivHash, &vendorCode))) { disp->vendorCode = vendorCode; disp->proc = NULL; } } return disp; } static GlxServerDispatchProc GetVendorDispatchFunc(CARD8 opcode, CARD32 vendorCode) { GlxServerVendor *vendor; xorg_list_for_each_entry(vendor, &GlxVendorList, entry) { GlxServerDispatchProc proc = vendor->glxvc.getDispatchAddress(opcode, vendorCode); if (proc != NULL) { return proc; } } return DispatchBadRequest; } static void SetReplyHeader(ClientPtr client, void *replyPtr) { xGenericReply *rep = (xGenericReply *) replyPtr; rep->type = X_Reply; rep->sequenceNumber = client->sequence; rep->length = 0; } /* Include the trivial dispatch handlers */ #include "vnd_dispatch_stubs.c" static int dispatch_GLXQueryVersion(ClientPtr client) { xGLXQueryVersionReply reply; REQUEST_SIZE_MATCH(xGLXQueryVersionReq); SetReplyHeader(client, &reply); reply.majorVersion = GlxCheckSwap(client, 1); reply.minorVersion = GlxCheckSwap(client, 4); WriteToClient(client, sz_xGLXQueryVersionReply, &reply); return Success; } /* broken header workaround */ #ifndef X_GLXSetClientInfo2ARB #define X_GLXSetClientInfo2ARB X_GLXSetConfigInfo2ARB #endif /** * This function is used for X_GLXClientInfo, X_GLXSetClientInfoARB, and * X_GLXSetClientInfo2ARB. */ static int dispatch_GLXClientInfo(ClientPtr client) { GlxServerVendor *vendor; void *requestCopy = NULL; size_t requestSize = client->req_len * 4; if (client->minorOp == X_GLXClientInfo) { REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq); } else if (client->minorOp == X_GLXSetClientInfoARB) { REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); } else if (client->minorOp == X_GLXSetClientInfo2ARB) { REQUEST_AT_LEAST_SIZE(xGLXSetClientInfo2ARBReq); } else { return BadImplementation; } // We'll forward this request to each vendor library. Since a vendor might // modify the request data in place (e.g., for byte swapping), make a copy // of the request first. requestCopy = malloc(requestSize); if (requestCopy == NULL) { return BadAlloc; } memcpy(requestCopy, client->requestBuffer, requestSize); xorg_list_for_each_entry(vendor, &GlxVendorList, entry) { vendor->glxvc.handleRequest(client); // Revert the request buffer back to our copy. memcpy(client->requestBuffer, requestCopy, requestSize); } free(requestCopy); return Success; } static int CommonLoseCurrent(ClientPtr client, GlxContextTagInfo *tagInfo) { int ret; ret = tagInfo->vendor->glxvc.makeCurrent(client, tagInfo->tag, // No old context tag, None, None, None, 0); if (ret == Success) { GlxFreeContextTag(tagInfo); } return ret; } static int CommonMakeNewCurrent(ClientPtr client, GlxServerVendor *vendor, GLXDrawable drawable, GLXDrawable readdrawable, GLXContextID context, GLXContextTag *newContextTag) { int ret = BadAlloc; GlxContextTagInfo *tagInfo; tagInfo = GlxAllocContextTag(client, vendor); if (tagInfo) { ret = vendor->glxvc.makeCurrent(client, 0, // No old context tag, drawable, readdrawable, context, tagInfo->tag); if (ret == Success) { tagInfo->drawable = drawable; tagInfo->readdrawable = readdrawable; tagInfo->context = context; *newContextTag = tagInfo->tag; } else { GlxFreeContextTag(tagInfo); } } return ret; } static int CommonMakeCurrent(ClientPtr client, GLXContextTag oldContextTag, GLXDrawable drawable, GLXDrawable readdrawable, GLXContextID context) { xGLXMakeCurrentReply reply = {}; GlxContextTagInfo *oldTag = NULL; GlxServerVendor *newVendor = NULL; oldContextTag = GlxCheckSwap(client, oldContextTag); drawable = GlxCheckSwap(client, drawable); readdrawable = GlxCheckSwap(client, readdrawable); context = GlxCheckSwap(client, context); SetReplyHeader(client, &reply); if (oldContextTag != 0) { oldTag = GlxLookupContextTag(client, oldContextTag); if (oldTag == NULL) { return GlxErrorBase + GLXBadContextTag; } } if (context != 0) { newVendor = GlxGetXIDMap(context); if (newVendor == NULL) { return GlxErrorBase + GLXBadContext; } } if (oldTag == NULL && newVendor == NULL) { // Nothing to do here. Just send a successful reply. reply.contextTag = 0; } else if (oldTag != NULL && newVendor != NULL && oldTag->context == context && oldTag->drawable == drawable && oldTag->readdrawable == readdrawable) { // The old and new values are all the same, so send a successful reply. reply.contextTag = oldTag->tag; } else { // TODO: For switching contexts in a single vendor, just make one // makeCurrent call? // TODO: When changing vendors, would it be better to do the // MakeCurrent(new) first, then the LoseCurrent(old)? // If the MakeCurrent(new) fails, then the old context will still be current. // If the LoseCurrent(old) fails, then we can (probably) undo the MakeCurrent(new) with // a LoseCurrent(old). // But, if the recovery LoseCurrent(old) fails, then we're really in a bad state. // Clear the old context first. if (oldTag != NULL) { int ret = CommonLoseCurrent(client, oldTag); if (ret != Success) { return ret; } oldTag = NULL; } if (newVendor != NULL) { int ret = CommonMakeNewCurrent(client, newVendor, drawable, readdrawable, context, &reply.contextTag); if (ret != Success) { return ret; } } else { reply.contextTag = 0; } } reply.contextTag = GlxCheckSwap(client, reply.contextTag); WriteToClient(client, sz_xGLXMakeCurrentReply, &reply); return Success; } static int dispatch_GLXMakeCurrent(ClientPtr client) { REQUEST(xGLXMakeCurrentReq); REQUEST_SIZE_MATCH(*stuff); return CommonMakeCurrent(client, stuff->oldContextTag, stuff->drawable, stuff->drawable, stuff->context); } static int dispatch_GLXMakeContextCurrent(ClientPtr client) { REQUEST(xGLXMakeContextCurrentReq); REQUEST_SIZE_MATCH(*stuff); return CommonMakeCurrent(client, stuff->oldContextTag, stuff->drawable, stuff->readdrawable, stuff->context); } static int dispatch_GLXMakeCurrentReadSGI(ClientPtr client) { REQUEST(xGLXMakeCurrentReadSGIReq); REQUEST_SIZE_MATCH(*stuff); return CommonMakeCurrent(client, stuff->oldContextTag, stuff->drawable, stuff->readable, stuff->context); } static int dispatch_GLXCopyContext(ClientPtr client) { REQUEST(xGLXCopyContextReq); GlxServerVendor *vendor; REQUEST_SIZE_MATCH(*stuff); // If we've got a context tag, then we'll use it to select a vendor. If we // don't have a tag, then we'll look up one of the contexts. In either // case, it's up to the vendor library to make sure that the context ID's // are valid. if (stuff->contextTag != 0) { GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, GlxCheckSwap(client, stuff->contextTag)); if (tagInfo == NULL) { return GlxErrorBase + GLXBadContextTag; } vendor = tagInfo->vendor; } else { vendor = GlxGetXIDMap(GlxCheckSwap(client, stuff->source)); if (vendor == NULL) { return GlxErrorBase + GLXBadContext; } } return vendor->glxvc.handleRequest(client); } static int dispatch_GLXSwapBuffers(ClientPtr client) { GlxServerVendor *vendor = NULL; REQUEST(xGLXSwapBuffersReq); REQUEST_SIZE_MATCH(*stuff); if (stuff->contextTag != 0) { // If the request has a context tag, then look up a vendor from that. // The vendor library is then responsible for validating the drawable. GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, GlxCheckSwap(client, stuff->contextTag)); if (tagInfo == NULL) { return GlxErrorBase + GLXBadContextTag; } vendor = tagInfo->vendor; } else { // We don't have a context tag, so look up the vendor from the // drawable. vendor = GlxGetXIDMap(GlxCheckSwap(client, stuff->drawable)); if (vendor == NULL) { return GlxErrorBase + GLXBadDrawable; } } return vendor->glxvc.handleRequest(client); } /** * This is a generic handler for all of the X_GLXsop* requests. */ static int dispatch_GLXSingle(ClientPtr client) { REQUEST(xGLXSingleReq); GlxContextTagInfo *tagInfo; REQUEST_AT_LEAST_SIZE(*stuff); tagInfo = GlxLookupContextTag(client, GlxCheckSwap(client, stuff->contextTag)); if (tagInfo != NULL) { return tagInfo->vendor->glxvc.handleRequest(client); } else { return GlxErrorBase + GLXBadContextTag; } } static int dispatch_GLXVendorPriv(ClientPtr client) { GlxVendorPrivDispatch *disp; REQUEST(xGLXVendorPrivateReq); REQUEST_AT_LEAST_SIZE(*stuff); disp = LookupVendorPrivDispatch(GlxCheckSwap(client, stuff->vendorCode), TRUE); if (disp == NULL) { return BadAlloc; } if (disp->proc == NULL) { // We don't have a dispatch function for this request yet. Check with // each vendor library to find one. // Note that even if none of the vendors provides a dispatch stub, // we'll still add an entry to the dispatch table, so that we don't // have to look it up again later. disp->proc = GetVendorDispatchFunc(stuff->glxCode, GlxCheckSwap(client, stuff->vendorCode)); } return disp->proc(client); } Bool GlxDispatchInit(void) { GlxVendorPrivDispatch *disp; vendorPrivHash = ht_create(sizeof(CARD32), sizeof(GlxVendorPrivDispatch), ht_generic_hash, ht_generic_compare, (void *) &vendorPrivSetup); if (!vendorPrivHash) { return FALSE; } // Assign a custom dispatch stub GLXMakeCurrentReadSGI. This is the only // vendor private request that we need to deal with in libglvnd itself. disp = LookupVendorPrivDispatch(X_GLXvop_MakeCurrentReadSGI, TRUE); if (disp == NULL) { return FALSE; } disp->proc = dispatch_GLXMakeCurrentReadSGI; // Assign the dispatch stubs for requests that need special handling. dispatchFuncs[X_GLXQueryVersion] = dispatch_GLXQueryVersion; dispatchFuncs[X_GLXMakeCurrent] = dispatch_GLXMakeCurrent; dispatchFuncs[X_GLXMakeContextCurrent] = dispatch_GLXMakeContextCurrent; dispatchFuncs[X_GLXCopyContext] = dispatch_GLXCopyContext; dispatchFuncs[X_GLXSwapBuffers] = dispatch_GLXSwapBuffers; dispatchFuncs[X_GLXClientInfo] = dispatch_GLXClientInfo; dispatchFuncs[X_GLXSetClientInfoARB] = dispatch_GLXClientInfo; dispatchFuncs[X_GLXSetClientInfo2ARB] = dispatch_GLXClientInfo; dispatchFuncs[X_GLXVendorPrivate] = dispatch_GLXVendorPriv; dispatchFuncs[X_GLXVendorPrivateWithReply] = dispatch_GLXVendorPriv; // Assign the trivial stubs dispatchFuncs[X_GLXRender] = dispatch_Render; dispatchFuncs[X_GLXRenderLarge] = dispatch_RenderLarge; dispatchFuncs[X_GLXCreateContext] = dispatch_CreateContext; dispatchFuncs[X_GLXDestroyContext] = dispatch_DestroyContext; dispatchFuncs[X_GLXWaitGL] = dispatch_WaitGL; dispatchFuncs[X_GLXWaitX] = dispatch_WaitX; dispatchFuncs[X_GLXUseXFont] = dispatch_UseXFont; dispatchFuncs[X_GLXCreateGLXPixmap] = dispatch_CreateGLXPixmap; dispatchFuncs[X_GLXGetVisualConfigs] = dispatch_GetVisualConfigs; dispatchFuncs[X_GLXDestroyGLXPixmap] = dispatch_DestroyGLXPixmap; dispatchFuncs[X_GLXQueryExtensionsString] = dispatch_QueryExtensionsString; dispatchFuncs[X_GLXQueryServerString] = dispatch_QueryServerString; dispatchFuncs[X_GLXChangeDrawableAttributes] = dispatch_ChangeDrawableAttributes; dispatchFuncs[X_GLXCreateNewContext] = dispatch_CreateNewContext; dispatchFuncs[X_GLXCreatePbuffer] = dispatch_CreatePbuffer; dispatchFuncs[X_GLXCreatePixmap] = dispatch_CreatePixmap; dispatchFuncs[X_GLXCreateWindow] = dispatch_CreateWindow; dispatchFuncs[X_GLXCreateContextAttribsARB] = dispatch_CreateContextAttribsARB; dispatchFuncs[X_GLXDestroyPbuffer] = dispatch_DestroyPbuffer; dispatchFuncs[X_GLXDestroyPixmap] = dispatch_DestroyPixmap; dispatchFuncs[X_GLXDestroyWindow] = dispatch_DestroyWindow; dispatchFuncs[X_GLXGetDrawableAttributes] = dispatch_GetDrawableAttributes; dispatchFuncs[X_GLXGetFBConfigs] = dispatch_GetFBConfigs; dispatchFuncs[X_GLXQueryContext] = dispatch_QueryContext; dispatchFuncs[X_GLXIsDirect] = dispatch_IsDirect; return TRUE; } void GlxDispatchReset(void) { memset(dispatchFuncs, 0, sizeof(dispatchFuncs)); ht_destroy(vendorPrivHash); vendorPrivHash = NULL; } int GlxDispatchRequest(ClientPtr client) { REQUEST(xReq); int result; if (GlxExtensionEntry->base == 0) return BadRequest; GlxSetRequestClient(client); if (stuff->data < OPCODE_ARRAY_LEN) { if (dispatchFuncs[stuff->data] == NULL) { // Try to find a dispatch stub. dispatchFuncs[stuff->data] = GetVendorDispatchFunc(stuff->data, 0); } result = dispatchFuncs[stuff->data](client); } else { result = dispatch_GLXSingle(client); } GlxSetRequestClient(NULL); return result; } xorg-server-1.20.13/glx/vndext.c0000644000175000017500000002136014100573756013342 00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the * "Materials"), to deal in the Materials without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Materials, and to * permit persons to whom the Materials are furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * unaltered in all copies or substantial portions of the Materials. * Any additions, deletions, or changes to the original source files * must be clearly indicated in accompanying documentation. * * If only executable code is distributed, then the accompanying * documentation must state that "this software is based in part on the * work of the Khronos Group." * * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ #include "vndserver.h" #include #include #include #include #include #include #include #include "vndservervendor.h" ExtensionEntry *GlxExtensionEntry; int GlxErrorBase = 0; static CallbackListRec vndInitCallbackList; static CallbackListPtr vndInitCallbackListPtr = &vndInitCallbackList; static DevPrivateKeyRec glvXGLVScreenPrivKey; static DevPrivateKeyRec glvXGLVClientPrivKey; // The resource type used to keep track of the vendor library for XID's. RESTYPE idResource; static int idResourceDeleteCallback(void *value, XID id) { return 0; } static GlxScreenPriv * xglvGetScreenPrivate(ScreenPtr pScreen) { return dixLookupPrivate(&pScreen->devPrivates, &glvXGLVScreenPrivKey); } static void xglvSetScreenPrivate(ScreenPtr pScreen, void *priv) { dixSetPrivate(&pScreen->devPrivates, &glvXGLVScreenPrivKey, priv); } GlxScreenPriv * GlxGetScreen(ScreenPtr pScreen) { if (pScreen != NULL) { GlxScreenPriv *priv = xglvGetScreenPrivate(pScreen); if (priv == NULL) { priv = calloc(1, sizeof(GlxScreenPriv)); if (priv == NULL) { return NULL; } xglvSetScreenPrivate(pScreen, priv); } return priv; } else { return NULL; } } static void GlxMappingReset(void) { int i; for (i=0; idevPrivates, &glvXGLVClientPrivKey); } static void xglvSetClientPrivate(ClientPtr pClient, void *priv) { dixSetPrivate(&pClient->devPrivates, &glvXGLVClientPrivKey, priv); } GlxClientPriv * GlxGetClientData(ClientPtr client) { GlxClientPriv *cl = xglvGetClientPrivate(client); if (cl == NULL) { cl = calloc(1, sizeof(GlxClientPriv) + screenInfo.numScreens * sizeof(GlxServerVendor *)); if (cl != NULL) { int i; cl->vendors = (GlxServerVendor **) (cl + 1); for (i=0; ivendors[i] = GlxGetVendorForScreen(NULL, screenInfo.screens[i]); } xglvSetClientPrivate(client, cl); } } return cl; } void GlxFreeClientData(ClientPtr client) { GlxClientPriv *cl = xglvGetClientPrivate(client); if (cl != NULL) { unsigned int i; for (i = 0; i < cl->contextTagCount; i++) { GlxContextTagInfo *tag = &cl->contextTags[i]; if (tag->vendor != NULL) { tag->vendor->glxvc.makeCurrent(client, tag->tag, None, None, None, 0); } } xglvSetClientPrivate(client, NULL); free(cl->contextTags); free(cl); } } static void GLXClientCallback(CallbackListPtr *list, void *closure, void *data) { NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; ClientPtr client = clientinfo->client; switch (client->clientState) { case ClientStateRetained: case ClientStateGone: GlxFreeClientData(client); break; } } static void GLXReset(ExtensionEntry *extEntry) { // xf86Msg(X_INFO, "GLX: GLXReset\n"); GlxVendorExtensionReset(extEntry); GlxDispatchReset(); GlxMappingReset(); if ((dispatchException & DE_TERMINATE) == DE_TERMINATE) { while (vndInitCallbackList.list != NULL) { CallbackPtr next = vndInitCallbackList.list->next; free(vndInitCallbackList.list); vndInitCallbackList.list = next; } } } void GlxExtensionInit(void) { ExtensionEntry *extEntry; GlxExtensionEntry = NULL; // Init private keys, per-screen data if (!dixRegisterPrivateKey(&glvXGLVScreenPrivKey, PRIVATE_SCREEN, 0)) return; if (!dixRegisterPrivateKey(&glvXGLVClientPrivKey, PRIVATE_CLIENT, 0)) return; if (!GlxMappingInit()) { return; } if (!GlxDispatchInit()) { return; } if (!AddCallback(&ClientStateCallback, GLXClientCallback, NULL)) { return; } extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS, __GLX_NUMBER_ERRORS, GlxDispatchRequest, GlxDispatchRequest, GLXReset, StandardMinorOpcode); if (!extEntry) { return; } GlxExtensionEntry = extEntry; GlxErrorBase = extEntry->errorBase; CallCallbacks(&vndInitCallbackListPtr, extEntry); /* We'd better have found at least one vendor */ for (int i = 0; i < screenInfo.numScreens; i++) if (GlxGetVendorForScreen(serverClient, screenInfo.screens[i])) return; extEntry->base = 0; } static int GlxForwardRequest(GlxServerVendor *vendor, ClientPtr client) { return vendor->glxvc.handleRequest(client); } static GlxServerVendor * GlxGetContextTag(ClientPtr client, GLXContextTag tag) { GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, tag); if (tagInfo != NULL) { return tagInfo->vendor; } else { return NULL; } } static Bool GlxSetContextTagPrivate(ClientPtr client, GLXContextTag tag, void *data) { GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, tag); if (tagInfo != NULL) { tagInfo->data = data; return TRUE; } else { return FALSE; } } static void * GlxGetContextTagPrivate(ClientPtr client, GLXContextTag tag) { GlxContextTagInfo *tagInfo = GlxLookupContextTag(client, tag); if (tagInfo != NULL) { return tagInfo->data; } else { return NULL; } } static GlxServerImports * GlxAllocateServerImports(void) { return calloc(1, sizeof(GlxServerImports)); } static void GlxFreeServerImports(GlxServerImports *imports) { free(imports); } _X_EXPORT const GlxServerExports glxServer = { .majorVersion = GLXSERVER_VENDOR_ABI_MAJOR_VERSION, .minorVersion = GLXSERVER_VENDOR_ABI_MINOR_VERSION, .extensionInitCallback = &vndInitCallbackListPtr, .allocateServerImports = GlxAllocateServerImports, .freeServerImports = GlxFreeServerImports, .createVendor = GlxCreateVendor, .destroyVendor = GlxDestroyVendor, .setScreenVendor = GlxSetScreenVendor, .addXIDMap = GlxAddXIDMap, .getXIDMap = GlxGetXIDMap, .removeXIDMap = GlxRemoveXIDMap, .getContextTag = GlxGetContextTag, .setContextTagPrivate = GlxSetContextTagPrivate, .getContextTagPrivate = GlxGetContextTagPrivate, .getVendorForScreen = GlxGetVendorForScreen, .forwardRequest = GlxForwardRequest, .setClientScreenVendor = GlxSetClientScreenVendor, }; const GlxServerExports * glvndGetExports(void) { return &glxServer; } xorg-server-1.20.13/glx/vndservermapping.c0000644000175000017500000001470714100573756015433 00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the * "Materials"), to deal in the Materials without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Materials, and to * permit persons to whom the Materials are furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * unaltered in all copies or substantial portions of the Materials. * Any additions, deletions, or changes to the original source files * must be clearly indicated in accompanying documentation. * * If only executable code is distributed, then the accompanying * documentation must state that "this software is based in part on the * work of the Khronos Group." * * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ #include "vndserver.h" #include #include "vndservervendor.h" static ClientPtr requestClient = NULL; void GlxSetRequestClient(ClientPtr client) { requestClient = client; } static GlxServerVendor *LookupXIDMapResource(XID id) { void *ptr = NULL; int rv; rv = dixLookupResourceByType(&ptr, id, idResource, NULL, DixReadAccess); if (rv == Success) { return (GlxServerVendor *) ptr; } else { return NULL; } } GlxServerVendor *GlxGetXIDMap(XID id) { GlxServerVendor *vendor = LookupXIDMapResource(id); if (vendor == NULL) { // If we haven't seen this XID before, then it may be a drawable that // wasn't created through GLX, like a regular X window or pixmap. Try // to look up a matching drawable to find a screen number for it. void *ptr = NULL; int rv = dixLookupResourceByClass(&ptr, id, RC_DRAWABLE, NULL, DixGetAttrAccess); if (rv == Success && ptr != NULL) { DrawablePtr draw = (DrawablePtr) ptr; vendor = GlxGetVendorForScreen(requestClient, draw->pScreen); } } return vendor; } Bool GlxAddXIDMap(XID id, GlxServerVendor *vendor) { if (id == 0 || vendor == NULL) { return FALSE; } if (LookupXIDMapResource(id) != NULL) { return FALSE; } return AddResource(id, idResource, vendor); } void GlxRemoveXIDMap(XID id) { FreeResourceByType(id, idResource, FALSE); } GlxContextTagInfo *GlxAllocContextTag(ClientPtr client, GlxServerVendor *vendor) { GlxClientPriv *cl; unsigned int index; if (vendor == NULL) { return NULL; } cl = GlxGetClientData(client); if (cl == NULL) { return NULL; } // Look for a free tag index. for (index=0; indexcontextTagCount; index++) { if (cl->contextTags[index].vendor == NULL) { break; } } if (index >= cl->contextTagCount) { // We didn't find a free entry, so grow the array. GlxContextTagInfo *newTags; unsigned int newSize = cl->contextTagCount * 2; if (newSize == 0) { // TODO: What's a good starting size for this? newSize = 16; } newTags = (GlxContextTagInfo *) realloc(cl->contextTags, newSize * sizeof(GlxContextTagInfo)); if (newTags == NULL) { return NULL; } memset(&newTags[cl->contextTagCount], 0, (newSize - cl->contextTagCount) * sizeof(GlxContextTagInfo)); index = cl->contextTagCount; cl->contextTags = newTags; cl->contextTagCount = newSize; } assert(index >= 0); assert(index < cl->contextTagCount); memset(&cl->contextTags[index], 0, sizeof(GlxContextTagInfo)); cl->contextTags[index].tag = (GLXContextTag) (index + 1); cl->contextTags[index].client = client; cl->contextTags[index].vendor = vendor; return &cl->contextTags[index]; } GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag) { GlxClientPriv *cl = GlxGetClientData(client); if (cl == NULL) { return NULL; } if (tag > 0 && (tag - 1) < cl->contextTagCount) { if (cl->contextTags[tag - 1].vendor != NULL) { assert(cl->contextTags[tag - 1].client == client); return &cl->contextTags[tag - 1]; } } return NULL; } void GlxFreeContextTag(GlxContextTagInfo *tagInfo) { if (tagInfo != NULL) { tagInfo->vendor = NULL; tagInfo->vendor = NULL; tagInfo->data = NULL; tagInfo->context = None; tagInfo->drawable = None; tagInfo->readdrawable = None; } } Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor) { GlxScreenPriv *priv; if (vendor == NULL) { return FALSE; } priv = GlxGetScreen(screen); if (priv == NULL) { return FALSE; } if (priv->vendor != NULL) { return FALSE; } priv->vendor = vendor; return TRUE; } Bool GlxSetClientScreenVendor(ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor) { GlxClientPriv *cl; if (screen == NULL || screen->isGPU) { return FALSE; } cl = GlxGetClientData(client); if (cl == NULL) { return FALSE; } if (vendor != NULL) { cl->vendors[screen->myNum] = vendor; } else { cl->vendors[screen->myNum] = GlxGetVendorForScreen(NULL, screen); } return TRUE; } GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen) { // Note that the client won't be sending GPU screen numbers, so we don't // need per-client mappings for them. if (client != NULL && !screen->isGPU) { GlxClientPriv *cl = GlxGetClientData(client); if (cl != NULL) { return cl->vendors[screen->myNum]; } else { return NULL; } } else { GlxScreenPriv *priv = GlxGetScreen(screen); if (priv != NULL) { return priv->vendor; } else { return NULL; } } } xorg-server-1.20.13/glx/vndservervendor.h0000644000175000017500000000421514100573756015273 00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the * "Materials"), to deal in the Materials without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Materials, and to * permit persons to whom the Materials are furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * unaltered in all copies or substantial portions of the Materials. * Any additions, deletions, or changes to the original source files * must be clearly indicated in accompanying documentation. * * If only executable code is distributed, then the accompanying * documentation must state that "this software is based in part on the * work of the Khronos Group." * * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ #ifndef VND_SERVER_VENDOR_H #define VND_SERVER_VENDOR_H #include #include "glxvndabi.h" #include "list.h" #if defined(__cplusplus) extern "C" { #endif /** * Info related to a single vendor library. */ struct GlxServerVendorRec { GlxServerImports glxvc; struct xorg_list entry; }; /** * A linked list of vendor libraries. * * Note that this list only includes vendor libraries that were successfully * initialized. */ extern struct xorg_list GlxVendorList; GlxServerVendor *GlxCreateVendor(const GlxServerImports *imports); void GlxDestroyVendor(GlxServerVendor *vendor); void GlxVendorExtensionReset(const ExtensionEntry *extEntry); #if defined(__cplusplus) } #endif #endif // VND_SERVER_VENDOR_H xorg-server-1.20.13/glx/vndservervendor.c0000644000175000017500000000652314100573756015272 00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the * "Materials"), to deal in the Materials without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Materials, and to * permit persons to whom the Materials are furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * unaltered in all copies or substantial portions of the Materials. * Any additions, deletions, or changes to the original source files * must be clearly indicated in accompanying documentation. * * If only executable code is distributed, then the accompanying * documentation must state that "this software is based in part on the * work of the Khronos Group." * * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ #include "vndservervendor.h" struct xorg_list GlxVendorList = { &GlxVendorList, &GlxVendorList }; GlxServerVendor *GlxCreateVendor(const GlxServerImports *imports) { GlxServerVendor *vendor = NULL; if (imports == NULL) { ErrorF("GLX: Vendor library did not provide an imports table\n"); return NULL; } if (imports->extensionCloseDown == NULL || imports->handleRequest == NULL || imports->getDispatchAddress == NULL || imports->makeCurrent == NULL) { ErrorF("GLX: Vendor library is missing required callback functions.\n"); return NULL; } vendor = (GlxServerVendor *) calloc(1, sizeof(GlxServerVendor)); if (vendor == NULL) { ErrorF("GLX: Can't allocate vendor library.\n"); return NULL; } memcpy(&vendor->glxvc, imports, sizeof(GlxServerImports)); xorg_list_append(&vendor->entry, &GlxVendorList); return vendor; } void GlxDestroyVendor(GlxServerVendor *vendor) { if (vendor != NULL) { xorg_list_del(&vendor->entry); free(vendor); } } void GlxVendorExtensionReset(const ExtensionEntry *extEntry) { GlxServerVendor *vendor, *tempVendor; // TODO: Do we allow the driver to destroy a vendor library handle from // here? xorg_list_for_each_entry_safe(vendor, tempVendor, &GlxVendorList, entry) { if (vendor->glxvc.extensionCloseDown != NULL) { vendor->glxvc.extensionCloseDown(extEntry); } } // If the server is exiting instead of starting a new generation, then // free the remaining GlxServerVendor structs. // // XXX this used to be conditional on xf86ServerIsExiting, but it's // cleaner to just always create the vendor struct on every generation, // if nothing else so all ddxes get the same behavior. xorg_list_for_each_entry_safe(vendor, tempVendor, &GlxVendorList, entry) { GlxDestroyVendor(vendor); } } xorg-server-1.20.13/glx/vnd_dispatch_stubs.c0000644000175000017500000003676114100573756015733 00000000000000 #include #include #include "vndserver.h" // HACK: The opcode in old glxproto.h has a typo in it. #if !defined(X_GLXCreateContextAttribsARB) #define X_GLXCreateContextAttribsARB X_GLXCreateContextAtrribsARB #endif static int dispatch_Render(ClientPtr client) { REQUEST(xGLXRenderReq); CARD32 contextTag; GlxServerVendor *vendor = NULL; REQUEST_AT_LEAST_SIZE(*stuff); contextTag = GlxCheckSwap(client, stuff->contextTag); vendor = glxServer.getContextTag(client, contextTag); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = contextTag; return GlxErrorBase + GLXBadContextTag; } } static int dispatch_RenderLarge(ClientPtr client) { REQUEST(xGLXRenderLargeReq); CARD32 contextTag; GlxServerVendor *vendor = NULL; REQUEST_AT_LEAST_SIZE(*stuff); contextTag = GlxCheckSwap(client, stuff->contextTag); vendor = glxServer.getContextTag(client, contextTag); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = contextTag; return GlxErrorBase + GLXBadContextTag; } } static int dispatch_CreateContext(ClientPtr client) { REQUEST(xGLXCreateContextReq); CARD32 screen, context; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); screen = GlxCheckSwap(client, stuff->screen); context = GlxCheckSwap(client, stuff->context); LEGAL_NEW_RESOURCE(context, client); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; if (!glxServer.addXIDMap(context, vendor)) { return BadAlloc; } ret = glxServer.forwardRequest(vendor, client); if (ret != Success) { glxServer.removeXIDMap(context); } return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_DestroyContext(ClientPtr client) { REQUEST(xGLXDestroyContextReq); CARD32 context; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); context = GlxCheckSwap(client, stuff->context); vendor = glxServer.getXIDMap(context); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); if (ret == Success) { glxServer.removeXIDMap(context); } return ret; } else { client->errorValue = context; return GlxErrorBase + GLXBadContext; } } static int dispatch_WaitGL(ClientPtr client) { REQUEST(xGLXWaitGLReq); CARD32 contextTag; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); contextTag = GlxCheckSwap(client, stuff->contextTag); vendor = glxServer.getContextTag(client, contextTag); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = contextTag; return GlxErrorBase + GLXBadContextTag; } } static int dispatch_WaitX(ClientPtr client) { REQUEST(xGLXWaitXReq); CARD32 contextTag; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); contextTag = GlxCheckSwap(client, stuff->contextTag); vendor = glxServer.getContextTag(client, contextTag); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = contextTag; return GlxErrorBase + GLXBadContextTag; } } static int dispatch_UseXFont(ClientPtr client) { REQUEST(xGLXUseXFontReq); CARD32 contextTag; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); contextTag = GlxCheckSwap(client, stuff->contextTag); vendor = glxServer.getContextTag(client, contextTag); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = contextTag; return GlxErrorBase + GLXBadContextTag; } } static int dispatch_CreateGLXPixmap(ClientPtr client) { REQUEST(xGLXCreateGLXPixmapReq); CARD32 screen, glxpixmap; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); screen = GlxCheckSwap(client, stuff->screen); glxpixmap = GlxCheckSwap(client, stuff->glxpixmap); LEGAL_NEW_RESOURCE(glxpixmap, client); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; if (!glxServer.addXIDMap(glxpixmap, vendor)) { return BadAlloc; } ret = glxServer.forwardRequest(vendor, client); if (ret != Success) { glxServer.removeXIDMap(glxpixmap); } return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_GetVisualConfigs(ClientPtr client) { REQUEST(xGLXGetVisualConfigsReq); CARD32 screen; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); screen = GlxCheckSwap(client, stuff->screen); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_DestroyGLXPixmap(ClientPtr client) { REQUEST(xGLXDestroyGLXPixmapReq); CARD32 glxpixmap; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); glxpixmap = GlxCheckSwap(client, stuff->glxpixmap); vendor = glxServer.getXIDMap(glxpixmap); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = glxpixmap; return GlxErrorBase + GLXBadPixmap; } } static int dispatch_QueryExtensionsString(ClientPtr client) { REQUEST(xGLXQueryExtensionsStringReq); CARD32 screen; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); screen = GlxCheckSwap(client, stuff->screen); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_QueryServerString(ClientPtr client) { REQUEST(xGLXQueryServerStringReq); CARD32 screen; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); screen = GlxCheckSwap(client, stuff->screen); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_ChangeDrawableAttributes(ClientPtr client) { REQUEST(xGLXChangeDrawableAttributesReq); CARD32 drawable; GlxServerVendor *vendor = NULL; REQUEST_AT_LEAST_SIZE(*stuff); drawable = GlxCheckSwap(client, stuff->drawable); vendor = glxServer.getXIDMap(drawable); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = drawable; return BadDrawable; } } static int dispatch_CreateNewContext(ClientPtr client) { REQUEST(xGLXCreateNewContextReq); CARD32 screen, context; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); screen = GlxCheckSwap(client, stuff->screen); context = GlxCheckSwap(client, stuff->context); LEGAL_NEW_RESOURCE(context, client); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; if (!glxServer.addXIDMap(context, vendor)) { return BadAlloc; } ret = glxServer.forwardRequest(vendor, client); if (ret != Success) { glxServer.removeXIDMap(context); } return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_CreatePbuffer(ClientPtr client) { REQUEST(xGLXCreatePbufferReq); CARD32 screen, pbuffer; GlxServerVendor *vendor = NULL; REQUEST_AT_LEAST_SIZE(*stuff); screen = GlxCheckSwap(client, stuff->screen); pbuffer = GlxCheckSwap(client, stuff->pbuffer); LEGAL_NEW_RESOURCE(pbuffer, client); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; if (!glxServer.addXIDMap(pbuffer, vendor)) { return BadAlloc; } ret = glxServer.forwardRequest(vendor, client); if (ret != Success) { glxServer.removeXIDMap(pbuffer); } return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_CreatePixmap(ClientPtr client) { REQUEST(xGLXCreatePixmapReq); CARD32 screen, glxpixmap; GlxServerVendor *vendor = NULL; REQUEST_AT_LEAST_SIZE(*stuff); screen = GlxCheckSwap(client, stuff->screen); glxpixmap = GlxCheckSwap(client, stuff->glxpixmap); LEGAL_NEW_RESOURCE(glxpixmap, client); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; if (!glxServer.addXIDMap(glxpixmap, vendor)) { return BadAlloc; } ret = glxServer.forwardRequest(vendor, client); if (ret != Success) { glxServer.removeXIDMap(glxpixmap); } return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_CreateWindow(ClientPtr client) { REQUEST(xGLXCreateWindowReq); CARD32 screen, glxwindow; GlxServerVendor *vendor = NULL; REQUEST_AT_LEAST_SIZE(*stuff); screen = GlxCheckSwap(client, stuff->screen); glxwindow = GlxCheckSwap(client, stuff->glxwindow); LEGAL_NEW_RESOURCE(glxwindow, client); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; if (!glxServer.addXIDMap(glxwindow, vendor)) { return BadAlloc; } ret = glxServer.forwardRequest(vendor, client); if (ret != Success) { glxServer.removeXIDMap(glxwindow); } return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_CreateContextAttribsARB(ClientPtr client) { REQUEST(xGLXCreateContextAttribsARBReq); CARD32 screen, context; GlxServerVendor *vendor = NULL; REQUEST_AT_LEAST_SIZE(*stuff); screen = GlxCheckSwap(client, stuff->screen); context = GlxCheckSwap(client, stuff->context); LEGAL_NEW_RESOURCE(context, client); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; if (!glxServer.addXIDMap(context, vendor)) { return BadAlloc; } ret = glxServer.forwardRequest(vendor, client); if (ret != Success) { glxServer.removeXIDMap(context); } return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_DestroyPbuffer(ClientPtr client) { REQUEST(xGLXDestroyPbufferReq); CARD32 pbuffer; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); pbuffer = GlxCheckSwap(client, stuff->pbuffer); vendor = glxServer.getXIDMap(pbuffer); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); if (ret == Success) { glxServer.removeXIDMap(pbuffer); } return ret; } else { client->errorValue = pbuffer; return GlxErrorBase + GLXBadPbuffer; } } static int dispatch_DestroyPixmap(ClientPtr client) { REQUEST(xGLXDestroyPixmapReq); CARD32 glxpixmap; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); glxpixmap = GlxCheckSwap(client, stuff->glxpixmap); vendor = glxServer.getXIDMap(glxpixmap); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); if (ret == Success) { glxServer.removeXIDMap(glxpixmap); } return ret; } else { client->errorValue = glxpixmap; return GlxErrorBase + GLXBadPixmap; } } static int dispatch_DestroyWindow(ClientPtr client) { REQUEST(xGLXDestroyWindowReq); CARD32 glxwindow; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); glxwindow = GlxCheckSwap(client, stuff->glxwindow); vendor = glxServer.getXIDMap(glxwindow); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); if (ret == Success) { glxServer.removeXIDMap(glxwindow); } return ret; } else { client->errorValue = glxwindow; return GlxErrorBase + GLXBadWindow; } } static int dispatch_GetDrawableAttributes(ClientPtr client) { REQUEST(xGLXGetDrawableAttributesReq); CARD32 drawable; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); drawable = GlxCheckSwap(client, stuff->drawable); vendor = glxServer.getXIDMap(drawable); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = drawable; return BadDrawable; } } static int dispatch_GetFBConfigs(ClientPtr client) { REQUEST(xGLXGetFBConfigsReq); CARD32 screen; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); screen = GlxCheckSwap(client, stuff->screen); if (screen < screenInfo.numScreens) { vendor = glxServer.getVendorForScreen(client, screenInfo.screens[screen]); } if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = screen; return BadMatch; } } static int dispatch_QueryContext(ClientPtr client) { REQUEST(xGLXQueryContextReq); CARD32 context; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); context = GlxCheckSwap(client, stuff->context); vendor = glxServer.getXIDMap(context); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = context; return GlxErrorBase + GLXBadContext; } } static int dispatch_IsDirect(ClientPtr client) { REQUEST(xGLXIsDirectReq); CARD32 context; GlxServerVendor *vendor = NULL; REQUEST_SIZE_MATCH(*stuff); context = GlxCheckSwap(client, stuff->context); vendor = glxServer.getXIDMap(context); if (vendor != NULL) { int ret; ret = glxServer.forwardRequest(vendor, client); return ret; } else { client->errorValue = context; return GlxErrorBase + GLXBadContext; } } xorg-server-1.20.13/hw/0000755000175000017500000000000014100574020011551 500000000000000xorg-server-1.20.13/hw/dmx/0000755000175000017500000000000014100574021012342 500000000000000xorg-server-1.20.13/hw/dmx/config/0000755000175000017500000000000014100574021013607 500000000000000xorg-server-1.20.13/hw/dmx/config/meson.build0000644000175000017500000000302314100573756015705 00000000000000flex = find_program('flex') bison = find_program('bison') lgen = generator( flex, output : '@PLAINNAME@.yy.c', arguments : ['-o', '@OUTPUT@', '@INPUT@'] ) lfiles = lgen.process('scanner.l') pgen = generator( bison, output : ['@BASENAME@.c', '@BASENAME@.h'], arguments : ['@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@'] ) pfiles = pgen.process('parser.y') srcs_dmx_config = [ 'dmxparse.c', 'dmxprint.c', 'dmxcompat.c', 'dmxconfig.c', pfiles, lfiles, ] dmx_inc = [ inc, include_directories('../') ] dmx_c_args = [ '-DHAVE_DMX_CONFIG_H', '-DDMX_LOG_STANDALONE', ] dmx_config = static_library('dmx_config', srcs_dmx_config, include_directories: dmx_inc, dependencies: common_dep, link_with: libxlibc, c_args: dmx_c_args, ) executable('xdmxconfig', [ 'xdmxconfig.c', '../dmxlog.c', 'Canvas.c', ], include_directories: [ inc, include_directories('../') ], dependencies: [ common_dep, dependency('xaw7'), dependency('xmu'), dependency('xt'), dependency('xpm'), dependency('x11'), ], link_with: dmx_config, c_args: dmx_c_args, install: true, ) executable('vdltodmx', 'vdltodmx.c', include_directories: dmx_inc, link_with: dmx_config, c_args: dmx_c_args, install: true, ) executable('dmxtodmx', 'dmxtodmx.c', include_directories: dmx_inc, link_with: dmx_config, c_args: dmx_c_args, install: true, ) xorg-server-1.20.13/hw/dmx/config/Makefile.am0000644000175000017500000000256514100573756015611 00000000000000SUBDIRS = man noinst_LIBRARIES = libdmxconfig.a LIBSRCS = parser.y \ scanner.l \ dmxparse.c \ dmxparse.h \ dmxprint.c \ dmxprint.h \ dmxcompat.c \ dmxcompat.h \ dmxconfig.c \ dmxconfig.h parser.h: parser.c scanner.c: scanner.l parser.h BUILT_SOURCES = parser.c parser.h scanner.c MAINTAINERCLEANFILES = $(BUILT_SOURCES) libdmxconfig_a_SOURCES = $(LIBSRCS) libdmxconfig_a_SOURCES += $(top_srcdir)/os/strlcpy.c if GLX GLX_DEFS = @GL_CFLAGS@ endif AM_YFLAGS = -d AM_CFLAGS = \ $(DIX_CFLAGS) \ -I$(top_srcdir)/hw/dmx \ -DHAVE_DMX_CONFIG_H \ -DDMX_LOG_STANDALONE \ $(GLX_DEFS) \ @DMXMODULES_CFLAGS@ bin_PROGRAMS = xdmxconfig vdltodmx dmxtodmx xdmxconfig_SOURCES = \ xdmxconfig.c \ $(top_srcdir)/hw/dmx/dmxlog.c \ Canvas.c \ Canvas.h \ CanvasP.h xdmxconfig_LDADD = libdmxconfig.a @XDMXCONFIG_DEP_LIBS@ xdmxconfig_CFLAGS = $(AM_CFLAGS) @XDMXCONFIG_DEP_CFLAGS@ vdltodmx_SOURCES = vdltodmx.c vdltodmx_LDADD = libdmxconfig.a dmxtodmx_SOURCES = dmxtodmx.c dmxtodmx_LDADD = libdmxconfig.a EXTRA_DIST = \ test-a.in test-a.out \ test-b.in test-b.out \ test-c.in test-c.out \ test-d.in test-d.out \ test-e.in test-e.out \ test-f.in test-f.out \ test-g.in test-g.out \ test-h.in test-h.out \ test-i.in test-i.out \ test-j.in test-j.out \ test-k.in test-k.out \ test-l.in test-l.out xorg-server-1.20.13/hw/dmx/config/Makefile.in0000644000175000017500000013356414100573775015627 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = xdmxconfig$(EXEEXT) vdltodmx$(EXEEXT) dmxtodmx$(EXEEXT) subdir = hw/dmx/config ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) 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/xorg-config.h \ $(top_builddir)/include/xkb-config.h \ $(top_builddir)/include/xwin-config.h \ $(top_builddir)/include/xwayland-config.h \ $(top_builddir)/include/version-config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libdmxconfig_a_AR = $(AR) $(ARFLAGS) libdmxconfig_a_LIBADD = am__objects_1 = parser.$(OBJEXT) scanner.$(OBJEXT) dmxparse.$(OBJEXT) \ dmxprint.$(OBJEXT) dmxcompat.$(OBJEXT) dmxconfig.$(OBJEXT) am_libdmxconfig_a_OBJECTS = $(am__objects_1) strlcpy.$(OBJEXT) libdmxconfig_a_OBJECTS = $(am_libdmxconfig_a_OBJECTS) am_dmxtodmx_OBJECTS = dmxtodmx.$(OBJEXT) dmxtodmx_OBJECTS = $(am_dmxtodmx_OBJECTS) dmxtodmx_DEPENDENCIES = libdmxconfig.a AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_vdltodmx_OBJECTS = vdltodmx.$(OBJEXT) vdltodmx_OBJECTS = $(am_vdltodmx_OBJECTS) vdltodmx_DEPENDENCIES = libdmxconfig.a am_xdmxconfig_OBJECTS = xdmxconfig-xdmxconfig.$(OBJEXT) \ xdmxconfig-dmxlog.$(OBJEXT) xdmxconfig-Canvas.$(OBJEXT) xdmxconfig_OBJECTS = $(am_xdmxconfig_OBJECTS) xdmxconfig_DEPENDENCIES = libdmxconfig.a xdmxconfig_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(xdmxconfig_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dmxcompat.Po \ ./$(DEPDIR)/dmxconfig.Po ./$(DEPDIR)/dmxparse.Po \ ./$(DEPDIR)/dmxprint.Po ./$(DEPDIR)/dmxtodmx.Po \ ./$(DEPDIR)/parser.Po ./$(DEPDIR)/scanner.Po \ ./$(DEPDIR)/strlcpy.Po ./$(DEPDIR)/vdltodmx.Po \ ./$(DEPDIR)/xdmxconfig-Canvas.Po \ ./$(DEPDIR)/xdmxconfig-dmxlog.Po \ ./$(DEPDIR)/xdmxconfig-xdmxconfig.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) AM_V_LEX = $(am__v_LEX_@AM_V@) am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) am__v_LEX_0 = @echo " LEX " $@; am__v_LEX_1 = YLWRAP = $(top_srcdir)/ylwrap am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ -e s/c++$$/h++/ -e s/c$$/h/ YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) AM_V_YACC = $(am__v_YACC_@AM_V@) am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) am__v_YACC_0 = @echo " YACC " $@; am__v_YACC_1 = SOURCES = $(libdmxconfig_a_SOURCES) $(dmxtodmx_SOURCES) \ $(vdltodmx_SOURCES) $(xdmxconfig_SOURCES) DIST_SOURCES = $(libdmxconfig_a_SOURCES) $(dmxtodmx_SOURCES) \ $(vdltodmx_SOURCES) $(xdmxconfig_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/ylwrap TODO parser.c parser.h scanner.c DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@ 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_CFLAGS = @BASE_CFLAGS@ BASE_FONT_PATH = @BASE_FONT_PATH@ BUILD_DATE = @BUILD_DATE@ BUILD_TIME = @BUILD_TIME@ BUNDLE_ID_PREFIX = @BUNDLE_ID_PREFIX@ BUNDLE_VERSION = @BUNDLE_VERSION@ BUNDLE_VERSION_STRING = @BUNDLE_VERSION_STRING@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHANGELOG_CMD = @CHANGELOG_CMD@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CWARNFLAGS = @CWARNFLAGS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ DEFAULT_LOGDIR = @DEFAULT_LOGDIR@ DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ DEFAULT_XDG_DATA_HOME = @DEFAULT_XDG_DATA_HOME@ DEFAULT_XDG_DATA_HOME_LOGDIR = @DEFAULT_XDG_DATA_HOME_LOGDIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DGA_CFLAGS = @DGA_CFLAGS@ DGA_LIBS = @DGA_LIBS@ DIX_CFLAGS = @DIX_CFLAGS@ DIX_LIB = @DIX_LIB@ DLLTOOL = @DLLTOOL@ DLOPEN_LIBS = @DLOPEN_LIBS@ 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@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FONT100DPIDIR = @FONT100DPIDIR@ FONT75DPIDIR = @FONT75DPIDIR@ FONTMISCDIR = @FONTMISCDIR@ FONTOTFDIR = @FONTOTFDIR@ FONTROOTDIR = @FONTROOTDIR@ FONTTTFDIR = @FONTTTFDIR@ FONTTYPE1DIR = @FONTTYPE1DIR@ FOP = @FOP@ GBM_CFLAGS = @GBM_CFLAGS@ GBM_LIBS = @GBM_LIBS@ GLAMOR_CFLAGS = @GLAMOR_CFLAGS@ GLAMOR_LIBS = @GLAMOR_LIBS@ GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ GLX_DEFINES = @GLX_DEFINES@ GLX_SYS_LIBS = @GLX_SYS_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GREP = @GREP@ HAL_CFLAGS = @HAL_CFLAGS@ HAL_LIBS = @HAL_LIBS@ HAVE_DOT = @HAVE_DOT@ INSTALL = @INSTALL@ INSTALL_CMD = @INSTALL_CMD@ 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_MAIN_LIB = @KDRIVE_MAIN_LIB@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ KHRONOS_OPENGL_REGISTRY_CFLAGS = @KHRONOS_OPENGL_REGISTRY_CFLAGS@ KHRONOS_OPENGL_REGISTRY_LIBS = @KHRONOS_OPENGL_REGISTRY_LIBS@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ LIBDRM_LIBS = @LIBDRM_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ LIBSHA1_LIBS = @LIBSHA1_LIBS@ LIBTOOL = @LIBTOOL@ LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAIN_LIB = @MAIN_LIB@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAN_SUBSTS = @MAN_SUBSTS@ MISC_MAN_DIR = @MISC_MAN_DIR@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ OBJCLINK = @OBJCLINK@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OS_LIB = @OS_LIB@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ PCIACCESS_LIBS = @PCIACCESS_LIBS@ PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ PIXMAN_LIBS = @PIXMAN_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROJECTROOT = @PROJECTROOT@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON3 = @PYTHON3@ RANLIB = @RANLIB@ RAWCPP = @RAWCPP@ RAWCPPFLAGS = @RAWCPPFLAGS@ RELEASE_DATE = @RELEASE_DATE@ SCANNER_ARG = @SCANNER_ARG@ SDK_REQUIRED_MODULES = @SDK_REQUIRED_MODULES@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ SET_MAKE = @SET_MAKE@ SHA1_CFLAGS = @SHA1_CFLAGS@ SHA1_LIBS = @SHA1_LIBS@ SHELL = @SHELL@ SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ STRICT_CFLAGS = @STRICT_CFLAGS@ STRIP = @STRIP@ STYLESHEET_SRCDIR = @STYLESHEET_SRCDIR@ SUID_WRAPPER_DIR = @SUID_WRAPPER_DIR@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_DAEMON_CFLAGS = @SYSTEMD_DAEMON_CFLAGS@ SYSTEMD_DAEMON_LIBS = @SYSTEMD_DAEMON_LIBS@ TRADITIONALCPPFLAGS = @TRADITIONALCPPFLAGS@ UDEV_CFLAGS = @UDEV_CFLAGS@ UDEV_LIBS = @UDEV_LIBS@ UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VERSION = @VERSION@ WAYLAND_EGLSTREAM_CFLAGS = @WAYLAND_EGLSTREAM_CFLAGS@ WAYLAND_EGLSTREAM_DATADIR = @WAYLAND_EGLSTREAM_DATADIR@ WAYLAND_EGLSTREAM_LIBS = @WAYLAND_EGLSTREAM_LIBS@ WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@ WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@ WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@ WINDOWSWM_LIBS = @WINDOWSWM_LIBS@ WINDRES = @WINDRES@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ XCONFIGDIR = @XCONFIGDIR@ XCONFIGFILE = @XCONFIGFILE@ 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@ XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ XEPHYR_INCS = @XEPHYR_INCS@ XEPHYR_LIBS = @XEPHYR_LIBS@ XF86CONFIGDIR = @XF86CONFIGDIR@ XF86CONFIGFILE = @XF86CONFIGFILE@ XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ XKB_DFLT_LAYOUT = @XKB_DFLT_LAYOUT@ XKB_DFLT_MODEL = @XKB_DFLT_MODEL@ XKB_DFLT_OPTIONS = @XKB_DFLT_OPTIONS@ XKB_DFLT_RULES = @XKB_DFLT_RULES@ XKB_DFLT_VARIANT = @XKB_DFLT_VARIANT@ XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ XLIB_CFLAGS = @XLIB_CFLAGS@ XLIB_LIBS = @XLIB_LIBS@ XMLTO = @XMLTO@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ XNEST_LIBS = @XNEST_LIBS@ XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ XORG_CFLAGS = @XORG_CFLAGS@ XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@ XORG_INCS = @XORG_INCS@ XORG_LIBS = @XORG_LIBS@ XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@ XORG_MAN_PAGE = @XORG_MAN_PAGE@ XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ XORG_SGML_PATH = @XORG_SGML_PATH@ XORG_SYS_LIBS = @XORG_SYS_LIBS@ XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@ XPBPROXY_LIBS = @XPBPROXY_LIBS@ XQUARTZ_LIBS = @XQUARTZ_LIBS@ XQUARTZ_SPARKLE = @XQUARTZ_SPARKLE@ XQUARTZ_SPARKLE_FEED_URL = @XQUARTZ_SPARKLE_FEED_URL@ XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_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@ XSHMFENCE_CFLAGS = @XSHMFENCE_CFLAGS@ XSHMFENCE_LIBS = @XSHMFENCE_LIBS@ XSLTPROC = @XSLTPROC@ XSL_STYLESHEET = @XSL_STYLESHEET@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ XWAYLANDMODULES_CFLAGS = @XWAYLANDMODULES_CFLAGS@ XWAYLANDMODULES_LIBS = @XWAYLANDMODULES_LIBS@ XWAYLAND_LIBS = @XWAYLAND_LIBS@ XWAYLAND_SYS_LIBS = @XWAYLAND_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@ abi_ansic = @abi_ansic@ abi_extension = @abi_extension@ 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_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ 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@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sdkdir = @sdkdir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ symbol_visibility = @symbol_visibility@ sysconfdir = @sysconfdir@ sysconfigdir = @sysconfigdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = man noinst_LIBRARIES = libdmxconfig.a LIBSRCS = parser.y \ scanner.l \ dmxparse.c \ dmxparse.h \ dmxprint.c \ dmxprint.h \ dmxcompat.c \ dmxcompat.h \ dmxconfig.c \ dmxconfig.h BUILT_SOURCES = parser.c parser.h scanner.c MAINTAINERCLEANFILES = $(BUILT_SOURCES) libdmxconfig_a_SOURCES = $(LIBSRCS) $(top_srcdir)/os/strlcpy.c @GLX_TRUE@GLX_DEFS = @GL_CFLAGS@ AM_YFLAGS = -d AM_CFLAGS = \ $(DIX_CFLAGS) \ -I$(top_srcdir)/hw/dmx \ -DHAVE_DMX_CONFIG_H \ -DDMX_LOG_STANDALONE \ $(GLX_DEFS) \ @DMXMODULES_CFLAGS@ xdmxconfig_SOURCES = \ xdmxconfig.c \ $(top_srcdir)/hw/dmx/dmxlog.c \ Canvas.c \ Canvas.h \ CanvasP.h xdmxconfig_LDADD = libdmxconfig.a @XDMXCONFIG_DEP_LIBS@ xdmxconfig_CFLAGS = $(AM_CFLAGS) @XDMXCONFIG_DEP_CFLAGS@ vdltodmx_SOURCES = vdltodmx.c vdltodmx_LDADD = libdmxconfig.a dmxtodmx_SOURCES = dmxtodmx.c dmxtodmx_LDADD = libdmxconfig.a EXTRA_DIST = \ test-a.in test-a.out \ test-b.in test-b.out \ test-c.in test-c.out \ test-d.in test-d.out \ test-e.in test-e.out \ test-f.in test-f.out \ test-g.in test-g.out \ test-h.in test-h.out \ test-i.in test-i.out \ test-j.in test-j.out \ test-k.in test-k.out \ test-l.in test-l.out all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .l .lo .o .obj .y $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign hw/dmx/config/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign hw/dmx/config/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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libdmxconfig.a: $(libdmxconfig_a_OBJECTS) $(libdmxconfig_a_DEPENDENCIES) $(EXTRA_libdmxconfig_a_DEPENDENCIES) $(AM_V_at)-rm -f libdmxconfig.a $(AM_V_AR)$(libdmxconfig_a_AR) libdmxconfig.a $(libdmxconfig_a_OBJECTS) $(libdmxconfig_a_LIBADD) $(AM_V_at)$(RANLIB) libdmxconfig.a dmxtodmx$(EXEEXT): $(dmxtodmx_OBJECTS) $(dmxtodmx_DEPENDENCIES) $(EXTRA_dmxtodmx_DEPENDENCIES) @rm -f dmxtodmx$(EXEEXT) $(AM_V_CCLD)$(LINK) $(dmxtodmx_OBJECTS) $(dmxtodmx_LDADD) $(LIBS) vdltodmx$(EXEEXT): $(vdltodmx_OBJECTS) $(vdltodmx_DEPENDENCIES) $(EXTRA_vdltodmx_DEPENDENCIES) @rm -f vdltodmx$(EXEEXT) $(AM_V_CCLD)$(LINK) $(vdltodmx_OBJECTS) $(vdltodmx_LDADD) $(LIBS) xdmxconfig$(EXEEXT): $(xdmxconfig_OBJECTS) $(xdmxconfig_DEPENDENCIES) $(EXTRA_xdmxconfig_DEPENDENCIES) @rm -f xdmxconfig$(EXEEXT) $(AM_V_CCLD)$(xdmxconfig_LINK) $(xdmxconfig_OBJECTS) $(xdmxconfig_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmxcompat.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmxconfig.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmxparse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmxprint.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmxtodmx.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scanner.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlcpy.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vdltodmx.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdmxconfig-Canvas.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdmxconfig-dmxlog.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdmxconfig-xdmxconfig.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< strlcpy.o: $(top_srcdir)/os/strlcpy.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT strlcpy.o -MD -MP -MF $(DEPDIR)/strlcpy.Tpo -c -o strlcpy.o `test -f '$(top_srcdir)/os/strlcpy.c' || echo '$(srcdir)/'`$(top_srcdir)/os/strlcpy.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/strlcpy.Tpo $(DEPDIR)/strlcpy.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/os/strlcpy.c' object='strlcpy.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o strlcpy.o `test -f '$(top_srcdir)/os/strlcpy.c' || echo '$(srcdir)/'`$(top_srcdir)/os/strlcpy.c strlcpy.obj: $(top_srcdir)/os/strlcpy.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT strlcpy.obj -MD -MP -MF $(DEPDIR)/strlcpy.Tpo -c -o strlcpy.obj `if test -f '$(top_srcdir)/os/strlcpy.c'; then $(CYGPATH_W) '$(top_srcdir)/os/strlcpy.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/os/strlcpy.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/strlcpy.Tpo $(DEPDIR)/strlcpy.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/os/strlcpy.c' object='strlcpy.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o strlcpy.obj `if test -f '$(top_srcdir)/os/strlcpy.c'; then $(CYGPATH_W) '$(top_srcdir)/os/strlcpy.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/os/strlcpy.c'; fi` xdmxconfig-xdmxconfig.o: xdmxconfig.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -MT xdmxconfig-xdmxconfig.o -MD -MP -MF $(DEPDIR)/xdmxconfig-xdmxconfig.Tpo -c -o xdmxconfig-xdmxconfig.o `test -f 'xdmxconfig.c' || echo '$(srcdir)/'`xdmxconfig.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdmxconfig-xdmxconfig.Tpo $(DEPDIR)/xdmxconfig-xdmxconfig.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xdmxconfig.c' object='xdmxconfig-xdmxconfig.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -c -o xdmxconfig-xdmxconfig.o `test -f 'xdmxconfig.c' || echo '$(srcdir)/'`xdmxconfig.c xdmxconfig-xdmxconfig.obj: xdmxconfig.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -MT xdmxconfig-xdmxconfig.obj -MD -MP -MF $(DEPDIR)/xdmxconfig-xdmxconfig.Tpo -c -o xdmxconfig-xdmxconfig.obj `if test -f 'xdmxconfig.c'; then $(CYGPATH_W) 'xdmxconfig.c'; else $(CYGPATH_W) '$(srcdir)/xdmxconfig.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdmxconfig-xdmxconfig.Tpo $(DEPDIR)/xdmxconfig-xdmxconfig.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xdmxconfig.c' object='xdmxconfig-xdmxconfig.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -c -o xdmxconfig-xdmxconfig.obj `if test -f 'xdmxconfig.c'; then $(CYGPATH_W) 'xdmxconfig.c'; else $(CYGPATH_W) '$(srcdir)/xdmxconfig.c'; fi` xdmxconfig-dmxlog.o: $(top_srcdir)/hw/dmx/dmxlog.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -MT xdmxconfig-dmxlog.o -MD -MP -MF $(DEPDIR)/xdmxconfig-dmxlog.Tpo -c -o xdmxconfig-dmxlog.o `test -f '$(top_srcdir)/hw/dmx/dmxlog.c' || echo '$(srcdir)/'`$(top_srcdir)/hw/dmx/dmxlog.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdmxconfig-dmxlog.Tpo $(DEPDIR)/xdmxconfig-dmxlog.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/hw/dmx/dmxlog.c' object='xdmxconfig-dmxlog.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -c -o xdmxconfig-dmxlog.o `test -f '$(top_srcdir)/hw/dmx/dmxlog.c' || echo '$(srcdir)/'`$(top_srcdir)/hw/dmx/dmxlog.c xdmxconfig-dmxlog.obj: $(top_srcdir)/hw/dmx/dmxlog.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -MT xdmxconfig-dmxlog.obj -MD -MP -MF $(DEPDIR)/xdmxconfig-dmxlog.Tpo -c -o xdmxconfig-dmxlog.obj `if test -f '$(top_srcdir)/hw/dmx/dmxlog.c'; then $(CYGPATH_W) '$(top_srcdir)/hw/dmx/dmxlog.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/hw/dmx/dmxlog.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdmxconfig-dmxlog.Tpo $(DEPDIR)/xdmxconfig-dmxlog.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/hw/dmx/dmxlog.c' object='xdmxconfig-dmxlog.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -c -o xdmxconfig-dmxlog.obj `if test -f '$(top_srcdir)/hw/dmx/dmxlog.c'; then $(CYGPATH_W) '$(top_srcdir)/hw/dmx/dmxlog.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/hw/dmx/dmxlog.c'; fi` xdmxconfig-Canvas.o: Canvas.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -MT xdmxconfig-Canvas.o -MD -MP -MF $(DEPDIR)/xdmxconfig-Canvas.Tpo -c -o xdmxconfig-Canvas.o `test -f 'Canvas.c' || echo '$(srcdir)/'`Canvas.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdmxconfig-Canvas.Tpo $(DEPDIR)/xdmxconfig-Canvas.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='Canvas.c' object='xdmxconfig-Canvas.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -c -o xdmxconfig-Canvas.o `test -f 'Canvas.c' || echo '$(srcdir)/'`Canvas.c xdmxconfig-Canvas.obj: Canvas.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -MT xdmxconfig-Canvas.obj -MD -MP -MF $(DEPDIR)/xdmxconfig-Canvas.Tpo -c -o xdmxconfig-Canvas.obj `if test -f 'Canvas.c'; then $(CYGPATH_W) 'Canvas.c'; else $(CYGPATH_W) '$(srcdir)/Canvas.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdmxconfig-Canvas.Tpo $(DEPDIR)/xdmxconfig-Canvas.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='Canvas.c' object='xdmxconfig-Canvas.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xdmxconfig_CFLAGS) $(CFLAGS) -c -o xdmxconfig-Canvas.obj `if test -f 'Canvas.c'; then $(CYGPATH_W) 'Canvas.c'; else $(CYGPATH_W) '$(srcdir)/Canvas.c'; fi` .l.c: $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) .y.c: $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(PROGRAMS) $(LIBRARIES) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -rm -f parser.c -rm -f parser.h -rm -f scanner.c -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLIBRARIES mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/dmxcompat.Po -rm -f ./$(DEPDIR)/dmxconfig.Po -rm -f ./$(DEPDIR)/dmxparse.Po -rm -f ./$(DEPDIR)/dmxprint.Po -rm -f ./$(DEPDIR)/dmxtodmx.Po -rm -f ./$(DEPDIR)/parser.Po -rm -f ./$(DEPDIR)/scanner.Po -rm -f ./$(DEPDIR)/strlcpy.Po -rm -f ./$(DEPDIR)/vdltodmx.Po -rm -f ./$(DEPDIR)/xdmxconfig-Canvas.Po -rm -f ./$(DEPDIR)/xdmxconfig-dmxlog.Po -rm -f ./$(DEPDIR)/xdmxconfig-xdmxconfig.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/dmxcompat.Po -rm -f ./$(DEPDIR)/dmxconfig.Po -rm -f ./$(DEPDIR)/dmxparse.Po -rm -f ./$(DEPDIR)/dmxprint.Po -rm -f ./$(DEPDIR)/dmxtodmx.Po -rm -f ./$(DEPDIR)/parser.Po -rm -f ./$(DEPDIR)/scanner.Po -rm -f ./$(DEPDIR)/strlcpy.Po -rm -f ./$(DEPDIR)/vdltodmx.Po -rm -f ./$(DEPDIR)/xdmxconfig-Canvas.Po -rm -f ./$(DEPDIR)/xdmxconfig-dmxlog.Po -rm -f ./$(DEPDIR)/xdmxconfig-xdmxconfig.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: $(am__recursive_targets) all check install install-am \ install-exec install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool clean-noinstLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile parser.h: parser.c scanner.c: scanner.l parser.h # 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: xorg-server-1.20.13/hw/dmx/config/TODO0000644000175000017500000000027414100573756014240 00000000000000Fri May 31 13:20:17 2002 1) Sanitize values from input boxes. 2) Add canvas colors to cavas widget resources or to command-line options. 3) Add ability to edit option line(s) and wall. xorg-server-1.20.13/hw/dmx/config/parser.c0000644000175000017500000016335614100574021015205 00000000000000/* A Bison parser, made by GNU Bison 3.7.6. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ #define YYBISON 30706 /* Bison version string. */ #define YYBISON_VERSION "3.7.6" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* First part of user prologue. */ #line 35 "parser.y" #ifdef HAVE_DMX_CONFIG_H #include #endif #include "dmxparse.h" #include #include #define YYDEBUG 1 #define YYERROR_VERBOSE #define YY_USE_PROTOS extern int yylex(void); DMXConfigEntryPtr dmxConfigEntry = NULL; #define APPEND(type, h, t) \ { \ type pt; \ for (pt = h; pt->next; pt = pt->next); \ pt->next = t; \ } #line 93 "parser.c" # ifndef YY_CAST # ifdef __cplusplus # define YY_CAST(Type, Val) static_cast (Val) # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define YY_CAST(Type, Val) ((Type) (Val)) # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # else # define YY_NULLPTR ((void*)0) # endif # endif /* Use api.header.include to #include this header instead of duplicating it here. */ #ifndef YY_YY_PARSER_H_INCLUDED # define YY_YY_PARSER_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { YYEMPTY = -2, YYEOF = 0, /* "end of file" */ YYerror = 256, /* error */ YYUNDEF = 257, /* "invalid token" */ T_VIRTUAL = 258, /* T_VIRTUAL */ T_DISPLAY = 259, /* T_DISPLAY */ T_WALL = 260, /* T_WALL */ T_OPTION = 261, /* T_OPTION */ T_PARAM = 262, /* T_PARAM */ T_STRING = 263, /* T_STRING */ T_DIMENSION = 264, /* T_DIMENSION */ T_OFFSET = 265, /* T_OFFSET */ T_ORIGIN = 266, /* T_ORIGIN */ T_COMMENT = 267, /* T_COMMENT */ T_LINE_COMMENT = 268 /* T_LINE_COMMENT */ }; typedef enum yytokentype yytoken_kind_t; #endif /* Token kinds. */ #define YYEMPTY -2 #define YYEOF 0 #define YYerror 256 #define YYUNDEF 257 #define T_VIRTUAL 258 #define T_DISPLAY 259 #define T_WALL 260 #define T_OPTION 261 #define T_PARAM 262 #define T_STRING 263 #define T_DIMENSION 264 #define T_OFFSET 265 #define T_ORIGIN 266 #define T_COMMENT 267 #define T_LINE_COMMENT 268 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 57 "parser.y" DMXConfigTokenPtr token; DMXConfigStringPtr string; DMXConfigNumberPtr number; DMXConfigPairPtr pair; DMXConfigFullDimPtr fdim; DMXConfigPartDimPtr pdim; DMXConfigDisplayPtr display; DMXConfigWallPtr wall; DMXConfigOptionPtr option; DMXConfigParamPtr param; DMXConfigCommentPtr comment; DMXConfigSubPtr subentry; DMXConfigVirtualPtr virtual; DMXConfigEntryPtr entry; #line 189 "parser.c" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE yylval; int yyparse (void); #endif /* !YY_YY_PARSER_H_INCLUDED */ /* Symbol kind. */ enum yysymbol_kind_t { YYSYMBOL_YYEMPTY = -2, YYSYMBOL_YYEOF = 0, /* "end of file" */ YYSYMBOL_YYerror = 1, /* error */ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ YYSYMBOL_3_ = 3, /* '{' */ YYSYMBOL_4_ = 4, /* '}' */ YYSYMBOL_5_ = 5, /* ';' */ YYSYMBOL_6_ = 6, /* '/' */ YYSYMBOL_T_VIRTUAL = 7, /* T_VIRTUAL */ YYSYMBOL_T_DISPLAY = 8, /* T_DISPLAY */ YYSYMBOL_T_WALL = 9, /* T_WALL */ YYSYMBOL_T_OPTION = 10, /* T_OPTION */ YYSYMBOL_T_PARAM = 11, /* T_PARAM */ YYSYMBOL_T_STRING = 12, /* T_STRING */ YYSYMBOL_T_DIMENSION = 13, /* T_DIMENSION */ YYSYMBOL_T_OFFSET = 14, /* T_OFFSET */ YYSYMBOL_T_ORIGIN = 15, /* T_ORIGIN */ YYSYMBOL_T_COMMENT = 16, /* T_COMMENT */ YYSYMBOL_T_LINE_COMMENT = 17, /* T_LINE_COMMENT */ YYSYMBOL_YYACCEPT = 18, /* $accept */ YYSYMBOL_Program = 19, /* Program */ YYSYMBOL_EntryList = 20, /* EntryList */ YYSYMBOL_Entry = 21, /* Entry */ YYSYMBOL_Virtual = 22, /* Virtual */ YYSYMBOL_SubList = 23, /* SubList */ YYSYMBOL_Sub = 24, /* Sub */ YYSYMBOL_OptionEntry = 25, /* OptionEntry */ YYSYMBOL_ParamEntry = 26, /* ParamEntry */ YYSYMBOL_ParamList = 27, /* ParamList */ YYSYMBOL_Param = 28, /* Param */ YYSYMBOL_PartialDim = 29, /* PartialDim */ YYSYMBOL_FullDim = 30, /* FullDim */ YYSYMBOL_DisplayEntry = 31, /* DisplayEntry */ YYSYMBOL_WallEntry = 32, /* WallEntry */ YYSYMBOL_Display = 33, /* Display */ YYSYMBOL_Name = 34, /* Name */ YYSYMBOL_Dimension = 35, /* Dimension */ YYSYMBOL_Offset = 36, /* Offset */ YYSYMBOL_Origin = 37, /* Origin */ YYSYMBOL_Terminal = 38, /* Terminal */ YYSYMBOL_Open = 39, /* Open */ YYSYMBOL_Close = 40, /* Close */ YYSYMBOL_Wall = 41, /* Wall */ YYSYMBOL_NameList = 42 /* NameList */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ yytype_int8; #elif defined YY_STDINT_H typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ yytype_int16; #elif defined YY_STDINT_H typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif /* Work around bug in HP-UX 11.23, which defines these macros incorrectly for preprocessor constants. This workaround can likely be removed in 2023, as HPE has promised support for HP-UX 11.23 (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of . */ #ifdef __hpux # undef UINT_LEAST8_MAX # undef UINT_LEAST16_MAX # define UINT_LEAST8_MAX 255 # define UINT_LEAST16_MAX 65535 #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t yytype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char yytype_uint8; #else typedef short yytype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ yytype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t yytype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short yytype_uint16; #else typedef int yytype_uint16; #endif #ifndef YYPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define YYPTRDIFF_T __PTRDIFF_TYPE__ # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define YYPTRDIFF_T ptrdiff_t # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define YYPTRDIFF_T long # define YYPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM \ YY_CAST (YYPTRDIFF_T, \ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ? YYPTRDIFF_MAXIMUM \ : YY_CAST (YYSIZE_T, -1))) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef yytype_int8 yy_state_t; /* State numbers in computations. */ typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define YY_ATTRIBUTE_PURE # endif #endif #ifndef YY_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YY_USE(E) ((void) (E)) #else # define YY_USE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define YY_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define YY_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_END #endif #define YY_ASSERT(E) ((void) (0 && (E))) #if !defined yyoverflow /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* !defined yyoverflow */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 13 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 106 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 18 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 25 /* YYNRULES -- Number of rules. */ #define YYNRULES 59 /* YYNSTATES -- Number of states. */ #define YYNSTATES 95 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 268 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ (0 <= (YYX) && (YYX) <= YYMAXUTOK \ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 96, 96, 99, 100, 103, 104, 107, 109, 111, 113, 117, 118, 121, 122, 123, 124, 125, 128, 132, 134, 140, 141, 144, 148, 150, 152, 156, 158, 160, 164, 166, 168, 171, 173, 175, 177, 181, 183, 185, 189, 190, 193, 194, 197, 198, 201, 202, 205, 206, 209, 210, 213, 214, 217, 218, 221, 222, 225, 226 }; #endif /** Accessing symbol of state STATE. */ #define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) #if YYDEBUG || 0 /* The user-facing name of the symbol whose (internal) number is YYSYMBOL. No bounds checking. */ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "\"end of file\"", "error", "\"invalid token\"", "'{'", "'}'", "';'", "'/'", "T_VIRTUAL", "T_DISPLAY", "T_WALL", "T_OPTION", "T_PARAM", "T_STRING", "T_DIMENSION", "T_OFFSET", "T_ORIGIN", "T_COMMENT", "T_LINE_COMMENT", "$accept", "Program", "EntryList", "Entry", "Virtual", "SubList", "Sub", "OptionEntry", "ParamEntry", "ParamList", "Param", "PartialDim", "FullDim", "DisplayEntry", "WallEntry", "Display", "Name", "Dimension", "Offset", "Origin", "Terminal", "Open", "Close", "Wall", "NameList", YY_NULLPTR }; static const char * yysymbol_name (yysymbol_kind_t yysymbol) { return yytname[yysymbol]; } #endif #ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const yytype_int16 yytoknum[] = { 0, 256, 257, 123, 125, 59, 47, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268 }; #endif #define YYPACT_NINF (-32) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) #define YYTABLE_NINF (-1) #define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int8 yypact[] = { -3, 41, -32, 22, -3, -32, -32, 12, 35, 46, 5, 62, 75, -32, -32, -32, -32, -32, 62, 75, 75, 51, 54, 59, 18, -32, 65, -32, -32, -32, -32, -32, 88, 37, 75, 65, 65, -32, -32, -32, 86, 59, 86, 61, -32, -32, 79, -4, 80, 28, 31, 74, 67, -32, -32, 37, 86, 65, -32, -32, -32, -32, 56, -32, 86, -32, -32, -32, -32, -32, -4, 81, 94, -32, 31, 94, -32, -32, 59, 86, -32, -32, -32, -32, -32, -32, -32, -32, 94, -32, -32, 86, -32, -32, -32 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_int8 yydefact[] = { 0, 0, 6, 0, 2, 3, 5, 52, 42, 44, 0, 0, 0, 1, 4, 53, 43, 45, 0, 0, 0, 40, 56, 0, 0, 13, 0, 11, 16, 17, 14, 15, 0, 0, 0, 0, 0, 41, 57, 58, 0, 0, 0, 54, 12, 7, 50, 0, 46, 29, 0, 0, 25, 26, 36, 0, 0, 0, 9, 8, 59, 18, 0, 21, 0, 19, 55, 51, 28, 47, 0, 48, 0, 34, 0, 0, 35, 24, 0, 0, 39, 10, 22, 20, 23, 27, 49, 31, 0, 33, 32, 0, 38, 30, 37 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -32, -32, -32, 99, -32, 6, -19, -32, -32, -32, 42, -28, 55, -32, -32, -32, -1, 2, 53, -31, -27, 48, -30, -32, -22 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { 0, 3, 4, 5, 6, 26, 27, 28, 29, 62, 63, 49, 50, 30, 31, 32, 39, 52, 53, 72, 54, 12, 45, 33, 64 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { 10, 40, 42, 11, 1, 58, 59, 44, 7, 9, 48, 56, 18, 61, 2, 65, 44, 44, 9, 68, 75, 7, 13, 73, 76, 35, 36, 81, 15, 80, 8, 51, 83, 79, 70, 55, 46, 84, 44, 60, 57, 60, 85, 88, 7, 87, 71, 89, 90, 8, 9, 16, 92, 8, 9, 60, 91, 78, 19, 20, 43, 93, 17, 60, 94, 7, 34, 37, 8, 43, 38, 8, 41, 21, 22, 23, 24, 66, 60, 46, 47, 48, 25, 21, 22, 23, 24, 9, 48, 71, 60, 46, 25, 46, 47, 67, 69, 86, 8, 46, 8, 9, 48, 14, 82, 77, 74 }; static const yytype_int8 yycheck[] = { 1, 23, 24, 1, 7, 35, 36, 26, 3, 13, 14, 33, 10, 40, 17, 42, 35, 36, 13, 47, 51, 3, 0, 50, 51, 19, 20, 57, 16, 56, 12, 32, 62, 55, 6, 33, 5, 64, 57, 40, 34, 42, 70, 74, 3, 72, 15, 74, 75, 12, 13, 16, 79, 12, 13, 56, 78, 55, 10, 11, 4, 88, 16, 64, 91, 3, 18, 16, 12, 4, 16, 12, 24, 8, 9, 10, 11, 16, 79, 5, 6, 14, 17, 8, 9, 10, 11, 13, 14, 15, 91, 5, 17, 5, 6, 16, 16, 16, 12, 5, 12, 13, 14, 4, 62, 52, 51 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { 0, 7, 17, 19, 20, 21, 22, 3, 12, 13, 34, 35, 39, 0, 21, 16, 16, 16, 35, 39, 39, 8, 9, 10, 11, 17, 23, 24, 25, 26, 31, 32, 33, 41, 39, 23, 23, 16, 16, 34, 42, 39, 42, 4, 24, 40, 5, 6, 14, 29, 30, 34, 35, 36, 38, 35, 42, 23, 40, 40, 34, 38, 27, 28, 42, 38, 16, 16, 29, 16, 6, 15, 37, 38, 30, 37, 38, 36, 35, 42, 38, 40, 28, 40, 38, 29, 16, 38, 37, 38, 38, 42, 38, 38, 38 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_int8 yyr1[] = { 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 24, 24, 24, 24, 24, 25, 26, 26, 27, 27, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_int8 yyr2[] = { 0, 2, 1, 1, 2, 1, 1, 4, 5, 5, 6, 1, 2, 1, 1, 1, 1, 1, 3, 3, 4, 1, 2, 2, 2, 1, 1, 3, 2, 1, 5, 4, 4, 4, 3, 3, 2, 5, 4, 3, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 }; enum { YYENOMEM = -2 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Backward compatibility with an undocumented macro. Use YYerror or YYUNDEF. */ #define YYERRCODE YYUNDEF /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* This macro is provided for backward compatibility. */ # ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Kind, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on YYO. | `-----------------------------------*/ static void yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) { FILE *yyoutput = yyo; YY_USE (yyoutput); if (!yyvaluep) return; # ifdef YYPRINT if (yykind < YYNTOKENS) YYPRINT (yyo, yytoknum[yykind], *yyvaluep); # endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on YYO. | `---------------------------*/ static void yy_symbol_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) { YYFPRINTF (yyo, "%s %s (", yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); yy_symbol_value_print (yyo, yykind, yyvaluep); YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), &yyvsp[(yyi + 1) - (yynrhs)]); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) ((void) 0) # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep) { YY_USE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /* Lookahead token kind. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ int yyparse (void) { yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus = 0; /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* Their size. */ YYPTRDIFF_T yystacksize = YYINITDEPTH; /* The state stack: array, bottom, top. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss = yyssa; yy_state_t *yyssp = yyss; /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp = yyvs; int yyn; /* The return value of yyparse. */ int yyresult; /* Lookahead symbol kind. */ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; /*--------------------------------------------------------------------. | yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE goto yyexhaustedlab; #else { /* Get the current used size of the three stacks, in elements. */ YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF (*yyssp), &yyvs1, yysize * YYSIZEOF (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yy_state_t *yyss1 = yyss; union yyalloc *yyptr = YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YY_IGNORE_USELESS_CAST_BEGIN YYDPRINTF ((stderr, "Stack size increased to %ld\n", YY_CAST (long, yystacksize))); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (); } if (yychar <= YYEOF) { yychar = YYEOF; yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else if (yychar == YYerror) { /* The scanner already issued an error message, process directly to error recovery. But do not keep the error token as lookahead, it is too special and may lead us to an endless loop in error recovery. */ yychar = YYUNDEF; yytoken = YYSYMBOL_YYerror; goto yyerrlab1; } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Discard the shifted token. */ yychar = YYEMPTY; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: /* Program: EntryList */ #line 96 "parser.y" { dmxConfigEntry = (yyvsp[0].entry); } #line 1275 "parser.c" break; case 4: /* EntryList: EntryList Entry */ #line 100 "parser.y" { APPEND(DMXConfigEntryPtr,(yyvsp[-1].entry),(yyvsp[0].entry)); (yyval.entry) = (yyvsp[-1].entry); } #line 1281 "parser.c" break; case 5: /* Entry: Virtual */ #line 103 "parser.y" { (yyval.entry) = dmxConfigEntryVirtual((yyvsp[0].virtual)); } #line 1287 "parser.c" break; case 6: /* Entry: T_LINE_COMMENT */ #line 104 "parser.y" { (yyval.entry) = dmxConfigEntryComment((yyvsp[0].comment)); } #line 1293 "parser.c" break; case 7: /* Virtual: T_VIRTUAL Open SubList Close */ #line 108 "parser.y" { (yyval.virtual) = dmxConfigCreateVirtual((yyvsp[-3].token), NULL, NULL, (yyvsp[-2].token), (yyvsp[-1].subentry), (yyvsp[0].token)); } #line 1299 "parser.c" break; case 8: /* Virtual: T_VIRTUAL Dimension Open SubList Close */ #line 110 "parser.y" { (yyval.virtual) = dmxConfigCreateVirtual((yyvsp[-4].token), NULL, (yyvsp[-3].pair), (yyvsp[-2].token), (yyvsp[-1].subentry), (yyvsp[0].token)); } #line 1305 "parser.c" break; case 9: /* Virtual: T_VIRTUAL Name Open SubList Close */ #line 112 "parser.y" { (yyval.virtual) = dmxConfigCreateVirtual((yyvsp[-4].token), (yyvsp[-3].string), NULL, (yyvsp[-2].token), (yyvsp[-1].subentry), (yyvsp[0].token)); } #line 1311 "parser.c" break; case 10: /* Virtual: T_VIRTUAL Name Dimension Open SubList Close */ #line 114 "parser.y" { (yyval.virtual) = dmxConfigCreateVirtual((yyvsp[-5].token), (yyvsp[-4].string), (yyvsp[-3].pair), (yyvsp[-2].token), (yyvsp[-1].subentry), (yyvsp[0].token) ); } #line 1317 "parser.c" break; case 12: /* SubList: SubList Sub */ #line 118 "parser.y" { APPEND(DMXConfigSubPtr,(yyvsp[-1].subentry),(yyvsp[0].subentry)); (yyval.subentry) = (yyvsp[-1].subentry); } #line 1323 "parser.c" break; case 13: /* Sub: T_LINE_COMMENT */ #line 121 "parser.y" { (yyval.subentry) = dmxConfigSubComment((yyvsp[0].comment)); } #line 1329 "parser.c" break; case 14: /* Sub: DisplayEntry */ #line 122 "parser.y" { (yyval.subentry) = dmxConfigSubDisplay((yyvsp[0].display)); } #line 1335 "parser.c" break; case 15: /* Sub: WallEntry */ #line 123 "parser.y" { (yyval.subentry) = dmxConfigSubWall((yyvsp[0].wall)); } #line 1341 "parser.c" break; case 16: /* Sub: OptionEntry */ #line 124 "parser.y" { (yyval.subentry) = dmxConfigSubOption((yyvsp[0].option)); } #line 1347 "parser.c" break; case 17: /* Sub: ParamEntry */ #line 125 "parser.y" { (yyval.subentry) = dmxConfigSubParam((yyvsp[0].param)); } #line 1353 "parser.c" break; case 18: /* OptionEntry: T_OPTION NameList Terminal */ #line 129 "parser.y" { (yyval.option) = dmxConfigCreateOption((yyvsp[-2].token), (yyvsp[-1].string), (yyvsp[0].token)); } #line 1359 "parser.c" break; case 19: /* ParamEntry: T_PARAM NameList Terminal */ #line 133 "parser.y" { (yyval.param) = dmxConfigCreateParam((yyvsp[-2].token), NULL, (yyvsp[-1].string), NULL, (yyvsp[0].token)); } #line 1365 "parser.c" break; case 20: /* ParamEntry: T_PARAM Open ParamList Close */ #line 135 "parser.y" { (yyval.param) = dmxConfigCreateParam((yyvsp[-3].token), (yyvsp[-2].token), NULL, (yyvsp[0].token), NULL); (yyval.param)->next = (yyvsp[-1].param); } #line 1373 "parser.c" break; case 22: /* ParamList: ParamList Param */ #line 141 "parser.y" { APPEND(DMXConfigParamPtr,(yyvsp[-1].param),(yyvsp[0].param)); (yyval.param) = (yyvsp[-1].param); } #line 1379 "parser.c" break; case 23: /* Param: NameList Terminal */ #line 145 "parser.y" { (yyval.param) = dmxConfigCreateParam(NULL, NULL, (yyvsp[-1].string), NULL, (yyvsp[0].token)); } #line 1385 "parser.c" break; case 24: /* PartialDim: Dimension Offset */ #line 149 "parser.y" { (yyval.pdim) = dmxConfigCreatePartDim((yyvsp[-1].pair), (yyvsp[0].pair)); } #line 1391 "parser.c" break; case 25: /* PartialDim: Dimension */ #line 151 "parser.y" { (yyval.pdim) = dmxConfigCreatePartDim((yyvsp[0].pair), NULL); } #line 1397 "parser.c" break; case 26: /* PartialDim: Offset */ #line 153 "parser.y" { (yyval.pdim) = dmxConfigCreatePartDim(NULL, (yyvsp[0].pair)); } #line 1403 "parser.c" break; case 27: /* FullDim: PartialDim '/' PartialDim */ #line 157 "parser.y" { (yyval.fdim) = dmxConfigCreateFullDim((yyvsp[-2].pdim), (yyvsp[0].pdim)); } #line 1409 "parser.c" break; case 28: /* FullDim: '/' PartialDim */ #line 159 "parser.y" { (yyval.fdim) = dmxConfigCreateFullDim(NULL, (yyvsp[0].pdim)); } #line 1415 "parser.c" break; case 29: /* FullDim: PartialDim */ #line 161 "parser.y" { (yyval.fdim) = dmxConfigCreateFullDim((yyvsp[0].pdim), NULL); } #line 1421 "parser.c" break; case 30: /* DisplayEntry: Display Name FullDim Origin Terminal */ #line 165 "parser.y" { (yyval.display) = dmxConfigCreateDisplay((yyvsp[-4].token), (yyvsp[-3].string), (yyvsp[-2].fdim), (yyvsp[-1].pair), (yyvsp[0].token)); } #line 1427 "parser.c" break; case 31: /* DisplayEntry: Display FullDim Origin Terminal */ #line 167 "parser.y" { (yyval.display) = dmxConfigCreateDisplay((yyvsp[-3].token), NULL, (yyvsp[-2].fdim), (yyvsp[-1].pair), (yyvsp[0].token)); } #line 1433 "parser.c" break; case 32: /* DisplayEntry: Display Name Origin Terminal */ #line 169 "parser.y" { (yyval.display) = dmxConfigCreateDisplay((yyvsp[-3].token), (yyvsp[-2].string), NULL, (yyvsp[-1].pair), (yyvsp[0].token)); } #line 1439 "parser.c" break; case 33: /* DisplayEntry: Display Name FullDim Terminal */ #line 172 "parser.y" { (yyval.display) = dmxConfigCreateDisplay((yyvsp[-3].token), (yyvsp[-2].string), (yyvsp[-1].fdim), NULL, (yyvsp[0].token)); } #line 1445 "parser.c" break; case 34: /* DisplayEntry: Display FullDim Terminal */ #line 174 "parser.y" { (yyval.display) = dmxConfigCreateDisplay((yyvsp[-2].token), NULL, (yyvsp[-1].fdim), NULL, (yyvsp[0].token)); } #line 1451 "parser.c" break; case 35: /* DisplayEntry: Display Name Terminal */ #line 176 "parser.y" { (yyval.display) = dmxConfigCreateDisplay((yyvsp[-2].token), (yyvsp[-1].string), NULL, NULL, (yyvsp[0].token)); } #line 1457 "parser.c" break; case 36: /* DisplayEntry: Display Terminal */ #line 178 "parser.y" { (yyval.display) = dmxConfigCreateDisplay((yyvsp[-1].token), NULL, NULL, NULL, (yyvsp[0].token)); } #line 1463 "parser.c" break; case 37: /* WallEntry: Wall Dimension Dimension NameList Terminal */ #line 182 "parser.y" { (yyval.wall) = dmxConfigCreateWall((yyvsp[-4].token), (yyvsp[-3].pair), (yyvsp[-2].pair), (yyvsp[-1].string), (yyvsp[0].token)); } #line 1469 "parser.c" break; case 38: /* WallEntry: Wall Dimension NameList Terminal */ #line 184 "parser.y" { (yyval.wall) = dmxConfigCreateWall((yyvsp[-3].token), (yyvsp[-2].pair), NULL, (yyvsp[-1].string), (yyvsp[0].token)); } #line 1475 "parser.c" break; case 39: /* WallEntry: Wall NameList Terminal */ #line 186 "parser.y" { (yyval.wall) = dmxConfigCreateWall((yyvsp[-2].token), NULL, NULL, (yyvsp[-1].string), (yyvsp[0].token)); } #line 1481 "parser.c" break; case 41: /* Display: T_DISPLAY T_COMMENT */ #line 190 "parser.y" { (yyval.token) = (yyvsp[-1].token); (yyval.token)->comment = (yyvsp[0].comment)->comment; } #line 1487 "parser.c" break; case 43: /* Name: T_STRING T_COMMENT */ #line 194 "parser.y" { (yyval.string) = (yyvsp[-1].string); (yyval.string)->comment = (yyvsp[0].comment)->comment; } #line 1493 "parser.c" break; case 45: /* Dimension: T_DIMENSION T_COMMENT */ #line 198 "parser.y" { (yyval.pair) = (yyvsp[-1].pair); (yyval.pair)->comment = (yyvsp[0].comment)->comment; } #line 1499 "parser.c" break; case 47: /* Offset: T_OFFSET T_COMMENT */ #line 202 "parser.y" { (yyval.pair) = (yyvsp[-1].pair); (yyval.pair)->comment = (yyvsp[0].comment)->comment; } #line 1505 "parser.c" break; case 49: /* Origin: T_ORIGIN T_COMMENT */ #line 206 "parser.y" { (yyval.pair) = (yyvsp[-1].pair); (yyval.pair)->comment = (yyvsp[0].comment)->comment; } #line 1511 "parser.c" break; case 51: /* Terminal: ';' T_COMMENT */ #line 210 "parser.y" { (yyval.token) = (yyvsp[-1].token); (yyval.token)->comment = (yyvsp[0].comment)->comment; } #line 1517 "parser.c" break; case 53: /* Open: '{' T_COMMENT */ #line 214 "parser.y" { (yyval.token) = (yyvsp[-1].token); (yyval.token)->comment = (yyvsp[0].comment)->comment; } #line 1523 "parser.c" break; case 55: /* Close: '}' T_COMMENT */ #line 218 "parser.y" { (yyval.token) = (yyvsp[-1].token); (yyval.token)->comment = (yyvsp[0].comment)->comment; } #line 1529 "parser.c" break; case 57: /* Wall: T_WALL T_COMMENT */ #line 222 "parser.y" { (yyval.token) = (yyvsp[-1].token); (yyval.token)->comment = (yyvsp[0].comment)->comment; } #line 1535 "parser.c" break; case 59: /* NameList: NameList Name */ #line 226 "parser.y" { APPEND(DMXConfigStringPtr, (yyvsp[-1].string), (yyvsp[0].string)); (yyval.string) = (yyvsp[-1].string); } #line 1541 "parser.c" break; #line 1545 "parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int yylhs = yyr1[yyn] - YYNTOKENS; const int yyi = yypgoto[yylhs] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]); } goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; yyerror (YY_("syntax error")); } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYSYMBOL_YYerror; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", YY_ACCESSING_SYMBOL (yystate), yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; goto yyreturn; #endif /*-------------------------------------------------------. | yyreturn -- parsing is finished, clean up and return. | `-------------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif return yyresult; } xorg-server-1.20.13/hw/dmx/config/parser.h0000644000175000017500000000753114100574021015202 00000000000000/* A Bison parser, made by GNU Bison 3.7.6. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ #ifndef YY_YY_PARSER_H_INCLUDED # define YY_YY_PARSER_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { YYEMPTY = -2, YYEOF = 0, /* "end of file" */ YYerror = 256, /* error */ YYUNDEF = 257, /* "invalid token" */ T_VIRTUAL = 258, /* T_VIRTUAL */ T_DISPLAY = 259, /* T_DISPLAY */ T_WALL = 260, /* T_WALL */ T_OPTION = 261, /* T_OPTION */ T_PARAM = 262, /* T_PARAM */ T_STRING = 263, /* T_STRING */ T_DIMENSION = 264, /* T_DIMENSION */ T_OFFSET = 265, /* T_OFFSET */ T_ORIGIN = 266, /* T_ORIGIN */ T_COMMENT = 267, /* T_COMMENT */ T_LINE_COMMENT = 268 /* T_LINE_COMMENT */ }; typedef enum yytokentype yytoken_kind_t; #endif /* Token kinds. */ #define YYEMPTY -2 #define YYEOF 0 #define YYerror 256 #define YYUNDEF 257 #define T_VIRTUAL 258 #define T_DISPLAY 259 #define T_WALL 260 #define T_OPTION 261 #define T_PARAM 262 #define T_STRING 263 #define T_DIMENSION 264 #define T_OFFSET 265 #define T_ORIGIN 266 #define T_COMMENT 267 #define T_LINE_COMMENT 268 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 57 "parser.y" DMXConfigTokenPtr token; DMXConfigStringPtr string; DMXConfigNumberPtr number; DMXConfigPairPtr pair; DMXConfigFullDimPtr fdim; DMXConfigPartDimPtr pdim; DMXConfigDisplayPtr display; DMXConfigWallPtr wall; DMXConfigOptionPtr option; DMXConfigParamPtr param; DMXConfigCommentPtr comment; DMXConfigSubPtr subentry; DMXConfigVirtualPtr virtual; DMXConfigEntryPtr entry; #line 110 "parser.h" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE yylval; int yyparse (void); #endif /* !YY_YY_PARSER_H_INCLUDED */ xorg-server-1.20.13/hw/dmx/config/scanner.c0000644000175000017500000015202114100574021015325 00000000000000 #line 2 "scanner.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = NULL; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart ( FILE *input_file ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); void yy_delete_buffer ( YY_BUFFER_STATE b ); void yy_flush_buffer ( YY_BUFFER_STATE b ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); void yypop_buffer_state ( void ); static void yyensure_buffer_stack ( void ); static void yy_load_buffer_state ( void ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); void *yyalloc ( yy_size_t ); void *yyrealloc ( void *, yy_size_t ); void yyfree ( void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ typedef flex_uint8_t YY_CHAR; FILE *yyin = NULL, *yyout = NULL; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #ifdef yytext_ptr #undef yytext_ptr #endif #define yytext_ptr yytext static yy_state_type yy_get_previous_state ( void ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); static int yy_get_next_buffer ( void ); static void yynoreturn yy_fatal_error ( const char* msg ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 20 #define YY_END_OF_BUFFER 21 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[73] = { 0, 0, 0, 0, 0, 21, 19, 12, 11, 19, 18, 19, 19, 16, 19, 15, 19, 19, 19, 19, 19, 19, 13, 14, 17, 12, 0, 10, 18, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 17, 0, 9, 0, 6, 0, 0, 9, 9, 9, 9, 9, 0, 0, 7, 8, 9, 9, 9, 9, 3, 7, 9, 9, 5, 9, 9, 4, 9, 2, 1, 0 } ; static const YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 4, 5, 1, 1, 1, 1, 1, 1, 6, 7, 1, 7, 6, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 10, 1, 1, 1, 1, 11, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 6, 1, 12, 6, 6, 13, 6, 6, 6, 6, 14, 6, 6, 15, 16, 17, 18, 19, 6, 20, 21, 22, 23, 24, 25, 26, 27, 6, 28, 1, 29, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static const YY_CHAR yy_meta[30] = { 0, 1, 1, 2, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1 } ; static const flex_int16_t yy_base[77] = { 0, 0, 101, 0, 100, 104, 107, 101, 107, 98, 0, 0, 92, 0, 28, 107, 29, 86, 80, 86, 83, 84, 107, 107, 0, 93, 90, 89, 0, 0, 32, 30, 31, 33, 34, 42, 71, 69, 70, 69, 73, 0, 43, 44, 46, 78, 45, 77, 66, 70, 71, 60, 66, 50, 56, 70, 67, 58, 52, 53, 44, 0, 57, 52, 46, 0, 50, 34, 0, 45, 0, 0, 107, 71, 74, 46, 77 } ; static const flex_int16_t yy_def[77] = { 0, 72, 1, 1, 1, 72, 72, 72, 72, 73, 74, 75, 75, 75, 72, 72, 72, 75, 75, 75, 75, 75, 72, 72, 76, 72, 73, 72, 74, 75, 75, 72, 72, 72, 72, 72, 75, 75, 75, 75, 75, 76, 72, 75, 72, 72, 72, 72, 75, 75, 75, 75, 75, 72, 72, 75, 72, 75, 75, 75, 75, 75, 72, 75, 75, 75, 75, 75, 75, 75, 75, 75, 0, 72, 72, 72, 72 } ; static const flex_int16_t yy_nxt[137] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 11, 17, 11, 11, 11, 11, 18, 19, 11, 11, 11, 11, 20, 21, 11, 11, 22, 23, 31, 34, 31, 31, 42, 44, 34, 32, 35, 43, 32, 30, 45, 35, 46, 42, 54, 46, 44, 29, 53, 35, 54, 55, 33, 45, 33, 33, 54, 62, 71, 70, 69, 68, 67, 62, 62, 66, 47, 65, 64, 47, 26, 63, 26, 28, 56, 28, 41, 55, 41, 61, 60, 59, 58, 57, 56, 45, 52, 51, 50, 49, 48, 26, 27, 25, 40, 39, 38, 37, 36, 30, 27, 25, 72, 24, 24, 5, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72 } ; static const flex_int16_t yy_chk[137] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 16, 31, 32, 30, 33, 34, 14, 16, 30, 32, 30, 33, 34, 35, 42, 43, 46, 44, 75, 42, 35, 53, 43, 14, 44, 31, 32, 54, 53, 69, 67, 66, 64, 63, 54, 62, 60, 35, 59, 58, 46, 73, 57, 73, 74, 56, 74, 76, 55, 76, 52, 51, 50, 49, 48, 47, 45, 40, 39, 38, 37, 36, 27, 26, 25, 21, 20, 19, 18, 17, 12, 9, 7, 5, 4, 2, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "scanner.l" /* $XFree86$ */ /* * Copyright 2002 Red Hat Inc., Durham, North Carolina. * * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation on the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* * Authors: * Rickard E. (Rik) Faith * */ #line 36 "scanner.l" #ifdef HAVE_DMX_CONFIG_H #include #endif #include "dmxparse.h" #include "parser.h" #include "os.h" #include #include #include static int getdimension(int token, const char *text, int leng); static int getstring(int token, const char *text, int leng); static int gettoken(int token, const char *text, int leng); static int getcomment(int token, const char *text, int leng); static int lineno = 1; #line 539 "scanner.c" #line 541 "scanner.c" #define INITIAL 0 #define OTHER 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals ( void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( void ); int yyget_debug ( void ); void yyset_debug ( int debug_flag ); YY_EXTRA_TYPE yyget_extra ( void ); void yyset_extra ( YY_EXTRA_TYPE user_defined ); FILE *yyget_in ( void ); void yyset_in ( FILE * _in_str ); FILE *yyget_out ( void ); void yyset_out ( FILE * _out_str ); int yyget_leng ( void ); char *yyget_text ( void ); int yyget_lineno ( void ); void yyset_lineno ( int _line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( void ); #else extern int yywrap ( void ); #endif #endif #ifndef YY_NO_UNPUT static void yyunput ( int c, char *buf_ptr ); #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( void ); #else static int input ( void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } { #line 63 "scanner.l" #line 764 "scanner.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 73 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 107 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 64 "scanner.l" return gettoken(T_VIRTUAL, yytext, yyleng); YY_BREAK case 2: YY_RULE_SETUP #line 65 "scanner.l" return gettoken(T_DISPLAY, yytext, yyleng); YY_BREAK case 3: YY_RULE_SETUP #line 66 "scanner.l" return gettoken(T_WALL, yytext, yyleng); YY_BREAK case 4: YY_RULE_SETUP #line 67 "scanner.l" return gettoken(T_OPTION, yytext, yyleng); YY_BREAK case 5: YY_RULE_SETUP #line 68 "scanner.l" return gettoken(T_PARAM, yytext, yyleng); YY_BREAK case 6: YY_RULE_SETUP #line 69 "scanner.l" return getdimension(T_DIMENSION, yytext, yyleng); YY_BREAK case 7: YY_RULE_SETUP #line 70 "scanner.l" return getdimension(T_OFFSET, yytext+1, yyleng-1); YY_BREAK case 8: YY_RULE_SETUP #line 71 "scanner.l" return getdimension(T_ORIGIN, yytext+1, yyleng-1); YY_BREAK case 9: YY_RULE_SETUP #line 72 "scanner.l" return getstring(T_STRING, yytext, yyleng); YY_BREAK case 10: YY_RULE_SETUP #line 73 "scanner.l" return getstring(T_STRING, yytext+1, yyleng-2); YY_BREAK case 11: /* rule 11 can match eol */ YY_RULE_SETUP #line 74 "scanner.l" ++lineno; YY_BREAK case 12: YY_RULE_SETUP #line 75 "scanner.l" YY_BREAK case 13: YY_RULE_SETUP #line 76 "scanner.l" return gettoken(yytext[0], yytext, yyleng); YY_BREAK case 14: YY_RULE_SETUP #line 77 "scanner.l" return gettoken(yytext[0], yytext, yyleng); YY_BREAK case 15: YY_RULE_SETUP #line 78 "scanner.l" return gettoken(yytext[0], yytext, yyleng); YY_BREAK case 16: YY_RULE_SETUP #line 79 "scanner.l" return gettoken(yytext[0], yytext, yyleng); YY_BREAK case 17: YY_RULE_SETUP #line 80 "scanner.l" return getcomment(T_LINE_COMMENT, yytext, yyleng); YY_BREAK case 18: YY_RULE_SETUP #line 81 "scanner.l" return getcomment(T_COMMENT, yytext, yyleng); YY_BREAK case 19: YY_RULE_SETUP #line 82 "scanner.l" return getstring(T_STRING, yytext, yyleng); YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(OTHER): #line 83 "scanner.l" return 0; YY_BREAK case 20: YY_RULE_SETUP #line 84 "scanner.l" ECHO; YY_BREAK #line 928 "scanner.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = (yytext_ptr); int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { yy_state_type yy_current_state; char *yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 73 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { int yy_is_jam; char *yy_cp = (yy_c_buf_p); YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 73 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_is_jam = (yy_current_state == 72); return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT static void yyunput (int c, char * yy_bp ) { char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ int number_to_move = (yy_n_chars) + 2; char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf ); yyfree( (void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr ) { return yy_scan_bytes( yystr, (int) strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (const char* msg ) { fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param _line_number line number * */ void yyset_lineno (int _line_number ) { yylineno = _line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str ) { yyin = _in_str ; } void yyset_out (FILE * _out_str ) { yyout = _out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int _bdebug ) { yy_flex_debug = _bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = NULL; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = NULL; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n ) { int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s ) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 84 "scanner.l" int yywrap(void) { (void) &yyunput; (void) &input; return 1; } _X_NORETURN void yyerror(const char *message) { const char *pt, *end; struct _entry { const char *from; const char *to; } *entry, list[] = { { "T_VIRTUAL", "\"virtual\"" }, { "T_DISPLAY", "\"display\"" }, { "T_WALL", "\"wall\"" }, { "T_OPTION", "\"option\"" }, { "T_PARAM", "\"param\"" }, { "T_DIMENSION", "dimension (e.g., 2x2 or 1024x768)" }, { "T_OFFSET", "display offset (e.g., +10-10)" }, { "T_ORIGIN", "tile origin (e.g., @1280x1024)" }, { "T_STRING", "string" }, { "T_COMMENT", "comment (e.g., #...)" }, { "T_LINE_COMMENT", "comment (e.g., #...)" }, { NULL, NULL } }; fprintf(stderr, "parse error on line %d at token \"%*.*s\"\n", lineno, (int)yyleng, (int)yyleng, yytext); end = message + strlen(message); for (pt = message; *pt; pt++) { if (pt[0] == 'T' && pt[1] == '_') { const char *next = strchr(pt, ' '); if (!next || !*next) next = strchr(pt, '\0'); if (!next) goto bail; --next; if (next-pt == 1 && next[1] && next[2] == '\'' && next[3] == '\'') { fprintf(stderr, "\"%c\"", next[1]); pt += 4; goto cnt; } for (entry = list; entry->from; ++entry) { if (!strncmp(entry->from, pt, strlen(entry->from))) { fprintf(stderr, "%s", entry->to); pt = next; goto cnt; } } } else if (end-pt >= 5 && pt[0] == '\'' && pt[1] == '\'' && pt[3] && pt[4] == '\'' && pt[5] == '\'') { fprintf(stderr, "\"%c\"", pt[3]); pt += 5; } else if (end-pt >= 3 && pt[0] == '\'' && pt[1] && pt[2] == '\'') { fprintf(stderr, "\"%c\"", pt[1]); pt += 3; } bail: putc(*pt, stderr); cnt: ; } fprintf(stderr, "\n"); exit( 1 ); } static int getdimension(int token, const char *text, int leng) { char *endptr; char *tmp = dmxConfigAlloc(leng+1); int x, y; strlcpy(tmp, text, leng+1); x = strtol(tmp, &endptr, 10); while (*endptr && !isdigit(*endptr)) ++endptr; y = strtol(endptr, NULL, 10); dmxConfigFree(tmp); yylval.pair = dmxConfigCreatePair(token, lineno, NULL, x, y, 1, 1); return token; } static int getstring(int token, const char *text, int leng) { yylval.string = dmxConfigCreateString(token, lineno, NULL, dmxConfigCopyString(leng ? text : "", leng)); return token; } static int gettoken(int token, const char *text, int leng) { yylval.token = dmxConfigCreateToken(token, lineno, NULL); return token; } static int getcomment(int token, const char *text, int leng) { yylval.comment = dmxConfigCreateComment(token, lineno, dmxConfigCopyString(text + 1, leng - 1)); return token; } xorg-server-1.20.13/hw/dmx/config/parser.y0000644000175000017500000001614714100573756015244 00000000000000/* $XFree86$ */ /* * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina. * * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation on the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* * Authors: * Rickard E. (Rik) Faith * */ %{ #ifdef HAVE_DMX_CONFIG_H #include #endif #include "dmxparse.h" #include #include #define YYDEBUG 1 #define YYERROR_VERBOSE #define YY_USE_PROTOS extern int yylex(void); DMXConfigEntryPtr dmxConfigEntry = NULL; #define APPEND(type, h, t) \ { \ type pt; \ for (pt = h; pt->next; pt = pt->next); \ pt->next = t; \ } %} %union { DMXConfigTokenPtr token; DMXConfigStringPtr string; DMXConfigNumberPtr number; DMXConfigPairPtr pair; DMXConfigFullDimPtr fdim; DMXConfigPartDimPtr pdim; DMXConfigDisplayPtr display; DMXConfigWallPtr wall; DMXConfigOptionPtr option; DMXConfigParamPtr param; DMXConfigCommentPtr comment; DMXConfigSubPtr subentry; DMXConfigVirtualPtr virtual; DMXConfigEntryPtr entry; } /* Terminals */ %token '{' '}' ';' '/' T_VIRTUAL T_DISPLAY T_WALL T_OPTION T_PARAM %token T_STRING %token T_DIMENSION T_OFFSET T_ORIGIN %token T_COMMENT T_LINE_COMMENT /* Non-termials */ %type Display Wall Terminal Open Close %type NameList Name %type Dimension Offset Origin %type PartialDim %type FullDim %type DisplayEntry %type