diff options
author | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
commit | 3562e78743202e43aec8727005182a2558117eca (patch) | |
tree | 8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /xorg-server/hw/kdrive/src | |
download | vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2 vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip |
Checked in the following released items:
xkeyboard-config-1.4.tar.gz
ttf-bitstream-vera-1.10.tar.gz
font-alias-1.0.1.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sony-misc-1.0.0.tar.gz
font-schumacher-misc-1.0.0.tar.gz
font-mutt-misc-1.0.0.tar.gz
font-misc-misc-1.0.0.tar.gz
font-misc-meltho-1.0.0.tar.gz
font-micro-misc-1.0.0.tar.gz
font-jis-misc-1.0.0.tar.gz
font-isas-misc-1.0.0.tar.gz
font-dec-misc-1.0.0.tar.gz
font-daewoo-misc-1.0.0.tar.gz
font-cursor-misc-1.0.0.tar.gz
font-arabic-misc-1.0.0.tar.gz
font-winitzki-cyrillic-1.0.0.tar.gz
font-misc-cyrillic-1.0.0.tar.gz
font-cronyx-cyrillic-1.0.0.tar.gz
font-screen-cyrillic-1.0.1.tar.gz
font-xfree86-type1-1.0.1.tar.gz
font-adobe-utopia-type1-1.0.1.tar.gz
font-ibm-type1-1.0.0.tar.gz
font-bitstream-type1-1.0.0.tar.gz
font-bitstream-speedo-1.0.0.tar.gz
font-bh-ttf-1.0.0.tar.gz
font-bh-type1-1.0.0.tar.gz
font-bitstream-100dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz
font-bh-100dpi-1.0.0.tar.gz
font-adobe-utopia-100dpi-1.0.1.tar.gz
font-adobe-100dpi-1.0.0.tar.gz
font-util-1.0.1.tar.gz
font-bitstream-75dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz
font-adobe-utopia-75dpi-1.0.1.tar.gz
font-bh-75dpi-1.0.0.tar.gz
bdftopcf-1.0.1.tar.gz
font-adobe-75dpi-1.0.0.tar.gz
mkfontscale-1.0.6.tar.gz
openssl-0.9.8k.tar.gz
bigreqsproto-1.0.2.tar.gz
xtrans-1.2.2.tar.gz
resourceproto-1.0.2.tar.gz
inputproto-1.4.4.tar.gz
compositeproto-0.4.tar.gz
damageproto-1.1.0.tar.gz
zlib-1.2.3.tar.gz
xkbcomp-1.0.5.tar.gz
freetype-2.3.9.tar.gz
pthreads-w32-2-8-0-release.tar.gz
pixman-0.12.0.tar.gz
kbproto-1.0.3.tar.gz
evieext-1.0.2.tar.gz
fixesproto-4.0.tar.gz
recordproto-1.13.2.tar.gz
randrproto-1.2.2.tar.gz
scrnsaverproto-1.1.0.tar.gz
renderproto-0.9.3.tar.gz
xcmiscproto-1.1.2.tar.gz
fontsproto-2.0.2.tar.gz
xextproto-7.0.3.tar.gz
xproto-7.0.14.tar.gz
libXdmcp-1.0.2.tar.gz
libxkbfile-1.0.5.tar.gz
libfontenc-1.0.4.tar.gz
libXfont-1.3.4.tar.gz
libX11-1.1.5.tar.gz
libXau-1.0.4.tar.gz
libxcb-1.1.tar.gz
xorg-server-1.5.3.tar.gz
Diffstat (limited to 'xorg-server/hw/kdrive/src')
24 files changed, 12958 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/src/Makefile.am b/xorg-server/hw/kdrive/src/Makefile.am new file mode 100644 index 000000000..07ab8c859 --- /dev/null +++ b/xorg-server/hw/kdrive/src/Makefile.am @@ -0,0 +1,40 @@ +INCLUDES = \ + @KDRIVE_INCS@ \ + @KDRIVE_CFLAGS@ + +AM_CFLAGS = -DHAVE_DIX_CONFIG_H + +noinst_LIBRARIES = libkdrive.a libkdrivestubs.a + +if KDRIVE_HW +KDRIVE_HW_SOURCES = \ + vga.c \ + vga.h +endif + +libkdrive_a_SOURCES = \ + fourcc.h \ + kaa.c \ + kaa.h \ + kaapict.c \ + kasync.c \ + kcmap.c \ + kcurscol.c \ + kdrive.c \ + kdrive.h \ + kinfo.c \ + kinput.c \ + kkeymap.c \ + kmap.c \ + kmode.c \ + knoop.c \ + koffscreen.c \ + kshadow.c \ + ktest.c \ + kxv.c \ + kxv.h \ + $(KDRIVE_HW_SOURCES) \ + $(top_srcdir)/mi/miinitext.c + +libkdrivestubs_a_SOURCES = \ + $(top_srcdir)/fb/fbcmap_mi.c diff --git a/xorg-server/hw/kdrive/src/Makefile.in b/xorg-server/hw/kdrive/src/Makefile.in new file mode 100644 index 000000000..4938456a5 --- /dev/null +++ b/xorg-server/hw/kdrive/src/Makefile.in @@ -0,0 +1,740 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = hw/kdrive/src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \ + $(top_builddir)/include/xorg-server.h \ + $(top_builddir)/include/dix-config.h \ + $(top_builddir)/include/xgl-config.h \ + $(top_builddir)/include/xorg-config.h \ + $(top_builddir)/include/xkb-config.h \ + $(top_builddir)/include/xwin-config.h \ + $(top_builddir)/include/kdrive-config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libkdrive_a_AR = $(AR) $(ARFLAGS) +libkdrive_a_LIBADD = +am__libkdrive_a_SOURCES_DIST = fourcc.h kaa.c kaa.h kaapict.c kasync.c \ + kcmap.c kcurscol.c kdrive.c kdrive.h kinfo.c kinput.c \ + kkeymap.c kmap.c kmode.c knoop.c koffscreen.c kshadow.c \ + ktest.c kxv.c kxv.h vga.c vga.h $(top_srcdir)/mi/miinitext.c +@KDRIVE_HW_TRUE@am__objects_1 = vga.$(OBJEXT) +am_libkdrive_a_OBJECTS = kaa.$(OBJEXT) kaapict.$(OBJEXT) \ + kasync.$(OBJEXT) kcmap.$(OBJEXT) kcurscol.$(OBJEXT) \ + kdrive.$(OBJEXT) kinfo.$(OBJEXT) kinput.$(OBJEXT) \ + kkeymap.$(OBJEXT) kmap.$(OBJEXT) kmode.$(OBJEXT) \ + knoop.$(OBJEXT) koffscreen.$(OBJEXT) kshadow.$(OBJEXT) \ + ktest.$(OBJEXT) kxv.$(OBJEXT) $(am__objects_1) \ + miinitext.$(OBJEXT) +libkdrive_a_OBJECTS = $(am_libkdrive_a_OBJECTS) +libkdrivestubs_a_AR = $(AR) $(ARFLAGS) +libkdrivestubs_a_LIBADD = +am_libkdrivestubs_a_OBJECTS = fbcmap_mi.$(OBJEXT) +libkdrivestubs_a_OBJECTS = $(am_libkdrivestubs_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libkdrive_a_SOURCES) $(libkdrivestubs_a_SOURCES) +DIST_SOURCES = $(am__libkdrive_a_SOURCES_DIST) \ + $(libkdrivestubs_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ +ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +APPDEFAULTDIR = @APPDEFAULTDIR@ +APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ +APP_MAN_DIR = @APP_MAN_DIR@ +APP_MAN_SUFFIX = @APP_MAN_SUFFIX@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASE_FONT_PATH = @BASE_FONT_PATH@ +BUILD_DATE = @BUILD_DATE@ +BUILD_TIME = @BUILD_TIME@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DARWIN_LIBS = @DARWIN_LIBS@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ +DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ +DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DGA_CFLAGS = @DGA_CFLAGS@ +DGA_LIBS = @DGA_LIBS@ +DIX_CFLAGS = @DIX_CFLAGS@ +DLLTOOL = @DLLTOOL@ +DMXEXAMPLES_DEP_CFLAGS = @DMXEXAMPLES_DEP_CFLAGS@ +DMXEXAMPLES_DEP_LIBS = @DMXEXAMPLES_DEP_LIBS@ +DMXMODULES_CFLAGS = @DMXMODULES_CFLAGS@ +DMXMODULES_LIBS = @DMXMODULES_LIBS@ +DMXXIEXAMPLES_DEP_CFLAGS = @DMXXIEXAMPLES_DEP_CFLAGS@ +DMXXIEXAMPLES_DEP_LIBS = @DMXXIEXAMPLES_DEP_LIBS@ +DMXXMUEXAMPLES_DEP_CFLAGS = @DMXXMUEXAMPLES_DEP_CFLAGS@ +DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@ +DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ +DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ +DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@ +DRIPROTO_LIBS = @DRIPROTO_LIBS@ +DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ +DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ +DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ +DSYMUTIL = @DSYMUTIL@ +DTRACE = @DTRACE@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FILE_MAN_DIR = @FILE_MAN_DIR@ +FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ +GLX_DEFINES = @GLX_DEFINES@ +GL_CFLAGS = @GL_CFLAGS@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +HAL_CFLAGS = @HAL_CFLAGS@ +HAL_LIBS = @HAL_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KDRIVE_CFLAGS = @KDRIVE_CFLAGS@ +KDRIVE_INCS = @KDRIVE_INCS@ +KDRIVE_LIBS = @KDRIVE_LIBS@ +KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@ +KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ +KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ +LAUNCHD = @LAUNCHD@ +LDFLAGS = @LDFLAGS@ +LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +LIBDRM_LIBS = @LIBDRM_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_MAN_DIR = @LIB_MAN_DIR@ +LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ +LINUXDOC = @LINUXDOC@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MAKE_HTML = @MAKE_HTML@ +MAKE_PDF = @MAKE_PDF@ +MAKE_PS = @MAKE_PS@ +MAKE_TEXT = @MAKE_TEXT@ +MESA_SOURCE = @MESA_SOURCE@ +MISC_MAN_DIR = @MISC_MAN_DIR@ +MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ +MKDIR_P = @MKDIR_P@ +MKFONTDIR = @MKFONTDIR@ +MKFONTSCALE = @MKFONTSCALE@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCCLD = @OBJCCLD@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJCLINK = @OBJCLINK@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ +PCIACCESS_LIBS = @PCIACCESS_LIBS@ +PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PROJECTROOT = @PROJECTROOT@ +PS2PDF = @PS2PDF@ +RANLIB = @RANLIB@ +RAWCPP = @RAWCPP@ +RAWCPPFLAGS = @RAWCPPFLAGS@ +SED = @SED@ +SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOLARIS_ASM_CFLAGS = @SOLARIS_ASM_CFLAGS@ +SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ +STRIP = @STRIP@ +TSLIB_CFLAGS = @TSLIB_CFLAGS@ +TSLIB_LIBS = @TSLIB_LIBS@ +UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ +VENDOR_MAN_VERSION = @VENDOR_MAN_VERSION@ +VENDOR_NAME = @VENDOR_NAME@ +VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ +VENDOR_RELEASE = @VENDOR_RELEASE@ +VERSION = @VERSION@ +X11APP_ARCHS = @X11APP_ARCHS@ +X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ +X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ +XDMCP_CFLAGS = @XDMCP_CFLAGS@ +XDMCP_LIBS = @XDMCP_LIBS@ +XDMXCONFIG_DEP_CFLAGS = @XDMXCONFIG_DEP_CFLAGS@ +XDMXCONFIG_DEP_LIBS = @XDMXCONFIG_DEP_LIBS@ +XDMX_CFLAGS = @XDMX_CFLAGS@ +XDMX_LIBS = @XDMX_LIBS@ +XDMX_SYS_LIBS = @XDMX_SYS_LIBS@ +XEGLMODULES_CFLAGS = @XEGLMODULES_CFLAGS@ +XEGL_LIBS = @XEGL_LIBS@ +XEGL_SYS_LIBS = @XEGL_SYS_LIBS@ +XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ +XEPHYR_DRI_LIBS = @XEPHYR_DRI_LIBS@ +XEPHYR_INCS = @XEPHYR_INCS@ +XEPHYR_LIBS = @XEPHYR_LIBS@ +XF86CONFIGFILE = @XF86CONFIGFILE@ +XF86MISC_CFLAGS = @XF86MISC_CFLAGS@ +XF86MISC_LIBS = @XF86MISC_LIBS@ +XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@ +XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@ +XGLMODULES_CFLAGS = @XGLMODULES_CFLAGS@ +XGLMODULES_LIBS = @XGLMODULES_LIBS@ +XGLXMODULES_CFLAGS = @XGLXMODULES_CFLAGS@ +XGLXMODULES_LIBS = @XGLXMODULES_LIBS@ +XGLX_LIBS = @XGLX_LIBS@ +XGLX_SYS_LIBS = @XGLX_SYS_LIBS@ +XGL_LIBS = @XGL_LIBS@ +XGL_MODULE_PATH = @XGL_MODULE_PATH@ +XGL_SYS_LIBS = @XGL_SYS_LIBS@ +XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ +XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ +XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ +XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ +XLIB_CFLAGS = @XLIB_CFLAGS@ +XLIB_LIBS = @XLIB_LIBS@ +XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ +XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ +XNEST_LIBS = @XNEST_LIBS@ +XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ +XORGCFG_DEP_CFLAGS = @XORGCFG_DEP_CFLAGS@ +XORGCFG_DEP_LIBS = @XORGCFG_DEP_LIBS@ +XORGCONFIG_DEP_CFLAGS = @XORGCONFIG_DEP_CFLAGS@ +XORGCONFIG_DEP_LIBS = @XORGCONFIG_DEP_LIBS@ +XORG_CFLAGS = @XORG_CFLAGS@ +XORG_INCS = @XORG_INCS@ +XORG_LIBS = @XORG_LIBS@ +XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ +XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ +XORG_OS = @XORG_OS@ +XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ +XORG_SYS_LIBS = @XORG_SYS_LIBS@ +XPRINTMODULES_CFLAGS = @XPRINTMODULES_CFLAGS@ +XPRINTMODULES_LIBS = @XPRINTMODULES_LIBS@ +XPRINTPROTO_CFLAGS = @XPRINTPROTO_CFLAGS@ +XPRINTPROTO_LIBS = @XPRINTPROTO_LIBS@ +XPRINT_CFLAGS = @XPRINT_CFLAGS@ +XPRINT_LIBS = @XPRINT_LIBS@ +XPRINT_SYS_LIBS = @XPRINT_SYS_LIBS@ +XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ +XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@ +XSDL_INCS = @XSDL_INCS@ +XSDL_LIBS = @XSDL_LIBS@ +XSERVERCFLAGS_CFLAGS = @XSERVERCFLAGS_CFLAGS@ +XSERVERCFLAGS_LIBS = @XSERVERCFLAGS_LIBS@ +XSERVERLIBS_CFLAGS = @XSERVERLIBS_CFLAGS@ +XSERVERLIBS_LIBS = @XSERVERLIBS_LIBS@ +XSERVER_LIBS = @XSERVER_LIBS@ +XSERVER_SYS_LIBS = @XSERVER_SYS_LIBS@ +XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ +XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ +XVFB_LIBS = @XVFB_LIBS@ +XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ +XWINMODULES_CFLAGS = @XWINMODULES_CFLAGS@ +XWINMODULES_LIBS = @XWINMODULES_LIBS@ +XWIN_LIBS = @XWIN_LIBS@ +XWIN_SERVER_NAME = @XWIN_SERVER_NAME@ +XWIN_SYS_LIBS = @XWIN_SYS_LIBS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +__XCONFIGFILE__ = @__XCONFIGFILE__@ +abi_ansic = @abi_ansic@ +abi_extension = @abi_extension@ +abi_font = @abi_font@ +abi_videodrv = @abi_videodrv@ +abi_xinput = @abi_xinput@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +driverdir = @driverdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +extdir = @extdir@ +ft_config = @ft_config@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +launchagentsdir = @launchagentsdir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +logdir = @logdir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moduledir = @moduledir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sdkdir = @sdkdir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +xglmoduledir = @xglmoduledir@ +xpconfigdir = @xpconfigdir@ +INCLUDES = \ + @KDRIVE_INCS@ \ + @KDRIVE_CFLAGS@ + +AM_CFLAGS = -DHAVE_DIX_CONFIG_H +noinst_LIBRARIES = libkdrive.a libkdrivestubs.a +@KDRIVE_HW_TRUE@KDRIVE_HW_SOURCES = \ +@KDRIVE_HW_TRUE@ vga.c \ +@KDRIVE_HW_TRUE@ vga.h + +libkdrive_a_SOURCES = \ + fourcc.h \ + kaa.c \ + kaa.h \ + kaapict.c \ + kasync.c \ + kcmap.c \ + kcurscol.c \ + kdrive.c \ + kdrive.h \ + kinfo.c \ + kinput.c \ + kkeymap.c \ + kmap.c \ + kmode.c \ + knoop.c \ + koffscreen.c \ + kshadow.c \ + ktest.c \ + kxv.c \ + kxv.h \ + $(KDRIVE_HW_SOURCES) \ + $(top_srcdir)/mi/miinitext.c + +libkdrivestubs_a_SOURCES = \ + $(top_srcdir)/fb/fbcmap_mi.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign hw/kdrive/src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign hw/kdrive/src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libkdrive.a: $(libkdrive_a_OBJECTS) $(libkdrive_a_DEPENDENCIES) + -rm -f libkdrive.a + $(libkdrive_a_AR) libkdrive.a $(libkdrive_a_OBJECTS) $(libkdrive_a_LIBADD) + $(RANLIB) libkdrive.a +libkdrivestubs.a: $(libkdrivestubs_a_OBJECTS) $(libkdrivestubs_a_DEPENDENCIES) + -rm -f libkdrivestubs.a + $(libkdrivestubs_a_AR) libkdrivestubs.a $(libkdrivestubs_a_OBJECTS) $(libkdrivestubs_a_LIBADD) + $(RANLIB) libkdrivestubs.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fbcmap_mi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kaa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kaapict.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kasync.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kcmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kcurscol.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdrive.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kinput.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kkeymap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kmode.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/knoop.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/koffscreen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kshadow.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ktest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kxv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miinitext.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vga.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +miinitext.o: $(top_srcdir)/mi/miinitext.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT miinitext.o -MD -MP -MF $(DEPDIR)/miinitext.Tpo -c -o miinitext.o `test -f '$(top_srcdir)/mi/miinitext.c' || echo '$(srcdir)/'`$(top_srcdir)/mi/miinitext.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/miinitext.Tpo $(DEPDIR)/miinitext.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/mi/miinitext.c' object='miinitext.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o miinitext.o `test -f '$(top_srcdir)/mi/miinitext.c' || echo '$(srcdir)/'`$(top_srcdir)/mi/miinitext.c + +miinitext.obj: $(top_srcdir)/mi/miinitext.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT miinitext.obj -MD -MP -MF $(DEPDIR)/miinitext.Tpo -c -o miinitext.obj `if test -f '$(top_srcdir)/mi/miinitext.c'; then $(CYGPATH_W) '$(top_srcdir)/mi/miinitext.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/mi/miinitext.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/miinitext.Tpo $(DEPDIR)/miinitext.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/mi/miinitext.c' object='miinitext.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o miinitext.obj `if test -f '$(top_srcdir)/mi/miinitext.c'; then $(CYGPATH_W) '$(top_srcdir)/mi/miinitext.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/mi/miinitext.c'; fi` + +fbcmap_mi.o: $(top_srcdir)/fb/fbcmap_mi.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fbcmap_mi.o -MD -MP -MF $(DEPDIR)/fbcmap_mi.Tpo -c -o fbcmap_mi.o `test -f '$(top_srcdir)/fb/fbcmap_mi.c' || echo '$(srcdir)/'`$(top_srcdir)/fb/fbcmap_mi.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fbcmap_mi.Tpo $(DEPDIR)/fbcmap_mi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/fb/fbcmap_mi.c' object='fbcmap_mi.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fbcmap_mi.o `test -f '$(top_srcdir)/fb/fbcmap_mi.c' || echo '$(srcdir)/'`$(top_srcdir)/fb/fbcmap_mi.c + +fbcmap_mi.obj: $(top_srcdir)/fb/fbcmap_mi.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fbcmap_mi.obj -MD -MP -MF $(DEPDIR)/fbcmap_mi.Tpo -c -o fbcmap_mi.obj `if test -f '$(top_srcdir)/fb/fbcmap_mi.c'; then $(CYGPATH_W) '$(top_srcdir)/fb/fbcmap_mi.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/fb/fbcmap_mi.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fbcmap_mi.Tpo $(DEPDIR)/fbcmap_mi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/fb/fbcmap_mi.c' object='fbcmap_mi.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fbcmap_mi.obj `if test -f '$(top_srcdir)/fb/fbcmap_mi.c'; then $(CYGPATH_W) '$(top_srcdir)/fb/fbcmap_mi.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/fb/fbcmap_mi.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +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: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/xorg-server/hw/kdrive/src/fourcc.h b/xorg-server/hw/kdrive/src/fourcc.h new file mode 100644 index 000000000..54be7ebe8 --- /dev/null +++ b/xorg-server/hw/kdrive/src/fourcc.h @@ -0,0 +1,133 @@ + +/* + This header file contains listings of STANDARD guids for video formats. + Please do not place non-registered, or incomplete entries in this file. + A list of some popular fourcc's are at: http://www.webartz.com/fourcc/ + For an explanation of fourcc <-> guid mappings see RFC2361. +*/ + +#ifndef _XF86_FOURCC_H_ +#define _XF86_FOURCC_H_ 1 + +#define FOURCC_YUY2 0x32595559 +#define XVIMAGE_YUY2 \ + { \ + FOURCC_YUY2, \ + XvYUV, \ + LSBFirst, \ + {'Y','U','Y','2', \ + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ + 16, \ + XvPacked, \ + 1, \ + 0, 0, 0, 0, \ + 8, 8, 8, \ + 1, 2, 2, \ + 1, 1, 1, \ + {'Y','U','Y','V', \ + 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}, \ + XvTopToBottom \ + } + +#define FOURCC_YV12 0x32315659 +#define XVIMAGE_YV12 \ + { \ + FOURCC_YV12, \ + XvYUV, \ + LSBFirst, \ + {'Y','V','1','2', \ + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ + 12, \ + XvPlanar, \ + 3, \ + 0, 0, 0, 0, \ + 8, 8, 8, \ + 1, 2, 2, \ + 1, 2, 2, \ + {'Y','V','U', \ + 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,0}, \ + XvTopToBottom \ + } + +#define FOURCC_I420 0x30323449 +#define XVIMAGE_I420 \ + { \ + FOURCC_I420, \ + XvYUV, \ + LSBFirst, \ + {'I','4','2','0', \ + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ + 12, \ + XvPlanar, \ + 3, \ + 0, 0, 0, 0, \ + 8, 8, 8, \ + 1, 2, 2, \ + 1, 2, 2, \ + {'Y','U','V', \ + 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,0}, \ + XvTopToBottom \ + } + + +#define FOURCC_UYVY 0x59565955 +#define XVIMAGE_UYVY \ + { \ + FOURCC_UYVY, \ + XvYUV, \ + LSBFirst, \ + {'U','Y','V','Y', \ + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ + 16, \ + XvPacked, \ + 1, \ + 0, 0, 0, 0, \ + 8, 8, 8, \ + 1, 2, 2, \ + 1, 1, 1, \ + {'U','Y','V','Y', \ + 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}, \ + XvTopToBottom \ + } + +#define FOURCC_IA44 0x34344149 +#define XVIMAGE_IA44 \ + { \ + FOURCC_IA44, \ + XvYUV, \ + LSBFirst, \ + {'I','A','4','4', \ + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ + 8, \ + XvPacked, \ + 1, \ + 0, 0, 0, 0, \ + 8, 8, 8, \ + 1, 1, 1, \ + 1, 1, 1, \ + {'A','I', \ + 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,0,0}, \ + XvTopToBottom \ + } + +#define FOURCC_AI44 0x34344941 +#define XVIMAGE_AI44 \ + { \ + FOURCC_AI44, \ + XvYUV, \ + LSBFirst, \ + {'A','I','4','4', \ + 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ + 8, \ + XvPacked, \ + 1, \ + 0, 0, 0, 0, \ + 8, 8, 8, \ + 1, 1, 1, \ + 1, 1, 1, \ + {'I','A', \ + 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,0,0}, \ + XvTopToBottom \ + } + +#endif /* _XF86_FOURCC_H_ */ diff --git a/xorg-server/hw/kdrive/src/kaa.c b/xorg-server/hw/kdrive/src/kaa.c new file mode 100644 index 000000000..db09e9dba --- /dev/null +++ b/xorg-server/hw/kdrive/src/kaa.c @@ -0,0 +1,1081 @@ +/* + * 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_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "kaa.h" +#include "dixfontstr.h" + +#define DEBUG_MIGRATE 0 +#define DEBUG_PIXMAP 0 +#if DEBUG_MIGRATE +#define DBG_MIGRATE(a) ErrorF a +#else +#define DBG_MIGRATE(a) +#endif +#if DEBUG_PIXMAP +#define DBG_PIXMAP(a) ErrorF a +#else +#define DBG_PIXMAP(a) +#endif + +DevPrivateKey kaaScreenPrivateKey = &kaaScreenPrivateKey; +DevPrivateKey kaaPixmapPrivateKey = &kaaPixmapPrivateKey; + +#define KAA_PIXMAP_SCORE_MOVE_IN 10 +#define KAA_PIXMAP_SCORE_MAX 20 +#define KAA_PIXMAP_SCORE_MOVE_OUT -10 +#define KAA_PIXMAP_SCORE_MIN -20 +#define KAA_PIXMAP_SCORE_PINNED 1000 +#define KAA_PIXMAP_SCORE_INIT 1001 + +void +kaaDrawableDirty (DrawablePtr pDrawable) +{ + PixmapPtr pPixmap; + KaaPixmapPrivPtr pKaaPixmap; + + if (pDrawable->type == DRAWABLE_WINDOW) + pPixmap = (*pDrawable->pScreen->GetWindowPixmap)((WindowPtr) pDrawable); + else + pPixmap = (PixmapPtr)pDrawable; + + pKaaPixmap = KaaGetPixmapPriv(pPixmap); + if (pKaaPixmap != NULL) + pKaaPixmap->dirty = TRUE; +} + +static void +kaaPixmapSave (ScreenPtr pScreen, KdOffscreenArea *area) +{ + PixmapPtr pPixmap = area->privData; + KaaPixmapPriv(pPixmap); + int dst_pitch, src_pitch, bytes; + unsigned char *dst, *src; + int i; + + DBG_MIGRATE (("Save 0x%08x (0x%x) (%dx%d)\n", + pPixmap->drawable.id, + KaaGetPixmapPriv(pPixmap)->area ? + KaaGetPixmapPriv(pPixmap)->area->offset : -1, + pPixmap->drawable.width, + pPixmap->drawable.height)); + + src_pitch = pPixmap->devKind; + dst_pitch = pKaaPixmap->devKind; + + src = pPixmap->devPrivate.ptr; + dst = pKaaPixmap->devPrivate.ptr; + + pPixmap->devKind = dst_pitch; + pPixmap->devPrivate.ptr = dst; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pKaaPixmap->area = NULL; + +#if 0 + if (!pKaaPixmap->dirty) + return; +#endif + + kaaWaitSync (pPixmap->drawable.pScreen); + + bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch; + + i = pPixmap->drawable.height; + while (i--) { + memcpy (dst, src, bytes); + dst += dst_pitch; + src += src_pitch; + } +} + +static int +kaaLog2(int val) +{ + int bits; + + if (!val) + return 0; + for (bits = 0; val != 0; bits++) + val >>= 1; + return bits - 1; +} + +static Bool +kaaPixmapAllocArea (PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + KaaScreenPriv (pScreen); + KaaPixmapPriv (pPixmap); + KdScreenPriv (pScreen); + int bpp = pPixmap->drawable.bitsPerPixel; + CARD16 h = pPixmap->drawable.height; + CARD16 w = pPixmap->drawable.width; + int pitch; + + if (pKaaScr->info->flags & KAA_OFFSCREEN_ALIGN_POT && w != 1) + w = 1 << (kaaLog2(w - 1) + 1); + pitch = (w * bpp / 8 + pKaaScr->info->pitchAlign - 1) & + ~(pKaaScr->info->pitchAlign - 1); + + pKaaPixmap->devKind = pPixmap->devKind; + pKaaPixmap->devPrivate = pPixmap->devPrivate; + pKaaPixmap->area = KdOffscreenAlloc (pScreen, pitch * h, + pKaaScr->info->offsetAlign, + FALSE, + kaaPixmapSave, (pointer) pPixmap); + if (!pKaaPixmap->area) + return FALSE; + + DBG_PIXMAP(("++ 0x%08x (0x%x) (%dx%d)\n", + pPixmap->drawable.id, + KaaGetPixmapPriv(pPixmap)->area ? + KaaGetPixmapPriv(pPixmap)->area->offset : -1, + pPixmap->drawable.width, + pPixmap->drawable.height)); + pPixmap->devKind = pitch; + pPixmap->devPrivate.ptr = (pointer) ((CARD8 *) pScreenPriv->screen->memory_base + pKaaPixmap->area->offset); + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + return TRUE; +} + +void +kaaMoveInPixmap (PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + KaaScreenPriv (pScreen); + KaaPixmapPriv (pPixmap); + int dst_pitch, src_pitch, bytes; + unsigned char *dst, *src; + int i; + + DBG_MIGRATE (("-> 0x%08x (0x%x) (%dx%d)\n", + pPixmap->drawable.id, + KaaGetPixmapPriv(pPixmap)->area ? + KaaGetPixmapPriv(pPixmap)->area->offset : -1, + pPixmap->drawable.width, + pPixmap->drawable.height)); + + src = pPixmap->devPrivate.ptr; + src_pitch = pPixmap->devKind; + + if (!kaaPixmapAllocArea (pPixmap)) + return; + + pKaaPixmap->dirty = FALSE; + + if (pKaaScr->info->UploadToScreen) + { + if (pKaaScr->info->UploadToScreen(pPixmap, (char *) src, src_pitch)) + return; + } + + dst = pPixmap->devPrivate.ptr; + dst_pitch = pPixmap->devKind; + + bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch; + + kaaWaitSync (pPixmap->drawable.pScreen); + + i = pPixmap->drawable.height; + while (i--) { + memcpy (dst, src, bytes); + dst += dst_pitch; + src += src_pitch; + } +} + +static void +kaaMoveOutPixmap (PixmapPtr pPixmap) +{ + KaaPixmapPriv (pPixmap); + KdOffscreenArea *area = pKaaPixmap->area; + + DBG_MIGRATE (("<- 0x%08x (0x%x) (%dx%d)\n", + pPixmap->drawable.id, + KaaGetPixmapPriv(pPixmap)->area ? + KaaGetPixmapPriv(pPixmap)->area->offset : -1, + pPixmap->drawable.width, + pPixmap->drawable.height)); + if (area) + { + kaaPixmapSave (pPixmap->drawable.pScreen, area); + KdOffscreenFree (pPixmap->drawable.pScreen, area); + } +} + +void +kaaPixmapUseScreen (PixmapPtr pPixmap) +{ + KaaPixmapPriv (pPixmap); + + if (pKaaPixmap->score == KAA_PIXMAP_SCORE_PINNED) + return; + + if (pKaaPixmap->score == KAA_PIXMAP_SCORE_INIT) { + kaaMoveInPixmap(pPixmap); + pKaaPixmap->score = 0; + } + + if (pKaaPixmap->score < KAA_PIXMAP_SCORE_MAX) + { + pKaaPixmap->score++; + if (!kaaPixmapIsOffscreen(pPixmap) && + pKaaPixmap->score >= KAA_PIXMAP_SCORE_MOVE_IN) + kaaMoveInPixmap (pPixmap); + } + KdOffscreenMarkUsed (pPixmap); +} + +void +kaaPixmapUseMemory (PixmapPtr pPixmap) +{ + KaaPixmapPriv (pPixmap); + + if (pKaaPixmap->score == KAA_PIXMAP_SCORE_PINNED) + return; + + if (pKaaPixmap->score == KAA_PIXMAP_SCORE_INIT) + pKaaPixmap->score = 0; + + if (pKaaPixmap->score > KAA_PIXMAP_SCORE_MIN) + { + pKaaPixmap->score--; + if (pKaaPixmap->area && + pKaaPixmap->score <= KAA_PIXMAP_SCORE_MOVE_OUT) + kaaMoveOutPixmap (pPixmap); + } +} + +static Bool +kaaDestroyPixmap (PixmapPtr pPixmap) +{ + if (pPixmap->refcnt == 1) + { + KaaPixmapPriv (pPixmap); + if (pKaaPixmap->area) + { + DBG_PIXMAP(("-- 0x%08x (0x%x) (%dx%d)\n", + pPixmap->drawable.id, + KaaGetPixmapPriv(pPixmap)->area->offset, + pPixmap->drawable.width, + pPixmap->drawable.height)); + /* Free the offscreen area */ + KdOffscreenFree (pPixmap->drawable.pScreen, pKaaPixmap->area); + pPixmap->devPrivate = pKaaPixmap->devPrivate; + pPixmap->devKind = pKaaPixmap->devKind; + } + } + return fbDestroyPixmap (pPixmap); +} + +static PixmapPtr +kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint) +{ + PixmapPtr pPixmap; + KaaPixmapPrivPtr pKaaPixmap; + int bpp; + + bpp = BitsPerPixel (depth); + if (bpp == 32 && depth == 24) + { + int fb; + KdScreenPriv (pScreen); + + for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++) + if (pScreenPriv->screen->fb[fb].depth == 24) + { + bpp = pScreenPriv->screen->fb[fb].bitsPerPixel; + break; + } + } + + pPixmap = fbCreatePixmapBpp (pScreen, w, h, depth, bpp, usage_hint); + if (!pPixmap) + return NULL; + pKaaPixmap = KaaGetPixmapPriv(pPixmap); + if (!w || !h) + pKaaPixmap->score = KAA_PIXMAP_SCORE_PINNED; + else + pKaaPixmap->score = KAA_PIXMAP_SCORE_INIT; + + pKaaPixmap->area = NULL; + pKaaPixmap->dirty = FALSE; + + return pPixmap; +} + +Bool +kaaPixmapIsOffscreen(PixmapPtr p) +{ + ScreenPtr pScreen = p->drawable.pScreen; + KdScreenPriv(pScreen); + + return ((unsigned long) ((CARD8 *) p->devPrivate.ptr - + (CARD8 *) pScreenPriv->screen->memory_base) < + pScreenPriv->screen->memory_size); +} + +PixmapPtr +kaaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp) +{ + PixmapPtr pPixmap; + int x, y; + + if (pDrawable->type == DRAWABLE_WINDOW) { + pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable); +#ifdef COMPOSITE + x = -pPixmap->screen_x; + y = -pPixmap->screen_y; +#else + x = 0; + y = 0; +#endif + } + else + { + pPixmap = (PixmapPtr) pDrawable; + x = 0; + y = 0; + } + *xp = x; + *yp = y; + if (kaaPixmapIsOffscreen (pPixmap)) + return pPixmap; + else + return NULL; +} + +Bool +kaaDrawableIsOffscreen (DrawablePtr pDrawable) +{ + PixmapPtr pPixmap; + if (pDrawable->type == DRAWABLE_WINDOW) + pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable); + else + pPixmap = (PixmapPtr) pDrawable; + return kaaPixmapIsOffscreen (pPixmap); +} + +#if 0 +static void +kaaFillTiled(int dst_x, + int dst_y, + int width, + int height, + int src_x, + int src_y, + int src_width, + int src_height, + void (*Copy) (int srcX, + int srcY, + int dstX, + int dstY, + int width, + int height)) +{ + modulus (src_x, src_width, src_x); + modulus (src_y, src_height, src_y); + + while (height) + { + int dst_x_tmp = dst_x; + int src_x_tmp = src_x; + int width_tmp = width; + int height_left = src_height - src_y; + int height_this = min (height, height_left); + + while (width_tmp) + { + int width_left = src_width - src_x_tmp; + int width_this = min (width_tmp, width_left); + + (*Copy) (src_x_tmp, src_y, + dst_x_tmp, dst_y, + width_this, height_this); + + width_tmp -= width_this; + dst_x_tmp += width_this; + } + height -= height_this; + dst_y += height_this; + src_y = 0; + } +} +#endif + +static void +kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, + DDXPointPtr ppt, int *pwidth, int fSorted) +{ + ScreenPtr pScreen = pDrawable->pScreen; + KdScreenPriv (pScreen); + KaaScreenPriv (pScreen); + RegionPtr pClip = fbGetCompositeClip(pGC); + PixmapPtr pPixmap; + BoxPtr pextent, pbox; + int nbox; + int extentX1, extentX2, extentY1, extentY2; + int fullX1, fullX2, fullY1; + int partX1, partX2; + int off_x, off_y; + + if (!pScreenPriv->enabled || + pGC->fillStyle != FillSolid || + !(pPixmap = kaaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || + !(*pKaaScr->info->PrepareSolid) (pPixmap, + pGC->alu, + pGC->planemask, + pGC->fgPixel)) + { + KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); + return; + } + + pextent = REGION_EXTENTS(pGC->pScreen, 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 = REGION_NUM_RECTS (pClip); + if (nbox == 1) + { + (*pKaaScr->info->Solid) (fullX1 + off_x, fullY1 + off_y, + fullX2 + off_x, fullY1 + 1 + off_y); + } + else + { + pbox = REGION_RECTS(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) + (*pKaaScr->info->Solid) (partX1 + off_x, fullY1 + off_y, + partX2 + off_x, fullY1 + 1 + off_y); + } + pbox++; + } + } + } + (*pKaaScr->info->DoneSolid) (); + kaaDrawableDirty (pDrawable); + kaaMarkSync (pDrawable->pScreen); +} + +void +kaaCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + KdScreenPriv (pDstDrawable->pScreen); + KaaScreenPriv (pDstDrawable->pScreen); + PixmapPtr pSrcPixmap, pDstPixmap; + int src_off_x, src_off_y; + int dst_off_x, dst_off_y; + + /* Migrate pixmaps to same place as destination */ + if (pScreenPriv->enabled && pSrcDrawable->type == DRAWABLE_PIXMAP) { + if (kaaDrawableIsOffscreen (pDstDrawable)) + kaaPixmapUseScreen ((PixmapPtr) pSrcDrawable); + else + kaaPixmapUseMemory ((PixmapPtr) pSrcDrawable); + } + + if (pScreenPriv->enabled && + (pSrcPixmap = kaaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y)) && + (pDstPixmap = kaaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y)) && + (*pKaaScr->info->PrepareCopy) (pSrcPixmap, + pDstPixmap, + dx, + dy, + pGC ? pGC->alu : GXcopy, + pGC ? pGC->planemask : FB_ALLONES)) + { + while (nbox--) + { + (*pKaaScr->info->Copy) (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++; + } + (*pKaaScr->info->DoneCopy) (); + kaaMarkSync (pDstDrawable->pScreen); + } + else + { + kaaWaitSync (pDstDrawable->pScreen); + fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, + pbox, nbox, dx, dy, reverse, upsidedown, + bitplane, closure); + } + kaaDrawableDirty (pDstDrawable); +} + +static RegionPtr +kaaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, + int srcx, int srcy, int width, int height, int dstx, int dsty) +{ + return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, + srcx, srcy, width, height, + dstx, dsty, kaaCopyNtoN, 0, 0); +} + +static void +kaaPolyFillRect(DrawablePtr pDrawable, + GCPtr pGC, + int nrect, + xRectangle *prect) +{ + KdScreenPriv (pDrawable->pScreen); + KaaScreenPriv (pDrawable->pScreen); + RegionPtr pClip = fbGetCompositeClip(pGC); + PixmapPtr 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; + + if (!pScreenPriv->enabled || + pGC->fillStyle != FillSolid || + !(pPixmap = kaaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || + !(*pKaaScr->info->PrepareSolid) (pPixmap, + pGC->alu, + pGC->planemask, + pGC->fgPixel)) + { + KdCheckPolyFillRect (pDrawable, pGC, nrect, prect); + return; + } + + xorg = pDrawable->x; + yorg = pDrawable->y; + + pextent = REGION_EXTENTS(pGC->pScreen, 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 = REGION_NUM_RECTS (pClip); + if (n == 1) + { + (*pKaaScr->info->Solid) (fullX1 + xoff, fullY1 + yoff, + fullX2 + xoff, fullY2 + yoff); + } + else + { + pbox = REGION_RECTS(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) + (*pKaaScr->info->Solid) (partX1 + xoff, partY1 + yoff, + partX2 + xoff, partY2 + yoff); + } + } + } + (*pKaaScr->info->DoneSolid) (); + kaaDrawableDirty (pDrawable); + kaaMarkSync (pDrawable->pScreen); +} + +static void +kaaSolidBoxClipped (DrawablePtr pDrawable, + RegionPtr pClip, + FbBits pm, + FbBits fg, + int x1, + int y1, + int x2, + int y2) +{ + KdScreenPriv (pDrawable->pScreen); + KaaScreenPriv (pDrawable->pScreen); + PixmapPtr pPixmap; + BoxPtr pbox; + int nbox; + int xoff, yoff; + int partX1, partX2, partY1, partY2; + + if (!pScreenPriv->enabled || + !(pPixmap = kaaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || + !(*pKaaScr->info->PrepareSolid) (pPixmap, GXcopy, pm, fg)) + { + kaaWaitSync (pDrawable->pScreen); + fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel); + fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2, + fbAnd (GXcopy, fg, pm), + fbXor (GXcopy, fg, pm)); + kaaDrawableDirty (pDrawable); + return; + } + for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(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; + + (*pKaaScr->info->Solid) (partX1 + xoff, partY1 + yoff, + partX2 + xoff, partY2 + yoff); + } + (*pKaaScr->info->DoneSolid) (); + kaaDrawableDirty (pDrawable); + kaaMarkSync (pDrawable->pScreen); +} + +static void +kaaImageGlyphBlt (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppciInit, + pointer 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; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbBits depthMask; + + depthMask = FbFullMask(pDrawable->depth); + if ((pGC->planemask & depthMask) != depthMask) + { + KdCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase); + return; + } + glyph = 0; + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + switch (dstBpp) { + case 8: glyph = fbGlyph8; break; + case 16: glyph = fbGlyph16; break; + case 24: glyph = fbGlyph24; 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); + kaaSolidBoxClipped (pDrawable, + fbGetCompositeClip(pGC), + pGC->planemask, + pGC->bgPixel, + xBack, + yBack, + xBack + widthBack, + yBack + heightBack); + opaque = FALSE; + } + + kaaWaitSync (pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + + 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)) + { + (*glyph) (dst + (gy + dstYoff) * dstStride, + dstStride, + dstBpp, + (FbStip *) pglyph, + pPriv->fg, + gx + dstXoff, + gHeight); + } + 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; + } +} + +static const GCOps kaaOps = { + kaaFillSpans, + KdCheckSetSpans, + KdCheckPutImage, + kaaCopyArea, + KdCheckCopyPlane, + KdCheckPolyPoint, + KdCheckPolylines, + KdCheckPolySegment, + miPolyRectangle, + KdCheckPolyArc, + miFillPolygon, + kaaPolyFillRect, + miPolyFillArc, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + kaaImageGlyphBlt, + KdCheckPolyGlyphBlt, + KdCheckPushPixels, +}; + +static void +kaaValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) +{ + fbValidateGC (pGC, changes, pDrawable); + + if (kaaDrawableIsOffscreen (pDrawable)) + pGC->ops = (GCOps *) &kaaOps; + else + pGC->ops = (GCOps *) &kdAsyncPixmapGCOps; +} + +GCFuncs kaaGCFuncs = { + kaaValidateGC, + miChangeGC, + miCopyGC, + miDestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip +}; + +static int +kaaCreateGC (GCPtr pGC) +{ + if (!fbCreateGC (pGC)) + return FALSE; + + pGC->funcs = &kaaGCFuncs; + + return TRUE; +} + + +static void +kaaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + RegionRec rgnDst; + int dx, dy; + PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); + + REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0); + + REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc); +#ifdef COMPOSITE + if (pPixmap->screen_x || pPixmap->screen_y) + REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst, + -pPixmap->screen_x, -pPixmap->screen_y); +#endif + + fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable, + 0, + &rgnDst, dx, dy, kaaCopyNtoN, 0, 0); + + REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); +} + +static void +kaaFillRegionSolid (DrawablePtr pDrawable, + RegionPtr pRegion, + Pixel pixel) +{ + KdScreenPriv(pDrawable->pScreen); + KaaScreenPriv(pDrawable->pScreen); + PixmapPtr pPixmap; + int xoff, yoff; + + if (pScreenPriv->enabled && + (pPixmap = kaaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && + (*pKaaScr->info->PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel)) + { + int nbox = REGION_NUM_RECTS (pRegion); + BoxPtr pBox = REGION_RECTS (pRegion); + + while (nbox--) + { + (*pKaaScr->info->Solid) (pBox->x1 + xoff, pBox->y1 + yoff, + pBox->x2 + xoff, pBox->y2 + yoff); + pBox++; + } + (*pKaaScr->info->DoneSolid) (); + kaaMarkSync (pDrawable->pScreen); + } + else + { + kaaWaitSync (pDrawable->pScreen); + fbFillRegionSolid (pDrawable, pRegion, 0, + fbReplicatePixel (pixel, pDrawable->bitsPerPixel)); + } + kaaDrawableDirty (pDrawable); +} + +Bool +kaaDrawInit (ScreenPtr pScreen, + KaaScreenInfoPtr pScreenInfo) +{ + KaaScreenPrivPtr pKaaScr; + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; +#ifdef RENDER + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); +#endif + + pKaaScr = xalloc (sizeof (KaaScreenPrivRec)); + + if (!pKaaScr) + return FALSE; + + pKaaScr->info = pScreenInfo; + + dixSetPrivate(&pScreen->devPrivates, kaaScreenPrivateKey, pKaaScr); + + /* + * Hook up asynchronous drawing + */ + KdScreenInitAsync (pScreen); + /* + * Replace various fb screen functions + */ + pScreen->CreateGC = kaaCreateGC; + pScreen->CopyWindow = kaaCopyWindow; +#ifdef RENDER + if (ps) { + ps->Composite = kaaComposite; + ps->RasterizeTrapezoid = kaaRasterizeTrapezoid; + } +#endif + + /* + * Hookup offscreen pixmaps + */ + if ((pKaaScr->info->flags & KAA_OFFSCREEN_PIXMAPS) && + screen->off_screen_base < screen->memory_size) + { + if (!dixRequestPrivate(kaaPixmapPrivateKey, sizeof (KaaPixmapPrivRec))) + return FALSE; + pScreen->CreatePixmap = kaaCreatePixmap; + pScreen->DestroyPixmap = kaaDestroyPixmap; + } + + return TRUE; +} + +void +kaaDrawFini (ScreenPtr pScreen) +{ + KaaScreenPriv(pScreen); + + xfree (pKaaScr); +} + +void +kaaMarkSync (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KaaScreenPriv(pScreen); + + pScreenPriv->card->needSync = TRUE; + if (pKaaScr->info->markSync != NULL) { + pScreenPriv->card->lastMarker = (*pKaaScr->info->markSync) (pScreen); + } +} + +void +kaaWaitSync (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KaaScreenPriv(pScreen); + KdCardInfo *card = pScreenPriv->card; + + if (card->needSync) { + (*pKaaScr->info->waitMarker) (pScreen, card->lastMarker); + card->needSync = FALSE; + } +} diff --git a/xorg-server/hw/kdrive/src/kaa.h b/xorg-server/hw/kdrive/src/kaa.h new file mode 100644 index 000000000..90b963b10 --- /dev/null +++ b/xorg-server/hw/kdrive/src/kaa.h @@ -0,0 +1,120 @@ +/* + * 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. + */ + +#ifndef _KAA_H_ +#define _KAA_H_ + +#include "picturestr.h" + +#define KaaGetScreenPriv(s) ((KaaScreenPrivPtr) \ + dixLookupPrivate(&(s)->devPrivates, kaaScreenPrivateKey)) +#define KaaScreenPriv(s) KaaScreenPrivPtr pKaaScr = KaaGetScreenPriv(s) + +#define KaaGetPixmapPriv(p) ((KaaPixmapPrivPtr) \ + dixLookupPrivate(&(p)->devPrivates, kaaPixmapPrivateKey)) +#define KaaSetPixmapPriv(p,a) \ + dixSetPrivate(&(p)->devPrivates, kaaPixmapPrivateKey, a) +#define KaaPixmapPriv(p) KaaPixmapPrivPtr pKaaPixmap = KaaGetPixmapPriv(p) + +typedef struct { + KaaScreenInfoPtr info; +} KaaScreenPrivRec, *KaaScreenPrivPtr; + +typedef struct { + KdOffscreenArea *area; + int score; + int devKind; + DevUnion devPrivate; + Bool dirty; +} KaaPixmapPrivRec, *KaaPixmapPrivPtr; + +extern DevPrivateKey kaaScreenPrivateKey; +extern DevPrivateKey kaaPixmapPrivateKey; + + +void +kaaPixmapUseScreen (PixmapPtr pPixmap); + +void +kaaPixmapUseMemory (PixmapPtr pPixmap); + +void +kaaDrawableDirty(DrawablePtr pDrawable); + +Bool +kaaDrawableIsOffscreen (DrawablePtr pDrawable); + +Bool +kaaPixmapIsOffscreen(PixmapPtr p); + +PixmapPtr +kaaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp); + +void +kaaMoveInPixmap (PixmapPtr pPixmap); + +void +kaaMarkSync (ScreenPtr pScreen); + +void +kaaWaitSync (ScreenPtr pScreen); + +void +kaaCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +void +kaaComposite(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 +kaaRasterizeTrapezoid(PicturePtr pPict, + xTrapezoid *trap, + int xoff, + int yoff); + +void +kaaInitTrapOffsets(int grid_order, float *x_offsets, float *y_offsets, + float x_offset, float y_offset); + +#endif /* _KAA_H_ */ diff --git a/xorg-server/hw/kdrive/src/kaapict.c b/xorg-server/hw/kdrive/src/kaapict.c new file mode 100644 index 000000000..501b6b9c4 --- /dev/null +++ b/xorg-server/hw/kdrive/src/kaapict.c @@ -0,0 +1,719 @@ +/* + * 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_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "kaa.h" + +#ifdef RENDER +#include "mipict.h" + +#define KAA_DEBUG_FALLBACKS 0 + +#if KAA_DEBUG_FALLBACKS +static void kaaCompositeFallbackPictDesc(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_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; + } + + loc = kaaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm'; + + snprintf(size, 20, "%dx%d%s", pict->pDrawable->width, + pict->pDrawable->height, pict->repeat ? + " R" : ""); + + snprintf(string, n, "0x%lx:%c fmt %s (%s)", (long)pict, loc, format, size); +} + +static void +kaaPrintCompositeFallback(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst) +{ + char sop[20]; + char srcdesc[40], maskdesc[40], dstdesc[40]; + + switch(op) + { + case PictOpSrc: + sprintf(sop, "Src"); + break; + case PictOpOver: + sprintf(sop, "Over"); + break; + default: + sprintf(sop, "0x%x", (int)op); + break; + } + + kaaCompositeFallbackPictDesc(pSrc, srcdesc, 40); + kaaCompositeFallbackPictDesc(pMask, maskdesc, 40); + kaaCompositeFallbackPictDesc(pDst, dstdesc, 40); + + ErrorF("Composite fallback: op %s, \n" + " src %s, \n" + " mask %s, \n" + " dst %s, \n", + sop, srcdesc, maskdesc, dstdesc); +} + +static void +kaaPrintTrapezoidFallback(PicturePtr pDst) +{ + char dstdesc[40]; + + kaaCompositeFallbackPictDesc(pDst, dstdesc, 40); + + ErrorF("Trapezoid fallback: dst %s, %c/%s\n", + dstdesc, + (pDst->polyMode == PolyModePrecise) ? 'p' : 'i', + (pDst->polyEdge == PolyEdgeSharp) ? "a" : "aa"); +} +#endif + +static Bool +kaaGetPixelFromRGBA(CARD32 *pixel, + CARD16 red, + CARD16 green, + CARD16 blue, + CARD16 alpha, + CARD32 format) +{ + int rbits, bbits, gbits, abits; + int rshift, bshift, gshift, ashift; + + *pixel = 0; + + if (!PICT_FORMAT_COLOR(format)) + return FALSE; + + 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_ARGB) { + bshift = 0; + gshift = bbits; + rshift = gshift + gbits; + ashift = rshift + rbits; + } else { /* PICT_TYPE_ABGR */ + rshift = 0; + gshift = rbits; + bshift = gshift + gbits; + ashift = bshift + bbits; + } + + *pixel |= ( blue >> (16 - bbits)) << bshift; + *pixel |= ( red >> (16 - rbits)) << rshift; + *pixel |= (green >> (16 - gbits)) << gshift; + *pixel |= (alpha >> (16 - abits)) << ashift; + + return TRUE; +} + + +static Bool +kaaGetRGBAFromPixel(CARD32 pixel, + CARD16 *red, + CARD16 *green, + CARD16 *blue, + CARD16 *alpha, + CARD32 format) +{ + int rbits, bbits, gbits, abits; + int rshift, bshift, gshift, ashift; + + if (!PICT_FORMAT_COLOR(format)) + return FALSE; + + 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_ARGB) { + bshift = 0; + gshift = bbits; + rshift = gshift + gbits; + ashift = rshift + rbits; + } else { /* PICT_TYPE_ABGR */ + rshift = 0; + gshift = rbits; + bshift = gshift + gbits; + ashift = bshift + bbits; + } + + *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; + } + + 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 +kaaTryDriverSolidFill(PicturePtr pSrc, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + KaaScreenPriv (pDst->pDrawable->pScreen); + RegionRec region; + BoxPtr pbox; + int nbox; + int dst_off_x, dst_off_y; + PixmapPtr pSrcPix, pDstPix; + CARD32 pixel; + CARD16 red, green, blue, alpha; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + + if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst, + xSrc, ySrc, 0, 0, xDst, yDst, + width, height)) + return 1; + + if (pSrc->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable); + if (pDst->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable); + + pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y); + if (!pDstPix) { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return 0; + } + + if (pSrc->pDrawable->type == DRAWABLE_WINDOW) + pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap)( + (WindowPtr) (pSrc->pDrawable)); + else + pSrcPix = (PixmapPtr) (pSrc->pDrawable); + + /* If source is offscreen, we need to sync the accelerator + * before accessing it. We'd prefer for it to be in memory. + */ + if (kaaPixmapIsOffscreen(pSrcPix)) { + kaaWaitSync(pDst->pDrawable->pScreen); + } + + pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr); + if (!kaaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha, + pSrc->format)) + { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return -1; + } + kaaGetPixelFromRGBA(&pixel, red, green, blue, alpha, + pDst->format); + + if (!(*pKaaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel)) + { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return -1; + } + + nbox = REGION_NUM_RECTS(®ion); + pbox = REGION_RECTS(®ion); + while (nbox--) + { + (*pKaaScr->info->Solid) (pbox->x1 + dst_off_x, + pbox->y1 + dst_off_y, + pbox->x2 + dst_off_x, + pbox->y2 + dst_off_y); + pbox++; + } + + (*pKaaScr->info->DoneSolid) (); + kaaMarkSync (pDst->pDrawable->pScreen); + kaaDrawableDirty (pDst->pDrawable); + + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return 1; +} + +static int +kaaTryDriverBlend(CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + KaaScreenPriv (pDst->pDrawable->pScreen); + RegionRec region; + BoxPtr pbox; + int nbox; + int src_off_x, src_off_y, dst_off_x, dst_off_y; + PixmapPtr pSrcPix, pDstPix; + struct _Pixmap srcScratch; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + + if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst, + xSrc, ySrc, 0, 0, xDst, yDst, + width, height)) + return 1; + + + if (pSrc->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable); + if (pDst->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable); + + pSrcPix = kaaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y); + pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y); + + if (!pDstPix) { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return 0; + } + + if (!pSrcPix && pKaaScr->info->UploadToScratch) { + if ((*pKaaScr->info->UploadToScratch) ((PixmapPtr) pSrc->pDrawable, + &srcScratch)) + pSrcPix = &srcScratch; + } + + if (!pSrcPix) { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return 0; + } + + if (!(*pKaaScr->info->PrepareBlend) (op, pSrc, pDst, pSrcPix, + pDstPix)) + { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return -1; + } + + nbox = REGION_NUM_RECTS(®ion); + pbox = REGION_RECTS(®ion); + + xSrc -= xDst; + ySrc -= yDst; + + while (nbox--) + { + (*pKaaScr->info->Blend) (pbox->x1 + xSrc + src_off_x, + pbox->y1 + ySrc + src_off_y, + pbox->x1 + dst_off_x, + pbox->y1 + dst_off_y, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + pbox++; + } + + (*pKaaScr->info->DoneBlend) (); + kaaMarkSync (pDst->pDrawable->pScreen); + kaaDrawableDirty (pDst->pDrawable); + + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return 1; +} + +static int +kaaTryDriverComposite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + KaaScreenPriv (pDst->pDrawable->pScreen); + RegionRec region; + BoxPtr pbox; + int nbox; + int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y; + PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix; + struct _Pixmap scratch; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + + if (pMask) { + xMask += pMask->pDrawable->x; + yMask += pMask->pDrawable->y; + } + + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + + if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height)) + return 1; + + if (pKaaScr->info->CheckComposite && + !(*pKaaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) + { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return -1; + } + + if (pSrc->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable); + if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseScreen ((PixmapPtr) pMask->pDrawable); + if (pDst->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable); + + pSrcPix = kaaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y); + if (pMask) + pMaskPix = kaaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x, + &mask_off_y); + pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y); + + if (!pDstPix) { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return 0; + } + + if (!pSrcPix && (!pMask || pMaskPix) && pKaaScr->info->UploadToScratch) { + if (pSrc->pDrawable->type == DRAWABLE_WINDOW) + pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap) ( + (WindowPtr) pSrc->pDrawable); + else + pSrcPix = (PixmapPtr) pSrc->pDrawable; + if ((*pKaaScr->info->UploadToScratch) (pSrcPix, &scratch)) + pSrcPix = &scratch; + } else if (pSrcPix && pMask && !pMaskPix && pKaaScr->info->UploadToScratch) { + if (pMask->pDrawable->type == DRAWABLE_WINDOW) + pMaskPix = (*pMask->pDrawable->pScreen->GetWindowPixmap) ( + (WindowPtr) pMask->pDrawable); + else + pMaskPix = (PixmapPtr) pMask->pDrawable; + if ((*pKaaScr->info->UploadToScratch) (pMaskPix, &scratch)) + pMaskPix = &scratch; + } + + if (!pSrcPix || (pMask && !pMaskPix)) { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return 0; + } + + if (!(*pKaaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix, + pMaskPix, pDstPix)) + { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return -1; + } + + nbox = REGION_NUM_RECTS(®ion); + pbox = REGION_RECTS(®ion); + + xMask -= xDst; + yMask -= yDst; + + xSrc -= xDst; + ySrc -= yDst; + + while (nbox--) + { + (*pKaaScr->info->Composite) (pbox->x1 + xSrc + src_off_x, + pbox->y1 + ySrc + src_off_y, + pbox->x1 + xMask + mask_off_x, + pbox->y1 + yMask + mask_off_y, + pbox->x1 + dst_off_x, + pbox->y1 + dst_off_y, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + pbox++; + } + + (*pKaaScr->info->DoneComposite) (); + kaaMarkSync (pDst->pDrawable->pScreen); + kaaDrawableDirty (pDst->pDrawable); + + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return 1; +} + + +void +kaaComposite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + KdScreenPriv (pDst->pDrawable->pScreen); + KaaScreenPriv (pDst->pDrawable->pScreen); + int ret = -1; + + if (!pMask && pSrc->pDrawable) + { + if (op == PictOpSrc) + { + if (pScreenPriv->enabled && pSrc->pDrawable && pSrc->pDrawable->width == 1 && + pSrc->pDrawable->height == 1 && pSrc->repeat) + { + ret = kaaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst, + width, height); + if (ret == 1) + return; + } + else if (!pSrc->repeat && !pSrc->transform && + pSrc->format == pDst->format) + { + RegionRec region; + + 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)) + return; + + + kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0, + REGION_RECTS(®ion), REGION_NUM_RECTS(®ion), + xSrc - xDst, ySrc - yDst, + FALSE, FALSE, 0, 0); + return; + } + } + + if (pScreenPriv->enabled && pKaaScr->info->PrepareBlend && + !pSrc->alphaMap && !pDst->alphaMap) + { + ret = kaaTryDriverBlend(op, pSrc, pDst, xSrc, ySrc, xDst, yDst, + width, height); + if (ret == 1) + return; + } + } + + if (pSrc->pDrawable && (!pMask || pMask->pDrawable) && + pScreenPriv->enabled && pKaaScr->info->PrepareComposite && + !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap) + { + ret = kaaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, + yMask, xDst, yDst, width, height); + if (ret == 1) + return; + } + + if (ret != 0) { + /* failure to accelerate was not due to pixmaps being in the wrong + * locations. + */ + if (pSrc->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable); + if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseMemory ((PixmapPtr) pMask->pDrawable); + if (pDst->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseMemory ((PixmapPtr) pDst->pDrawable); + } + +#if KAA_DEBUG_FALLBACKS + kaaPrintCompositeFallback (op, pSrc, pMask, pDst); +#endif + + KdCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc, + xMask, yMask, xDst, yDst, width, height); +} +#endif + +static xFixed +miLineFixedX (xLineFixed *l, xFixed y, Bool ceil) +{ + xFixed dx = l->p2.x - l->p1.x; + xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx; + xFixed dy = l->p2.y - l->p1.y; + if (ceil) + ex += (dy - 1); + return l->p1.x + (xFixed) (ex / dy); +} + +/* Need to decide just how much to trim, to maintain translation independence + * when converted to floating point. + */ +#define XFIXED_TO_FLOAT(x) (((float)((x) & 0xffffff00)) / 65536.0) + +/* This is just to allow us to work on the hardware side of the problem while + * waiting for cairo to get a new tesselator. We may not be able to support + * RasterizeTrapezoid at all due to the abutting edges requirement, but it might + * be technically legal if we widened the trap by some epsilon, so that alpha + * values at abutting edges were a little too big and capped at one, rather than + * a little too small and looked bad. + */ +void kaaRasterizeTrapezoid(PicturePtr pDst, + xTrapezoid *trap, + int xoff, + int yoff) +{ + KdScreenPriv (pDst->pDrawable->pScreen); + KaaScreenPriv (pDst->pDrawable->pScreen); + KaaTrapezoid ktrap; + PixmapPtr pPix; + xFixed x1, x2; + + if (!pScreenPriv->enabled || + !pKaaScr->info->PrepareTrapezoids || + pDst->pDrawable->type != DRAWABLE_PIXMAP || + pDst->alphaMap || pDst->format != PICT_a8) + { + KdCheckRasterizeTrapezoid (pDst, trap, xoff, yoff); +#if KAA_DEBUG_FALLBACKS + kaaPrintTrapezoidFallback (pDst); +#endif + return; + } + pPix = (PixmapPtr)pDst->pDrawable; + + kaaPixmapUseScreen (pPix); + + if (!kaaPixmapIsOffscreen (pPix) || + !(*pKaaScr->info->PrepareTrapezoids) (pDst, pPix)) + { +#if KAA_DEBUG_FALLBACKS + kaaPrintTrapezoidFallback (pDst); +#endif + KdCheckRasterizeTrapezoid (pDst, trap, xoff, yoff); + return; + } + + ktrap.ty = XFIXED_TO_FLOAT(trap->top) + yoff; + x1 = miLineFixedX (&trap->left, trap->top, FALSE); + x2 = miLineFixedX (&trap->right, trap->top, TRUE); + ktrap.tl = XFIXED_TO_FLOAT(x1) + xoff; + ktrap.tr = XFIXED_TO_FLOAT(x2) + xoff; + ktrap.by = XFIXED_TO_FLOAT(trap->bottom) + yoff; + x1 = miLineFixedX (&trap->left, trap->bottom, FALSE); + x2 = miLineFixedX (&trap->right, trap->bottom, TRUE); + ktrap.bl = XFIXED_TO_FLOAT(x1) + xoff; + ktrap.br = XFIXED_TO_FLOAT(x2) + xoff; + + (*pKaaScr->info->Trapezoids) (&ktrap, 1); + (*pKaaScr->info->DoneTrapezoids) (); +} + +void +kaaInitTrapOffsets(int grid_order, float *x_offsets, float *y_offsets, + float x_offset, float y_offset) +{ + int i = 0; + float x, y, x_count, y_count; + + x_count = (1 << (grid_order / 2)) + 1; + y_count = (1 << (grid_order / 2)) - 1; + + x_offset += 1.0 / x_count / 2.0; + y_offset += 1.0 / y_count / 2.0; + + for (x = 0; x < x_count; x++) { + for (y = 0; y < y_count; y++) { + x_offsets[i] = x / x_count + x_offset; + y_offsets[i] = y / y_count + y_offset; + i++; + } + } +} + diff --git a/xorg-server/hw/kdrive/src/kasync.c b/xorg-server/hw/kdrive/src/kasync.c new file mode 100644 index 000000000..5388f217d --- /dev/null +++ b/xorg-server/hw/kdrive/src/kasync.c @@ -0,0 +1,341 @@ +/* + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "kaa.h" +#include "picturestr.h" +#include "mipict.h" +#include "fbpict.h" + +/* + * These functions wrap the low-level fb rendering functions and + * synchronize framebuffer/accelerated drawing by stalling until + * the accelerator is idle + */ + +void +KdCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans, + DDXPointPtr ppt, int *pwidth, int fSorted) +{ + kaaWaitSync (pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted); +} + +void +KdCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc, + DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) +{ + kaaWaitSync (pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); +} + +void +KdCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, + int x, int y, int w, int h, int leftPad, int format, + char *bits) +{ + kaaWaitSync (pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); +} + +RegionPtr +KdCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, int dstx, int dsty) +{ + kaaWaitSync (pSrc->pScreen); + kaaDrawableDirty (pDst); + return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); +} + +RegionPtr +KdCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, int dstx, int dsty, + unsigned long bitPlane) +{ + kaaWaitSync (pSrc->pScreen); + kaaDrawableDirty (pDst); + return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, + bitPlane); +} + +void +KdCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr pptInit) +{ + kaaWaitSync (pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbPolyPoint (pDrawable, pGC, mode, npt, pptInit); +} + +void +KdCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr ppt) +{ + + if (pGC->lineWidth == 0) { + kaaWaitSync(pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + } + kaaDrawableDirty (pDrawable); + fbPolyLine (pDrawable, pGC, mode, npt, ppt); +} + +void +KdCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, + int nsegInit, xSegment *pSegInit) +{ + if (pGC->lineWidth == 0) { + kaaWaitSync(pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + } + kaaDrawableDirty (pDrawable); + fbPolySegment (pDrawable, pGC, nsegInit, pSegInit); +} + +void +KdCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC, + int nrects, xRectangle *prect) +{ + if (pGC->lineWidth == 0) { + kaaWaitSync(pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + } + fbPolyRectangle (pDrawable, pGC, nrects, prect); +} + +void +KdCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, + int narcs, xArc *pArcs) +{ + if (pGC->lineWidth == 0) + { + kaaWaitSync(pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbPolyArc (pDrawable, pGC, narcs, pArcs); + } + else + miPolyArc (pDrawable, pGC, narcs, pArcs); +} + +#if 0 +void +KdCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC, + int shape, int mode, int count, DDXPointPtr pPts) +{ + kaaWaitSync(pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbFillPolygon (pDrawable, pGC, mode, count, pPts); +} +#endif + +void +KdCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, + int nrect, xRectangle *prect) +{ + kaaWaitSync(pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbPolyFillRect (pDrawable, pGC, nrect, prect); +} + +void +KdCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC, + int narcs, xArc *pArcs) +{ + kaaWaitSync(pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbPolyFillArc (pDrawable, pGC, narcs, pArcs); +} + +void +KdCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase) +{ + kaaWaitSync(pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); +} + +void +KdCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase) +{ + kaaWaitSync(pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); +} + +void +KdCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, + DrawablePtr pDrawable, + int w, int h, int x, int y) +{ + kaaWaitSync(pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y); +} + +void +KdCheckGetImage (DrawablePtr pDrawable, + int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, + char *d) +{ + kaaWaitSync(pDrawable->pScreen); + fbGetImage (pDrawable, x, y, w, h, format, planeMask, d); +} + +void +KdCheckGetSpans (DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pdstStart) +{ + kaaWaitSync(pDrawable->pScreen); + fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); +} + +void +KdCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + kaaWaitSync (pWin->drawable.pScreen); + kaaDrawableDirty ((DrawablePtr)pWin); + fbCopyWindow (pWin, ptOldOrg, prgnSrc); +} + +#if KD_MAX_FB > 1 +void +KdCheckPaintKey(DrawablePtr pDrawable, + RegionPtr pRegion, + CARD32 pixel, + int layer) +{ + kaaWaitSync (pDrawable->pScreen); + kaaDrawableDirty (pDrawable); + fbOverlayPaintKey (pDrawable, pRegion, pixel, layer); +} + +void +KdCheckOverlayCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + kaaWaitSync (pWin->drawable.pScreen); + kaaDrawableDirty ((DrawablePtr)pWin); + fbOverlayCopyWindow (pWin, ptOldOrg, prgnSrc); +} +#endif + +void +KdScreenInitAsync (ScreenPtr pScreen) +{ + pScreen->GetImage = KdCheckGetImage; + pScreen->GetSpans = KdCheckGetSpans; + pScreen->CopyWindow = KdCheckCopyWindow; +#ifdef RENDER + KdPictureInitAsync (pScreen); +#endif +} + +void +KdCheckComposite (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + kaaWaitSync (pDst->pDrawable->pScreen); + kaaDrawableDirty (pDst->pDrawable); + fbComposite (op, + pSrc, + pMask, + pDst, + xSrc, + ySrc, + xMask, + yMask, + xDst, + yDst, + width, + height); +} + +void +KdCheckRasterizeTrapezoid(PicturePtr pMask, + xTrapezoid *trap, + int x_off, + int y_off) +{ + kaaWaitSync (pMask->pDrawable->pScreen); + kaaDrawableDirty (pMask->pDrawable); + fbRasterizeTrapezoid (pMask, trap, x_off, y_off); +} + +/* + * Only need to stall for copyarea/copyplane + */ +const GCOps kdAsyncPixmapGCOps = { + fbFillSpans, + fbSetSpans, + fbPutImage, + KdCheckCopyArea, + KdCheckCopyPlane, + fbPolyPoint, + fbPolyLine, + fbPolySegment, + fbPolyRectangle, + fbPolyArc, + fbFillPolygon, + fbPolyFillRect, + fbPolyFillArc, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + fbImageGlyphBlt, + fbPolyGlyphBlt, + fbPushPixels +}; + +void +KdPictureInitAsync (ScreenPtr pScreen) +{ + PictureScreenPtr ps; + + ps = GetPictureScreen(pScreen); + ps->Composite = KdCheckComposite; + ps->RasterizeTrapezoid = KdCheckRasterizeTrapezoid; +} diff --git a/xorg-server/hw/kdrive/src/kcmap.c b/xorg-server/hw/kdrive/src/kcmap.c new file mode 100644 index 000000000..4941ad17f --- /dev/null +++ b/xorg-server/hw/kdrive/src/kcmap.c @@ -0,0 +1,294 @@ +/* + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" + +/* + * Put the entire colormap into the DAC + */ + +void +KdSetColormap (ScreenPtr pScreen, int fb) +{ + KdScreenPriv(pScreen); + ColormapPtr pCmap = pScreenPriv->pInstalledmap[fb]; + Pixel pixels[KD_MAX_PSEUDO_SIZE]; + xrgb colors[KD_MAX_PSEUDO_SIZE]; + xColorItem defs[KD_MAX_PSEUDO_SIZE]; + int i; + + if (!pScreenPriv->card->cfuncs->putColors) + return; + if (pScreenPriv->screen->fb[fb].depth > KD_MAX_PSEUDO_DEPTH) + return; + + if (!pScreenPriv->enabled) + return; + + if (!pCmap) + return; + + /* + * Make DIX convert pixels into RGB values -- this handles + * true/direct as well as pseudo/static visuals + */ + + for (i = 0; i < (1 << pScreenPriv->screen->fb[fb].depth); i++) + pixels[i] = i; + + QueryColors (pCmap, (1 << pScreenPriv->screen->fb[fb].depth), pixels, colors); + + for (i = 0; i < (1 << pScreenPriv->screen->fb[fb].depth); i++) + { + defs[i].pixel = i; + defs[i].red = colors[i].red; + defs[i].green = colors[i].green; + defs[i].blue = colors[i].blue; + defs[i].flags = DoRed|DoGreen|DoBlue; + } + + (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, fb, + (1 << pScreenPriv->screen->fb[fb].depth), + defs); + + /* recolor hardware cursor */ + if (pScreenPriv->card->cfuncs->recolorCursor) + (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, 0, 0); +} + +/* + * When the hardware is enabled, save the hardware colors and store + * the current colormap + */ +void +KdEnableColormap (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + int i; + int fb; + Bool done = FALSE; + + if (!pScreenPriv->card->cfuncs->putColors) + return; + for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++) + { + if (pScreenPriv->screen->fb[fb].depth <= KD_MAX_PSEUDO_DEPTH && !done) + { + for (i = 0; i < (1 << pScreenPriv->screen->fb[fb].depth); i++) + pScreenPriv->systemPalette[i].pixel = i; + (*pScreenPriv->card->cfuncs->getColors) (pScreen, fb, + (1 << pScreenPriv->screen->fb[fb].depth), + pScreenPriv->systemPalette); + done = TRUE; + } + KdSetColormap (pScreen, fb); + } +} + +void +KdDisableColormap (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + int fb; + + if (!pScreenPriv->card->cfuncs->putColors) + return; + for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++) + { + if (pScreenPriv->screen->fb[fb].depth <= KD_MAX_PSEUDO_DEPTH) + { + (*pScreenPriv->card->cfuncs->putColors) (pScreen, fb, + (1 << pScreenPriv->screen->fb[fb].depth), + pScreenPriv->systemPalette); + break; + } + } +} + +static int +KdColormapFb (ColormapPtr pCmap) +{ + ScreenPtr pScreen = pCmap->pScreen; + KdScreenPriv (pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + int d; + DepthPtr depth; + int v; + VisualID vid = pCmap->pVisual->vid; + int fb; + + if (screen->fb[1].depth) + { + for (d = 0; d < pScreen->numDepths; d++) + { + depth = &pScreen->allowedDepths[d]; + for (v = 0; v < depth->numVids; v++) + { + if (depth->vids[v] == vid) + { + for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++) + { + if (depth->depth == screen->fb[fb].depth) + return fb; + } + } + } + } + } + return 0; +} + +/* + * KdInstallColormap + * + * This function is called when the server receives a request to install a + * colormap or when the server needs to install one on its own, like when + * there's no window manager running and the user has moved the pointer over + * an X client window. It needs to build an identity Windows palette for the + * colormap and realize it into the Windows system palette. + */ +void +KdInstallColormap (ColormapPtr pCmap) +{ + KdScreenPriv(pCmap->pScreen); + int fb = KdColormapFb (pCmap); + + if (pCmap == pScreenPriv->pInstalledmap[fb]) + return; + + /* Tell X clients that the installed colormap is going away. */ + if (pScreenPriv->pInstalledmap[fb]) + WalkTree(pScreenPriv->pInstalledmap[fb]->pScreen, TellLostMap, + (pointer) &(pScreenPriv->pInstalledmap[fb]->mid)); + + /* Take note of the new installed colorscreen-> */ + pScreenPriv->pInstalledmap[fb] = pCmap; + + KdSetColormap (pCmap->pScreen, fb); + + /* Tell X clients of the new colormap */ + WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &(pCmap->mid)); +} + +/* + * KdUninstallColormap + * + * This function uninstalls a colormap by either installing + * the default X colormap or erasing the installed colormap pointer. + * The default X colormap itself cannot be uninstalled. + */ +void +KdUninstallColormap (ColormapPtr pCmap) +{ + KdScreenPriv(pCmap->pScreen); + int fb = KdColormapFb (pCmap); + Colormap defMapID; + ColormapPtr defMap; + + /* ignore if not installed */ + if (pCmap != pScreenPriv->pInstalledmap[fb]) + return; + + /* ignore attempts to uninstall default colormap */ + defMapID = pCmap->pScreen->defColormap; + if ((Colormap) pCmap->mid == defMapID) + return; + + /* install default if on same fb */ + defMap = (ColormapPtr) LookupIDByType(defMapID, RT_COLORMAP); + if (defMap && KdColormapFb (defMap) == fb) + (*pCmap->pScreen->InstallColormap)(defMap); + else + { + /* uninstall and clear colormap pointer */ + WalkTree(pCmap->pScreen, TellLostMap, + (pointer) &(pCmap->mid)); + pScreenPriv->pInstalledmap[fb] = 0; + } +} + +int +KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps) +{ + KdScreenPriv(pScreen); + int fb; + int n = 0; + + for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++) + { + if (pScreenPriv->pInstalledmap[fb]) + { + *pCmaps++ = pScreenPriv->pInstalledmap[fb]->mid; + n++; + } + } + return n; +} + +/* + * KdStoreColors + * + * This function is called whenever the server receives a request to store + * color values into one or more entries in the currently installed X + * colormap; it can be either the default colormap or a private colorscreen-> + */ +void +KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs) +{ + KdScreenPriv(pCmap->pScreen); + VisualPtr pVisual; + xColorItem expanddefs[KD_MAX_PSEUDO_SIZE]; + int fb = KdColormapFb (pCmap); + + if (pCmap != pScreenPriv->pInstalledmap[fb]) + return; + + if (!pScreenPriv->card->cfuncs->putColors) + return; + + if (pScreenPriv->screen->fb[fb].depth > KD_MAX_PSEUDO_DEPTH) + return; + + if (!pScreenPriv->enabled) + return; + + /* Check for DirectColor or TrueColor being simulated on a PseudoColor device. */ + pVisual = pCmap->pVisual; + if ((pVisual->class | DynamicClass) == DirectColor) + { + /* + * Expand DirectColor or TrueColor color values into a PseudoColor + * format. Defer to the Color Framebuffer (CFB) code to do that. + */ + ndef = fbExpandDirectColors(pCmap, ndef, pdefs, expanddefs); + pdefs = expanddefs; + } + + (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, fb, ndef, pdefs); + + /* recolor hardware cursor */ + if (pScreenPriv->card->cfuncs->recolorCursor) + (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, ndef, pdefs); +} diff --git a/xorg-server/hw/kdrive/src/kcurscol.c b/xorg-server/hw/kdrive/src/kcurscol.c new file mode 100644 index 000000000..6a17df30f --- /dev/null +++ b/xorg-server/hw/kdrive/src/kcurscol.c @@ -0,0 +1,94 @@ +/* + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "cursorstr.h" + +static int +KdComputeCmapShift (unsigned long mask) +{ + int shift; + unsigned long bit; + + shift = 16; + bit = 0x80000000; + while (!(mask & bit)) + { + shift--; + bit >>= 1; + } + return shift; +} + +#define Shift(v,d) ((d) < 0 ? ((v) >> (-d)) : ((v) << (d))) + +void +KdAllocateCursorPixels (ScreenPtr pScreen, + int fb, + CursorPtr pCursor, + Pixel *source, + Pixel *mask) +{ + xColorItem sourceColor, maskColor; + int r, g, b; + KdScreenPriv(pScreen); + + if (pScreenPriv->screen->fb[fb].redMask) + { + + r = KdComputeCmapShift (pScreenPriv->screen->fb[fb].redMask); + g = KdComputeCmapShift (pScreenPriv->screen->fb[fb].greenMask); + b = KdComputeCmapShift (pScreenPriv->screen->fb[fb].blueMask); + *source = ((Shift(pCursor->foreRed,r) & pScreenPriv->screen->fb[fb].redMask) | + (Shift(pCursor->foreGreen,g) & pScreenPriv->screen->fb[fb].greenMask) | + (Shift(pCursor->foreBlue,b) & pScreenPriv->screen->fb[fb].blueMask)); + *mask = ((Shift(pCursor->backRed,r) & pScreenPriv->screen->fb[fb].redMask) | + (Shift(pCursor->backGreen,g) & pScreenPriv->screen->fb[fb].greenMask) | + (Shift(pCursor->backBlue,b) & pScreenPriv->screen->fb[fb].blueMask)); + } + else + { + /* + * Set these to an invalid pixel value so that + * when the store colors comes through, the cursor + * won't get recolored + */ + *source = ~0; + *mask = ~0; + + sourceColor.red = pCursor->foreRed; + sourceColor.green = pCursor->foreGreen; + sourceColor.blue = pCursor->foreBlue; + FakeAllocColor(pScreenPriv->pInstalledmap[fb], &sourceColor); + maskColor.red = pCursor->backRed; + maskColor.green = pCursor->backGreen; + maskColor.blue = pCursor->backBlue; + FakeAllocColor(pScreenPriv->pInstalledmap[fb], &maskColor); + FakeFreeColor(pScreenPriv->pInstalledmap[fb], sourceColor.pixel); + FakeFreeColor(pScreenPriv->pInstalledmap[fb], maskColor.pixel); + *source = sourceColor.pixel; + *mask = maskColor.pixel; + } +} diff --git a/xorg-server/hw/kdrive/src/kdrive.c b/xorg-server/hw/kdrive/src/kdrive.c new file mode 100644 index 000000000..e2ee4adea --- /dev/null +++ b/xorg-server/hw/kdrive/src/kdrive.c @@ -0,0 +1,1416 @@ +/* + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#ifdef PSEUDO8 +#include "pseudo8/pseudo8.h" +#endif +#include <mivalidate.h> +#include <dixstruct.h> +#include "privates.h" +#ifdef RANDR +#include <randrstr.h> +#endif + +#ifdef XV +#include "kxv.h" +#endif + +#ifdef DPMSExtension +#include "dpmsproc.h" +#endif + +#ifdef HAVE_EXECINFO_H +#include <execinfo.h> +#endif + +#include <signal.h> + +typedef struct _kdDepths { + CARD8 depth; + CARD8 bpp; +} KdDepths; + +KdDepths kdDepths[] = { + { 1, 1 }, + { 4, 4 }, + { 8, 8 }, + { 15, 16 }, + { 16, 16 }, + { 24, 32 }, + { 32, 32 } +}; + +#define NUM_KD_DEPTHS (sizeof (kdDepths) / sizeof (kdDepths[0])) + +#define KD_DEFAULT_BUTTONS 5 + +DevPrivateKey kdScreenPrivateKey = &kdScreenPrivateKey; +unsigned long kdGeneration; + +Bool kdVideoTest; +unsigned long kdVideoTestTime; +Bool kdEmulateMiddleButton; +Bool kdRawPointerCoordinates; +Bool kdDisableZaphod; +Bool kdDontZap; +Bool kdEnabled; +int kdSubpixelOrder; +int kdVirtualTerminal = -1; +Bool kdSwitchPending; +char *kdSwitchCmd; +DDXPointRec kdOrigin; +Bool kdHasPointer = FALSE; +Bool kdHasKbd = FALSE; + +static Bool kdCaughtSignal = FALSE; + +/* + * Carry arguments from InitOutput through driver initialization + * to KdScreenInit + */ + +KdOsFuncs *kdOsFuncs; +extern WindowPtr *WindowTable; + +void +KdSetRootClip (ScreenPtr pScreen, BOOL enable) +{ + WindowPtr pWin = WindowTable[pScreen->myNum]; + WindowPtr pChild; + Bool WasViewable; + Bool anyMarked = FALSE; + RegionPtr pOldClip = 0; +#ifdef DO_SAVE_UNDERS + Bool dosave = FALSE; +#endif + WindowPtr pLayerWin; + BoxRec box; + + 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 = REGION_CREATE(pScreen, NullBox, 1); + REGION_SUBTRACT(pScreen, borderVisible, + &pWin->borderClip, &pWin->winSize); + pWin->valdata->before.borderVisible = borderVisible; + } + pWin->valdata->before.resized = TRUE; + } + } + + if (enable) + { + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + pWin->drawable.width = pScreen->width; + pWin->drawable.height = pScreen->height; + REGION_INIT (pScreen, &pWin->winSize, &box, 1); + REGION_INIT (pScreen, &pWin->borderSize, &box, 1); + REGION_RESET(pScreen, &pWin->borderClip, &box); + REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); + } + else + { + REGION_EMPTY(pScreen, &pWin->borderClip); + REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); + } + + ResizeChildrenWinSize (pWin, 0, 0, 0, 0); + + if (WasViewable) + { + if (pWin->firstChild) + { + anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild, + pWin->firstChild, + (WindowPtr *)NULL); + } + else + { + (*pScreen->MarkWindow) (pWin); + anyMarked = TRUE; + } + +#ifdef DO_SAVE_UNDERS + if (DO_SAVE_UNDERS(pWin)) + { + dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin); + } +#endif /* DO_SAVE_UNDERS */ + + if (anyMarked) + (*pScreen->ValidateTree)(pWin, NullWindow, VTOther); + } + + if (WasViewable) + { + if (anyMarked) + (*pScreen->HandleExposures)(pWin); +#ifdef DO_SAVE_UNDERS + if (dosave) + (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin); +#endif /* DO_SAVE_UNDERS */ + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther); + } + if (pWin->realized) + WindowsRestructured (); +} + +void +KdDisableScreen (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + + if (!pScreenPriv->enabled) + return; + if (!pScreenPriv->closed) + KdSetRootClip (pScreen, FALSE); + KdDisableColormap (pScreen); + KdOffscreenSwapOut (pScreen); + if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->disableAccel) + (*pScreenPriv->card->cfuncs->disableAccel) (pScreen); + if (!pScreenPriv->screen->softCursor && pScreenPriv->card->cfuncs->disableCursor) + (*pScreenPriv->card->cfuncs->disableCursor) (pScreen); + if (pScreenPriv->card->cfuncs->dpms) + (*pScreenPriv->card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL); + pScreenPriv->enabled = FALSE; + if(pScreenPriv->card->cfuncs->disable) + (*pScreenPriv->card->cfuncs->disable) (pScreen); +} + +static void +KdDoSwitchCmd (char *reason) +{ + if (kdSwitchCmd) + { + char *command = xalloc (strlen (kdSwitchCmd) + + 1 + + strlen (reason) + + 1); + if (!command) + return; + strcpy (command, kdSwitchCmd); + strcat (command, " "); + strcat (command, reason); + system (command); + xfree (command); + } +} + +void +KdSuspend (void) +{ + KdCardInfo *card; + KdScreenInfo *screen; + + if (kdEnabled) + { + for (card = kdCardInfo; card; card = card->next) + { + for (screen = card->screenList; screen; screen = screen->next) + if (screen->mynum == card->selected && screen->pScreen) + KdDisableScreen (screen->pScreen); + if (card->driver && card->cfuncs->restore) + (*card->cfuncs->restore) (card); + } + KdDisableInput (); + KdDoSwitchCmd ("suspend"); + } +} + +void +KdDisableScreens (void) +{ + KdSuspend (); + if (kdEnabled) + { + if (kdOsFuncs->Disable) + (*kdOsFuncs->Disable) (); + kdEnabled = FALSE; + } +} + +Bool +KdEnableScreen (ScreenPtr pScreen) +{ + KdScreenPriv (pScreen); + + if (pScreenPriv->enabled) + return TRUE; + if(pScreenPriv->card->cfuncs->enable) + if (!(*pScreenPriv->card->cfuncs->enable) (pScreen)) + return FALSE; + pScreenPriv->enabled = TRUE; + pScreenPriv->dpmsState = KD_DPMS_NORMAL; + pScreenPriv->card->selected = pScreenPriv->screen->mynum; + KdOffscreenSwapIn (pScreen); + if (!pScreenPriv->screen->softCursor && pScreenPriv->card->cfuncs->enableCursor) + (*pScreenPriv->card->cfuncs->enableCursor) (pScreen); + if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->enableAccel) + (*pScreenPriv->card->cfuncs->enableAccel) (pScreen); + KdEnableColormap (pScreen); + KdSetRootClip (pScreen, TRUE); + if (pScreenPriv->card->cfuncs->dpms) + (*pScreenPriv->card->cfuncs->dpms) (pScreen, pScreenPriv->dpmsState); + return TRUE; +} + +void +KdResume (void) +{ + KdCardInfo *card; + KdScreenInfo *screen; + + if (kdEnabled) + { + KdDoSwitchCmd ("resume"); + for (card = kdCardInfo; card; card = card->next) + { + if(card->cfuncs->preserve) + (*card->cfuncs->preserve) (card); + for (screen = card->screenList; screen; screen = screen->next) + if (screen->mynum == card->selected && screen->pScreen) + KdEnableScreen (screen->pScreen); + } + KdEnableInput (); + KdReleaseAllKeys (); + } +} + +void +KdEnableScreens (void) +{ + if (!kdEnabled) + { + kdEnabled = TRUE; + if (kdOsFuncs->Enable) + (*kdOsFuncs->Enable) (); + } + KdResume (); +} + +void +KdProcessSwitch (void) +{ + if (kdEnabled) + KdDisableScreens (); + else + KdEnableScreens (); +} + +void +AbortDDX(void) +{ + KdDisableScreens (); + if (kdOsFuncs) + { + if (kdEnabled && kdOsFuncs->Disable) + (*kdOsFuncs->Disable) (); + if (kdOsFuncs->Fini) + (*kdOsFuncs->Fini) (); + KdDoSwitchCmd ("stop"); + } + + if (kdCaughtSignal) + abort(); +} + +void +ddxGiveUp () +{ + AbortDDX (); +} + +Bool kdDumbDriver; +Bool kdSoftCursor; + +char * +KdParseFindNext (char *cur, char *delim, char *save, char *last) +{ + while (*cur && !strchr (delim, *cur)) + { + *save++ = *cur++; + } + *save = 0; + *last = *cur; + if (*cur) + cur++; + return cur; +} + +Rotation +KdAddRotation (Rotation a, Rotation b) +{ + Rotation rotate = (a & RR_Rotate_All) * (b & RR_Rotate_All); + Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All); + + if (rotate > RR_Rotate_270) + rotate /= (RR_Rotate_270 * RR_Rotate_90); + return reflect | rotate; +} + +Rotation +KdSubRotation (Rotation a, Rotation b) +{ + Rotation rotate = (a & RR_Rotate_All) * 16 / (b & RR_Rotate_All); + Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All); + + if (rotate > RR_Rotate_270) + rotate /= (RR_Rotate_270 * RR_Rotate_90); + return reflect | rotate; +} + +void +KdParseScreen (KdScreenInfo *screen, + char *arg) +{ + char delim; + char save[1024]; + int fb; + int i; + int pixels, mm; + + screen->dumb = kdDumbDriver; + screen->softCursor = kdSoftCursor; + screen->origin = kdOrigin; + screen->randr = RR_Rotate_0; + screen->width = 0; + screen->height = 0; + screen->width_mm = 0; + screen->height_mm = 0; + screen->subpixel_order = kdSubpixelOrder; + screen->rate = 0; + for (fb = 0; fb < KD_MAX_FB; fb++) + screen->fb[fb].depth = 0; + if (!arg) + return; + if (strlen (arg) >= sizeof (save)) + return; + + for (i = 0; i < 2; i++) + { + arg = KdParseFindNext (arg, "x/@XY", save, &delim); + if (!save[0]) + return; + + pixels = atoi(save); + mm = 0; + + if (delim == '/') + { + arg = KdParseFindNext (arg, "x@XY", save, &delim); + if (!save[0]) + return; + mm = atoi(save); + } + + if (i == 0) + { + screen->width = pixels; + screen->width_mm = mm; + } + else + { + screen->height = pixels; + screen->height_mm = mm; + } + if (delim != 'x' && delim != '@' && delim != 'X' && delim != 'Y') + return; + } + + kdOrigin.x += screen->width; + kdOrigin.y = 0; + kdDumbDriver = FALSE; + kdSoftCursor = FALSE; + kdSubpixelOrder = SubPixelUnknown; + + if (delim == '@') + { + arg = KdParseFindNext (arg, "xXY", save, &delim); + if (save[0]) + { + int rotate = atoi (save); + if (rotate < 45) + screen->randr = RR_Rotate_0; + else if (rotate < 135) + screen->randr = RR_Rotate_90; + else if (rotate < 225) + screen->randr = RR_Rotate_180; + else if (rotate < 315) + screen->randr = RR_Rotate_270; + else + screen->randr = RR_Rotate_0; + } + } + if (delim == 'X') + { + arg = KdParseFindNext (arg, "xY", save, &delim); + screen->randr |= RR_Reflect_X; + } + + if (delim == 'Y') + { + arg = KdParseFindNext (arg, "xY", save, &delim); + screen->randr |= RR_Reflect_Y; + } + + fb = 0; + while (fb < KD_MAX_FB) + { + arg = KdParseFindNext (arg, "x/,", save, &delim); + if (!save[0]) + break; + screen->fb[fb].depth = atoi(save); + if (delim == '/') + { + arg = KdParseFindNext (arg, "x,", save, &delim); + if (!save[0]) + break; + screen->fb[fb].bitsPerPixel = atoi (save); + } + else + screen->fb[fb].bitsPerPixel = 0; + if (delim != ',') + break; + fb++; + } + + if (delim == 'x') + { + arg = KdParseFindNext (arg, "x", save, &delim); + if (save[0]) + screen->rate = atoi(save); + } +} + +/* + * Mouse argument syntax: + * + * device,protocol,options... + * + * Options are any of: + * 1-5 n button mouse + * 2button emulate middle button + * {NMO} Reorder buttons + */ + +char * +KdSaveString (char *str) +{ + char *n = (char *) xalloc (strlen (str) + 1); + + if (!n) + return 0; + strcpy (n, str); + return n; +} + +void +KdParseRgba (char *rgba) +{ + if (!strcmp (rgba, "rgb")) + kdSubpixelOrder = SubPixelHorizontalRGB; + else if (!strcmp (rgba, "bgr")) + kdSubpixelOrder = SubPixelHorizontalBGR; + else if (!strcmp (rgba, "vrgb")) + kdSubpixelOrder = SubPixelVerticalRGB; + else if (!strcmp (rgba, "vbgr")) + kdSubpixelOrder = SubPixelVerticalBGR; + else if (!strcmp (rgba, "none")) + kdSubpixelOrder = SubPixelNone; + else + kdSubpixelOrder = SubPixelUnknown; +} + +void +KdUseMsg (void) +{ + ErrorF("\nTinyX Device Dependent Usage:\n"); + ErrorF("-card pcmcia Use PCMCIA card as additional screen\n"); + ErrorF("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM][@ROTATION][X][Y][xDEPTH/BPP{,DEPTH/BPP}[xFREQ]] Specify screen characteristics\n"); + ErrorF("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\n"); + ErrorF("-mouse driver [,n,,options] Specify the pointer driver and its options (n is the number of buttons)\n"); + ErrorF("-keybd driver [,,options] Specify the keyboard driver and its options\n"); + ErrorF("-zaphod Disable cursor screen switching\n"); + ErrorF("-2button Emulate 3 button mouse\n"); + ErrorF("-3button Disable 3 button mouse emulation\n"); + ErrorF("-rawcoord Don't transform pointer coordinates on rotation\n"); + ErrorF("-dumb Disable hardware acceleration\n"); + ErrorF("-softCursor Force software cursor\n"); + ErrorF("-videoTest Start the server, pause momentarily and exit\n"); + ErrorF("-origin X,Y Locates the next screen in the the virtual screen (Xinerama)\n"); + ErrorF("-switchCmd Command to execute on vt switch\n"); + ErrorF("-nozap Don't terminate server on Ctrl+Alt+Backspace\n"); + ErrorF("vtxx Use virtual terminal xx instead of the next available\n"); +#ifdef PSEUDO8 + p8UseMsg (); +#endif +} + +int +KdProcessArgument (int argc, char **argv, int i) +{ + KdCardInfo *card; + KdScreenInfo *screen; + + if (!strcmp (argv[i], "-card")) + { + if ((i+1) < argc) + InitCard (argv[i+1]); + else + UseMsg (); + return 2; + } + if (!strcmp (argv[i], "-screen")) + { + if ((i+1) < argc) + { + card = KdCardInfoLast (); + if (!card) + { + InitCard (0); + card = KdCardInfoLast (); + } + if (card) { + screen = KdScreenInfoAdd (card); + KdParseScreen (screen, argv[i+1]); + } else + ErrorF("No matching card found!\n"); + } + else + UseMsg (); + return 2; + } + if (!strcmp (argv[i], "-zaphod")) + { + kdDisableZaphod = TRUE; + return 1; + } + if (!strcmp (argv[i], "-nozap")) + { + kdDontZap = TRUE; + return 1; + } + if (!strcmp (argv[i], "-3button")) + { + kdEmulateMiddleButton = FALSE; + return 1; + } + if (!strcmp (argv[i], "-2button")) + { + kdEmulateMiddleButton = TRUE; + return 1; + } + if (!strcmp (argv[i], "-rawcoord")) + { + kdRawPointerCoordinates = 1; + return 1; + } + if (!strcmp (argv[i], "-dumb")) + { + kdDumbDriver = TRUE; + return 1; + } + if (!strcmp (argv[i], "-softCursor")) + { + kdSoftCursor = TRUE; + return 1; + } + if (!strcmp (argv[i], "-videoTest")) + { + kdVideoTest = TRUE; + return 1; + } + if (!strcmp (argv[i], "-origin")) + { + if ((i+1) < argc) + { + char *x = argv[i+1]; + char *y = strchr (x, ','); + if (x) + kdOrigin.x = atoi (x); + else + kdOrigin.x = 0; + if (y) + kdOrigin.y = atoi(y+1); + else + kdOrigin.y = 0; + } + else + UseMsg (); + return 2; + } + if (!strcmp (argv[i], "-rgba")) + { + if ((i+1) < argc) + KdParseRgba (argv[i+1]); + else + UseMsg (); + return 2; + } + if (!strcmp (argv[i], "-switchCmd")) + { + if ((i+1) < argc) + kdSwitchCmd = argv[i+1]; + else + UseMsg (); + return 2; + } + if (!strncmp (argv[i], "vt", 2) && + sscanf (argv[i], "vt%2d", &kdVirtualTerminal) == 1) + { + return 1; + } + if (!strcmp (argv[i], "-mouse") || + !strcmp (argv[i], "-pointer")) { + if (i + 1 >= argc) + UseMsg(); + KdAddConfigPointer(argv[i + 1]); + kdHasPointer = TRUE; + return 2; + } + if (!strcmp (argv[i], "-keybd")) { + if (i + 1 >= argc) + UseMsg(); + KdAddConfigKeyboard(argv[i + 1]); + kdHasKbd = TRUE; + return 2; + } + +#ifdef PSEUDO8 + return p8ProcessArgument (argc, argv, i); +#else + return 0; +#endif +} + +/* + * These are getting tossed in here until I can think of where + * they really belong + */ + +void +KdOsInit (KdOsFuncs *pOsFuncs) +{ + kdOsFuncs = pOsFuncs; + if (pOsFuncs) + { + if (serverGeneration == 1) + { + KdDoSwitchCmd ("start"); + if (pOsFuncs->Init) + (*pOsFuncs->Init) (); + } + } +} + +Bool +KdAllocatePrivates (ScreenPtr pScreen) +{ + KdPrivScreenPtr pScreenPriv; + + if (kdGeneration != serverGeneration) + kdGeneration = serverGeneration; + + pScreenPriv = (KdPrivScreenPtr) xalloc(sizeof (*pScreenPriv)); + if (!pScreenPriv) + return FALSE; + memset (pScreenPriv, '\0', sizeof (KdPrivScreenRec)); + KdSetScreenPriv (pScreen, pScreenPriv); + return TRUE; +} + +Bool +KdCreateScreenResources (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdCardInfo *card = pScreenPriv->card; + Bool ret; + + pScreen->CreateScreenResources = pScreenPriv->CreateScreenResources; + if(pScreen->CreateScreenResources) + ret = (*pScreen->CreateScreenResources) (pScreen); + else + ret= -1; + pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = KdCreateScreenResources; + if (ret && card->cfuncs->createRes) + ret = (*card->cfuncs->createRes) (pScreen); + return ret; +} + +Bool +KdCloseScreen (int index, ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + KdCardInfo *card = pScreenPriv->card; + Bool ret; + + pScreenPriv->closed = TRUE; + pScreen->CloseScreen = pScreenPriv->CloseScreen; + if(pScreen->CloseScreen) + ret = (*pScreen->CloseScreen) (index, pScreen); + else + ret = TRUE; + + if (screen->off_screen_base < screen->memory_size) + KdOffscreenFini (pScreen); + + if (pScreenPriv->dpmsState != KD_DPMS_NORMAL) + (*card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL); + + if (screen->mynum == card->selected) + KdDisableScreen (pScreen); + + /* + * Restore video hardware when last screen is closed + */ + if (screen == card->screenList) + { + if (kdEnabled && card->cfuncs->restore) + (*card->cfuncs->restore) (card); + } + + if (!pScreenPriv->screen->dumb && card->cfuncs->finiAccel) + (*card->cfuncs->finiAccel) (pScreen); + + if (!pScreenPriv->screen->softCursor && card->cfuncs->finiCursor) + (*card->cfuncs->finiCursor) (pScreen); + + if(card->cfuncs->scrfini) + (*card->cfuncs->scrfini) (screen); + + /* + * Clean up card when last screen is closed, DIX closes them in + * reverse order, thus we check for when the first in the list is closed + */ + if (screen == card->screenList) + { + if(card->cfuncs->cardfini) + (*card->cfuncs->cardfini) (card); + /* + * Clean up OS when last card is closed + */ + if (card == kdCardInfo) + { + if (kdEnabled) + { + kdEnabled = FALSE; + if(kdOsFuncs->Disable) + (*kdOsFuncs->Disable) (); + } + } + } + + pScreenPriv->screen->pScreen = 0; + + xfree ((pointer) pScreenPriv); + return ret; +} + +Bool +KdSaveScreen (ScreenPtr pScreen, int on) +{ + KdScreenPriv(pScreen); + int dpmsState; + + if (!pScreenPriv->card->cfuncs->dpms) + return FALSE; + + dpmsState = pScreenPriv->dpmsState; + switch (on) { + case SCREEN_SAVER_OFF: + dpmsState = KD_DPMS_NORMAL; + break; + case SCREEN_SAVER_ON: + if (dpmsState == KD_DPMS_NORMAL) + dpmsState = KD_DPMS_NORMAL+1; + break; + case SCREEN_SAVER_CYCLE: + if (dpmsState < KD_DPMS_MAX) + dpmsState++; + break; + case SCREEN_SAVER_FORCER: + break; + } + if (dpmsState != pScreenPriv->dpmsState) + { + if (pScreenPriv->enabled) + (*pScreenPriv->card->cfuncs->dpms) (pScreen, dpmsState); + pScreenPriv->dpmsState = dpmsState; + } + return TRUE; +} + +static Bool +KdCreateWindow (WindowPtr pWin) +{ +#ifndef PHOENIX + if (!pWin->parent) + { + KdScreenPriv(pWin->drawable.pScreen); + + if (!pScreenPriv->enabled) + { + REGION_EMPTY (pWin->drawable.pScreen, &pWin->borderClip); + REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); + } + } +#endif + return fbCreateWindow (pWin); +} + +void +KdSetSubpixelOrder (ScreenPtr pScreen, Rotation randr) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + int subpixel_order = screen->subpixel_order; + Rotation subpixel_dir; + int i; + + static struct { + int subpixel_order; + Rotation direction; + } orders[] = { + { SubPixelHorizontalRGB, RR_Rotate_0 }, + { SubPixelHorizontalBGR, RR_Rotate_180 }, + { SubPixelVerticalRGB, RR_Rotate_270 }, + { SubPixelVerticalBGR, RR_Rotate_90 }, + }; + + static struct { + int bit; + int normal; + int reflect; + } reflects[] = { + { RR_Reflect_X, SubPixelHorizontalRGB, SubPixelHorizontalBGR }, + { RR_Reflect_X, SubPixelHorizontalBGR, SubPixelHorizontalRGB }, + { RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalBGR }, + { RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalRGB }, + }; + + /* map subpixel to direction */ + for (i = 0; i < 4; i++) + if (orders[i].subpixel_order == subpixel_order) + break; + if (i < 4) + { + subpixel_dir = KdAddRotation (randr & RR_Rotate_All, orders[i].direction); + + /* map back to subpixel order */ + for (i = 0; i < 4; i++) + if (orders[i].direction & subpixel_dir) + { + subpixel_order = orders[i].subpixel_order; + break; + } + /* reflect */ + for (i = 0; i < 4; i++) + if ((randr & reflects[i].bit) && + reflects[i].normal == subpixel_order) + { + subpixel_order = reflects[i].reflect; + break; + } + } + PictureSetSubpixelOrder (pScreen, subpixel_order); +} + +/* Pass through AddScreen, which doesn't take any closure */ +static KdScreenInfo *kdCurrentScreen; + +Bool +KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) +{ + KdScreenInfo *screen = kdCurrentScreen; + KdCardInfo *card = screen->card; + KdPrivScreenPtr pScreenPriv; + int fb; + /* + * note that screen->fb is set up for the nominal orientation + * of the screen; that means if randr is rotated, the values + * there should reflect a rotated frame buffer (or shadow). + */ + Bool rotated = (screen->randr & (RR_Rotate_90|RR_Rotate_270)) != 0; + int width, height, *width_mmp, *height_mmp; + + KdAllocatePrivates (pScreen); + + pScreenPriv = KdGetScreenPriv(pScreen); + + if (!rotated) + { + width = screen->width; + height = screen->height; + width_mmp = &screen->width_mm; + height_mmp = &screen->height_mm; + } + else + { + width = screen->height; + height = screen->width; + width_mmp = &screen->height_mm; + height_mmp = &screen->width_mm; + } + screen->pScreen = pScreen; + pScreenPriv->screen = screen; + pScreenPriv->card = card; + for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++) + pScreenPriv->bytesPerPixel[fb] = screen->fb[fb].bitsPerPixel >> 3; + pScreenPriv->dpmsState = KD_DPMS_NORMAL; +#ifdef PANORAMIX + dixScreenOrigins[pScreen->myNum] = screen->origin; +#endif + + if (!monitorResolution) + monitorResolution = 75; + /* + * This is done in this order so that backing store wraps + * our GC functions; fbFinishScreenInit initializes MI + * backing store + */ + if (!fbSetupScreen (pScreen, + screen->fb[0].frameBuffer, + width, height, + monitorResolution, monitorResolution, + screen->fb[0].pixelStride, + screen->fb[0].bitsPerPixel)) + { + return FALSE; + } + + /* + * Set colormap functions + */ + pScreen->InstallColormap = KdInstallColormap; + pScreen->UninstallColormap = KdUninstallColormap; + pScreen->ListInstalledColormaps = KdListInstalledColormaps; + pScreen->StoreColors = KdStoreColors; + + pScreen->SaveScreen = KdSaveScreen; + pScreen->CreateWindow = KdCreateWindow; + +#if KD_MAX_FB > 1 + if (screen->fb[1].depth) + { + if (!fbOverlayFinishScreenInit (pScreen, + screen->fb[0].frameBuffer, + screen->fb[1].frameBuffer, + width, height, + monitorResolution, monitorResolution, + screen->fb[0].pixelStride, + screen->fb[1].pixelStride, + screen->fb[0].bitsPerPixel, + screen->fb[1].bitsPerPixel, + screen->fb[0].depth, + screen->fb[1].depth)) + { + return FALSE; + } + } + else +#endif + { + if (!fbFinishScreenInit (pScreen, + screen->fb[0].frameBuffer, + width, height, + monitorResolution, monitorResolution, + screen->fb[0].pixelStride, + screen->fb[0].bitsPerPixel)) + { + return FALSE; + } + } + + /* + * Fix screen sizes; for some reason mi takes dpi instead of mm. + * Rounding errors are annoying + */ + if (*width_mmp) + pScreen->mmWidth = *width_mmp; + else + *width_mmp = pScreen->mmWidth; + if (*height_mmp) + pScreen->mmHeight = *height_mmp; + else + *height_mmp = pScreen->mmHeight; + + /* + * Plug in our own block/wakeup handlers. + * miScreenInit installs NoopDDA in both places + */ + pScreen->BlockHandler = KdBlockHandler; + pScreen->WakeupHandler = KdWakeupHandler; + +#ifdef RENDER + if (!fbPictureInit (pScreen, 0, 0)) + return FALSE; +#endif + if (card->cfuncs->initScreen) + if (!(*card->cfuncs->initScreen) (pScreen)) + return FALSE; + + if (!screen->dumb && card->cfuncs->initAccel) + if (!(*card->cfuncs->initAccel) (pScreen)) + screen->dumb = TRUE; + + if (screen->off_screen_base < screen->memory_size) + KdOffscreenInit (pScreen); + +#ifdef PSEUDO8 + (void) p8Init (pScreen, PSEUDO8_USE_DEFAULT); +#endif + + if (card->cfuncs->finishInitScreen) + if (!(*card->cfuncs->finishInitScreen) (pScreen)) + return FALSE; + +#if 0 + fbInitValidateTree (pScreen); +#endif + +#if 0 + pScreen->backingStoreSupport = Always; + miInitializeBackingStore (pScreen); +#endif + + + /* + * Wrap CloseScreen, the order now is: + * KdCloseScreen + * miBSCloseScreen + * fbCloseScreen + */ + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = KdCloseScreen; + + pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = KdCreateScreenResources; + + if (screen->softCursor || + !card->cfuncs->initCursor || + !(*card->cfuncs->initCursor) (pScreen)) + { + /* Use MI for cursor display and event queueing. */ + screen->softCursor = TRUE; + miDCInitialize(pScreen, &kdPointerScreenFuncs); + } + + + if (!fbCreateDefColormap (pScreen)) + { + return FALSE; + } + + KdSetSubpixelOrder (pScreen, screen->randr); + + /* + * Enable the hardware + */ + if (!kdEnabled) + { + kdEnabled = TRUE; + if(kdOsFuncs->Enable) + (*kdOsFuncs->Enable) (); + } + + if (screen->mynum == card->selected) + { + if(card->cfuncs->preserve) + (*card->cfuncs->preserve) (card); + if(card->cfuncs->enable) + if (!(*card->cfuncs->enable) (pScreen)) + return FALSE; + pScreenPriv->enabled = TRUE; + if (!screen->softCursor && card->cfuncs->enableCursor) + (*card->cfuncs->enableCursor) (pScreen); + KdEnableColormap (pScreen); + if (!screen->dumb && card->cfuncs->enableAccel) + (*card->cfuncs->enableAccel) (pScreen); + } + + return TRUE; +} + +void +KdInitScreen (ScreenInfo *pScreenInfo, + KdScreenInfo *screen, + int argc, + char **argv) +{ + KdCardInfo *card = screen->card; + + (*card->cfuncs->scrinit) (screen); + + if (!card->cfuncs->initAccel) + screen->dumb = TRUE; + if (!card->cfuncs->initCursor) + screen->softCursor = TRUE; +} + +static Bool +KdSetPixmapFormats (ScreenInfo *pScreenInfo) +{ + CARD8 depthToBpp[33]; /* depth -> bpp map */ + KdCardInfo *card; + KdScreenInfo *screen; + int i; + int bpp; + int fb; + PixmapFormatRec *format; + + for (i = 1; i <= 32; i++) + depthToBpp[i] = 0; + + /* + * Generate mappings between bitsPerPixel and depth, + * also ensure that all screens comply with protocol + * restrictions on equivalent formats for the same + * depth on different screens + */ + for (card = kdCardInfo; card; card = card->next) + { + for (screen = card->screenList; screen; screen = screen->next) + { + for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++) + { + bpp = screen->fb[fb].bitsPerPixel; + if (bpp == 24) + bpp = 32; + if (!depthToBpp[screen->fb[fb].depth]) + depthToBpp[screen->fb[fb].depth] = bpp; + else if (depthToBpp[screen->fb[fb].depth] != bpp) + return FALSE; + } + } + } + + /* + * Fill in additional formats + */ + for (i = 0; i < NUM_KD_DEPTHS; i++) + if (!depthToBpp[kdDepths[i].depth]) + depthToBpp[kdDepths[i].depth] = kdDepths[i].bpp; + + pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER; + pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; + + pScreenInfo->numPixmapFormats = 0; + + for (i = 1; i <= 32; i++) + { + if (depthToBpp[i]) + { + format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats++]; + format->depth = i; + format->bitsPerPixel = depthToBpp[i]; + format->scanlinePad = BITMAP_SCANLINE_PAD; + } + } + + return TRUE; +} + +static void +KdAddScreen (ScreenInfo *pScreenInfo, + KdScreenInfo *screen, + int argc, + char **argv) +{ + int i; + /* + * Fill in fb visual type masks for this screen + */ + for (i = 0; i < pScreenInfo->numPixmapFormats; i++) + { + unsigned long visuals; + Pixel rm, gm, bm; + int fb; + + visuals = 0; + rm = gm = bm = 0; + for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++) + { + if (pScreenInfo->formats[i].depth == screen->fb[fb].depth) + { + visuals = screen->fb[fb].visuals; + rm = screen->fb[fb].redMask; + gm = screen->fb[fb].greenMask; + bm = screen->fb[fb].blueMask; + break; + } + } + fbSetVisualTypesAndMasks (pScreenInfo->formats[i].depth, + visuals, + 8, + rm, gm, bm); + } + + kdCurrentScreen = screen; + + AddScreen (KdScreenInit, argc, argv); +} + +#if 0 /* This function is not used currently */ + +int +KdDepthToFb (ScreenPtr pScreen, int depth) +{ + KdScreenPriv(pScreen); + int fb; + + for (fb = 0; fb <= KD_MAX_FB && pScreenPriv->screen->fb[fb].frameBuffer; fb++) + if (pScreenPriv->screen->fb[fb].depth == depth) + return fb; +} + +#endif + +#ifdef HAVE_BACKTRACE +/* shamelessly ripped from xf86Events.c */ +void +KdBacktrace (int signum) +{ + void *array[32]; /* more than 32 and you have bigger problems */ + size_t size, i; + char **strings; + + signal(signum, SIG_IGN); + + size = backtrace (array, 32); + fprintf (stderr, "\nBacktrace (%d deep):\n", size); + strings = backtrace_symbols (array, size); + for (i = 0; i < size; i++) + fprintf (stderr, "%d: %s\n", i, strings[i]); + free (strings); + + kdCaughtSignal = TRUE; + if (signum == SIGSEGV) + FatalError("Segmentation fault caught\n"); + else if (signum > 0) + FatalError("Signal %d caught\n", signum); +} +#else +void +KdBacktrace (int signum) +{ + kdCaughtSignal = TRUE; + FatalError("Segmentation fault caught\n"); +} +#endif + +void +KdInitOutput (ScreenInfo *pScreenInfo, + int argc, + char **argv) +{ + KdCardInfo *card; + KdScreenInfo *screen; + + if (!kdCardInfo) + { + InitCard (0); + if (!(card = KdCardInfoLast ())) + FatalError("No matching cards found!\n"); + screen = KdScreenInfoAdd (card); + KdParseScreen (screen, 0); + } + /* + * Initialize all of the screens for all of the cards + */ + for (card = kdCardInfo; card; card = card->next) + { + int ret=1; + if(card->cfuncs->cardinit) + ret=(*card->cfuncs->cardinit) (card); + if (ret) + { + for (screen = card->screenList; screen; screen = screen->next) + KdInitScreen (pScreenInfo, screen, argc, argv); + } + } + + /* + * Merge the various pixmap formats together, this can fail + * when two screens share depth but not bitsPerPixel + */ + if (!KdSetPixmapFormats (pScreenInfo)) + return; + + /* + * Add all of the screens + */ + for (card = kdCardInfo; card; card = card->next) + for (screen = card->screenList; screen; screen = screen->next) + KdAddScreen (pScreenInfo, screen, argc, argv); + + signal(SIGSEGV, KdBacktrace); +} + +#ifdef DPMSExtension +int +DPMSSet(ClientPtr client, int level) +{ +} + +int +DPMSGet (int *level) +{ + return -1; +} + +Bool +DPMSSupported (void) +{ + return FALSE; +} +#endif + +void ddxInitGlobals(void) { /* THANK YOU XPRINT */ } + diff --git a/xorg-server/hw/kdrive/src/kdrive.h b/xorg-server/hw/kdrive/src/kdrive.h new file mode 100644 index 000000000..4e04b59f7 --- /dev/null +++ b/xorg-server/hw/kdrive/src/kdrive.h @@ -0,0 +1,1000 @@ +/* + * 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. + */ + +#ifndef _KDRIVE_H_ +#define _KDRIVE_H_ + +#include <stdio.h> +#include <X11/X.h> +#define NEED_EVENTS +#include <X11/Xproto.h> +#include <X11/Xos.h> +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "servermd.h" +#include "mibstore.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 "shadow.h" +#include "randrstr.h" + +#ifdef XKB +#include <X11/extensions/XKBstr.h> +#endif + +extern WindowPtr *WindowTable; + +#define KD_DPMS_NORMAL 0 +#define KD_DPMS_STANDBY 1 +#define KD_DPMS_SUSPEND 2 +#define KD_DPMS_POWERDOWN 3 +#define KD_DPMS_MAX KD_DPMS_POWERDOWN + +#ifndef KD_MAX_FB +#define KD_MAX_FB FB_OVERLAY_MAX +#endif + +#ifndef KD_MAX_CARD_ADDRESS +#define KD_MAX_CARD_ADDRESS 8 +#endif + +#define Status int + +/* + * Configuration information per video card + */ + +typedef struct _KdCardAttr { + CARD32 io; + CARD32 address[KD_MAX_CARD_ADDRESS]; + int naddr; + + /* PCI bus info */ + CARD16 vendorID; + CARD16 deviceID; + CARD8 domain; + CARD8 bus; + CARD8 slot; + CARD8 func; +} KdCardAttr; + +typedef struct _KdCardInfo { + struct _KdCardFuncs *cfuncs; + void *closure; + KdCardAttr attr; + void *driver; + struct _KdScreenInfo *screenList; + int selected; + struct _KdCardInfo *next; + + Bool needSync; + int lastMarker; +} KdCardInfo; + +extern KdCardInfo *kdCardInfo; + +/* + * Configuration information per X screen + */ +typedef struct _KdFrameBuffer { + CARD8 *frameBuffer; + int depth; + int bitsPerPixel; + int pixelStride; + int byteStride; + Bool shadow; + unsigned long visuals; + Pixel redMask, greenMask, blueMask; + void *closure; +} KdFrameBuffer; + +typedef struct _KdOffscreenArea KdOffscreenArea; + +typedef void (*KdOffscreenSaveProc) (ScreenPtr pScreen, KdOffscreenArea *area); + +typedef enum _KdOffscreenState { + KdOffscreenAvail, + KdOffscreenRemovable, + KdOffscreenLocked, +} KdOffscreenState; + +struct _KdOffscreenArea { + int offset; + int save_offset; + int size; + int score; + pointer privData; + + KdOffscreenSaveProc save; + + KdOffscreenState state; + + KdOffscreenArea *next; +}; + +#define RR_Rotate_All (RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270) +#define RR_Reflect_All (RR_Reflect_X|RR_Reflect_Y) + +typedef struct _KdScreenInfo { + struct _KdScreenInfo *next; + KdCardInfo *card; + ScreenPtr pScreen; + void *driver; + Rotation randr; /* rotation and reflection */ + int width; + int height; + int rate; + int width_mm; + int height_mm; + int subpixel_order; + Bool dumb; + Bool softCursor; + int mynum; + DDXPointRec origin; + KdFrameBuffer fb[KD_MAX_FB]; + CARD8 *memory_base; + unsigned long memory_size; + unsigned long off_screen_base; +} KdScreenInfo; + +typedef struct _KdCardFuncs { + Bool (*cardinit) (KdCardInfo *); /* detect and map device */ + Bool (*scrinit) (KdScreenInfo *);/* initialize screen information */ + Bool (*initScreen) (ScreenPtr); /* initialize ScreenRec */ + Bool (*finishInitScreen) (ScreenPtr pScreen); + Bool (*createRes) (ScreenPtr); /* create screen resources */ + void (*preserve) (KdCardInfo *); /* save graphics card state */ + Bool (*enable) (ScreenPtr); /* set up for rendering */ + Bool (*dpms) (ScreenPtr, int); /* set DPMS screen saver */ + void (*disable) (ScreenPtr); /* turn off rendering */ + void (*restore) (KdCardInfo *); /* restore graphics card state */ + void (*scrfini) (KdScreenInfo *);/* close down screen */ + void (*cardfini) (KdCardInfo *); /* close down */ + + Bool (*initCursor) (ScreenPtr); /* detect and map cursor */ + void (*enableCursor) (ScreenPtr); /* enable cursor */ + void (*disableCursor) (ScreenPtr); /* disable cursor */ + void (*finiCursor) (ScreenPtr); /* close down */ + void (*recolorCursor) (ScreenPtr, int, xColorItem *); + + Bool (*initAccel) (ScreenPtr); + void (*enableAccel) (ScreenPtr); + void (*disableAccel) (ScreenPtr); + void (*finiAccel) (ScreenPtr); + + void (*getColors) (ScreenPtr, int, int, xColorItem *); + void (*putColors) (ScreenPtr, int, int, xColorItem *); + +} KdCardFuncs; + +#define KD_MAX_PSEUDO_DEPTH 8 +#define KD_MAX_PSEUDO_SIZE (1 << KD_MAX_PSEUDO_DEPTH) + +typedef struct { + KdScreenInfo *screen; + KdCardInfo *card; + + Bool enabled; + Bool closed; + int bytesPerPixel[KD_MAX_FB]; + + int dpmsState; + + KdOffscreenArea *off_screen_areas; + + ColormapPtr pInstalledmap[KD_MAX_FB]; /* current colormap */ + xColorItem systemPalette[KD_MAX_PSEUDO_SIZE];/* saved windows colors */ + + CreateScreenResourcesProcPtr CreateScreenResources; + CloseScreenProcPtr CloseScreen; +} KdPrivScreenRec, *KdPrivScreenPtr; + +typedef enum _kdPointerState { + start, + button_1_pend, + button_1_down, + button_2_down, + button_3_pend, + button_3_down, + synth_2_down_13, + synth_2_down_3, + synth_2_down_1, + num_input_states +} KdPointerState; + +#define KD_MAX_BUTTON 32 + +#define KD_KEYBOARD 1 +#define KD_MOUSE 2 +#define KD_TOUCHSCREEN 3 + +typedef struct _KdPointerInfo KdPointerInfo; + +typedef struct _KdPointerDriver { + char *name; + Status (*Init) (KdPointerInfo *); + Status (*Enable) (KdPointerInfo *); + void (*Disable) (KdPointerInfo *); + void (*Fini) (KdPointerInfo *); + struct _KdPointerDriver *next; +} KdPointerDriver; + +struct _KdPointerInfo { + DeviceIntPtr dixdev; + char *name; + char *path; + InputOption *options; + int inputClass; + + CARD8 map[KD_MAX_BUTTON + 1]; + int nButtons; + int nAxes; + + Bool emulateMiddleButton; + unsigned long emulationTimeout; + int emulationDx, emulationDy; + + Bool timeoutPending; + KdPointerState mouseState; + Bool eventHeld; + struct { + int type; + int x; + int y; + int z; + int flags; + int absrel; + } heldEvent; + unsigned char buttonState; + Bool transformCoordinates; + int pressureThreshold; + + KdPointerDriver *driver; + void *driverPrivate; + + struct _KdPointerInfo *next; +}; + +extern int KdCurScreen; + +void KdAddPointerDriver (KdPointerDriver *driver); +void KdRemovePointerDriver (KdPointerDriver *driver); +KdPointerInfo *KdNewPointer (void); +void KdFreePointer (KdPointerInfo *); +int KdAddPointer (KdPointerInfo *ki); +int KdAddConfigPointer (char *pointer); +void KdRemovePointer (KdPointerInfo *ki); + + +#define KD_KEY_COUNT 248 +#define KD_MIN_KEYCODE 8 +#define KD_MAX_KEYCODE 255 +#define KD_MAX_WIDTH 4 +#define KD_MAX_LENGTH (KD_MAX_KEYCODE - KD_MIN_KEYCODE + 1) + +typedef struct { + KeySym modsym; + int modbit; +} KdKeySymModsRec; + +extern const KeySym kdDefaultKeymap[KD_MAX_LENGTH * KD_MAX_WIDTH]; +extern const int kdDefaultKeymapWidth; +extern const CARD8 kdDefaultModMap[MAP_LENGTH]; +extern const KeySymsRec kdDefaultKeySyms; + +typedef struct _KdKeyboardInfo KdKeyboardInfo; + +typedef struct _KdKeyboardDriver { + char *name; + Bool (*Init) (KdKeyboardInfo *); + Bool (*Enable) (KdKeyboardInfo *); + void (*Leds) (KdKeyboardInfo *, int); + void (*Bell) (KdKeyboardInfo *, int, int, int); + void (*Disable) (KdKeyboardInfo *); + void (*Fini) (KdKeyboardInfo *); + struct _KdKeyboardDriver *next; +} KdKeyboardDriver; + +struct _KdKeyboardInfo { + struct _KdKeyboardInfo *next; + DeviceIntPtr dixdev; + void *closure; + char *name; + char *path; + int inputClass; +#ifdef XKB + XkbDescPtr xkb; + char *xkbRules; + char *xkbModel; + char *xkbLayout; + char *xkbVariant; + char *xkbOptions; +#endif + int LockLed; + + CARD8 keyState[KD_KEY_COUNT/8]; + int minScanCode; + int maxScanCode; + CARD8 modmap[MAP_LENGTH]; + KeySymsRec keySyms; + + int leds; + int bellPitch; + int bellDuration; + InputOption *options; + + KdKeyboardDriver *driver; + void *driverPrivate; +}; + +void KdAddKeyboardDriver (KdKeyboardDriver *driver); +void KdRemoveKeyboardDriver (KdKeyboardDriver *driver); +KdKeyboardInfo *KdNewKeyboard (void); +void KdFreeKeyboard (KdKeyboardInfo *ki); +int KdAddConfigKeyboard (char *pointer); +int KdAddKeyboard (KdKeyboardInfo *ki); +void KdRemoveKeyboard (KdKeyboardInfo *ki); + +typedef struct _KdOsFuncs { + int (*Init) (void); + void (*Enable) (void); + Bool (*SpecialKey) (KeySym); + void (*Disable) (void); + void (*Fini) (void); + void (*pollEvents) (void); + void (*Bell) (int, int, int); +} KdOsFuncs; + +typedef enum _KdSyncPolarity { + KdSyncNegative, KdSyncPositive +} KdSyncPolarity; + +typedef struct _KdMonitorTiming { + /* label */ + int horizontal; + int vertical; + int rate; + /* pixel clock */ + int clock; /* in KHz */ + /* horizontal timing */ + int hfp; /* front porch */ + int hbp; /* back porch */ + int hblank; /* blanking */ + KdSyncPolarity hpol; /* polarity */ + /* vertical timing */ + int vfp; /* front porch */ + int vbp; /* back porch */ + int vblank; /* blanking */ + KdSyncPolarity vpol; /* polarity */ +} KdMonitorTiming; + +extern const KdMonitorTiming kdMonitorTimings[]; +extern const int kdNumMonitorTimings; + +typedef struct _KdPointerMatrix { + int matrix[2][3]; +} KdPointerMatrix; + +typedef struct _KaaTrapezoid { + float tl, tr, ty; + float bl, br, by; +} KaaTrapezoid; + +typedef struct _KaaScreenInfo { + int offsetAlign; + int pitchAlign; + int flags; + + int (*markSync) (ScreenPtr pScreen); + void (*waitMarker) (ScreenPtr pScreen, int marker); + + Bool (*PrepareSolid) (PixmapPtr pPixmap, + int alu, + Pixel planemask, + Pixel fg); + void (*Solid) (int x1, int y1, int x2, int y2); + void (*DoneSolid) (void); + + Bool (*PrepareCopy) (PixmapPtr pSrcPixmap, + PixmapPtr pDstPixmap, + Bool upsidedown, + Bool reverse, + int alu, + Pixel planemask); + void (*Copy) (int srcX, + int srcY, + int dstX, + int dstY, + int width, + int height); + void (*DoneCopy) (void); + + Bool (*PrepareBlend) (int op, + PicturePtr pSrcPicture, + PicturePtr pDstPicture, + PixmapPtr pSrc, + PixmapPtr pDst); + void (*Blend) (int srcX, + int srcY, + int dstX, + int dstY, + int width, + int height); + void (*DoneBlend) (void); + + Bool (*CheckComposite) (int op, + PicturePtr pSrcPicture, + PicturePtr pMaskPicture, + PicturePtr pDstPicture); + Bool (*PrepareComposite) (int op, + PicturePtr pSrcPicture, + PicturePtr pMaskPicture, + PicturePtr pDstPicture, + PixmapPtr pSrc, + PixmapPtr pMask, + PixmapPtr pDst); + void (*Composite) (int srcX, + int srcY, + int maskX, + int maskY, + int dstX, + int dstY, + int width, + int height); + void (*DoneComposite) (void); + + Bool (*PrepareTrapezoids) (PicturePtr pDstPicture, + PixmapPtr pDst); + void (*Trapezoids) (KaaTrapezoid *traps, + int ntraps); + void (*DoneTrapezoids) (void); + + Bool (*UploadToScreen) (PixmapPtr pDst, + char *src, + int src_pitch); + Bool (*UploadToScratch) (PixmapPtr pSrc, + PixmapPtr pDst); +} KaaScreenInfoRec, *KaaScreenInfoPtr; + +#define KAA_OFFSCREEN_PIXMAPS (1 << 0) +#define KAA_OFFSCREEN_ALIGN_POT (1 << 1) + +/* + * This is the only completely portable way to + * compute this info. + */ + +#ifndef BitsPerPixel +#define BitsPerPixel(d) (\ + PixmapWidthPaddingInfo[d].notPower2 ? \ + (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \ + ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \ + (PixmapWidthPaddingInfo[d].padRoundUp+1))) +#endif + +extern DevPrivateKey kdScreenPrivateKey; +extern unsigned long kdGeneration; +extern Bool kdEnabled; +extern Bool kdSwitchPending; +extern Bool kdEmulateMiddleButton; +extern Bool kdDisableZaphod; +extern Bool kdDontZap; +extern int kdVirtualTerminal; +extern char *kdSwitchCmd; +extern KdOsFuncs *kdOsFuncs; + +#define KdGetScreenPriv(pScreen) ((KdPrivScreenPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, kdScreenPrivateKey)) +#define KdSetScreenPriv(pScreen,v) \ + dixSetPrivate(&(pScreen)->devPrivates, kdScreenPrivateKey, v) +#define KdScreenPriv(pScreen) KdPrivScreenPtr pScreenPriv = KdGetScreenPriv(pScreen) + +/* kaa.c */ +Bool +kaaDrawInit (ScreenPtr pScreen, + KaaScreenInfoPtr pScreenInfo); + +void +kaaDrawFini (ScreenPtr pScreen); + +void +kaaWrapGC (GCPtr pGC); + +void +kaaUnwrapGC (GCPtr pGC); + +/* kasync.c */ +void +KdCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans, + DDXPointPtr ppt, int *pwidth, int fSorted); + +void +KdCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc, + DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); + +void +KdCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, + int x, int y, int w, int h, int leftPad, int format, + char *bits); + +RegionPtr +KdCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, int dstx, int dsty); + +RegionPtr +KdCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, int dstx, int dsty, + unsigned long bitPlane); + +void +KdCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr pptInit); + +void +KdCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr ppt); + +void +KdCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, + int nsegInit, xSegment *pSegInit); + +void +KdCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC, + int nrects, xRectangle *prect); + +void +KdCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, + int narcs, xArc *pArcs); + +#define KdCheckFillPolygon miFillPolygon + +void +KdCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, + int nrect, xRectangle *prect); + +void +KdCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC, + int narcs, xArc *pArcs); + +void +KdCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase); + +void +KdCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase); + +void +KdCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, + DrawablePtr pDrawable, + int w, int h, int x, int y); + +void +KdCheckGetImage (DrawablePtr pDrawable, + int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, + char *d); + +void +KdCheckGetSpans (DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pdstStart); + +void +KdCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); + +void +KdCheckPaintKey(DrawablePtr pDrawable, + RegionPtr pRegion, + CARD32 pixel, + int layer); + +void +KdCheckOverlayCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); + +void +KdScreenInitAsync (ScreenPtr pScreen); + +extern const GCOps kdAsyncPixmapGCOps; + +/* knoop.c */ +extern GCOps kdNoopOps; + +/* kcmap.c */ +void +KdSetColormap (ScreenPtr pScreen, int fb); + +void +KdEnableColormap (ScreenPtr pScreen); + +void +KdDisableColormap (ScreenPtr pScreen); + +void +KdInstallColormap (ColormapPtr pCmap); + +void +KdUninstallColormap (ColormapPtr pCmap); + +int +KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps); + +void +KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs); + +/* kcurscol.c */ +void +KdAllocateCursorPixels (ScreenPtr pScreen, + int fb, + CursorPtr pCursor, + Pixel *source, + Pixel *mask); + +/* kdrive.c */ +extern miPointerScreenFuncRec kdPointerScreenFuncs; + +void +KdSetRootClip (ScreenPtr pScreen, BOOL enable); + +void +KdDisableScreen (ScreenPtr pScreen); + +void +KdDisableScreens (void); + +Bool +KdEnableScreen (ScreenPtr pScreen); + +void +KdEnableScreens (void); + +void +KdSuspend (void); + +void +KdResume (void); + +void +KdProcessSwitch (void); + +Rotation +KdAddRotation (Rotation a, Rotation b); + +Rotation +KdSubRotation (Rotation a, Rotation b); + +void +KdParseScreen (KdScreenInfo *screen, + char *arg); + +char * +KdSaveString (char *str); + +KdPointerInfo * +KdParsePointer (char *arg); + +KdKeyboardInfo * +KdParseKeyboard (char *arg); + +char * +KdParseFindNext (char *cur, char *delim, char *save, char *last); + +void +KdParseRgba (char *rgba); + +void +KdUseMsg (void); + +int +KdProcessArgument (int argc, char **argv, int i); + +void +KdOsInit (KdOsFuncs *pOsFuncs); + +void +KdOsAddInputDrivers (void); + +Bool +KdAllocatePrivates (ScreenPtr pScreen); + +Bool +KdCreateScreenResources (ScreenPtr pScreen); + +Bool +KdCloseScreen (int index, ScreenPtr pScreen); + +Bool +KdSaveScreen (ScreenPtr pScreen, int on); + +Bool +KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv); + +void +KdInitScreen (ScreenInfo *pScreenInfo, + KdScreenInfo *screen, + int argc, + char **argv); + +void +KdInitCard (ScreenInfo *pScreenInfo, + KdCardInfo *card, + int argc, + char **argv); + +void +KdInitOutput (ScreenInfo *pScreenInfo, + int argc, + char **argv); + +void +KdSetSubpixelOrder (ScreenPtr pScreen, Rotation randr); + +void +KdBacktrace (int signum); + +/* kinfo.c */ +KdCardInfo * +KdCardInfoAdd (KdCardFuncs *funcs, + KdCardAttr *attr, + void *closure); + +KdCardInfo * +KdCardInfoLast (void); + +void +KdCardInfoDispose (KdCardInfo *ci); + +KdScreenInfo * +KdScreenInfoAdd (KdCardInfo *ci); + +void +KdScreenInfoDispose (KdScreenInfo *si); + + +/* kinput.c */ +void +KdInitInput(void); + +void +KdAddPointerDriver(KdPointerDriver *); + +void +KdAddKeyboardDriver(KdKeyboardDriver *); + +Bool +KdRegisterFd (int fd, void (*read) (int fd, void *closure), void *closure); + +void +KdUnregisterFds (void *closure, Bool do_close); + +void +KdUnregisterFd (void *closure, int fd, Bool do_close); + +void +KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, unsigned char scan_code, + unsigned char is_up); + +#define KD_BUTTON_1 0x01 +#define KD_BUTTON_2 0x02 +#define KD_BUTTON_3 0x04 +#define KD_BUTTON_4 0x08 +#define KD_BUTTON_5 0x10 +#define KD_BUTTON_8 0x80 +#define KD_MOUSE_DELTA 0x80000000 + +void +KdEnqueuePointerEvent(KdPointerInfo *pi, unsigned long flags, int rx, int ry, + int rz); + +void +_KdEnqueuePointerEvent(KdPointerInfo *pi, int type, int x, int y, int z, + int b, int absrel, Bool force); + +void +KdReleaseAllKeys (void); + +void +KdSetLed (KdKeyboardInfo *ki, int led, Bool on); + +void +KdSetPointerMatrix (KdPointerMatrix *pointer); + +void +KdComputePointerMatrix (KdPointerMatrix *pointer, Rotation randr, int width, int height); + +void +KdScreenToPointerCoords (int *x, int *y); + +void +KdBlockHandler (int screen, + pointer blockData, + pointer timeout, + pointer readmask); + +void +KdWakeupHandler (int screen, + pointer data, + unsigned long result, + pointer readmask); + +void +KdDisableInput (void); + +void +KdEnableInput (void); + +void +ProcessInputEvents (void); + +void +KdRingBell (KdKeyboardInfo *ki, + int volume, + int pitch, + int duration); + +extern KdPointerDriver LinuxMouseDriver; +extern KdPointerDriver LinuxEvdevMouseDriver; +extern KdPointerDriver Ps2MouseDriver; +extern KdPointerDriver BusMouseDriver; +extern KdPointerDriver MsMouseDriver; +extern KdPointerDriver TsDriver; +extern KdKeyboardDriver LinuxKeyboardDriver; +extern KdKeyboardDriver LinuxEvdevKeyboardDriver; +extern KdOsFuncs LinuxFuncs; + +extern KdPointerDriver VxWorksMouseDriver; +extern KdKeyboardDriver VxWorksKeyboardDriver; +extern KdOsFuncs VxWorksFuncs; + +/* kmap.c */ + +#define KD_MAPPED_MODE_REGISTERS 0 +#define KD_MAPPED_MODE_FRAMEBUFFER 1 + +void * +KdMapDevice (CARD32 addr, CARD32 size); + +void +KdUnmapDevice (void *addr, CARD32 size); + +void +KdSetMappedMode (CARD32 addr, CARD32 size, int mode); + +void +KdResetMappedMode (CARD32 addr, CARD32 size, int mode); + +/* kmode.c */ +const KdMonitorTiming * +KdFindMode (KdScreenInfo *screen, + Bool (*supported) (KdScreenInfo *, + const KdMonitorTiming *)); + +Bool +KdTuneMode (KdScreenInfo *screen, + Bool (*usable) (KdScreenInfo *), + Bool (*supported) (KdScreenInfo *, + const KdMonitorTiming *)); + +#ifdef RANDR +Bool +KdRandRGetInfo (ScreenPtr pScreen, + int randr, + Bool (*supported) (ScreenPtr pScreen, + const KdMonitorTiming *)); + +const KdMonitorTiming * +KdRandRGetTiming (ScreenPtr pScreen, + Bool (*supported) (ScreenPtr pScreen, + const KdMonitorTiming *), + int rate, + RRScreenSizePtr pSize); +#endif + +/* kpict.c */ +void +KdPictureInitAsync (ScreenPtr pScreen); + +#ifdef RENDER +void +KdCheckComposite (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 +KdCheckRasterizeTrapezoid(PicturePtr pMask, + xTrapezoid *trap, + int x_off, + int y_off); +#endif + +/* kshadow.c */ +Bool +KdShadowFbAlloc (KdScreenInfo *screen, int fb, Bool rotate); + +void +KdShadowFbFree (KdScreenInfo *screen, int fb); + +Bool +KdShadowSet (ScreenPtr pScreen, int randr, ShadowUpdateProc update, ShadowWindowProc window); + +void +KdShadowUnset (ScreenPtr pScreen); + +/* ktest.c */ +Bool +KdFrameBufferValid (CARD8 *base, int size); + +int +KdFrameBufferSize (CARD8 *base, int max); + +/* koffscreen.c */ + +Bool +KdOffscreenInit (ScreenPtr pScreen); + +KdOffscreenArea * +KdOffscreenAlloc (ScreenPtr pScreen, int size, int align, + Bool locked, + KdOffscreenSaveProc save, + pointer privData); + +KdOffscreenArea * +KdOffscreenFree (ScreenPtr pScreen, KdOffscreenArea *area); + +void +KdOffscreenMarkUsed (PixmapPtr pPixmap); + +void +KdOffscreenSwapOut (ScreenPtr pScreen); + +void +KdOffscreenSwapIn (ScreenPtr pScreen); + +void +KdOffscreenFini (ScreenPtr pScreen); + +/* function prototypes to be implemented by the drivers */ +void +InitCard (char *name); + +#endif /* _KDRIVE_H_ */ diff --git a/xorg-server/hw/kdrive/src/kinfo.c b/xorg-server/hw/kdrive/src/kinfo.c new file mode 100644 index 000000000..2621f10dd --- /dev/null +++ b/xorg-server/hw/kdrive/src/kinfo.c @@ -0,0 +1,173 @@ +/* + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" + +KdCardInfo *kdCardInfo; + +KdCardInfo * +KdCardInfoAdd (KdCardFuncs *funcs, + KdCardAttr *attr, + void *closure) +{ + KdCardInfo *ci, **prev; + + ci = (KdCardInfo *) xalloc (sizeof (KdCardInfo)); + if (!ci) + return 0; + bzero (ci, sizeof (KdCardInfo)); + for (prev = &kdCardInfo; *prev; prev = &(*prev)->next); + *prev = ci; + ci->cfuncs = funcs; + ci->attr = *attr; + ci->closure = closure; + ci->screenList = 0; + ci->selected = 0; + ci->next = 0; + return ci; +} + +KdCardInfo * +KdCardInfoLast (void) +{ + KdCardInfo *ci; + + if (!kdCardInfo) + return 0; + for (ci = kdCardInfo; ci->next; ci = ci->next); + return ci; +} + +void +KdCardInfoDispose (KdCardInfo *ci) +{ + KdCardInfo **prev; + + for (prev = &kdCardInfo; *prev; prev = &(*prev)->next) + if (*prev == ci) + { + *prev = ci->next; + xfree (ci); + break; + } +} + +KdScreenInfo * +KdScreenInfoAdd (KdCardInfo *ci) +{ + KdScreenInfo *si, **prev; + int n; + + si = (KdScreenInfo *) xalloc (sizeof (KdScreenInfo)); + if (!si) + return 0; + bzero (si, sizeof (KdScreenInfo)); + for (prev = &ci->screenList, n = 0; *prev; prev = &(*prev)->next, n++); + *prev = si; + si->next = 0; + si->card = ci; + si->mynum = n; + return si; +} + +void +KdScreenInfoDispose (KdScreenInfo *si) +{ + KdCardInfo *ci = si->card; + KdScreenInfo **prev; + + for (prev = &ci->screenList; *prev; prev = &(*prev)->next) { + if (*prev == si) + { + *prev = si->next; + xfree (si); + if (!ci->screenList) + KdCardInfoDispose (ci); + break; + } + } +} + +KdPointerInfo * +KdNewPointer (void) +{ + KdPointerInfo *pi; + int i; + + pi = (KdPointerInfo *)xcalloc(1, sizeof(KdPointerInfo)); + if (!pi) + return NULL; + + pi->name = KdSaveString("Generic Pointer"); + pi->path = NULL; + pi->inputClass = KD_MOUSE; + pi->driver = NULL; + pi->driverPrivate = NULL; + pi->next = NULL; + pi->options = NULL; + pi->nAxes = 3; + pi->nButtons = KD_MAX_BUTTON; + for (i = 1; i < KD_MAX_BUTTON; i++) + pi->map[i] = i; + + return pi; +} + +void +KdFreePointer(KdPointerInfo *pi) +{ + InputOption *option, *prev = NULL; + + if (pi->name) + xfree(pi->name); + if (pi->path) + xfree(pi->path); + + for (option = pi->options; option; option = option->next) { + if (prev) + xfree(prev); + if (option->key) + xfree(option->key); + if (option->value) + xfree(option->value); + prev = option; + } + + if (prev) + xfree(prev); + + xfree(pi); +} + +void +KdFreeKeyboard(KdKeyboardInfo *ki) +{ + if (ki->name) + xfree(ki->name); + if (ki->path) + xfree(ki->path); + ki->next = NULL; + xfree(ki); +} diff --git a/xorg-server/hw/kdrive/src/kinput.c b/xorg-server/hw/kdrive/src/kinput.c new file mode 100644 index 000000000..9ba11661c --- /dev/null +++ b/xorg-server/hw/kdrive/src/kinput.c @@ -0,0 +1,2513 @@ +/* + * Copyright © 1999 Keith Packard + * Copyright © 2006 Nokia Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the authors not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "inputstr.h" + +#define XK_PUBLISHING +#include <X11/keysym.h> +#if HAVE_X11_XF86KEYSYM_H +#include <X11/XF86keysym.h> +#endif +#include <signal.h> +#include <stdio.h> +#ifdef sun +#include <sys/file.h> /* needed for FNONBLOCK & FASYNC */ +#endif + +#ifdef XKB +#include <xkbsrv.h> +#endif + +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "XIstubs.h" /* even though we don't use stubs. cute, no? */ +#include "exevents.h" +#include "extinit.h" +#include "exglobals.h" + +#define AtomFromName(x) MakeAtom(x, strlen(x), 1) + +struct KdConfigDevice { + char *line; + struct KdConfigDevice *next; +}; + +/* kdKeyboards and kdPointers hold all the real devices. */ +static KdKeyboardInfo *kdKeyboards = NULL; +static KdPointerInfo *kdPointers = NULL; +static struct KdConfigDevice *kdConfigKeyboards = NULL; +static struct KdConfigDevice *kdConfigPointers = NULL; + +static KdKeyboardDriver *kdKeyboardDrivers = NULL; +static KdPointerDriver *kdPointerDrivers = NULL; + +static xEvent *kdEvents = NULL; + +static Bool kdInputEnabled; +static Bool kdOffScreen; +static unsigned long kdOffScreenTime; +static KdPointerMatrix kdPointerMatrix = { + { { 1, 0, 0 }, + { 0, 1, 0 } } +}; + +void KdResetInputMachine (void); + +#define IsKeyDown(ki, key) ((ki->keyState[(key) >> 3] >> ((key) & 7)) & 1) +#define KEYMAP(ki) (ki->dixdev->key->curKeySyms) +#define KEYMAPDDX(ki) (ki->keySyms) +#define KEYCOL1(ki, k) (KEYMAP(ki).map[((k)-(KEYMAP(ki).minKeyCode))*KEYMAP(ki).mapWidth]) +#define KEYCOL1DDX(ki, k) (KEYMAPDDX(ki).map[((k)-(KEYMAPDDX(ki).minKeyCode))*KEYMAPDDX(ki).mapWidth]) + +#define KD_MAX_INPUT_FDS 8 + +typedef struct _kdInputFd { + int fd; + void (*read) (int fd, void *closure); + int (*enable) (int fd, void *closure); + void (*disable) (int fd, void *closure); + void *closure; +} KdInputFd; + +static KdInputFd kdInputFds[KD_MAX_INPUT_FDS]; +static int kdNumInputFds; + +extern Bool kdRawPointerCoordinates; + +static void +KdSigio (int sig) +{ + int i; + + for (i = 0; i < kdNumInputFds; i++) + (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); +} + +static void +KdBlockSigio (void) +{ + sigset_t set; + + sigemptyset (&set); + sigaddset (&set, SIGIO); + sigprocmask (SIG_BLOCK, &set, 0); +} + +static void +KdUnblockSigio (void) +{ + sigset_t set; + + sigemptyset (&set); + sigaddset (&set, SIGIO); + sigprocmask (SIG_UNBLOCK, &set, 0); +} + +#ifdef DEBUG_SIGIO + +void +KdAssertSigioBlocked (char *where) +{ + sigset_t set, old; + + sigemptyset (&set); + sigprocmask (SIG_BLOCK, &set, &old); + if (!sigismember (&old, SIGIO)) { + ErrorF ("SIGIO not blocked at %s\n", where); + KdBacktrace(0); + } +} + +#else + +#define KdAssertSigioBlocked(s) + +#endif + +static int kdnFds; + +#ifdef FNONBLOCK +#define NOBLOCK FNONBLOCK +#else +#define NOBLOCK FNDELAY +#endif + +void +KdResetInputMachine (void) +{ + KdPointerInfo *pi; + + for (pi = kdPointers; pi; pi = pi->next) { + pi->mouseState = start; + pi->eventHeld = FALSE; + } +} + +static void +KdNonBlockFd (int fd) +{ + int flags; + flags = fcntl (fd, F_GETFL); + flags |= FASYNC|NOBLOCK; + fcntl (fd, F_SETFL, flags); +} + +static void +KdAddFd (int fd) +{ + struct sigaction act; + sigset_t set; + + kdnFds++; + fcntl (fd, F_SETOWN, getpid()); + KdNonBlockFd (fd); + AddEnabledDevice (fd); + memset (&act, '\0', sizeof act); + act.sa_handler = KdSigio; + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGIO); + sigaddset (&act.sa_mask, SIGALRM); + sigaddset (&act.sa_mask, SIGVTALRM); + sigaction (SIGIO, &act, 0); + sigemptyset (&set); + sigprocmask (SIG_SETMASK, &set, 0); +} + +static void +KdRemoveFd (int fd) +{ + struct sigaction act; + int flags; + + kdnFds--; + RemoveEnabledDevice (fd); + flags = fcntl (fd, F_GETFL); + flags &= ~(FASYNC|NOBLOCK); + fcntl (fd, F_SETFL, flags); + if (kdnFds == 0) + { + memset (&act, '\0', sizeof act); + act.sa_handler = SIG_IGN; + sigemptyset (&act.sa_mask); + sigaction (SIGIO, &act, 0); + } +} + +Bool +KdRegisterFd (int fd, void (*read) (int fd, void *closure), void *closure) +{ + if (kdNumInputFds == KD_MAX_INPUT_FDS) + return FALSE; + kdInputFds[kdNumInputFds].fd = fd; + kdInputFds[kdNumInputFds].read = read; + kdInputFds[kdNumInputFds].enable = 0; + kdInputFds[kdNumInputFds].disable = 0; + kdInputFds[kdNumInputFds].closure = closure; + kdNumInputFds++; + if (kdInputEnabled) + KdAddFd (fd); + return TRUE; +} + +void +KdUnregisterFd (void *closure, int fd, Bool do_close) +{ + int i, j; + + for (i = 0; i < kdNumInputFds; i++) { + if (kdInputFds[i].closure == closure && + (fd == -1 || kdInputFds[i].fd == fd)) { + if (kdInputEnabled) + KdRemoveFd (kdInputFds[i].fd); + if (do_close) + close (kdInputFds[i].fd); + kdNumInputFds--; + for (j = i; j < kdNumInputFds; j++) + kdInputFds[j] = kdInputFds[j+1]; + break; + } + } +} + +void +KdUnregisterFds (void *closure, Bool do_close) +{ + KdUnregisterFd(closure, -1, do_close); +} + +void +KdDisableInput (void) +{ + KdKeyboardInfo *ki; + KdPointerInfo *pi; + int found = 0, i = 0; + + KdBlockSigio(); + + for (ki = kdKeyboards; ki; ki = ki->next) { + if (ki->driver && ki->driver->Disable) + (*ki->driver->Disable) (ki); + } + + for (pi = kdPointers; pi; pi = pi->next) { + if (pi->driver && pi->driver->Disable) + (*pi->driver->Disable) (pi); + } + + if (kdNumInputFds) { + ErrorF("[KdDisableInput] Buggy drivers: still %d input fds left!", + kdNumInputFds); + i = 0; + while (i < kdNumInputFds) { + found = 0; + for (ki = kdKeyboards; ki; ki = ki->next) { + if (ki == kdInputFds[i].closure) { + ErrorF(" fd %d belongs to keybd driver %s\n", + kdInputFds[i].fd, + ki->driver && ki->driver->name ? + ki->driver->name : "(unnamed!)"); + found = 1; + break; + } + } + + if (found) { + i++; + continue; + } + + for (pi = kdPointers; pi; pi = pi->next) { + if (pi == kdInputFds[i].closure) { + ErrorF(" fd %d belongs to pointer driver %s\n", + kdInputFds[i].fd, + pi->driver && pi->driver->name ? + pi->driver->name : "(unnamed!)"); + break; + } + } + + if (found) { + i++; + continue; + } + + ErrorF(" fd %d not claimed by any active device!\n", + kdInputFds[i].fd); + KdUnregisterFd(kdInputFds[i].closure, kdInputFds[i].fd, TRUE); + } + } + + kdInputEnabled = FALSE; +} + +void +KdEnableInput (void) +{ + xEvent xE; + KdKeyboardInfo *ki; + KdPointerInfo *pi; + + kdInputEnabled = TRUE; + + for (ki = kdKeyboards; ki; ki = ki->next) { + if (ki->driver && ki->driver->Enable) + (*ki->driver->Enable) (ki); + } + + for (pi = kdPointers; pi; pi = pi->next) { + if (pi->driver && pi->driver->Enable) + (*pi->driver->Enable) (pi); + } + + /* reset screen saver */ + xE.u.keyButtonPointer.time = GetTimeInMillis (); + NoticeEventTime (&xE); + + KdUnblockSigio (); +} + +static KdKeyboardDriver * +KdFindKeyboardDriver (char *name) +{ + KdKeyboardDriver *ret; + + /* ask a stupid question ... */ + if (!name) + return NULL; + + for (ret = kdKeyboardDrivers; ret; ret = ret->next) { + if (strcmp(ret->name, name) == 0) + return ret; + } + + return NULL; +} + +static KdPointerDriver * +KdFindPointerDriver (char *name) +{ + KdPointerDriver *ret; + + /* ask a stupid question ... */ + if (!name) + return NULL; + + for (ret = kdPointerDrivers; ret; ret = ret->next) { + if (strcmp(ret->name, name) == 0) + return ret; + } + + return NULL; +} + +static int +KdPointerProc(DeviceIntPtr pDevice, int onoff) +{ + DevicePtr pDev = (DevicePtr)pDevice; + KdPointerInfo *pi; + Atom xiclass; + + if (!pDev) + return BadImplementation; + + for (pi = kdPointers; pi; pi = pi->next) { + if (pi->dixdev && pi->dixdev->id == pDevice->id) + break; + } + + if (!pi || !pi->dixdev || pi->dixdev->id != pDevice->id) { + ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n", + pDevice->id); + return BadImplementation; + } + + switch (onoff) + { + case DEVICE_INIT: +#ifdef DEBUG + ErrorF("initialising pointer %s ...\n", pi->name); +#endif + if (!pi->driver) { + if (!pi->driverPrivate) { + ErrorF("no driver specified for %s\n", pi->name); + return BadImplementation; + } + + pi->driver = KdFindPointerDriver(pi->driverPrivate); + if (!pi->driver) { + ErrorF("Couldn't find pointer driver %s\n", + pi->driverPrivate ? (char *) pi->driverPrivate : + "(unnamed)"); + return !Success; + } + xfree(pi->driverPrivate); + pi->driverPrivate = NULL; + } + + if (!pi->driver->Init) { + ErrorF("no init function\n"); + return BadImplementation; + } + + if ((*pi->driver->Init) (pi) != Success) { + return !Success; + } + + InitPointerDeviceStruct(pDev, pi->map, pi->nButtons, + GetMotionHistory, + (PtrCtrlProcPtr)NoopDDA, + GetMotionHistorySize(), pi->nAxes); + + if (pi->inputClass == KD_TOUCHSCREEN) { + InitAbsoluteClassDeviceStruct(pDevice); + xiclass = AtomFromName(XI_TOUCHSCREEN); + } + else { + xiclass = AtomFromName(XI_MOUSE); + } + + AssignTypeAndName(pi->dixdev, xiclass, + pi->name ? pi->name : "Generic KDrive Pointer"); + + return Success; + + case DEVICE_ON: + if (pDev->on == TRUE) + return Success; + + if (!pi->driver->Enable) { + ErrorF("no enable function\n"); + return BadImplementation; + } + + if ((*pi->driver->Enable) (pi) == Success) { + pDev->on = TRUE; + return Success; + } + else { + return BadImplementation; + } + + return Success; + + case DEVICE_OFF: + if (pDev->on == FALSE) { + return Success; + } + + if (!pi->driver->Disable) { + return BadImplementation; + } + else { + (*pi->driver->Disable) (pi); + pDev->on = FALSE; + return Success; + } + + return Success; + + case DEVICE_CLOSE: + if (pDev->on) { + if (!pi->driver->Disable) { + return BadImplementation; + } + (*pi->driver->Disable) (pi); + pDev->on = FALSE; + } + + if (!pi->driver->Fini) + return BadImplementation; + + (*pi->driver->Fini) (pi); + + KdRemovePointer(pi); + + return Success; + } + + /* NOTREACHED */ + return BadImplementation; +} + +Bool +LegalModifier(unsigned int key, DeviceIntPtr pDev) +{ + return TRUE; +} + +static void +KdBell (int volume, DeviceIntPtr pDev, pointer arg, int something) +{ + KeybdCtrl *ctrl = arg; + KdKeyboardInfo *ki = NULL; + + for (ki = kdKeyboards; ki; ki = ki->next) { + if (ki->dixdev && ki->dixdev->id == pDev->id) + break; + } + + if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver) + return; + + KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration); +} + +void +DDXRingBell(int volume, int pitch, int duration) +{ + KdKeyboardInfo *ki = NULL; + + if (kdOsFuncs->Bell) { + (*kdOsFuncs->Bell)(volume, pitch, duration); + } + else { + for (ki = kdKeyboards; ki; ki = ki->next) { + if (ki->dixdev->coreEvents) + KdRingBell(ki, volume, pitch, duration); + } + } +} + +void +KdRingBell(KdKeyboardInfo *ki, int volume, int pitch, int duration) +{ + if (!ki || !ki->driver || !ki->driver->Bell) + return; + + if (kdInputEnabled) + (*ki->driver->Bell) (ki, volume, pitch, duration); +} + + +static void +KdSetLeds (KdKeyboardInfo *ki, int leds) +{ + if (!ki || !ki->driver) + return; + + if (kdInputEnabled) { + if (ki->driver->Leds) + (*ki->driver->Leds) (ki, leds); + } +} + +void +KdSetLed (KdKeyboardInfo *ki, int led, Bool on) +{ + if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed) + return; + + NoteLedState (ki->dixdev, led, on); + KdSetLeds (ki, ki->dixdev->kbdfeed->ctrl.leds); +} + +void +KdSetPointerMatrix (KdPointerMatrix *matrix) +{ + kdPointerMatrix = *matrix; +} + +void +KdComputePointerMatrix (KdPointerMatrix *m, Rotation randr, int width, + int height) +{ + int x_dir = 1, y_dir = 1; + int i, j; + int size[2]; + + size[0] = width; size[1] = height; + if (randr & RR_Reflect_X) + x_dir = -1; + if (randr & RR_Reflect_Y) + y_dir = -1; + switch (randr & (RR_Rotate_All)) { + case RR_Rotate_0: + m->matrix[0][0] = x_dir; m->matrix[0][1] = 0; + m->matrix[1][0] = 0; m->matrix[1][1] = y_dir; + break; + case RR_Rotate_90: + m->matrix[0][0] = 0; m->matrix[0][1] = -x_dir; + m->matrix[1][0] = y_dir; m->matrix[1][1] = 0; + break; + case RR_Rotate_180: + m->matrix[0][0] = -x_dir; m->matrix[0][1] = 0; + m->matrix[1][0] = 0; m->matrix[1][1] = -y_dir; + break; + case RR_Rotate_270: + m->matrix[0][0] = 0; m->matrix[0][1] = x_dir; + m->matrix[1][0] = -y_dir; m->matrix[1][1] = 0; + break; + } + for (i = 0; i < 2; i++) + { + m->matrix[i][2] = 0; + for (j = 0 ; j < 2; j++) + if (m->matrix[i][j] < 0) + m->matrix[i][2] = size[j] - 1; + } +} + +void +KdScreenToPointerCoords (int *x, int *y) +{ + int (*m)[3] = kdPointerMatrix.matrix; + int div = m[0][1] * m[1][0] - m[1][1] * m[0][0]; + int sx = *x; + int sy = *y; + + *x = (m[0][1] * sy - m[0][1] * m[1][2] + m[1][1] * m[0][2] - m[1][1] * sx) / div; + *y = (m[1][0] * sx + m[0][0] * m[1][2] - m[1][0] * m[0][2] - m[0][0] * sy) / div; +} + +static void +KdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl) +{ + KdKeyboardInfo *ki; + + for (ki = kdKeyboards; ki; ki = ki->next) { + if (ki->dixdev && ki->dixdev->id == pDevice->id) + break; + } + + if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver) + return; + + KdSetLeds(ki, ctrl->leds); + ki->bellPitch = ctrl->bell_pitch; + ki->bellDuration = ctrl->bell_duration; +} + +extern KeybdCtrl defaultKeyboardControl; + +static void +KdInitAutoRepeats (KdKeyboardInfo *ki) +{ + int key_code; + unsigned char mask; + int i; + unsigned char *repeats; + + repeats = defaultKeyboardControl.autoRepeats; + memset (repeats, '\0', 32); + for (key_code = KD_MIN_KEYCODE; key_code <= KD_MAX_KEYCODE; key_code++) + { + if (!ki->modmap[key_code]) + { + i = key_code >> 3; + mask = 1 << (key_code & 7); + repeats[i] |= mask; + } + } +} + +const KdKeySymModsRec kdKeySymMods[] = { + { XK_Control_L, ControlMask }, + { XK_Control_R, ControlMask }, + { XK_Shift_L, ShiftMask }, + { XK_Shift_R, ShiftMask }, + { XK_Caps_Lock, LockMask }, + { XK_Shift_Lock, LockMask }, + { XK_Alt_L, Mod1Mask }, + { XK_Alt_R, Mod1Mask }, + { XK_Meta_L, Mod1Mask }, + { XK_Meta_R, Mod1Mask }, + { XK_Num_Lock, Mod2Mask }, + { XK_Super_L, Mod3Mask }, + { XK_Super_R, Mod3Mask }, + { XK_Hyper_L, Mod3Mask }, + { XK_Hyper_R, Mod3Mask }, + { XK_Mode_switch, Mod4Mask }, + /* PDA specific hacks */ +#ifdef XF86XK_Start + { XF86XK_Start, ControlMask }, +#endif + { XK_Menu, ShiftMask }, + { XK_telephone, Mod1Mask }, +#ifdef XF86XK_AudioRecord + { XF86XK_AudioRecord, Mod2Mask }, +#endif +#ifdef XF86XK_Calendar + { XF86XK_Calendar, Mod3Mask } +#endif +}; + +#define NUM_SYM_MODS (sizeof(kdKeySymMods) / sizeof(kdKeySymMods[0])) + +static void +KdInitModMap (KdKeyboardInfo *ki) +{ + int key_code; + int row; + int width; + KeySym *syms; + int i; + + width = ki->keySyms.mapWidth; + for (key_code = ki->keySyms.minKeyCode; key_code <= ki->keySyms.maxKeyCode; key_code++) + { + ki->modmap[key_code] = 0; + syms = ki->keySyms.map + (key_code - ki->keySyms.minKeyCode) * width; + for (row = 0; row < width; row++, syms++) + { + for (i = 0; i < NUM_SYM_MODS; i++) + { + if (*syms == kdKeySymMods[i].modsym) + ki->modmap[key_code] |= kdKeySymMods[i].modbit; + } + } + } +} + +static int +KdKeyboardProc(DeviceIntPtr pDevice, int onoff) +{ + Bool ret; + DevicePtr pDev = (DevicePtr)pDevice; + KdKeyboardInfo *ki; + Atom xiclass; +#ifdef XKB + XkbComponentNamesRec names; +#endif + + if (!pDev) + return BadImplementation; + + for (ki = kdKeyboards; ki; ki = ki->next) { + if (ki->dixdev && ki->dixdev->id == pDevice->id) + break; + } + + if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id) { + return BadImplementation; + } + + switch (onoff) + { + case DEVICE_INIT: +#ifdef DEBUG + ErrorF("initialising keyboard %s\n", ki->name); +#endif + if (!ki->driver) { + if (!ki->driverPrivate) { + ErrorF("no driver specified!\n"); + return BadImplementation; + } + + ki->driver = KdFindKeyboardDriver(ki->driverPrivate); + if (!ki->driver) { + ErrorF("Couldn't find keyboard driver %s\n", + ki->driverPrivate ? (char *) ki->driverPrivate : + "(unnamed)"); + return !Success; + } + xfree(ki->driverPrivate); + ki->driverPrivate = NULL; + } + + if (!ki->driver->Init) { + ErrorF("Keyboard %s: no init function\n", ki->name); + return BadImplementation; + } + + if ((*ki->driver->Init) (ki) != Success) { + return !Success; + } + + KdInitModMap(ki); + KdInitAutoRepeats(ki); + +#ifdef XKB + if (!noXkbExtension) { + memset(&names, 0, sizeof(XkbComponentNamesRec)); + + XkbSetRulesDflts (ki->xkbRules, ki->xkbModel, ki->xkbLayout, + ki->xkbVariant, ki->xkbOptions); + + ret = XkbInitKeyboardDeviceStruct (pDevice, + &names, + &ki->keySyms, + ki->modmap, + KdBell, KdKbdCtrl); + } + else +#endif + ret = InitKeyboardDeviceStruct(pDev, + &ki->keySyms, + ki->modmap, + KdBell, KdKbdCtrl); + if (!ret) { + ErrorF("Couldn't initialise keyboard %s\n", ki->name); + return BadImplementation; + } + + xiclass = AtomFromName(XI_KEYBOARD); + AssignTypeAndName(pDevice, xiclass, + ki->name ? ki->name : "Generic KDrive Keyboard"); + + KdResetInputMachine(); + + return Success; + + case DEVICE_ON: + if (pDev->on == TRUE) + return Success; + + if (!ki->driver->Enable) + return BadImplementation; + + if ((*ki->driver->Enable) (ki) != Success) { + return BadMatch; + } + + pDev->on = TRUE; + return Success; + + case DEVICE_OFF: + if (pDev->on == FALSE) + return Success; + + if (!ki->driver->Disable) + return BadImplementation; + + (*ki->driver->Disable) (ki); + pDev->on = FALSE; + + return Success; + + break; + + case DEVICE_CLOSE: + if (pDev->on) { + if (!ki->driver->Disable) + return BadImplementation; + + (*ki->driver->Disable) (ki); + pDev->on = FALSE; + } + + if (!ki->driver->Fini) + return BadImplementation; + + (*ki->driver->Fini) (ki); + + KdRemoveKeyboard(ki); + + return Success; + } + + /* NOTREACHED */ + return BadImplementation; +} + +void +KdAddPointerDriver (KdPointerDriver *driver) +{ + KdPointerDriver **prev; + + if (!driver) + return; + + for (prev = &kdPointerDrivers; *prev; prev = &(*prev)->next) { + if (*prev == driver) + return; + } + *prev = driver; +} + +void +KdRemovePointerDriver (KdPointerDriver *driver) +{ + KdPointerDriver *tmp; + + if (!driver) + return; + + /* FIXME remove all pointers using this driver */ + for (tmp = kdPointerDrivers; tmp; tmp = tmp->next) { + if (tmp->next == driver) + tmp->next = driver->next; + } + if (tmp == driver) + tmp = NULL; +} + +void +KdAddKeyboardDriver (KdKeyboardDriver *driver) +{ + KdKeyboardDriver **prev; + + if (!driver) + return; + + for (prev = &kdKeyboardDrivers; *prev; prev = &(*prev)->next) { + if (*prev == driver) + return; + } + *prev = driver; +} + +void +KdRemoveKeyboardDriver (KdKeyboardDriver *driver) +{ + KdKeyboardDriver *tmp; + + if (!driver) + return; + + /* FIXME remove all keyboards using this driver */ + for (tmp = kdKeyboardDrivers; tmp; tmp = tmp->next) { + if (tmp->next == driver) + tmp->next = driver->next; + } + if (tmp == driver) + tmp = NULL; +} + +KdKeyboardInfo * +KdNewKeyboard (void) +{ + KdKeyboardInfo *ki = xcalloc(sizeof(KdKeyboardInfo), 1); + + if (!ki) + return NULL; + + ki->keySyms.map = (KeySym *)xcalloc(sizeof(KeySym), + KD_MAX_LENGTH * + kdDefaultKeySyms.mapWidth); + if (!ki->keySyms.map) { + xfree(ki); + return NULL; + } + + memcpy(ki->keySyms.map, kdDefaultKeySyms.map, + sizeof(KeySym) * (KD_MAX_LENGTH * kdDefaultKeySyms.mapWidth)); + ki->keySyms.minKeyCode = kdDefaultKeySyms.minKeyCode; + ki->keySyms.maxKeyCode = kdDefaultKeySyms.maxKeyCode; + ki->keySyms.mapWidth = kdDefaultKeySyms.mapWidth; + ki->minScanCode = 0; + ki->maxScanCode = 0; + ki->leds = 0; + ki->bellPitch = 1000; + ki->bellDuration = 200; + ki->next = NULL; + ki->options = NULL; +#ifdef XKB + ki->xkbRules = KdSaveString("base"); + ki->xkbModel = KdSaveString("pc105"); + ki->xkbLayout = KdSaveString("us"); + ki->xkbVariant = NULL; + ki->xkbOptions = NULL; +#endif + + return ki; +} + +int +KdAddConfigKeyboard (char *keyboard) +{ + struct KdConfigDevice **prev, *new; + + if (!keyboard) + return Success; + + new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1); + if (!new) + return BadAlloc; + + new->line = xstrdup(keyboard); + new->next = NULL; + + for (prev = &kdConfigKeyboards; *prev; prev = &(*prev)->next); + *prev = new; + + return Success; +} + +int +KdAddKeyboard (KdKeyboardInfo *ki) +{ + KdKeyboardInfo **prev; + + if (!ki) + return !Success; + + ki->dixdev = AddInputDevice(KdKeyboardProc, TRUE); + if (!ki->dixdev) { + ErrorF("Couldn't register keyboard device %s\n", + ki->name ? ki->name : "(unnamed)"); + return !Success; + } + + RegisterOtherDevice(ki->dixdev); + +#ifdef DEBUG + ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id); +#endif + + for (prev = &kdKeyboards; *prev; prev = &(*prev)->next); + *prev = ki; + + return Success; +} + +void +KdRemoveKeyboard (KdKeyboardInfo *ki) +{ + KdKeyboardInfo **prev; + + if (!ki) + return; + + for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) { + if (*prev == ki) { + *prev = ki->next; + break; + } + } + + KdFreeKeyboard(ki); +} + +int +KdAddConfigPointer (char *pointer) +{ + struct KdConfigDevice **prev, *new; + + if (!pointer) + return Success; + + new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1); + if (!new) + return BadAlloc; + + new->line = xstrdup(pointer); + new->next = NULL; + + for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next); + *prev = new; + + return Success; +} + +int +KdAddPointer (KdPointerInfo *pi) +{ + KdPointerInfo **prev; + + if (!pi) + return Success; + + pi->mouseState = start; + pi->eventHeld = FALSE; + + pi->dixdev = AddInputDevice(KdPointerProc, TRUE); + if (!pi->dixdev) { + ErrorF("Couldn't add pointer device %s\n", + pi->name ? pi->name : "(unnamed)"); + return BadDevice; + } + + RegisterOtherDevice(pi->dixdev); + + for (prev = &kdPointers; *prev; prev = &(*prev)->next); + *prev = pi; + + return Success; +} + +void +KdRemovePointer (KdPointerInfo *pi) +{ + KdPointerInfo **prev; + + if (!pi) + return; + + for (prev = &kdPointers; *prev; prev = &(*prev)->next) { + if (*prev == pi) { + *prev = pi->next; + break; + } + } + + KdFreePointer(pi); +} + +/* + * You can call your kdriver server with something like: + * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd + * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br + */ +static Bool +KdGetOptions (InputOption **options, char *string) +{ + InputOption *newopt = NULL, **tmpo = NULL; + int tam_key = 0; + + newopt = (InputOption *) xalloc(sizeof (InputOption)); + if (!newopt) + return FALSE; + + bzero(newopt, sizeof (InputOption)); + + for (tmpo = options; *tmpo; tmpo = &(*tmpo)->next) + ; /* Hello, I'm here */ + *tmpo = newopt; + + if (strchr(string, '=')) + { + tam_key = (strchr(string, '=') - string); + newopt->key = (char *)xalloc(tam_key); + strncpy(newopt->key, string, tam_key); + newopt->key[tam_key] = '\0'; + newopt->value = xstrdup(strchr(string, '=') + 1); + } + else + { + newopt->key = xstrdup(string); + newopt->value = NULL; + } + newopt->next = NULL; + + return TRUE; +} + +static void +KdParseKbdOptions (KdKeyboardInfo *ki) +{ + InputOption *option = NULL; + + for (option = ki->options; option; option = option->next) + { +#ifdef XKB + if (strcasecmp(option->key, "XkbRules") == 0) + ki->xkbRules = option->value; + else if (strcasecmp(option->key, "XkbModel") == 0) + ki->xkbModel = option->value; + else if (strcasecmp(option->key, "XkbLayout") == 0) + ki->xkbLayout = option->value; + else if (strcasecmp(option->key, "XkbVariant") == 0) + ki->xkbVariant = option->value; + else if (strcasecmp(option->key, "XkbOptions") == 0) + ki->xkbOptions = option->value; + else if (!strcasecmp (option->key, "device")) + ki->path = KdSaveString(option->value); + else +#endif + ErrorF("Kbd option key (%s) of value (%s) not assigned!\n", + option->key, option->value); + } +} + +KdKeyboardInfo * +KdParseKeyboard (char *arg) +{ + char save[1024]; + char delim; + InputOption *options = NULL; + KdKeyboardInfo *ki = NULL; + + ki = KdNewKeyboard(); + if (!ki) + return NULL; + + ki->name = strdup("Unknown KDrive Keyboard"); + ki->path = NULL; + ki->driver = NULL; + ki->driverPrivate = NULL; +#ifdef XKB + ki->xkb = NULL; +#endif + ki->next = NULL; + + if (!arg) + { + ErrorF("keybd: no arg\n"); + KdFreeKeyboard (ki); + return NULL; + } + + if (strlen (arg) >= sizeof (save)) + { + ErrorF("keybd: arg too long\n"); + KdFreeKeyboard (ki); + return NULL; + } + + arg = KdParseFindNext (arg, ",", save, &delim); + if (!save[0]) + { + ErrorF("keybd: failed on save[0]\n"); + KdFreeKeyboard (ki); + return NULL; + } + + if (strcmp (save, "auto") == 0) + ki->driverPrivate = NULL; + else + ki->driverPrivate = xstrdup(save); + + if (delim != ',') + { + return ki; + } + + arg = KdParseFindNext (arg, ",", save, &delim); + + while (delim == ',') + { + arg = KdParseFindNext (arg, ",", save, &delim); + + if (!KdGetOptions(&options, save)) + { + KdFreeKeyboard(ki); + return NULL; + } + } + + if (options) + { + ki->options = options; + KdParseKbdOptions(ki); + } + + return ki; +} + +static void +KdParsePointerOptions (KdPointerInfo *pi) +{ + InputOption *option = NULL; + + for (option = pi->options; option; option = option->next) + { + if (!strcmp (option->key, "emulatemiddle")) + pi->emulateMiddleButton = TRUE; + else if (!strcmp (option->key, "noemulatemiddle")) + pi->emulateMiddleButton = FALSE; + else if (!strcmp (option->key, "transformcoord")) + pi->transformCoordinates = TRUE; + else if (!strcmp (option->key, "rawcoord")) + pi->transformCoordinates = FALSE; + else if (!strcasecmp (option->key, "device")) + pi->path = KdSaveString(option->value); + else + ErrorF("Pointer option key (%s) of value (%s) not assigned!\n", + option->key, option->value); + } +} + +KdPointerInfo * +KdParsePointer (char *arg) +{ + char save[1024]; + char delim; + KdPointerInfo *pi = NULL; + InputOption *options = NULL; + int i = 0; + + pi = KdNewPointer(); + if (!pi) + return NULL; + pi->emulateMiddleButton = kdEmulateMiddleButton; + pi->transformCoordinates = !kdRawPointerCoordinates; + pi->nButtons = 5; /* XXX should not be hardcoded */ + pi->inputClass = KD_MOUSE; + + if (!arg) + { + ErrorF("mouse: no arg\n"); + KdFreePointer (pi); + return NULL; + } + + if (strlen (arg) >= sizeof (save)) + { + ErrorF("mouse: arg too long\n"); + KdFreePointer (pi); + return NULL; + } + arg = KdParseFindNext (arg, ",", save, &delim); + if (!save[0]) + { + ErrorF("failed on save[0]\n"); + KdFreePointer (pi); + return NULL; + } + + if (strcmp(save, "auto") == 0) + pi->driverPrivate = NULL; + else + pi->driverPrivate = xstrdup(save); + + if (delim != ',') + { + return pi; + } + + arg = KdParseFindNext (arg, ",", save, &delim); + + while (delim == ',') + { + arg = KdParseFindNext (arg, ",", save, &delim); + if (save[0] == '{') + { + char *s = save + 1; + i = 0; + while (*s && *s != '}') + { + if ('1' <= *s && *s <= '0' + pi->nButtons) + pi->map[i] = *s - '0'; + else + UseMsg (); + s++; + } + } + else + { + if (!KdGetOptions(&options, save)) + { + KdFreePointer(pi); + return NULL; + } + } + } + + if (options) + { + pi->options = options; + KdParsePointerOptions(pi); + } + + return pi; +} + + +void +KdInitInput (void) +{ + KdPointerInfo *pi; + KdKeyboardInfo *ki; + struct KdConfigDevice *dev; + + kdInputEnabled = TRUE; + + for (dev = kdConfigPointers; dev; dev = dev->next) { + pi = KdParsePointer(dev->line); + if (!pi) + ErrorF("Failed to parse pointer\n"); + if (KdAddPointer(pi) != Success) + ErrorF("Failed to add pointer!\n"); + } + for (dev = kdConfigKeyboards; dev; dev = dev->next) { + ki = KdParseKeyboard(dev->line); + if (!ki) + ErrorF("Failed to parse keyboard\n"); + if (KdAddKeyboard(ki) != Success) + ErrorF("Failed to add keyboard!\n"); + } + + if (!kdEvents) + kdEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + if (!kdEvents) + FatalError("Couldn't allocate event buffer\n"); + + mieqInit(); +} + +/* + * Middle button emulation state machine + * + * Possible transitions: + * Button 1 press v1 + * Button 1 release ^1 + * Button 2 press v2 + * Button 2 release ^2 + * Button 3 press v3 + * Button 3 release ^3 + * Button other press vo + * Button other release ^o + * Mouse motion <> + * Keyboard event k + * timeout ... + * outside box <-> + * + * States: + * start + * button_1_pend + * button_1_down + * button_2_down + * button_3_pend + * button_3_down + * synthetic_2_down_13 + * synthetic_2_down_3 + * synthetic_2_down_1 + * + * Transition diagram + * + * start + * v1 -> (hold) (settimeout) button_1_pend + * ^1 -> (deliver) start + * v2 -> (deliver) button_2_down + * ^2 -> (deliever) start + * v3 -> (hold) (settimeout) button_3_pend + * ^3 -> (deliver) start + * vo -> (deliver) start + * ^o -> (deliver) start + * <> -> (deliver) start + * k -> (deliver) start + * + * button_1_pend (button 1 is down, timeout pending) + * ^1 -> (release) (deliver) start + * v2 -> (release) (deliver) button_1_down + * ^2 -> (release) (deliver) button_1_down + * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13 + * ^3 -> (release) (deliver) button_1_down + * vo -> (release) (deliver) button_1_down + * ^o -> (release) (deliver) button_1_down + * <-> -> (release) (deliver) button_1_down + * <> -> (deliver) button_1_pend + * k -> (release) (deliver) button_1_down + * ... -> (release) button_1_down + * + * button_1_down (button 1 is down) + * ^1 -> (deliver) start + * v2 -> (deliver) button_1_down + * ^2 -> (deliver) button_1_down + * v3 -> (deliver) button_1_down + * ^3 -> (deliver) button_1_down + * vo -> (deliver) button_1_down + * ^o -> (deliver) button_1_down + * <> -> (deliver) button_1_down + * k -> (deliver) button_1_down + * + * button_2_down (button 2 is down) + * v1 -> (deliver) button_2_down + * ^1 -> (deliver) button_2_down + * ^2 -> (deliver) start + * v3 -> (deliver) button_2_down + * ^3 -> (deliver) button_2_down + * vo -> (deliver) button_2_down + * ^o -> (deliver) button_2_down + * <> -> (deliver) button_2_down + * k -> (deliver) button_2_down + * + * button_3_pend (button 3 is down, timeout pending) + * v1 -> (generate v2) synthetic_2_down + * ^1 -> (release) (deliver) button_3_down + * v2 -> (release) (deliver) button_3_down + * ^2 -> (release) (deliver) button_3_down + * ^3 -> (release) (deliver) start + * vo -> (release) (deliver) button_3_down + * ^o -> (release) (deliver) button_3_down + * <-> -> (release) (deliver) button_3_down + * <> -> (deliver) button_3_pend + * k -> (release) (deliver) button_3_down + * ... -> (release) button_3_down + * + * button_3_down (button 3 is down) + * v1 -> (deliver) button_3_down + * ^1 -> (deliver) button_3_down + * v2 -> (deliver) button_3_down + * ^2 -> (deliver) button_3_down + * ^3 -> (deliver) start + * vo -> (deliver) button_3_down + * ^o -> (deliver) button_3_down + * <> -> (deliver) button_3_down + * k -> (deliver) button_3_down + * + * synthetic_2_down_13 (button 1 and 3 are down) + * ^1 -> (generate ^2) synthetic_2_down_3 + * v2 -> synthetic_2_down_13 + * ^2 -> synthetic_2_down_13 + * ^3 -> (generate ^2) synthetic_2_down_1 + * vo -> (deliver) synthetic_2_down_13 + * ^o -> (deliver) synthetic_2_down_13 + * <> -> (deliver) synthetic_2_down_13 + * k -> (deliver) synthetic_2_down_13 + * + * synthetic_2_down_3 (button 3 is down) + * v1 -> (deliver) synthetic_2_down_3 + * ^1 -> (deliver) synthetic_2_down_3 + * v2 -> synthetic_2_down_3 + * ^2 -> synthetic_2_down_3 + * ^3 -> start + * vo -> (deliver) synthetic_2_down_3 + * ^o -> (deliver) synthetic_2_down_3 + * <> -> (deliver) synthetic_2_down_3 + * k -> (deliver) synthetic_2_down_3 + * + * synthetic_2_down_1 (button 1 is down) + * ^1 -> start + * v2 -> synthetic_2_down_1 + * ^2 -> synthetic_2_down_1 + * v3 -> (deliver) synthetic_2_down_1 + * ^3 -> (deliver) synthetic_2_down_1 + * vo -> (deliver) synthetic_2_down_1 + * ^o -> (deliver) synthetic_2_down_1 + * <> -> (deliver) synthetic_2_down_1 + * k -> (deliver) synthetic_2_down_1 + */ + +typedef enum _inputClass { + down_1, up_1, + down_2, up_2, + down_3, up_3, + down_o, up_o, + motion, outside_box, + keyboard, timeout, + num_input_class +} KdInputClass; + +typedef enum _inputAction { + noop, + hold, + setto, + deliver, + release, + clearto, + gen_down_2, + gen_up_2 +} KdInputAction; + +#define MAX_ACTIONS 2 + +typedef struct _inputTransition { + KdInputAction actions[MAX_ACTIONS]; + KdPointerState nextState; +} KdInputTransition; + +static const +KdInputTransition kdInputMachine[num_input_states][num_input_class] = { + /* start */ + { + { { hold, setto }, button_1_pend }, /* v1 */ + { { deliver, noop }, start }, /* ^1 */ + { { deliver, noop }, button_2_down }, /* v2 */ + { { deliver, noop }, start }, /* ^2 */ + { { hold, setto }, button_3_pend }, /* v3 */ + { { deliver, noop }, start }, /* ^3 */ + { { deliver, noop }, start }, /* vo */ + { { deliver, noop }, start }, /* ^o */ + { { deliver, noop }, start }, /* <> */ + { { deliver, noop }, start }, /* <-> */ + { { noop, noop }, start }, /* k */ + { { noop, noop }, start }, /* ... */ + }, + /* button_1_pend */ + { + { { noop, noop }, button_1_pend }, /* v1 */ + { { release, deliver }, start }, /* ^1 */ + { { release, deliver }, button_1_down }, /* v2 */ + { { release, deliver }, button_1_down }, /* ^2 */ + { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */ + { { release, deliver }, button_1_down }, /* ^3 */ + { { release, deliver }, button_1_down }, /* vo */ + { { release, deliver }, button_1_down }, /* ^o */ + { { deliver, noop }, button_1_pend }, /* <> */ + { { release, deliver }, button_1_down }, /* <-> */ + { { noop, noop }, button_1_down }, /* k */ + { { release, noop }, button_1_down }, /* ... */ + }, + /* button_1_down */ + { + { { noop, noop }, button_1_down }, /* v1 */ + { { deliver, noop }, start }, /* ^1 */ + { { deliver, noop }, button_1_down }, /* v2 */ + { { deliver, noop }, button_1_down }, /* ^2 */ + { { deliver, noop }, button_1_down }, /* v3 */ + { { deliver, noop }, button_1_down }, /* ^3 */ + { { deliver, noop }, button_1_down }, /* vo */ + { { deliver, noop }, button_1_down }, /* ^o */ + { { deliver, noop }, button_1_down }, /* <> */ + { { deliver, noop }, button_1_down }, /* <-> */ + { { noop, noop }, button_1_down }, /* k */ + { { noop, noop }, button_1_down }, /* ... */ + }, + /* button_2_down */ + { + { { deliver, noop }, button_2_down }, /* v1 */ + { { deliver, noop }, button_2_down }, /* ^1 */ + { { noop, noop }, button_2_down }, /* v2 */ + { { deliver, noop }, start }, /* ^2 */ + { { deliver, noop }, button_2_down }, /* v3 */ + { { deliver, noop }, button_2_down }, /* ^3 */ + { { deliver, noop }, button_2_down }, /* vo */ + { { deliver, noop }, button_2_down }, /* ^o */ + { { deliver, noop }, button_2_down }, /* <> */ + { { deliver, noop }, button_2_down }, /* <-> */ + { { noop, noop }, button_2_down }, /* k */ + { { noop, noop }, button_2_down }, /* ... */ + }, + /* button_3_pend */ + { + { { clearto, gen_down_2 }, synth_2_down_13 }, /* v1 */ + { { release, deliver }, button_3_down }, /* ^1 */ + { { release, deliver }, button_3_down }, /* v2 */ + { { release, deliver }, button_3_down }, /* ^2 */ + { { release, deliver }, button_3_down }, /* v3 */ + { { release, deliver }, start }, /* ^3 */ + { { release, deliver }, button_3_down }, /* vo */ + { { release, deliver }, button_3_down }, /* ^o */ + { { deliver, noop }, button_3_pend }, /* <> */ + { { release, deliver }, button_3_down }, /* <-> */ + { { release, noop }, button_3_down }, /* k */ + { { release, noop }, button_3_down }, /* ... */ + }, + /* button_3_down */ + { + { { deliver, noop }, button_3_down }, /* v1 */ + { { deliver, noop }, button_3_down }, /* ^1 */ + { { deliver, noop }, button_3_down }, /* v2 */ + { { deliver, noop }, button_3_down }, /* ^2 */ + { { noop, noop }, button_3_down }, /* v3 */ + { { deliver, noop }, start }, /* ^3 */ + { { deliver, noop }, button_3_down }, /* vo */ + { { deliver, noop }, button_3_down }, /* ^o */ + { { deliver, noop }, button_3_down }, /* <> */ + { { deliver, noop }, button_3_down }, /* <-> */ + { { noop, noop }, button_3_down }, /* k */ + { { noop, noop }, button_3_down }, /* ... */ + }, + /* synthetic_2_down_13 */ + { + { { noop, noop }, synth_2_down_13 }, /* v1 */ + { { gen_up_2, noop }, synth_2_down_3 }, /* ^1 */ + { { noop, noop }, synth_2_down_13 }, /* v2 */ + { { noop, noop }, synth_2_down_13 }, /* ^2 */ + { { noop, noop }, synth_2_down_13 }, /* v3 */ + { { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */ + { { deliver, noop }, synth_2_down_13 }, /* vo */ + { { deliver, noop }, synth_2_down_13 }, /* ^o */ + { { deliver, noop }, synth_2_down_13 }, /* <> */ + { { deliver, noop }, synth_2_down_13 }, /* <-> */ + { { noop, noop }, synth_2_down_13 }, /* k */ + { { noop, noop }, synth_2_down_13 }, /* ... */ + }, + /* synthetic_2_down_3 */ + { + { { deliver, noop }, synth_2_down_3 }, /* v1 */ + { { deliver, noop }, synth_2_down_3 }, /* ^1 */ + { { deliver, noop }, synth_2_down_3 }, /* v2 */ + { { deliver, noop }, synth_2_down_3 }, /* ^2 */ + { { noop, noop }, synth_2_down_3 }, /* v3 */ + { { noop, noop }, start }, /* ^3 */ + { { deliver, noop }, synth_2_down_3 }, /* vo */ + { { deliver, noop }, synth_2_down_3 }, /* ^o */ + { { deliver, noop }, synth_2_down_3 }, /* <> */ + { { deliver, noop }, synth_2_down_3 }, /* <-> */ + { { noop, noop }, synth_2_down_3 }, /* k */ + { { noop, noop }, synth_2_down_3 }, /* ... */ + }, + /* synthetic_2_down_1 */ + { + { { noop, noop }, synth_2_down_1 }, /* v1 */ + { { noop, noop }, start }, /* ^1 */ + { { deliver, noop }, synth_2_down_1 }, /* v2 */ + { { deliver, noop }, synth_2_down_1 }, /* ^2 */ + { { deliver, noop }, synth_2_down_1 }, /* v3 */ + { { deliver, noop }, synth_2_down_1 }, /* ^3 */ + { { deliver, noop }, synth_2_down_1 }, /* vo */ + { { deliver, noop }, synth_2_down_1 }, /* ^o */ + { { deliver, noop }, synth_2_down_1 }, /* <> */ + { { deliver, noop }, synth_2_down_1 }, /* <-> */ + { { noop, noop }, synth_2_down_1 }, /* k */ + { { noop, noop }, synth_2_down_1 }, /* ... */ + }, +}; + +#define EMULATION_WINDOW 10 +#define EMULATION_TIMEOUT 100 + +static int +KdInsideEmulationWindow (KdPointerInfo *pi, int x, int y, int z) +{ + pi->emulationDx = pi->heldEvent.x - x; + pi->emulationDy = pi->heldEvent.y - y; + + return (abs (pi->emulationDx) < EMULATION_WINDOW && + abs (pi->emulationDy) < EMULATION_WINDOW); +} + +static KdInputClass +KdClassifyInput (KdPointerInfo *pi, int type, int x, int y, int z, int b) +{ + switch (type) { + case ButtonPress: + switch (b) { + case 1: return down_1; + case 2: return down_2; + case 3: return down_3; + default: return down_o; + } + break; + case ButtonRelease: + switch (b) { + case 1: return up_1; + case 2: return up_2; + case 3: return up_3; + default: return up_o; + } + break; + case MotionNotify: + if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z)) + return outside_box; + else + return motion; + default: + return keyboard; + } + return keyboard; +} + +#ifndef NDEBUG +char *kdStateNames[] = { + "start", + "button_1_pend", + "button_1_down", + "button_2_down", + "button_3_pend", + "button_3_down", + "synth_2_down_13", + "synth_2_down_3", + "synthetic_2_down_1", + "num_input_states" +}; + +char *kdClassNames[] = { + "down_1", "up_1", + "down_2", "up_2", + "down_3", "up_3", + "motion", "ouside_box", + "keyboard", "timeout", + "num_input_class" +}; + +char *kdActionNames[] = { + "noop", + "hold", + "setto", + "deliver", + "release", + "clearto", + "gen_down_2", + "gen_up_2", +}; +#endif + +static void +KdQueueEvent (DeviceIntPtr pDev, xEvent *ev) +{ + KdAssertSigioBlocked ("KdQueueEvent"); + mieqEnqueue (pDev, ev); +} + +/* We return true if we're stealing the event. */ +static Bool +KdRunMouseMachine (KdPointerInfo *pi, KdInputClass c, int type, int x, int y, + int z, int b, int absrel) +{ + const KdInputTransition *t; + int a; + + c = KdClassifyInput(pi, type, x, y, z, b); + t = &kdInputMachine[pi->mouseState][c]; + for (a = 0; a < MAX_ACTIONS; a++) + { + switch (t->actions[a]) { + case noop: + break; + case hold: + pi->eventHeld = TRUE; + pi->emulationDx = 0; + pi->emulationDy = 0; + pi->heldEvent.type = type; + pi->heldEvent.x = x; + pi->heldEvent.y = y; + pi->heldEvent.z = z; + pi->heldEvent.flags = b; + pi->heldEvent.absrel = absrel; + return TRUE; + break; + case setto: + pi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT; + pi->timeoutPending = TRUE; + break; + case deliver: + _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, + pi->heldEvent.y, pi->heldEvent.z, + pi->heldEvent.flags, pi->heldEvent.absrel, + TRUE); + break; + case release: + pi->eventHeld = FALSE; + pi->timeoutPending = FALSE; + _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, + pi->heldEvent.y, pi->heldEvent.z, + pi->heldEvent.flags, pi->heldEvent.absrel, + TRUE); + return TRUE; + break; + case clearto: + pi->timeoutPending = FALSE; + break; + case gen_down_2: + _KdEnqueuePointerEvent (pi, ButtonPress, x, y, z, 2, absrel, + TRUE); + pi->eventHeld = FALSE; + return TRUE; + break; + case gen_up_2: + _KdEnqueuePointerEvent (pi, ButtonRelease, x, y, z, 2, absrel, + TRUE); + return TRUE; + break; + } + } + pi->mouseState = t->nextState; + return FALSE; +} + +static int +KdHandlePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b, + int absrel) +{ + if (pi->emulateMiddleButton) + return KdRunMouseMachine (pi, KdClassifyInput(pi, type, x, y, z, b), + type, x, y, z, b, absrel); + return FALSE; +} + +static void +KdReceiveTimeout (KdPointerInfo *pi) +{ + KdRunMouseMachine (pi, timeout, 0, 0, 0, 0, 0, 0); +} + +#define KILL_SEQUENCE ((1L << KK_CONTROL)|(1L << KK_ALT)|(1L << KK_F8)|(1L << KK_F10)) +#define SPECIAL_SEQUENCE ((1L << KK_CONTROL) | (1L << KK_ALT)) +#define SETKILLKEY(b) (KdSpecialKeys |= (1L << (b))) +#define CLEARKILLKEY(b) (KdSpecialKeys &= ~(1L << (b))) + +CARD32 KdSpecialKeys = 0; + +/* + * kdCheckTermination + * + * This function checks for the key sequence that terminates the server. When + * detected, it sets the dispatchException flag and returns. The key sequence + * is: + * Control-Alt + * It's assumed that the server will be waken up by the caller when this + * function returns. + */ + +extern int nClients; + +static void +KdCheckSpecialKeys(KdKeyboardInfo *ki, int type, int sym) +{ + if (!ki) + return; + + /* + * Ignore key releases + */ + + if (type == KeyRelease) + return; + + /* Some iPaq keyboard -> mouse button mapping used to be here, but I + * refuse to perpetuate this madness. -daniels */ + + /* + * Check for control/alt pressed + */ + if ((ki->dixdev->key->state & (ControlMask|Mod1Mask)) != + (ControlMask|Mod1Mask)) + return; + + /* + * Let OS function see keysym first + */ + + if (kdOsFuncs->SpecialKey) + if ((*kdOsFuncs->SpecialKey) (sym)) + return; + + /* + * Now check for backspace or delete; these signal the + * X server to terminate + * + * I can't believe it's not XKB. -daniels + */ + switch (sym) { + case XK_BackSpace: + case XK_Delete: + case XK_KP_Delete: + /* + * Set the dispatch exception flag so the server will terminate the + * next time through the dispatch loop. + */ + if (kdDontZap == FALSE) + dispatchException |= DE_TERMINATE; + break; + } +} + +/* + * kdEnqueueKeyboardEvent + * + * This function converts hardware keyboard event information into an X event + * and enqueues it using MI. It wakes up the server before returning so that + * the event will be processed normally. + * + */ + +static void +KdHandleKeyboardEvent (KdKeyboardInfo *ki, int type, int key) +{ + int byte; + CARD8 bit; + KdPointerInfo *pi; + + byte = key >> 3; + bit = 1 << (key & 7); + + switch (type) { + case KeyPress: + ki->keyState[byte] |= bit; + break; + case KeyRelease: + ki->keyState[byte] &= ~bit; + break; + } + + for (pi = kdPointers; pi; pi = pi->next) + KdRunMouseMachine (pi, keyboard, 0, 0, 0, 0, 0, 0); +} + +void +KdReleaseAllKeys (void) +{ + int key, nEvents, i; + KdKeyboardInfo *ki; + + KdBlockSigio (); + + for (ki = kdKeyboards; ki; ki = ki->next) { + for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode; + key++) { + if (IsKeyDown(ki, key)) { + KdHandleKeyboardEvent(ki, KeyRelease, key); + nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key); + for (i = 0; i < nEvents; i++) + KdQueueEvent (ki->dixdev, kdEvents + i); + } + } + } + + KdUnblockSigio (); +} + +static void +KdCheckLock (void) +{ + KeyClassPtr keyc = NULL; + Bool isSet = FALSE, shouldBeSet = FALSE; + KdKeyboardInfo *tmp = NULL; + + for (tmp = kdKeyboards; tmp; tmp = tmp->next) { + if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) { + keyc = tmp->dixdev->key; + isSet = (tmp->leds & (1 << (tmp->LockLed-1))) != 0; + shouldBeSet = (keyc->state & LockMask) != 0; + if (isSet != shouldBeSet) + KdSetLed (tmp, tmp->LockLed, shouldBeSet); + } + } +} + +void +KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, + unsigned char scan_code, + unsigned char is_up) +{ + unsigned char key_code; + KeyClassPtr keyc = NULL; + KeybdCtrl *ctrl = NULL; + int type, nEvents, i; + + if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key) + return; + + keyc = ki->dixdev->key; + ctrl = &ki->dixdev->kbdfeed->ctrl; + + if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) + { + key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode; + + /* + * Set up this event -- the type may be modified below + */ + if (is_up) + type = KeyRelease; + else + type = KeyPress; + +#ifdef XKB + if (noXkbExtension) +#endif + { + KdCheckSpecialKeys(ki, type, key_code); + KdHandleKeyboardEvent(ki, type, key_code); + } + + nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code); + for (i = 0; i < nEvents; i++) + KdQueueEvent(ki->dixdev, kdEvents + i); + } + else { + ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", + ki->name, scan_code, ki->minScanCode, ki->maxScanCode); + } +} + +/* + * kdEnqueuePointerEvent + * + * This function converts hardware mouse event information into X event + * information. A mouse movement event is passed off to MI to generate + * a MotionNotify event, if appropriate. Button events are created and + * passed off to MI for enqueueing. + */ + +/* FIXME do something a little more clever to deal with multiple axes here */ +void +KdEnqueuePointerEvent(KdPointerInfo *pi, unsigned long flags, int rx, int ry, + int rz) +{ + CARD32 ms; + unsigned char buttons; + int x, y, z; + int (*matrix)[3] = kdPointerMatrix.matrix; + unsigned long button; + int n; + int dixflags = 0; + + if (!pi) + return; + + ms = GetTimeInMillis(); + + /* we don't need to transform z, so we don't. */ + if (flags & KD_MOUSE_DELTA) { + if (pi->transformCoordinates) { + x = matrix[0][0] * rx + matrix[0][1] * ry; + y = matrix[1][0] * rx + matrix[1][1] * ry; + } + else { + x = rx; + y = ry; + } + } + else { + if (pi->transformCoordinates) { + x = matrix[0][0] * rx + matrix[0][1] * ry; + y = matrix[1][0] * rx + matrix[1][1] * ry; + } + else { + x = rx; + y = ry; + } + } + z = rz; + + if (flags & KD_MOUSE_DELTA) + { + if (x || y || z) + dixflags = POINTER_RELATIVE | POINTER_ACCELERATE; + } else if ((pi->dixdev->valuator) && (x != pi->dixdev->valuator->lastx || + y != pi->dixdev->valuator->lasty)) + dixflags = POINTER_ABSOLUTE; + + if (dixflags) + _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE); + + buttons = flags; + + for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; + button <<= 1, n++) { + if (((pi->buttonState & button) ^ (buttons & button)) && + !(buttons & button)) { + _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n, + dixflags, FALSE); + } + } + for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; + button <<= 1, n++) { + if (((pi->buttonState & button) ^ (buttons & button)) && + (buttons & button)) { + _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n, + dixflags, FALSE); + } + } + + pi->buttonState = buttons; +} + +void +_KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, + int b, int absrel, Bool force) +{ + int nEvents = 0, i = 0; + int valuators[3] = { x, y, z }; + + /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */ + if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel)) + return; + + nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, 0, 3, + valuators); + for (i = 0; i < nEvents; i++) + KdQueueEvent(pi->dixdev, kdEvents + i); +} + +void +KdBlockHandler (int screen, + pointer blockData, + pointer timeout, + pointer readmask) +{ + KdPointerInfo *pi; + int myTimeout=0; + + for (pi = kdPointers; pi; pi = pi->next) + { + if (pi->timeoutPending) + { + int ms; + + ms = pi->emulationTimeout - GetTimeInMillis (); + if (ms < 1) + ms = 1; + if(ms<myTimeout || myTimeout==0) + myTimeout=ms; + } + } + /* if we need to poll for events, do that */ + if(kdOsFuncs->pollEvents) + { + (*kdOsFuncs->pollEvents)(); + myTimeout=20; + } + if(myTimeout>0) + AdjustWaitForDelay (timeout, myTimeout); +} + +void +KdWakeupHandler (int screen, + pointer data, + unsigned long lresult, + pointer readmask) +{ + int result = (int) lresult; + fd_set *pReadmask = (fd_set *) readmask; + int i; + KdPointerInfo *pi; + + if (kdInputEnabled && result > 0) + { + for (i = 0; i < kdNumInputFds; i++) + if (FD_ISSET (kdInputFds[i].fd, pReadmask)) + { + KdBlockSigio (); + (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); + KdUnblockSigio (); + } + } + for (pi = kdPointers; pi; pi = pi->next) + { + if (pi->timeoutPending) + { + if ((long) (GetTimeInMillis () - pi->emulationTimeout) >= 0) + { + pi->timeoutPending = FALSE; + KdBlockSigio (); + KdReceiveTimeout (pi); + KdUnblockSigio (); + } + } + } + if (kdSwitchPending) + KdProcessSwitch (); +} + +#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin)) + +static Bool +KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) +{ + ScreenPtr pScreen = *ppScreen; + ScreenPtr pNewScreen; + int n; + int dx, dy; + int best_x, best_y; + int n_best_x, n_best_y; + CARD32 ms; + + if (kdDisableZaphod || screenInfo.numScreens <= 1) + return FALSE; + + if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height) + return FALSE; + + ms = GetTimeInMillis (); + if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000) + return FALSE; + kdOffScreen = TRUE; + kdOffScreenTime = ms; + n_best_x = -1; + best_x = 32767; + n_best_y = -1; + best_y = 32767; + for (n = 0; n < screenInfo.numScreens; n++) + { + pNewScreen = screenInfo.screens[n]; + if (pNewScreen == pScreen) + continue; + dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x; + dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y; + if (*x < 0) + { + if (dx <= 0 && -dx < best_x) + { + best_x = -dx; + n_best_x = n; + } + } + else if (*x >= pScreen->width) + { + if (dx >= 0 && dx < best_x) + { + best_x = dx; + n_best_x = n; + } + } + if (*y < 0) + { + if (dy <= 0 && -dy < best_y) + { + best_y = -dy; + n_best_y = n; + } + } + else if (*y >= pScreen->height) + { + if (dy >= 0 && dy < best_y) + { + best_y = dy; + n_best_y = n; + } + } + } + if (best_y < best_x) + n_best_x = n_best_y; + if (n_best_x == -1) + return FALSE; + pNewScreen = screenInfo.screens[n_best_x]; + + if (*x < 0) + *x += pNewScreen->width; + if (*y < 0) + *y += pNewScreen->height; + + if (*x >= pScreen->width) + *x -= pScreen->width; + if (*y >= pScreen->height) + *y -= pScreen->height; + + *ppScreen = pNewScreen; + return TRUE; +} + +static void +KdCrossScreen(ScreenPtr pScreen, Bool entering) +{ +#ifndef XIPAQ + if (entering) + KdEnableScreen (pScreen); + else + KdDisableScreen (pScreen); +#endif +} + +int KdCurScreen; /* current event screen */ + +static void +KdWarpCursor (ScreenPtr pScreen, int x, int y) +{ + KdBlockSigio (); + KdCurScreen = pScreen->myNum; + miPointerWarpCursor (pScreen, x, y); + KdUnblockSigio (); +} + +miPointerScreenFuncRec kdPointerScreenFuncs = +{ + KdCursorOffScreen, + KdCrossScreen, + KdWarpCursor +}; + +void +ProcessInputEvents () +{ + mieqProcessInputEvents(); + miPointerUpdate(); + if (kdSwitchPending) + KdProcessSwitch (); + KdCheckLock (); +} + +/* FIXME use XSECURITY to work out whether the client should be allowed to + * open and close. */ +void +OpenInputDevice(DeviceIntPtr pDev, ClientPtr client, int *status) +{ + if (!pDev) + *status = BadDevice; + else + *status = Success; +} + +void +CloseInputDevice(DeviceIntPtr pDev, ClientPtr client) +{ + return; +} + +/* We initialise all input devices at startup. */ +void +AddOtherInputDevices(void) +{ + return; +} + +/* At the moment, absolute/relative is up to the client. */ +int +SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode) +{ + return BadMatch; +} + +int +SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev, + int *valuators, int first_valuator, int num_valuators) +{ + return BadMatch; +} + +int +ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev, + xDeviceCtl *control) +{ + switch (control->control) { + case DEVICE_RESOLUTION: + /* FIXME do something more intelligent here */ + return BadMatch; + + case DEVICE_ABS_CALIB: + case DEVICE_ABS_AREA: + return Success; + + case DEVICE_CORE: + case DEVICE_ENABLE: + return Success; + + default: + return BadMatch; + } + + /* NOTREACHED */ + return BadImplementation; +} + +int +NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) +{ + InputOption *option = NULL; + KdPointerInfo *pi = NULL; + KdKeyboardInfo *ki = NULL; + + for (option = options; option; option = option->next) { + if (strcmp(option->key, "type") == 0) { + if (strcmp(option->value, "pointer") == 0) { + pi = KdNewPointer(); + if (!pi) + return BadAlloc; + } + else if (strcmp(option->value, "keyboard") == 0) { + ki = KdNewKeyboard(); + if (!ki) + return BadAlloc; + } + else { + ErrorF("unrecognised device type!\n"); + return BadValue; + } + } + } + + if (!ki && !pi) { + ErrorF("unrecognised device identifier!\n"); + return BadValue; + } + + /* FIXME: change this code below to use KdParseKbdOptions and + * KdParsePointerOptions */ + for (option = options; option; option = option->next) { + if (strcmp(option->key, "device") == 0) { + if (pi && option->value) + pi->path = KdSaveString(option->value); + else if (ki && option->value) + ki->path = KdSaveString(option->value); + } + else if (strcmp(option->key, "driver") == 0) { + if (pi) { + pi->driver = KdFindPointerDriver(option->value); + if (!pi->driver) { + ErrorF("couldn't find driver!\n"); + KdFreePointer(pi); + return BadValue; + } + pi->options = options; + } + else if (ki) { + ki->driver = KdFindKeyboardDriver(option->value); + if (!ki->driver) { + ErrorF("couldn't find driver!\n"); + KdFreeKeyboard(ki); + return BadValue; + } + ki->options = options; + } + } + } + + if (pi) { + if (KdAddPointer(pi) != Success || + ActivateDevice(pi->dixdev) != Success || + EnableDevice(pi->dixdev) != TRUE) { + ErrorF("couldn't add or enable pointer\n"); + return BadImplementation; + } + } + else if (ki) { + if (KdAddKeyboard(ki) != Success || + ActivateDevice(ki->dixdev) != Success || + EnableDevice(ki->dixdev) != TRUE) { + ErrorF("couldn't add or enable keyboard\n"); + return BadImplementation; + } + } + + if (pi) { + *pdev = pi->dixdev; + } else if(ki) { + *pdev = ki->dixdev; + } + + return Success; +} + +void +DeleteInputDeviceRequest(DeviceIntPtr pDev) +{ + RemoveDevice(pDev); +} diff --git a/xorg-server/hw/kdrive/src/kkeymap.c b/xorg-server/hw/kdrive/src/kkeymap.c new file mode 100644 index 000000000..ae90a3499 --- /dev/null +++ b/xorg-server/hw/kdrive/src/kkeymap.c @@ -0,0 +1,189 @@ +/* + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include <X11/keysym.h> + +/* + * Map scan codes (both regular and synthesized from extended keys) + * to X keysyms + */ + +const KeySym kdDefaultKeymap[KD_MAX_LENGTH * KD_MAX_WIDTH] = { +/* These are directly mapped from DOS scanset 0 */ +/* 1 8 */ XK_Escape, NoSymbol, +/* 2 9 */ XK_1, XK_exclam, +/* 3 10 */ XK_2, XK_at, +/* 4 11 */ XK_3, XK_numbersign, +/* 5 12 */ XK_4, XK_dollar, +/* 6 13 */ XK_5, XK_percent, +/* 7 14 */ XK_6, XK_asciicircum, +/* 8 15 */ XK_7, XK_ampersand, +/* 9 16 */ XK_8, XK_asterisk, +/* 10 17 */ XK_9, XK_parenleft, +/* 11 18 */ XK_0, XK_parenright, +/* 12 19 */ XK_minus, XK_underscore, +/* 13 20 */ XK_equal, XK_plus, +/* 14 21 */ XK_BackSpace, NoSymbol, +/* 15 22 */ XK_Tab, NoSymbol, +/* 16 23 */ XK_Q, NoSymbol, +/* 17 24 */ XK_W, NoSymbol, +/* 18 25 */ XK_E, NoSymbol, +/* 19 26 */ XK_R, NoSymbol, +/* 20 27 */ XK_T, NoSymbol, +/* 21 28 */ XK_Y, NoSymbol, +/* 22 29 */ XK_U, NoSymbol, +/* 23 30 */ XK_I, NoSymbol, +/* 24 31 */ XK_O, NoSymbol, +/* 25 32 */ XK_P, NoSymbol, +/* 26 33 */ XK_bracketleft, XK_braceleft, +/* 27 34 */ XK_bracketright, XK_braceright, +/* 28 35 */ XK_Return, NoSymbol, +/* 29 36 */ XK_Control_L, NoSymbol, +/* 30 37 */ XK_A, NoSymbol, +/* 31 38 */ XK_S, NoSymbol, +/* 32 39 */ XK_D, NoSymbol, +/* 33 40 */ XK_F, NoSymbol, +/* 34 41 */ XK_G, NoSymbol, +/* 35 42 */ XK_H, NoSymbol, +/* 36 43 */ XK_J, NoSymbol, +/* 37 44 */ XK_K, NoSymbol, +/* 38 45 */ XK_L, NoSymbol, +/* 39 46 */ XK_semicolon, XK_colon, +/* 40 47 */ XK_apostrophe, XK_quotedbl, +/* 41 48 */ XK_grave, XK_asciitilde, +/* 42 49 */ XK_Shift_L, NoSymbol, +/* 43 50 */ XK_backslash, XK_bar, +/* 44 51 */ XK_Z, NoSymbol, +/* 45 52 */ XK_X, NoSymbol, +/* 46 53 */ XK_C, NoSymbol, +/* 47 54 */ XK_V, NoSymbol, +/* 48 55 */ XK_B, NoSymbol, +/* 49 56 */ XK_N, NoSymbol, +/* 50 57 */ XK_M, NoSymbol, +/* 51 58 */ XK_comma, XK_less, +/* 52 59 */ XK_period, XK_greater, +/* 53 60 */ XK_slash, XK_question, +/* 54 61 */ XK_Shift_R, NoSymbol, +/* 55 62 */ XK_KP_Multiply, NoSymbol, +/* 56 63 */ XK_Alt_L, XK_Meta_L, +/* 57 64 */ XK_space, NoSymbol, +/* 58 65 */ XK_Caps_Lock, NoSymbol, +/* 59 66 */ XK_F1, NoSymbol, +/* 60 67 */ XK_F2, NoSymbol, +/* 61 68 */ XK_F3, NoSymbol, +/* 62 69 */ XK_F4, NoSymbol, +/* 63 70 */ XK_F5, NoSymbol, +/* 64 71 */ XK_F6, NoSymbol, +/* 65 72 */ XK_F7, NoSymbol, +/* 66 73 */ XK_F8, NoSymbol, +/* 67 74 */ XK_F9, NoSymbol, +/* 68 75 */ XK_F10, NoSymbol, +/* 69 76 */ XK_Break, XK_Pause, +/* 70 77 */ XK_Scroll_Lock, NoSymbol, +/* 71 78 */ XK_KP_Home, XK_KP_7, +/* 72 79 */ XK_KP_Up, XK_KP_8, +/* 73 80 */ XK_KP_Page_Up, XK_KP_9, +/* 74 81 */ XK_KP_Subtract, NoSymbol, +/* 75 82 */ XK_KP_Left, XK_KP_4, +/* 76 83 */ XK_KP_5, NoSymbol, +/* 77 84 */ XK_KP_Right, XK_KP_6, +/* 78 85 */ XK_KP_Add, NoSymbol, +/* 79 86 */ XK_KP_End, XK_KP_1, +/* 80 87 */ XK_KP_Down, XK_KP_2, +/* 81 88 */ XK_KP_Page_Down, XK_KP_3, +/* 82 89 */ XK_KP_Insert, XK_KP_0, +/* 83 90 */ XK_KP_Delete, XK_KP_Decimal, +/* 84 91 */ NoSymbol, NoSymbol, +/* 85 92 */ NoSymbol, NoSymbol, +/* 86 93 */ NoSymbol, NoSymbol, +/* 87 94 */ XK_F11, NoSymbol, +/* 88 95 */ XK_F12, NoSymbol, + +/* These are remapped from the extended set (using ExtendMap) */ + +/* 89 96 */ XK_Control_R, NoSymbol, +/* 90 97 */ XK_KP_Enter, NoSymbol, +/* 91 98 */ XK_KP_Divide, NoSymbol, +/* 92 99 */ XK_Sys_Req, XK_Print, +/* 93 100 */ XK_Alt_R, XK_Meta_R, +/* 94 101 */ XK_Num_Lock, NoSymbol, +/* 95 102 */ XK_Home, NoSymbol, +/* 96 103 */ XK_Up, NoSymbol, +/* 97 104 */ XK_Page_Up, NoSymbol, +/* 98 105 */ XK_Left, NoSymbol, +/* 99 106 */ XK_Right, NoSymbol, +/* 100 107 */ XK_End, NoSymbol, +/* 101 108 */ XK_Down, NoSymbol, +/* 102 109 */ XK_Page_Down, NoSymbol, +/* 103 110 */ XK_Insert, NoSymbol, +/* 104 111 */ XK_Delete, NoSymbol, +/* 105 112 */ XK_Super_L, NoSymbol, +/* 106 113 */ XK_Super_R, NoSymbol, +/* 107 114 */ XK_Menu, NoSymbol, +/* 108 115 */ NoSymbol, NoSymbol, +/* 109 116 */ NoSymbol, NoSymbol, +/* 110 117 */ NoSymbol, NoSymbol, +/* 111 118 */ NoSymbol, NoSymbol, +/* 112 119 */ NoSymbol, NoSymbol, +}; + +/* + * List of locking key codes + */ + +CARD8 kdLockMap[] = { + 65, + 101, + 77, +}; + +#define NUM_LOCK (sizeof (kdLockMap) / sizeof (kdLockMap[0])) + +int kdNumLock = NUM_LOCK; + +/* + * Map containing list of keys which the X server makes locking when + * the KEYMAP_LOCKING_ALTGR flag is set in CEKeymapFlags + */ + +CARD8 kdOptionalLockMap[] = { + 100, +}; + +#define NUM_OPTIONAL_LOCK (sizeof (kdOptionalLockMap) / sizeof (kdOptionalLockMap[0])) + +int kdNumOptionalLock = NUM_OPTIONAL_LOCK; + +const CARD8 kdDefaultModMap[MAP_LENGTH]; + +unsigned long kdDefaultKeymapFlags = 0; + +const KeySymsRec kdDefaultKeySyms = { + kdDefaultKeymap, + KD_MIN_KEYCODE, + KD_MAX_KEYCODE, + KD_MAX_WIDTH +}; diff --git a/xorg-server/hw/kdrive/src/kmap.c b/xorg-server/hw/kdrive/src/kmap.c new file mode 100644 index 000000000..ce1e28ae4 --- /dev/null +++ b/xorg-server/hw/kdrive/src/kmap.c @@ -0,0 +1,178 @@ +/* + * 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 <kdrive-config.h> +#include "kdrive.h" + +#include <errno.h> +#include <unistd.h> +#include <sys/mman.h> +#ifdef HAVE_ASM_MTRR_H +#include <asm/mtrr.h> +#endif + +#include <sys/ioctl.h> + +void * +KdMapDevice (CARD32 addr, CARD32 size) +{ +#ifdef WINDOWS + void *a; + void *d; + + d = VirtualAlloc (NULL, size, MEM_RESERVE, PAGE_NOACCESS); + if (!d) + return NULL; + DRAW_DEBUG ((DEBUG_S3INIT, "Virtual address of 0x%x is 0x%x", addr, d)); + a = VirtualCopyAddr (addr); + DRAW_DEBUG ((DEBUG_S3INIT, "Translated address is 0x%x", a)); + if (!VirtualCopy (d, a, size, + PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL)) + { + DRAW_DEBUG ((DEBUG_FAILURE, "VirtualCopy failed %d", + GetLastError ())); + return NULL; + } + DRAW_DEBUG ((DEBUG_S3INIT, "Device mapped successfully")); + return d; +#endif +#ifdef linux + void *a; + int fd; + +#ifdef __arm__ + fd = open ("/dev/mem", O_RDWR|O_SYNC); +#else + fd = open ("/dev/mem", O_RDWR); +#endif + if (fd < 0) + FatalError ("KdMapDevice: failed to open /dev/mem (%s)\n", + strerror (errno)); + + a = mmap ((caddr_t) 0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, addr); + close (fd); + if ((long) a == -1) + FatalError ("KdMapDevice: failed to map frame buffer (%s)\n", + strerror (errno)); + return a; +#endif +#ifdef VXWORKS + return (void *) addr; +#endif +} + +void +KdUnmapDevice (void *addr, CARD32 size) +{ +#ifdef WINDOWS + VirtualFree (addr, size, MEM_DECOMMIT); + VirtualFree (addr, 0, MEM_RELEASE); +#endif +#ifdef linux + munmap (addr, size); +#endif +#ifdef VXWORKS + ; +#endif +} + +#ifdef HAVE_ASM_MTRR_H +static int mtrr; +#endif + +void +KdSetMappedMode (CARD32 addr, CARD32 size, int mode) +{ +#ifdef HAVE_ASM_MTRR_H + struct mtrr_sentry sentry; + unsigned long base, bound; + unsigned int type = MTRR_TYPE_WRBACK; + + if (addr < 0x100000) + return; + if (!mtrr) + mtrr = open ("/proc/mtrr", 2); + if (mtrr > 0) + { + unsigned long nsize; + base = addr & ~((1<<22)-1); + bound = ((addr + size) + ((1<<22) - 1)) & ~((1<<22) - 1); + nsize = 1; + while (nsize < (bound - base)) + nsize <<= 1; + switch (mode) { + case KD_MAPPED_MODE_REGISTERS: + type = MTRR_TYPE_UNCACHABLE; + break; + case KD_MAPPED_MODE_FRAMEBUFFER: + type = MTRR_TYPE_WRCOMB; + break; + } + sentry.base = base; + sentry.size = nsize; + sentry.type = type; + + if (ioctl (mtrr, MTRRIOC_ADD_ENTRY, &sentry) < 0) + ErrorF ("MTRRIOC_ADD_ENTRY failed 0x%x 0x%x %d (%s)\n", + base, bound - base, type, strerror(errno)); + } +#endif +} + +void +KdResetMappedMode (CARD32 addr, CARD32 size, int mode) +{ +#ifdef HAVE_ASM_MTRR_H + struct mtrr_sentry sentry; + unsigned long base, bound; + unsigned int type = MTRR_TYPE_WRBACK; + + if (addr < 0x100000) + return; + if (!mtrr) + mtrr = open ("/proc/mtrr", 2); + if (mtrr > 0) + { + unsigned long nsize; + base = addr & ~((1<<22)-1); + bound = ((addr + size) + ((1<<22) - 1)) & ~((1<<22) - 1); + nsize = 1; + while (nsize < (bound - base)) + nsize <<= 1; + switch (mode) { + case KD_MAPPED_MODE_REGISTERS: + type = MTRR_TYPE_UNCACHABLE; + break; + case KD_MAPPED_MODE_FRAMEBUFFER: + type = MTRR_TYPE_WRCOMB; + break; + } + sentry.base = base; + sentry.size = nsize; + sentry.type = type; + + if (ioctl (mtrr, MTRRIOC_DEL_ENTRY, &sentry) < 0) + ErrorF ("MTRRIOC_DEL_ENTRY failed 0x%x 0x%x %d (%s)\n", + base, bound - base, type, strerror(errno)); + } +#endif +} diff --git a/xorg-server/hw/kdrive/src/kmode.c b/xorg-server/hw/kdrive/src/kmode.c new file mode 100644 index 000000000..d02cb55e1 --- /dev/null +++ b/xorg-server/hw/kdrive/src/kmode.c @@ -0,0 +1,400 @@ +/* + * Copyright 1999 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_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" + +const KdMonitorTiming kdMonitorTimings[] = { + /* H V Hz KHz */ + /* FP BP BLANK POLARITY */ + + /* IPAQ modeline: + * + * Modeline "320x240" 5.7222 320 337 340 352 240 241 244 254" + */ + { 320, 240, 64, 16256, + 17, 12, 32, KdSyncNegative, + 1, 11, 14, KdSyncNegative, + }, + + /* Other VESA modes */ + { 640, 350, 85, 31500, /* VESA */ + 32, 96, 192, KdSyncPositive, /* 26.413 */ + 32, 60, 95, KdSyncNegative, /* 59.354 */ + }, + { 640, 400, 60, 31500, /* VESA */ + 32, 96, 192, KdSyncNegative, /* 26.413 */ + 1, 41, 45, KdSyncPositive, /* 59.354 */ + }, + { 720, 400, 85, 35500, /* VESA */ + 36, 108, 216, KdSyncNegative, /* 37.927 */ + 1, 42, 46, KdSyncPositive, /* 85.039 */ + }, + + + /* Modeline "720x576" 29.000 720 736 800 880 576 577 580 625 */ + { + 720, 576, 52, 32954, /* PAL Video */ + 16, 80, 160, KdSyncPositive, /* 32.954 */ + 1, 45, 49, KdSyncPositive, /* 52.727 */ + }, + + /* 640x480 modes */ + { 640, 480, 85, 36000, /* VESA */ + 56, 80, 192, KdSyncNegative, /* 43.269 */ + 1, 25, 29, KdSyncNegative, /* 85.008 */ + }, + { 640, 480, 75, 31500, /* VESA */ + 16, 120, 200, KdSyncNegative, /* 37.500 */ + 1, 16, 20, KdSyncNegative, /* 75.000 */ + }, + { 640, 480, 72, 31500, /* VESA */ + 16, 120, 176, KdSyncNegative, /* 37.861 */ + 1, 20, 24, KdSyncNegative, /* 72.809 */ + }, + { 640, 480, 60, 25175, /* VESA */ + 16, 48, 160, KdSyncNegative, /* 31.469 */ + 10, 33, 45, KdSyncNegative, /* 59.940 */ + }, + + /* 800x600 modes */ + { 800, 600, 85, 56250, /* VESA */ + 32, 152, 248, KdSyncPositive, /* 53.674 */ + 1, 27, 31, KdSyncPositive, /* 85.061 */ + }, + { 800, 600, 75, 49500, /* VESA */ + 16, 160, 256, KdSyncPositive, /* 46.875 */ + 1, 21, 25, KdSyncPositive, /* 75.000 */ + }, + /* DEFAULT */ +#define MONITOR_TIMING_DEFAULT 9 + { 800, 600, 72, 50000, /* VESA */ + 56, 64, 240, KdSyncPositive, /* 48.077 */ + 37, 23, 66, KdSyncPositive, /* 72.188 */ + }, + { 800, 600, 60, 40000, /* VESA */ + 40, 88, 256, KdSyncPositive, /* 37.879 */ + 1, 23, 28, KdSyncPositive, /* 60.317 */ + }, + { 800, 600, 56, 36000, /* VESA */ + 24, 128, 224, KdSyncPositive, /* 35.156 */ + 1, 22, 25, KdSyncPositive, /* 56.250 */ + }, + + /* 1024x768 modes */ + { 1024, 768, 85, 94500, /* VESA */ + 48, 208, 352, KdSyncPositive, /* 68.677 */ + 1, 36, 40, KdSyncPositive, /* 84.997 */ + }, + { 1024, 768, 75, 78750, /* VESA */ + 16, 176, 288, KdSyncPositive, /* 60.023 */ + 1, 28, 32, KdSyncPositive, /* 75.029 */ + }, + { 1024, 768, 70, 75000, /* VESA */ + 24, 144, 304, KdSyncNegative, /* 56.476 */ + 3, 29, 38, KdSyncNegative, /* 70.069 */ + }, + { 1024, 768, 60, 65000, /* VESA */ + 24, 160, 320, KdSyncNegative, /* 48.363 */ + 3, 29, 38, KdSyncNegative, /* 60.004 */ + }, + + /* 1152x864 mode */ + { 1152, 864, 75, 108000, /* VESA */ + 64, 256, 448, KdSyncPositive, /* 67.500 */ + 1, 32, 36, KdSyncPositive, /* 75.000 */ + }, + + /* 1152x900 modes */ + { 1152, 900, 85, 122500, /* ADDED */ + 48, 208, 384, KdSyncPositive, /* 79.753 */ + 1, 32, 38, KdSyncPositive, /* 85.024 */ + }, + { 1152, 900, 75, 108250, /* ADDED */ + 32, 208, 384, KdSyncPositive, /* 70.475 */ + 1, 32, 38, KdSyncPositive, /* 75.133 */ + }, + { 1152, 900, 70, 100250, /* ADDED */ + 32, 208, 384, KdSyncPositive, /* 65.267 */ + 2, 32, 38, KdSyncPositive, /* 69.581 */ + }, + { 1152, 900, 66, 95000, /* ADDED */ + 32, 208, 384, KdSyncPositive, /* 61.849 */ + 1, 32, 38, KdSyncPositive, /* 65.937 */ + }, + + /* 1280x854 modes */ + { 1280, 854, 103, 12500, /* ADDED */ + 56, 16, 128, KdSyncPositive, /* 102.554 */ + 1, 216, 12, KdSyncPositive, + }, + + /* 1280x960 modes */ + { 1280, 960, 85, 148500, /* VESA */ + 64, 224, 448, KdSyncPositive, /* 85.938 */ + 1, 47, 51, KdSyncPositive, /* 85.002 */ + }, + { 1280, 960, 60, 108000, /* VESA */ + 96, 312, 520, KdSyncPositive, /* 60.000 */ + 1, 36, 40, KdSyncPositive, /* 60.000 */ + }, + + /* 1280x1024 modes */ + { 1280, 1024, 85, 157500, /* VESA */ + 64, 224, 448, KdSyncPositive, /* 91.146 */ + 1, 44, 48, KdSyncPositive, /* 85.024 */ + }, + { 1280, 1024, 75, 135000, /* VESA */ + 16, 248, 408, KdSyncPositive, /* 79.976 */ + 1, 38, 42, KdSyncPositive, /* 75.025 */ + }, + { 1280, 1024, 60, 108000, /* VESA */ + 48, 248, 408, KdSyncPositive, /* 63.981 */ + 1, 38, 42, KdSyncPositive, /* 60.020 */ + }, + + /* 1600x1200 modes */ + { 1600, 1200, 85, 229500, /* VESA */ + 64, 304, 560, KdSyncPositive, /* 106.250 */ + 1, 46, 50, KdSyncPositive, /* 85.000 */ + }, + { 1600, 1200, 75, 202500, /* VESA */ + 64, 304, 560, KdSyncPositive, /* 93.750 */ + 1, 46, 50, KdSyncPositive, /* 75.000 */ + }, + { 1600, 1200, 70, 189000, /* VESA */ + 64, 304, 560, KdSyncPositive, /* 87.500 */ + 1, 46, 50, KdSyncPositive, /* 70.000 */ + }, + { 1600, 1200, 65, 175500, /* VESA */ + 64, 304, 560, KdSyncPositive, /* 81.250 */ + 1, 46, 50, KdSyncPositive, /* 65.000 */ + }, + { 1600, 1200, 60, 162000, /* VESA */ + 64, 304, 560, KdSyncPositive, /* 75.000 */ + 1, 46, 50, KdSyncPositive, /* 60.000 */ + }, + + /* 1792x1344 modes */ + { 1792, 1344, 85, 301500, /* ADDED */ + 96, 352, 672, KdSyncNegative, /* 122.362 */ + 1, 92, 96, KdSyncPositive, /* 84.974 */ + }, + { 1792, 1344, 75, 261000, /* VESA */ + 96, 352, 664, KdSyncNegative, /* 106.270 */ + 1, 69, 73, KdSyncPositive, /* 74.997 */ + }, + { 1792, 1344, 60, 204750, /* VESA */ + 128, 328, 656, KdSyncNegative, /* 83.640 */ + 1, 46, 50, KdSyncPositive, /* 60.000 */ + }, + +#if 0 + { 1800, 1012, 75 }, + { 1906, 1072, 68 }, +#endif + + /* 1856x1392 modes */ + { 1856, 1392, 85, 330500, /* ADDED */ + 160, 352, 736, KdSyncNegative, /* 127.508 */ + 1, 104, 108, KdSyncPositive, /* 85.001 */ + }, + { 1856, 1392, 75, 288000, /* VESA */ + 128, 352, 704, KdSyncNegative, /* 112.500 */ + 1, 104, 108, KdSyncPositive, /* 75.000 */ + }, + { 1856, 1392, 60, 218250, /* VESA */ + 96, 352, 672, KdSyncNegative, /* 86.333 */ + 1, 43, 47, KdSyncPositive, /* 59.995 */ + }, + + /* 1920x1440 modes */ + { 1920, 1440, 85, 341750, /* ADDED */ + 160, 352, 760, KdSyncNegative, /* 127.512 */ + 1, 56, 60, KdSyncPositive, /* 85.012 */ + }, + { 1920, 1440, 75, 297000, /* VESA */ + 144, 352, 720, KdSyncNegative, /* 112.500 */ + 1, 56, 60, KdSyncPositive, /* 75.000 */ + }, + { 1920, 1440, 60, 234000, /* VESA */ + 128, 244, 680, KdSyncNegative, /* 90.000 */ + 1, 56, 60, KdSyncPositive, /* 60.000 */ + }, +}; + +#define NUM_MONITOR_TIMINGS (sizeof kdMonitorTimings/sizeof kdMonitorTimings[0]) + +const int kdNumMonitorTimings = NUM_MONITOR_TIMINGS; + +const KdMonitorTiming * +KdFindMode (KdScreenInfo *screen, + Bool (*supported) (KdScreenInfo *, + const KdMonitorTiming *)) +{ + int i; + const KdMonitorTiming *t; + + for (i = 0, t = kdMonitorTimings; i < NUM_MONITOR_TIMINGS; i++, t++) + { + if ((*supported) (screen, t) && + t->horizontal == screen->width && + t->vertical == screen->height && + (!screen->rate || t->rate <= screen->rate)) + { + return t; + } + } + ErrorF("Warning: mode not found, using default\n"); + return &kdMonitorTimings[MONITOR_TIMING_DEFAULT]; +} + +static const KdMonitorTiming * +kdFindPrevSize (const KdMonitorTiming *old) +{ + const KdMonitorTiming *new, *prev; + + if (old == kdMonitorTimings) + return 0; + new = old; + /* + * Search for the previous size + */ + while (new != kdMonitorTimings) + { + new--; + if (new->horizontal != old->horizontal && + new->vertical != old->vertical) + { + break; + } + } + /* + * Match the refresh rate (<=) + */ + while (new != kdMonitorTimings) + { + prev = new - 1; + if (prev->horizontal == new->horizontal && + prev->vertical == new->vertical && + prev->rate > old->rate) + { + break; + } + new--; + } + return new; +} + +Bool +KdTuneMode (KdScreenInfo *screen, + Bool (*usable) (KdScreenInfo *), + Bool (*supported) (KdScreenInfo *, + const KdMonitorTiming *)) +{ + const KdMonitorTiming *t; + + while (!(*usable) (screen)) + { + /* + * Fix requested depth and geometry until it works + */ + if (screen->fb[1].depth) + screen->fb[1].depth = 0; + else if (screen->fb[0].depth > 16) + screen->fb[0].depth = 16; + else if (screen->fb[0].depth > 8) + screen->fb[0].depth = 8; + else + { + t = kdFindPrevSize (KdFindMode (screen, supported)); + if (!t) + return FALSE; + screen->width = t->horizontal; + screen->height = t->vertical; + screen->rate = t->rate; + } + } + return TRUE; +} + +#ifdef RANDR +Bool +KdRandRGetInfo (ScreenPtr pScreen, + int randr, + Bool (*supported) (ScreenPtr pScreen, + const KdMonitorTiming *)) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + int i; + const KdMonitorTiming *t; + + for (i = 0, t = kdMonitorTimings; i < NUM_MONITOR_TIMINGS; i++, t++) + { + if ((*supported) (pScreen, t)) + { + RRScreenSizePtr pSize; + + pSize = RRRegisterSize (pScreen, + t->horizontal, + t->vertical, + screen->width_mm, + screen->height_mm); + if (!pSize) + return FALSE; + if (!RRRegisterRate (pScreen, pSize, t->rate)) + return FALSE; + if (t->horizontal == screen->width && + t->vertical == screen->height && + t->rate == screen->rate) + RRSetCurrentConfig (pScreen, randr, t->rate, pSize); + } + } + + return TRUE; +} + +const KdMonitorTiming * +KdRandRGetTiming (ScreenPtr pScreen, + Bool (*supported) (ScreenPtr pScreen, + const KdMonitorTiming *), + int rate, + RRScreenSizePtr pSize) +{ + int i; + const KdMonitorTiming *t; + + for (i = 0, t = kdMonitorTimings; i < NUM_MONITOR_TIMINGS; i++, t++) + { + if (t->horizontal == pSize->width && + t->vertical == pSize->height && + t->rate == rate && + (*supported) (pScreen, t)) + return t; + } + return 0; +} +#endif diff --git a/xorg-server/hw/kdrive/src/knoop.c b/xorg-server/hw/kdrive/src/knoop.c new file mode 100644 index 000000000..a3e9468ed --- /dev/null +++ b/xorg-server/hw/kdrive/src/knoop.c @@ -0,0 +1,251 @@ +/* + * 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. + */ + +/* + * GC ops that don't do anything + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include <gcstruct.h> + +typedef void (* typeFillSpans)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nInit*/, + DDXPointPtr /*pptInit*/, + int * /*pwidthInit*/, + int /*fSorted*/ +); + +typedef void (* typeSetSpans)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + char * /*psrc*/, + DDXPointPtr /*ppt*/, + int * /*pwidth*/, + int /*nspans*/, + int /*fSorted*/ +); + +typedef void (* typePutImage)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*depth*/, + int /*x*/, + int /*y*/, + int /*w*/, + int /*h*/, + int /*leftPad*/, + int /*format*/, + char * /*pBits*/ +); + +typedef RegionPtr (* typeCopyArea)( + DrawablePtr /*pSrc*/, + DrawablePtr /*pDst*/, + GCPtr /*pGC*/, + int /*srcx*/, + int /*srcy*/, + int /*w*/, + int /*h*/, + int /*dstx*/, + int /*dsty*/ +); + +typedef RegionPtr (* typeCopyPlane)( + DrawablePtr /*pSrcDrawable*/, + DrawablePtr /*pDstDrawable*/, + GCPtr /*pGC*/, + int /*srcx*/, + int /*srcy*/, + int /*width*/, + int /*height*/, + int /*dstx*/, + int /*dsty*/, + unsigned long /*bitPlane*/ +); +typedef void (* typePolyPoint)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/ +); + +typedef void (* typePolylines)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*mode*/, + int /*npt*/, + DDXPointPtr /*pptInit*/ +); + +typedef void (* typePolySegment)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nseg*/, + xSegment * /*pSegs*/ +); + +typedef void (* typePolyRectangle)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nrects*/, + xRectangle * /*pRects*/ +); + +typedef void (* typePolyArc)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +); + +typedef void (* typeFillPolygon)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*shape*/, + int /*mode*/, + int /*count*/, + DDXPointPtr /*pPts*/ +); + +typedef void (* typePolyFillRect)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*nrectFill*/, + xRectangle * /*prectInit*/ +); + +typedef void (* typePolyFillArc)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*narcs*/, + xArc * /*parcs*/ +); + +typedef int (* typePolyText8)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + int /*count*/, + char * /*chars*/ +); + +typedef int (* typePolyText16)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + int /*count*/, + unsigned short * /*chars*/ +); + +typedef void (* typeImageText8)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + int /*count*/, + char * /*chars*/ +); + +typedef void (* typeImageText16)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + int /*count*/, + unsigned short * /*chars*/ +); + +typedef void (* typeImageGlyphBlt)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +); + +typedef void (* typePolyGlyphBlt)( + DrawablePtr /*pDrawable*/, + GCPtr /*pGC*/, + int /*x*/, + int /*y*/, + unsigned int /*nglyph*/, + CharInfoPtr * /*ppci*/, + pointer /*pglyphBase*/ +); + +typedef void (* typePushPixels)( + GCPtr /*pGC*/, + PixmapPtr /*pBitMap*/, + DrawablePtr /*pDst*/, + int /*w*/, + int /*h*/, + int /*x*/, + int /*y*/ +); + +static RegionPtr +KdNoopCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, + int srcx, int srcy, int width, int height, int dstx, int dsty) +{ + return NullRegion; +} + +static RegionPtr +KdNoopCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, + int srcx, int srcy, int width, int height, + int dstx, int dsty, unsigned long bitPlane) +{ + return NullRegion; +} + +GCOps kdNoopOps = { + (typeFillSpans) NoopDDA, /* fill spans */ + (typeSetSpans) NoopDDA, /* set spans */ + (typePutImage) NoopDDA, /* put image */ + KdNoopCopyArea, /* copy area */ + KdNoopCopyPlane, /* copy plane */ + (typePolyPoint) NoopDDA, /* poly point */ + (typePolylines) NoopDDA, /* poly lines */ + (typePolySegment) NoopDDA, /* poly segment */ + (typePolyRectangle) NoopDDA, /* poly rectangle */ + (typePolyArc) NoopDDA, /* poly arc */ + (typeFillPolygon) NoopDDA, /* fill polygon */ + (typePolyFillRect) NoopDDA, /* poly fillrect */ + (typePolyFillArc) NoopDDA, /* poly fillarc */ + (typePolyText8) NoopDDA, /* text 8 */ + (typePolyText16) NoopDDA, /* text 16 */ + (typeImageText8) NoopDDA, /* itext 8 */ + (typeImageText16) NoopDDA, /* itext 16 */ + (typePolyGlyphBlt) NoopDDA, /* glyph blt */ + (typeImageGlyphBlt) NoopDDA, /* iglyph blt */ + (typePushPixels) NoopDDA, /* push pixels */ +}; diff --git a/xorg-server/hw/kdrive/src/koffscreen.c b/xorg-server/hw/kdrive/src/koffscreen.c new file mode 100644 index 000000000..efe03642f --- /dev/null +++ b/xorg-server/hw/kdrive/src/koffscreen.c @@ -0,0 +1,375 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" +#include "kaa.h" + +#define DEBUG_OFFSCREEN 0 +#if DEBUG_OFFSCREEN +#define DBG_OFFSCREEN(a) ErrorF a +#else +#define DBG_OFFSCREEN(a) +#endif + +#if DEBUG_OFFSCREEN +static void +KdOffscreenValidate (ScreenPtr pScreen) +{ + KdScreenPriv (pScreen); + KdOffscreenArea *prev = 0, *area; + + assert (pScreenPriv->screen->off_screen_areas->area.offset == 0); + for (area = pScreenPriv->off_screen_areas; area; area = area->next) + { + if (prev) + assert (prev->offset + prev->size == area->offset); + + prev = area; + } + assert (prev->offset + prev->size == pScreenPriv->screen->memory_size); +} +#else +#define KdOffscreenValidate(s) +#endif + +static KdOffscreenArea * +KdOffscreenKickOut (ScreenPtr pScreen, KdOffscreenArea *area) +{ + if (area->save) + (*area->save) (pScreen, area); + return KdOffscreenFree (pScreen, area); +} + +KdOffscreenArea * +KdOffscreenAlloc (ScreenPtr pScreen, int size, int align, + Bool locked, + KdOffscreenSaveProc save, + pointer privData) +{ + KdOffscreenArea *area, *begin, *best; + KdScreenPriv (pScreen); + int tmp, real_size = 0, best_score; + + KdOffscreenValidate (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 > (pScreenPriv->screen->memory_size - pScreenPriv->screen->off_screen_base)) + { + DBG_OFFSCREEN (("Alloc 0x%x -> TOBIG\n", size)); + return NULL; + } + + /* Try to find a free space that'll fit. */ + for (area = pScreenPriv->off_screen_areas; area; area = area->next) + { + /* skip allocated areas */ + if (area->state != KdOffscreenAvail) + continue; + + /* adjust size to match alignment requirement */ + real_size = size; + tmp = area->offset % align; + if (tmp) + real_size += (align - tmp); + + /* does it fit? */ + if (real_size <= area->size) + break; + } + + if (!area) + { + /* + * Kick out existing users to make space. + * + * First, locate a region which can hold the desired object. + */ + + /* prev points at the first object to boot */ + best = NULL; + best_score = MAXINT; + for (begin = pScreenPriv->off_screen_areas; begin != NULL; + begin = begin->next) + { + int avail, score; + KdOffscreenArea *scan; + + if (begin->state == KdOffscreenLocked) + continue; + + /* adjust size to match alignment requirement */ + real_size = size; + tmp = begin->offset % align; + if (tmp) + real_size += (align - tmp); + + avail = 0; + score = 0; + /* now see if we can make room here, and how "costly" it'll be. */ + for (scan = begin; scan != NULL; scan = scan->next) + { + if (scan->state == KdOffscreenLocked) { + /* Can't make room here, start after this locked area. */ + begin = scan->next; + break; + } + /* Score should only be non-zero for KdOffscreenRemovable */ + score += scan->score; + avail += scan->size; + if (avail >= real_size) + break; + } + /* Is it the best option we've found so far? */ + if (avail >= real_size && score < best_score) { + best = begin; + best_score = score; + } + } + area = best; + if (!area) + { + DBG_OFFSCREEN (("Alloc 0x%x -> NOSPACE\n", size)); + /* Could not allocate memory */ + KdOffscreenValidate (pScreen); + return NULL; + } + + /* adjust size to match alignment requirement */ + real_size = size; + tmp = begin->offset % align; + if (tmp) + real_size += (align - tmp); + + /* + * Kick out first area if in use + */ + if (area->state != KdOffscreenAvail) + area = KdOffscreenKickOut (pScreen, area); + /* + * Now get the system to merge the other needed areas together + */ + while (area->size < real_size) + { + assert (area->next && area->next->state == KdOffscreenRemovable); + (void) KdOffscreenKickOut (pScreen, area->next); + } + } + + /* save extra space in new area */ + if (real_size < area->size) + { + KdOffscreenArea *new_area = xalloc (sizeof (KdOffscreenArea)); + if (!new_area) + return NULL; + new_area->offset = area->offset + real_size; + new_area->size = area->size - real_size; + new_area->state = KdOffscreenAvail; + new_area->save = 0; + new_area->score = 0; + new_area->next = area->next; + area->next = new_area; + area->size = real_size; + } + /* + * Mark this area as in use + */ + if (locked) + area->state = KdOffscreenLocked; + else + area->state = KdOffscreenRemovable; + area->privData = privData; + area->save = save; + area->score = 0; + + area->save_offset = area->offset; + { + int tmp = area->offset % align; + if (tmp) + area->offset += (align - tmp); + } + + KdOffscreenValidate (pScreen); + + DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, area->offset)); + return area; +} + +void +KdOffscreenSwapOut (ScreenPtr pScreen) +{ + KdScreenPriv (pScreen); + + KdOffscreenValidate (pScreen); + /* loop until a single free area spans the space */ + for (;;) + { + KdOffscreenArea *area = pScreenPriv->off_screen_areas; + + if (!area) + break; + if (area->state == KdOffscreenAvail) + { + area = area->next; + if (!area) + break; + } + assert (area->state != KdOffscreenAvail); + (void) KdOffscreenKickOut (pScreen, area); + KdOffscreenValidate (pScreen); + } + KdOffscreenValidate (pScreen); + KdOffscreenFini (pScreen); +} + +void +KdOffscreenSwapIn (ScreenPtr pScreen) +{ + KdOffscreenInit (pScreen); +} + +/* merge the next free area into this one */ +static void +KdOffscreenMerge (KdOffscreenArea *area) +{ + KdOffscreenArea *next = area->next; + + /* account for space */ + area->size += next->size; + /* frob pointer */ + area->next = next->next; + xfree (next); +} + +KdOffscreenArea * +KdOffscreenFree (ScreenPtr pScreen, KdOffscreenArea *area) +{ + KdScreenPriv(pScreen); + KdOffscreenArea *next = area->next; + KdOffscreenArea *prev; + + DBG_OFFSCREEN (("Free 0x%x -> 0x%x\n", area->size, area->offset)); + KdOffscreenValidate (pScreen); + + area->state = KdOffscreenAvail; + area->save = 0; + area->offset = area->save_offset; + area->score = 0; + + /* + * Find previous area + */ + if (area == pScreenPriv->off_screen_areas) + prev = 0; + else + for (prev = pScreenPriv->off_screen_areas; prev; prev = prev->next) + if (prev->next == area) + break; + + /* link with next area if free */ + if (next && next->state == KdOffscreenAvail) + KdOffscreenMerge (area); + + /* link with prev area if free */ + if (prev && prev->state == KdOffscreenAvail) + { + area = prev; + KdOffscreenMerge (area); + } + + KdOffscreenValidate (pScreen); + return area; +} + +void +KdOffscreenMarkUsed (PixmapPtr pPixmap) +{ + KaaPixmapPriv (pPixmap); + KdScreenPriv (pPixmap->drawable.pScreen); + static int iter = 0; + + if (!pKaaPixmap->area) + return; + + /* The numbers here are arbitrary. We may want to tune these. */ + pKaaPixmap->area->score += 100; + if (++iter == 10) { + KdOffscreenArea *area; + for (area = pScreenPriv->off_screen_areas; area != NULL; + area = area->next) + { + if (area->state == KdOffscreenRemovable) + area->score = (area->score * 7) / 8; + } + } +} + +Bool +KdOffscreenInit (ScreenPtr pScreen) +{ + KdScreenPriv (pScreen); + KdOffscreenArea *area; + + /* Allocate a big free area */ + area = xalloc (sizeof (KdOffscreenArea)); + + if (!area) + return FALSE; + + area->state = KdOffscreenAvail; + area->offset = pScreenPriv->screen->off_screen_base; + area->size = pScreenPriv->screen->memory_size - area->offset; + area->save = 0; + area->next = NULL; + area->score = 0; + + /* Add it to the free areas */ + pScreenPriv->off_screen_areas = area; + + KdOffscreenValidate (pScreen); + + return TRUE; +} + +void +KdOffscreenFini (ScreenPtr pScreen) +{ + KdScreenPriv (pScreen); + KdOffscreenArea *area; + + /* just free all of the area records */ + while ((area = pScreenPriv->off_screen_areas)) + { + pScreenPriv->off_screen_areas = area->next; + xfree (area); + } +} diff --git a/xorg-server/hw/kdrive/src/kshadow.c b/xorg-server/hw/kdrive/src/kshadow.c new file mode 100644 index 000000000..ea44812db --- /dev/null +++ b/xorg-server/hw/kdrive/src/kshadow.c @@ -0,0 +1,83 @@ +/* + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" + +Bool +KdShadowFbAlloc (KdScreenInfo *screen, int fb, Bool rotate) +{ + int paddedWidth; + void *buf; + int width = rotate ? screen->height : screen->width; + int height = rotate ? screen->width : screen->height; + int bpp = screen->fb[fb].bitsPerPixel; + + /* use fb computation for width */ + paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits); + buf = xalloc (paddedWidth * height); + if (!buf) + return FALSE; + if (screen->fb[fb].shadow) + xfree (screen->fb[fb].frameBuffer); + screen->fb[fb].shadow = TRUE; + screen->fb[fb].frameBuffer = buf; + screen->fb[fb].byteStride = paddedWidth; + screen->fb[fb].pixelStride = paddedWidth * 8 / bpp; + return TRUE; +} + +void +KdShadowFbFree (KdScreenInfo *screen, int fb) +{ + if (screen->fb[fb].shadow) + { + xfree (screen->fb[fb].frameBuffer); + screen->fb[fb].frameBuffer = 0; + screen->fb[fb].shadow = FALSE; + } +} + +Bool +KdShadowSet (ScreenPtr pScreen, int randr, ShadowUpdateProc update, ShadowWindowProc window) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + int fb; + + shadowRemove (pScreen, pScreen->GetScreenPixmap(pScreen)); + for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++) + { + if (screen->fb[fb].shadow) + return shadowAdd (pScreen, pScreen->GetScreenPixmap(pScreen), + update, window, randr, 0); + } + return TRUE; +} + +void +KdShadowUnset (ScreenPtr pScreen) +{ + shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen)); +} diff --git a/xorg-server/hw/kdrive/src/ktest.c b/xorg-server/hw/kdrive/src/ktest.c new file mode 100644 index 000000000..150af5639 --- /dev/null +++ b/xorg-server/hw/kdrive/src/ktest.c @@ -0,0 +1,76 @@ +/* + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" + + +static CARD8 memoryPatterns[] = { 0xff, 0x00, 0x5a, 0xa5, 0xaa, 0x55 }; + +#define NUM_PATTERNS (sizeof (memoryPatterns) / sizeof (memoryPatterns[0])) + +Bool +KdFrameBufferValid (CARD8 *base, int size) +{ + volatile CARD8 *b = (volatile CARD8 *) base; + CARD8 save, test, compare; + int i, j; + + b = base + (size - 1); + save = *b; + + for (i = 0; i < NUM_PATTERNS; i++) + { + test = memoryPatterns[i]; + *b = test; + for (j = 0; j < 1000; j++) + { + compare = *b; + if (compare != test) + return FALSE; + } + } + *b = save; + return TRUE; +} + +int +KdFrameBufferSize (CARD8 *base, int max) +{ + int min, cur; + + min = 0; + while (min + 1 < max) + { + cur = (max + min) / 2; + if (KdFrameBufferValid (base, cur)) + min = cur; + else + max = cur; + } + if (KdFrameBufferValid (base, max)) + return max; + else + return min; +} diff --git a/xorg-server/hw/kdrive/src/kxv.c b/xorg-server/hw/kdrive/src/kxv.c new file mode 100644 index 000000000..0b8d1c4e0 --- /dev/null +++ b/xorg-server/hw/kdrive/src/kxv.c @@ -0,0 +1,1954 @@ +/* + + XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com) + Adapted for KDrive by Pontus Lidman <pontus.lidman@nokia.com> + + Copyright (C) 2000, 2001 - Nokia Home Communications + Copyright (C) 1998, 1999 - 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, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +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 +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +*/ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "kdrive.h" + +#include "scrnintstr.h" +#include "regionstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "mivalidate.h" +#include "validate.h" +#include "resource.h" +#include "gcstruct.h" +#include "dixstruct.h" + +#include <X11/extensions/Xv.h> +#include <X11/extensions/Xvproto.h> + +#include "kxv.h" +#include "fourcc.h" + + +/* XvScreenRec fields */ + +static Bool KdXVCloseScreen(int, ScreenPtr); +static int KdXVQueryAdaptors(ScreenPtr, XvAdaptorPtr *, int *); + +/* XvAdaptorRec fields */ + +static int KdXVAllocatePort(unsigned long, XvPortPtr, XvPortPtr*); +static int KdXVFreePort(XvPortPtr); +static int KdXVPutVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +static int KdXVPutStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +static int KdXVGetVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +static int KdXVGetStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +static int KdXVStopVideo(ClientPtr, XvPortPtr, DrawablePtr); +static int KdXVSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32); +static int KdXVGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32 *); +static int KdXVQueryBestSize(ClientPtr, XvPortPtr, CARD8, + CARD16, CARD16,CARD16, CARD16, + unsigned int*, unsigned int*); +static int KdXVPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16, + XvImagePtr, unsigned char*, Bool, + CARD16, CARD16); +static int KdXVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr, + CARD16*, CARD16*, int*, int*); + + +/* ScreenRec fields */ + +static Bool KdXVCreateWindow(WindowPtr pWin); +static Bool KdXVDestroyWindow(WindowPtr pWin); +static void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2); +static void KdXVClipNotify(WindowPtr pWin, int dx, int dy); + +/* misc */ +static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr*, int); + + +DevPrivateKey KdXVWindowKey = &KdXVWindowKey; +DevPrivateKey KdXvScreenKey = &KdXvScreenKey; +static unsigned long KdXVGeneration = 0; +static unsigned long PortResource = 0; + +DevPrivateKey (*XvGetScreenKeyProc)(void) = XvGetScreenKey; +unsigned long (*XvGetRTPortProc)(void) = XvGetRTPort; +int (*XvScreenInitProc)(ScreenPtr) = XvScreenInit; + +#define GET_XV_SCREEN(pScreen) ((XvScreenPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, KdXvScreenKey)) + +#define GET_KDXV_SCREEN(pScreen) \ + ((KdXVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr)) + +#define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \ + dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey)) + +static KdXVInitGenericAdaptorPtr *GenDrivers = NULL; +static int NumGenDrivers = 0; + +int +KdXVRegisterGenericAdaptorDriver( + KdXVInitGenericAdaptorPtr InitFunc +){ + KdXVInitGenericAdaptorPtr *newdrivers; + +/* fprintf(stderr,"KdXVRegisterGenericAdaptorDriver\n"); */ + + newdrivers = xrealloc(GenDrivers, sizeof(KdXVInitGenericAdaptorPtr) * + (1 + NumGenDrivers)); + if (!newdrivers) + return 0; + GenDrivers = newdrivers; + + GenDrivers[NumGenDrivers++] = InitFunc; + + return 1; +} + +int +KdXVListGenericAdaptors( + KdScreenInfo * screen, + KdVideoAdaptorPtr **adaptors +){ + int i,j,n,num; + KdVideoAdaptorPtr *DrivAdap,*new; + + num = 0; + *adaptors = NULL; + for (i = 0; i < NumGenDrivers; i++) { + n = GenDrivers[i](screen,&DrivAdap); + if (0 == n) + continue; + new = xrealloc(*adaptors, sizeof(KdVideoAdaptorPtr) * (num+n)); + if (NULL == new) + continue; + *adaptors = new; + for (j = 0; j < n; j++, num++) + (*adaptors)[num] = DrivAdap[j]; + } + return num; +} + +KdVideoAdaptorPtr +KdXVAllocateVideoAdaptorRec(KdScreenInfo * screen) +{ + return xcalloc(1, sizeof(KdVideoAdaptorRec)); +} + +void +KdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr) +{ + xfree(ptr); +} + + +Bool +KdXVScreenInit( + ScreenPtr pScreen, + KdVideoAdaptorPtr *adaptors, + int num +){ + KdXVScreenPtr ScreenPriv; + XvScreenPtr pxvs; + +/* fprintf(stderr,"KdXVScreenInit initializing %d adaptors\n",num); */ + + if (KdXVGeneration != serverGeneration) + KdXVGeneration = serverGeneration; + + if(!XvGetScreenKeyProc || !XvGetRTPortProc || !XvScreenInitProc) + return FALSE; + + if(Success != (*XvScreenInitProc)(pScreen)) return FALSE; + + KdXvScreenKey = (*XvGetScreenKeyProc)(); + PortResource = (*XvGetRTPortProc)(); + + pxvs = GET_XV_SCREEN(pScreen); + + + /* Anyone initializing the Xv layer must provide these two. + The Xv di layer calls them without even checking if they exist! */ + + pxvs->ddCloseScreen = KdXVCloseScreen; + pxvs->ddQueryAdaptors = KdXVQueryAdaptors; + + /* The Xv di layer provides us with a private hook so that we don't + have to allocate our own screen private. They also provide + a CloseScreen hook so that we don't have to wrap it. I'm not + sure that I appreciate that. */ + + ScreenPriv = xalloc(sizeof(KdXVScreenRec)); + pxvs->devPriv.ptr = (pointer)ScreenPriv; + + if(!ScreenPriv) return FALSE; + + + ScreenPriv->CreateWindow = pScreen->CreateWindow; + ScreenPriv->DestroyWindow = pScreen->DestroyWindow; + ScreenPriv->WindowExposures = pScreen->WindowExposures; + ScreenPriv->ClipNotify = pScreen->ClipNotify; + +/* fprintf(stderr,"XV: Wrapping screen funcs\n"); */ + + pScreen->CreateWindow = KdXVCreateWindow; + pScreen->DestroyWindow = KdXVDestroyWindow; + pScreen->WindowExposures = KdXVWindowExposures; + pScreen->ClipNotify = KdXVClipNotify; + + if(!KdXVInitAdaptors(pScreen, adaptors, num)) + return FALSE; + + return TRUE; +} + +static void +KdXVFreeAdaptor(XvAdaptorPtr pAdaptor) +{ + int i; + + if(pAdaptor->name) + xfree(pAdaptor->name); + + if(pAdaptor->pEncodings) { + XvEncodingPtr pEncode = pAdaptor->pEncodings; + + for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++) { + if(pEncode->name) xfree(pEncode->name); + } + xfree(pAdaptor->pEncodings); + } + + if(pAdaptor->pFormats) + xfree(pAdaptor->pFormats); + + if(pAdaptor->pPorts) { + XvPortPtr pPort = pAdaptor->pPorts; + XvPortRecPrivatePtr pPriv; + + for(i = 0; i < pAdaptor->nPorts; i++, pPort++) { + pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr; + if(pPriv) { + if(pPriv->clientClip) + REGION_DESTROY(pAdaptor->pScreen, pPriv->clientClip); + if(pPriv->pCompositeClip && pPriv->FreeCompositeClip) + REGION_DESTROY(pAdaptor->pScreen, pPriv->pCompositeClip); + xfree(pPriv); + } + } + xfree(pAdaptor->pPorts); + } + + if(pAdaptor->nAttributes) { + XvAttributePtr pAttribute = pAdaptor->pAttributes; + + for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++) { + if(pAttribute->name) xfree(pAttribute->name); + } + + xfree(pAdaptor->pAttributes); + } + + if(pAdaptor->nImages) + xfree(pAdaptor->pImages); + + if(pAdaptor->devPriv.ptr) + xfree(pAdaptor->devPriv.ptr); +} + +static Bool +KdXVInitAdaptors( + ScreenPtr pScreen, + KdVideoAdaptorPtr *infoPtr, + int number +) { + KdScreenPriv(pScreen); + KdScreenInfo * screen = pScreenPriv->screen; + + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); + KdVideoAdaptorPtr adaptorPtr; + XvAdaptorPtr pAdaptor, pa; + XvAdaptorRecPrivatePtr adaptorPriv; + int na, numAdaptor; + XvPortRecPrivatePtr portPriv; + XvPortPtr pPort, pp; + int numPort; + KdAttributePtr attributePtr; + XvAttributePtr pAttribute, pat; + KdVideoFormatPtr formatPtr; + XvFormatPtr pFormat, pf; + int numFormat, totFormat; + KdVideoEncodingPtr encodingPtr; + XvEncodingPtr pEncode, pe; + KdImagePtr imagePtr; + XvImagePtr pImage, pi; + int numVisuals; + VisualPtr pVisual; + int i; + + pxvs->nAdaptors = 0; + pxvs->pAdaptors = NULL; + + if(!(pAdaptor = xcalloc(number, sizeof(XvAdaptorRec)))) + return FALSE; + + for(pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) { + adaptorPtr = infoPtr[na]; + + if(!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute || + !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize) + continue; + + /* client libs expect at least one encoding */ + if(!adaptorPtr->nEncodings || !adaptorPtr->pEncodings) + continue; + + pa->type = adaptorPtr->type; + + if(!adaptorPtr->PutVideo && !adaptorPtr->GetVideo) + pa->type &= ~XvVideoMask; + + if(!adaptorPtr->PutStill && !adaptorPtr->GetStill) + pa->type &= ~XvStillMask; + + if(!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes) + pa->type &= ~XvImageMask; + + if(!adaptorPtr->PutVideo && !adaptorPtr->PutImage && + !adaptorPtr->PutStill) + pa->type &= ~XvInputMask; + + if(!adaptorPtr->GetVideo && !adaptorPtr->GetStill) + pa->type &= ~XvOutputMask; + + if(!(adaptorPtr->type & (XvPixmapMask | XvWindowMask))) + continue; + if(!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask))) + continue; + + pa->pScreen = pScreen; + pa->ddAllocatePort = KdXVAllocatePort; + pa->ddFreePort = KdXVFreePort; + pa->ddPutVideo = KdXVPutVideo; + pa->ddPutStill = KdXVPutStill; + pa->ddGetVideo = KdXVGetVideo; + pa->ddGetStill = KdXVGetStill; + pa->ddStopVideo = KdXVStopVideo; + pa->ddPutImage = KdXVPutImage; + pa->ddSetPortAttribute = KdXVSetPortAttribute; + pa->ddGetPortAttribute = KdXVGetPortAttribute; + pa->ddQueryBestSize = KdXVQueryBestSize; + pa->ddQueryImageAttributes = KdXVQueryImageAttributes; + if((pa->name = xalloc(strlen(adaptorPtr->name) + 1))) + strcpy(pa->name, adaptorPtr->name); + + if(adaptorPtr->nEncodings && + (pEncode = xcalloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) { + + for(pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0; + i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++) + { + pe->id = encodingPtr->id; + pe->pScreen = pScreen; + if((pe->name = xalloc(strlen(encodingPtr->name) + 1))) + strcpy(pe->name, encodingPtr->name); + pe->width = encodingPtr->width; + pe->height = encodingPtr->height; + pe->rate.numerator = encodingPtr->rate.numerator; + pe->rate.denominator = encodingPtr->rate.denominator; + } + pa->nEncodings = adaptorPtr->nEncodings; + pa->pEncodings = pEncode; + } + + if(adaptorPtr->nImages && + (pImage = xcalloc(adaptorPtr->nImages, sizeof(XvImageRec)))) { + + for(i = 0, pi = pImage, imagePtr = adaptorPtr->pImages; + i < adaptorPtr->nImages; i++, pi++, imagePtr++) + { + pi->id = imagePtr->id; + pi->type = imagePtr->type; + pi->byte_order = imagePtr->byte_order; + memcpy(pi->guid, imagePtr->guid, 16); + pi->bits_per_pixel = imagePtr->bits_per_pixel; + pi->format = imagePtr->format; + pi->num_planes = imagePtr->num_planes; + pi->depth = imagePtr->depth; + pi->red_mask = imagePtr->red_mask; + pi->green_mask = imagePtr->green_mask; + pi->blue_mask = imagePtr->blue_mask; + pi->y_sample_bits = imagePtr->y_sample_bits; + pi->u_sample_bits = imagePtr->u_sample_bits; + pi->v_sample_bits = imagePtr->v_sample_bits; + pi->horz_y_period = imagePtr->horz_y_period; + pi->horz_u_period = imagePtr->horz_u_period; + pi->horz_v_period = imagePtr->horz_v_period; + pi->vert_y_period = imagePtr->vert_y_period; + pi->vert_u_period = imagePtr->vert_u_period; + pi->vert_v_period = imagePtr->vert_v_period; + memcpy(pi->component_order, imagePtr->component_order, 32); + pi->scanline_order = imagePtr->scanline_order; + } + pa->nImages = adaptorPtr->nImages; + pa->pImages = pImage; + } + + if(adaptorPtr->nAttributes && + (pAttribute = xcalloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) + { + for(pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0; + i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) + { + pat->flags = attributePtr->flags; + pat->min_value = attributePtr->min_value; + pat->max_value = attributePtr->max_value; + if((pat->name = xalloc(strlen(attributePtr->name) + 1))) + strcpy(pat->name, attributePtr->name); + } + pa->nAttributes = adaptorPtr->nAttributes; + pa->pAttributes = pAttribute; + } + + + totFormat = adaptorPtr->nFormats; + + if(!(pFormat = xcalloc(totFormat, sizeof(XvFormatRec)))) { + KdXVFreeAdaptor(pa); + continue; + } + for(pf = pFormat, i = 0, numFormat = 0, formatPtr = adaptorPtr->pFormats; + i < adaptorPtr->nFormats; i++, formatPtr++) + { + numVisuals = pScreen->numVisuals; + pVisual = pScreen->visuals; + + while(numVisuals--) { + if((pVisual->class == formatPtr->class) && + (pVisual->nplanes == formatPtr->depth)) { + + if(numFormat >= totFormat) { + void *moreSpace; + totFormat *= 2; + moreSpace = xrealloc(pFormat, + totFormat * sizeof(XvFormatRec)); + if(!moreSpace) break; + pFormat = moreSpace; + pf = pFormat + numFormat; + } + + pf->visual = pVisual->vid; + pf->depth = formatPtr->depth; + + pf++; + numFormat++; + } + pVisual++; + } + } + pa->nFormats = numFormat; + pa->pFormats = pFormat; + if(!numFormat) { + KdXVFreeAdaptor(pa); + continue; + } + + if(!(adaptorPriv = xcalloc(1, sizeof(XvAdaptorRecPrivate)))) { + KdXVFreeAdaptor(pa); + continue; + } + + adaptorPriv->flags = adaptorPtr->flags; + adaptorPriv->PutVideo = adaptorPtr->PutVideo; + adaptorPriv->PutStill = adaptorPtr->PutStill; + adaptorPriv->GetVideo = adaptorPtr->GetVideo; + adaptorPriv->GetStill = adaptorPtr->GetStill; + adaptorPriv->StopVideo = adaptorPtr->StopVideo; + adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute; + adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute; + adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize; + adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes; + adaptorPriv->PutImage = adaptorPtr->PutImage; + adaptorPriv->ReputImage = adaptorPtr->ReputImage; + + pa->devPriv.ptr = (pointer)adaptorPriv; + + if(!(pPort = xcalloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) { + KdXVFreeAdaptor(pa); + continue; + } + for(pp = pPort, i = 0, numPort = 0; + i < adaptorPtr->nPorts; i++) { + + if(!(pp->id = FakeClientID(0))) + continue; + + if(!(portPriv = xcalloc(1, sizeof(XvPortRecPrivate)))) + continue; + + if(!AddResource(pp->id, PortResource, pp)) { + xfree(portPriv); + continue; + } + + pp->pAdaptor = pa; + pp->pNotify = (XvPortNotifyPtr)NULL; + pp->pDraw = (DrawablePtr)NULL; + pp->client = (ClientPtr)NULL; + pp->grab.client = (ClientPtr)NULL; + pp->time = currentTime; + pp->devPriv.ptr = portPriv; + + portPriv->screen = screen; + portPriv->AdaptorRec = adaptorPriv; + portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr; + + pp++; + numPort++; + } + pa->nPorts = numPort; + pa->pPorts = pPort; + if(!numPort) { + KdXVFreeAdaptor(pa); + continue; + } + + pa->base_id = pPort->id; + + pa++; + numAdaptor++; + } + + if(numAdaptor) { + pxvs->nAdaptors = numAdaptor; + pxvs->pAdaptors = pAdaptor; + } else { + xfree(pAdaptor); + return FALSE; + } + + return TRUE; +} + +/* Video should be clipped to the intersection of the window cliplist + and the client cliplist specified in the GC for which the video was + initialized. When we need to reclip a window, the GC that started + the video may not even be around anymore. That's why we save the + client clip from the GC when the video is initialized. We then + use KdXVUpdateCompositeClip to calculate the new composite clip + when we need it. This is different from what DEC did. They saved + the GC and used it's clip list when they needed to reclip the window, + even if the client clip was different from the one the video was + initialized with. If the original GC was destroyed, they had to stop + the video. I like the new method better (MArk). + + This function only works for windows. Will need to rewrite when + (if) we support pixmap rendering. +*/ + +static void +KdXVUpdateCompositeClip(XvPortRecPrivatePtr portPriv) +{ + RegionPtr pregWin, pCompositeClip; + WindowPtr pWin; + Bool freeCompClip = FALSE; + + if(portPriv->pCompositeClip) + return; + + pWin = (WindowPtr)portPriv->pDraw; + + /* get window clip list */ + if(portPriv->subWindowMode == IncludeInferiors) { + pregWin = NotClippedByChildren(pWin); + freeCompClip = TRUE; + } else + pregWin = &pWin->clipList; + + if(!portPriv->clientClip) { + portPriv->pCompositeClip = pregWin; + portPriv->FreeCompositeClip = freeCompClip; + return; + } + + pCompositeClip = REGION_CREATE(pWin->pScreen, NullBox, 1); + REGION_COPY(pWin->pScreen, pCompositeClip, portPriv->clientClip); + REGION_TRANSLATE(pWin->pScreen, pCompositeClip, + portPriv->pDraw->x + portPriv->clipOrg.x, + portPriv->pDraw->y + portPriv->clipOrg.y); + REGION_INTERSECT(pWin->pScreen, pCompositeClip, pregWin, pCompositeClip); + + portPriv->pCompositeClip = pCompositeClip; + portPriv->FreeCompositeClip = TRUE; + + if(freeCompClip) { + REGION_DESTROY(pWin->pScreen, pregWin); + } +} + +/* Save the current clientClip and update the CompositeClip whenever + we have a fresh GC */ + +static void +KdXVCopyClip( + XvPortRecPrivatePtr portPriv, + GCPtr pGC +){ + /* copy the new clip if it exists */ + if((pGC->clientClipType == CT_REGION) && pGC->clientClip) { + if(!portPriv->clientClip) + portPriv->clientClip = REGION_CREATE(pGC->pScreen, NullBox, 1); + /* Note: this is in window coordinates */ + REGION_COPY(pGC->pScreen, portPriv->clientClip, pGC->clientClip); + } else if(portPriv->clientClip) { /* free the old clientClip */ + REGION_DESTROY(pGC->pScreen, portPriv->clientClip); + portPriv->clientClip = NULL; + } + + /* get rid of the old clip list */ + if(portPriv->pCompositeClip && portPriv->FreeCompositeClip) { + REGION_DESTROY(pWin->pScreen, portPriv->pCompositeClip); + } + + portPriv->clipOrg = pGC->clipOrg; + portPriv->pCompositeClip = pGC->pCompositeClip; + portPriv->FreeCompositeClip = FALSE; + portPriv->subWindowMode = pGC->subWindowMode; +} + +static int +KdXVRegetVideo(XvPortRecPrivatePtr portPriv) +{ + RegionRec WinRegion; + RegionRec ClipRegion; + BoxRec WinBox; + int ret = Success; + Bool clippedAway = FALSE; + + KdXVUpdateCompositeClip(portPriv); + + /* translate the video region to the screen */ + WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x; + WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y; + WinBox.x2 = WinBox.x1 + portPriv->drw_w; + WinBox.y2 = WinBox.y1 + portPriv->drw_h; + + /* clip to the window composite clip */ + REGION_INIT(portPriv->pDraw->pScreen, &WinRegion, &WinBox, 1); + REGION_INIT(portPriv->pDraw->pScreen, &ClipRegion, NullBox, 1); + REGION_INTERSECT(portPriv->pDraw->pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip); + + /* that's all if it's totally obscured */ + if(!REGION_NOTEMPTY(portPriv->pDraw->pScreen, &ClipRegion)) { + clippedAway = TRUE; + goto CLIP_VIDEO_BAILOUT; + } + + if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { + REGION_SUBTRACT(portPriv->pDraw->pScreen, &ClipRegion, &WinRegion, &ClipRegion); + } + + ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->screen, portPriv->pDraw, + portPriv->vid_x, portPriv->vid_y, + WinBox.x1, WinBox.y1, + portPriv->vid_w, portPriv->vid_h, + portPriv->drw_w, portPriv->drw_h, + &ClipRegion, portPriv->DevPriv.ptr); + + if(ret == Success) + portPriv->isOn = XV_ON; + +CLIP_VIDEO_BAILOUT: + + if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) { + (*portPriv->AdaptorRec->StopVideo)( + portPriv->screen, portPriv->DevPriv.ptr, FALSE); + portPriv->isOn = XV_PENDING; + } + + /* This clip was copied and only good for one shot */ + if(!portPriv->FreeCompositeClip) + portPriv->pCompositeClip = NULL; + + REGION_UNINIT(portPriv->pDraw->pScreen, &WinRegion); + REGION_UNINIT(portPriv->pDraw->pScreen, &ClipRegion); + + return ret; +} + + +static int +KdXVReputVideo(XvPortRecPrivatePtr portPriv) +{ + RegionRec WinRegion; + RegionRec ClipRegion; + BoxRec WinBox; + ScreenPtr pScreen = portPriv->pDraw->pScreen; + KdScreenPriv(pScreen); + KdScreenInfo *screen=pScreenPriv->screen; + int ret = Success; + Bool clippedAway = FALSE; + + KdXVUpdateCompositeClip(portPriv); + + /* translate the video region to the screen */ + WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x; + WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y; + WinBox.x2 = WinBox.x1 + portPriv->drw_w; + WinBox.y2 = WinBox.y1 + portPriv->drw_h; + + /* clip to the window composite clip */ + REGION_INIT(pScreen, &WinRegion, &WinBox, 1); + REGION_INIT(pScreen, &ClipRegion, NullBox, 1); + REGION_INTERSECT(Screen, &ClipRegion, &WinRegion, portPriv->pCompositeClip); + + /* clip and translate to the viewport */ + if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { + RegionRec VPReg; + BoxRec VPBox; + + VPBox.x1 = 0; + VPBox.y1 = 0; + VPBox.x2 = screen->width; + VPBox.y2 = screen->height; + + REGION_INIT(pScreen, &VPReg, &VPBox, 1); + REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg); + REGION_UNINIT(pScreen, &VPReg); + } + + /* that's all if it's totally obscured */ + if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) { + clippedAway = TRUE; + goto CLIP_VIDEO_BAILOUT; + } + + /* bailout if we have to clip but the hardware doesn't support it */ + if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) { + BoxPtr clipBox = REGION_RECTS(&ClipRegion); + if( (REGION_NUM_RECTS(&ClipRegion) != 1) || + (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) || + (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2)) + { + clippedAway = TRUE; + goto CLIP_VIDEO_BAILOUT; + } + } + + if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { + REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); + } + + ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->screen, portPriv->pDraw, + portPriv->vid_x, portPriv->vid_y, + WinBox.x1, WinBox.y1, + portPriv->vid_w, portPriv->vid_h, + portPriv->drw_w, portPriv->drw_h, + &ClipRegion, portPriv->DevPriv.ptr); + + if(ret == Success) portPriv->isOn = XV_ON; + +CLIP_VIDEO_BAILOUT: + + if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { + (*portPriv->AdaptorRec->StopVideo)( + portPriv->screen, portPriv->DevPriv.ptr, FALSE); + portPriv->isOn = XV_PENDING; + } + + /* This clip was copied and only good for one shot */ + if(!portPriv->FreeCompositeClip) + portPriv->pCompositeClip = NULL; + + REGION_UNINIT(pScreen, &WinRegion); + REGION_UNINIT(pScreen, &ClipRegion); + + return ret; +} + +static int +KdXVReputImage(XvPortRecPrivatePtr portPriv) +{ + RegionRec WinRegion; + RegionRec ClipRegion; + BoxRec WinBox; + ScreenPtr pScreen = portPriv->pDraw->pScreen; + KdScreenPriv(pScreen); + KdScreenInfo *screen=pScreenPriv->screen; + int ret = Success; + Bool clippedAway = FALSE; + + KdXVUpdateCompositeClip(portPriv); + + /* translate the video region to the screen */ + WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x; + WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y; + WinBox.x2 = WinBox.x1 + portPriv->drw_w; + WinBox.y2 = WinBox.y1 + portPriv->drw_h; + + /* clip to the window composite clip */ + REGION_INIT(pScreen, &WinRegion, &WinBox, 1); + REGION_INIT(pScreen, &ClipRegion, NullBox, 1); + REGION_INTERSECT(Screen, &ClipRegion, &WinRegion, portPriv->pCompositeClip); + + /* clip and translate to the viewport */ + if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { + RegionRec VPReg; + BoxRec VPBox; + + VPBox.x1 = 0; + VPBox.y1 = 0; + VPBox.x2 = screen->width; + VPBox.y2 = screen->height; + + REGION_INIT(pScreen, &VPReg, &VPBox, 1); + REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg); + REGION_UNINIT(pScreen, &VPReg); + } + + /* that's all if it's totally obscured */ + if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) { + clippedAway = TRUE; + goto CLIP_VIDEO_BAILOUT; + } + + /* bailout if we have to clip but the hardware doesn't support it */ + if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) { + BoxPtr clipBox = REGION_RECTS(&ClipRegion); + if( (REGION_NUM_RECTS(&ClipRegion) != 1) || + (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) || + (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2)) + { + clippedAway = TRUE; + goto CLIP_VIDEO_BAILOUT; + } + } + + if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { + REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); + } + + ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->screen, portPriv->pDraw, + WinBox.x1, WinBox.y1, + &ClipRegion, portPriv->DevPriv.ptr); + + portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF; + +CLIP_VIDEO_BAILOUT: + + if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { + (*portPriv->AdaptorRec->StopVideo)( + portPriv->screen, portPriv->DevPriv.ptr, FALSE); + portPriv->isOn = XV_PENDING; + } + + /* This clip was copied and only good for one shot */ + if(!portPriv->FreeCompositeClip) + portPriv->pCompositeClip = NULL; + + REGION_UNINIT(pScreen, &WinRegion); + REGION_UNINIT(pScreen, &ClipRegion); + + return ret; +} + + +static int +KdXVReputAllVideo(WindowPtr pWin, pointer data) +{ + KdXVWindowPtr WinPriv; + + if (pWin->drawable.type != DRAWABLE_WINDOW) + return WT_DONTWALKCHILDREN; + + WinPriv = GET_KDXV_WINDOW(pWin); + + while(WinPriv) { + if(WinPriv->PortRec->type == XvInputMask) + KdXVReputVideo(WinPriv->PortRec); + else + KdXVRegetVideo(WinPriv->PortRec); + WinPriv = WinPriv->next; + } + + return WT_WALKCHILDREN; +} + +static int +KdXVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv) +{ + KdXVWindowPtr winPriv, PrivRoot; + + winPriv = PrivRoot = GET_KDXV_WINDOW(pWin); + + /* Enlist our port in the window private */ + while(winPriv) { + if(winPriv->PortRec == portPriv) /* we're already listed */ + break; + winPriv = winPriv->next; + } + + if(!winPriv) { + winPriv = xalloc(sizeof(KdXVWindowRec)); + if(!winPriv) return BadAlloc; + winPriv->PortRec = portPriv; + winPriv->next = PrivRoot; + dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv); + } + return Success; +} + + +static void +KdXVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv) +{ + KdXVWindowPtr winPriv, prevPriv = NULL; + + winPriv = GET_KDXV_WINDOW(pWin); + + while(winPriv) { + if(winPriv->PortRec == portPriv) { + if(prevPriv) + prevPriv->next = winPriv->next; + else + dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv->next); + xfree(winPriv); + break; + } + prevPriv = winPriv; + winPriv = winPriv->next; + } + portPriv->pDraw = NULL; +} + +/**** ScreenRec fields ****/ + + +static Bool +KdXVCreateWindow(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); + int ret; + + pScreen->CreateWindow = ScreenPriv->CreateWindow; + ret = (*pScreen->CreateWindow)(pWin); + pScreen->CreateWindow = KdXVCreateWindow; + + if (ret) + dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, NULL); + + return ret; +} + + +static Bool +KdXVDestroyWindow(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); + KdXVWindowPtr tmp, WinPriv = GET_KDXV_WINDOW(pWin); + int ret; + + while(WinPriv) { + XvPortRecPrivatePtr pPriv = WinPriv->PortRec; + + if(pPriv->isOn > XV_OFF) { + (*pPriv->AdaptorRec->StopVideo)( + pPriv->screen, pPriv->DevPriv.ptr, TRUE); + pPriv->isOn = XV_OFF; + } + + pPriv->pDraw = NULL; + tmp = WinPriv; + WinPriv = WinPriv->next; + xfree(tmp); + } + + dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, NULL); + + pScreen->DestroyWindow = ScreenPriv->DestroyWindow; + ret = (*pScreen->DestroyWindow)(pWin); + pScreen->DestroyWindow = KdXVDestroyWindow; + + return ret; +} + + +static void +KdXVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); + KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin); + KdXVWindowPtr pPrev; + XvPortRecPrivatePtr pPriv; + Bool AreasExposed; + + AreasExposed = (WinPriv && reg1 && REGION_NOTEMPTY(pScreen, reg1)); + + pScreen->WindowExposures = ScreenPriv->WindowExposures; + (*pScreen->WindowExposures)(pWin, reg1, reg2); + pScreen->WindowExposures = KdXVWindowExposures; + + /* filter out XClearWindow/Area */ + if (!pWin->valdata) return; + + pPrev = NULL; + + while(WinPriv) { + pPriv = WinPriv->PortRec; + + /* Reput anyone with a reput function */ + + switch(pPriv->type) { + case XvInputMask: + KdXVReputVideo(pPriv); + break; + case XvOutputMask: + KdXVRegetVideo(pPriv); + break; + default: /* overlaid still/image*/ + if (pPriv->AdaptorRec->ReputImage) + KdXVReputImage(pPriv); + else if(AreasExposed) { + KdXVWindowPtr tmp; + + if (pPriv->isOn == XV_ON) { + (*pPriv->AdaptorRec->StopVideo)( + pPriv->screen, pPriv->DevPriv.ptr, FALSE); + pPriv->isOn = XV_PENDING; + } + pPriv->pDraw = NULL; + + if(!pPrev) + dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, WinPriv->next); + else + pPrev->next = WinPriv->next; + tmp = WinPriv; + WinPriv = WinPriv->next; + xfree(tmp); + continue; + } + break; + } + pPrev = WinPriv; + WinPriv = WinPriv->next; + } +} + + +static void +KdXVClipNotify(WindowPtr pWin, int dx, int dy) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); + KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin); + KdXVWindowPtr tmp, pPrev = NULL; + XvPortRecPrivatePtr pPriv; + Bool visible = (pWin->visibility == VisibilityUnobscured) || + (pWin->visibility == VisibilityPartiallyObscured); + + while(WinPriv) { + pPriv = WinPriv->PortRec; + + if(pPriv->pCompositeClip && pPriv->FreeCompositeClip) + REGION_DESTROY(pScreen, pPriv->pCompositeClip); + + pPriv->pCompositeClip = NULL; + + /* Stop everything except images, but stop them too if the + window isn't visible. But we only remove the images. */ + + if(pPriv->type || !visible) { + if(pPriv->isOn == XV_ON) { + (*pPriv->AdaptorRec->StopVideo)( + pPriv->screen, pPriv->DevPriv.ptr, FALSE); + pPriv->isOn = XV_PENDING; + } + + if(!pPriv->type) { /* overlaid still/image */ + pPriv->pDraw = NULL; + + if(!pPrev) + dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, WinPriv->next); + else + pPrev->next = WinPriv->next; + tmp = WinPriv; + WinPriv = WinPriv->next; + xfree(tmp); + continue; + } + } + + pPrev = WinPriv; + WinPriv = WinPriv->next; + } + + if(ScreenPriv->ClipNotify) { + pScreen->ClipNotify = ScreenPriv->ClipNotify; + (*pScreen->ClipNotify)(pWin, dx, dy); + pScreen->ClipNotify = KdXVClipNotify; + } +} + + + +/**** Required XvScreenRec fields ****/ + +static Bool +KdXVCloseScreen(int i, ScreenPtr pScreen) +{ + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); + KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); + XvAdaptorPtr pa; + int c; + + if(!ScreenPriv) return TRUE; + + pScreen->CreateWindow = ScreenPriv->CreateWindow; + pScreen->DestroyWindow = ScreenPriv->DestroyWindow; + pScreen->WindowExposures = ScreenPriv->WindowExposures; + pScreen->ClipNotify = ScreenPriv->ClipNotify; + +/* fprintf(stderr,"XV: Unwrapping screen funcs\n"); */ + + for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) { + KdXVFreeAdaptor(pa); + } + + if(pxvs->pAdaptors) + xfree(pxvs->pAdaptors); + + xfree(ScreenPriv); + + + return TRUE; +} + + +static int +KdXVQueryAdaptors( + ScreenPtr pScreen, + XvAdaptorPtr *p_pAdaptors, + int *p_nAdaptors +){ + XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); + + *p_nAdaptors = pxvs->nAdaptors; + *p_pAdaptors = pxvs->pAdaptors; + + return (Success); +} + +static Bool +KdXVRunning (ScreenPtr pScreen) +{ + return (KdXVGeneration == serverGeneration && + GET_XV_SCREEN(pScreen) != 0); +} + +Bool +KdXVEnable(ScreenPtr pScreen) +{ + if (!KdXVRunning (pScreen)) + return TRUE; + + WalkTree(pScreen, KdXVReputAllVideo, 0); + + return TRUE; +} + +void +KdXVDisable(ScreenPtr pScreen) +{ + XvScreenPtr pxvs; + KdXVScreenPtr ScreenPriv; + XvAdaptorPtr pAdaptor; + XvPortPtr pPort; + XvPortRecPrivatePtr pPriv; + int i, j; + + if (!KdXVRunning (pScreen)) + return; + + pxvs = GET_XV_SCREEN(pScreen); + ScreenPriv = GET_KDXV_SCREEN(pScreen); + + for(i = 0; i < pxvs->nAdaptors; i++) { + pAdaptor = &pxvs->pAdaptors[i]; + for(j = 0; j < pAdaptor->nPorts; j++) { + pPort = &pAdaptor->pPorts[j]; + pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr; + if(pPriv->isOn > XV_OFF) { + + (*pPriv->AdaptorRec->StopVideo)( + pPriv->screen, pPriv->DevPriv.ptr, TRUE); + pPriv->isOn = XV_OFF; + + if(pPriv->pCompositeClip && pPriv->FreeCompositeClip) + REGION_DESTROY(pScreen, pPriv->pCompositeClip); + + pPriv->pCompositeClip = NULL; + + if(!pPriv->type && pPriv->pDraw) { /* still */ + KdXVRemovePortFromWindow((WindowPtr)pPriv->pDraw, pPriv); + } + } + } + } +} + +/**** XvAdaptorRec fields ****/ + +static int +KdXVAllocatePort( + unsigned long port, + XvPortPtr pPort, + XvPortPtr *ppPort +){ + *ppPort = pPort; + return Success; +} + +static int +KdXVFreePort(XvPortPtr pPort) +{ + return Success; +} + +static int +KdXVPutVideo( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); + KdScreenPriv(portPriv->screen->pScreen); + int result; + + /* No dumping video to pixmaps... For now anyhow */ + if(pDraw->type != DRAWABLE_WINDOW) { + pPort->pDraw = (DrawablePtr)NULL; + return BadAlloc; + } + + /* If we are changing windows, unregister our port in the old window */ + if(portPriv->pDraw && (portPriv->pDraw != pDraw)) + KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); + + /* Register our port with the new window */ + result = KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv); + if(result != Success) return result; + + portPriv->pDraw = pDraw; + portPriv->type = XvInputMask; + + /* save a copy of these parameters */ + portPriv->vid_x = vid_x; portPriv->vid_y = vid_y; + portPriv->vid_w = vid_w; portPriv->vid_h = vid_h; + portPriv->drw_x = drw_x; portPriv->drw_y = drw_y; + portPriv->drw_w = drw_w; portPriv->drw_h = drw_h; + + /* make sure we have the most recent copy of the clientClip */ + KdXVCopyClip(portPriv, pGC); + + /* To indicate to the DI layer that we were successful */ + pPort->pDraw = pDraw; + + if (!pScreenPriv->enabled) return Success; + + return(KdXVReputVideo(portPriv)); +} + +static int +KdXVPutStill( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); + ScreenPtr pScreen = pDraw->pScreen; + KdScreenPriv(pScreen); + KdScreenInfo *screen=pScreenPriv->screen; + RegionRec WinRegion; + RegionRec ClipRegion; + BoxRec WinBox; + int ret = Success; + Bool clippedAway = FALSE; + + if (pDraw->type != DRAWABLE_WINDOW) + return BadAlloc; + + if (!pScreenPriv->enabled) return Success; + + WinBox.x1 = pDraw->x + drw_x; + WinBox.y1 = pDraw->y + drw_y; + WinBox.x2 = WinBox.x1 + drw_w; + WinBox.y2 = WinBox.y1 + drw_h; + + REGION_INIT(pScreen, &WinRegion, &WinBox, 1); + REGION_INIT(pScreen, &ClipRegion, NullBox, 1); + REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip); + + if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { + RegionRec VPReg; + BoxRec VPBox; + + VPBox.x1 = 0; + VPBox.y1 = 0; + VPBox.x2 = screen->width; + VPBox.y2 = screen->height; + + REGION_INIT(pScreen, &VPReg, &VPBox, 1); + REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg); + REGION_UNINIT(pScreen, &VPReg); + } + + if(portPriv->pDraw) { + KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); + } + + if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) { + clippedAway = TRUE; + goto PUT_STILL_BAILOUT; + } + + if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) { + BoxPtr clipBox = REGION_RECTS(&ClipRegion); + if( (REGION_NUM_RECTS(&ClipRegion) != 1) || + (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) || + (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2)) + { + clippedAway = TRUE; + goto PUT_STILL_BAILOUT; + } + } + + if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { + REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); + } + + ret = (*portPriv->AdaptorRec->PutStill)(portPriv->screen, pDraw, + vid_x, vid_y, WinBox.x1, WinBox.y1, + vid_w, vid_h, drw_w, drw_h, + &ClipRegion, portPriv->DevPriv.ptr); + + if((ret == Success) && + (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) { + + KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv); + portPriv->isOn = XV_ON; + portPriv->pDraw = pDraw; + portPriv->drw_x = drw_x; portPriv->drw_y = drw_y; + portPriv->drw_w = drw_w; portPriv->drw_h = drw_h; + portPriv->type = 0; /* no mask means it's transient and should + not be reput once it's removed */ + pPort->pDraw = pDraw; /* make sure we can get stop requests */ + } + +PUT_STILL_BAILOUT: + + if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { + (*portPriv->AdaptorRec->StopVideo)( + portPriv->screen, portPriv->DevPriv.ptr, FALSE); + portPriv->isOn = XV_PENDING; + } + + REGION_UNINIT(pScreen, &WinRegion); + REGION_UNINIT(pScreen, &ClipRegion); + + return ret; +} + +static int +KdXVGetVideo( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); + int result; + KdScreenPriv(portPriv->screen->pScreen); + + /* No pixmaps... For now anyhow */ + if(pDraw->type != DRAWABLE_WINDOW) { + pPort->pDraw = (DrawablePtr)NULL; + return BadAlloc; + } + + /* If we are changing windows, unregister our port in the old window */ + if(portPriv->pDraw && (portPriv->pDraw != pDraw)) + KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); + + /* Register our port with the new window */ + result = KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv); + if(result != Success) return result; + + portPriv->pDraw = pDraw; + portPriv->type = XvOutputMask; + + /* save a copy of these parameters */ + portPriv->vid_x = vid_x; portPriv->vid_y = vid_y; + portPriv->vid_w = vid_w; portPriv->vid_h = vid_h; + portPriv->drw_x = drw_x; portPriv->drw_y = drw_y; + portPriv->drw_w = drw_w; portPriv->drw_h = drw_h; + + /* make sure we have the most recent copy of the clientClip */ + KdXVCopyClip(portPriv, pGC); + + /* To indicate to the DI layer that we were successful */ + pPort->pDraw = pDraw; + + if(!pScreenPriv->enabled) return Success; + + return(KdXVRegetVideo(portPriv)); +} + +static int +KdXVGetStill( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); + ScreenPtr pScreen = pDraw->pScreen; + KdScreenPriv(pScreen); + RegionRec WinRegion; + RegionRec ClipRegion; + BoxRec WinBox; + int ret = Success; + Bool clippedAway = FALSE; + + if (pDraw->type != DRAWABLE_WINDOW) + return BadAlloc; + + if(!pScreenPriv->enabled) return Success; + + WinBox.x1 = pDraw->x + drw_x; + WinBox.y1 = pDraw->y + drw_y; + WinBox.x2 = WinBox.x1 + drw_w; + WinBox.y2 = WinBox.y1 + drw_h; + + REGION_INIT(pScreen, &WinRegion, &WinBox, 1); + REGION_INIT(pScreen, &ClipRegion, NullBox, 1); + REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip); + + if(portPriv->pDraw) { + KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); + } + + if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) { + clippedAway = TRUE; + goto GET_STILL_BAILOUT; + } + + if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { + REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); + } + + ret = (*portPriv->AdaptorRec->GetStill)(portPriv->screen, pDraw, + vid_x, vid_y, WinBox.x1, WinBox.y1, + vid_w, vid_h, drw_w, drw_h, + &ClipRegion, portPriv->DevPriv.ptr); + +GET_STILL_BAILOUT: + + if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { + (*portPriv->AdaptorRec->StopVideo)( + portPriv->screen, portPriv->DevPriv.ptr, FALSE); + portPriv->isOn = XV_PENDING; + } + + REGION_UNINIT(pScreen, &WinRegion); + REGION_UNINIT(pScreen, &ClipRegion); + + return ret; +} + + + +static int +KdXVStopVideo( + ClientPtr client, + XvPortPtr pPort, + DrawablePtr pDraw +){ + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); + KdScreenPriv(portPriv->screen->pScreen); + + if(pDraw->type != DRAWABLE_WINDOW) + return BadAlloc; + + KdXVRemovePortFromWindow((WindowPtr)pDraw, portPriv); + + if(!pScreenPriv->enabled) return Success; + + /* Must free resources. */ + + if(portPriv->isOn > XV_OFF) { + (*portPriv->AdaptorRec->StopVideo)( + portPriv->screen, portPriv->DevPriv.ptr, TRUE); + portPriv->isOn = XV_OFF; + } + + return Success; +} + +static int +KdXVSetPortAttribute( + ClientPtr client, + XvPortPtr pPort, + Atom attribute, + INT32 value +){ + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); + + return((*portPriv->AdaptorRec->SetPortAttribute)(portPriv->screen, + attribute, value, portPriv->DevPriv.ptr)); +} + + +static int +KdXVGetPortAttribute( + ClientPtr client, + XvPortPtr pPort, + Atom attribute, + INT32 *p_value +){ + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); + + return((*portPriv->AdaptorRec->GetPortAttribute)(portPriv->screen, + attribute, (int *) p_value, portPriv->DevPriv.ptr)); +} + + + +static int +KdXVQueryBestSize( + ClientPtr client, + XvPortPtr pPort, + CARD8 motion, + CARD16 vid_w, CARD16 vid_h, + CARD16 drw_w, CARD16 drw_h, + unsigned int *p_w, unsigned int *p_h +){ + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); + + (*portPriv->AdaptorRec->QueryBestSize)(portPriv->screen, + (Bool)motion, vid_w, vid_h, drw_w, drw_h, + p_w, p_h, portPriv->DevPriv.ptr); + + return Success; +} + + +static int +KdXVPutImage( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 src_x, INT16 src_y, + CARD16 src_w, CARD16 src_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h, + XvImagePtr format, + unsigned char* data, + Bool sync, + CARD16 width, CARD16 height +){ + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); + ScreenPtr pScreen = pDraw->pScreen; + KdScreenPriv(pScreen); + RegionRec WinRegion; + RegionRec ClipRegion; + BoxRec WinBox; + int ret = Success; + Bool clippedAway = FALSE; + + if (pDraw->type != DRAWABLE_WINDOW) + return BadAlloc; + + if(!pScreenPriv->enabled) return Success; + + WinBox.x1 = pDraw->x + drw_x; + WinBox.y1 = pDraw->y + drw_y; + WinBox.x2 = WinBox.x1 + drw_w; + WinBox.y2 = WinBox.y1 + drw_h; + + REGION_INIT(pScreen, &WinRegion, &WinBox, 1); + REGION_INIT(pScreen, &ClipRegion, NullBox, 1); + REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip); + + if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) { + RegionRec VPReg; + BoxRec VPBox; + + VPBox.x1 = 0; + VPBox.y1 = 0; + VPBox.x2 = pScreen->width; + VPBox.y2 = pScreen->height; + + REGION_INIT(pScreen, &VPReg, &VPBox, 1); + REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg); + REGION_UNINIT(pScreen, &VPReg); + } + + if(portPriv->pDraw) { + KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv); + } + + if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) { + clippedAway = TRUE; + goto PUT_IMAGE_BAILOUT; + } + + if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) { + BoxPtr clipBox = REGION_RECTS(&ClipRegion); + if( (REGION_NUM_RECTS(&ClipRegion) != 1) || + (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) || + (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2)) + { + clippedAway = TRUE; + goto PUT_IMAGE_BAILOUT; + } + } + + if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) { + REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion); + } + + ret = (*portPriv->AdaptorRec->PutImage)(portPriv->screen, pDraw, + src_x, src_y, WinBox.x1, WinBox.y1, + src_w, src_h, drw_w, drw_h, format->id, data, width, height, + sync, &ClipRegion, portPriv->DevPriv.ptr); + + if((ret == Success) && + (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) { + + KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv); + portPriv->isOn = XV_ON; + portPriv->pDraw = pDraw; + portPriv->drw_x = drw_x; portPriv->drw_y = drw_y; + portPriv->drw_w = drw_w; portPriv->drw_h = drw_h; + portPriv->type = 0; /* no mask means it's transient and should + not be reput once it's removed */ + pPort->pDraw = pDraw; /* make sure we can get stop requests */ + } + +PUT_IMAGE_BAILOUT: + + if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) { + (*portPriv->AdaptorRec->StopVideo)( + portPriv->screen, portPriv->DevPriv.ptr, FALSE); + portPriv->isOn = XV_PENDING; + } + + REGION_UNINIT(pScreen, &WinRegion); + REGION_UNINIT(pScreen, &ClipRegion); + + return ret; +} + + +static int +KdXVQueryImageAttributes( + ClientPtr client, + XvPortPtr pPort, + XvImagePtr format, + CARD16 *width, + CARD16 *height, + int *pitches, + int *offsets +){ + XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr); + + return (*portPriv->AdaptorRec->QueryImageAttributes)(portPriv->screen, + format->id, width, height, pitches, offsets); +} + + +/**************** Offscreen surface stuff *******************/ + +typedef struct { + KdOffscreenImagePtr images; + int num; +} OffscreenImageRec; + +static OffscreenImageRec OffscreenImages[MAXSCREENS]; +static Bool offscreenInited = FALSE; + +Bool +KdXVRegisterOffscreenImages( + ScreenPtr pScreen, + KdOffscreenImagePtr images, + int num +){ + if(!offscreenInited) { + bzero(OffscreenImages, sizeof(OffscreenImages[MAXSCREENS])); + offscreenInited = TRUE; + } + + OffscreenImages[pScreen->myNum].num = num; + OffscreenImages[pScreen->myNum].images = images; + + return TRUE; +} + +KdOffscreenImagePtr +KdXVQueryOffscreenImages( + ScreenPtr pScreen, + int *num +){ + if(!offscreenInited) { + *num = 0; + return NULL; + } + + *num = OffscreenImages[pScreen->myNum].num; + return OffscreenImages[pScreen->myNum].images; +} + +/**************** Common video manipulation functions *******************/ + +void +KdXVCopyPackedData(KdScreenInfo *screen, CARD8 *src, CARD8 *dst, int randr, + int srcPitch, int dstPitch, int srcW, int srcH, int top, int left, + int h, int w) +{ + int srcDown = srcPitch, srcRight = 2, srcNext; + int p; + + switch (randr & RR_Rotate_All) { + case RR_Rotate_0: + srcDown = srcPitch; + srcRight = 2; + break; + case RR_Rotate_90: + src += (srcH - 1) * 2; + srcDown = -2; + srcRight = srcPitch; + break; + case RR_Rotate_180: + src += srcPitch * (srcH - 1) + (srcW - 1) * 2; + srcDown = -srcPitch; + srcRight = -2; + break; + case RR_Rotate_270: + src += srcPitch * (srcW - 1); + srcDown = 2; + srcRight = -srcPitch; + break; + } + + src = src + top * srcDown + left * srcRight; + + w >>= 1; + /* srcRight >>= 1; */ + srcNext = srcRight >> 1; + while (h--) { + CARD16 *s = (CARD16 *)src; + CARD32 *d = (CARD32 *)dst; + p = w; + while (p--) { + *d++ = s[0] | (s[srcNext] << 16); + s += srcRight; + } + src += srcPitch; + dst += dstPitch; + } +} + +void +KdXVCopyPlanarData(KdScreenInfo *screen, CARD8 *src, CARD8 *dst, int randr, + int srcPitch, int srcPitch2, int dstPitch, int srcW, int srcH, int height, + int top, int left, int h, int w, int id) +{ + int i, j; + CARD8 *src1, *src2, *src3, *dst1; + int srcDown = srcPitch, srcDown2 = srcPitch2; + int srcRight = 2, srcRight2 = 1, srcNext = 1; + + /* compute source data pointers */ + src1 = src; + src2 = src1 + height * srcPitch; + src3 = src2 + (height >> 1) * srcPitch2; + switch (randr & RR_Rotate_All) { + case RR_Rotate_0: + srcDown = srcPitch; + srcDown2 = srcPitch2; + srcRight = 2; + srcRight2 = 1; + srcNext = 1; + break; + case RR_Rotate_90: + src1 = src1 + srcH - 1; + src2 = src2 + (srcH >> 1) - 1; + src3 = src3 + (srcH >> 1) - 1; + srcDown = -1; + srcDown2 = -1; + srcRight = srcPitch * 2; + srcRight2 = srcPitch2; + srcNext = srcPitch; + break; + case RR_Rotate_180: + src1 = src1 + srcPitch * (srcH - 1) + (srcW - 1); + src2 = src2 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1); + src3 = src3 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1); + srcDown = -srcPitch; + srcDown2 = -srcPitch2; + srcRight = -2; + srcRight2 = -1; + srcNext = -1; + break; + case RR_Rotate_270: + src1 = src1 + srcPitch * (srcW - 1); + src2 = src2 + srcPitch2 * ((srcW >> 1) - 1); + src3 = src3 + srcPitch2 * ((srcW >> 1) - 1); + srcDown = 1; + srcDown2 = 1; + srcRight = -srcPitch * 2; + srcRight2 = -srcPitch2; + srcNext = -srcPitch; + break; + } + + /* adjust for origin */ + src1 += top * srcDown + left * srcNext; + src2 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2; + src3 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2; + + if (id == FOURCC_I420) { + CARD8 *srct = src2; + src2 = src3; + src3 = srct; + } + + dst1 = dst; + + w >>= 1; + for (j = 0; j < h; j++) { + CARD32 *dst = (CARD32 *)dst1; + CARD8 *s1l = src1; + CARD8 *s1r = src1 + srcNext; + CARD8 *s2 = src2; + CARD8 *s3 = src3; + + for (i = 0; i < w; i++) { + *dst++ = *s1l | (*s1r << 16) | (*s3 << 8) | (*s2 << 24); + s1l += srcRight; + s1r += srcRight; + s2 += srcRight2; + s3 += srcRight2; + } + src1 += srcDown; + dst1 += dstPitch; + if (j & 1) { + src2 += srcDown2; + src3 += srcDown2; + } + } +} + +void +KXVPaintRegion (DrawablePtr pDraw, RegionPtr pRgn, Pixel fg) +{ + GCPtr pGC; + CARD32 val[2]; + xRectangle *rects, *r; + BoxPtr pBox = REGION_RECTS (pRgn); + int nBox = REGION_NUM_RECTS (pRgn); + + rects = xalloc (nBox * sizeof (xRectangle)); + if (!rects) + goto bail0; + r = rects; + while (nBox--) + { + r->x = pBox->x1 - pDraw->x; + r->y = pBox->y1 - pDraw->y; + r->width = pBox->x2 - pBox->x1; + r->height = pBox->y2 - pBox->y1; + r++; + pBox++; + } + + pGC = GetScratchGC (pDraw->depth, pDraw->pScreen); + if (!pGC) + goto bail1; + + val[0] = fg; + val[1] = IncludeInferiors; + ChangeGC (pGC, GCForeground|GCSubwindowMode, val); + + ValidateGC (pDraw, pGC); + + (*pGC->ops->PolyFillRect) (pDraw, pGC, + REGION_NUM_RECTS (pRgn), rects); + + FreeScratchGC (pGC); +bail1: + xfree (rects); +bail0: + ; +} diff --git a/xorg-server/hw/kdrive/src/kxv.h b/xorg-server/hw/kdrive/src/kxv.h new file mode 100644 index 000000000..5d1441642 --- /dev/null +++ b/xorg-server/hw/kdrive/src/kxv.h @@ -0,0 +1,316 @@ +/* + + XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com) + Adapted for KDrive by Pontus Lidman <pontus.lidman@nokia.com> + + Copyright (C) 2000, 2001 - Nokia Home Communications + Copyright (C) 1998, 1999 - 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, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +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 +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +*/ + +#ifndef _XVDIX_H_ +#define _XVDIX_H_ + +#include "scrnintstr.h" +#include "regionstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "mivalidate.h" +#include "validate.h" +#include "resource.h" +#include "gcstruct.h" +#include "dixstruct.h" + +#include "../../Xext/xvdix.h" + +#define VIDEO_NO_CLIPPING 0x00000001 +#define VIDEO_INVERT_CLIPLIST 0x00000002 +#define VIDEO_OVERLAID_IMAGES 0x00000004 +#define VIDEO_OVERLAID_STILLS 0x00000008 +#define VIDEO_CLIP_TO_VIEWPORT 0x00000010 + +typedef struct { + int id; + int type; + int byte_order; + unsigned char guid[16]; + int bits_per_pixel; + int format; + int num_planes; + + /* for RGB formats only */ + int depth; + unsigned int red_mask; + unsigned int green_mask; + unsigned int blue_mask; + + /* for YUV formats only */ + unsigned int y_sample_bits; + unsigned int u_sample_bits; + unsigned int v_sample_bits; + unsigned int horz_y_period; + unsigned int horz_u_period; + unsigned int horz_v_period; + unsigned int vert_y_period; + unsigned int vert_u_period; + unsigned int vert_v_period; + char component_order[32]; + int scanline_order; +} KdImageRec, *KdImagePtr; + + +typedef struct { + KdScreenInfo * screen; + int id; + unsigned short width, height; + int *pitches; /* bytes */ + int *offsets; /* in bytes from start of framebuffer */ + DevUnion devPrivate; +} KdSurfaceRec, *KdSurfacePtr; + + +typedef int (* PutVideoFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw, + short vid_x, short vid_y, short drw_x, short drw_y, + short vid_w, short vid_h, short drw_w, short drw_h, + RegionPtr clipBoxes, pointer data ); +typedef int (* PutStillFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw, + short vid_x, short vid_y, short drw_x, short drw_y, + short vid_w, short vid_h, short drw_w, short drw_h, + RegionPtr clipBoxes, pointer data ); +typedef int (* GetVideoFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw, + short vid_x, short vid_y, short drw_x, short drw_y, + short vid_w, short vid_h, short drw_w, short drw_h, + RegionPtr clipBoxes, pointer data ); +typedef int (* GetStillFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw, + short vid_x, short vid_y, short drw_x, short drw_y, + short vid_w, short vid_h, short drw_w, short drw_h, + RegionPtr clipBoxes, pointer data ); +typedef void (* StopVideoFuncPtr)(KdScreenInfo * screen, pointer data, Bool Exit); +typedef int (* SetPortAttributeFuncPtr)(KdScreenInfo * screen, Atom attribute, + int value, pointer data); +typedef int (* GetPortAttributeFuncPtr)(KdScreenInfo * screen, Atom attribute, + int *value, pointer data); +typedef void (* QueryBestSizeFuncPtr)(KdScreenInfo * screen, Bool motion, + short vid_w, short vid_h, short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, pointer data); +typedef int (* PutImageFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw, + short src_x, short src_y, short drw_x, short drw_y, + short src_w, short src_h, short drw_w, short drw_h, + int image, unsigned char* buf, short width, short height, Bool Sync, + RegionPtr clipBoxes, pointer data ); +typedef int (* ReputImageFuncPtr)( KdScreenInfo * screen, DrawablePtr pDraw, + short drw_x, short drw_y, + RegionPtr clipBoxes, pointer data ); +typedef int (*QueryImageAttributesFuncPtr)(KdScreenInfo * screen, + int image, unsigned short *width, unsigned short *height, + int *pitches, int *offsets); + +typedef enum { + XV_OFF, + XV_PENDING, + XV_ON +} XvStatus; + +/*** this is what the driver needs to fill out ***/ + +typedef struct { + int id; + char *name; + unsigned short width, height; + XvRationalRec rate; +} KdVideoEncodingRec, *KdVideoEncodingPtr; + +typedef struct { + char depth; + short class; +} KdVideoFormatRec, *KdVideoFormatPtr; + +typedef struct { + int flags; + int min_value; + int max_value; + char *name; +} KdAttributeRec, *KdAttributePtr; + +typedef struct { + unsigned int type; + int flags; + char *name; + int nEncodings; + KdVideoEncodingPtr pEncodings; + int nFormats; + KdVideoFormatPtr pFormats; + int nPorts; + DevUnion *pPortPrivates; + int nAttributes; + KdAttributePtr pAttributes; + int nImages; + KdImagePtr pImages; + PutVideoFuncPtr PutVideo; + PutStillFuncPtr PutStill; + GetVideoFuncPtr GetVideo; + GetStillFuncPtr GetStill; + StopVideoFuncPtr StopVideo; + SetPortAttributeFuncPtr SetPortAttribute; + GetPortAttributeFuncPtr GetPortAttribute; + QueryBestSizeFuncPtr QueryBestSize; + PutImageFuncPtr PutImage; + ReputImageFuncPtr ReputImage; + QueryImageAttributesFuncPtr QueryImageAttributes; +} KdVideoAdaptorRec, *KdVideoAdaptorPtr; + +typedef struct { + KdImagePtr image; + int flags; + int (*alloc_surface)(KdScreenInfo * screen, + int id, + unsigned short width, + unsigned short height, + KdSurfacePtr surface); + int (*free_surface)(KdSurfacePtr surface); + int (*display) (KdSurfacePtr surface, + short vid_x, short vid_y, + short drw_x, short drw_y, + short vid_w, short vid_h, + short drw_w, short drw_h, + RegionPtr clipBoxes); + int (*stop) (KdSurfacePtr surface); + int (*getAttribute) (KdScreenInfo * screen, Atom attr, INT32 *value); + int (*setAttribute) (KdScreenInfo * screen, Atom attr, INT32 value); + int max_width; + int max_height; + int num_attributes; + KdAttributePtr attributes; +} KdOffscreenImageRec, *KdOffscreenImagePtr; + +Bool +KdXVScreenInit( + ScreenPtr pScreen, + KdVideoAdaptorPtr *Adaptors, + int num +); + +typedef int (* KdXVInitGenericAdaptorPtr)(KdScreenInfo * screen, + KdVideoAdaptorPtr **Adaptors); + +int +KdXVRegisterGenericAdaptorDriver( + KdXVInitGenericAdaptorPtr InitFunc +); + +int +KdXVListGenericAdaptors( + KdScreenInfo * screen, + KdVideoAdaptorPtr **Adaptors +); + +Bool +KdXVRegisterOffscreenImages( + ScreenPtr pScreen, + KdOffscreenImagePtr images, + int num +); + +KdOffscreenImagePtr +KdXVQueryOffscreenImages( + ScreenPtr pScreen, + int *num +); + +void +KdXVCopyPackedData(KdScreenInfo *screen, CARD8 *src, CARD8 *dst, int randr, + int srcPitch, int dstPitch, int srcW, int srcH, int top, int left, + int h, int w); + +void +KdXVCopyPlanarData(KdScreenInfo *screen, CARD8 *src, CARD8 *dst, int randr, + int srcPitch, int srcPitch2, int dstPitch, int srcW, int srcH, int height, + int top, int left, int h, int w, int id); + +void +KXVPaintRegion (DrawablePtr pDraw, RegionPtr pRgn, Pixel fg); + +KdVideoAdaptorPtr KdXVAllocateVideoAdaptorRec(KdScreenInfo * screen); + +void KdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr); + +/* Must be called from KdCardInfo functions, can be called without Xv enabled */ +Bool KdXVEnable(ScreenPtr); +void KdXVDisable(ScreenPtr); + +/*** These are DDX layer privates ***/ + + +typedef struct { + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + ClipNotifyProcPtr ClipNotify; + WindowExposuresProcPtr WindowExposures; +} KdXVScreenRec, *KdXVScreenPtr; + +typedef struct { + int flags; + PutVideoFuncPtr PutVideo; + PutStillFuncPtr PutStill; + GetVideoFuncPtr GetVideo; + GetStillFuncPtr GetStill; + StopVideoFuncPtr StopVideo; + SetPortAttributeFuncPtr SetPortAttribute; + GetPortAttributeFuncPtr GetPortAttribute; + QueryBestSizeFuncPtr QueryBestSize; + PutImageFuncPtr PutImage; + ReputImageFuncPtr ReputImage; + QueryImageAttributesFuncPtr QueryImageAttributes; +} XvAdaptorRecPrivate, *XvAdaptorRecPrivatePtr; + +typedef struct { + KdScreenInfo * screen; + DrawablePtr pDraw; + unsigned char type; + unsigned int subWindowMode; + DDXPointRec clipOrg; + RegionPtr clientClip; + RegionPtr pCompositeClip; + Bool FreeCompositeClip; + XvAdaptorRecPrivatePtr AdaptorRec; + XvStatus isOn; + Bool moved; + int vid_x, vid_y, vid_w, vid_h; + int drw_x, drw_y, drw_w, drw_h; + DevUnion DevPriv; +} XvPortRecPrivate, *XvPortRecPrivatePtr; + +typedef struct _KdXVWindowRec{ + XvPortRecPrivatePtr PortRec; + struct _KdXVWindowRec *next; +} KdXVWindowRec, *KdXVWindowPtr; + +#endif /* _XVDIX_H_ */ + diff --git a/xorg-server/hw/kdrive/src/vga.c b/xorg-server/hw/kdrive/src/vga.c new file mode 100644 index 000000000..862f074a2 --- /dev/null +++ b/xorg-server/hw/kdrive/src/vga.c @@ -0,0 +1,328 @@ +/* + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "vga.h" +#include <stdio.h> + +#ifdef linux +#ifdef __i386__ +#define extern static +#include <sys/io.h> +#undef extern + +#define _VgaInb(r) inb(r) +#define _VgaOutb(v,r) outb(v,r) +#else +#define _VgaInb(r) 0 +#define _VgaOutb(v,r) +#endif + +#define _VgaByteAddr(a) ((VGAVOL8 *) (a)) +#define _VgaBytePort(a) (a) +#endif + +#ifdef VXWORKS +#define _VgaInb(r) 0 +#define _VgaOutb(v,r) 0 + +#define _VgaByteAddr(a) ((VGAVOL8 *) ((VGA32) (a) ^ 3)) +#define _VgaBytePort(a) 0 + +#undef stderr +#define stderr stdout + +#endif + +#undef VGA_DEBUG_REGISTERS +#ifdef VGA_DEBUG_REGISTERS +#define VGA_DEBUG(a) fprintf a +#else +#define VGA_DEBUG(a) +#endif + +VGA8 +VgaInb (VGA16 r) +{ + return _VgaInb(r); +} + +void +VgaOutb (VGA8 v, VGA16 r) +{ + _VgaOutb (v,r); +} + +VGA8 +VgaReadMemb (VGA32 addr) +{ + return *_VgaByteAddr(addr); +} + +void +VgaWriteMemb (VGA8 v, VGA32 addr) +{ + *_VgaByteAddr(addr) = v; +} + +VGA8 +VgaFetch (VgaCard *card, VGA16 reg) +{ + VgaMap map; + VGA8 value = 0; + + (*card->map) (card, reg, &map, VGAFALSE); + switch (map.access) { + case VgaAccessMem: + value = VgaReadMemb (map.port); + VGA_DEBUG ((stderr, "%08x -> %2x\n", map.port, value)); + break; + case VgaAccessIo: + value = _VgaInb (map.port); + VGA_DEBUG ((stderr, "%4x -> %2x\n", map.port, value)); + break; + case VgaAccessIndMem: + VgaWriteMemb (map.index, map.port + map.addr); + value = VgaReadMemb (map.port + map.value); + VGA_DEBUG ((stderr, "%4x/%2x -> %2x\n", map.port, map.index, value)); + break; + case VgaAccessIndIo: + _VgaOutb (map.index, map.port + map.addr); + value = _VgaInb (map.port + map.value); + VGA_DEBUG ((stderr, "%4x/%2x -> %2x\n", map.port, map.index, value)); + break; + case VgaAccessDone: + value = map.value; + VGA_DEBUG ((stderr, "direct %4x -> %2x\n", reg, value)); + break; + } + return value; +} + +void +VgaStore (VgaCard *card, VGA16 reg, VGA8 value) +{ + VgaMap map; + + map.value = value; + (*card->map) (card, reg, &map, VGATRUE); + switch (map.access) { + case VgaAccessMem: + VGA_DEBUG ((stderr, "%8x <- %2x\n", map.port, value)); + VgaWriteMemb (map.value, map.port); + break; + case VgaAccessIo: + VGA_DEBUG ((stderr, "%4x <- %2x\n", map.port, value)); + _VgaOutb (value, map.port); + break; + case VgaAccessIndMem: + VgaWriteMemb (map.index, map.port + map.addr); + VgaWriteMemb (value, map.port + map.value); + VGA_DEBUG ((stderr, "%4x/%2x <- %2x\n", map.port, map.index, value)); + break; + case VgaAccessIndIo: + VGA_DEBUG ((stderr, "%4x/%2x <- %2x\n", map.port, map.index, value)); + _VgaOutb (map.index, map.port + map.addr); + _VgaOutb (value, map.port + map.value); + break; + case VgaAccessDone: + VGA_DEBUG ((stderr, "direct %4x <- %2x\n", reg, value)); + break; + } +} + +void +VgaPreserve (VgaCard *card) +{ + VgaSave *s; + VGA16 id; + + for (s = card->saves; s->first != VGA_REG_NONE; s++) + { + for (id = s->first; id <= s->last; id++) + { + card->values[id].cur = VgaFetch (card, id); + card->values[id].save = card->values[id].cur; + card->values[id].flags = VGA_VALUE_VALID | VGA_VALUE_SAVED; + } + } +} + +void +VgaRestore (VgaCard *card) +{ + VgaSave *s; + VGA16 id; + + for (s = card->saves; s->first != VGA_REG_NONE; s++) + { + for (id = s->first; id <= s->last; id++) + { + if (card->values[id].flags & VGA_VALUE_SAVED) + { + VgaStore (card, id, card->values[id].save); + card->values[id].cur = card->values[id].save; + } + } + } +} + +void +VgaFinish (VgaCard *card) +{ + VGA16 id; + + for (id = 0; id < card->max; id++) + card->values[id].flags = 0; +} + +void +VgaInvalidate (VgaCard *card) +{ + VGA16 id; + + for (id = 0; id < card->max; id++) + card->values[id].flags &= ~VGA_VALUE_VALID; +} + + +static void +_VgaSync (VgaCard *card, VGA16 id) +{ + if (!(card->values[id].flags & VGA_VALUE_VALID)) + { + card->values[id].cur = VgaFetch (card, id); + card->values[id].flags |= VGA_VALUE_VALID; + } +} + +void +VgaSet (VgaCard *card, VgaReg *reg, VGA32 value) +{ + VGA8 v, mask, new; + + while (reg->len) + { + if (reg->id != VGA_REG_NONE) + { + _VgaSync (card, reg->id); + mask = ((1 << reg->len) - 1); + new = value & mask; + mask <<= reg->base; + new <<= reg->base; + v = card->values[reg->id].cur; + v = (v & ~mask) | new; + card->values[reg->id].cur = v; + card->values[reg->id].flags |= VGA_VALUE_MODIFIED|VGA_VALUE_DIRTY; + } + value >>= reg->len; + reg++; + } +} + +void +VgaFlushReg (VgaCard *card, VgaReg *reg) +{ + while (reg->len) + { + if (reg->id != VGA_REG_NONE) + { + if (card->values[reg->id].flags & VGA_VALUE_DIRTY) + { + VgaStore (card, reg->id, card->values[reg->id].cur); + card->values[reg->id].flags &= ~VGA_VALUE_DIRTY; + } + } + reg++; + } + +} + +void +VgaSetImm (VgaCard *card, VgaReg *reg, VGA32 value) +{ + VgaSet (card, reg, value); + VgaFlushReg (card, reg); +} + +VGA32 +VgaGet (VgaCard *card, VgaReg *reg) +{ + VGA32 value, offset, v; + VGA8 mask; + + value = 0; + offset = 0; + while (reg->len) + { + if (reg->id != VGA_REG_NONE) + { + _VgaSync (card, reg->id); + mask = ((1 << reg->len) - 1); + v = (card->values[reg->id].cur >> reg->base) & mask; + value |= (v << offset); + } + offset += reg->len; + reg++; + } + return value; +} + +VGA32 +VgaGetImm (VgaCard *card, VgaReg *reg) +{ + VgaReg *r = reg; + + while (r->len) + { + if (r->id != VGA_REG_NONE) + card->values[r->id].flags &= ~VGA_VALUE_VALID; + r++; + } + return VgaGet (card, reg); +} + +void +VgaFlush (VgaCard *card) +{ + VGA16 id; + + for (id = 0; id < card->max; id++) + { + if (card->values[id].flags & VGA_VALUE_DIRTY) + { + VgaStore (card, id, card->values[id].cur); + card->values[id].flags &= ~VGA_VALUE_DIRTY; + } + } +} + +void +VgaFill (VgaCard *card, VGA16 low, VGA16 high) +{ + VGA16 id; + + for (id = low; id < high; id++) + _VgaSync (card, id); +} diff --git a/xorg-server/hw/kdrive/src/vga.h b/xorg-server/hw/kdrive/src/vga.h new file mode 100644 index 000000000..0615d5256 --- /dev/null +++ b/xorg-server/hw/kdrive/src/vga.h @@ -0,0 +1,144 @@ +/* + * 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. + */ + +#ifndef _VGA_H_ +#define _VGA_H_ + +typedef unsigned long VGA32; +typedef unsigned short VGA16; +typedef unsigned char VGA8; +typedef int VGABOOL; +typedef volatile VGA8 VGAVOL8; + +#define VGATRUE 1 +#define VGAFALSE 0 + +typedef struct _vgaReg { + VGA16 id; + VGA8 base; + VGA8 len; +} VgaReg; + +#define VGA_REG_NONE 0xffff +#define VGA_REG_END VGA_REG_NONE, 0, 0 + +typedef struct _vgaValue { + VGA8 save; + VGA8 cur; + VGA16 flags; +} VgaValue; + +#define VGA_VALUE_VALID 1 /* value ever fetched */ +#define VGA_VALUE_MODIFIED 2 /* value ever changed */ +#define VGA_VALUE_DIRTY 4 /* value needs syncing */ +#define VGA_VALUE_SAVED 8 /* value preserved */ + +typedef enum _vgaAccess { + VgaAccessMem, VgaAccessIo, VgaAccessIndMem, VgaAccessIndIo, + VgaAccessDone +} VgaAccess; + +typedef struct _vgaMap { + VgaAccess access; + VGA32 port; + VGA8 addr; /* for Ind access; addr offset from port */ + VGA8 value; /* for Ind access; value offset from port */ + VGA8 index; /* for Ind access; index value */ +} VgaMap; + +#define VGA_UNLOCK_FIXED 1 /* dont save current value */ +#define VGA_UNLOCK_LOCK 2 /* execute only on relock */ +#define VGA_UNLOCK_UNLOCK 4 /* execute only on unlock */ + +typedef struct _vgaSave { + VGA16 first; + VGA16 last; +} VgaSave; + +#define VGA_SAVE_END VGA_REG_NONE, VGA_REG_NONE + +typedef struct _vgaCard { + void (*map) (struct _vgaCard *card, VGA16 reg, VgaMap *map, VGABOOL write); + void *closure; + int max; + VgaValue *values; + VgaSave *saves; +} VgaCard; + +VGA8 +VgaInb (VGA16 r); + +void +VgaOutb (VGA8 v, VGA16 r); + +VGA8 +VgaReadMemb (VGA32 addr); + +void +VgaWriteMemb (VGA8 v, VGA32 addr); + +void +VgaSetImm (VgaCard *card, VgaReg *reg, VGA32 value); + +VGA32 +VgaGetImm (VgaCard *card, VgaReg *reg); + +void +VgaSet (VgaCard *card, VgaReg *reg, VGA32 value); + +VGA32 +VgaGet (VgaCard *card, VgaReg *reg); + +void +VgaFlush (VgaCard *card); + +void +VgaFill (VgaCard *card, VGA16 low, VGA16 high); + +void +VgaPreserve (VgaCard *card); + +void +VgaInvalidate (VgaCard *card); + +void +VgaRestore (VgaCard *card); + +void +VgaFinish (VgaCard *card); + +void +VgaFlushReg (VgaCard *card, VgaReg *reg); + +VGA8 +VgaFetch (VgaCard *card, VGA16 id); + +void +VgaStore (VgaCard *card, VGA16 id, VGA8 value); + +VGA8 +_VgaFetchInd (VGA16 port, VGA8 reg); + +void +_VgaStoreInd (VGA16 port, VGA8 reg, VGA8 value); + +#endif /* _VGA_H_ */ |