diff options
67 files changed, 6571 insertions, 6351 deletions
diff --git a/apps/xwininfo/configure.ac b/apps/xwininfo/configure.ac index cc85a7ad8..b86aa20f5 100644 --- a/apps/xwininfo/configure.ac +++ b/apps/xwininfo/configure.ac @@ -22,7 +22,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ([2.60]) -AC_INIT([xwininfo], [1.1.1], +AC_INIT([xwininfo], [1.1.2], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xwininfo]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE diff --git a/libX11/configure.ac b/libX11/configure.ac index c085df379..0c68ff4ce 100644 --- a/libX11/configure.ac +++ b/libX11/configure.ac @@ -20,17 +20,18 @@ AM_MAINTAINER_MODE # Initialize libtool AC_PROG_LIBTOOL -# Require xorg-macros minimum of 1.12 for DocBook external references +# Require xorg-macros minimum of 1.15 for fop minimum version m4_ifndef([XORG_MACROS_VERSION], - [m4_fatal([must install xorg-macros 1.12 or later before running autoconf/autogen])]) -XORG_MACROS_VERSION(1.12) + [m4_fatal([must install xorg-macros 1.15 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.15) XORG_DEFAULT_OPTIONS XORG_ENABLE_SPECS XORG_WITH_XMLTO(0.0.22) -XORG_WITH_FOP([no]) +XORG_WITH_FOP([],[no]) XORG_WITH_XSLTPROC XORG_CHECK_SGML_DOCTOOLS(1.8) XORG_PROG_RAWCPP +XORG_WITH_PERL # Required when PKG_CHECK_MODULES called within an if statement PKG_PROG_PKG_CONFIG @@ -65,15 +66,6 @@ if test x"$LDFLAGS_FOR_BUILD" = x; then fi AC_SUBST(LDFLAGS_FOR_BUILD) -# Find perl for "make check" tests in nls/Makefile.am -AC_ARG_WITH(perl, - AS_HELP_STRING([--with-perl=<path>], - [path to perl interpreter for build-time tests]), - [PERL=$withval ; AC_MSG_CHECKING([perl]) ; - AC_MSG_RESULT([(from --with-perl) $PERL])], - AC_CHECK_PROGS([PERL], [perl], [no])) -AM_CONDITIONAL(HAVE_PERL, test x$PERL != xno) - # Checks for pkg-config packages # Always required diff --git a/mesalib/Makefile b/mesalib/Makefile index 131e57872..0a3deb816 100644 --- a/mesalib/Makefile +++ b/mesalib/Makefile @@ -183,7 +183,7 @@ ultrix-gcc: # Rules for making release tarballs -VERSION=7.11-devel +VERSION=7.12-devel DIRECTORY = Mesa-$(VERSION) LIB_NAME = MesaLib-$(VERSION) GLUT_NAME = MesaGLUT-$(VERSION) diff --git a/mesalib/configs/default b/mesalib/configs/default index e9f493a17..132ccbee3 100644 --- a/mesalib/configs/default +++ b/mesalib/configs/default @@ -9,7 +9,7 @@ CONFIG_NAME = default # Version info MESA_MAJOR=7 -MESA_MINOR=11 +MESA_MINOR=12 MESA_TINY=0 MESA_VERSION = $(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY) diff --git a/mesalib/configs/linux-llvm b/mesalib/configs/linux-llvm index 12ccb0217..54d82b537 100644 --- a/mesalib/configs/linux-llvm +++ b/mesalib/configs/linux-llvm @@ -1,44 +1,47 @@ -# -*-makefile-*-
-# Configuration for Linux and LLVM with optimizations
-# Builds the llvmpipe gallium driver
-
-include $(TOP)/configs/linux
-
-CONFIG_NAME = linux-llvm
-
-# Add llvmpipe driver
-GALLIUM_DRIVERS_DIRS += llvmpipe
-
-OPT_FLAGS = -O3 -ansi -pedantic
-ARCH_FLAGS = -mmmx -msse -msse2 -mstackrealign
-
-DEFINES += -DNDEBUG -DGALLIUM_LLVMPIPE
-
-# override -std=c99
-CFLAGS += -std=gnu99
-
-LLVM_VERSION := $(shell llvm-config --version)
-
-ifeq ($(LLVM_VERSION),)
- $(warning Could not find LLVM! Make Sure 'llvm-config' is in the path)
- MESA_LLVM=0
-else
- MESA_LLVM=1
- HAVE_LLVM := 0x0$(subst .,0,$(LLVM_VERSION:svn=))
- DEFINES += -DHAVE_LLVM=$(HAVE_LLVM)
-# $(info Using LLVM version: $(LLVM_VERSION))
-endif
-
-ifeq ($(MESA_LLVM),1)
- LLVM_CFLAGS=`llvm-config --cppflags`
- LLVM_CXXFLAGS=`llvm-config --cxxflags` -Wno-long-long
- LLVM_LDFLAGS = $(shell llvm-config --ldflags)
- LLVM_LIBS = $(shell llvm-config --libs)
- MKLIB_OPTIONS=-cplusplus
-else
- LLVM_CFLAGS=
- LLVM_CXXFLAGS=
-endif
-
-LD = g++
-GL_LIB_DEPS = $(LLVM_LDFLAGS) $(LLVM_LIBS) $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread -lstdc++
+# -*-makefile-*- +# Configuration for Linux and LLVM with optimizations +# Builds the llvmpipe gallium driver + +include $(TOP)/configs/linux + +CONFIG_NAME = linux-llvm + +# Add llvmpipe driver +GALLIUM_DRIVERS_DIRS += llvmpipe + +OPT_FLAGS = -O3 -ansi -pedantic +ARCH_FLAGS = -mmmx -msse -msse2 -mstackrealign + +DEFINES += -DNDEBUG -DGALLIUM_LLVMPIPE + +# override -std=c99 +CFLAGS += -std=gnu99 + +LLVM_VERSION := $(shell llvm-config --version) + +ifeq ($(LLVM_VERSION),) + $(warning Could not find LLVM! Make Sure 'llvm-config' is in the path) + MESA_LLVM=0 +else + MESA_LLVM=1 + HAVE_LLVM := 0x0$(subst .,0,$(LLVM_VERSION:svn=)) + DEFINES += -DHAVE_LLVM=$(HAVE_LLVM) +# $(info Using LLVM version: $(LLVM_VERSION)) +endif + +ifeq ($(MESA_LLVM),1) + LLVM_CFLAGS=`llvm-config --cppflags` + LLVM_CXXFLAGS=`llvm-config --cxxflags` -Wno-long-long + LLVM_LDFLAGS = $(shell llvm-config --ldflags) + LLVM_LIBS = $(shell llvm-config --libs) + MKLIB_OPTIONS=-cplusplus +else + LLVM_CFLAGS= + LLVM_CXXFLAGS= +endif + +LD = g++ +GL_LIB_DEPS = $(LLVM_LDFLAGS) $(LLVM_LIBS) $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread -lstdc++ + +# to allow the NV drivers to compile +LIBDRM_CFLAGS = $(shell pkg-config --cflags libdrm) diff --git a/mesalib/configure.ac b/mesalib/configure.ac index 0346a8ade..acf9f0604 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -177,8 +177,10 @@ if test "x$GXX" = xyes; then AC_MSG_CHECKING([whether $CXX supports -fvisibility=hidden]) VISIBILITY_CXXFLAGS="-fvisibility=hidden" CXXFLAGS="$CXXFLAGS $VISIBILITY_CXXFLAGS" + AC_LANG_PUSH([C++]) AC_LINK_IFELSE([AC_LANG_PROGRAM()], AC_MSG_RESULT([yes]), [VISIBILITY_CXXFLAGS="" ; AC_MSG_RESULT([no])]); + AC_LANG_POP([C++]) # Restore CXXFLAGS; VISIBILITY_CXXFLAGS are added to it where needed. CXXFLAGS=$save_CXXFLAGS @@ -187,6 +189,15 @@ if test "x$GXX" = xyes; then CXXFLAGS="$CXXFLAGS -fno-strict-aliasing" fi +dnl even if the compiler appears to support it, using visibility attributes isn't +dnl going to do anything useful currently on cygwin apart from emit lots of warnings +case "$host_os" in +cygwin*) + VISIBILITY_CFLAGS="" + VISIBILITY_CXXFLAGS="" + ;; +esac + AC_SUBST([VISIBILITY_CFLAGS]) AC_SUBST([VISIBILITY_CXXFLAGS]) @@ -872,7 +883,11 @@ dri|no) # these checks are still desired when there is no mesa_driver else # should check these... X11_INCLUDES="$X11_INCLUDES $X_CFLAGS" - GL_LIB_DEPS="$X_LIBS -lX11 -lXext -lXxf86vm -lXdamage -lXfixes" + if test "x$HAVE_XF86VIDMODE" == xyes; then + GL_LIB_DEPS="$X_LIBS -lX11 -lXext -lXxf86vm -lXdamage -lXfixes" + else + GL_LIB_DEPS="$X_LIBS -lX11 -lXext -lXdamage -lXfixes" + fi GL_PC_LIB_PRIV="$GL_LIB_DEPS" GL_PC_CFLAGS="$X11_INCLUDES" diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index 3ba699ad9..60a2c617f 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -271,17 +271,36 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) assert(a <= GLSL_TYPE_BOOL); assert(b <= GLSL_TYPE_BOOL); - if ((a == b) || (src->type->is_integer() && desired_type->is_integer())) + if (a == b) return src; switch (a) { case GLSL_TYPE_UINT: + switch (b) { + case GLSL_TYPE_INT: + result = new(ctx) ir_expression(ir_unop_i2u, src); + break; + case GLSL_TYPE_FLOAT: + result = new(ctx) ir_expression(ir_unop_i2u, + new(ctx) ir_expression(ir_unop_f2i, src)); + break; + case GLSL_TYPE_BOOL: + result = new(ctx) ir_expression(ir_unop_i2u, + new(ctx) ir_expression(ir_unop_b2i, src)); + break; + } + break; case GLSL_TYPE_INT: - if (b == GLSL_TYPE_FLOAT) - result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL); - else { - assert(b == GLSL_TYPE_BOOL); - result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL); + switch (b) { + case GLSL_TYPE_UINT: + result = new(ctx) ir_expression(ir_unop_u2i, src); + break; + case GLSL_TYPE_FLOAT: + result = new(ctx) ir_expression(ir_unop_f2i, src); + break; + case GLSL_TYPE_BOOL: + result = new(ctx) ir_expression(ir_unop_b2i, src); + break; } break; case GLSL_TYPE_FLOAT: @@ -300,6 +319,9 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) case GLSL_TYPE_BOOL: switch (b) { case GLSL_TYPE_UINT: + result = new(ctx) ir_expression(ir_unop_i2b, + new(ctx) ir_expression(ir_unop_u2i, src)); + break; case GLSL_TYPE_INT: result = new(ctx) ir_expression(ir_unop_i2b, desired_type, src, NULL); break; @@ -311,6 +333,7 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) } assert(result != NULL); + assert(result->type == desired_type); /* Try constant folding; it may fold in the conversion we just added. */ ir_constant *const constant = result->constant_expression_value(); diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 3b87f0d56..2e54e8c22 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -447,9 +447,17 @@ modulus_result_type(const struct glsl_type *type_a, * integer vectors. The operand types must both be signed or both be * unsigned." */ - if (!type_a->is_integer() || !type_b->is_integer() - || (type_a->base_type != type_b->base_type)) { - _mesa_glsl_error(loc, state, "type mismatch"); + if (!type_a->is_integer()) { + _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer."); + return glsl_type::error_type; + } + if (!type_b->is_integer()) { + _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer."); + return glsl_type::error_type; + } + if (type_a->base_type != type_b->base_type) { + _mesa_glsl_error(loc, state, + "operands of %% must have the same base type"); return glsl_type::error_type; } @@ -1940,7 +1948,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, break; case fragment_shader: - if (!global_scope || (var->mode != ir_var_in)) { + if (!global_scope || (var->mode != ir_var_out)) { fail = true; string = "output"; } diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index d9aa300bb..cc781378d 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -165,133 +165,242 @@ _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, } +/** + * Enum representing the possible behaviors that can be specified in + * an #extension directive. + */ +enum ext_behavior { + extension_disable, + extension_enable, + extension_require, + extension_warn +}; + +/** + * Element type for _mesa_glsl_supported_extensions + */ +struct _mesa_glsl_extension { + /** + * Name of the extension when referred to in a GLSL extension + * statement + */ + const char *name; + + /** True if this extension is available to vertex shaders */ + bool avail_in_VS; + + /** True if this extension is available to geometry shaders */ + bool avail_in_GS; + + /** True if this extension is available to fragment shaders */ + bool avail_in_FS; + + /** True if this extension is available to desktop GL shaders */ + bool avail_in_GL; + + /** True if this extension is available to GLES shaders */ + bool avail_in_ES; + + /** + * Flag in the gl_extensions struct indicating whether this + * extension is supported by the driver, or + * &gl_extensions::dummy_true if supported by all drivers. + * + * Note: the type (GLboolean gl_extensions::*) is a "pointer to + * member" type, the type-safe alternative to the "offsetof" macro. + * In a nutshell: + * + * - foo bar::* p declares p to be an "offset" to a field of type + * foo that exists within struct bar + * - &bar::baz computes the "offset" of field baz within struct bar + * - x.*p accesses the field of x that exists at "offset" p + * - x->*p is equivalent to (*x).*p + */ + const GLboolean gl_extensions::* supported_flag; + + /** + * Flag in the _mesa_glsl_parse_state struct that should be set + * when this extension is enabled. + * + * See note in _mesa_glsl_extension::supported_flag about "pointer + * to member" types. + */ + bool _mesa_glsl_parse_state::* enable_flag; + + /** + * Flag in the _mesa_glsl_parse_state struct that should be set + * when the shader requests "warn" behavior for this extension. + * + * See note in _mesa_glsl_extension::supported_flag about "pointer + * to member" types. + */ + bool _mesa_glsl_parse_state::* warn_flag; + + + bool compatible_with_state(const _mesa_glsl_parse_state *state) const; + void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const; +}; + +#define EXT(NAME, VS, GS, FS, GL, ES, SUPPORTED_FLAG) \ + { "GL_" #NAME, VS, GS, FS, GL, ES, &gl_extensions::SUPPORTED_FLAG, \ + &_mesa_glsl_parse_state::NAME##_enable, \ + &_mesa_glsl_parse_state::NAME##_warn } + +/** + * Table of extensions that can be enabled/disabled within a shader, + * and the conditions under which they are supported. + */ +static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { + /* target availability API availability */ + /* name VS GS FS GL ES supported flag */ + EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true), + EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced), + EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location), + EXT(ARB_fragment_coord_conventions, true, false, true, true, false, ARB_fragment_coord_conventions), + EXT(ARB_texture_rectangle, true, false, true, true, false, dummy_true), + EXT(EXT_texture_array, true, false, true, true, false, EXT_texture_array), + EXT(ARB_shader_texture_lod, true, false, true, true, false, ARB_shader_texture_lod), + EXT(ARB_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), + EXT(AMD_conservative_depth, true, false, true, true, false, AMD_conservative_depth), + EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), + EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D), +}; + +#undef EXT + + +/** + * Determine whether a given extension is compatible with the target, + * API, and extension information in the current parser state. + */ +bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state * + state) const +{ + /* Check that this extension matches the type of shader we are + * compiling to. + */ + switch (state->target) { + case vertex_shader: + if (!this->avail_in_VS) { + return false; + } + break; + case geometry_shader: + if (!this->avail_in_GS) { + return false; + } + break; + case fragment_shader: + if (!this->avail_in_FS) { + return false; + } + break; + default: + assert (!"Unrecognized shader target"); + return false; + } + + /* Check that this extension matches whether we are compiling + * for desktop GL or GLES. + */ + if (state->es_shader) { + if (!this->avail_in_ES) return false; + } else { + if (!this->avail_in_GL) return false; + } + + /* Check that this extension is supported by the OpenGL + * implementation. + * + * Note: the ->* operator indexes into state->extensions by the + * offset this->supported_flag. See + * _mesa_glsl_extension::supported_flag for more info. + */ + return state->extensions->*(this->supported_flag); +} + +/** + * Set the appropriate flags in the parser state to establish the + * given behavior for this extension. + */ +void _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state, + ext_behavior behavior) const +{ + /* Note: the ->* operator indexes into state by the + * offsets this->enable_flag and this->warn_flag. See + * _mesa_glsl_extension::supported_flag for more info. + */ + state->*(this->enable_flag) = (behavior != extension_disable); + state->*(this->warn_flag) = (behavior == extension_warn); +} + +/** + * Find an extension by name in _mesa_glsl_supported_extensions. If + * the name is not found, return NULL. + */ +static const _mesa_glsl_extension *find_extension(const char *name) +{ + for (unsigned i = 0; i < Elements(_mesa_glsl_supported_extensions); ++i) { + if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) { + return &_mesa_glsl_supported_extensions[i]; + } + } + return NULL; +} + + bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, - const char *behavior, YYLTYPE *behavior_locp, + const char *behavior_string, YYLTYPE *behavior_locp, _mesa_glsl_parse_state *state) { - enum { - extension_disable, - extension_enable, - extension_require, - extension_warn - } ext_mode; - - if (strcmp(behavior, "warn") == 0) { - ext_mode = extension_warn; - } else if (strcmp(behavior, "require") == 0) { - ext_mode = extension_require; - } else if (strcmp(behavior, "enable") == 0) { - ext_mode = extension_enable; - } else if (strcmp(behavior, "disable") == 0) { - ext_mode = extension_disable; + ext_behavior behavior; + if (strcmp(behavior_string, "warn") == 0) { + behavior = extension_warn; + } else if (strcmp(behavior_string, "require") == 0) { + behavior = extension_require; + } else if (strcmp(behavior_string, "enable") == 0) { + behavior = extension_enable; + } else if (strcmp(behavior_string, "disable") == 0) { + behavior = extension_disable; } else { _mesa_glsl_error(behavior_locp, state, "Unknown extension behavior `%s'", - behavior); + behavior_string); return false; } - bool unsupported = false; - if (strcmp(name, "all") == 0) { - if ((ext_mode == extension_enable) || (ext_mode == extension_require)) { + if ((behavior == extension_enable) || (behavior == extension_require)) { _mesa_glsl_error(name_locp, state, "Cannot %s all extensions", - (ext_mode == extension_enable) + (behavior == extension_enable) ? "enable" : "require"); return false; - } - } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) { - /* This extension is only supported in fragment shaders. - */ - if (state->target != fragment_shader) { - unsupported = true; } else { - state->ARB_draw_buffers_enable = (ext_mode != extension_disable); - state->ARB_draw_buffers_warn = (ext_mode == extension_warn); + for (unsigned i = 0; + i < Elements(_mesa_glsl_supported_extensions); ++i) { + const _mesa_glsl_extension *extension + = &_mesa_glsl_supported_extensions[i]; + if (extension->compatible_with_state(state)) { + _mesa_glsl_supported_extensions[i].set_flags(state, behavior); + } + } } - } else if (strcmp(name, "GL_ARB_draw_instanced") == 0) { - state->ARB_draw_instanced_enable = (ext_mode != extension_disable); - state->ARB_draw_instanced_warn = (ext_mode == extension_warn); - - /* This extension is only supported in vertex shaders. - */ - unsupported = (state->target != vertex_shader) - || !state->extensions->ARB_draw_instanced; - } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) { - state->ARB_explicit_attrib_location_enable = - (ext_mode != extension_disable); - state->ARB_explicit_attrib_location_warn = - (ext_mode == extension_warn); - - unsupported = !state->extensions->ARB_explicit_attrib_location; - } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) { - state->ARB_fragment_coord_conventions_enable = - (ext_mode != extension_disable); - state->ARB_fragment_coord_conventions_warn = - (ext_mode == extension_warn); - - unsupported = !state->extensions->ARB_fragment_coord_conventions; - } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) { - state->ARB_texture_rectangle_enable = (ext_mode != extension_disable); - state->ARB_texture_rectangle_warn = (ext_mode == extension_warn); - } else if (strcmp(name, "GL_EXT_texture_array") == 0) { - state->EXT_texture_array_enable = (ext_mode != extension_disable); - state->EXT_texture_array_warn = (ext_mode == extension_warn); - - unsupported = !state->extensions->EXT_texture_array; - } else if (strcmp(name, "GL_ARB_shader_texture_lod") == 0) { - /* Force ARB_texture_rectangle to be on so sampler2DRects are defined */ - state->ARB_texture_rectangle_enable = true; - - state->ARB_shader_texture_lod_enable = (ext_mode != extension_disable); - state->ARB_shader_texture_lod_warn = (ext_mode == extension_warn); - - unsupported = !state->extensions->ARB_shader_texture_lod; - } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) { - state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable); - state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn); - - /* This extension is only supported in fragment shaders. - */ - unsupported = (state->target != fragment_shader) - || !state->extensions->ARB_shader_stencil_export; - } else if (strcmp(name, "GL_AMD_conservative_depth") == 0) { - /* The AMD_conservative spec does not forbid requiring the extension in - * the vertex shader. - */ - state->AMD_conservative_depth_enable = (ext_mode != extension_disable); - state->AMD_conservative_depth_warn = (ext_mode == extension_warn); - unsupported = !state->extensions->AMD_conservative_depth; - } else if (strcmp(name, "GL_AMD_shader_stencil_export") == 0) { - state->AMD_shader_stencil_export_enable = (ext_mode != extension_disable); - state->AMD_shader_stencil_export_warn = (ext_mode == extension_warn); - - /* This extension is only supported in fragment shaders. - * Both the ARB and AMD variants share the same ARB flag - * in gl_extensions. - */ - unsupported = (state->target != fragment_shader) - || !state->extensions->ARB_shader_stencil_export; - } else if (strcmp(name, "GL_OES_texture_3D") == 0 && state->es_shader) { - state->OES_texture_3D_enable = (ext_mode != extension_disable); - state->OES_texture_3D_warn = (ext_mode == extension_warn); - - unsupported = !state->extensions->EXT_texture3D; } else { - unsupported = true; - } - - if (unsupported) { - static const char *const fmt = "extension `%s' unsupported in %s shader"; - - if (ext_mode == extension_require) { - _mesa_glsl_error(name_locp, state, fmt, - name, _mesa_glsl_shader_target_name(state->target)); - return false; + const _mesa_glsl_extension *extension = find_extension(name); + if (extension && extension->compatible_with_state(state)) { + extension->set_flags(state, behavior); } else { - _mesa_glsl_warning(name_locp, state, fmt, - name, _mesa_glsl_shader_target_name(state->target)); + static const char *const fmt = "extension `%s' unsupported in %s shader"; + + if (behavior == extension_require) { + _mesa_glsl_error(name_locp, state, fmt, + name, _mesa_glsl_shader_target_name(state->target)); + return false; + } else { + _mesa_glsl_warning(name_locp, state, fmt, + name, _mesa_glsl_shader_target_name(state->target)); + } } } diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index 878d2ae3f..2f4d3cba7 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -156,28 +156,28 @@ struct _mesa_glsl_parse_state { * \name Enable bits for GLSL extensions */ /*@{*/ - unsigned ARB_draw_buffers_enable:1; - unsigned ARB_draw_buffers_warn:1; - unsigned ARB_draw_instanced_enable:1; - unsigned ARB_draw_instanced_warn:1; - unsigned ARB_explicit_attrib_location_enable:1; - unsigned ARB_explicit_attrib_location_warn:1; - unsigned ARB_fragment_coord_conventions_enable:1; - unsigned ARB_fragment_coord_conventions_warn:1; - unsigned ARB_texture_rectangle_enable:1; - unsigned ARB_texture_rectangle_warn:1; - unsigned EXT_texture_array_enable:1; - unsigned EXT_texture_array_warn:1; - unsigned ARB_shader_texture_lod_enable:1; - unsigned ARB_shader_texture_lod_warn:1; - unsigned ARB_shader_stencil_export_enable:1; - unsigned ARB_shader_stencil_export_warn:1; - unsigned AMD_conservative_depth_enable:1; - unsigned AMD_conservative_depth_warn:1; - unsigned AMD_shader_stencil_export_enable:1; - unsigned AMD_shader_stencil_export_warn:1; - unsigned OES_texture_3D_enable:1; - unsigned OES_texture_3D_warn:1; + bool ARB_draw_buffers_enable; + bool ARB_draw_buffers_warn; + bool ARB_draw_instanced_enable; + bool ARB_draw_instanced_warn; + bool ARB_explicit_attrib_location_enable; + bool ARB_explicit_attrib_location_warn; + bool ARB_fragment_coord_conventions_enable; + bool ARB_fragment_coord_conventions_warn; + bool ARB_texture_rectangle_enable; + bool ARB_texture_rectangle_warn; + bool EXT_texture_array_enable; + bool EXT_texture_array_warn; + bool ARB_shader_texture_lod_enable; + bool ARB_shader_texture_lod_warn; + bool ARB_shader_stencil_export_enable; + bool ARB_shader_stencil_export_warn; + bool AMD_conservative_depth_enable; + bool AMD_conservative_depth_warn; + bool AMD_shader_stencil_export_enable; + bool AMD_shader_stencil_export_warn; + bool OES_texture_3D_enable; + bool OES_texture_3D_warn; /*@}*/ /** Extensions supported by the OpenGL implementation. */ diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index a3623b31e..95689dc10 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -272,6 +272,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_f2i: case ir_unop_b2i: + case ir_unop_u2i: this->type = glsl_type::get_instance(GLSL_TYPE_INT, op0->type->vector_elements, 1); break; @@ -289,6 +290,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) op0->type->vector_elements, 1); break; + case ir_unop_i2u: + this->type = glsl_type::get_instance(GLSL_TYPE_UINT, + op0->type->vector_elements, 1); + break; + case ir_unop_noise: this->type = glsl_type::float_type; break; @@ -419,6 +425,8 @@ static const char *const operator_strs[] = { "i2b", "b2i", "u2f", + "i2u", + "u2i", "any", "trunc", "ceil", diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index a41984310..42a393697 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -682,7 +682,7 @@ public: class ir_assignment : public ir_instruction { public: - ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition); + ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition = NULL); /** * Construct an assignment with an explicit write mask @@ -789,6 +789,8 @@ enum ir_expression_operation { ir_unop_i2b, /**< int-to-boolean conversion */ ir_unop_b2i, /**< Boolean-to-int conversion */ ir_unop_u2f, /**< Unsigned-to-float conversion. */ + ir_unop_i2u, /**< Integer-to-unsigned conversion. */ + ir_unop_u2i, /**< Unsigned-to-integer conversion. */ ir_unop_any, /** diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp index 2a3084896..f0299a2c4 100644 --- a/mesalib/src/glsl/ir_constant_expression.cpp +++ b/mesalib/src/glsl/ir_constant_expression.cpp @@ -166,7 +166,18 @@ ir_expression::constant_expression_value() data.b[c] = op[0]->value.u[c] ? true : false; } break; - + case ir_unop_u2i: + assert(op[0]->type->base_type == GLSL_TYPE_UINT); + for (unsigned c = 0; c < op[0]->type->components(); c++) { + data.i[c] = op[0]->value.u[c]; + } + break; + case ir_unop_i2u: + assert(op[0]->type->base_type == GLSL_TYPE_INT); + for (unsigned c = 0; c < op[0]->type->components(); c++) { + data.u[c] = op[0]->value.i[c]; + } + break; case ir_unop_any: assert(op[0]->type->is_boolean()); data.b[0] = false; diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp index caee9296a..ef8d4fcfc 100644 --- a/mesalib/src/glsl/ir_function.cpp +++ b/mesalib/src/glsl/ir_function.cpp @@ -165,6 +165,7 @@ ir_function_signature * ir_function::matching_signature(const exec_list *actual_parameters) { ir_function_signature *match = NULL; + int matched_score; foreach_iter(exec_list_iterator, iter, signatures) { ir_function_signature *const sig = @@ -173,14 +174,14 @@ ir_function::matching_signature(const exec_list *actual_parameters) const int score = parameter_lists_match(& sig->parameters, actual_parameters); + /* If we found an exact match, simply return it */ if (score == 0) return sig; - if (score > 0) { - if (match != NULL) - return NULL; - + /* If we found a match with fewer conversions, use that instead */ + if (score > 0 && (match == NULL || score < matched_score)) { match = sig; + matched_score = score; } } diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index 7b1c19d65..f3fceb2a5 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -254,7 +254,7 @@ ir_validate::visit_leave(ir_expression *ir) case ir_unop_f2i: assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->type->is_integer()); + assert(ir->type->base_type == GLSL_TYPE_INT); break; case ir_unop_i2f: assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); @@ -269,17 +269,25 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->type->base_type == GLSL_TYPE_FLOAT); break; case ir_unop_i2b: - assert(ir->operands[0]->type->is_integer()); + assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); assert(ir->type->base_type == GLSL_TYPE_BOOL); break; case ir_unop_b2i: assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - assert(ir->type->is_integer()); + assert(ir->type->base_type == GLSL_TYPE_INT); break; case ir_unop_u2f: assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); assert(ir->type->base_type == GLSL_TYPE_FLOAT); break; + case ir_unop_i2u: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); + assert(ir->type->base_type == GLSL_TYPE_UINT); + break; + case ir_unop_u2i: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); + assert(ir->type->base_type == GLSL_TYPE_INT); + break; case ir_unop_any: assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); diff --git a/mesalib/src/glsl/lower_if_to_cond_assign.cpp b/mesalib/src/glsl/lower_if_to_cond_assign.cpp index e3a1065d9..b637eb4fe 100644 --- a/mesalib/src/glsl/lower_if_to_cond_assign.cpp +++ b/mesalib/src/glsl/lower_if_to_cond_assign.cpp @@ -149,11 +149,9 @@ ir_visitor_status ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) { /* Only flatten when beyond the GPU's maximum supported nesting depth. */ - if (this->depth <= this->max_depth) + if (this->depth-- <= this->max_depth) return visit_continue; - this->depth--; - bool found_control_flow = false; ir_variable *cond_var; ir_assignment *assign; diff --git a/mesalib/src/glsl/lower_instructions.cpp b/mesalib/src/glsl/lower_instructions.cpp index 6e44d1319..806f86399 100644 --- a/mesalib/src/glsl/lower_instructions.cpp +++ b/mesalib/src/glsl/lower_instructions.cpp @@ -1,288 +1,293 @@ -/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file lower_instructions.cpp
- *
- * Many GPUs lack native instructions for certain expression operations, and
- * must replace them with some other expression tree. This pass lowers some
- * of the most common cases, allowing the lowering code to be implemented once
- * rather than in each driver backend.
- *
- * Currently supported transformations:
- * - SUB_TO_ADD_NEG
- * - DIV_TO_MUL_RCP
- * - EXP_TO_EXP2
- * - POW_TO_EXP2
- * - LOG_TO_LOG2
- * - MOD_TO_FRACT
- *
- * SUB_TO_ADD_NEG:
- * ---------------
- * Breaks an ir_binop_sub expression down to add(op0, neg(op1))
- *
- * This simplifies expression reassociation, and for many backends
- * there is no subtract operation separate from adding the negation.
- * For backends with native subtract operations, they will probably
- * want to recognize add(op0, neg(op1)) or the other way around to
- * produce a subtract anyway.
- *
- * DIV_TO_MUL_RCP:
- * ---------------
- * Breaks an ir_unop_div expression down to op0 * (rcp(op1)).
- *
- * Many GPUs don't have a divide instruction (945 and 965 included),
- * but they do have an RCP instruction to compute an approximate
- * reciprocal. By breaking the operation down, constant reciprocals
- * can get constant folded.
- *
- * EXP_TO_EXP2 and LOG_TO_LOG2:
- * ----------------------------
- * Many GPUs don't have a base e log or exponent instruction, but they
- * do have base 2 versions, so this pass converts exp and log to exp2
- * and log2 operations.
- *
- * POW_TO_EXP2:
- * -----------
- * Many older GPUs don't have an x**y instruction. For these GPUs, convert
- * x**y to 2**(y * log2(x)).
- *
- * MOD_TO_FRACT:
- * -------------
- * Breaks an ir_unop_mod expression down to (op1 * fract(op0 / op1))
- *
- * Many GPUs don't have a MOD instruction (945 and 965 included), and
- * if we have to break it down like this anyway, it gives an
- * opportunity to do things like constant fold the (1.0 / op1) easily.
- */
-
-#include "main/core.h" /* for M_LOG2E */
-#include "glsl_types.h"
-#include "ir.h"
-#include "ir_optimization.h"
-
-class lower_instructions_visitor : public ir_hierarchical_visitor {
-public:
- lower_instructions_visitor(unsigned lower)
- : progress(false), lower(lower) { }
-
- ir_visitor_status visit_leave(ir_expression *);
-
- bool progress;
-
-private:
- unsigned lower; /** Bitfield of which operations to lower */
-
- void sub_to_add_neg(ir_expression *);
- void div_to_mul_rcp(ir_expression *);
- void mod_to_fract(ir_expression *);
- void exp_to_exp2(ir_expression *);
- void pow_to_exp2(ir_expression *);
- void log_to_log2(ir_expression *);
-};
-
-/**
- * Determine if a particular type of lowering should occur
- */
-#define lowering(x) (this->lower & x)
-
-bool
-lower_instructions(exec_list *instructions, unsigned what_to_lower)
-{
- lower_instructions_visitor v(what_to_lower);
-
- visit_list_elements(&v, instructions);
- return v.progress;
-}
-
-void
-lower_instructions_visitor::sub_to_add_neg(ir_expression *ir)
-{
- ir->operation = ir_binop_add;
- ir->operands[1] = new(ir) ir_expression(ir_unop_neg, ir->operands[1]->type,
- ir->operands[1], NULL);
- this->progress = true;
-}
-
-void
-lower_instructions_visitor::div_to_mul_rcp(ir_expression *ir)
-{
- if (!ir->operands[1]->type->is_integer()) {
- /* New expression for the 1.0 / op1 */
- ir_rvalue *expr;
- expr = new(ir) ir_expression(ir_unop_rcp,
- ir->operands[1]->type,
- ir->operands[1],
- NULL);
-
- /* op0 / op1 -> op0 * (1.0 / op1) */
- ir->operation = ir_binop_mul;
- ir->operands[1] = expr;
- } else {
- /* Be careful with integer division -- we need to do it as a
- * float and re-truncate, since rcp(n > 1) of an integer would
- * just be 0.
- */
- ir_rvalue *op0, *op1;
- const struct glsl_type *vec_type;
-
- vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT,
- ir->operands[1]->type->vector_elements,
- ir->operands[1]->type->matrix_columns);
-
- if (ir->operands[1]->type->base_type == GLSL_TYPE_INT)
- op1 = new(ir) ir_expression(ir_unop_i2f, vec_type, ir->operands[1], NULL);
- else
- op1 = new(ir) ir_expression(ir_unop_u2f, vec_type, ir->operands[1], NULL);
-
- op1 = new(ir) ir_expression(ir_unop_rcp, op1->type, op1, NULL);
-
- vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT,
- ir->operands[0]->type->vector_elements,
- ir->operands[0]->type->matrix_columns);
-
- if (ir->operands[0]->type->base_type == GLSL_TYPE_INT)
- op0 = new(ir) ir_expression(ir_unop_i2f, vec_type, ir->operands[0], NULL);
- else
- op0 = new(ir) ir_expression(ir_unop_u2f, vec_type, ir->operands[0], NULL);
-
- op0 = new(ir) ir_expression(ir_binop_mul, vec_type, op0, op1);
-
- ir->operation = ir_unop_f2i;
- ir->operands[0] = op0;
- ir->operands[1] = NULL;
- }
-
- this->progress = true;
-}
-
-void
-lower_instructions_visitor::exp_to_exp2(ir_expression *ir)
-{
- ir_constant *log2_e = new(ir) ir_constant(float(M_LOG2E));
-
- ir->operation = ir_unop_exp2;
- ir->operands[0] = new(ir) ir_expression(ir_binop_mul, ir->operands[0]->type,
- ir->operands[0], log2_e);
- this->progress = true;
-}
-
-void
-lower_instructions_visitor::pow_to_exp2(ir_expression *ir)
-{
- ir_expression *const log2_x =
- new(ir) ir_expression(ir_unop_log2, ir->operands[0]->type,
- ir->operands[0]);
-
- ir->operation = ir_unop_exp2;
- ir->operands[0] = new(ir) ir_expression(ir_binop_mul, ir->operands[1]->type,
- ir->operands[1], log2_x);
- ir->operands[1] = NULL;
- this->progress = true;
-}
-
-void
-lower_instructions_visitor::log_to_log2(ir_expression *ir)
-{
- ir->operation = ir_binop_mul;
- ir->operands[0] = new(ir) ir_expression(ir_unop_log2, ir->operands[0]->type,
- ir->operands[0], NULL);
- ir->operands[1] = new(ir) ir_constant(float(1.0 / M_LOG2E));
- this->progress = true;
-}
-
-void
-lower_instructions_visitor::mod_to_fract(ir_expression *ir)
-{
- ir_variable *temp = new(ir) ir_variable(ir->operands[1]->type, "mod_b",
- ir_var_temporary);
- this->base_ir->insert_before(temp);
-
- ir_assignment *const assign =
- new(ir) ir_assignment(new(ir) ir_dereference_variable(temp),
- ir->operands[1], NULL);
-
- this->base_ir->insert_before(assign);
-
- ir_expression *const div_expr =
- new(ir) ir_expression(ir_binop_div, ir->operands[0]->type,
- ir->operands[0],
- new(ir) ir_dereference_variable(temp));
-
- /* Don't generate new IR that would need to be lowered in an additional
- * pass.
- */
- if (lowering(DIV_TO_MUL_RCP))
- div_to_mul_rcp(div_expr);
-
- ir_rvalue *expr = new(ir) ir_expression(ir_unop_fract,
- ir->operands[0]->type,
- div_expr,
- NULL);
-
- ir->operation = ir_binop_mul;
- ir->operands[0] = new(ir) ir_dereference_variable(temp);
- ir->operands[1] = expr;
- this->progress = true;
-}
-
-ir_visitor_status
-lower_instructions_visitor::visit_leave(ir_expression *ir)
-{
- switch (ir->operation) {
- case ir_binop_sub:
- if (lowering(SUB_TO_ADD_NEG))
- sub_to_add_neg(ir);
- break;
-
- case ir_binop_div:
- if (lowering(DIV_TO_MUL_RCP))
- div_to_mul_rcp(ir);
- break;
-
- case ir_unop_exp:
- if (lowering(EXP_TO_EXP2))
- exp_to_exp2(ir);
- break;
-
- case ir_unop_log:
- if (lowering(LOG_TO_LOG2))
- log_to_log2(ir);
- break;
-
- case ir_binop_mod:
- if (lowering(MOD_TO_FRACT))
- mod_to_fract(ir);
- break;
-
- case ir_binop_pow:
- if (lowering(POW_TO_EXP2))
- pow_to_exp2(ir);
- break;
-
- default:
- return visit_continue;
- }
-
- return visit_continue;
-}
+/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file lower_instructions.cpp + * + * Many GPUs lack native instructions for certain expression operations, and + * must replace them with some other expression tree. This pass lowers some + * of the most common cases, allowing the lowering code to be implemented once + * rather than in each driver backend. + * + * Currently supported transformations: + * - SUB_TO_ADD_NEG + * - DIV_TO_MUL_RCP + * - EXP_TO_EXP2 + * - POW_TO_EXP2 + * - LOG_TO_LOG2 + * - MOD_TO_FRACT + * + * SUB_TO_ADD_NEG: + * --------------- + * Breaks an ir_binop_sub expression down to add(op0, neg(op1)) + * + * This simplifies expression reassociation, and for many backends + * there is no subtract operation separate from adding the negation. + * For backends with native subtract operations, they will probably + * want to recognize add(op0, neg(op1)) or the other way around to + * produce a subtract anyway. + * + * DIV_TO_MUL_RCP: + * --------------- + * Breaks an ir_unop_div expression down to op0 * (rcp(op1)). + * + * Many GPUs don't have a divide instruction (945 and 965 included), + * but they do have an RCP instruction to compute an approximate + * reciprocal. By breaking the operation down, constant reciprocals + * can get constant folded. + * + * EXP_TO_EXP2 and LOG_TO_LOG2: + * ---------------------------- + * Many GPUs don't have a base e log or exponent instruction, but they + * do have base 2 versions, so this pass converts exp and log to exp2 + * and log2 operations. + * + * POW_TO_EXP2: + * ----------- + * Many older GPUs don't have an x**y instruction. For these GPUs, convert + * x**y to 2**(y * log2(x)). + * + * MOD_TO_FRACT: + * ------------- + * Breaks an ir_unop_mod expression down to (op1 * fract(op0 / op1)) + * + * Many GPUs don't have a MOD instruction (945 and 965 included), and + * if we have to break it down like this anyway, it gives an + * opportunity to do things like constant fold the (1.0 / op1) easily. + */ + +#include "main/core.h" /* for M_LOG2E */ +#include "glsl_types.h" +#include "ir.h" +#include "ir_optimization.h" + +class lower_instructions_visitor : public ir_hierarchical_visitor { +public: + lower_instructions_visitor(unsigned lower) + : progress(false), lower(lower) { } + + ir_visitor_status visit_leave(ir_expression *); + + bool progress; + +private: + unsigned lower; /** Bitfield of which operations to lower */ + + void sub_to_add_neg(ir_expression *); + void div_to_mul_rcp(ir_expression *); + void mod_to_fract(ir_expression *); + void exp_to_exp2(ir_expression *); + void pow_to_exp2(ir_expression *); + void log_to_log2(ir_expression *); +}; + +/** + * Determine if a particular type of lowering should occur + */ +#define lowering(x) (this->lower & x) + +bool +lower_instructions(exec_list *instructions, unsigned what_to_lower) +{ + lower_instructions_visitor v(what_to_lower); + + visit_list_elements(&v, instructions); + return v.progress; +} + +void +lower_instructions_visitor::sub_to_add_neg(ir_expression *ir) +{ + ir->operation = ir_binop_add; + ir->operands[1] = new(ir) ir_expression(ir_unop_neg, ir->operands[1]->type, + ir->operands[1], NULL); + this->progress = true; +} + +void +lower_instructions_visitor::div_to_mul_rcp(ir_expression *ir) +{ + if (!ir->operands[1]->type->is_integer()) { + /* New expression for the 1.0 / op1 */ + ir_rvalue *expr; + expr = new(ir) ir_expression(ir_unop_rcp, + ir->operands[1]->type, + ir->operands[1], + NULL); + + /* op0 / op1 -> op0 * (1.0 / op1) */ + ir->operation = ir_binop_mul; + ir->operands[1] = expr; + } else { + /* Be careful with integer division -- we need to do it as a + * float and re-truncate, since rcp(n > 1) of an integer would + * just be 0. + */ + ir_rvalue *op0, *op1; + const struct glsl_type *vec_type; + + vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, + ir->operands[1]->type->vector_elements, + ir->operands[1]->type->matrix_columns); + + if (ir->operands[1]->type->base_type == GLSL_TYPE_INT) + op1 = new(ir) ir_expression(ir_unop_i2f, vec_type, ir->operands[1], NULL); + else + op1 = new(ir) ir_expression(ir_unop_u2f, vec_type, ir->operands[1], NULL); + + op1 = new(ir) ir_expression(ir_unop_rcp, op1->type, op1, NULL); + + vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, + ir->operands[0]->type->vector_elements, + ir->operands[0]->type->matrix_columns); + + if (ir->operands[0]->type->base_type == GLSL_TYPE_INT) + op0 = new(ir) ir_expression(ir_unop_i2f, vec_type, ir->operands[0], NULL); + else + op0 = new(ir) ir_expression(ir_unop_u2f, vec_type, ir->operands[0], NULL); + + op0 = new(ir) ir_expression(ir_binop_mul, vec_type, op0, op1); + + if (ir->operands[1]->type->base_type == GLSL_TYPE_INT) { + ir->operation = ir_unop_f2i; + ir->operands[0] = op0; + } else { + ir->operation = ir_unop_i2u; + ir->operands[0] = new(ir) ir_expression(ir_unop_f2i, op0); + } + ir->operands[1] = NULL; + } + + this->progress = true; +} + +void +lower_instructions_visitor::exp_to_exp2(ir_expression *ir) +{ + ir_constant *log2_e = new(ir) ir_constant(float(M_LOG2E)); + + ir->operation = ir_unop_exp2; + ir->operands[0] = new(ir) ir_expression(ir_binop_mul, ir->operands[0]->type, + ir->operands[0], log2_e); + this->progress = true; +} + +void +lower_instructions_visitor::pow_to_exp2(ir_expression *ir) +{ + ir_expression *const log2_x = + new(ir) ir_expression(ir_unop_log2, ir->operands[0]->type, + ir->operands[0]); + + ir->operation = ir_unop_exp2; + ir->operands[0] = new(ir) ir_expression(ir_binop_mul, ir->operands[1]->type, + ir->operands[1], log2_x); + ir->operands[1] = NULL; + this->progress = true; +} + +void +lower_instructions_visitor::log_to_log2(ir_expression *ir) +{ + ir->operation = ir_binop_mul; + ir->operands[0] = new(ir) ir_expression(ir_unop_log2, ir->operands[0]->type, + ir->operands[0], NULL); + ir->operands[1] = new(ir) ir_constant(float(1.0 / M_LOG2E)); + this->progress = true; +} + +void +lower_instructions_visitor::mod_to_fract(ir_expression *ir) +{ + ir_variable *temp = new(ir) ir_variable(ir->operands[1]->type, "mod_b", + ir_var_temporary); + this->base_ir->insert_before(temp); + + ir_assignment *const assign = + new(ir) ir_assignment(new(ir) ir_dereference_variable(temp), + ir->operands[1], NULL); + + this->base_ir->insert_before(assign); + + ir_expression *const div_expr = + new(ir) ir_expression(ir_binop_div, ir->operands[0]->type, + ir->operands[0], + new(ir) ir_dereference_variable(temp)); + + /* Don't generate new IR that would need to be lowered in an additional + * pass. + */ + if (lowering(DIV_TO_MUL_RCP)) + div_to_mul_rcp(div_expr); + + ir_rvalue *expr = new(ir) ir_expression(ir_unop_fract, + ir->operands[0]->type, + div_expr, + NULL); + + ir->operation = ir_binop_mul; + ir->operands[0] = new(ir) ir_dereference_variable(temp); + ir->operands[1] = expr; + this->progress = true; +} + +ir_visitor_status +lower_instructions_visitor::visit_leave(ir_expression *ir) +{ + switch (ir->operation) { + case ir_binop_sub: + if (lowering(SUB_TO_ADD_NEG)) + sub_to_add_neg(ir); + break; + + case ir_binop_div: + if (lowering(DIV_TO_MUL_RCP)) + div_to_mul_rcp(ir); + break; + + case ir_unop_exp: + if (lowering(EXP_TO_EXP2)) + exp_to_exp2(ir); + break; + + case ir_unop_log: + if (lowering(LOG_TO_LOG2)) + log_to_log2(ir); + break; + + case ir_binop_mod: + if (lowering(MOD_TO_FRACT) && ir->type->is_float()) + mod_to_fract(ir); + break; + + case ir_binop_pow: + if (lowering(POW_TO_EXP2)) + pow_to_exp2(ir); + break; + + default: + return visit_continue; + } + + return visit_continue; +} diff --git a/mesalib/src/glsl/lower_mat_op_to_vec.cpp b/mesalib/src/glsl/lower_mat_op_to_vec.cpp index 8cbbfa713..a371afc14 100644 --- a/mesalib/src/glsl/lower_mat_op_to_vec.cpp +++ b/mesalib/src/glsl/lower_mat_op_to_vec.cpp @@ -45,19 +45,19 @@ public: ir_visitor_status visit_leave(ir_assignment *); - ir_dereference *get_column(ir_variable *var, int col); - ir_rvalue *get_element(ir_variable *var, int col, int row); - - void do_mul_mat_mat(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_mat_vec(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_vec_mat(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_mat_scalar(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_equal_mat_mat(ir_variable *result_var, ir_variable *a_var, - ir_variable *b_var, bool test_equal); + ir_dereference *get_column(ir_dereference *val, int col); + ir_rvalue *get_element(ir_dereference *val, int col, int row); + + void do_mul_mat_mat(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_mat_vec(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_vec_mat(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_mat_scalar(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_equal_mat_mat(ir_dereference *result, ir_dereference *a, + ir_dereference *b, bool test_equal); void *mem_ctx; bool made_progress; @@ -97,182 +97,137 @@ do_mat_op_to_vec(exec_list *instructions) } ir_rvalue * -ir_mat_op_to_vec_visitor::get_element(ir_variable *var, int col, int row) +ir_mat_op_to_vec_visitor::get_element(ir_dereference *val, int col, int row) { - ir_dereference *deref; + val = get_column(val, col); - deref = new(mem_ctx) ir_dereference_variable(var); - - if (var->type->is_matrix()) { - deref = new(mem_ctx) ir_dereference_array(var, - new(mem_ctx) ir_constant(col)); - } else { - assert(col == 0); - } - - return new(mem_ctx) ir_swizzle(deref, row, 0, 0, 0, 1); + return new(mem_ctx) ir_swizzle(val, row, 0, 0, 0, 1); } ir_dereference * -ir_mat_op_to_vec_visitor::get_column(ir_variable *var, int row) +ir_mat_op_to_vec_visitor::get_column(ir_dereference *val, int row) { - ir_dereference *deref; - - if (!var->type->is_matrix()) { - deref = new(mem_ctx) ir_dereference_variable(var); - } else { - deref = new(mem_ctx) ir_dereference_variable(var); - deref = new(mem_ctx) ir_dereference_array(deref, - new(mem_ctx) ir_constant(row)); + val = val->clone(mem_ctx, NULL); + + if (val->type->is_matrix()) { + val = new(mem_ctx) ir_dereference_array(val, + new(mem_ctx) ir_constant(row)); } - return deref; + return val; } void -ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) +ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int b_col, i; ir_assignment *assign; ir_expression *expr; - for (b_col = 0; b_col < b_var->type->matrix_columns; b_col++) { - ir_rvalue *a = get_column(a_var, 0); - ir_rvalue *b = get_element(b_var, b_col, 0); - + for (b_col = 0; b_col < b->type->matrix_columns; b_col++) { /* first column */ expr = new(mem_ctx) ir_expression(ir_binop_mul, - a->type, - a, - b); + get_column(a, 0), + get_element(b, b_col, 0)); /* following columns */ - for (i = 1; i < a_var->type->matrix_columns; i++) { + for (i = 1; i < a->type->matrix_columns; i++) { ir_expression *mul_expr; - a = get_column(a_var, i); - b = get_element(b_var, b_col, i); - mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - a->type, - a, - b); + get_column(a, i), + get_element(b, b_col, i)); expr = new(mem_ctx) ir_expression(ir_binop_add, - a->type, expr, mul_expr); } - ir_rvalue *result = get_column(result_var, b_col); - assign = new(mem_ctx) ir_assignment(result, - expr, - NULL); + assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr); base_ir->insert_before(assign); } } void -ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) +ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; - ir_rvalue *a = get_column(a_var, 0); - ir_rvalue *b = get_element(b_var, 0, 0); ir_assignment *assign; ir_expression *expr; /* first column */ expr = new(mem_ctx) ir_expression(ir_binop_mul, - result_var->type, - a, - b); + get_column(a, 0), + get_element(b, 0, 0)); /* following columns */ - for (i = 1; i < a_var->type->matrix_columns; i++) { + for (i = 1; i < a->type->matrix_columns; i++) { ir_expression *mul_expr; - a = get_column(a_var, i); - b = get_element(b_var, 0, i); - mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - result_var->type, - a, - b); - expr = new(mem_ctx) ir_expression(ir_binop_add, - result_var->type, - expr, - mul_expr); + get_column(a, i), + get_element(b, 0, i)); + expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); } - ir_rvalue *result = new(mem_ctx) ir_dereference_variable(result_var); - assign = new(mem_ctx) ir_assignment(result, - expr, - NULL); + result = result->clone(mem_ctx, NULL); + assign = new(mem_ctx) ir_assignment(result, expr); base_ir->insert_before(assign); } void -ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) +ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; - for (i = 0; i < b_var->type->matrix_columns; i++) { - ir_rvalue *a = new(mem_ctx) ir_dereference_variable(a_var); - ir_rvalue *b = get_column(b_var, i); - ir_rvalue *result; + for (i = 0; i < b->type->matrix_columns; i++) { + ir_rvalue *column_result; ir_expression *column_expr; ir_assignment *column_assign; - result = new(mem_ctx) ir_dereference_variable(result_var); - result = new(mem_ctx) ir_swizzle(result, i, 0, 0, 0, 1); + column_result = result->clone(mem_ctx, NULL); + column_result = new(mem_ctx) ir_swizzle(column_result, i, 0, 0, 0, 1); column_expr = new(mem_ctx) ir_expression(ir_binop_dot, - result->type, - a, - b); + a->clone(mem_ctx, NULL), + get_column(b, i)); - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL); + column_assign = new(mem_ctx) ir_assignment(column_result, + column_expr); base_ir->insert_before(column_assign); } } void -ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) +ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; - for (i = 0; i < a_var->type->matrix_columns; i++) { - ir_rvalue *a = get_column(a_var, i); - ir_rvalue *b = new(mem_ctx) ir_dereference_variable(b_var); - ir_rvalue *result = get_column(result_var, i); + for (i = 0; i < a->type->matrix_columns; i++) { ir_expression *column_expr; ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(ir_binop_mul, - result->type, - a, - b); + get_column(a, i), + b->clone(mem_ctx, NULL)); - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL); + column_assign = new(mem_ctx) ir_assignment(get_column(result, i), + column_expr); base_ir->insert_before(column_assign); } } void -ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var, +ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b, bool test_equal) { /* This essentially implements the following GLSL: @@ -293,7 +248,7 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, * a[3] != b[3]); * } */ - const unsigned columns = a_var->type->matrix_columns; + const unsigned columns = a->type->matrix_columns; const glsl_type *const bvec_type = glsl_type::get_instance(GLSL_TYPE_BOOL, columns, 1); @@ -303,12 +258,10 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, this->base_ir->insert_before(tmp_bvec); for (unsigned i = 0; i < columns; i++) { - ir_dereference *const op0 = get_column(a_var, i); - ir_dereference *const op1 = get_column(b_var, i); - ir_expression *const cmp = new(this->mem_ctx) ir_expression(ir_binop_any_nequal, - glsl_type::bool_type, op0, op1); + get_column(a, i), + get_column(b, i)); ir_dereference *const lhs = new(this->mem_ctx) ir_dereference_variable(tmp_bvec); @@ -319,23 +272,14 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, this->base_ir->insert_before(assign); } - ir_rvalue *const val = - new(this->mem_ctx) ir_dereference_variable(tmp_bvec); - - ir_expression *any = - new(this->mem_ctx) ir_expression(ir_unop_any, glsl_type::bool_type, - val, NULL); + ir_rvalue *const val = new(this->mem_ctx) ir_dereference_variable(tmp_bvec); + ir_expression *any = new(this->mem_ctx) ir_expression(ir_unop_any, val); if (test_equal) - any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, - glsl_type::bool_type, - any, NULL); - - ir_rvalue *const result = - new(this->mem_ctx) ir_dereference_variable(result_var); + any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any); ir_assignment *const assign = - new(mem_ctx) ir_assignment(result, any, NULL); + new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any); base_ir->insert_before(assign); } @@ -358,7 +302,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) { ir_expression *orig_expr = orig_assign->rhs->as_expression(); unsigned int i, matrix_columns = 1; - ir_variable *op_var[2]; + ir_dereference *op[2]; if (!orig_expr) return visit_continue; @@ -370,51 +314,53 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) mem_ctx = ralloc_parent(orig_assign); - ir_dereference_variable *lhs_deref = + ir_dereference_variable *result = orig_assign->lhs->as_dereference_variable(); - assert(lhs_deref); - - ir_variable *result_var = lhs_deref->var; + assert(result); /* Store the expression operands in temps so we can use them * multiple times. */ for (i = 0; i < orig_expr->get_num_operands(); i++) { ir_assignment *assign; + ir_dereference *deref = orig_expr->operands[i]->as_dereference(); - op_var[i] = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, - "mat_op_to_vec", - ir_var_temporary); - base_ir->insert_before(op_var[i]); + /* Avoid making a temporary if we don't need to to avoid aliasing. */ + if (deref && + deref->variable_referenced() != result->variable_referenced()) { + op[i] = deref; + continue; + } - lhs_deref = new(mem_ctx) ir_dereference_variable(op_var[i]); - assign = new(mem_ctx) ir_assignment(lhs_deref, - orig_expr->operands[i], - NULL); + /* Otherwise, store the operand in a temporary generally if it's + * not a dereference. + */ + ir_variable *var = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, + "mat_op_to_vec", + ir_var_temporary); + base_ir->insert_before(var); + + /* Note that we use this dereference for the assignment. That means + * that others that want to use op[i] have to clone the deref. + */ + op[i] = new(mem_ctx) ir_dereference_variable(var); + assign = new(mem_ctx) ir_assignment(op[i], orig_expr->operands[i]); base_ir->insert_before(assign); } /* OK, time to break down this matrix operation. */ switch (orig_expr->operation) { case ir_unop_neg: { - const unsigned mask = (1U << result_var->type->vector_elements) - 1; - /* Apply the operation to each column.*/ for (i = 0; i < matrix_columns; i++) { - ir_rvalue *op0 = get_column(op_var[0], i); - ir_dereference *result = get_column(result_var, i); ir_expression *column_expr; ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - result->type, - op0, - NULL); - - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL, - mask); + get_column(op[0], i)); + + column_assign = new(mem_ctx) ir_assignment(get_column(result, i), + column_expr); assert(column_assign->write_mask != 0); base_ir->insert_before(column_assign); } @@ -424,57 +370,49 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) case ir_binop_sub: case ir_binop_div: case ir_binop_mod: { - const unsigned mask = (1U << result_var->type->vector_elements) - 1; - /* For most operations, the matrix version is just going * column-wise through and applying the operation to each column * if available. */ for (i = 0; i < matrix_columns; i++) { - ir_rvalue *op0 = get_column(op_var[0], i); - ir_rvalue *op1 = get_column(op_var[1], i); - ir_dereference *result = get_column(result_var, i); ir_expression *column_expr; ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - result->type, - op0, - op1); - - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL, - mask); + get_column(op[0], i), + get_column(op[1], i)); + + column_assign = new(mem_ctx) ir_assignment(get_column(result, i), + column_expr); assert(column_assign->write_mask != 0); base_ir->insert_before(column_assign); } break; } case ir_binop_mul: - if (op_var[0]->type->is_matrix()) { - if (op_var[1]->type->is_matrix()) { - do_mul_mat_mat(result_var, op_var[0], op_var[1]); - } else if (op_var[1]->type->is_vector()) { - do_mul_mat_vec(result_var, op_var[0], op_var[1]); + if (op[0]->type->is_matrix()) { + if (op[1]->type->is_matrix()) { + do_mul_mat_mat(result, op[0], op[1]); + } else if (op[1]->type->is_vector()) { + do_mul_mat_vec(result, op[0], op[1]); } else { - assert(op_var[1]->type->is_scalar()); - do_mul_mat_scalar(result_var, op_var[0], op_var[1]); + assert(op[1]->type->is_scalar()); + do_mul_mat_scalar(result, op[0], op[1]); } } else { - assert(op_var[1]->type->is_matrix()); - if (op_var[0]->type->is_vector()) { - do_mul_vec_mat(result_var, op_var[0], op_var[1]); + assert(op[1]->type->is_matrix()); + if (op[0]->type->is_vector()) { + do_mul_vec_mat(result, op[0], op[1]); } else { - assert(op_var[0]->type->is_scalar()); - do_mul_mat_scalar(result_var, op_var[1], op_var[0]); + assert(op[0]->type->is_scalar()); + do_mul_mat_scalar(result, op[1], op[0]); } } break; case ir_binop_all_equal: case ir_binop_any_nequal: - do_equal_mat_mat(result_var, op_var[1], op_var[0], + do_equal_mat_mat(result, op[1], op[0], (orig_expr->operation == ir_binop_all_equal)); break; diff --git a/mesalib/src/mesa/main/version.h b/mesalib/src/mesa/main/version.h index ffe21fea5..0a0512c33 100644 --- a/mesalib/src/mesa/main/version.h +++ b/mesalib/src/mesa/main/version.h @@ -1,60 +1,60 @@ -/*
- * Mesa 3-D graphics library
- * Version: 7.11
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef VERSION_H
-#define VERSION_H
-
-
-struct gl_context;
-
-
-/* Mesa version */
-#define MESA_MAJOR 7
-#define MESA_MINOR 11
-#define MESA_PATCH 0
-#define MESA_VERSION_STRING "7.11-devel"
-
-/* To make version comparison easy */
-#define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#define MESA_VERSION_CODE MESA_VERSION(MESA_MAJOR, MESA_MINOR, MESA_PATCH)
-
-
-/* OpenGL API version */
-#define OPENGL_MAJOR 2
-#define OPENGL_MINOR 1
-#define OPENGL_PATCH 0
-#define OPENGL_VERSION_STRING "2.1"
-
-/* To make version comparison easy */
-#define OPENGL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#define OPENGL_VERSION_CODE OPENGL_VERSION(OPENGL_MAJOR, OPENGL_MINOR, OPENGL_PATCH)
-
-
-extern void
-_mesa_compute_version(struct gl_context *ctx);
-
-
-#endif /* VERSION_H */
+/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef VERSION_H +#define VERSION_H + + +struct gl_context; + + +/* Mesa version */ +#define MESA_MAJOR 7 +#define MESA_MINOR 12 +#define MESA_PATCH 0 +#define MESA_VERSION_STRING "7.12-devel" + +/* To make version comparison easy */ +#define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#define MESA_VERSION_CODE MESA_VERSION(MESA_MAJOR, MESA_MINOR, MESA_PATCH) + + +/* OpenGL API version */ +#define OPENGL_MAJOR 2 +#define OPENGL_MINOR 1 +#define OPENGL_PATCH 0 +#define OPENGL_VERSION_STRING "2.1" + +/* To make version comparison easy */ +#define OPENGL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#define OPENGL_VERSION_CODE OPENGL_VERSION(OPENGL_MAJOR, OPENGL_MINOR, OPENGL_PATCH) + + +extern void +_mesa_compute_version(struct gl_context *ctx); + + +#endif /* VERSION_H */ diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 00869979d..67adb8f3d 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -1296,8 +1296,11 @@ ir_to_mesa_visitor::visit(ir_expression *ir) emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]); break; case ir_unop_i2f: + case ir_unop_u2f: case ir_unop_b2f: case ir_unop_b2i: + case ir_unop_i2u: + case ir_unop_u2i: /* Mesa IR lacks types, ints are stored as truncated floats. */ result_src = op[0]; break; @@ -1335,7 +1338,6 @@ ir_to_mesa_visitor::visit(ir_expression *ir) break; case ir_unop_bit_not: - case ir_unop_u2f: case ir_binop_lshift: case ir_binop_rshift: case ir_binop_bit_and: diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index c730975df..d61d7ac22 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -1400,14 +1400,14 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, /* srcFormat can't be used as a texture format */ if (type == GL_DEPTH) { texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT, - st->internal_target, GL_NONE, GL_NONE, + GL_NONE, GL_NONE, st->internal_target, sample_count, PIPE_BIND_DEPTH_STENCIL); assert(texFormat != PIPE_FORMAT_NONE); } else { /* default color format */ texFormat = st_choose_format(screen, GL_RGBA, - st->internal_target, GL_NONE, GL_NONE, + GL_NONE, GL_NONE, st->internal_target, sample_count, PIPE_BIND_SAMPLER_VIEW); assert(texFormat != PIPE_FORMAT_NONE); } diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index d52e27351..6907cfc03 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -842,7 +842,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level, else { /* format translation via floats */ GLuint row; - enum pipe_format format = util_format_linear(dst_texture->format); + enum pipe_format pformat = util_format_linear(dst_texture->format); for (row = 0; row < height; row++) { const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ GLfloat rgba[4 * MAX_WIDTH]; @@ -854,7 +854,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level, /* get float[4] rgba row from surface */ pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1, - format, rgba); + pformat, rgba); _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, type, dest, &ctx->Pack, transferOps); diff --git a/mesalib/src/mesa/state_tracker/st_cb_viewport.c b/mesalib/src/mesa/state_tracker/st_cb_viewport.c index a61e3d4d4..d4742eb89 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_viewport.c +++ b/mesalib/src/mesa/state_tracker/st_cb_viewport.c @@ -1,71 +1,78 @@ -/**************************************************************************
- *
- * Copyright 2009 VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "main/glheader.h"
-#include "st_context.h"
-#include "st_cb_viewport.h"
-
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_atomic.h"
-
-/**
- * Cast wrapper to convert a struct gl_framebuffer to an st_framebuffer.
- * Return NULL if the struct gl_framebuffer is a user-created framebuffer.
- * We'll only return non-null for window system framebuffers.
- * Note that this function may fail.
- */
-static INLINE struct st_framebuffer *
-st_ws_framebuffer(struct gl_framebuffer *fb)
-{
- /* FBO cannot be casted. See st_new_framebuffer */
- return (struct st_framebuffer *) ((fb && !fb->Name) ? fb : NULL);
-}
-
-static void st_viewport(struct gl_context * ctx, GLint x, GLint y,
- GLsizei width, GLsizei height)
-{
- struct st_context *st = ctx->st;
- struct st_framebuffer *stdraw;
- struct st_framebuffer *stread;
-
- if (!st->invalidate_on_gl_viewport)
- return;
-
- stdraw = st_ws_framebuffer(st->ctx->DrawBuffer);
- stread = st_ws_framebuffer(st->ctx->ReadBuffer);
-
- if (stdraw)
- p_atomic_set(&stdraw->revalidate, TRUE);
- if (stread && stread != stdraw)
- p_atomic_set(&stread->revalidate, TRUE);
-}
-
-void st_init_viewport_functions(struct dd_function_table *functions)
-{
- functions->Viewport = st_viewport;
-}
+/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "main/glheader.h" +#include "st_context.h" +#include "st_cb_viewport.h" + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_atomic.h" + +/** + * Cast wrapper to convert a struct gl_framebuffer to an st_framebuffer. + * Return NULL if the struct gl_framebuffer is a user-created framebuffer. + * We'll only return non-null for window system framebuffers. + * Note that this function may fail. + */ +static INLINE struct st_framebuffer * +st_ws_framebuffer(struct gl_framebuffer *fb) +{ + /* FBO cannot be casted. See st_new_framebuffer */ + return (struct st_framebuffer *) ((fb && !fb->Name) ? fb : NULL); +} + +static void st_viewport(struct gl_context * ctx, GLint x, GLint y, + GLsizei width, GLsizei height) +{ + struct st_context *st = ctx->st; + struct st_framebuffer *stdraw; + struct st_framebuffer *stread; + + if (!st->invalidate_on_gl_viewport) + return; + + /* + * Normally we'd want the state tracker manager to mark the drawables + * invalid only when needed. This will force the state tracker manager + * to revalidate the drawable, rather than just update the context with + * the latest cached drawable info. + */ + + stdraw = st_ws_framebuffer(st->ctx->DrawBuffer); + stread = st_ws_framebuffer(st->ctx->ReadBuffer); + + if (stdraw && stdraw->iface) + stdraw->iface_stamp = p_atomic_read(&stdraw->iface->stamp) - 1; + if (stread && stread != stdraw && stread->iface) + stread->iface_stamp = p_atomic_read(&stread->iface->stamp) - 1; +} + +void st_init_viewport_functions(struct dd_function_table *functions) +{ + functions->Viewport = st_viewport; +} diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index ff207039d..0a3220221 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -204,6 +204,9 @@ struct st_context /* Active render condition. */ struct pipe_query *render_condition; unsigned condition_mode; + + int32_t draw_stamp; + int32_t read_stamp; }; @@ -227,7 +230,8 @@ struct st_framebuffer struct st_framebuffer_iface *iface; enum st_attachment_type statts[ST_ATTACHMENT_COUNT]; unsigned num_statts; - int32_t revalidate; + int32_t stamp; + int32_t iface_stamp; }; diff --git a/mesalib/src/mesa/state_tracker/st_format.h b/mesalib/src/mesa/state_tracker/st_format.h index 7bda785af..1c1f5965f 100644 --- a/mesalib/src/mesa/state_tracker/st_format.h +++ b/mesalib/src/mesa/state_tracker/st_format.h @@ -54,7 +54,7 @@ extern enum pipe_format st_choose_format(struct pipe_screen *screen, GLenum internalFormat, GLenum format, GLenum type, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage); + unsigned bindings); extern enum pipe_format st_choose_renderbuffer_format(struct pipe_screen *screen, diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index c95514cbe..a8c4b5c3f 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -139,23 +139,64 @@ buffer_index_to_attachment(gl_buffer_index index) } /** + * Make sure a context picks up the latest cached state of the + * drawables it binds to. + */ +static void +st_context_validate(struct st_context *st, + struct st_framebuffer *stdraw, + struct st_framebuffer *stread) +{ + if (stdraw && stdraw->stamp != st->draw_stamp) { + st->dirty.st |= ST_NEW_FRAMEBUFFER; + _mesa_resize_framebuffer(st->ctx, &stdraw->Base, + stdraw->Base.Width, + stdraw->Base.Height); + st->draw_stamp = stdraw->stamp; + } + + if (stread && stread->stamp != st->read_stamp) { + if (stread != stdraw) { + st->dirty.st |= ST_NEW_FRAMEBUFFER; + _mesa_resize_framebuffer(st->ctx, &stread->Base, + stread->Base.Width, + stread->Base.Height); + } + st->read_stamp = stread->stamp; + } +} + +/** * Validate a framebuffer to make sure up-to-date pipe_textures are used. + * The context we need to pass in is s dummy context needed only to be + * able to get a pipe context to create pipe surfaces, and to have a + * context to call _mesa_resize_framebuffer(): + * (That should probably be rethought, since those surfaces become + * drawable state, not context state, and can be freed by another pipe + * context). */ static void -st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st) +st_framebuffer_validate(struct st_framebuffer *stfb, + struct st_context *st) { - struct pipe_context *pipe = st->pipe; struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; uint width, height; unsigned i; boolean changed = FALSE; + int32_t new_stamp = p_atomic_read(&stfb->iface->stamp); - if (!p_atomic_read(&stfb->revalidate)) + if (stfb->iface_stamp == new_stamp) return; /* validate the fb */ - if (!stfb->iface->validate(stfb->iface, stfb->statts, stfb->num_statts, textures)) - return; + do { + if (!stfb->iface->validate(stfb->iface, stfb->statts, + stfb->num_statts, textures)) + return; + + stfb->iface_stamp = new_stamp; + new_stamp = p_atomic_read(&stfb->iface->stamp); + } while(stfb->iface_stamp != new_stamp); width = stfb->Base.Width; height = stfb->Base.Height; @@ -184,7 +225,7 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st) memset(&surf_tmpl, 0, sizeof(surf_tmpl)); u_surface_default_template(&surf_tmpl, textures[i], PIPE_BIND_RENDER_TARGET); - ps = pipe->create_surface(pipe, textures[i], &surf_tmpl); + ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl); if (ps) { pipe_surface_reference(&strb->surface, ps); pipe_resource_reference(&strb->texture, ps->texture); @@ -204,14 +245,9 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st) } if (changed) { - st->dirty.st |= ST_NEW_FRAMEBUFFER; + ++stfb->stamp; _mesa_resize_framebuffer(st->ctx, &stfb->Base, width, height); - - assert(stfb->Base.Width == width); - assert(stfb->Base.Height == height); } - - p_atomic_set(&stfb->revalidate, FALSE); } /** @@ -236,8 +272,7 @@ st_framebuffer_update_attachments(struct st_framebuffer *stfb) st_visual_have_buffers(stfb->iface->visual, 1 << statt)) stfb->statts[stfb->num_statts++] = statt; } - - p_atomic_set(&stfb->revalidate, TRUE); + stfb->stamp++; } /** @@ -443,6 +478,7 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi) &stfb->Base._ColorReadBufferIndex); stfb->iface = stfbi; + stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1; /* add the color buffer */ idx = stfb->Base._ColorDrawBufferIndexes[0]; @@ -454,6 +490,7 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi) st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH); st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM); + stfb->stamp = 0; st_framebuffer_update_attachments(stfb); stfb->Base.Initialized = GL_TRUE; @@ -473,31 +510,6 @@ st_framebuffer_reference(struct st_framebuffer **ptr, } static void -st_context_notify_invalid_framebuffer(struct st_context_iface *stctxi, - struct st_framebuffer_iface *stfbi) -{ - struct st_context *st = (struct st_context *) stctxi; - struct st_framebuffer *stfb; - - /* either draw or read winsys fb */ - stfb = st_ws_framebuffer(st->ctx->WinSysDrawBuffer); - if (!stfb || stfb->iface != stfbi) - stfb = st_ws_framebuffer(st->ctx->WinSysReadBuffer); - - if (stfb && stfb->iface == stfbi) { - p_atomic_set(&stfb->revalidate, TRUE); - } - else { - /* This function is probably getting called when we've detected a - * change in a window's size but the currently bound context is - * not bound to that window. - * If the st_framebuffer_iface structure had a pointer to the - * corresponding st_framebuffer we'd be able to handle this. - */ - } -} - -static void st_context_flush(struct st_context_iface *stctxi, unsigned flags, struct pipe_fence_handle **fence) { @@ -696,8 +708,6 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE); st->iface.destroy = st_context_destroy; - st->iface.notify_invalid_framebuffer = - st_context_notify_invalid_framebuffer; st->iface.flush = st_context_flush; st->iface.teximage = st_context_teximage; st->iface.copy = st_context_copy; @@ -762,10 +772,6 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, } if (stdraw && stread) { - if (stctxi != st_api_get_current(stapi)) { - p_atomic_set(&stdraw->revalidate, TRUE); - p_atomic_set(&stread->revalidate, TRUE); - } st_framebuffer_validate(stdraw, st); if (stread != stdraw) st_framebuffer_validate(stread, st); @@ -781,6 +787,10 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, } ret = _mesa_make_current(st->ctx, &stdraw->Base, &stread->Base); + + st->draw_stamp = stdraw->stamp - 1; + st->read_stamp = stread->stamp - 1; + st_context_validate(st, stdraw, stread); } else { struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer(); @@ -872,6 +882,8 @@ st_manager_validate_framebuffers(struct st_context *st) st_framebuffer_validate(stdraw, st); if (stread && stread != stdraw) st_framebuffer_validate(stread, st); + + st_context_validate(st, stdraw, stread); } /** diff --git a/mkfontscale/configure.ac b/mkfontscale/configure.ac index b7f72aa5d..f001e0937 100644 --- a/mkfontscale/configure.ac +++ b/mkfontscale/configure.ac @@ -22,7 +22,7 @@ dnl Process this file with autoconf to create configure. # Initialize Autoconf AC_PREREQ([2.60]) -AC_INIT([mkfontscale], [1.0.8], +AC_INIT([mkfontscale], [1.0.9], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [mkfontscale]) AC_CONFIG_SRCDIR([Makefile.am]) diff --git a/xorg-server/Xext/xvmc.c b/xorg-server/Xext/xvmc.c index 4d29941ee..bc78b55ae 100644 --- a/xorg-server/Xext/xvmc.c +++ b/xorg-server/Xext/xvmc.c @@ -487,8 +487,8 @@ ProcXvMCListSubpictureTypes(ClientPtr client) pScreen = pPort->pAdaptor->pScreen; - if(XvMCScreenKey == NULL) /* No XvMC adaptors */ - return BadMatch; + if (!dixPrivateKeyRegistered(XvMCScreenKey)) + return BadMatch; /* No XvMC adaptors */ if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) return BadMatch; /* None this screen */ @@ -668,8 +668,8 @@ XvMCExtensionInit(void) { ExtensionEntry *extEntry; - if(XvMCScreenKey == NULL) /* nobody supports it */ - return; + if (!dixPrivateKeyRegistered(XvMCScreenKey)) + return; if(!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes, "XvMCRTContext"))) @@ -746,7 +746,8 @@ XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id) XvMCAdaptorPtr adaptor = NULL; int i; - if(XvMCScreenKey == NULL) return NULL; + if (!dixPrivateKeyRegistered(XvMCScreenKey)) + return NULL; if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) return NULL; diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index a53ab5038..4656a83fb 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -774,18 +774,18 @@ RECORDPROTO="recordproto >= 1.13.99.1" SCRNSAVERPROTO="scrnsaverproto >= 1.1" RESOURCEPROTO="resourceproto" DRIPROTO="xf86driproto >= 2.1.0" -DRI2PROTO="dri2proto >= 2.3" +DRI2PROTO="dri2proto >= 2.6" XINERAMAPROTO="xineramaproto" BIGFONTPROTO="xf86bigfontproto >= 1.2.0" DGAPROTO="xf86dgaproto >= 2.0.99.1" -GLPROTO="glproto >= 1.4.10" +GLPROTO="glproto >= 1.4.14" DMXPROTO="dmxproto >= 2.2.99.1" VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1" WINDOWSWMPROTO="windowswmproto" APPLEWMPROTO="applewmproto >= 1.4" dnl Core modules for most extensions, et al. -SDK_REQUIRED_MODULES="[xproto >= 7.0.17] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto" +SDK_REQUIRED_MODULES="[xproto >= 7.0.22] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto" # Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc AC_SUBST(SDK_REQUIRED_MODULES) @@ -1735,14 +1735,6 @@ if test "x$XORG" = xyes; then AC_SUBST([XORG_INCS]) AC_SUBST([XORG_OS]) AC_SUBST([XORG_OS_SUBDIR]) - - AC_PATH_PROG(PERL, perl, no) - dnl unlikely as this may be ... - if test "x$PERL" = xno; then - AC_MSG_ERROR([Perl is required to build the XFree86/Xorg DDX.]) - fi - AC_SUBST(PERL) - AC_SUBST([XORG_CFLAGS]) dnl these only go in xorg-config.h @@ -1889,8 +1881,8 @@ if test "x$XQUARTZ" = xyes; then AC_DEFINE(XQUARTZ,1,[Have Quartz]) AC_DEFINE(ROOTLESS,1,[Build Rootless code]) - DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB" - AC_SUBST([DARWIN_LIBS]) + XQUARTZ_LIBS="$MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB" + AC_SUBST([XQUARTZ_LIBS]) AC_CHECK_LIB([Xplugin],[xp_init],[:]) @@ -2144,7 +2136,7 @@ AC_SUBST([libdir]) AC_SUBST([exec_prefix]) AC_SUBST([prefix]) -AC_CONFIG_COMMANDS([sdksyms], [touch hw/xfree86/loader/sdksyms.dep]) +AC_CONFIG_COMMANDS([sdksyms], [touch hw/xfree86/sdksyms.dep]) AC_OUTPUT([ Makefile diff --git a/xorg-server/dix/Makefile.am b/xorg-server/dix/Makefile.am index 543554669..f5af619e3 100644 --- a/xorg-server/dix/Makefile.am +++ b/xorg-server/dix/Makefile.am @@ -64,11 +64,9 @@ dtrace-dix.o: $(top_srcdir)/dix/Xserver.d $(am_libdix_la_OBJECTS) noinst_PROGRAMS = dix.O +dix_O_SOURCES = dix.O: dtrace-dix.o $(am_libdix_la_OBJECTS) $(AM_V_GEN)ld -r -o $@ $(am_libdix_la_OBJECTS:%.lo=.libs/%.o) endif -dix.c: - touch $@ - -CLEANFILES = dix.c Xserver-dtrace.h +CLEANFILES = Xserver-dtrace.h diff --git a/xorg-server/fb/fb24_32.c b/xorg-server/fb/fb24_32.c index 748a0ec04..033fa46c5 100644 --- a/xorg-server/fb/fb24_32.c +++ b/xorg-server/fb/fb24_32.c @@ -1,635 +1,635 @@ -/*
- * Copyright © 2000 SuSE, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. SuSE makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Keith Packard, SuSE, Inc.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include "fb.h"
-
-/* X apps don't like 24bpp images, this code exposes 32bpp images */
-
-/*
- * These two functions do a full CopyArea while reformatting
- * the data between 24 and 32bpp. They try to go a bit faster
- * by reading/writing aligned CARD32s where it's easy
- */
-
-#define Get8(a) ((CARD32) READ(a))
-
-#if BITMAP_BIT_ORDER == MSBFirst
-#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2))
-#define Put24(a,p) ((WRITE((a+0), (CARD8) ((p) >> 16))), \
- (WRITE((a+1), (CARD8) ((p) >> 8))), \
- (WRITE((a+2), (CARD8) (p))))
-#else
-#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16))
-#define Put24(a,p) ((WRITE((a+0), (CARD8) (p))), \
- (WRITE((a+1), (CARD8) ((p) >> 8))), \
- (WRITE((a+2), (CARD8) ((p) >> 16))))
-#endif
-
-typedef void (*fb24_32BltFunc) (CARD8 *srcLine,
- FbStride srcStride,
- int srcX,
-
- CARD8 *dstLine,
- FbStride dstStride,
- int dstX,
-
- int width,
- int height,
-
- int alu,
- FbBits pm);
-
-static void
-fb24_32BltDown (CARD8 *srcLine,
- FbStride srcStride,
- int srcX,
-
- CARD8 *dstLine,
- FbStride dstStride,
- int dstX,
-
- int width,
- int height,
-
- int alu,
- FbBits pm)
-{
- CARD32 *src;
- CARD8 *dst;
- int w;
- Bool destInvarient;
- CARD32 pixel, dpixel;
- FbDeclareMergeRop ();
-
- srcLine += srcX * 4;
- dstLine += dstX * 3;
-
- FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff));
- destInvarient = FbDestInvarientMergeRop();
-
- while (height--)
- {
- src = (CARD32 *) srcLine;
- dst = dstLine;
- srcLine += srcStride;
- dstLine += dstStride;
- w = width;
- if (destInvarient)
- {
- while (((long) dst & 3) && w)
- {
- w--;
- pixel = READ(src++);
- pixel = FbDoDestInvarientMergeRop(pixel);
- Put24 (dst, pixel);
- dst += 3;
- }
- /* Do four aligned pixels at a time */
- while (w >= 4)
- {
- CARD32 s0, s1;
- s0 = READ(src++);
- s0 = FbDoDestInvarientMergeRop(s0);
- s1 = READ(src++);
- s1 = FbDoDestInvarientMergeRop(s1);
-#if BITMAP_BIT_ORDER == LSBFirst
- WRITE((CARD32 *)dst, (s0 & 0xffffff) | (s1 << 24));
-#else
- WRITE((CARD32 *)dst, (s0 << 8) | ((s1 & 0xffffff) >> 16));
-#endif
- s0 = READ(src++);
- s0 = FbDoDestInvarientMergeRop(s0);
-#if BITMAP_BIT_ORDER == LSBFirst
- WRITE((CARD32 *)(dst+4), ((s1 & 0xffffff) >> 8) | (s0 << 16));
-#else
- WRITE((CARD32 *)(dst+4), (s1 << 16) | ((s0 & 0xffffff) >> 8));
-#endif
- s1 = READ(src++);
- s1 = FbDoDestInvarientMergeRop(s1);
-#if BITMAP_BIT_ORDER == LSBFirst
- WRITE((CARD32 *)(dst+8), ((s0 & 0xffffff) >> 16) | (s1 << 8));
-#else
- WRITE((CARD32 *)(dst+8), (s0 << 24) | (s1 & 0xffffff));
-#endif
- dst += 12;
- w -= 4;
- }
- while (w--)
- {
- pixel = READ(src++);
- pixel = FbDoDestInvarientMergeRop(pixel);
- Put24 (dst, pixel);
- dst += 3;
- }
- }
- else
- {
- while (w--)
- {
- pixel = READ(src++);
- dpixel = Get24 (dst);
- pixel = FbDoMergeRop(pixel, dpixel);
- Put24 (dst, pixel);
- dst += 3;
- }
- }
- }
-}
-
-static void
-fb24_32BltUp (CARD8 *srcLine,
- FbStride srcStride,
- int srcX,
-
- CARD8 *dstLine,
- FbStride dstStride,
- int dstX,
-
- int width,
- int height,
-
- int alu,
- FbBits pm)
-{
- CARD8 *src;
- CARD32 *dst;
- int w;
- Bool destInvarient;
- CARD32 pixel;
- FbDeclareMergeRop ();
-
- FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff)));
- destInvarient = FbDestInvarientMergeRop();
-
- srcLine += srcX * 3;
- dstLine += dstX * 4;
-
- while (height--)
- {
- w = width;
- src = srcLine;
- dst = (CARD32 *) dstLine;
- srcLine += srcStride;
- dstLine += dstStride;
- if (destInvarient)
- {
- while (((long) src & 3) && w)
- {
- w--;
- pixel = Get24(src);
- src += 3;
- WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
- }
- /* Do four aligned pixels at a time */
- while (w >= 4)
- {
- CARD32 s0, s1;
-
- s0 = READ((CARD32 *)src);
-#if BITMAP_BIT_ORDER == LSBFirst
- pixel = s0 & 0xffffff;
-#else
- pixel = s0 >> 8;
-#endif
- WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
- s1 = READ((CARD32 *)(src+4));
-#if BITMAP_BIT_ORDER == LSBFirst
- pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff);
-#else
- pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16);
-#endif
- WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
- s0 = READ((CARD32 *)(src+8));
-#if BITMAP_BIT_ORDER == LSBFirst
- pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff);
-#else
- pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24);
-#endif
- WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
-#if BITMAP_BIT_ORDER == LSBFirst
- pixel = s0 >> 8;
-#else
- pixel = s0 & 0xffffff;
-#endif
- WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
- src += 12;
- w -= 4;
- }
- while (w)
- {
- w--;
- pixel = Get24(src);
- src += 3;
- WRITE(dst++, FbDoDestInvarientMergeRop(pixel));
- }
- }
- else
- {
- while (w--)
- {
- pixel = Get24(src);
- src += 3;
- WRITE(dst, FbDoMergeRop(pixel, READ(dst)));
- dst++;
- }
- }
- }
-}
-
-/*
- * Spans functions; probably unused.
- */
-void
-fb24_32GetSpans(DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- char *pchardstStart)
-{
- FbBits *srcBits;
- CARD8 *src;
- FbStride srcStride;
- int srcBpp;
- int srcXoff, srcYoff;
- CARD8 *dst;
-
- fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
- src = (CARD8 *) srcBits;
- srcStride *= sizeof (FbBits);
-
- while (nspans--)
- {
- dst = (CARD8 *) pchardstStart;
- fb24_32BltUp (src + (ppt->y + srcYoff) * srcStride, srcStride,
- ppt->x + srcXoff,
-
- dst,
- 1,
- 0,
-
- *pwidth,
- 1,
-
- GXcopy,
- FB_ALLONES);
-
- pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth);
- ppt++;
- pwidth++;
- }
-
- fbFinishAccess (pDrawable);
-}
-
-void
-fb24_32SetSpans (DrawablePtr pDrawable,
- GCPtr pGC,
- char *src,
- DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- int fSorted)
-{
- FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
- RegionPtr pClip = fbGetCompositeClip(pGC);
- FbBits *dstBits;
- CARD8 *dst, *d, *s;
- FbStride dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- BoxPtr pbox;
- int n;
- int x1, x2;
-
- fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
- dst = (CARD8 *) dstBits;
- dstStride *= sizeof (FbBits);
- while (nspans--)
- {
- d = dst + (ppt->y + dstYoff) * dstStride;
- s = (CARD8 *) src;
- n = RegionNumRects(pClip);
- pbox = RegionRects (pClip);
- while (n--)
- {
- if (pbox->y1 > ppt->y)
- break;
- if (pbox->y2 > ppt->y)
- {
- x1 = ppt->x;
- x2 = x1 + *pwidth;
- if (pbox->x1 > x1)
- x1 = pbox->x1;
- if (pbox->x2 < x2)
- x2 = pbox->x2;
- if (x1 < x2)
- fb24_32BltDown (s,
- 0,
- (x1 - ppt->x),
- d,
- dstStride,
- x1 + dstXoff,
-
- (x2 - x1),
- 1,
- pGC->alu,
- pPriv->pm);
- }
- }
- src += PixmapBytePad (*pwidth, pDrawable->depth);
- ppt++;
- pwidth++;
- }
-
- fbFinishAccess (pDrawable);
-}
-
-/*
- * Clip and put 32bpp Z-format images to a 24bpp drawable
- */
-void
-fb24_32PutZImage (DrawablePtr pDrawable,
- RegionPtr pClip,
- int alu,
- FbBits pm,
- int x,
- int y,
- int width,
- int height,
- CARD8 *src,
- FbStride srcStride)
-{
- FbBits *dstBits;
- CARD8 *dst;
- FbStride dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- int nbox;
- BoxPtr pbox;
- int x1, y1, x2, y2;
-
- fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
- dstStride *= sizeof(FbBits);
- dst = (CARD8 *) dstBits;
-
- for (nbox = RegionNumRects (pClip),
- pbox = RegionRects(pClip);
- nbox--;
- pbox++)
- {
- x1 = x;
- y1 = y;
- x2 = x + width;
- y2 = y + height;
- if (x1 < pbox->x1)
- x1 = pbox->x1;
- if (y1 < pbox->y1)
- y1 = pbox->y1;
- if (x2 > pbox->x2)
- x2 = pbox->x2;
- if (y2 > pbox->y2)
- y2 = pbox->y2;
- if (x1 >= x2 || y1 >= y2)
- continue;
- fb24_32BltDown (src + (y1 - y) * srcStride,
- srcStride,
- (x1 - x),
-
- dst + (y1 + dstYoff) * dstStride,
- dstStride,
- x1 + dstXoff,
-
- (x2 - x1),
- (y2 - y1),
-
- alu,
- pm);
- }
-
- fbFinishAccess (pDrawable);
-}
-
-void
-fb24_32GetImage (DrawablePtr pDrawable,
- int x,
- int y,
- int w,
- int h,
- unsigned int format,
- unsigned long planeMask,
- char *d)
-{
- FbBits *srcBits;
- CARD8 *src;
- FbStride srcStride;
- int srcBpp;
- int srcXoff, srcYoff;
- FbStride dstStride;
- FbBits pm;
-
- fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
- src = (CARD8 *) srcBits;
- srcStride *= sizeof (FbBits);
-
- x += pDrawable->x;
- y += pDrawable->y;
-
- pm = fbReplicatePixel (planeMask, 32);
- dstStride = PixmapBytePad(w, pDrawable->depth);
- if (pm != FB_ALLONES)
- memset (d, 0, dstStride * h);
- fb24_32BltUp (src + (y + srcYoff) * srcStride, srcStride, x + srcXoff,
- (CARD8 *) d, dstStride, 0,
- w, h, GXcopy, pm);
-
- fbFinishAccess (pDrawable);
-}
-
-void
-fb24_32CopyMtoN (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown,
- Pixel bitplane,
- void *closure)
-{
- FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
- FbBits *srcBits;
- CARD8 *src;
- FbStride srcStride;
- int srcBpp;
- FbBits *dstBits;
- CARD8 *dst;
- FbStride dstStride;
- int dstBpp;
- fb24_32BltFunc blt;
- int srcXoff, srcYoff;
- int dstXoff, dstYoff;
-
- fbGetDrawable (pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
- src = (CARD8 *) srcBits;
- srcStride *= sizeof (FbBits);
- fbGetDrawable (pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
- dst = (CARD8 *) dstBits;
- dstStride *= sizeof (FbBits);
- if (srcBpp == 24)
- blt = fb24_32BltUp;
- else
- blt = fb24_32BltDown;
-
- while (nbox--)
- {
- (*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride,
- srcStride,
- (pbox->x1 + dx + srcXoff),
-
- dst + (pbox->y1 + dstYoff) * dstStride,
- dstStride,
- (pbox->x1 + dstXoff),
-
- (pbox->x2 - pbox->x1),
- (pbox->y2 - pbox->y1),
-
- pGC->alu,
- pPriv->pm);
- pbox++;
- }
-
- fbFinishAccess (pSrcDrawable);
- fbFinishAccess (pDstDrawable);
-}
-
-PixmapPtr
-fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel)
-{
- ScreenPtr pScreen = pOldTile->drawable.pScreen;
- PixmapPtr pNewTile;
- FbBits *old, *new;
- FbStride oldStride, newStride;
- int oldBpp, newBpp;
- fb24_32BltFunc blt;
- int oldXoff, oldYoff;
- int newXoff, newYoff;
-
- pNewTile = pScreen->CreatePixmap(pScreen, pOldTile->drawable.width,
- pOldTile->drawable.height,
- pOldTile->drawable.depth,
- pOldTile->usage_hint);
- if (!pNewTile)
- return 0;
- fbGetDrawable (&pOldTile->drawable,
- old, oldStride, oldBpp, oldXoff, oldYoff);
- fbGetDrawable (&pNewTile->drawable,
- new, newStride, newBpp, newXoff, newYoff);
- if (oldBpp == 24)
- blt = fb24_32BltUp;
- else
- blt = fb24_32BltDown;
-
- (*blt) ((CARD8 *) old,
- oldStride * sizeof (FbBits),
- 0,
-
- (CARD8 *) new,
- newStride * sizeof (FbBits),
- 0,
-
- pOldTile->drawable.width,
- pOldTile->drawable.height,
-
- GXcopy,
- FB_ALLONES);
-
- fbFinishAccess (&pOldTile->drawable);
- fbFinishAccess (&pNewTile->drawable);
-
- return pNewTile;
-}
-
-typedef struct {
- pointer pbits;
- int width;
-} miScreenInitParmsRec, *miScreenInitParmsPtr;
-
-Bool
-fb24_32CreateScreenResources(ScreenPtr pScreen)
-{
- miScreenInitParmsPtr pScrInitParms;
- int pitch;
- Bool retval;
-
- /* get the pitch before mi destroys it */
- pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
- pitch = BitmapBytePad(pScrInitParms->width * 24);
-
- if((retval = miCreateScreenResources(pScreen))) {
- /* fix the screen pixmap */
- PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate;
- pPix->drawable.bitsPerPixel = 24;
- pPix->devKind = pitch;
- }
-
- return retval;
-}
-
-Bool
-fb24_32ModifyPixmapHeader (PixmapPtr pPixmap,
- int width,
- int height,
- int depth,
- int bitsPerPixel,
- int devKind,
- pointer pPixData)
-{
- int bpp, w;
-
- if (!pPixmap)
- return FALSE;
- bpp = bitsPerPixel;
- if (bpp <= 0)
- bpp = pPixmap->drawable.bitsPerPixel;
- if (bpp == 24)
- {
- if (devKind < 0)
- {
- w = width;
- if (w <= 0)
- w = pPixmap->drawable.width;
- devKind = BitmapBytePad(w * 24);
- }
- }
- return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel,
- devKind, pPixData);
-}
+/* + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> + +#include "fb.h" + +/* X apps don't like 24bpp images, this code exposes 32bpp images */ + +/* + * These two functions do a full CopyArea while reformatting + * the data between 24 and 32bpp. They try to go a bit faster + * by reading/writing aligned CARD32s where it's easy + */ + +#define Get8(a) ((CARD32) READ(a)) + +#if BITMAP_BIT_ORDER == MSBFirst +#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2)) +#define Put24(a,p) ((WRITE((a+0), (CARD8) ((p) >> 16))), \ + (WRITE((a+1), (CARD8) ((p) >> 8))), \ + (WRITE((a+2), (CARD8) (p)))) +#else +#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16)) +#define Put24(a,p) ((WRITE((a+0), (CARD8) (p))), \ + (WRITE((a+1), (CARD8) ((p) >> 8))), \ + (WRITE((a+2), (CARD8) ((p) >> 16)))) +#endif + +typedef void (*fb24_32BltFunc) (CARD8 *srcLine, + FbStride srcStride, + int srcX, + + CARD8 *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm); + +static void +fb24_32BltDown (CARD8 *srcLine, + FbStride srcStride, + int srcX, + + CARD8 *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm) +{ + CARD32 *src; + CARD8 *dst; + int w; + Bool destInvarient; + CARD32 pixel, dpixel; + FbDeclareMergeRop (); + + srcLine += srcX * 4; + dstLine += dstX * 3; + + FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff)); + destInvarient = FbDestInvarientMergeRop(); + + while (height--) + { + src = (CARD32 *) srcLine; + dst = dstLine; + srcLine += srcStride; + dstLine += dstStride; + w = width; + if (destInvarient) + { + while (((long) dst & 3) && w) + { + w--; + pixel = READ(src++); + pixel = FbDoDestInvarientMergeRop(pixel); + Put24 (dst, pixel); + dst += 3; + } + /* Do four aligned pixels at a time */ + while (w >= 4) + { + CARD32 s0, s1; + s0 = READ(src++); + s0 = FbDoDestInvarientMergeRop(s0); + s1 = READ(src++); + s1 = FbDoDestInvarientMergeRop(s1); +#if BITMAP_BIT_ORDER == LSBFirst + WRITE((CARD32 *)dst, (s0 & 0xffffff) | (s1 << 24)); +#else + WRITE((CARD32 *)dst, (s0 << 8) | ((s1 & 0xffffff) >> 16)); +#endif + s0 = READ(src++); + s0 = FbDoDestInvarientMergeRop(s0); +#if BITMAP_BIT_ORDER == LSBFirst + WRITE((CARD32 *)(dst+4), ((s1 & 0xffffff) >> 8) | (s0 << 16)); +#else + WRITE((CARD32 *)(dst+4), (s1 << 16) | ((s0 & 0xffffff) >> 8)); +#endif + s1 = READ(src++); + s1 = FbDoDestInvarientMergeRop(s1); +#if BITMAP_BIT_ORDER == LSBFirst + WRITE((CARD32 *)(dst+8), ((s0 & 0xffffff) >> 16) | (s1 << 8)); +#else + WRITE((CARD32 *)(dst+8), (s0 << 24) | (s1 & 0xffffff)); +#endif + dst += 12; + w -= 4; + } + while (w--) + { + pixel = READ(src++); + pixel = FbDoDestInvarientMergeRop(pixel); + Put24 (dst, pixel); + dst += 3; + } + } + else + { + while (w--) + { + pixel = READ(src++); + dpixel = Get24 (dst); + pixel = FbDoMergeRop(pixel, dpixel); + Put24 (dst, pixel); + dst += 3; + } + } + } +} + +static void +fb24_32BltUp (CARD8 *srcLine, + FbStride srcStride, + int srcX, + + CARD8 *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm) +{ + CARD8 *src; + CARD32 *dst; + int w; + Bool destInvarient; + CARD32 pixel; + FbDeclareMergeRop (); + + FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff))); + destInvarient = FbDestInvarientMergeRop(); + + srcLine += srcX * 3; + dstLine += dstX * 4; + + while (height--) + { + w = width; + src = srcLine; + dst = (CARD32 *) dstLine; + srcLine += srcStride; + dstLine += dstStride; + if (destInvarient) + { + while (((long) src & 3) && w) + { + w--; + pixel = Get24(src); + src += 3; + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); + } + /* Do four aligned pixels at a time */ + while (w >= 4) + { + CARD32 s0, s1; + + s0 = READ((CARD32 *)src); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = s0 & 0xffffff; +#else + pixel = s0 >> 8; +#endif + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); + s1 = READ((CARD32 *)(src+4)); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff); +#else + pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16); +#endif + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); + s0 = READ((CARD32 *)(src+8)); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff); +#else + pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24); +#endif + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = s0 >> 8; +#else + pixel = s0 & 0xffffff; +#endif + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); + src += 12; + w -= 4; + } + while (w) + { + w--; + pixel = Get24(src); + src += 3; + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); + } + } + else + { + while (w--) + { + pixel = Get24(src); + src += 3; + WRITE(dst, FbDoMergeRop(pixel, READ(dst))); + dst++; + } + } + } +} + +/* + * Spans functions; probably unused. + */ +void +fb24_32GetSpans(DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pchardstStart) +{ + FbBits *srcBits; + CARD8 *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + CARD8 *dst; + + fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); + src = (CARD8 *) srcBits; + srcStride *= sizeof (FbBits); + + while (nspans--) + { + dst = (CARD8 *) pchardstStart; + fb24_32BltUp (src + (ppt->y + srcYoff) * srcStride, srcStride, + ppt->x + srcXoff, + + dst, + 1, + 0, + + *pwidth, + 1, + + GXcopy, + FB_ALLONES); + + pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth); + ppt++; + pwidth++; + } + + fbFinishAccess (pDrawable); +} + +void +fb24_32SetSpans (DrawablePtr pDrawable, + GCPtr pGC, + char *src, + DDXPointPtr ppt, + int *pwidth, + int nspans, + int fSorted) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + RegionPtr pClip = fbGetCompositeClip(pGC); + FbBits *dstBits; + CARD8 *dst, *d, *s; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + BoxPtr pbox; + int n; + int x1, x2; + + fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + dst = (CARD8 *) dstBits; + dstStride *= sizeof (FbBits); + while (nspans--) + { + d = dst + (ppt->y + dstYoff) * dstStride; + s = (CARD8 *) src; + n = RegionNumRects(pClip); + pbox = RegionRects (pClip); + while (n--) + { + if (pbox->y1 > ppt->y) + break; + if (pbox->y2 > ppt->y) + { + x1 = ppt->x; + x2 = x1 + *pwidth; + if (pbox->x1 > x1) + x1 = pbox->x1; + if (pbox->x2 < x2) + x2 = pbox->x2; + if (x1 < x2) + fb24_32BltDown (s, + 0, + (x1 - ppt->x), + d, + dstStride, + x1 + dstXoff, + + (x2 - x1), + 1, + pGC->alu, + pPriv->pm); + } + } + src += PixmapBytePad (*pwidth, pDrawable->depth); + ppt++; + pwidth++; + } + + fbFinishAccess (pDrawable); +} + +/* + * Clip and put 32bpp Z-format images to a 24bpp drawable + */ +void +fb24_32PutZImage (DrawablePtr pDrawable, + RegionPtr pClip, + int alu, + FbBits pm, + int x, + int y, + int width, + int height, + CARD8 *src, + FbStride srcStride) +{ + FbBits *dstBits; + CARD8 *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + int nbox; + BoxPtr pbox; + int x1, y1, x2, y2; + + fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + dstStride *= sizeof(FbBits); + dst = (CARD8 *) dstBits; + + for (nbox = RegionNumRects (pClip), + pbox = RegionRects(pClip); + nbox--; + pbox++) + { + x1 = x; + y1 = y; + x2 = x + width; + y2 = y + height; + if (x1 < pbox->x1) + x1 = pbox->x1; + if (y1 < pbox->y1) + y1 = pbox->y1; + if (x2 > pbox->x2) + x2 = pbox->x2; + if (y2 > pbox->y2) + y2 = pbox->y2; + if (x1 >= x2 || y1 >= y2) + continue; + fb24_32BltDown (src + (y1 - y) * srcStride, + srcStride, + (x1 - x), + + dst + (y1 + dstYoff) * dstStride, + dstStride, + x1 + dstXoff, + + (x2 - x1), + (y2 - y1), + + alu, + pm); + } + + fbFinishAccess (pDrawable); +} + +void +fb24_32GetImage (DrawablePtr pDrawable, + int x, + int y, + int w, + int h, + unsigned int format, + unsigned long planeMask, + char *d) +{ + FbBits *srcBits; + CARD8 *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + FbStride dstStride; + FbBits pm; + + fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); + src = (CARD8 *) srcBits; + srcStride *= sizeof (FbBits); + + x += pDrawable->x; + y += pDrawable->y; + + pm = fbReplicatePixel (planeMask, 32); + dstStride = PixmapBytePad(w, pDrawable->depth); + if (pm != FB_ALLONES) + memset (d, 0, dstStride * h); + fb24_32BltUp (src + (y + srcYoff) * srcStride, srcStride, x + srcXoff, + (CARD8 *) d, dstStride, 0, + w, h, GXcopy, pm); + + fbFinishAccess (pDrawable); +} + +void +fb24_32CopyMtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + FbBits *srcBits; + CARD8 *src; + FbStride srcStride; + int srcBpp; + FbBits *dstBits; + CARD8 *dst; + FbStride dstStride; + int dstBpp; + fb24_32BltFunc blt; + int srcXoff, srcYoff; + int dstXoff, dstYoff; + + fbGetDrawable (pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); + src = (CARD8 *) srcBits; + srcStride *= sizeof (FbBits); + fbGetDrawable (pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + dst = (CARD8 *) dstBits; + dstStride *= sizeof (FbBits); + if (srcBpp == 24) + blt = fb24_32BltUp; + else + blt = fb24_32BltDown; + + while (nbox--) + { + (*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride, + srcStride, + (pbox->x1 + dx + srcXoff), + + dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff), + + (pbox->x2 - pbox->x1), + (pbox->y2 - pbox->y1), + + pGC->alu, + pPriv->pm); + pbox++; + } + + fbFinishAccess (pSrcDrawable); + fbFinishAccess (pDstDrawable); +} + +PixmapPtr +fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel) +{ + ScreenPtr pScreen = pOldTile->drawable.pScreen; + PixmapPtr pNewTile; + FbBits *old, *new; + FbStride oldStride, newStride; + int oldBpp, newBpp; + fb24_32BltFunc blt; + _X_UNUSED int oldXoff, oldYoff; + _X_UNUSED int newXoff, newYoff; + + pNewTile = pScreen->CreatePixmap(pScreen, pOldTile->drawable.width, + pOldTile->drawable.height, + pOldTile->drawable.depth, + pOldTile->usage_hint); + if (!pNewTile) + return 0; + fbGetDrawable (&pOldTile->drawable, + old, oldStride, oldBpp, oldXoff, oldYoff); + fbGetDrawable (&pNewTile->drawable, + new, newStride, newBpp, newXoff, newYoff); + if (oldBpp == 24) + blt = fb24_32BltUp; + else + blt = fb24_32BltDown; + + (*blt) ((CARD8 *) old, + oldStride * sizeof (FbBits), + 0, + + (CARD8 *) new, + newStride * sizeof (FbBits), + 0, + + pOldTile->drawable.width, + pOldTile->drawable.height, + + GXcopy, + FB_ALLONES); + + fbFinishAccess (&pOldTile->drawable); + fbFinishAccess (&pNewTile->drawable); + + return pNewTile; +} + +typedef struct { + pointer pbits; + int width; +} miScreenInitParmsRec, *miScreenInitParmsPtr; + +Bool +fb24_32CreateScreenResources(ScreenPtr pScreen) +{ + miScreenInitParmsPtr pScrInitParms; + int pitch; + Bool retval; + + /* get the pitch before mi destroys it */ + pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate; + pitch = BitmapBytePad(pScrInitParms->width * 24); + + if((retval = miCreateScreenResources(pScreen))) { + /* fix the screen pixmap */ + PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate; + pPix->drawable.bitsPerPixel = 24; + pPix->devKind = pitch; + } + + return retval; +} + +Bool +fb24_32ModifyPixmapHeader (PixmapPtr pPixmap, + int width, + int height, + int depth, + int bitsPerPixel, + int devKind, + pointer pPixData) +{ + int bpp, w; + + if (!pPixmap) + return FALSE; + bpp = bitsPerPixel; + if (bpp <= 0) + bpp = pPixmap->drawable.bitsPerPixel; + if (bpp == 24) + { + if (devKind < 0) + { + w = width; + if (w <= 0) + w = pPixmap->drawable.width; + devKind = BitmapBytePad(w * 24); + } + } + return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, + devKind, pPixData); +} diff --git a/xorg-server/fb/fbarc.c b/xorg-server/fb/fbarc.c index a0c5343e0..e54c80491 100644 --- a/xorg-server/fb/fbarc.c +++ b/xorg-server/fb/fbarc.c @@ -68,15 +68,12 @@ fbPolyArc (DrawablePtr pDrawable, BoxRec box; int x2, y2; RegionPtr cclip; - int wrapped = 0; +#ifdef FB_ACCESS_WRAPPER + int wrapped = 1; +#endif cclip = fbGetCompositeClip (pGC); fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); -#ifdef FB_ACCESS_WRAPPER - wrapped = 1; -#else - wrapped = 0; -#endif while (narcs--) { if (miCanZeroArc (parcs)) diff --git a/xorg-server/fb/fbfill.c b/xorg-server/fb/fbfill.c index 664d6a82e..e62a48ae0 100644 --- a/xorg-server/fb/fbfill.c +++ b/xorg-server/fb/fbfill.c @@ -1,230 +1,230 @@ -/*
- * Copyright © 1998 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "fb.h"
-
-void
-fbFill (DrawablePtr pDrawable,
- GCPtr pGC,
- int x,
- int y,
- int width,
- int height)
-{
- FbBits *dst;
- FbStride dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
-
- fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
-
- switch (pGC->fillStyle) {
- case FillSolid:
-#ifndef FB_ACCESS_WRAPPER
- if (pPriv->and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
- x + dstXoff, y + dstYoff,
- width, height,
- pPriv->xor))
-#endif
- fbSolid (dst + (y + dstYoff) * dstStride,
- dstStride,
- (x + dstXoff) * dstBpp,
- dstBpp,
- width * dstBpp, height,
- pPriv->and, pPriv->xor);
- break;
- case FillStippled:
- case FillOpaqueStippled: {
- PixmapPtr pStip = pGC->stipple;
- int stipWidth = pStip->drawable.width;
- int stipHeight = pStip->drawable.height;
-
- if (dstBpp == 1)
- {
- int alu;
- FbBits *stip;
- FbStride stipStride;
- int stipBpp;
- int stipXoff, stipYoff; /* XXX assumed to be zero */
-
- if (pGC->fillStyle == FillStippled)
- alu = FbStipple1Rop(pGC->alu,pGC->fgPixel);
- else
- alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
- fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
- fbTile (dst + (y + dstYoff) * dstStride,
- dstStride,
- x + dstXoff,
- width, height,
- stip,
- stipStride,
- stipWidth,
- stipHeight,
- alu,
- pPriv->pm,
- dstBpp,
-
- (pGC->patOrg.x + pDrawable->x + dstXoff),
- pGC->patOrg.y + pDrawable->y - y);
- fbFinishAccess (&pStip->drawable);
- }
- else
- {
- FbStip *stip;
- FbStride stipStride;
- int stipBpp;
- int stipXoff, stipYoff; /* XXX assumed to be zero */
- FbBits fgand, fgxor, bgand, bgxor;
-
- fgand = pPriv->and;
- fgxor = pPriv->xor;
- if (pGC->fillStyle == FillStippled)
- {
- bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES);
- bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES);
- }
- else
- {
- bgand = pPriv->bgand;
- bgxor = pPriv->bgxor;
- }
-
- fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
- fbStipple (dst + (y + dstYoff) * dstStride,
- dstStride,
- (x + dstXoff) * dstBpp,
- dstBpp,
- width * dstBpp, height,
- stip,
- stipStride,
- stipWidth,
- stipHeight,
- pPriv->evenStipple,
- fgand, fgxor,
- bgand, bgxor,
- pGC->patOrg.x + pDrawable->x + dstXoff,
- pGC->patOrg.y + pDrawable->y - y);
- fbFinishAccess (&pStip->drawable);
- }
- break;
- }
- case FillTiled: {
- PixmapPtr pTile = pGC->tile.pixmap;
- FbBits *tile;
- FbStride tileStride;
- int tileBpp;
- int tileWidth;
- int tileHeight;
- int tileXoff, tileYoff; /* XXX assumed to be zero */
-
- fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
- tileWidth = pTile->drawable.width;
- tileHeight = pTile->drawable.height;
- fbTile (dst + (y + dstYoff) * dstStride,
- dstStride,
- (x + dstXoff) * dstBpp,
- width * dstBpp, height,
- tile,
- tileStride,
- tileWidth * tileBpp,
- tileHeight,
- pGC->alu,
- pPriv->pm,
- dstBpp,
- (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
- pGC->patOrg.y + pDrawable->y - y);
- fbFinishAccess (&pTile->drawable);
- break;
- }
- }
- fbValidateDrawable (pDrawable);
- fbFinishAccess (pDrawable);
-}
-
-void
-fbSolidBoxClipped (DrawablePtr pDrawable,
- RegionPtr pClip,
- int x1,
- int y1,
- int x2,
- int y2,
- FbBits and,
- FbBits xor)
-{
- FbBits *dst;
- FbStride dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- BoxPtr pbox;
- int nbox;
- int partX1, partX2, partY1, partY2;
-
- fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
-
- for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip);
- nbox--;
- pbox++)
- {
- partX1 = pbox->x1;
- if (partX1 < x1)
- partX1 = x1;
-
- partX2 = pbox->x2;
- if (partX2 > x2)
- partX2 = x2;
-
- if (partX2 <= partX1)
- continue;
-
- partY1 = pbox->y1;
- if (partY1 < y1)
- partY1 = y1;
-
- partY2 = pbox->y2;
- if (partY2 > y2)
- partY2 = y2;
-
- if (partY2 <= partY1)
- continue;
-
-#ifndef FB_ACCESS_WRAPPER
- if (and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
- partX1 + dstXoff, partY1 + dstYoff,
- (partX2 - partX1), (partY2 - partY1),
- xor))
-#endif
- fbSolid (dst + (partY1 + dstYoff) * dstStride,
- dstStride,
- (partX1 + dstXoff) * dstBpp,
- dstBpp,
-
- (partX2 - partX1) * dstBpp,
- (partY2 - partY1),
- and, xor);
- }
- fbFinishAccess (pDrawable);
-}
+/* + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "fb.h" + +void +fbFill (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int width, + int height) +{ + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + switch (pGC->fillStyle) { + case FillSolid: +#ifndef FB_ACCESS_WRAPPER + if (pPriv->and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp, + x + dstXoff, y + dstYoff, + width, height, + pPriv->xor)) +#endif + fbSolid (dst + (y + dstYoff) * dstStride, + dstStride, + (x + dstXoff) * dstBpp, + dstBpp, + width * dstBpp, height, + pPriv->and, pPriv->xor); + break; + case FillStippled: + case FillOpaqueStippled: { + PixmapPtr pStip = pGC->stipple; + int stipWidth = pStip->drawable.width; + int stipHeight = pStip->drawable.height; + + if (dstBpp == 1) + { + int alu; + FbBits *stip; + FbStride stipStride; + int stipBpp; + _X_UNUSED int stipXoff, stipYoff; + + if (pGC->fillStyle == FillStippled) + alu = FbStipple1Rop(pGC->alu,pGC->fgPixel); + else + alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel); + fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); + fbTile (dst + (y + dstYoff) * dstStride, + dstStride, + x + dstXoff, + width, height, + stip, + stipStride, + stipWidth, + stipHeight, + alu, + pPriv->pm, + dstBpp, + + (pGC->patOrg.x + pDrawable->x + dstXoff), + pGC->patOrg.y + pDrawable->y - y); + fbFinishAccess (&pStip->drawable); + } + else + { + FbStip *stip; + FbStride stipStride; + int stipBpp; + _X_UNUSED int stipXoff, stipYoff; + FbBits fgand, fgxor, bgand, bgxor; + + fgand = pPriv->and; + fgxor = pPriv->xor; + if (pGC->fillStyle == FillStippled) + { + bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES); + bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES); + } + else + { + bgand = pPriv->bgand; + bgxor = pPriv->bgxor; + } + + fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); + fbStipple (dst + (y + dstYoff) * dstStride, + dstStride, + (x + dstXoff) * dstBpp, + dstBpp, + width * dstBpp, height, + stip, + stipStride, + stipWidth, + stipHeight, + pPriv->evenStipple, + fgand, fgxor, + bgand, bgxor, + pGC->patOrg.x + pDrawable->x + dstXoff, + pGC->patOrg.y + pDrawable->y - y); + fbFinishAccess (&pStip->drawable); + } + break; + } + case FillTiled: { + PixmapPtr pTile = pGC->tile.pixmap; + FbBits *tile; + FbStride tileStride; + int tileBpp; + int tileWidth; + int tileHeight; + _X_UNUSED int tileXoff, tileYoff; + + fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff); + tileWidth = pTile->drawable.width; + tileHeight = pTile->drawable.height; + fbTile (dst + (y + dstYoff) * dstStride, + dstStride, + (x + dstXoff) * dstBpp, + width * dstBpp, height, + tile, + tileStride, + tileWidth * tileBpp, + tileHeight, + pGC->alu, + pPriv->pm, + dstBpp, + (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp, + pGC->patOrg.y + pDrawable->y - y); + fbFinishAccess (&pTile->drawable); + break; + } + } + fbValidateDrawable (pDrawable); + fbFinishAccess (pDrawable); +} + +void +fbSolidBoxClipped (DrawablePtr pDrawable, + RegionPtr pClip, + int x1, + int y1, + int x2, + int y2, + FbBits and, + FbBits xor) +{ + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + BoxPtr pbox; + int nbox; + int partX1, partX2, partY1, partY2; + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + + for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip); + nbox--; + pbox++) + { + partX1 = pbox->x1; + if (partX1 < x1) + partX1 = x1; + + partX2 = pbox->x2; + if (partX2 > x2) + partX2 = x2; + + if (partX2 <= partX1) + continue; + + partY1 = pbox->y1; + if (partY1 < y1) + partY1 = y1; + + partY2 = pbox->y2; + if (partY2 > y2) + partY2 = y2; + + if (partY2 <= partY1) + continue; + +#ifndef FB_ACCESS_WRAPPER + if (and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp, + partX1 + dstXoff, partY1 + dstYoff, + (partX2 - partX1), (partY2 - partY1), + xor)) +#endif + fbSolid (dst + (partY1 + dstYoff) * dstStride, + dstStride, + (partX1 + dstXoff) * dstBpp, + dstBpp, + + (partX2 - partX1) * dstBpp, + (partY2 - partY1), + and, xor); + } + fbFinishAccess (pDrawable); +} diff --git a/xorg-server/fb/fbgc.c b/xorg-server/fb/fbgc.c index cc504c1b8..8108c3acb 100644 --- a/xorg-server/fb/fbgc.c +++ b/xorg-server/fb/fbgc.c @@ -89,7 +89,7 @@ fbPadPixmap (PixmapPtr pPixmap) int w; int stride; int bpp; - int xOff, yOff; + _X_UNUSED int xOff, yOff; fbGetDrawable (&pPixmap->drawable, bits, stride, bpp, xOff, yOff); @@ -163,7 +163,7 @@ fbCanEvenStipple (PixmapPtr pStipple, int bpp) FbBits *bits; int stride; int stip_bpp; - int stipXoff, stipYoff; + _X_UNUSED int stipXoff, stipYoff; int h; /* can't even stipple 24bpp drawables */ diff --git a/xorg-server/fb/fbpush.c b/xorg-server/fb/fbpush.c index cfb702483..8dd7c2b59 100644 --- a/xorg-server/fb/fbpush.c +++ b/xorg-server/fb/fbpush.c @@ -1,245 +1,245 @@ -/*
- * Copyright © 1998 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "fb.h"
-
-void
-fbPushPattern (DrawablePtr pDrawable,
- GCPtr pGC,
-
- FbStip *src,
- FbStride srcStride,
- int srcX,
-
- int x,
- int y,
-
- int width,
- int height)
-{
- FbStip *s, bitsMask, bitsMask0, bits;
- int xspan;
- int w;
- int lenspan;
-
- src += srcX >> FB_STIP_SHIFT;
- srcX &= FB_STIP_MASK;
-
- bitsMask0 = FbStipMask (srcX, 1);
-
- while (height--)
- {
- bitsMask = bitsMask0;
- w = width;
- s = src;
- src += srcStride;
- bits = READ(s++);
- xspan = x;
- while (w)
- {
- if (bits & bitsMask)
- {
- lenspan = 0;
- do
- {
- lenspan++;
- if (lenspan == w)
- break;
- bitsMask = FbStipRight (bitsMask, 1);
- if (!bitsMask)
- {
- bits = READ(s++);
- bitsMask = FbBitsMask(0,1);
- }
- } while (bits & bitsMask);
- fbFill (pDrawable, pGC, xspan, y, lenspan, 1);
- xspan += lenspan;
- w -= lenspan;
- }
- else
- {
- do
- {
- w--;
- xspan++;
- if (!w)
- break;
- bitsMask = FbStipRight (bitsMask, 1);
- if (!bitsMask)
- {
- bits = READ(s++);
- bitsMask = FbBitsMask(0,1);
- }
- } while (!(bits & bitsMask));
- }
- }
- y++;
- }
-}
-
-void
-fbPushFill (DrawablePtr pDrawable,
- GCPtr pGC,
-
- FbStip *src,
- FbStride srcStride,
- int srcX,
-
- int x,
- int y,
- int width,
- int height)
-{
- FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
-
- if (pGC->fillStyle == FillSolid)
- {
- FbBits *dst;
- FbStride dstStride;
- int dstBpp;
- int dstXoff, dstYoff;
- int dstX;
- int dstWidth;
-
- fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
- dst = dst + (y + dstYoff) * dstStride;
- dstX = (x + dstXoff) * dstBpp;
- dstWidth = width * dstBpp;
- if (dstBpp == 1)
- {
- fbBltStip (src,
- srcStride,
- srcX,
-
- (FbStip *) dst,
- FbBitsStrideToStipStride (dstStride),
- dstX,
-
- dstWidth,
- height,
-
- FbStipple1Rop(pGC->alu,pGC->fgPixel),
- pPriv->pm,
- dstBpp);
- }
- else
- {
- fbBltOne (src,
- srcStride,
- srcX,
-
- dst,
- dstStride,
- dstX,
- dstBpp,
-
- dstWidth,
- height,
-
- pPriv->and, pPriv->xor,
- fbAnd(GXnoop,(FbBits) 0,FB_ALLONES),
- fbXor(GXnoop,(FbBits) 0,FB_ALLONES));
- }
- fbFinishAccess (pDrawable);
- }
- else
- {
- fbPushPattern (pDrawable, pGC, src, srcStride, srcX,
- x, y, width, height);
- }
-}
-
-void
-fbPushImage (DrawablePtr pDrawable,
- GCPtr pGC,
-
- FbStip *src,
- FbStride srcStride,
- int srcX,
-
- int x,
- int y,
- int width,
- int height)
-{
- RegionPtr pClip = fbGetCompositeClip (pGC);
- int nbox;
- BoxPtr pbox;
- int x1, y1, x2, y2;
-
- for (nbox = RegionNumRects (pClip),
- pbox = RegionRects(pClip);
- nbox--;
- pbox++)
- {
- x1 = x;
- y1 = y;
- x2 = x + width;
- y2 = y + height;
- if (x1 < pbox->x1)
- x1 = pbox->x1;
- if (y1 < pbox->y1)
- y1 = pbox->y1;
- if (x2 > pbox->x2)
- x2 = pbox->x2;
- if (y2 > pbox->y2)
- y2 = pbox->y2;
- if (x1 >= x2 || y1 >= y2)
- continue;
- fbPushFill (pDrawable,
- pGC,
-
- src + (y1 - y) * srcStride,
- srcStride,
- srcX + (x1 - x),
-
- x1,
- y1,
- x2 - x1,
- y2 - y1);
- }
-}
-
-void
-fbPushPixels (GCPtr pGC,
- PixmapPtr pBitmap,
- DrawablePtr pDrawable,
- int dx,
- int dy,
- int xOrg,
- int yOrg)
-{
- FbStip *stip;
- FbStride stipStride;
- int stipBpp;
- int stipXoff, stipYoff; /* Assumed to be zero */
-
- fbGetStipDrawable (&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
-
- fbPushImage (pDrawable, pGC,
- stip, stipStride, 0,
- xOrg, yOrg, dx, dy);
-}
+/* + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "fb.h" + +void +fbPushPattern (DrawablePtr pDrawable, + GCPtr pGC, + + FbStip *src, + FbStride srcStride, + int srcX, + + int x, + int y, + + int width, + int height) +{ + FbStip *s, bitsMask, bitsMask0, bits; + int xspan; + int w; + int lenspan; + + src += srcX >> FB_STIP_SHIFT; + srcX &= FB_STIP_MASK; + + bitsMask0 = FbStipMask (srcX, 1); + + while (height--) + { + bitsMask = bitsMask0; + w = width; + s = src; + src += srcStride; + bits = READ(s++); + xspan = x; + while (w) + { + if (bits & bitsMask) + { + lenspan = 0; + do + { + lenspan++; + if (lenspan == w) + break; + bitsMask = FbStipRight (bitsMask, 1); + if (!bitsMask) + { + bits = READ(s++); + bitsMask = FbBitsMask(0,1); + } + } while (bits & bitsMask); + fbFill (pDrawable, pGC, xspan, y, lenspan, 1); + xspan += lenspan; + w -= lenspan; + } + else + { + do + { + w--; + xspan++; + if (!w) + break; + bitsMask = FbStipRight (bitsMask, 1); + if (!bitsMask) + { + bits = READ(s++); + bitsMask = FbBitsMask(0,1); + } + } while (!(bits & bitsMask)); + } + } + y++; + } +} + +void +fbPushFill (DrawablePtr pDrawable, + GCPtr pGC, + + FbStip *src, + FbStride srcStride, + int srcX, + + int x, + int y, + int width, + int height) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + + if (pGC->fillStyle == FillSolid) + { + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + int dstX; + int dstWidth; + + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + dst = dst + (y + dstYoff) * dstStride; + dstX = (x + dstXoff) * dstBpp; + dstWidth = width * dstBpp; + if (dstBpp == 1) + { + fbBltStip (src, + srcStride, + srcX, + + (FbStip *) dst, + FbBitsStrideToStipStride (dstStride), + dstX, + + dstWidth, + height, + + FbStipple1Rop(pGC->alu,pGC->fgPixel), + pPriv->pm, + dstBpp); + } + else + { + fbBltOne (src, + srcStride, + srcX, + + dst, + dstStride, + dstX, + dstBpp, + + dstWidth, + height, + + pPriv->and, pPriv->xor, + fbAnd(GXnoop,(FbBits) 0,FB_ALLONES), + fbXor(GXnoop,(FbBits) 0,FB_ALLONES)); + } + fbFinishAccess (pDrawable); + } + else + { + fbPushPattern (pDrawable, pGC, src, srcStride, srcX, + x, y, width, height); + } +} + +void +fbPushImage (DrawablePtr pDrawable, + GCPtr pGC, + + FbStip *src, + FbStride srcStride, + int srcX, + + int x, + int y, + int width, + int height) +{ + RegionPtr pClip = fbGetCompositeClip (pGC); + int nbox; + BoxPtr pbox; + int x1, y1, x2, y2; + + for (nbox = RegionNumRects (pClip), + pbox = RegionRects(pClip); + nbox--; + pbox++) + { + x1 = x; + y1 = y; + x2 = x + width; + y2 = y + height; + if (x1 < pbox->x1) + x1 = pbox->x1; + if (y1 < pbox->y1) + y1 = pbox->y1; + if (x2 > pbox->x2) + x2 = pbox->x2; + if (y2 > pbox->y2) + y2 = pbox->y2; + if (x1 >= x2 || y1 >= y2) + continue; + fbPushFill (pDrawable, + pGC, + + src + (y1 - y) * srcStride, + srcStride, + srcX + (x1 - x), + + x1, + y1, + x2 - x1, + y2 - y1); + } +} + +void +fbPushPixels (GCPtr pGC, + PixmapPtr pBitmap, + DrawablePtr pDrawable, + int dx, + int dy, + int xOrg, + int yOrg) +{ + FbStip *stip; + FbStride stipStride; + int stipBpp; + _X_UNUSED int stipXoff, stipYoff; + + fbGetStipDrawable (&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); + + fbPushImage (pDrawable, pGC, + stip, stipStride, 0, + xOrg, yOrg, dx, dy); +} diff --git a/xorg-server/glx/Makefile.am b/xorg-server/glx/Makefile.am index 7cc2521d5..34be4ae49 100644 --- a/xorg-server/glx/Makefile.am +++ b/xorg-server/glx/Makefile.am @@ -48,9 +48,7 @@ glapi_sources = \ glthread.c \ glthread.h -libglxdri_la_SOURCES = \ - extension_string.c \ - extension_string.h +libglxdri_la_SOURCES = if DRI libglxdri_la_SOURCES += glxdri.c @@ -65,6 +63,8 @@ libglxdri_la_LIBADD = $(DLOPEN_LIBS) libglx_la_SOURCES = \ $(indirect_sources) \ $(glapi_sources) \ + extension_string.c \ + extension_string.h \ indirect_util.c \ indirect_util.h \ indirect_program.c \ diff --git a/xorg-server/glx/glapi_gentable.c b/xorg-server/glx/glapi_gentable.c index a9ba3af56..b49ae20f4 100644 --- a/xorg-server/glx/glapi_gentable.c +++ b/xorg-server/glx/glapi_gentable.c @@ -31,7 +31,10 @@ #include <dix-config.h> #endif +#ifdef HAVE_BACKTRACE #include <execinfo.h> +#endif + #include <dlfcn.h> #include <stdlib.h> #include <stdio.h> @@ -46,6 +49,8 @@ static void __glapi_gentable_NoOp(void) { const char *fstr = "Unknown"; + +#ifdef HAVE_BACKTRACE void *frames[2]; if(backtrace(frames, 2) == 2) { @@ -54,6 +59,7 @@ __glapi_gentable_NoOp(void) { if(info.dli_sname) fstr = info.dli_sname; } +#endif LogMessage(X_ERROR, "GLX: Call to unimplemented API: %s\n", fstr); } diff --git a/xorg-server/glx/glxdri2.c b/xorg-server/glx/glxdri2.c index d97971739..e8722585b 100644 --- a/xorg-server/glx/glxdri2.c +++ b/xorg-server/glx/glxdri2.c @@ -163,10 +163,10 @@ __glXDRIdrawableWaitGL(__GLXdrawable *drawable) static void __glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust, - CARD64 msc, CARD64 sbc) + CARD64 msc, CARD32 sbc) { __GLXdrawable *drawable = data; - xGLXBufferSwapComplete wire; + xGLXBufferSwapComplete2 wire; if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK)) return; @@ -192,8 +192,7 @@ __glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust, wire.ust_lo = ust & 0xffffffff; wire.msc_hi = msc >> 32; wire.msc_lo = msc & 0xffffffff; - wire.sbc_hi = sbc >> 32; - wire.sbc_lo = sbc & 0xffffffff; + wire.sbc = sbc; WriteEventsToClient(client, 1, (xEvent *) &wire); } @@ -222,7 +221,7 @@ __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable) #endif if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused, - __glXdriSwapEvent, drawable->pDraw) != Success) + __glXdriSwapEvent, drawable) != Success) return FALSE; return TRUE; diff --git a/xorg-server/glx/glxscreens.c b/xorg-server/glx/glxscreens.c index 060dfaccd..c4ad42648 100644 --- a/xorg-server/glx/glxscreens.c +++ b/xorg-server/glx/glxscreens.c @@ -1,418 +1,425 @@ -/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <GL/glxtokens.h>
-#include <string.h>
-#include <windowstr.h>
-#include <os.h>
-#include <colormapst.h>
-
-#include "privates.h"
-#include "glxserver.h"
-#include "glxutil.h"
-#include "glxext.h"
-#include "protocol-versions.h"
-
-static DevPrivateKeyRec glxScreenPrivateKeyRec;
-#define glxScreenPrivateKey (&glxScreenPrivateKeyRec)
-
-const char GLServerVersion[] = "1.4";
-static const char GLServerExtensions[] =
- "GL_ARB_depth_texture "
- "GL_ARB_draw_buffers "
- "GL_ARB_fragment_program "
- "GL_ARB_fragment_program_shadow "
- "GL_ARB_imaging "
- "GL_ARB_multisample "
- "GL_ARB_multitexture "
- "GL_ARB_occlusion_query "
- "GL_ARB_point_parameters "
- "GL_ARB_point_sprite "
- "GL_ARB_shadow "
- "GL_ARB_shadow_ambient "
- "GL_ARB_texture_border_clamp "
- "GL_ARB_texture_compression "
- "GL_ARB_texture_cube_map "
- "GL_ARB_texture_env_add "
- "GL_ARB_texture_env_combine "
- "GL_ARB_texture_env_crossbar "
- "GL_ARB_texture_env_dot3 "
- "GL_ARB_texture_mirrored_repeat "
- "GL_ARB_texture_non_power_of_two "
- "GL_ARB_transpose_matrix "
- "GL_ARB_vertex_program "
- "GL_ARB_window_pos "
- "GL_EXT_abgr "
- "GL_EXT_bgra "
- "GL_EXT_blend_color "
- "GL_EXT_blend_equation_separate "
- "GL_EXT_blend_func_separate "
- "GL_EXT_blend_logic_op "
- "GL_EXT_blend_minmax "
- "GL_EXT_blend_subtract "
- "GL_EXT_clip_volume_hint "
- "GL_EXT_copy_texture "
- "GL_EXT_draw_range_elements "
- "GL_EXT_fog_coord "
- "GL_EXT_framebuffer_object "
- "GL_EXT_multi_draw_arrays "
- "GL_EXT_packed_pixels "
- "GL_EXT_paletted_texture "
- "GL_EXT_point_parameters "
- "GL_EXT_polygon_offset "
- "GL_EXT_rescale_normal "
- "GL_EXT_secondary_color "
- "GL_EXT_separate_specular_color "
- "GL_EXT_shadow_funcs "
- "GL_EXT_shared_texture_palette "
- "GL_EXT_stencil_two_side "
- "GL_EXT_stencil_wrap "
- "GL_EXT_subtexture "
- "GL_EXT_texture "
- "GL_EXT_texture3D "
- "GL_EXT_texture_compression_dxt1 "
- "GL_EXT_texture_compression_s3tc "
- "GL_EXT_texture_edge_clamp "
- "GL_EXT_texture_env_add "
- "GL_EXT_texture_env_combine "
- "GL_EXT_texture_env_dot3 "
- "GL_EXT_texture_filter_anisotropic "
- "GL_EXT_texture_lod "
- "GL_EXT_texture_lod_bias "
- "GL_EXT_texture_mirror_clamp "
- "GL_EXT_texture_object "
- "GL_EXT_texture_rectangle "
- "GL_EXT_vertex_array "
- "GL_3DFX_texture_compression_FXT1 "
- "GL_APPLE_packed_pixels "
- "GL_ATI_draw_buffers "
- "GL_ATI_texture_env_combine3 "
- "GL_ATI_texture_mirror_once "
- "GL_HP_occlusion_test "
- "GL_IBM_texture_mirrored_repeat "
- "GL_INGR_blend_func_separate "
- "GL_MESA_pack_invert "
- "GL_MESA_ycbcr_texture "
- "GL_NV_blend_square "
- "GL_NV_depth_clamp "
- "GL_NV_fog_distance "
- "GL_NV_fragment_program "
- "GL_NV_fragment_program_option "
- "GL_NV_fragment_program2 "
- "GL_NV_light_max_exponent "
- "GL_NV_multisample_filter_hint "
- "GL_NV_point_sprite "
- "GL_NV_texgen_reflection "
- "GL_NV_texture_compression_vtc "
- "GL_NV_texture_env_combine4 "
- "GL_NV_texture_expand_normal "
- "GL_NV_texture_rectangle "
- "GL_NV_vertex_program "
- "GL_NV_vertex_program1_1 "
- "GL_NV_vertex_program2 "
- "GL_NV_vertex_program2_option "
- "GL_NV_vertex_program3 "
- "GL_OES_compressed_paletted_texture "
- "GL_SGI_color_matrix "
- "GL_SGI_color_table "
- "GL_SGIS_generate_mipmap "
- "GL_SGIS_multisample "
- "GL_SGIS_point_parameters "
- "GL_SGIS_texture_border_clamp "
- "GL_SGIS_texture_edge_clamp "
- "GL_SGIS_texture_lod "
- "GL_SGIX_depth_texture "
- "GL_SGIX_shadow "
- "GL_SGIX_shadow_ambient "
- "GL_SUN_slice_accum "
- ;
-
-/*
-** We have made the simplifying assuption that the same extensions are
-** supported across all screens in a multi-screen system.
-*/
-static char GLXServerVendorName[] = "SGI";
-unsigned glxMajorVersion = SERVER_GLX_MAJOR_VERSION;
-unsigned glxMinorVersion = SERVER_GLX_MINOR_VERSION;
-static char GLXServerExtensions[] =
- "GLX_ARB_multisample "
- "GLX_EXT_visual_info "
- "GLX_EXT_visual_rating "
- "GLX_EXT_import_context "
- "GLX_EXT_texture_from_pixmap "
- "GLX_OML_swap_method "
- "GLX_SGI_make_current_read "
-#ifndef __APPLE__
- "GLX_SGIS_multisample "
-#endif
- "GLX_SGIX_fbconfig "
- "GLX_SGIX_pbuffer "
- "GLX_MESA_copy_sub_buffer "
- "GLX_INTEL_swap_event"
- ;
-
-static Bool
-glxCloseScreen (int index, ScreenPtr pScreen)
-{
- __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
-
- pScreen->CloseScreen = pGlxScreen->CloseScreen;
-
- pGlxScreen->destroy(pGlxScreen);
-
- return pScreen->CloseScreen(index, pScreen);
-}
-
-__GLXscreen *
-glxGetScreen(ScreenPtr pScreen)
-{
- return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey);
-}
-
-_X_EXPORT void GlxSetVisualConfigs(int nconfigs,
- void *configs, void **privates)
-{
- /* We keep this stub around for the DDX drivers that still
- * call it. */
-}
-
-GLint glxConvertToXVisualType(int visualType)
-{
- static const int x_visual_types[] = {
- TrueColor, DirectColor,
- PseudoColor, StaticColor,
- GrayScale, StaticGray
- };
-
- return ( (unsigned) (visualType - GLX_TRUE_COLOR) < 6 )
- ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1;
-}
-
-/* This code inspired by composite/compinit.c. We could move this to
- * mi/ and share it with composite.*/
-
-static VisualPtr
-AddScreenVisuals(ScreenPtr pScreen, int count, int d)
-{
- int i;
- DepthPtr depth;
-
- depth = NULL;
- for (i = 0; i < pScreen->numDepths; i++) {
- if (pScreen->allowedDepths[i].depth == d) {
- depth = &pScreen->allowedDepths[i];
- break;
- }
- }
- if (depth == NULL)
- return NULL;
-
- if (ResizeVisualArray(pScreen, count, depth) == FALSE)
- return NULL;
-
- /* Return a pointer to the first of the added visuals. */
- return pScreen->visuals + pScreen->numVisuals - count;
-}
-
-static int
-findFirstSet(unsigned int v)
-{
- int i;
-
- for (i = 0; i < 32; i++)
- if (v & (1 << i))
- return i;
-
- return -1;
-}
-
-static void
-initGlxVisual(VisualPtr visual, __GLXconfig *config)
-{
- int maxBits;
- maxBits = max(config->redBits, max(config->greenBits, config->blueBits));
-
- config->visualID = visual->vid;
- visual->class = glxConvertToXVisualType(config->visualType);
- visual->bitsPerRGBValue = maxBits;
- visual->ColormapEntries = 1 << maxBits;
- visual->nplanes = config->redBits + config->greenBits + config->blueBits;
-
- visual->redMask = config->redMask;
- visual->greenMask = config->greenMask;
- visual->blueMask = config->blueMask;
- visual->offsetRed = findFirstSet(config->redMask);
- visual->offsetGreen = findFirstSet(config->greenMask);
- visual->offsetBlue = findFirstSet(config->blueMask);
-}
-
-static __GLXconfig *
-pickFBConfig(__GLXscreen *pGlxScreen, VisualPtr visual)
-{
- __GLXconfig *best = NULL, *config;
- int best_score = 0;
-
- for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
- int score = 0;
-
- if (config->redMask != visual->redMask ||
- config->greenMask != visual->greenMask ||
- config->blueMask != visual->blueMask)
- continue;
- if (config->visualRating != GLX_NONE)
- continue;
- if (glxConvertToXVisualType(config->visualType) != visual->class)
- continue;
- /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */
- if (visual->nplanes == 32 && config->rgbBits != 32)
- continue;
- /* Can't use the same FBconfig for multiple X visuals. I think. */
- if (config->visualID != 0)
- continue;
-
- if (config->doubleBufferMode > 0)
- score += 8;
- if (config->depthBits > 0)
- score += 4;
- if (config->stencilBits > 0)
- score += 2;
- if (config->alphaBits > 0)
- score++;
-
- if (score > best_score) {
- best = config;
- best_score = score;
- }
- }
-
- return best;
-}
-
-void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
-{
- __GLXconfig *m;
- __GLXconfig *config;
- int i;
-
- if (!dixRegisterPrivateKey(&glxScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
- return;
-
- pGlxScreen->pScreen = pScreen;
- pGlxScreen->GLextensions = strdup(GLServerExtensions);
- pGlxScreen->GLXvendor = strdup(GLXServerVendorName);
- pGlxScreen->GLXextensions = strdup(GLXServerExtensions);
-
- /* All GLX providers must support all of the functionality required for at
- * least GLX 1.2. If the provider supports a higher version, the GLXminor
- * version can be changed in the provider's screen-probe routine. For
- * most providers, the screen-probe routine is the caller of this
- * function.
- */
- pGlxScreen->GLXmajor = 1;
- pGlxScreen->GLXminor = 2;
-
- pGlxScreen->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = glxCloseScreen;
-
- i = 0;
- for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
- m->fbconfigID = FakeClientID(0);
- m->visualID = 0;
- i++;
- }
- pGlxScreen->numFBConfigs = i;
-
- pGlxScreen->visuals =
- calloc(pGlxScreen->numFBConfigs, sizeof (__GLXconfig *));
-
- /* First, try to choose featureful FBconfigs for the existing X visuals.
- * Note that if multiple X visuals end up with the same FBconfig being
- * chosen, the later X visuals don't get GLX visuals (because we want to
- * prioritize the root visual being GLX).
- */
- for (i = 0; i < pScreen->numVisuals; i++) {
- VisualPtr visual = &pScreen->visuals[i];
-
- config = pickFBConfig(pGlxScreen, visual);
- if (config) {
- pGlxScreen->visuals[pGlxScreen->numVisuals++] = config;
- config->visualID = visual->vid;
- }
- }
-
- /* Then, add new visuals corresponding to all FBconfigs that didn't have
- * an existing, appropriate visual.
- */
- for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
- int depth;
-
- VisualPtr visual;
-
- if (config->visualID != 0)
- continue;
-
- /* Only count RGB bits and not alpha, as we're not trying to create
- * visuals for compositing (that's what the 32-bit composite visual
- * set up above is for.
- */
- depth = config->redBits + config->greenBits + config->blueBits;
-
- /* Make sure that our FBconfig's depth can actually be displayed
- * (corresponds to an existing visual).
- */
- for (i = 0; i < pScreen->numVisuals; i++) {
- if (depth == pScreen->visuals[i].nplanes)
- break;
- }
- if (i == pScreen->numVisuals)
- continue;
-
- /* Create a new X visual for our FBconfig. */
- visual = AddScreenVisuals(pScreen, 1, depth);
- if (visual == NULL)
- continue;
-
- pGlxScreen->visuals[pGlxScreen->numVisuals++] = config;
- initGlxVisual(visual, config);
- }
-
- dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen);
-}
-
-void __glXScreenDestroy(__GLXscreen *screen)
-{
- free(screen->GLXvendor);
- free(screen->GLXextensions);
- free(screen->GLextensions);
-}
+/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <GL/glxtokens.h> +#include <string.h> +#include <windowstr.h> +#include <os.h> +#include <colormapst.h> + +#include "privates.h" +#include "glxserver.h" +#include "glxutil.h" +#include "glxext.h" +#include "protocol-versions.h" + +static DevPrivateKeyRec glxScreenPrivateKeyRec; +#define glxScreenPrivateKey (&glxScreenPrivateKeyRec) + +const char GLServerVersion[] = "1.4"; +static const char GLServerExtensions[] = + "GL_ARB_depth_texture " + "GL_ARB_draw_buffers " + "GL_ARB_fragment_program " + "GL_ARB_fragment_program_shadow " + "GL_ARB_imaging " + "GL_ARB_multisample " + "GL_ARB_multitexture " + "GL_ARB_occlusion_query " + "GL_ARB_point_parameters " + "GL_ARB_point_sprite " + "GL_ARB_shadow " + "GL_ARB_shadow_ambient " + "GL_ARB_texture_border_clamp " + "GL_ARB_texture_compression " + "GL_ARB_texture_cube_map " + "GL_ARB_texture_env_add " + "GL_ARB_texture_env_combine " + "GL_ARB_texture_env_crossbar " + "GL_ARB_texture_env_dot3 " + "GL_ARB_texture_mirrored_repeat " + "GL_ARB_texture_non_power_of_two " + "GL_ARB_transpose_matrix " + "GL_ARB_vertex_program " + "GL_ARB_window_pos " + "GL_EXT_abgr " + "GL_EXT_bgra " + "GL_EXT_blend_color " + "GL_EXT_blend_equation_separate " + "GL_EXT_blend_func_separate " + "GL_EXT_blend_logic_op " + "GL_EXT_blend_minmax " + "GL_EXT_blend_subtract " + "GL_EXT_clip_volume_hint " + "GL_EXT_copy_texture " + "GL_EXT_draw_range_elements " + "GL_EXT_fog_coord " + "GL_EXT_framebuffer_object " + "GL_EXT_multi_draw_arrays " + "GL_EXT_packed_pixels " + "GL_EXT_paletted_texture " + "GL_EXT_point_parameters " + "GL_EXT_polygon_offset " + "GL_EXT_rescale_normal " + "GL_EXT_secondary_color " + "GL_EXT_separate_specular_color " + "GL_EXT_shadow_funcs " + "GL_EXT_shared_texture_palette " + "GL_EXT_stencil_two_side " + "GL_EXT_stencil_wrap " + "GL_EXT_subtexture " + "GL_EXT_texture " + "GL_EXT_texture3D " + "GL_EXT_texture_compression_dxt1 " + "GL_EXT_texture_compression_s3tc " + "GL_EXT_texture_edge_clamp " + "GL_EXT_texture_env_add " + "GL_EXT_texture_env_combine " + "GL_EXT_texture_env_dot3 " + "GL_EXT_texture_filter_anisotropic " + "GL_EXT_texture_lod " + "GL_EXT_texture_lod_bias " + "GL_EXT_texture_mirror_clamp " + "GL_EXT_texture_object " + "GL_EXT_texture_rectangle " + "GL_EXT_vertex_array " + "GL_3DFX_texture_compression_FXT1 " + "GL_APPLE_packed_pixels " + "GL_ATI_draw_buffers " + "GL_ATI_texture_env_combine3 " + "GL_ATI_texture_mirror_once " + "GL_HP_occlusion_test " + "GL_IBM_texture_mirrored_repeat " + "GL_INGR_blend_func_separate " + "GL_MESA_pack_invert " + "GL_MESA_ycbcr_texture " + "GL_NV_blend_square " + "GL_NV_depth_clamp " + "GL_NV_fog_distance " + "GL_NV_fragment_program " + "GL_NV_fragment_program_option " + "GL_NV_fragment_program2 " + "GL_NV_light_max_exponent " + "GL_NV_multisample_filter_hint " + "GL_NV_point_sprite " + "GL_NV_texgen_reflection " + "GL_NV_texture_compression_vtc " + "GL_NV_texture_env_combine4 " + "GL_NV_texture_expand_normal " + "GL_NV_texture_rectangle " + "GL_NV_vertex_program " + "GL_NV_vertex_program1_1 " + "GL_NV_vertex_program2 " + "GL_NV_vertex_program2_option " + "GL_NV_vertex_program3 " + "GL_OES_compressed_paletted_texture " + "GL_SGI_color_matrix " + "GL_SGI_color_table " + "GL_SGIS_generate_mipmap " + "GL_SGIS_multisample " + "GL_SGIS_point_parameters " + "GL_SGIS_texture_border_clamp " + "GL_SGIS_texture_edge_clamp " + "GL_SGIS_texture_lod " + "GL_SGIX_depth_texture " + "GL_SGIX_shadow " + "GL_SGIX_shadow_ambient " + "GL_SUN_slice_accum " + ; + +/* +** We have made the simplifying assuption that the same extensions are +** supported across all screens in a multi-screen system. +*/ +static char GLXServerVendorName[] = "SGI"; +unsigned glxMajorVersion = SERVER_GLX_MAJOR_VERSION; +unsigned glxMinorVersion = SERVER_GLX_MINOR_VERSION; +static char GLXServerExtensions[] = + "GLX_ARB_multisample " + "GLX_EXT_visual_info " + "GLX_EXT_visual_rating " + "GLX_EXT_import_context " + "GLX_EXT_texture_from_pixmap " + "GLX_OML_swap_method " + "GLX_SGI_make_current_read " +#ifndef __APPLE__ + "GLX_SGIS_multisample " +#endif + "GLX_SGIX_fbconfig " + "GLX_SGIX_pbuffer " + "GLX_MESA_copy_sub_buffer " + "GLX_INTEL_swap_event" + ; + +static Bool +glxCloseScreen (int index, ScreenPtr pScreen) +{ + __GLXscreen *pGlxScreen = glxGetScreen(pScreen); + + pScreen->CloseScreen = pGlxScreen->CloseScreen; + + pGlxScreen->destroy(pGlxScreen); + + return pScreen->CloseScreen(index, pScreen); +} + +__GLXscreen * +glxGetScreen(ScreenPtr pScreen) +{ + return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey); +} + +_X_EXPORT void GlxSetVisualConfigs(int nconfigs, + void *configs, void **privates) +{ + /* We keep this stub around for the DDX drivers that still + * call it. */ +} + +GLint glxConvertToXVisualType(int visualType) +{ + static const int x_visual_types[] = { + TrueColor, DirectColor, + PseudoColor, StaticColor, + GrayScale, StaticGray + }; + + return ( (unsigned) (visualType - GLX_TRUE_COLOR) < 6 ) + ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1; +} + +/* This code inspired by composite/compinit.c. We could move this to + * mi/ and share it with composite.*/ + +static VisualPtr +AddScreenVisuals(ScreenPtr pScreen, int count, int d) +{ + int i; + DepthPtr depth; + + depth = NULL; + for (i = 0; i < pScreen->numDepths; i++) { + if (pScreen->allowedDepths[i].depth == d) { + depth = &pScreen->allowedDepths[i]; + break; + } + } + if (depth == NULL) + return NULL; + + if (ResizeVisualArray(pScreen, count, depth) == FALSE) + return NULL; + + /* Return a pointer to the first of the added visuals. */ + return pScreen->visuals + pScreen->numVisuals - count; +} + +static int +findFirstSet(unsigned int v) +{ + int i; + + for (i = 0; i < 32; i++) + if (v & (1 << i)) + return i; + + return -1; +} + +static void +initGlxVisual(VisualPtr visual, __GLXconfig *config) +{ + int maxBits; + maxBits = max(config->redBits, max(config->greenBits, config->blueBits)); + + config->visualID = visual->vid; + visual->class = glxConvertToXVisualType(config->visualType); + visual->bitsPerRGBValue = maxBits; + visual->ColormapEntries = 1 << maxBits; + visual->nplanes = config->redBits + config->greenBits + config->blueBits; + + visual->redMask = config->redMask; + visual->greenMask = config->greenMask; + visual->blueMask = config->blueMask; + visual->offsetRed = findFirstSet(config->redMask); + visual->offsetGreen = findFirstSet(config->greenMask); + visual->offsetBlue = findFirstSet(config->blueMask); +} + +static __GLXconfig * +pickFBConfig(__GLXscreen *pGlxScreen, VisualPtr visual) +{ + __GLXconfig *best = NULL, *config; + int best_score = 0; + + for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { + int score = 0; + + if (config->redMask != visual->redMask || + config->greenMask != visual->greenMask || + config->blueMask != visual->blueMask) + continue; + if (config->visualRating != GLX_NONE) + continue; + if (glxConvertToXVisualType(config->visualType) != visual->class) + continue; + /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */ + if (visual->nplanes == 32 && config->rgbBits != 32) + continue; + /* Can't use the same FBconfig for multiple X visuals. I think. */ + if (config->visualID != 0) + continue; + + if (config->doubleBufferMode > 0) + score += 8; + if (config->depthBits > 0) + score += 4; + if (config->stencilBits > 0) + score += 2; + if (config->alphaBits > 0) + score++; + + if (score > best_score) { + best = config; + best_score = score; + } + } + + return best; +} + +void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) +{ + __GLXconfig *m; + __GLXconfig *config; + int i; + + if (!dixRegisterPrivateKey(&glxScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) + return; + + pGlxScreen->pScreen = pScreen; + pGlxScreen->GLextensions = strdup(GLServerExtensions); + pGlxScreen->GLXvendor = strdup(GLXServerVendorName); + pGlxScreen->GLXextensions = strdup(GLXServerExtensions); + + /* All GLX providers must support all of the functionality required for at + * least GLX 1.2. If the provider supports a higher version, the GLXminor + * version can be changed in the provider's screen-probe routine. For + * most providers, the screen-probe routine is the caller of this + * function. + */ + pGlxScreen->GLXmajor = 1; + pGlxScreen->GLXminor = 2; + + pGlxScreen->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = glxCloseScreen; + + i = 0; + for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) { + m->fbconfigID = FakeClientID(0); + m->visualID = 0; + i++; + } + pGlxScreen->numFBConfigs = i; + + pGlxScreen->visuals = + calloc(pGlxScreen->numFBConfigs, sizeof (__GLXconfig *)); + + /* First, try to choose featureful FBconfigs for the existing X visuals. + * Note that if multiple X visuals end up with the same FBconfig being + * chosen, the later X visuals don't get GLX visuals (because we want to + * prioritize the root visual being GLX). + */ + for (i = 0; i < pScreen->numVisuals; i++) { + VisualPtr visual = &pScreen->visuals[i]; + + config = pickFBConfig(pGlxScreen, visual); + if (config) { + pGlxScreen->visuals[pGlxScreen->numVisuals++] = config; + config->visualID = visual->vid; + } + } + + /* Then, add new visuals corresponding to all FBconfigs that didn't have + * an existing, appropriate visual. + */ + for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { + int depth; + + VisualPtr visual; + + if (config->visualID != 0) + continue; + + /* Only count RGB bits and not alpha, as we're not trying to create + * visuals for compositing (that's what the 32-bit composite visual + * set up above is for. + */ + depth = config->redBits + config->greenBits + config->blueBits; + + /* Make sure that our FBconfig's depth can actually be displayed + * (corresponds to an existing visual). + */ + for (i = 0; i < pScreen->numVisuals; i++) { + if (depth == pScreen->visuals[i].nplanes) + break; + } + /* if it can't, fix up the fbconfig to not advertise window support */ + if (i == pScreen->numVisuals) + config->drawableType &= ~(GLX_WINDOW_BIT); + + /* fbconfig must support window drawables */ + if (!(config->drawableType & GLX_WINDOW_BIT)) { + config->visualID = 0; + continue; + } + + /* Create a new X visual for our FBconfig. */ + visual = AddScreenVisuals(pScreen, 1, depth); + if (visual == NULL) + continue; + + pGlxScreen->visuals[pGlxScreen->numVisuals++] = config; + initGlxVisual(visual, config); + } + + dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen); +} + +void __glXScreenDestroy(__GLXscreen *screen) +{ + free(screen->GLXvendor); + free(screen->GLXextensions); + free(screen->GLextensions); +} diff --git a/xorg-server/hw/dmx/config/xdmxconfig.c b/xorg-server/hw/dmx/config/xdmxconfig.c index c67077aec..2de7f2b85 100644 --- a/xorg-server/hw/dmx/config/xdmxconfig.c +++ b/xorg-server/hw/dmx/config/xdmxconfig.c @@ -877,8 +877,8 @@ int main(int argc, char **argv) Widget parent, menubox, bottombox, databox, canvasbox; Widget filebutton, helpbutton; Widget filemenu, openbutton, savebutton, quitbutton; - Widget helpmenu, aboutbutton, aboutbox, abouttext, aboutok; - Widget quitbox, quittext, quitok, quitcan; + Widget helpmenu, aboutbutton, aboutbox, aboutok; + Widget quitbox, quitok, quitcan; Widget ncbutton; Widget canbutton; Widget ecbox, ecokbutton, eccanbutton; @@ -1096,7 +1096,7 @@ int main(int argc, char **argv) toplevel, NULL); aboutbox = XtVaCreateManagedWidget("aboutbox", boxWidgetClass, aboutpopup, NULL); - abouttext = XtVaCreateManagedWidget("abouttext", labelWidgetClass, + XtVaCreateManagedWidget("abouttext", labelWidgetClass, aboutbox, XtNlabel, DMX_INFO, NULL); @@ -1108,7 +1108,7 @@ int main(int argc, char **argv) toplevel, NULL); quitbox = XtVaCreateManagedWidget("quitbox", boxWidgetClass, quitpopup, NULL); - quittext = XtVaCreateManagedWidget("quittext", labelWidgetClass, + XtVaCreateManagedWidget("quittext", labelWidgetClass, quitbox, XtNlabel, "Changes to the configuration\n" diff --git a/xorg-server/hw/dmx/examples/xbell.c b/xorg-server/hw/dmx/examples/xbell.c index f3e3be1b8..79419d324 100644 --- a/xorg-server/hw/dmx/examples/xbell.c +++ b/xorg-server/hw/dmx/examples/xbell.c @@ -71,7 +71,6 @@ int main(int argc, char **argv) XKeyboardControl kc; XKeyboardState ks; unsigned long vm; - int percent; if (argc != 5) { printf("Usage: xbell percent baseVolume pitch duration\n"); @@ -81,7 +80,7 @@ int main(int argc, char **argv) vm = (KBBellPercent | KBBellPitch | KBBellDuration); - percent = atoi(argv[1]); + kc.key_click_percent = atoi(argv[1]); kc.bell_percent = atoi(argv[2]); kc.bell_pitch = atoi(argv[3]); kc.bell_duration = atoi(argv[4]); diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am index f1a759a27..e3ef14fc1 100644 --- a/xorg-server/hw/xfree86/Makefile.am +++ b/xorg-server/hw/xfree86/Makefile.am @@ -38,18 +38,18 @@ DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \ utils doc man bin_PROGRAMS = Xorg -Xorg_SOURCES = xorg.c +nodist_Xorg_SOURCES = sdksyms.c AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@ -INCLUDES = @XORG_INCS@ +INCLUDES = $(XORG_INCS) -I$(srcdir)/parser -I$(top_srcdir)/miext/cw \ + -I$(srcdir)/ddc -I$(srcdir)/i2c -I$(srcdir)/modes -I$(srcdir)/ramdac -noinst_LTLIBRARIES = libxorg.la -libxorg_la_SOURCES = libxorg.c -libxorg_la_LIBADD = \ +LOCAL_LIBS = \ + $(MAIN_LIB) \ $(XSERVER_LIBS) \ loader/libloader.la \ - os-support/libxorgos.la \ common/libcommon.la \ + os-support/libxorgos.la \ parser/libxf86config_internal.la \ dixmods/libdixmods.la \ modes/libxf86modes.la \ @@ -57,31 +57,21 @@ libxorg_la_LIBADD = \ ddc/libddc.la \ i2c/libi2c.la \ dixmods/libxorgxkb.la \ + $(XORG_LIBS) \ $(top_builddir)/mi/libmi.la \ - $(top_builddir)/os/libos.la \ - @XORG_LIBS@ - -libxorg_la_DEPENDENCIES = $(libxorg_la_LIBADD) - -libxorg.c xorg.c: - touch $@ - -DISTCLEANFILES = libxorg.c xorg.c - -Xorg_DEPENDENCIES = libxorg.la -Xorg_LDADD = $(MAIN_LIB) libxorg.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) + $(top_builddir)/os/libos.la +Xorg_LDADD = \ + $(LOCAL_LIBS) \ + $(XORG_SYS_LIBS) \ + $(XSERVER_SYS_LIBS) +Xorg_DEPENDENCIES = $(LOCAL_LIBS) Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) BUILT_SOURCES = xorg.conf.example -DISTCLEANFILES += xorg.conf.example +DISTCLEANFILES = xorg.conf.example EXTRA_DIST = xorgconf.cpp -if SPECIAL_DTRACE_OBJECTS -# Re-add dtrace object code that gets lost when building static libraries -Xorg_LDADD += $(XSERVER_LIBS) -endif - if SOLARIS_ASM_INLINE # Needs to be built before any files are compiled when using Sun compilers # so in*/out* inline definitions are properly processed. @@ -116,3 +106,12 @@ xorg.conf.example: xorgconf.cpp relink: $(AM_V_at)rm -f Xorg && $(MAKE) Xorg + +CLEANFILES = sdksyms.c sdksyms.dep +EXTRA_DIST += sdksyms.sh + +sdksyms.dep sdksyms.c: sdksyms.sh + CPP='$(CPP)' AWK='$(AWK)' $(srcdir)/sdksyms.sh $(top_srcdir) $(CFLAGS) $(AM_CFLAGS) $(INCLUDES) + +SDKSYMS_DEP = sdksyms.dep +include $(SDKSYMS_DEP) diff --git a/xorg-server/hw/xfree86/dri2/dri2.h b/xorg-server/hw/xfree86/dri2/dri2.h index afe2083de..2a41ead5b 100644 --- a/xorg-server/hw/xfree86/dri2/dri2.h +++ b/xorg-server/hw/xfree86/dri2/dri2.h @@ -1,287 +1,287 @@ -/*
- * Copyright © 2007 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Soft-
- * ware"), 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 Soft-
- * ware 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 MERCHANTABIL-
- * ITY, 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 CONSE-
- * QUENTIAL 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 PERFOR-
- * MANCE 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.
- *
- * Authors:
- * Kristian Høgsberg (krh@redhat.com)
- */
-
-#ifndef _DRI2_H_
-#define _DRI2_H_
-
-#include <X11/extensions/dri2tokens.h>
-
-/* Version 2 structure (with format at the end) */
-typedef struct {
- unsigned int attachment;
- unsigned int name;
- unsigned int pitch;
- unsigned int cpp;
- unsigned int flags;
- unsigned int format;
- void *driverPrivate;
-} DRI2BufferRec, *DRI2BufferPtr;
-
-extern CARD8 dri2_major; /* version of DRI2 supported by DDX */
-extern CARD8 dri2_minor;
-
-typedef DRI2BufferRec DRI2Buffer2Rec, *DRI2Buffer2Ptr;
-typedef void (*DRI2SwapEventPtr)(ClientPtr client, void *data, int type,
- CARD64 ust, CARD64 msc, CARD64 sbc);
-
-
-typedef DRI2BufferPtr (*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw,
- unsigned int *attachments,
- int count);
-typedef void (*DRI2DestroyBuffersProcPtr)(DrawablePtr pDraw,
- DRI2BufferPtr buffers,
- int count);
-typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
- RegionPtr pRegion,
- DRI2BufferPtr pDestBuffer,
- DRI2BufferPtr pSrcBuffer);
-typedef void (*DRI2WaitProcPtr)(WindowPtr pWin,
- unsigned int sequence);
-typedef int (*DRI2AuthMagicProcPtr)(int fd, uint32_t magic);
-
-/**
- * Schedule a buffer swap
- *
- * This callback is used to support glXSwapBuffers and the OML_sync_control
- * extension (see it for a description of the params).
- *
- * Drivers should queue an event for the frame count that satisfies the
- * parameters passed in. If the event is in the future (i.e. the conditions
- * aren't currently satisfied), the server may block the client at the next
- * GLX request using DRI2WaitSwap. When the event arrives, drivers should call
- * \c DRI2SwapComplete, which will handle waking the client and returning
- * the appropriate data.
- *
- * The DDX is responsible for doing a flip, exchange, or blit of the swap
- * when the corresponding event arrives. The \c DRI2CanFlip and
- * \c DRI2CanExchange functions can be used as helpers for this purpose.
- *
- * \param client client pointer (used for block/unblock)
- * \param pDraw drawable whose count we want
- * \param pDestBuffer current front buffer
- * \param pSrcBuffer current back buffer
- * \param target_msc frame count to wait for
- * \param divisor divisor for condition equation
- * \param remainder remainder for division equation
- * \param func function to call when the swap completes
- * \param data data for the callback \p func.
- */
-typedef int (*DRI2ScheduleSwapProcPtr)(ClientPtr client,
- DrawablePtr pDraw,
- DRI2BufferPtr pDestBuffer,
- DRI2BufferPtr pSrcBuffer,
- CARD64 *target_msc,
- CARD64 divisor,
- CARD64 remainder,
- DRI2SwapEventPtr func,
- void *data);
-typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
- unsigned int attachment,
- unsigned int format);
-typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
- DRI2BufferPtr buffer);
-/**
- * Get current media stamp counter values
- *
- * This callback is used to support the SGI_video_sync and OML_sync_control
- * extensions.
- *
- * Drivers should return the current frame counter and the timestamp from
- * when the returned frame count was last incremented.
- *
- * The count should correspond to the screen where the drawable is currently
- * visible. If the drawable isn't visible (e.g. redirected), the server
- * should return BadDrawable to the client, pending GLX spec updates to
- * define this behavior.
- *
- * \param pDraw drawable whose count we want
- * \param ust timestamp from when the count was last incremented.
- * \param mst current frame count
- */
-typedef int (*DRI2GetMSCProcPtr)(DrawablePtr pDraw, CARD64 *ust,
- CARD64 *msc);
-/**
- * Schedule a frame count related wait
- *
- * This callback is used to support the SGI_video_sync and OML_sync_control
- * extensions. See those specifications for details on how to handle
- * the divisor and remainder parameters.
- *
- * Drivers should queue an event for the frame count that satisfies the
- * parameters passed in. If the event is in the future (i.e. the conditions
- * aren't currently satisfied), the driver should block the client using
- * \c DRI2BlockClient. When the event arrives, drivers should call
- * \c DRI2WaitMSCComplete, which will handle waking the client and returning
- * the appropriate data.
- *
- * \param client client pointer (used for block/unblock)
- * \param pDraw drawable whose count we want
- * \param target_msc frame count to wait for
- * \param divisor divisor for condition equation
- * \param remainder remainder for division equation
- */
-typedef int (*DRI2ScheduleWaitMSCProcPtr)(ClientPtr client,
- DrawablePtr pDraw,
- CARD64 target_msc,
- CARD64 divisor,
- CARD64 remainder);
-
-typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw,
- void *data);
-
-/**
- * Version of the DRI2InfoRec structure defined in this header
- */
-#define DRI2INFOREC_VERSION 5
-
-typedef struct {
- unsigned int version; /**< Version of this struct */
- int fd;
- const char *driverName;
- const char *deviceName;
-
- DRI2CreateBufferProcPtr CreateBuffer;
- DRI2DestroyBufferProcPtr DestroyBuffer;
- DRI2CopyRegionProcPtr CopyRegion;
- DRI2WaitProcPtr Wait;
-
- /* added in version 4 */
-
- DRI2ScheduleSwapProcPtr ScheduleSwap;
- DRI2GetMSCProcPtr GetMSC;
- DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
-
- /* number of drivers in the driverNames array */
- unsigned int numDrivers;
- /* array of driver names, indexed by DRI2Driver* driver types */
- /* a name of NULL means that driver is not supported */
- const char * const *driverNames;
-
- /* added in version 5 */
-
- DRI2AuthMagicProcPtr AuthMagic;
-} DRI2InfoRec, *DRI2InfoPtr;
-
-extern _X_EXPORT int DRI2EventBase;
-
-extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen,
- DRI2InfoPtr info);
-
-extern _X_EXPORT void DRI2CloseScreen(ScreenPtr pScreen);
-
-extern _X_EXPORT Bool DRI2HasSwapControl(ScreenPtr pScreen);
-
-extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen,
- unsigned int driverType,
- int *fd,
- const char **driverName,
- const char **deviceName);
-
-extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, uint32_t magic);
-
-extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
- DrawablePtr pDraw,
- XID id,
- DRI2InvalidateProcPtr invalidate,
- void *priv);
-
-extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw);
-
-extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw,
- int *width,
- int *height,
- unsigned int *attachments,
- int count,
- int *out_count);
-
-extern _X_EXPORT int DRI2CopyRegion(DrawablePtr pDraw,
- RegionPtr pRegion,
- unsigned int dest,
- unsigned int src);
-
-/**
- * Determine the major and minor version of the DRI2 extension.
- *
- * Provides a mechanism to other modules (e.g., 2D drivers) to determine the
- * version of the DRI2 extension. While it is possible to peek directly at
- * the \c XF86ModuleData from a layered module, such a module will fail to
- * load (due to an unresolved symbol) if the DRI2 extension is not loaded.
- *
- * \param major Location to store the major verion of the DRI2 extension
- * \param minor Location to store the minor verion of the DRI2 extension
- *
- * \note
- * This interface was added some time after the initial release of the DRI2
- * module. Layered modules that wish to use this interface must first test
- * its existance by calling \c xf86LoaderCheckSymbol.
- */
-extern _X_EXPORT void DRI2Version(int *major, int *minor);
-
-extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
- int *width, int *height, unsigned int *attachments, int count,
- int *out_count);
-
-extern _X_EXPORT void DRI2SwapInterval(DrawablePtr pDrawable, int interval);
-extern _X_EXPORT int DRI2SwapBuffers(ClientPtr client, DrawablePtr pDrawable,
- CARD64 target_msc, CARD64 divisor,
- CARD64 remainder, CARD64 *swap_target,
- DRI2SwapEventPtr func, void *data);
-extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable);
-
-extern _X_EXPORT int DRI2GetMSC(DrawablePtr pDrawable, CARD64 *ust,
- CARD64 *msc, CARD64 *sbc);
-extern _X_EXPORT int DRI2WaitMSC(ClientPtr client, DrawablePtr pDrawable,
- CARD64 target_msc, CARD64 divisor,
- CARD64 remainder);
-extern _X_EXPORT int ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust,
- CARD64 msc, CARD64 sbc);
-extern _X_EXPORT int DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw,
- CARD64 target_sbc);
-extern _X_EXPORT Bool DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw);
-
-extern _X_EXPORT Bool DRI2CanFlip(DrawablePtr pDraw);
-
-extern _X_EXPORT Bool DRI2CanExchange(DrawablePtr pDraw);
-
-/* Note: use *only* for MSC related waits */
-extern _X_EXPORT void DRI2BlockClient(ClientPtr client, DrawablePtr pDraw);
-
-extern _X_EXPORT void DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw,
- int frame, unsigned int tv_sec,
- unsigned int tv_usec, int type,
- DRI2SwapEventPtr swap_complete,
- void *swap_data);
-extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw,
- int frame, unsigned int tv_sec,
- unsigned int tv_usec);
-
-#endif
+/* + * Copyright © 2007 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), 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 Soft- + * ware 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 MERCHANTABIL- + * ITY, 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 CONSE- + * QUENTIAL 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 PERFOR- + * MANCE 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. + * + * Authors: + * Kristian Høgsberg (krh@redhat.com) + */ + +#ifndef _DRI2_H_ +#define _DRI2_H_ + +#include <X11/extensions/dri2tokens.h> + +/* Version 2 structure (with format at the end) */ +typedef struct { + unsigned int attachment; + unsigned int name; + unsigned int pitch; + unsigned int cpp; + unsigned int flags; + unsigned int format; + void *driverPrivate; +} DRI2BufferRec, *DRI2BufferPtr; + +extern CARD8 dri2_major; /* version of DRI2 supported by DDX */ +extern CARD8 dri2_minor; + +typedef DRI2BufferRec DRI2Buffer2Rec, *DRI2Buffer2Ptr; +typedef void (*DRI2SwapEventPtr)(ClientPtr client, void *data, int type, + CARD64 ust, CARD64 msc, CARD32 sbc); + + +typedef DRI2BufferPtr (*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw, + unsigned int *attachments, + int count); +typedef void (*DRI2DestroyBuffersProcPtr)(DrawablePtr pDraw, + DRI2BufferPtr buffers, + int count); +typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw, + RegionPtr pRegion, + DRI2BufferPtr pDestBuffer, + DRI2BufferPtr pSrcBuffer); +typedef void (*DRI2WaitProcPtr)(WindowPtr pWin, + unsigned int sequence); +typedef int (*DRI2AuthMagicProcPtr)(int fd, uint32_t magic); + +/** + * Schedule a buffer swap + * + * This callback is used to support glXSwapBuffers and the OML_sync_control + * extension (see it for a description of the params). + * + * Drivers should queue an event for the frame count that satisfies the + * parameters passed in. If the event is in the future (i.e. the conditions + * aren't currently satisfied), the server may block the client at the next + * GLX request using DRI2WaitSwap. When the event arrives, drivers should call + * \c DRI2SwapComplete, which will handle waking the client and returning + * the appropriate data. + * + * The DDX is responsible for doing a flip, exchange, or blit of the swap + * when the corresponding event arrives. The \c DRI2CanFlip and + * \c DRI2CanExchange functions can be used as helpers for this purpose. + * + * \param client client pointer (used for block/unblock) + * \param pDraw drawable whose count we want + * \param pDestBuffer current front buffer + * \param pSrcBuffer current back buffer + * \param target_msc frame count to wait for + * \param divisor divisor for condition equation + * \param remainder remainder for division equation + * \param func function to call when the swap completes + * \param data data for the callback \p func. + */ +typedef int (*DRI2ScheduleSwapProcPtr)(ClientPtr client, + DrawablePtr pDraw, + DRI2BufferPtr pDestBuffer, + DRI2BufferPtr pSrcBuffer, + CARD64 *target_msc, + CARD64 divisor, + CARD64 remainder, + DRI2SwapEventPtr func, + void *data); +typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw, + unsigned int attachment, + unsigned int format); +typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw, + DRI2BufferPtr buffer); +/** + * Get current media stamp counter values + * + * This callback is used to support the SGI_video_sync and OML_sync_control + * extensions. + * + * Drivers should return the current frame counter and the timestamp from + * when the returned frame count was last incremented. + * + * The count should correspond to the screen where the drawable is currently + * visible. If the drawable isn't visible (e.g. redirected), the server + * should return BadDrawable to the client, pending GLX spec updates to + * define this behavior. + * + * \param pDraw drawable whose count we want + * \param ust timestamp from when the count was last incremented. + * \param mst current frame count + */ +typedef int (*DRI2GetMSCProcPtr)(DrawablePtr pDraw, CARD64 *ust, + CARD64 *msc); +/** + * Schedule a frame count related wait + * + * This callback is used to support the SGI_video_sync and OML_sync_control + * extensions. See those specifications for details on how to handle + * the divisor and remainder parameters. + * + * Drivers should queue an event for the frame count that satisfies the + * parameters passed in. If the event is in the future (i.e. the conditions + * aren't currently satisfied), the driver should block the client using + * \c DRI2BlockClient. When the event arrives, drivers should call + * \c DRI2WaitMSCComplete, which will handle waking the client and returning + * the appropriate data. + * + * \param client client pointer (used for block/unblock) + * \param pDraw drawable whose count we want + * \param target_msc frame count to wait for + * \param divisor divisor for condition equation + * \param remainder remainder for division equation + */ +typedef int (*DRI2ScheduleWaitMSCProcPtr)(ClientPtr client, + DrawablePtr pDraw, + CARD64 target_msc, + CARD64 divisor, + CARD64 remainder); + +typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw, + void *data); + +/** + * Version of the DRI2InfoRec structure defined in this header + */ +#define DRI2INFOREC_VERSION 5 + +typedef struct { + unsigned int version; /**< Version of this struct */ + int fd; + const char *driverName; + const char *deviceName; + + DRI2CreateBufferProcPtr CreateBuffer; + DRI2DestroyBufferProcPtr DestroyBuffer; + DRI2CopyRegionProcPtr CopyRegion; + DRI2WaitProcPtr Wait; + + /* added in version 4 */ + + DRI2ScheduleSwapProcPtr ScheduleSwap; + DRI2GetMSCProcPtr GetMSC; + DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC; + + /* number of drivers in the driverNames array */ + unsigned int numDrivers; + /* array of driver names, indexed by DRI2Driver* driver types */ + /* a name of NULL means that driver is not supported */ + const char * const *driverNames; + + /* added in version 5 */ + + DRI2AuthMagicProcPtr AuthMagic; +} DRI2InfoRec, *DRI2InfoPtr; + +extern _X_EXPORT int DRI2EventBase; + +extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, + DRI2InfoPtr info); + +extern _X_EXPORT void DRI2CloseScreen(ScreenPtr pScreen); + +extern _X_EXPORT Bool DRI2HasSwapControl(ScreenPtr pScreen); + +extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen, + unsigned int driverType, + int *fd, + const char **driverName, + const char **deviceName); + +extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, uint32_t magic); + +extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client, + DrawablePtr pDraw, + XID id, + DRI2InvalidateProcPtr invalidate, + void *priv); + +extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw); + +extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw, + int *width, + int *height, + unsigned int *attachments, + int count, + int *out_count); + +extern _X_EXPORT int DRI2CopyRegion(DrawablePtr pDraw, + RegionPtr pRegion, + unsigned int dest, + unsigned int src); + +/** + * Determine the major and minor version of the DRI2 extension. + * + * Provides a mechanism to other modules (e.g., 2D drivers) to determine the + * version of the DRI2 extension. While it is possible to peek directly at + * the \c XF86ModuleData from a layered module, such a module will fail to + * load (due to an unresolved symbol) if the DRI2 extension is not loaded. + * + * \param major Location to store the major verion of the DRI2 extension + * \param minor Location to store the minor verion of the DRI2 extension + * + * \note + * This interface was added some time after the initial release of the DRI2 + * module. Layered modules that wish to use this interface must first test + * its existance by calling \c xf86LoaderCheckSymbol. + */ +extern _X_EXPORT void DRI2Version(int *major, int *minor); + +extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw, + int *width, int *height, unsigned int *attachments, int count, + int *out_count); + +extern _X_EXPORT void DRI2SwapInterval(DrawablePtr pDrawable, int interval); +extern _X_EXPORT int DRI2SwapBuffers(ClientPtr client, DrawablePtr pDrawable, + CARD64 target_msc, CARD64 divisor, + CARD64 remainder, CARD64 *swap_target, + DRI2SwapEventPtr func, void *data); +extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable); + +extern _X_EXPORT int DRI2GetMSC(DrawablePtr pDrawable, CARD64 *ust, + CARD64 *msc, CARD64 *sbc); +extern _X_EXPORT int DRI2WaitMSC(ClientPtr client, DrawablePtr pDrawable, + CARD64 target_msc, CARD64 divisor, + CARD64 remainder); +extern _X_EXPORT int ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, + CARD64 msc, CARD64 sbc); +extern _X_EXPORT int DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, + CARD64 target_sbc); +extern _X_EXPORT Bool DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw); + +extern _X_EXPORT Bool DRI2CanFlip(DrawablePtr pDraw); + +extern _X_EXPORT Bool DRI2CanExchange(DrawablePtr pDraw); + +/* Note: use *only* for MSC related waits */ +extern _X_EXPORT void DRI2BlockClient(ClientPtr client, DrawablePtr pDraw); + +extern _X_EXPORT void DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, + int frame, unsigned int tv_sec, + unsigned int tv_usec, int type, + DRI2SwapEventPtr swap_complete, + void *swap_data); +extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, + int frame, unsigned int tv_sec, + unsigned int tv_usec); + +#endif diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c index 6853fab9e..552b26b7c 100644 --- a/xorg-server/hw/xfree86/dri2/dri2ext.c +++ b/xorg-server/hw/xfree86/dri2/dri2ext.c @@ -1,650 +1,649 @@ -/*
- * Copyright © 2008 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Soft-
- * ware"), 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 Soft-
- * ware 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 MERCHANTABIL-
- * ITY, 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 CONSE-
- * QUENTIAL 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 PERFOR-
- * MANCE 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.
- *
- * Authors:
- * Kristian Høgsberg (krh@redhat.com)
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/extensions/dri2proto.h>
-#include <X11/extensions/xfixeswire.h>
-#include "dixstruct.h"
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "extnsionst.h"
-#include "xfixes.h"
-#include "dri2.h"
-#include "protocol-versions.h"
-
-/* The only xf86 include */
-#include "xf86Module.h"
-
-static ExtensionEntry *dri2Extension;
-
-static Bool
-validDrawable(ClientPtr client, XID drawable, Mask access_mode,
- DrawablePtr *pDrawable, int *status)
-{
- *status = dixLookupDrawable(pDrawable, drawable, client,
- M_DRAWABLE_WINDOW | M_DRAWABLE_PIXMAP,
- access_mode);
- if (*status != Success) {
- client->errorValue = drawable;
- return FALSE;
- }
-
- return TRUE;
-}
-
-static int
-ProcDRI2QueryVersion(ClientPtr client)
-{
- REQUEST(xDRI2QueryVersionReq);
- xDRI2QueryVersionReply rep;
- int n;
-
- if (client->swapped)
- swaps(&stuff->length, n);
-
- REQUEST_SIZE_MATCH(xDRI2QueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = dri2_major;
- rep.minorVersion = dri2_minor;
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.majorVersion, n);
- swapl(&rep.minorVersion, n);
- }
-
- WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep);
-
- return Success;
-}
-
-static int
-ProcDRI2Connect(ClientPtr client)
-{
- REQUEST(xDRI2ConnectReq);
- xDRI2ConnectReply rep;
- DrawablePtr pDraw;
- int fd, status;
- const char *driverName;
- const char *deviceName;
-
- REQUEST_SIZE_MATCH(xDRI2ConnectReq);
- if (!validDrawable(client, stuff->window, DixGetAttrAccess,
- &pDraw, &status))
- return status;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.driverNameLength = 0;
- rep.deviceNameLength = 0;
-
- if (!DRI2Connect(pDraw->pScreen,
- stuff->driverType, &fd, &driverName, &deviceName))
- goto fail;
-
- rep.driverNameLength = strlen(driverName);
- rep.deviceNameLength = strlen(deviceName);
- rep.length = (rep.driverNameLength + 3) / 4 +
- (rep.deviceNameLength + 3) / 4;
-
- fail:
- WriteToClient(client, sizeof(xDRI2ConnectReply), &rep);
- WriteToClient(client, rep.driverNameLength, driverName);
- WriteToClient(client, rep.deviceNameLength, deviceName);
-
- return Success;
-}
-
-static int
-ProcDRI2Authenticate(ClientPtr client)
-{
- REQUEST(xDRI2AuthenticateReq);
- xDRI2AuthenticateReply rep;
- DrawablePtr pDraw;
- int status;
-
- REQUEST_SIZE_MATCH(xDRI2AuthenticateReq);
- if (!validDrawable(client, stuff->window, DixGetAttrAccess,
- &pDraw, &status))
- return status;
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic);
- WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
-
- return Success;
-}
-
-static void
-DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv)
-{
- xDRI2InvalidateBuffers event;
- ClientPtr client = priv;
-
- event.type = DRI2EventBase + DRI2_InvalidateBuffers;
- event.drawable = pDraw->id;
-
- WriteEventsToClient(client, 1, (xEvent *)&event);
-}
-
-static int
-ProcDRI2CreateDrawable(ClientPtr client)
-{
- REQUEST(xDRI2CreateDrawableReq);
- DrawablePtr pDrawable;
- int status;
-
- REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq);
-
- if (!validDrawable(client, stuff->drawable, DixAddAccess,
- &pDrawable, &status))
- return status;
-
- status = DRI2CreateDrawable(client, pDrawable, stuff->drawable,
- DRI2InvalidateBuffersEvent, client);
- if (status != Success)
- return status;
-
- return Success;
-}
-
-static int
-ProcDRI2DestroyDrawable(ClientPtr client)
-{
- REQUEST(xDRI2DestroyDrawableReq);
- DrawablePtr pDrawable;
- int status;
-
- REQUEST_SIZE_MATCH(xDRI2DestroyDrawableReq);
- if (!validDrawable(client, stuff->drawable, DixRemoveAccess,
- &pDrawable, &status))
- return status;
-
- return Success;
-}
-
-
-static int
-send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
- DRI2BufferPtr *buffers, int count, int width, int height)
-{
- xDRI2GetBuffersReply rep;
- int skip = 0;
- int i;
-
- if (buffers == NULL)
- return BadAlloc;
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- for (i = 0; i < count; i++) {
- /* Do not send the real front buffer of a window to the client.
- */
- if (buffers[i]->attachment == DRI2BufferFrontLeft) {
- skip++;
- continue;
- }
- }
- }
-
- rep.type = X_Reply;
- rep.length = (count - skip) * sizeof(xDRI2Buffer) / 4;
- rep.sequenceNumber = client->sequence;
- rep.width = width;
- rep.height = height;
- rep.count = count - skip;
- WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep);
-
- for (i = 0; i < count; i++) {
- xDRI2Buffer buffer;
-
- /* Do not send the real front buffer of a window to the client.
- */
- if ((pDrawable->type == DRAWABLE_WINDOW)
- && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
- continue;
- }
-
- buffer.attachment = buffers[i]->attachment;
- buffer.name = buffers[i]->name;
- buffer.pitch = buffers[i]->pitch;
- buffer.cpp = buffers[i]->cpp;
- buffer.flags = buffers[i]->flags;
- WriteToClient(client, sizeof(xDRI2Buffer), &buffer);
- }
- return Success;
-}
-
-
-static int
-ProcDRI2GetBuffers(ClientPtr client)
-{
- REQUEST(xDRI2GetBuffersReq);
- DrawablePtr pDrawable;
- DRI2BufferPtr *buffers;
- int status, width, height, count;
- unsigned int *attachments;
-
- REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
- if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess,
- &pDrawable, &status))
- return status;
-
- if (DRI2ThrottleClient(client, pDrawable))
- return Success;
-
- attachments = (unsigned int *) &stuff[1];
- buffers = DRI2GetBuffers(pDrawable, &width, &height,
- attachments, stuff->count, &count);
-
-
- return send_buffers_reply(client, pDrawable, buffers, count, width, height);
-
-}
-
-static int
-ProcDRI2GetBuffersWithFormat(ClientPtr client)
-{
- REQUEST(xDRI2GetBuffersReq);
- DrawablePtr pDrawable;
- DRI2BufferPtr *buffers;
- int status, width, height, count;
- unsigned int *attachments;
-
- REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4));
- if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess,
- &pDrawable, &status))
- return status;
-
- if (DRI2ThrottleClient(client, pDrawable))
- return Success;
-
- attachments = (unsigned int *) &stuff[1];
- buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
- attachments, stuff->count, &count);
-
- return send_buffers_reply(client, pDrawable, buffers, count, width, height);
-}
-
-static int
-ProcDRI2CopyRegion(ClientPtr client)
-{
- REQUEST(xDRI2CopyRegionReq);
- xDRI2CopyRegionReply rep;
- DrawablePtr pDrawable;
- int status;
- RegionPtr pRegion;
-
- REQUEST_SIZE_MATCH(xDRI2CopyRegionReq);
-
- if (!validDrawable(client, stuff->drawable, DixWriteAccess,
- &pDrawable, &status))
- return status;
-
- VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess);
-
- status = DRI2CopyRegion(pDrawable, pRegion, stuff->dest, stuff->src);
- if (status != Success)
- return status;
-
- /* CopyRegion needs to be a round trip to make sure the X server
- * queues the swap buffer rendering commands before the DRI client
- * continues rendering. The reply has a bitmask to signal the
- * presense of optional return values as well, but we're not using
- * that yet.
- */
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- WriteToClient(client, sizeof(xDRI2CopyRegionReply), &rep);
-
- return Success;
-}
-
-static void
-load_swap_reply(xDRI2SwapBuffersReply *rep, CARD64 sbc)
-{
- rep->swap_hi = sbc >> 32;
- rep->swap_lo = sbc & 0xffffffff;
-}
-
-static CARD64
-vals_to_card64(CARD32 lo, CARD32 hi)
-{
- return (CARD64)hi << 32 | lo;
-}
-
-static void
-DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc,
- CARD64 sbc)
-{
- xDRI2BufferSwapComplete event;
- DrawablePtr pDrawable = data;
-
- event.type = DRI2EventBase + DRI2_BufferSwapComplete;
- event.event_type = type;
- event.drawable = pDrawable->id;
- event.ust_hi = (CARD64)ust >> 32;
- event.ust_lo = ust & 0xffffffff;
- event.msc_hi = (CARD64)msc >> 32;
- event.msc_lo = msc & 0xffffffff;
- event.sbc_hi = (CARD64)sbc >> 32;
- event.sbc_lo = sbc & 0xffffffff;
-
- WriteEventsToClient(client, 1, (xEvent *)&event);
-}
-
-static int
-ProcDRI2SwapBuffers(ClientPtr client)
-{
- REQUEST(xDRI2SwapBuffersReq);
- xDRI2SwapBuffersReply rep;
- DrawablePtr pDrawable;
- CARD64 target_msc, divisor, remainder, swap_target;
- int status;
-
- REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq);
-
- if (!validDrawable(client, stuff->drawable,
- DixReadAccess | DixWriteAccess, &pDrawable, &status))
- return status;
-
- /*
- * Ensures an out of control client can't exhaust our swap queue, and
- * also orders swaps.
- */
- if (DRI2ThrottleClient(client, pDrawable))
- return Success;
-
- target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
- divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
- remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi);
-
- status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder,
- &swap_target, DRI2SwapEvent, pDrawable);
- if (status != Success)
- return BadDrawable;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- load_swap_reply(&rep, swap_target);
-
- WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep);
-
- return Success;
-}
-
-static void
-load_msc_reply(xDRI2MSCReply *rep, CARD64 ust, CARD64 msc, CARD64 sbc)
-{
- rep->ust_hi = ust >> 32;
- rep->ust_lo = ust & 0xffffffff;
- rep->msc_hi = msc >> 32;
- rep->msc_lo = msc & 0xffffffff;
- rep->sbc_hi = sbc >> 32;
- rep->sbc_lo = sbc & 0xffffffff;
-}
-
-static int
-ProcDRI2GetMSC(ClientPtr client)
-{
- REQUEST(xDRI2GetMSCReq);
- xDRI2MSCReply rep;
- DrawablePtr pDrawable;
- CARD64 ust, msc, sbc;
- int status;
-
- REQUEST_SIZE_MATCH(xDRI2GetMSCReq);
-
- if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
- &status))
- return status;
-
- status = DRI2GetMSC(pDrawable, &ust, &msc, &sbc);
- if (status != Success)
- return status;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- load_msc_reply(&rep, ust, msc, sbc);
-
- WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
-
- return Success;
-}
-
-static int
-ProcDRI2WaitMSC(ClientPtr client)
-{
- REQUEST(xDRI2WaitMSCReq);
- DrawablePtr pDrawable;
- CARD64 target, divisor, remainder;
- int status;
-
- /* FIXME: in restart case, client may be gone at this point */
-
- REQUEST_SIZE_MATCH(xDRI2WaitMSCReq);
-
- if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
- &status))
- return status;
-
- target = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
- divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
- remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi);
-
- status = DRI2WaitMSC(client, pDrawable, target, divisor, remainder);
- if (status != Success)
- return status;
-
- return Success;
-}
-
-int
-ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, CARD64 msc, CARD64 sbc)
-{
- xDRI2MSCReply rep;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- load_msc_reply(&rep, ust, msc, sbc);
-
- WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
-
- return Success;
-}
-
-static int
-ProcDRI2SwapInterval(ClientPtr client)
-{
- REQUEST(xDRI2SwapIntervalReq);
- DrawablePtr pDrawable;
- int status;
-
- /* FIXME: in restart case, client may be gone at this point */
-
- REQUEST_SIZE_MATCH(xDRI2SwapIntervalReq);
-
- if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess,
- &pDrawable, &status))
- return status;
-
- DRI2SwapInterval(pDrawable, stuff->interval);
-
- return Success;
-}
-
-static int
-ProcDRI2WaitSBC(ClientPtr client)
-{
- REQUEST(xDRI2WaitSBCReq);
- DrawablePtr pDrawable;
- CARD64 target;
- int status;
-
- REQUEST_SIZE_MATCH(xDRI2WaitSBCReq);
-
- if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
- &status))
- return status;
-
- target = vals_to_card64(stuff->target_sbc_lo, stuff->target_sbc_hi);
- status = DRI2WaitSBC(client, pDrawable, target);
-
- return status;
-}
-
-static int
-ProcDRI2Dispatch (ClientPtr client)
-{
- REQUEST(xReq);
-
- switch (stuff->data) {
- case X_DRI2QueryVersion:
- return ProcDRI2QueryVersion(client);
- }
-
- if (!LocalClient(client))
- return BadRequest;
-
- switch (stuff->data) {
- case X_DRI2Connect:
- return ProcDRI2Connect(client);
- case X_DRI2Authenticate:
- return ProcDRI2Authenticate(client);
- case X_DRI2CreateDrawable:
- return ProcDRI2CreateDrawable(client);
- case X_DRI2DestroyDrawable:
- return ProcDRI2DestroyDrawable(client);
- case X_DRI2GetBuffers:
- return ProcDRI2GetBuffers(client);
- case X_DRI2CopyRegion:
- return ProcDRI2CopyRegion(client);
- case X_DRI2GetBuffersWithFormat:
- return ProcDRI2GetBuffersWithFormat(client);
- case X_DRI2SwapBuffers:
- return ProcDRI2SwapBuffers(client);
- case X_DRI2GetMSC:
- return ProcDRI2GetMSC(client);
- case X_DRI2WaitMSC:
- return ProcDRI2WaitMSC(client);
- case X_DRI2WaitSBC:
- return ProcDRI2WaitSBC(client);
- case X_DRI2SwapInterval:
- return ProcDRI2SwapInterval(client);
- default:
- return BadRequest;
- }
-}
-
-static int
-SProcDRI2Connect(ClientPtr client)
-{
- REQUEST(xDRI2ConnectReq);
- xDRI2ConnectReply rep;
- int n;
-
- /* If the client is swapped, it's not local. Talk to the hand. */
-
- swaps(&stuff->length, n);
- if (sizeof(*stuff) / 4 != client->req_len)
- return BadLength;
-
- rep.sequenceNumber = client->sequence;
- swaps(&rep.sequenceNumber, n);
- rep.length = 0;
- rep.driverNameLength = 0;
- rep.deviceNameLength = 0;
-
- return Success;
-}
-
-static int
-SProcDRI2Dispatch (ClientPtr client)
-{
- REQUEST(xReq);
-
- /*
- * Only local clients are allowed DRI access, but remote clients
- * still need these requests to find out cleanly.
- */
- switch (stuff->data)
- {
- case X_DRI2QueryVersion:
- return ProcDRI2QueryVersion(client);
- case X_DRI2Connect:
- return SProcDRI2Connect(client);
- default:
- return BadRequest;
- }
-}
-
-int DRI2EventBase;
-
-static void
-DRI2ExtensionInit(void)
-{
- dri2Extension = AddExtension(DRI2_NAME,
- DRI2NumberEvents,
- DRI2NumberErrors,
- ProcDRI2Dispatch,
- SProcDRI2Dispatch,
- NULL,
- StandardMinorOpcode);
-
- DRI2EventBase = dri2Extension->eventBase;
-}
-
-extern Bool noDRI2Extension;
-
-_X_HIDDEN ExtensionModule dri2ExtensionModule = {
- DRI2ExtensionInit,
- DRI2_NAME,
- &noDRI2Extension,
- NULL,
- NULL
-};
+/* + * Copyright © 2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), 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 Soft- + * ware 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 MERCHANTABIL- + * ITY, 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 CONSE- + * QUENTIAL 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 PERFOR- + * MANCE 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. + * + * Authors: + * Kristian Høgsberg (krh@redhat.com) + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/extensions/dri2proto.h> +#include <X11/extensions/xfixeswire.h> +#include "dixstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "extnsionst.h" +#include "xfixes.h" +#include "dri2.h" +#include "protocol-versions.h" + +/* The only xf86 include */ +#include "xf86Module.h" + +static ExtensionEntry *dri2Extension; + +static Bool +validDrawable(ClientPtr client, XID drawable, Mask access_mode, + DrawablePtr *pDrawable, int *status) +{ + *status = dixLookupDrawable(pDrawable, drawable, client, + M_DRAWABLE_WINDOW | M_DRAWABLE_PIXMAP, + access_mode); + if (*status != Success) { + client->errorValue = drawable; + return FALSE; + } + + return TRUE; +} + +static int +ProcDRI2QueryVersion(ClientPtr client) +{ + REQUEST(xDRI2QueryVersionReq); + xDRI2QueryVersionReply rep; + int n; + + if (client->swapped) + swaps(&stuff->length, n); + + REQUEST_SIZE_MATCH(xDRI2QueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = dri2_major; + rep.minorVersion = dri2_minor; + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + + WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep); + + return Success; +} + +static int +ProcDRI2Connect(ClientPtr client) +{ + REQUEST(xDRI2ConnectReq); + xDRI2ConnectReply rep; + DrawablePtr pDraw; + int fd, status; + const char *driverName; + const char *deviceName; + + REQUEST_SIZE_MATCH(xDRI2ConnectReq); + if (!validDrawable(client, stuff->window, DixGetAttrAccess, + &pDraw, &status)) + return status; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.driverNameLength = 0; + rep.deviceNameLength = 0; + + if (!DRI2Connect(pDraw->pScreen, + stuff->driverType, &fd, &driverName, &deviceName)) + goto fail; + + rep.driverNameLength = strlen(driverName); + rep.deviceNameLength = strlen(deviceName); + rep.length = (rep.driverNameLength + 3) / 4 + + (rep.deviceNameLength + 3) / 4; + + fail: + WriteToClient(client, sizeof(xDRI2ConnectReply), &rep); + WriteToClient(client, rep.driverNameLength, driverName); + WriteToClient(client, rep.deviceNameLength, deviceName); + + return Success; +} + +static int +ProcDRI2Authenticate(ClientPtr client) +{ + REQUEST(xDRI2AuthenticateReq); + xDRI2AuthenticateReply rep; + DrawablePtr pDraw; + int status; + + REQUEST_SIZE_MATCH(xDRI2AuthenticateReq); + if (!validDrawable(client, stuff->window, DixGetAttrAccess, + &pDraw, &status)) + return status; + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic); + WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep); + + return Success; +} + +static void +DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv) +{ + xDRI2InvalidateBuffers event; + ClientPtr client = priv; + + event.type = DRI2EventBase + DRI2_InvalidateBuffers; + event.drawable = pDraw->id; + + WriteEventsToClient(client, 1, (xEvent *)&event); +} + +static int +ProcDRI2CreateDrawable(ClientPtr client) +{ + REQUEST(xDRI2CreateDrawableReq); + DrawablePtr pDrawable; + int status; + + REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq); + + if (!validDrawable(client, stuff->drawable, DixAddAccess, + &pDrawable, &status)) + return status; + + status = DRI2CreateDrawable(client, pDrawable, stuff->drawable, + DRI2InvalidateBuffersEvent, client); + if (status != Success) + return status; + + return Success; +} + +static int +ProcDRI2DestroyDrawable(ClientPtr client) +{ + REQUEST(xDRI2DestroyDrawableReq); + DrawablePtr pDrawable; + int status; + + REQUEST_SIZE_MATCH(xDRI2DestroyDrawableReq); + if (!validDrawable(client, stuff->drawable, DixRemoveAccess, + &pDrawable, &status)) + return status; + + return Success; +} + + +static int +send_buffers_reply(ClientPtr client, DrawablePtr pDrawable, + DRI2BufferPtr *buffers, int count, int width, int height) +{ + xDRI2GetBuffersReply rep; + int skip = 0; + int i; + + if (buffers == NULL) + return BadAlloc; + + if (pDrawable->type == DRAWABLE_WINDOW) { + for (i = 0; i < count; i++) { + /* Do not send the real front buffer of a window to the client. + */ + if (buffers[i]->attachment == DRI2BufferFrontLeft) { + skip++; + continue; + } + } + } + + rep.type = X_Reply; + rep.length = (count - skip) * sizeof(xDRI2Buffer) / 4; + rep.sequenceNumber = client->sequence; + rep.width = width; + rep.height = height; + rep.count = count - skip; + WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep); + + for (i = 0; i < count; i++) { + xDRI2Buffer buffer; + + /* Do not send the real front buffer of a window to the client. + */ + if ((pDrawable->type == DRAWABLE_WINDOW) + && (buffers[i]->attachment == DRI2BufferFrontLeft)) { + continue; + } + + buffer.attachment = buffers[i]->attachment; + buffer.name = buffers[i]->name; + buffer.pitch = buffers[i]->pitch; + buffer.cpp = buffers[i]->cpp; + buffer.flags = buffers[i]->flags; + WriteToClient(client, sizeof(xDRI2Buffer), &buffer); + } + return Success; +} + + +static int +ProcDRI2GetBuffers(ClientPtr client) +{ + REQUEST(xDRI2GetBuffersReq); + DrawablePtr pDrawable; + DRI2BufferPtr *buffers; + int status, width, height, count; + unsigned int *attachments; + + REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); + if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, + &pDrawable, &status)) + return status; + + if (DRI2ThrottleClient(client, pDrawable)) + return Success; + + attachments = (unsigned int *) &stuff[1]; + buffers = DRI2GetBuffers(pDrawable, &width, &height, + attachments, stuff->count, &count); + + + return send_buffers_reply(client, pDrawable, buffers, count, width, height); + +} + +static int +ProcDRI2GetBuffersWithFormat(ClientPtr client) +{ + REQUEST(xDRI2GetBuffersReq); + DrawablePtr pDrawable; + DRI2BufferPtr *buffers; + int status, width, height, count; + unsigned int *attachments; + + REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4)); + if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, + &pDrawable, &status)) + return status; + + if (DRI2ThrottleClient(client, pDrawable)) + return Success; + + attachments = (unsigned int *) &stuff[1]; + buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height, + attachments, stuff->count, &count); + + return send_buffers_reply(client, pDrawable, buffers, count, width, height); +} + +static int +ProcDRI2CopyRegion(ClientPtr client) +{ + REQUEST(xDRI2CopyRegionReq); + xDRI2CopyRegionReply rep; + DrawablePtr pDrawable; + int status; + RegionPtr pRegion; + + REQUEST_SIZE_MATCH(xDRI2CopyRegionReq); + + if (!validDrawable(client, stuff->drawable, DixWriteAccess, + &pDrawable, &status)) + return status; + + VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess); + + status = DRI2CopyRegion(pDrawable, pRegion, stuff->dest, stuff->src); + if (status != Success) + return status; + + /* CopyRegion needs to be a round trip to make sure the X server + * queues the swap buffer rendering commands before the DRI client + * continues rendering. The reply has a bitmask to signal the + * presense of optional return values as well, but we're not using + * that yet. + */ + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + WriteToClient(client, sizeof(xDRI2CopyRegionReply), &rep); + + return Success; +} + +static void +load_swap_reply(xDRI2SwapBuffersReply *rep, CARD64 sbc) +{ + rep->swap_hi = sbc >> 32; + rep->swap_lo = sbc & 0xffffffff; +} + +static CARD64 +vals_to_card64(CARD32 lo, CARD32 hi) +{ + return (CARD64)hi << 32 | lo; +} + +static void +DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc, + CARD32 sbc) +{ + xDRI2BufferSwapComplete2 event; + DrawablePtr pDrawable = data; + + event.type = DRI2EventBase + DRI2_BufferSwapComplete; + event.event_type = type; + event.drawable = pDrawable->id; + event.ust_hi = (CARD64)ust >> 32; + event.ust_lo = ust & 0xffffffff; + event.msc_hi = (CARD64)msc >> 32; + event.msc_lo = msc & 0xffffffff; + event.sbc = sbc; + + WriteEventsToClient(client, 1, (xEvent *)&event); +} + +static int +ProcDRI2SwapBuffers(ClientPtr client) +{ + REQUEST(xDRI2SwapBuffersReq); + xDRI2SwapBuffersReply rep; + DrawablePtr pDrawable; + CARD64 target_msc, divisor, remainder, swap_target; + int status; + + REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq); + + if (!validDrawable(client, stuff->drawable, + DixReadAccess | DixWriteAccess, &pDrawable, &status)) + return status; + + /* + * Ensures an out of control client can't exhaust our swap queue, and + * also orders swaps. + */ + if (DRI2ThrottleClient(client, pDrawable)) + return Success; + + target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi); + divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi); + remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi); + + status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder, + &swap_target, DRI2SwapEvent, pDrawable); + if (status != Success) + return BadDrawable; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + load_swap_reply(&rep, swap_target); + + WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep); + + return Success; +} + +static void +load_msc_reply(xDRI2MSCReply *rep, CARD64 ust, CARD64 msc, CARD64 sbc) +{ + rep->ust_hi = ust >> 32; + rep->ust_lo = ust & 0xffffffff; + rep->msc_hi = msc >> 32; + rep->msc_lo = msc & 0xffffffff; + rep->sbc_hi = sbc >> 32; + rep->sbc_lo = sbc & 0xffffffff; +} + +static int +ProcDRI2GetMSC(ClientPtr client) +{ + REQUEST(xDRI2GetMSCReq); + xDRI2MSCReply rep; + DrawablePtr pDrawable; + CARD64 ust, msc, sbc; + int status; + + REQUEST_SIZE_MATCH(xDRI2GetMSCReq); + + if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable, + &status)) + return status; + + status = DRI2GetMSC(pDrawable, &ust, &msc, &sbc); + if (status != Success) + return status; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + load_msc_reply(&rep, ust, msc, sbc); + + WriteToClient(client, sizeof(xDRI2MSCReply), &rep); + + return Success; +} + +static int +ProcDRI2WaitMSC(ClientPtr client) +{ + REQUEST(xDRI2WaitMSCReq); + DrawablePtr pDrawable; + CARD64 target, divisor, remainder; + int status; + + /* FIXME: in restart case, client may be gone at this point */ + + REQUEST_SIZE_MATCH(xDRI2WaitMSCReq); + + if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable, + &status)) + return status; + + target = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi); + divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi); + remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi); + + status = DRI2WaitMSC(client, pDrawable, target, divisor, remainder); + if (status != Success) + return status; + + return Success; +} + +int +ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, CARD64 msc, CARD64 sbc) +{ + xDRI2MSCReply rep; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + load_msc_reply(&rep, ust, msc, sbc); + + WriteToClient(client, sizeof(xDRI2MSCReply), &rep); + + return Success; +} + +static int +ProcDRI2SwapInterval(ClientPtr client) +{ + REQUEST(xDRI2SwapIntervalReq); + DrawablePtr pDrawable; + int status; + + /* FIXME: in restart case, client may be gone at this point */ + + REQUEST_SIZE_MATCH(xDRI2SwapIntervalReq); + + if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, + &pDrawable, &status)) + return status; + + DRI2SwapInterval(pDrawable, stuff->interval); + + return Success; +} + +static int +ProcDRI2WaitSBC(ClientPtr client) +{ + REQUEST(xDRI2WaitSBCReq); + DrawablePtr pDrawable; + CARD64 target; + int status; + + REQUEST_SIZE_MATCH(xDRI2WaitSBCReq); + + if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable, + &status)) + return status; + + target = vals_to_card64(stuff->target_sbc_lo, stuff->target_sbc_hi); + status = DRI2WaitSBC(client, pDrawable, target); + + return status; +} + +static int +ProcDRI2Dispatch (ClientPtr client) +{ + REQUEST(xReq); + + switch (stuff->data) { + case X_DRI2QueryVersion: + return ProcDRI2QueryVersion(client); + } + + if (!LocalClient(client)) + return BadRequest; + + switch (stuff->data) { + case X_DRI2Connect: + return ProcDRI2Connect(client); + case X_DRI2Authenticate: + return ProcDRI2Authenticate(client); + case X_DRI2CreateDrawable: + return ProcDRI2CreateDrawable(client); + case X_DRI2DestroyDrawable: + return ProcDRI2DestroyDrawable(client); + case X_DRI2GetBuffers: + return ProcDRI2GetBuffers(client); + case X_DRI2CopyRegion: + return ProcDRI2CopyRegion(client); + case X_DRI2GetBuffersWithFormat: + return ProcDRI2GetBuffersWithFormat(client); + case X_DRI2SwapBuffers: + return ProcDRI2SwapBuffers(client); + case X_DRI2GetMSC: + return ProcDRI2GetMSC(client); + case X_DRI2WaitMSC: + return ProcDRI2WaitMSC(client); + case X_DRI2WaitSBC: + return ProcDRI2WaitSBC(client); + case X_DRI2SwapInterval: + return ProcDRI2SwapInterval(client); + default: + return BadRequest; + } +} + +static int +SProcDRI2Connect(ClientPtr client) +{ + REQUEST(xDRI2ConnectReq); + xDRI2ConnectReply rep; + int n; + + /* If the client is swapped, it's not local. Talk to the hand. */ + + swaps(&stuff->length, n); + if (sizeof(*stuff) / 4 != client->req_len) + return BadLength; + + rep.sequenceNumber = client->sequence; + swaps(&rep.sequenceNumber, n); + rep.length = 0; + rep.driverNameLength = 0; + rep.deviceNameLength = 0; + + return Success; +} + +static int +SProcDRI2Dispatch (ClientPtr client) +{ + REQUEST(xReq); + + /* + * Only local clients are allowed DRI access, but remote clients + * still need these requests to find out cleanly. + */ + switch (stuff->data) + { + case X_DRI2QueryVersion: + return ProcDRI2QueryVersion(client); + case X_DRI2Connect: + return SProcDRI2Connect(client); + default: + return BadRequest; + } +} + +int DRI2EventBase; + +static void +DRI2ExtensionInit(void) +{ + dri2Extension = AddExtension(DRI2_NAME, + DRI2NumberEvents, + DRI2NumberErrors, + ProcDRI2Dispatch, + SProcDRI2Dispatch, + NULL, + StandardMinorOpcode); + + DRI2EventBase = dri2Extension->eventBase; +} + +extern Bool noDRI2Extension; + +_X_HIDDEN ExtensionModule dri2ExtensionModule = { + DRI2ExtensionInit, + DRI2_NAME, + &noDRI2Extension, + NULL, + NULL +}; diff --git a/xorg-server/hw/xfree86/loader/Makefile.am b/xorg-server/hw/xfree86/loader/Makefile.am index 0e5b304a4..ebe0c813a 100644 --- a/xorg-server/hw/xfree86/loader/Makefile.am +++ b/xorg-server/hw/xfree86/loader/Makefile.am @@ -9,11 +9,7 @@ AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) EXTRA_DIST = \ loader.h \ - loaderProcs.h \ - sdksyms.sh - -nodist_libloader_la_SOURCES = \ - sdksyms.c + loaderProcs.h libloader_la_SOURCES = \ loader.c \ @@ -23,11 +19,3 @@ libloader_la_SOURCES = \ os.c libloader_la_LIBADD = $(DLOPEN_LIBS) - -CLEANFILES = sdksyms.c sdksyms.dep - -sdksyms.dep sdksyms.c: sdksyms.sh $(top_builddir)/include/do-not-use-config.h - CPP='$(CPP)' AWK='$(AWK)' $(srcdir)/sdksyms.sh $(top_srcdir) $(AM_CFLAGS) $(CFLAGS) $(INCLUDES) - -SDKSYMS_DEP = sdksyms.dep -include $(SDKSYMS_DEP) diff --git a/xorg-server/hw/xfree86/os-support/Makefile.am b/xorg-server/hw/xfree86/os-support/Makefile.am index 3af4328ff..348b7ffec 100644 --- a/xorg-server/hw/xfree86/os-support/Makefile.am +++ b/xorg-server/hw/xfree86/os-support/Makefile.am @@ -9,18 +9,13 @@ EXTRA_DIST = int10Defines.h xf86OSpriv.h # as one library, otherwise libtool will actively defeat your attempts to # list them multiple times on the link line. noinst_LTLIBRARIES = libxorgos.la -libxorgos_la_SOURCES = xorgos.c +libxorgos_la_SOURCES = libxorgos_la_LIBADD = @XORG_OS_SUBDIR@/lib@XORG_OS_SUBDIR@.la \ bus/libbus.la \ misc/libmisc.la AM_CFLAGS = $(DIX_CFLAGS) -xorgos.c: - touch $@ - -DISTCLEANFILES = xorgos.c - # FIXME: These don't seem to be used anywhere EXTRA_DIST += \ shared/bios_devmem.c diff --git a/xorg-server/hw/xfree86/os-support/shared/posix_tty.c b/xorg-server/hw/xfree86/os-support/shared/posix_tty.c index 97860d0f2..fb8386022 100644 --- a/xorg-server/hw/xfree86/os-support/shared/posix_tty.c +++ b/xorg-server/hw/xfree86/os-support/shared/posix_tty.c @@ -1,655 +1,655 @@ -/*
- * Copyright 1993-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of the XFree86 Project shall
- * not be used in advertising or otherwise to promote the sale, use or other
- * dealings in this Software without prior written authorization from the
- * XFree86 Project.
- */
-/*
- *
- * Copyright (c) 1997 Metro Link Incorporated
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of the Metro Link shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from Metro Link.
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-
-static int
-GetBaud (int baudrate)
-{
-#ifdef B300
- if (baudrate == 300)
- return B300;
-#endif
-#ifdef B1200
- if (baudrate == 1200)
- return B1200;
-#endif
-#ifdef B2400
- if (baudrate == 2400)
- return B2400;
-#endif
-#ifdef B4800
- if (baudrate == 4800)
- return B4800;
-#endif
-#ifdef B9600
- if (baudrate == 9600)
- return B9600;
-#endif
-#ifdef B19200
- if (baudrate == 19200)
- return B19200;
-#endif
-#ifdef B38400
- if (baudrate == 38400)
- return B38400;
-#endif
-#ifdef B57600
- if (baudrate == 57600)
- return B57600;
-#endif
-#ifdef B115200
- if (baudrate == 115200)
- return B115200;
-#endif
-#ifdef B230400
- if (baudrate == 230400)
- return B230400;
-#endif
-#ifdef B460800
- if (baudrate == 460800)
- return B460800;
-#endif
- return 0;
-}
-
-int
-xf86OpenSerial (pointer options)
-{
- struct termios t;
- int fd, i;
- char *dev;
-
- dev = xf86SetStrOption (options, "Device", NULL);
- if (!dev)
- {
- xf86Msg (X_ERROR, "xf86OpenSerial: No Device specified.\n");
- return -1;
- }
-
- SYSCALL (fd = open (dev, O_RDWR | O_NONBLOCK));
- if (fd == -1)
- {
- xf86Msg (X_ERROR,
- "xf86OpenSerial: Cannot open device %s\n\t%s.\n",
- dev, strerror (errno));
- free(dev);
- return -1;
- }
-
- if (!isatty (fd))
- {
- /* Allow non-tty devices to be opened. */
- free(dev);
- return fd;
- }
-
- /* set up default port parameters */
- SYSCALL (tcgetattr (fd, &t));
- t.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR\
- |IGNCR|ICRNL|IXON);
- t.c_oflag &= ~OPOST;
- t.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
- t.c_cflag &= ~(CSIZE|PARENB);
- t.c_cflag |= CS8|CLOCAL;
-
- cfsetispeed (&t, B9600);
- cfsetospeed (&t, B9600);
- t.c_cc[VMIN] = 1;
- t.c_cc[VTIME] = 0;
-
- SYSCALL (tcsetattr (fd, TCSANOW, &t));
-
- if (xf86SetSerial (fd, options) == -1)
- {
- SYSCALL (close (fd));
- free(dev);
- return -1;
- }
-
- SYSCALL (i = fcntl (fd, F_GETFL, 0));
- if (i == -1)
- {
- SYSCALL (close (fd));
- free(dev);
- return -1;
- }
- i &= ~O_NONBLOCK;
- SYSCALL (i = fcntl (fd, F_SETFL, i));
- if (i == -1)
- {
- SYSCALL (close (fd));
- free(dev);
- return -1;
- }
- free(dev);
- return fd;
-}
-
-int
-xf86SetSerial (int fd, pointer options)
-{
- struct termios t;
- int val;
- const char *s;
- int baud, r;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
- SYSCALL (tcgetattr (fd, &t));
-
- if ((val = xf86SetIntOption (options, "BaudRate", 0)))
- {
- if ((baud = GetBaud (val)))
- {
- cfsetispeed (&t, baud);
- cfsetospeed (&t, baud);
- }
- else
- {
- xf86Msg (X_ERROR,
- "Invalid Option BaudRate value: %d\n", val);
- return -1;
- }
- }
-
- if ((val = xf86SetIntOption (options, "StopBits", 0)))
- {
- switch (val)
- {
- case 1:
- t.c_cflag &= ~(CSTOPB);
- break;
- case 2:
- t.c_cflag |= CSTOPB;
- break;
- default:
- xf86Msg (X_ERROR,
- "Invalid Option StopBits value: %d\n", val);
- return -1;
- break;
- }
- }
-
- if ((val = xf86SetIntOption (options, "DataBits", 0)))
- {
- switch (val)
- {
- case 5:
- t.c_cflag &= ~(CSIZE);
- t.c_cflag |= CS5;
- break;
- case 6:
- t.c_cflag &= ~(CSIZE);
- t.c_cflag |= CS6;
- break;
- case 7:
- t.c_cflag &= ~(CSIZE);
- t.c_cflag |= CS7;
- break;
- case 8:
- t.c_cflag &= ~(CSIZE);
- t.c_cflag |= CS8;
- break;
- default:
- xf86Msg (X_ERROR,
- "Invalid Option DataBits value: %d\n", val);
- return -1;
- break;
- }
- }
-
- if ((s = xf86SetStrOption (options, "Parity", NULL)))
- {
- if (xf86NameCmp (s, "Odd") == 0)
- {
- t.c_cflag |= PARENB | PARODD;
- }
- else if (xf86NameCmp (s, "Even") == 0)
- {
- t.c_cflag |= PARENB;
- t.c_cflag &= ~(PARODD);
- }
- else if (xf86NameCmp (s, "None") == 0)
- {
- t.c_cflag &= ~(PARENB);
- }
- else
- {
- xf86Msg (X_ERROR, "Invalid Option Parity value: %s\n",
- s);
- return -1;
- }
- }
-
- if ((val = xf86SetIntOption (options, "Vmin", -1)) != -1)
- {
- t.c_cc[VMIN] = val;
- }
- if ((val = xf86SetIntOption (options, "Vtime", -1)) != -1)
- {
- t.c_cc[VTIME] = val;
- }
-
- if ((s = xf86SetStrOption (options, "FlowControl", NULL)))
- {
- xf86MarkOptionUsedByName (options, "FlowControl");
- if (xf86NameCmp (s, "Xoff") == 0)
- {
- t.c_iflag |= IXOFF;
- }
- else if (xf86NameCmp (s, "Xon") == 0)
- {
- t.c_iflag |= IXON;
- }
- else if (xf86NameCmp (s, "XonXoff") == 0)
- {
- t.c_iflag |= IXON|IXOFF;
- }
- else if (xf86NameCmp (s, "None") == 0)
- {
- t.c_iflag &= ~(IXON | IXOFF);
- }
- else
- {
- xf86Msg (X_ERROR,
- "Invalid Option FlowControl value: %s\n", s);
- return -1;
- }
- }
-
- if ((xf86SetBoolOption (options, "ClearDTR", FALSE)))
- {
-#ifdef CLEARDTR_SUPPORT
-# if defined(TIOCMBIC)
- val = TIOCM_DTR;
- SYSCALL (ioctl(fd, TIOCMBIC, &val));
-# else
- SYSCALL (ioctl(fd, TIOCCDTR, NULL));
-# endif
-#else
- xf86Msg (X_WARNING,
- "Option ClearDTR not supported on this OS\n");
- return -1;
-#endif
- xf86MarkOptionUsedByName (options, "ClearDTR");
- }
-
- if ((xf86SetBoolOption (options, "ClearRTS", FALSE)))
- {
- xf86Msg (X_WARNING,
- "Option ClearRTS not supported on this OS\n");
- return -1;
- xf86MarkOptionUsedByName (options, "ClearRTS");
- }
-
- SYSCALL (r = tcsetattr (fd, TCSANOW, &t));
- return r;
-}
-
-int
-xf86SetSerialSpeed (int fd, int speed)
-{
- struct termios t;
- int baud, r;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
- SYSCALL (tcgetattr (fd, &t));
-
- if ((baud = GetBaud (speed)))
- {
- cfsetispeed (&t, baud);
- cfsetospeed (&t, baud);
- }
- else
- {
- xf86Msg (X_ERROR,
- "Invalid Option BaudRate value: %d\n", speed);
- return -1;
- }
-
- SYSCALL (r = tcsetattr (fd, TCSANOW, &t));
- return r;
-}
-
-int
-xf86ReadSerial (int fd, void *buf, int count)
-{
- int r;
- int i;
-
- SYSCALL (r = read (fd, buf, count));
- DebugF("ReadingSerial: 0x%x",
- (unsigned char)*(((unsigned char *)buf)));
- for (i = 1; i < r; i++)
- DebugF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i));
- DebugF("\n");
- return r;
-}
-
-int
-xf86WriteSerial (int fd, const void *buf, int count)
-{
- int r;
- int i;
-
- DebugF("WritingSerial: 0x%x",(unsigned char)*(((unsigned char *)buf)));
- for (i = 1; i < count; i++)
- ErrorF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i));
- DebugF("\n");
- SYSCALL (r = write (fd, buf, count));
- return r;
-}
-
-int
-xf86CloseSerial (int fd)
-{
- int r;
-
- SYSCALL (r = close (fd));
- return r;
-}
-
-int
-xf86WaitForInput (int fd, int timeout)
-{
- fd_set readfds;
- struct timeval to;
- int r;
-
- FD_ZERO(&readfds);
-
- if (fd >= 0) {
- FD_SET(fd, &readfds);
- }
-
- to.tv_sec = timeout / 1000000;
- to.tv_usec = timeout % 1000000;
-
- if (fd >= 0) {
- SYSCALL (r = select (FD_SETSIZE, &readfds, NULL, NULL, &to));
- }
- else {
- SYSCALL (r = select (FD_SETSIZE, NULL, NULL, NULL, &to));
- }
- xf86ErrorFVerb (9,"select returned %d\n", r);
- return r;
-}
-
-int
-xf86SerialSendBreak (int fd, int duration)
-{
- int r;
-
- SYSCALL (r = tcsendbreak (fd, duration));
- return r;
-
-}
-
-int
-xf86FlushInput(int fd)
-{
- fd_set fds;
- struct timeval timeout;
- char c[4];
-
- DebugF("FlushingSerial\n");
- if (tcflush(fd, TCIFLUSH) == 0)
- return 0;
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- while (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) > 0) {
- if (read(fd, &c, sizeof(c)) < 1)
- return 0;
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- }
- return 0;
-}
-
-static struct states {
- int xf;
- int os;
-} modemStates[] = {
-#ifdef TIOCM_LE
- { XF86_M_LE, TIOCM_LE },
-#endif
-#ifdef TIOCM_DTR
- { XF86_M_DTR, TIOCM_DTR },
-#endif
-#ifdef TIOCM_RTS
- { XF86_M_RTS, TIOCM_RTS },
-#endif
-#ifdef TIOCM_ST
- { XF86_M_ST, TIOCM_ST },
-#endif
-#ifdef TIOCM_SR
- { XF86_M_SR, TIOCM_SR },
-#endif
-#ifdef TIOCM_CTS
- { XF86_M_CTS, TIOCM_CTS },
-#endif
-#ifdef TIOCM_CAR
- { XF86_M_CAR, TIOCM_CAR },
-#elif defined(TIOCM_CD)
- { XF86_M_CAR, TIOCM_CD },
-#endif
-#ifdef TIOCM_RNG
- { XF86_M_RNG, TIOCM_RNG },
-#elif defined(TIOCM_RI)
- { XF86_M_CAR, TIOCM_RI },
-#endif
-#ifdef TIOCM_DSR
- { XF86_M_DSR, TIOCM_DSR },
-#endif
-};
-
-static int numStates = sizeof(modemStates) / sizeof(modemStates[0]);
-
-static int
-xf2osState(int state)
-{
- int i;
- int ret = 0;
-
- for (i = 0; i < numStates; i++)
- if (state & modemStates[i].xf)
- ret |= modemStates[i].os;
- return ret;
-}
-
-static int
-os2xfState(int state)
-{
- int i;
- int ret = 0;
-
- for (i = 0; i < numStates; i++)
- if (state & modemStates[i].os)
- ret |= modemStates[i].xf;
- return ret;
-}
-
-static int
-getOsStateMask(void)
-{
- int i;
- int ret = 0;
- for (i = 0; i < numStates; i++)
- ret |= modemStates[i].os;
- return ret;
-}
-
-static int osStateMask = 0;
-
-int
-xf86SetSerialModemState(int fd, int state)
-{
- int ret;
- int s;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
-#ifndef TIOCMGET
- return -1;
-#else
- if (!osStateMask)
- osStateMask = getOsStateMask();
-
- state = xf2osState(state);
- SYSCALL((ret = ioctl(fd, TIOCMGET, &s)));
- if (ret < 0)
- return -1;
- s &= ~osStateMask;
- s |= state;
- SYSCALL((ret = ioctl(fd, TIOCMSET, &s)));
- if (ret < 0)
- return -1;
- else
- return 0;
-#endif
-}
-
-int
-xf86GetSerialModemState(int fd)
-{
- int ret;
- int s;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
-#ifndef TIOCMGET
- return -1;
-#else
- SYSCALL((ret = ioctl(fd, TIOCMGET, &s)));
- if (ret < 0)
- return -1;
- return os2xfState(s);
-#endif
-}
-
-int
-xf86SerialModemSetBits(int fd, int bits)
-{
- int ret;
- int s;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
-#ifndef TIOCMGET
- return -1;
-#else
- s = xf2osState(bits);
- SYSCALL((ret = ioctl(fd, TIOCMBIS, &s)));
- return ret;
-#endif
-}
-
-int
-xf86SerialModemClearBits(int fd, int bits)
-{
- int ret;
- int s;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
-#ifndef TIOCMGET
- return -1;
-#else
- s = xf2osState(bits);
- SYSCALL((ret = ioctl(fd, TIOCMBIC, &s)));
- return ret;
-#endif
-}
+/* + * Copyright 1993-2003 by The XFree86 Project, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +static int +GetBaud (int baudrate) +{ +#ifdef B300 + if (baudrate == 300) + return B300; +#endif +#ifdef B1200 + if (baudrate == 1200) + return B1200; +#endif +#ifdef B2400 + if (baudrate == 2400) + return B2400; +#endif +#ifdef B4800 + if (baudrate == 4800) + return B4800; +#endif +#ifdef B9600 + if (baudrate == 9600) + return B9600; +#endif +#ifdef B19200 + if (baudrate == 19200) + return B19200; +#endif +#ifdef B38400 + if (baudrate == 38400) + return B38400; +#endif +#ifdef B57600 + if (baudrate == 57600) + return B57600; +#endif +#ifdef B115200 + if (baudrate == 115200) + return B115200; +#endif +#ifdef B230400 + if (baudrate == 230400) + return B230400; +#endif +#ifdef B460800 + if (baudrate == 460800) + return B460800; +#endif + return 0; +} + +int +xf86OpenSerial (pointer options) +{ + struct termios t; + int fd, i; + char *dev; + + dev = xf86SetStrOption (options, "Device", NULL); + if (!dev) + { + xf86Msg (X_ERROR, "xf86OpenSerial: No Device specified.\n"); + return -1; + } + + SYSCALL (fd = open (dev, O_RDWR | O_NONBLOCK)); + if (fd == -1) + { + xf86Msg (X_ERROR, + "xf86OpenSerial: Cannot open device %s\n\t%s.\n", + dev, strerror (errno)); + free(dev); + return -1; + } + + if (!isatty (fd)) + { + /* Allow non-tty devices to be opened. */ + free(dev); + return fd; + } + + /* set up default port parameters */ + SYSCALL (tcgetattr (fd, &t)); + t.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR\ + |IGNCR|ICRNL|IXON); + t.c_oflag &= ~OPOST; + t.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + t.c_cflag &= ~(CSIZE|PARENB); + t.c_cflag |= CS8|CLOCAL; + + cfsetispeed (&t, B9600); + cfsetospeed (&t, B9600); + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; + + SYSCALL (tcsetattr (fd, TCSANOW, &t)); + + if (xf86SetSerial (fd, options) == -1) + { + SYSCALL (close (fd)); + free(dev); + return -1; + } + + SYSCALL (i = fcntl (fd, F_GETFL, 0)); + if (i == -1) + { + SYSCALL (close (fd)); + free(dev); + return -1; + } + i &= ~O_NONBLOCK; + SYSCALL (i = fcntl (fd, F_SETFL, i)); + if (i == -1) + { + SYSCALL (close (fd)); + free(dev); + return -1; + } + free(dev); + return fd; +} + +int +xf86SetSerial (int fd, pointer options) +{ + struct termios t; + int val; + const char *s; + int baud, r; + + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + + SYSCALL (tcgetattr (fd, &t)); + + if ((val = xf86SetIntOption (options, "BaudRate", 0))) + { + if ((baud = GetBaud (val))) + { + cfsetispeed (&t, baud); + cfsetospeed (&t, baud); + } + else + { + xf86Msg (X_ERROR, + "Invalid Option BaudRate value: %d\n", val); + return -1; + } + } + + if ((val = xf86SetIntOption (options, "StopBits", 0))) + { + switch (val) + { + case 1: + t.c_cflag &= ~(CSTOPB); + break; + case 2: + t.c_cflag |= CSTOPB; + break; + default: + xf86Msg (X_ERROR, + "Invalid Option StopBits value: %d\n", val); + return -1; + break; + } + } + + if ((val = xf86SetIntOption (options, "DataBits", 0))) + { + switch (val) + { + case 5: + t.c_cflag &= ~(CSIZE); + t.c_cflag |= CS5; + break; + case 6: + t.c_cflag &= ~(CSIZE); + t.c_cflag |= CS6; + break; + case 7: + t.c_cflag &= ~(CSIZE); + t.c_cflag |= CS7; + break; + case 8: + t.c_cflag &= ~(CSIZE); + t.c_cflag |= CS8; + break; + default: + xf86Msg (X_ERROR, + "Invalid Option DataBits value: %d\n", val); + return -1; + break; + } + } + + if ((s = xf86SetStrOption (options, "Parity", NULL))) + { + if (xf86NameCmp (s, "Odd") == 0) + { + t.c_cflag |= PARENB | PARODD; + } + else if (xf86NameCmp (s, "Even") == 0) + { + t.c_cflag |= PARENB; + t.c_cflag &= ~(PARODD); + } + else if (xf86NameCmp (s, "None") == 0) + { + t.c_cflag &= ~(PARENB); + } + else + { + xf86Msg (X_ERROR, "Invalid Option Parity value: %s\n", + s); + return -1; + } + } + + if ((val = xf86SetIntOption (options, "Vmin", -1)) != -1) + { + t.c_cc[VMIN] = val; + } + if ((val = xf86SetIntOption (options, "Vtime", -1)) != -1) + { + t.c_cc[VTIME] = val; + } + + if ((s = xf86SetStrOption (options, "FlowControl", NULL))) + { + xf86MarkOptionUsedByName (options, "FlowControl"); + if (xf86NameCmp (s, "Xoff") == 0) + { + t.c_iflag |= IXOFF; + } + else if (xf86NameCmp (s, "Xon") == 0) + { + t.c_iflag |= IXON; + } + else if (xf86NameCmp (s, "XonXoff") == 0) + { + t.c_iflag |= IXON|IXOFF; + } + else if (xf86NameCmp (s, "None") == 0) + { + t.c_iflag &= ~(IXON | IXOFF); + } + else + { + xf86Msg (X_ERROR, + "Invalid Option FlowControl value: %s\n", s); + return -1; + } + } + + if ((xf86SetBoolOption (options, "ClearDTR", FALSE))) + { +#ifdef CLEARDTR_SUPPORT +# if defined(TIOCMBIC) + val = TIOCM_DTR; + SYSCALL (ioctl(fd, TIOCMBIC, &val)); +# else + SYSCALL (ioctl(fd, TIOCCDTR, NULL)); +# endif +#else + xf86Msg (X_WARNING, + "Option ClearDTR not supported on this OS\n"); + return -1; +#endif + xf86MarkOptionUsedByName (options, "ClearDTR"); + } + + if ((xf86SetBoolOption (options, "ClearRTS", FALSE))) + { + xf86Msg (X_WARNING, + "Option ClearRTS not supported on this OS\n"); + return -1; + xf86MarkOptionUsedByName (options, "ClearRTS"); + } + + SYSCALL (r = tcsetattr (fd, TCSANOW, &t)); + return r; +} + +int +xf86SetSerialSpeed (int fd, int speed) +{ + struct termios t; + int baud, r; + + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + + SYSCALL (tcgetattr (fd, &t)); + + if ((baud = GetBaud (speed))) + { + cfsetispeed (&t, baud); + cfsetospeed (&t, baud); + } + else + { + xf86Msg (X_ERROR, + "Invalid Option BaudRate value: %d\n", speed); + return -1; + } + + SYSCALL (r = tcsetattr (fd, TCSANOW, &t)); + return r; +} + +int +xf86ReadSerial (int fd, void *buf, int count) +{ + int r; + int i; + + SYSCALL (r = read (fd, buf, count)); + DebugF("ReadingSerial: 0x%x", + (unsigned char)*(((unsigned char *)buf))); + for (i = 1; i < r; i++) + DebugF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i)); + DebugF("\n"); + return r; +} + +int +xf86WriteSerial (int fd, const void *buf, int count) +{ + int r; + int i; + + DebugF("WritingSerial: 0x%x",(unsigned char)*(((unsigned char *)buf))); + for (i = 1; i < count; i++) + DebugF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i)); + DebugF("\n"); + SYSCALL (r = write (fd, buf, count)); + return r; +} + +int +xf86CloseSerial (int fd) +{ + int r; + + SYSCALL (r = close (fd)); + return r; +} + +int +xf86WaitForInput (int fd, int timeout) +{ + fd_set readfds; + struct timeval to; + int r; + + FD_ZERO(&readfds); + + if (fd >= 0) { + FD_SET(fd, &readfds); + } + + to.tv_sec = timeout / 1000000; + to.tv_usec = timeout % 1000000; + + if (fd >= 0) { + SYSCALL (r = select (FD_SETSIZE, &readfds, NULL, NULL, &to)); + } + else { + SYSCALL (r = select (FD_SETSIZE, NULL, NULL, NULL, &to)); + } + xf86ErrorFVerb (9,"select returned %d\n", r); + return r; +} + +int +xf86SerialSendBreak (int fd, int duration) +{ + int r; + + SYSCALL (r = tcsendbreak (fd, duration)); + return r; + +} + +int +xf86FlushInput(int fd) +{ + fd_set fds; + struct timeval timeout; + char c[4]; + + DebugF("FlushingSerial\n"); + if (tcflush(fd, TCIFLUSH) == 0) + return 0; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&fds); + FD_SET(fd, &fds); + while (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) > 0) { + if (read(fd, &c, sizeof(c)) < 1) + return 0; + FD_ZERO(&fds); + FD_SET(fd, &fds); + } + return 0; +} + +static struct states { + int xf; + int os; +} modemStates[] = { +#ifdef TIOCM_LE + { XF86_M_LE, TIOCM_LE }, +#endif +#ifdef TIOCM_DTR + { XF86_M_DTR, TIOCM_DTR }, +#endif +#ifdef TIOCM_RTS + { XF86_M_RTS, TIOCM_RTS }, +#endif +#ifdef TIOCM_ST + { XF86_M_ST, TIOCM_ST }, +#endif +#ifdef TIOCM_SR + { XF86_M_SR, TIOCM_SR }, +#endif +#ifdef TIOCM_CTS + { XF86_M_CTS, TIOCM_CTS }, +#endif +#ifdef TIOCM_CAR + { XF86_M_CAR, TIOCM_CAR }, +#elif defined(TIOCM_CD) + { XF86_M_CAR, TIOCM_CD }, +#endif +#ifdef TIOCM_RNG + { XF86_M_RNG, TIOCM_RNG }, +#elif defined(TIOCM_RI) + { XF86_M_CAR, TIOCM_RI }, +#endif +#ifdef TIOCM_DSR + { XF86_M_DSR, TIOCM_DSR }, +#endif +}; + +static int numStates = sizeof(modemStates) / sizeof(modemStates[0]); + +static int +xf2osState(int state) +{ + int i; + int ret = 0; + + for (i = 0; i < numStates; i++) + if (state & modemStates[i].xf) + ret |= modemStates[i].os; + return ret; +} + +static int +os2xfState(int state) +{ + int i; + int ret = 0; + + for (i = 0; i < numStates; i++) + if (state & modemStates[i].os) + ret |= modemStates[i].xf; + return ret; +} + +static int +getOsStateMask(void) +{ + int i; + int ret = 0; + for (i = 0; i < numStates; i++) + ret |= modemStates[i].os; + return ret; +} + +static int osStateMask = 0; + +int +xf86SetSerialModemState(int fd, int state) +{ + int ret; + int s; + + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + +#ifndef TIOCMGET + return -1; +#else + if (!osStateMask) + osStateMask = getOsStateMask(); + + state = xf2osState(state); + SYSCALL((ret = ioctl(fd, TIOCMGET, &s))); + if (ret < 0) + return -1; + s &= ~osStateMask; + s |= state; + SYSCALL((ret = ioctl(fd, TIOCMSET, &s))); + if (ret < 0) + return -1; + else + return 0; +#endif +} + +int +xf86GetSerialModemState(int fd) +{ + int ret; + int s; + + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + +#ifndef TIOCMGET + return -1; +#else + SYSCALL((ret = ioctl(fd, TIOCMGET, &s))); + if (ret < 0) + return -1; + return os2xfState(s); +#endif +} + +int +xf86SerialModemSetBits(int fd, int bits) +{ + int ret; + int s; + + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + +#ifndef TIOCMGET + return -1; +#else + s = xf2osState(bits); + SYSCALL((ret = ioctl(fd, TIOCMBIS, &s))); + return ret; +#endif +} + +int +xf86SerialModemClearBits(int fd, int bits) +{ + int ret; + int s; + + if (fd < 0) + return -1; + + /* Don't try to set parameters for non-tty devices. */ + if (!isatty(fd)) + return 0; + +#ifndef TIOCMGET + return -1; +#else + s = xf2osState(bits); + SYSCALL((ret = ioctl(fd, TIOCMBIC, &s))); + return ret; +#endif +} diff --git a/xorg-server/hw/xfree86/loader/sdksyms.sh b/xorg-server/hw/xfree86/sdksyms.sh index 18bb73523..18bb73523 100644 --- a/xorg-server/hw/xfree86/loader/sdksyms.sh +++ b/xorg-server/hw/xfree86/sdksyms.sh diff --git a/xorg-server/hw/xquartz/X11Application.m b/xorg-server/hw/xquartz/X11Application.m index 31aa9b97f..3973110fe 100644 --- a/xorg-server/hw/xquartz/X11Application.m +++ b/xorg-server/hw/xquartz/X11Application.m @@ -338,18 +338,21 @@ static void message_kit_thread (SEL selector, NSObject *arg) { case NSAppKitDefined: switch ([e subtype]) { + static BOOL x_was_active = NO; + case NSApplicationActivatedEventType: for_x = NO; - if ([self modalWindow] == nil) { + if ([e window] == nil && x_was_active) { BOOL order_all_windows = YES, workspaces, ok; for_appkit = NO; - - /* FIXME: hack to avoid having to pass the event to appkit, - which would cause it to raise one of its windows. */ + + /* FIXME: This is a hack to avoid passing the event to AppKit which + * would result in it raising one of its windows. + */ _appFlags._active = YES; - - [self activateX:YES]; - + + X11ApplicationSetFrontProcess(); + /* Get the Spaces preference for SwitchOnActivate */ (void)CFPreferencesAppSynchronize(CFSTR("com.apple.dock")); workspaces = CFPreferencesGetAppBooleanValue(CFSTR("workspaces"), CFSTR("com.apple.dock"), &ok); @@ -370,8 +373,9 @@ static void message_kit_thread (SEL selector, NSObject *arg) { * If there are no active windows, and there are minimized windows, we should * be restoring one of them. */ - if ([e data2] & 0x10) // 0x10 is set when we use cmd-tab or the dock icon + if ([e data2] & 0x10) { // 0x10 (bfCPSOrderAllWindowsForward) is set when we use cmd-tab or the dock icon DarwinSendDDXEvent(kXquartzBringAllToFront, 1, order_all_windows); + } } break; @@ -381,7 +385,10 @@ static void message_kit_thread (SEL selector, NSObject *arg) { case NSApplicationDeactivatedEventType: for_x = NO; - [self activateX:NO]; + + x_was_active = _x_active; + if(_x_active) + [self activateX:NO]; break; } break; diff --git a/xorg-server/hw/xquartz/mach-startup/Makefile.am b/xorg-server/hw/xquartz/mach-startup/Makefile.am index 8e49ea8ac..0b1f8977e 100644 --- a/xorg-server/hw/xquartz/mach-startup/Makefile.am +++ b/xorg-server/hw/xquartz/mach-startup/Makefile.am @@ -22,7 +22,7 @@ X11_bin_LDADD = \ $(top_builddir)/dix/dixfonts.lo \ $(top_builddir)/miext/rootless/librootless.la \ $(top_builddir)/hw/xquartz/pbproxy/libxpbproxy.la \ - $(DARWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) + $(XQUARTZ_LIBS) $(XSERVER_LIBS) X11_bin_LDFLAGS = \ $(XSERVER_SYS_LIBS) -lXplugin \ @@ -52,6 +52,8 @@ X11_bin_LDADD += \ $(top_builddir)/record/librecord.la endif +X11_bin_DEPENDENCIES = $(X11_bin_LDADD) + bin_PROGRAMS = Xquartz dist_Xquartz_SOURCES = \ diff --git a/xorg-server/hw/xwin/XWin.rc b/xorg-server/hw/xwin/XWin.rc index 539bd0e4d..a142f3070 100644 --- a/xorg-server/hw/xwin/XWin.rc +++ b/xorg-server/hw/xwin/XWin.rc @@ -50,7 +50,7 @@ BEGIN LTEXT BUILDERSTRING, IDC_STATIC, 36, 28, 220, 8 LTEXT "This software is licensed under the terms of the MIT/X11 License.", IDC_STATIC, 36, 48, 220, 20 CONTROL __VENDORDWEBSUPPORT__, ID_ABOUT_WEBSITE, "Button", - BS_OWNERDRAW | WS_TABSTOP, 36, 68, 68, 8 + BS_OWNERDRAW | WS_TABSTOP, 36, 68, 220, 8 DEFPUSHBUTTON "&OK", IDOK, 105, 85, 50, 15 END diff --git a/xorg-server/hw/xwin/windialogs.c b/xorg-server/hw/xwin/windialogs.c index c3a149762..bb4f447e2 100644 --- a/xorg-server/hw/xwin/windialogs.c +++ b/xorg-server/hw/xwin/windialogs.c @@ -115,7 +115,7 @@ winDrawURLWindow (LPARAM lParam) /* Draw it */ SetBkMode (draw->hDC, OPAQUE); SelectObject (draw->hDC, font); - DrawText (draw->hDC, str, strlen (str),&rect,DT_CENTER | DT_VCENTER); + DrawText (draw->hDC, str, strlen (str),&rect,DT_LEFT | DT_VCENTER); /* Delete the created font, replace it with stock font */ DeleteObject (SelectObject (draw->hDC, GetStockObject (ANSI_VAR_FONT))); } diff --git a/xorg-server/hw/xwin/winmultiwindowwindow.c b/xorg-server/hw/xwin/winmultiwindowwindow.c index 21b818b89..2d9a46e40 100644 --- a/xorg-server/hw/xwin/winmultiwindowwindow.c +++ b/xorg-server/hw/xwin/winmultiwindowwindow.c @@ -493,6 +493,8 @@ winCreateWindowsWindow (WindowPtr pWin) winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv; WinXSizeHints hints; WindowPtr pDaddy; + DWORD dwStyle, dwExStyle; + RECT rc; winInitMultiWindowClass(); @@ -517,6 +519,8 @@ winCreateWindowsWindow (WindowPtr pWin) iY = CW_USEDEFAULT; } + winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY); + if (winMultiWindowGetTransientFor (pWin, &pDaddy)) { if (pDaddy) @@ -538,16 +542,35 @@ winCreateWindowsWindow (WindowPtr pWin) } } - /* Create the window */ - /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */ + /* Make it WS_OVERLAPPED in create call since WS_POPUP doesn't support */ /* CW_USEDEFAULT, change back to popup after creation */ - hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + dwExStyle = WS_EX_TOOLWINDOW; + + /* + Calculate the window coordinates containing the requested client area, + being careful to preseve CW_USEDEFAULT + */ + rc.top = (iY != CW_USEDEFAULT) ? iY : 0; + rc.left = (iX != CW_USEDEFAULT) ? iX : 0; + rc.bottom = rc.top + iHeight; + rc.right = rc.left + iWidth; + AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle); + if (iY != CW_USEDEFAULT) iY = rc.top; + if (iX != CW_USEDEFAULT) iX = rc.left; + iHeight = rc.bottom - rc.top; + iWidth = rc.right - rc.left; + + winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY); + + /* Create the window */ + hWnd = CreateWindowExA (dwExStyle, /* Extended styles */ WINDOW_CLASS_X, /* Class name */ WINDOW_TITLE_X, /* Window name */ - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + dwStyle, /* Styles */ iX, /* Horizontal position */ iY, /* Vertical position */ - iWidth, /* Right edge */ + iWidth, /* Right edge */ iHeight, /* Bottom edge */ hFore, /* Null or Parent window if transient*/ (HMENU) NULL, /* No menu */ @@ -569,6 +592,10 @@ winCreateWindowsWindow (WindowPtr pWin) SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); SetWindowPos (hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + + /* Adjust the X window to match the window placement we actually got... */ + winAdjustXWindow (pWin, hWnd); + /* Make sure it gets the proper system menu for a WS_POPUP, too */ GetSystemMenu (hWnd, TRUE); diff --git a/xorg-server/hw/xwin/winmultiwindowwndproc.c b/xorg-server/hw/xwin/winmultiwindowwndproc.c index 10123c63a..1a3be78d5 100644 --- a/xorg-server/hw/xwin/winmultiwindowwndproc.c +++ b/xorg-server/hw/xwin/winmultiwindowwndproc.c @@ -1,1046 +1,1104 @@ -/*
- *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- *Copyright (C) Colin Harrison 2005-2008
- *
- *Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- *"Software"), to deal in the Software without restriction, including
- *without limitation the rights to use, copy, modify, merge, publish,
- *distribute, sublicense, and/or sell copies of the Software, and to
- *permit persons to whom the Software is furnished to do so, subject to
- *the following conditions:
- *
- *The above copyright notice and this permission notice shall be
- *included in all copies or substantial portions of the Software.
- *
- *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
- *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- *Except as contained in this notice, the name of the XFree86 Project
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from the XFree86 Project.
- *
- * Authors: Kensuke Matsuzaki
- * Earle F. Philhower, III
- * Harold L Hunt II
- * Colin Harrison
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include "dixevents.h"
-#include "winmultiwindowclass.h"
-#include "winprefs.h"
-#include "winmsg.h"
-#include "inputstr.h"
-
-extern void winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle);
-
-
-/*
- * Local globals
- */
-
-static UINT_PTR g_uipMousePollingTimerID = 0;
-
-
-/*
- * Constant defines
- */
-
-#define WIN_MULTIWINDOW_SHAPE YES
-
-
-/*
- * ConstrainSize - Taken from TWM sources - Respects hints for sizing
- */
-#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
-static void
-ConstrainSize (WinXSizeHints hints, int *widthp, int *heightp)
-{
- int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta;
- int baseWidth, baseHeight;
- int dwidth = *widthp, dheight = *heightp;
-
- if (hints.flags & PMinSize)
- {
- minWidth = hints.min_width;
- minHeight = hints.min_height;
- }
- else if (hints.flags & PBaseSize)
- {
- minWidth = hints.base_width;
- minHeight = hints.base_height;
- }
- else
- minWidth = minHeight = 1;
-
- if (hints.flags & PBaseSize)
- {
- baseWidth = hints.base_width;
- baseHeight = hints.base_height;
- }
- else if (hints.flags & PMinSize)
- {
- baseWidth = hints.min_width;
- baseHeight = hints.min_height;
- }
- else
- baseWidth = baseHeight = 0;
-
- if (hints.flags & PMaxSize)
- {
- maxWidth = hints.max_width;
- maxHeight = hints.max_height;
- }
- else
- {
- maxWidth = MAXINT;
- maxHeight = MAXINT;
- }
-
- if (hints.flags & PResizeInc)
- {
- xinc = hints.width_inc;
- yinc = hints.height_inc;
- }
- else
- xinc = yinc = 1;
-
- /*
- * First, clamp to min and max values
- */
- if (dwidth < minWidth)
- dwidth = minWidth;
- if (dheight < minHeight)
- dheight = minHeight;
-
- if (dwidth > maxWidth)
- dwidth = maxWidth;
- if (dheight > maxHeight)
- dheight = maxHeight;
-
- /*
- * Second, fit to base + N * inc
- */
- dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
- dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
-
- /*
- * Third, adjust for aspect ratio
- */
-
- /*
- * The math looks like this:
- *
- * minAspectX dwidth maxAspectX
- * ---------- <= ------- <= ----------
- * minAspectY dheight maxAspectY
- *
- * If that is multiplied out, then the width and height are
- * invalid in the following situations:
- *
- * minAspectX * dheight > minAspectY * dwidth
- * maxAspectX * dheight < maxAspectY * dwidth
- *
- */
-
- if (hints.flags & PAspect)
- {
- if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth)
- {
- delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc);
- if (dwidth + delta <= maxWidth)
- dwidth += delta;
- else
- {
- delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc);
- if (dheight - delta >= minHeight)
- dheight -= delta;
- }
- }
-
- if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth)
- {
- delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc);
- if (dheight + delta <= maxHeight)
- dheight += delta;
- else
- {
- delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc);
- if (dwidth - delta >= minWidth)
- dwidth -= delta;
- }
- }
- }
-
- /* Return computed values */
- *widthp = dwidth;
- *heightp = dheight;
-}
-#undef makemult
-
-
-
-/*
- * ValidateSizing - Ensures size request respects hints
- */
-static int
-ValidateSizing (HWND hwnd, WindowPtr pWin,
- WPARAM wParam, LPARAM lParam)
-{
- WinXSizeHints sizeHints;
- RECT *rect;
- int iWidth, iHeight;
- RECT rcClient, rcWindow;
- int iBorderWidthX, iBorderWidthY;
-
- /* Invalid input checking */
- if (pWin==NULL || lParam==0)
- return FALSE;
-
- /* No size hints, no checking */
- if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints))
- return FALSE;
-
- /* Avoid divide-by-zero */
- if (sizeHints.flags & PResizeInc)
- {
- if (sizeHints.width_inc == 0) sizeHints.width_inc = 1;
- if (sizeHints.height_inc == 0) sizeHints.height_inc = 1;
- }
-
- rect = (RECT*)lParam;
-
- iWidth = rect->right - rect->left;
- iHeight = rect->bottom - rect->top;
-
- /* Now remove size of any borders and title bar */
- GetClientRect(hwnd, &rcClient);
- GetWindowRect(hwnd, &rcWindow);
- iBorderWidthX = (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left);
- iBorderWidthY = (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top);
- iWidth -= iBorderWidthX;
- iHeight -= iBorderWidthY;
-
- /* Constrain the size to legal values */
- ConstrainSize (sizeHints, &iWidth, &iHeight);
-
- /* Add back the size of borders and title bar */
- iWidth += iBorderWidthX;
- iHeight += iBorderWidthY;
-
- /* Adjust size according to where we're dragging from */
- switch(wParam) {
- case WMSZ_TOP:
- case WMSZ_TOPRIGHT:
- case WMSZ_BOTTOM:
- case WMSZ_BOTTOMRIGHT:
- case WMSZ_RIGHT:
- rect->right = rect->left + iWidth;
- break;
- default:
- rect->left = rect->right - iWidth;
- break;
- }
- switch(wParam) {
- case WMSZ_BOTTOM:
- case WMSZ_BOTTOMRIGHT:
- case WMSZ_BOTTOMLEFT:
- case WMSZ_RIGHT:
- case WMSZ_LEFT:
- rect->bottom = rect->top + iHeight;
- break;
- default:
- rect->top = rect->bottom - iHeight;
- break;
- }
- return TRUE;
-}
-
-extern Bool winInDestroyWindowsWindow;
-static Bool winInRaiseWindow = FALSE;
-static void winRaiseWindow(WindowPtr pWin)
-{
- if (!winInDestroyWindowsWindow && !winInRaiseWindow)
- {
- BOOL oldstate = winInRaiseWindow;
- XID vlist[1] = { 0 };
- winInRaiseWindow = TRUE;
- /* Call configure window directly to make sure it gets processed
- * in time
- */
- ConfigureWindow(pWin, CWStackMode, vlist, serverClient);
- winInRaiseWindow = oldstate;
- }
-}
-
-static
-void winStartMousePolling(winPrivScreenPtr s_pScreenPriv)
-{
- /*
- * Timer to poll mouse position. This is needed to make
- * programs like xeyes follow the mouse properly when the
- * mouse pointer is outside of any X window.
- */
- if (g_uipMousePollingTimerID == 0)
- g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen,
- WIN_POLLING_MOUSE_TIMER_ID,
- MOUSE_POLLING_INTERVAL,
- NULL);
-}
-
-/*
- * winTopLevelWindowProc - Window procedure for all top-level Windows windows.
- */
-
-LRESULT CALLBACK
-winTopLevelWindowProc (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam)
-{
- POINT ptMouse;
- HDC hdcUpdate;
- PAINTSTRUCT ps;
- WindowPtr pWin = NULL;
- winPrivWinPtr pWinPriv = NULL;
- ScreenPtr s_pScreen = NULL;
- winPrivScreenPtr s_pScreenPriv = NULL;
- winScreenInfo *s_pScreenInfo = NULL;
- HWND hwndScreen = NULL;
- DrawablePtr pDraw = NULL;
- winWMMessageRec wmMsg;
- Bool fWMMsgInitialized = FALSE;
- static Bool s_fTracking = FALSE;
- Bool needRestack = FALSE;
- LRESULT ret;
-
-#if CYGDEBUG
- winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam);
-#endif
-
- /* Check if the Windows window property for our X window pointer is valid */
- if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
- {
- /* Our X window pointer is valid */
-
- /* Get pointers to the drawable and the screen */
- pDraw = &pWin->drawable;
- s_pScreen = pWin->drawable.pScreen;
-
- /* Get a pointer to our window privates */
- pWinPriv = winGetWindowPriv(pWin);
-
- /* Get pointers to our screen privates and screen info */
- s_pScreenPriv = pWinPriv->pScreenPriv;
- s_pScreenInfo = s_pScreenPriv->pScreenInfo;
-
- /* Get the handle for our screen-sized window */
- hwndScreen = s_pScreenPriv->hwndScreen;
-
- /* */
- wmMsg.msg = 0;
- wmMsg.hwndWindow = hwnd;
- wmMsg.iWindow = (Window)GetProp (hwnd, WIN_WID_PROP);
-
- wmMsg.iX = pDraw->x;
- wmMsg.iY = pDraw->y;
- wmMsg.iWidth = pDraw->width;
- wmMsg.iHeight = pDraw->height;
-
- fWMMsgInitialized = TRUE;
-
-#if 0
- /*
- * Print some debugging information
- */
-
- ErrorF ("hWnd %08X\n", hwnd);
- ErrorF ("pWin %08X\n", pWin);
- ErrorF ("pDraw %08X\n", pDraw);
- ErrorF ("\ttype %08X\n", pWin->drawable.type);
- ErrorF ("\tclass %08X\n", pWin->drawable.class);
- ErrorF ("\tdepth %08X\n", pWin->drawable.depth);
- ErrorF ("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel);
- ErrorF ("\tid %08X\n", pWin->drawable.id);
- ErrorF ("\tx %08X\n", pWin->drawable.x);
- ErrorF ("\ty %08X\n", pWin->drawable.y);
- ErrorF ("\twidth %08X\n", pWin->drawable.width);
- ErrorF ("\thenght %08X\n", pWin->drawable.height);
- ErrorF ("\tpScreen %08X\n", pWin->drawable.pScreen);
- ErrorF ("\tserialNumber %08X\n", pWin->drawable.serialNumber);
- ErrorF ("g_iWindowPrivateKey %p\n", g_iWindowPrivateKey);
- ErrorF ("pWinPriv %08X\n", pWinPriv);
- ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv);
- ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo);
- ErrorF ("hwndScreen %08X\n", hwndScreen);
-#endif
- }
-
- /* Branch on message type */
- switch (message)
- {
- case WM_CREATE:
-
- /* */
- SetProp (hwnd,
- WIN_WINDOW_PROP,
- (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams);
-
- /* */
- SetProp (hwnd,
- WIN_WID_PROP,
- (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams));
-
- /*
- * Make X windows' Z orders sync with Windows windows because
- * there can be AlwaysOnTop windows overlapped on the window
- * currently being created.
- */
- winReorderWindowsMultiWindow ();
-
- /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */
- {
- RECT rWindow;
- HRGN hRgnWindow;
- GetWindowRect(hwnd, &rWindow);
- hRgnWindow = CreateRectRgnIndirect(&rWindow);
- SetWindowRgn (hwnd, hRgnWindow, TRUE);
- DeleteObject(hRgnWindow);
- }
-
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)XMING_SIGNATURE);
-
- return 0;
-
- case WM_INIT_SYS_MENU:
- /*
- * Add whatever the setup file wants to for this window
- */
- SetupSysMenu ((unsigned long)hwnd);
- return 0;
-
- case WM_SYSCOMMAND:
- /*
- * Any window menu items go through here
- */
- if (HandleCustomWM_COMMAND ((unsigned long)hwnd, LOWORD(wParam)))
- {
- /* Don't pass customized menus to DefWindowProc */
- return 0;
- }
- if (wParam == SC_RESTORE || wParam == SC_MAXIMIZE)
- {
- WINDOWPLACEMENT wndpl;
- wndpl.length = sizeof(wndpl);
- if (GetWindowPlacement(hwnd, &wndpl) && wndpl.showCmd == SW_SHOWMINIMIZED)
- needRestack = TRUE;
- }
- break;
-
- case WM_INITMENU:
- /* Checks/Unchecks any menu items before they are displayed */
- HandleCustomWM_INITMENU ((unsigned long)hwnd, wParam);
- break;
-
- case WM_ERASEBKGND:
- /*
- * Pretend that we did erase the background but we don't care,
- * since we repaint the entire region anyhow
- * This avoids some flickering when resizing.
- */
- return TRUE;
-
- case WM_PAINT:
- /* Only paint if our window handle is valid */
- if (hwndScreen == NULL)
- break;
-
- /* BeginPaint gives us an hdc that clips to the invalidated region */
- hdcUpdate = BeginPaint (hwnd, &ps);
- /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */
- if (ps.rcPaint.right==0 && ps.rcPaint.bottom==0 && ps.rcPaint.left==0 && ps.rcPaint.top==0)
- {
- EndPaint (hwnd, &ps);
- return 0;
- }
-
- /* Try to copy from the shadow buffer */
- if (!BitBlt (hdcUpdate,
- ps.rcPaint.left, ps.rcPaint.top,
- ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top,
- s_pScreenPriv->hdcShadow,
- ps.rcPaint.left + pWin->drawable.x, ps.rcPaint.top + pWin->drawable.y,
- SRCCOPY))
- {
- LPVOID lpMsgBuf;
-
- /* Display a fancy error message */
- FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError (),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0, NULL);
-
- ErrorF ("winTopLevelWindowProc - BitBlt failed: %s\n",
- (LPSTR)lpMsgBuf);
- LocalFree (lpMsgBuf);
- }
-
- /* EndPaint frees the DC */
- EndPaint (hwnd, &ps);
- return 0;
-
- case WM_MOUSEMOVE:
- /* Unpack the client area mouse coordinates */
- ptMouse.x = GET_X_LPARAM(lParam);
- ptMouse.y = GET_Y_LPARAM(lParam);
-
- /* Translate the client area mouse coordinates to screen coordinates */
- ClientToScreen (hwnd, &ptMouse);
-
- /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
- ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN);
- ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- /* We can't do anything without privates */
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
-
- /* Has the mouse pointer crossed screens? */
- if (s_pScreen != miPointerGetScreen(g_pwinPointer))
- miPointerSetScreen (g_pwinPointer, s_pScreenInfo->dwScreen,
- ptMouse.x - s_pScreenInfo->dwXOffset,
- ptMouse.y - s_pScreenInfo->dwYOffset);
-
- /* Are we tracking yet? */
- if (!s_fTracking)
- {
- TRACKMOUSEEVENT tme;
-
- /* Setup data structure */
- ZeroMemory (&tme, sizeof (tme));
- tme.cbSize = sizeof (tme);
- tme.dwFlags = TME_LEAVE;
- tme.hwndTrack = hwnd;
-
- /* Call the tracking function */
- if (!(*g_fpTrackMouseEvent) (&tme))
- ErrorF ("winTopLevelWindowProc - _TrackMouseEvent failed\n");
-
- /* Flag that we are tracking now */
- s_fTracking = TRUE;
- }
-
- /* Hide or show the Windows mouse cursor */
- if (g_fSoftwareCursor && g_fCursor)
- {
- /* Hide Windows cursor */
- g_fCursor = FALSE;
- ShowCursor (FALSE);
- }
-
- /* Kill the timer used to poll mouse events */
- if (g_uipMousePollingTimerID != 0)
- {
- KillTimer (s_pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
- g_uipMousePollingTimerID = 0;
- }
-
- /* Deliver absolute cursor position to X Server */
- winEnqueueMotion(ptMouse.x - s_pScreenInfo->dwXOffset,
- ptMouse.y - s_pScreenInfo->dwYOffset);
-
- return 0;
-
- case WM_NCMOUSEMOVE:
- /*
- * We break instead of returning 0 since we need to call
- * DefWindowProc to get the mouse cursor changes
- * and min/max/close button highlighting in Windows XP.
- * The Platform SDK says that you should return 0 if you
- * process this message, but it fails to mention that you
- * will give up any default functionality if you do return 0.
- */
-
- /* We can't do anything without privates */
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
-
- /* Non-client mouse movement, show Windows cursor */
- if (g_fSoftwareCursor && !g_fCursor)
- {
- g_fCursor = TRUE;
- ShowCursor (TRUE);
- }
-
- winStartMousePolling(s_pScreenPriv);
-
- break;
-
- case WM_MOUSELEAVE:
- /* Mouse has left our client area */
-
- /* Flag that we are no longer tracking */
- s_fTracking = FALSE;
-
- /* Show the mouse cursor, if necessary */
- if (g_fSoftwareCursor && !g_fCursor)
- {
- g_fCursor = TRUE;
- ShowCursor (TRUE);
- }
-
- winStartMousePolling(s_pScreenPriv);
-
- return 0;
-
- case WM_LBUTTONDBLCLK:
- case WM_LBUTTONDOWN:
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
- g_fButton[0] = TRUE;
- SetCapture(hwnd);
- return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam);
-
- case WM_LBUTTONUP:
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
- g_fButton[0] = FALSE;
- ReleaseCapture();
- winStartMousePolling(s_pScreenPriv);
- return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam);
-
- case WM_MBUTTONDBLCLK:
- case WM_MBUTTONDOWN:
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
- g_fButton[1] = TRUE;
- SetCapture(hwnd);
- return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam);
-
- case WM_MBUTTONUP:
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
- g_fButton[1] = FALSE;
- ReleaseCapture();
- winStartMousePolling(s_pScreenPriv);
- return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam);
-
- case WM_RBUTTONDBLCLK:
- case WM_RBUTTONDOWN:
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
- g_fButton[2] = TRUE;
- SetCapture(hwnd);
- return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam);
-
- case WM_RBUTTONUP:
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
- g_fButton[2] = FALSE;
- ReleaseCapture();
- winStartMousePolling(s_pScreenPriv);
- return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam);
-
- case WM_XBUTTONDBLCLK:
- case WM_XBUTTONDOWN:
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
- SetCapture(hwnd);
- return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam);
-
- case WM_XBUTTONUP:
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
- ReleaseCapture();
- winStartMousePolling(s_pScreenPriv);
- return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam);
-
- case WM_MOUSEWHEEL:
- if (SendMessage(hwnd, WM_NCHITTEST, 0, MAKELONG(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) == HTCLIENT)
- {
- /* Pass the message to the root window */
- SendMessage (hwndScreen, message, wParam, lParam);
- return 0;
- }
- else break;
-
- case WM_SETFOCUS:
- if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
- break;
-
- {
- /* Get the parent window for transient handling */
- HWND hParent = GetParent(hwnd);
- if (hParent && IsIconic(hParent)) ShowWindow (hParent, SW_RESTORE);
- }
-
- winRestoreModeKeyStates ();
-
- /* Add the keyboard hook if possible */
- if (g_fKeyboardHookLL)
- g_fKeyboardHookLL = winInstallKeyboardHookLL ();
- return 0;
-
- case WM_KILLFOCUS:
- /* Pop any pressed keys since we are losing keyboard focus */
- winKeybdReleaseKeys ();
-
- /* Remove our keyboard hook if it is installed */
- winRemoveKeyboardHookLL ();
- if (!wParam)
- /* Revert the X focus as well, but only if the Windows focus is going to another window */
- DeleteWindowFromAnyEvents(pWin, FALSE);
- return 0;
-
- case WM_SYSDEADCHAR:
- case WM_DEADCHAR:
- /*
- * NOTE: We do nothing with WM_*CHAR messages,
- * nor does the root window, so we can just toss these messages.
- */
- return 0;
-
- case WM_SYSKEYDOWN:
- case WM_KEYDOWN:
-
- /*
- * Don't pass Alt-F4 key combo to root window,
- * let Windows translate to WM_CLOSE and close this top-level window.
- *
- * NOTE: We purposely don't check the fUseWinKillKey setting because
- * it should only apply to the key handling for the root window,
- * not for top-level window-manager windows.
- *
- * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
- * because that is a key combo that no X app should be expecting to
- * receive, since it has historically been used to shutdown the X server.
- * Passing Ctrl-Alt-Backspace to the root window preserves that
- * behavior, assuming that -unixkill has been passed as a parameter.
- */
- if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000))
- break;
-
-#if CYGWINDOWING_DEBUG
- if (wParam == VK_ESCAPE)
- {
- /* Place for debug: put any tests and dumps here */
- WINDOWPLACEMENT windPlace;
- RECT rc;
- LPRECT pRect;
-
- windPlace.length = sizeof (WINDOWPLACEMENT);
- GetWindowPlacement (hwnd, &windPlace);
- pRect = &windPlace.rcNormalPosition;
- ErrorF ("\nCYGWINDOWING Dump:\n"
- "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x,
- pDraw->y, pDraw->width, pDraw->height);
- ErrorF ("\twindPlace: (%ld, %ld) - %ldx%ld\n", pRect->left,
- pRect->top, pRect->right - pRect->left,
- pRect->bottom - pRect->top);
- if (GetClientRect (hwnd, &rc))
- {
- pRect = &rc;
- ErrorF ("\tClientRect: (%ld, %ld) - %ldx%ld\n", pRect->left,
- pRect->top, pRect->right - pRect->left,
- pRect->bottom - pRect->top);
- }
- if (GetWindowRect (hwnd, &rc))
- {
- pRect = &rc;
- ErrorF ("\tWindowRect: (%ld, %ld) - %ldx%ld\n", pRect->left,
- pRect->top, pRect->right - pRect->left,
- pRect->bottom - pRect->top);
- }
- ErrorF ("\n");
- }
-#endif
-
- /* Pass the message to the root window */
- return winWindowProc(hwndScreen, message, wParam, lParam);
-
- case WM_SYSKEYUP:
- case WM_KEYUP:
-
-
- /* Pass the message to the root window */
- return winWindowProc(hwndScreen, message, wParam, lParam);
-
- case WM_HOTKEY:
-
- /* Pass the message to the root window */
- SendMessage (hwndScreen, message, wParam, lParam);
- return 0;
-
- case WM_ACTIVATE:
-
- /* Pass the message to the root window */
- SendMessage (hwndScreen, message, wParam, lParam);
-
- if (LOWORD(wParam) != WA_INACTIVE)
- {
- /* Raise the window to the top in Z order */
- /* ago: Activate does not mean putting it to front! */
- /*
- wmMsg.msg = WM_WM_RAISE;
- if (fWMMsgInitialized)
- winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
- */
-
- /* Tell our Window Manager thread to activate the window */
- wmMsg.msg = WM_WM_ACTIVATE;
- if (fWMMsgInitialized)
- if (!pWin || !pWin->overrideRedirect) /* for OOo menus */
- winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
- }
- /* Prevent the mouse wheel from stalling when another window is minimized */
- if (HIWORD(wParam) == 0 && LOWORD(wParam) == WA_ACTIVE &&
- (HWND)lParam != NULL && (HWND)lParam != (HWND)GetParent(hwnd))
- SetFocus(hwnd);
- return 0;
-
- case WM_ACTIVATEAPP:
- /*
- * This message is also sent to the root window
- * so we do nothing for individual multiwindow windows
- */
- break;
-
- case WM_CLOSE:
- /* Branch on if the window was killed in X already */
- if (pWinPriv->fXKilled)
- {
- /* Window was killed, go ahead and destroy the window */
- DestroyWindow (hwnd);
- }
- else
- {
- /* Tell our Window Manager thread to kill the window */
- wmMsg.msg = WM_WM_KILL;
- if (fWMMsgInitialized)
- winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
- }
- return 0;
-
- case WM_DESTROY:
-
- /* Branch on if the window was killed in X already */
- if (pWinPriv && !pWinPriv->fXKilled)
- {
- ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n");
-
- /* Tell our Window Manager thread to kill the window */
- wmMsg.msg = WM_WM_KILL;
- if (fWMMsgInitialized)
- winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
- }
-
- RemoveProp (hwnd, WIN_WINDOW_PROP);
- RemoveProp (hwnd, WIN_WID_PROP);
- RemoveProp (hwnd, WIN_NEEDMANAGE_PROP);
-
- break;
-
- case WM_MOVE:
- /* Adjust the X Window to the moved Windows window */
- winAdjustXWindow (pWin, hwnd);
- return 0;
-
- case WM_SHOWWINDOW:
- /* Bail out if the window is being hidden */
- if (!wParam)
- return 0;
-
- /* */
- if (!pWin->overrideRedirect)
- {
- /* Flag that this window needs to be made active when clicked */
- SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1);
-
- if (!(GetWindowLongPtr (hwnd, GWL_EXSTYLE) & WS_EX_APPWINDOW))
- {
- HWND zstyle = HWND_NOTOPMOST;
-
- /* Set the window extended style flags */
- SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
-
- /* Set the transient style flags */
- if (GetParent(hwnd)) SetWindowLongPtr (hwnd, GWL_STYLE,
- WS_POPUP | WS_OVERLAPPED | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
- /* Set the window standard style flags */
- else SetWindowLongPtr (hwnd, GWL_STYLE,
- (WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
- & ~WS_CAPTION & ~WS_SIZEBOX);
-
- winUpdateWindowPosition (hwnd, FALSE, &zstyle);
- SetForegroundWindow (hwnd);
- }
- wmMsg.msg = WM_WM_MAP3;
- }
- else /* It is an overridden window so make it top of Z stack */
- {
- HWND forHwnd = GetForegroundWindow();
-#if CYGWINDOWING_DEBUG
- ErrorF ("overridden window is shown\n");
-#endif
- if (forHwnd != NULL)
- {
- if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)XMING_SIGNATURE)
- {
- if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
- SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- else
- SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- }
- }
- wmMsg.msg = WM_WM_MAP2;
- }
-
- /* Tell our Window Manager thread to map the window */
- if (fWMMsgInitialized)
- winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
-
- winStartMousePolling(s_pScreenPriv);
-
- return 0;
-
- case WM_SIZING:
- /* Need to legalize the size according to WM_NORMAL_HINTS */
- /* for applications like xterm */
- return ValidateSizing (hwnd, pWin, wParam, lParam);
-
- case WM_WINDOWPOSCHANGED:
- {
- LPWINDOWPOS pWinPos = (LPWINDOWPOS) lParam;
-
- if (!(pWinPos->flags & SWP_NOZORDER))
- {
-#if CYGWINDOWING_DEBUG
- winDebug ("\twindow z order was changed\n");
-#endif
- if (pWinPos->hwndInsertAfter == HWND_TOP
- ||pWinPos->hwndInsertAfter == HWND_TOPMOST
- ||pWinPos->hwndInsertAfter == HWND_NOTOPMOST)
- {
-#if CYGWINDOWING_DEBUG
- winDebug ("\traise to top\n");
-#endif
- /* Raise the window to the top in Z order */
- winRaiseWindow(pWin);
- }
- else if (pWinPos->hwndInsertAfter == HWND_BOTTOM)
- {
- }
- else
- {
- /* Check if this window is top of X windows. */
- HWND hWndAbove = NULL;
- DWORD dwCurrentProcessID = GetCurrentProcessId ();
- DWORD dwWindowProcessID = 0;
-
- for (hWndAbove = pWinPos->hwndInsertAfter;
- hWndAbove != NULL;
- hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV))
- {
- /* Ignore other XWin process's window */
- GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID);
-
- if ((dwWindowProcessID == dwCurrentProcessID)
- && GetProp (hWndAbove, WIN_WINDOW_PROP)
- && !IsWindowVisible (hWndAbove)
- && !IsIconic (hWndAbove) ) /* ignore minimized windows */
- break;
- }
- /* If this is top of X windows in Windows stack,
- raise it in X stack. */
- if (hWndAbove == NULL)
- {
-#if CYGWINDOWING_DEBUG
- winDebug ("\traise to top\n");
-#endif
- winRaiseWindow(pWin);
- }
- }
- }
- }
- /*
- * Pass the message to DefWindowProc to let the function
- * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE.
- */
- break;
-
- case WM_SIZE:
- /* see dix/window.c */
-#if CYGWINDOWING_DEBUG
- {
- char buf[64];
- switch (wParam)
- {
- case SIZE_MINIMIZED:
- strcpy(buf, "SIZE_MINIMIZED");
- break;
- case SIZE_MAXIMIZED:
- strcpy(buf, "SIZE_MAXIMIZED");
- break;
- case SIZE_RESTORED:
- strcpy(buf, "SIZE_RESTORED");
- break;
- default:
- strcpy(buf, "UNKNOWN_FLAG");
- }
- ErrorF ("winTopLevelWindowProc - WM_SIZE to %dx%d (%s) - %d ms\n",
- (int)LOWORD(lParam), (int)HIWORD(lParam), buf,
- (int)(GetTickCount ()));
- }
-#endif
- /* Adjust the X Window to the moved Windows window */
- winAdjustXWindow (pWin, hwnd);
- return 0; /* end of WM_SIZE handler */
-
- case WM_MOUSEACTIVATE:
-
- /* Check if this window needs to be made active when clicked */
- if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP))
- {
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - "
- "MA_NOACTIVATE\n");
-#endif
-
- /* */
- return MA_NOACTIVATE;
- }
- break;
-
- case WM_SETCURSOR:
- if (LOWORD(lParam) == HTCLIENT)
- {
- if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle);
- return TRUE;
- }
- break;
-
- default:
- break;
- }
-
- ret = DefWindowProc (hwnd, message, wParam, lParam);
- /*
- * If the window was minized we get the stack change before the window is restored
- * and so it gets lost. Ensure there stacking order is correct.
- */
- if (needRestack)
- winReorderWindowsMultiWindow();
- return ret;
-}
+/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + *Copyright (C) Colin Harrison 2005-2008 + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Kensuke Matsuzaki + * Earle F. Philhower, III + * Harold L Hunt II + * Colin Harrison + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.h" +#include "winmsg.h" +#include "inputstr.h" + +extern void winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle); + + +/* + * Local globals + */ + +static UINT_PTR g_uipMousePollingTimerID = 0; + + +/* + * Constant defines + */ + +#define WIN_MULTIWINDOW_SHAPE YES + + +/* + * ConstrainSize - Taken from TWM sources - Respects hints for sizing + */ +#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) +static void +ConstrainSize (WinXSizeHints hints, int *widthp, int *heightp) +{ + int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta; + int baseWidth, baseHeight; + int dwidth = *widthp, dheight = *heightp; + + if (hints.flags & PMinSize) + { + minWidth = hints.min_width; + minHeight = hints.min_height; + } + else if (hints.flags & PBaseSize) + { + minWidth = hints.base_width; + minHeight = hints.base_height; + } + else + minWidth = minHeight = 1; + + if (hints.flags & PBaseSize) + { + baseWidth = hints.base_width; + baseHeight = hints.base_height; + } + else if (hints.flags & PMinSize) + { + baseWidth = hints.min_width; + baseHeight = hints.min_height; + } + else + baseWidth = baseHeight = 0; + + if (hints.flags & PMaxSize) + { + maxWidth = hints.max_width; + maxHeight = hints.max_height; + } + else + { + maxWidth = MAXINT; + maxHeight = MAXINT; + } + + if (hints.flags & PResizeInc) + { + xinc = hints.width_inc; + yinc = hints.height_inc; + } + else + xinc = yinc = 1; + + /* + * First, clamp to min and max values + */ + if (dwidth < minWidth) + dwidth = minWidth; + if (dheight < minHeight) + dheight = minHeight; + + if (dwidth > maxWidth) + dwidth = maxWidth; + if (dheight > maxHeight) + dheight = maxHeight; + + /* + * Second, fit to base + N * inc + */ + dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth; + dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight; + + /* + * Third, adjust for aspect ratio + */ + + /* + * The math looks like this: + * + * minAspectX dwidth maxAspectX + * ---------- <= ------- <= ---------- + * minAspectY dheight maxAspectY + * + * If that is multiplied out, then the width and height are + * invalid in the following situations: + * + * minAspectX * dheight > minAspectY * dwidth + * maxAspectX * dheight < maxAspectY * dwidth + * + */ + + if (hints.flags & PAspect) + { + if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth) + { + delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc); + if (dwidth + delta <= maxWidth) + dwidth += delta; + else + { + delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc); + if (dheight - delta >= minHeight) + dheight -= delta; + } + } + + if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth) + { + delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc); + if (dheight + delta <= maxHeight) + dheight += delta; + else + { + delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc); + if (dwidth - delta >= minWidth) + dwidth -= delta; + } + } + } + + /* Return computed values */ + *widthp = dwidth; + *heightp = dheight; +} +#undef makemult + + + +/* + * ValidateSizing - Ensures size request respects hints + */ +static int +ValidateSizing (HWND hwnd, WindowPtr pWin, + WPARAM wParam, LPARAM lParam) +{ + WinXSizeHints sizeHints; + RECT *rect; + int iWidth, iHeight; + RECT rcClient, rcWindow; + int iBorderWidthX, iBorderWidthY; + + /* Invalid input checking */ + if (pWin==NULL || lParam==0) + return FALSE; + + /* No size hints, no checking */ + if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints)) + return FALSE; + + /* Avoid divide-by-zero */ + if (sizeHints.flags & PResizeInc) + { + if (sizeHints.width_inc == 0) sizeHints.width_inc = 1; + if (sizeHints.height_inc == 0) sizeHints.height_inc = 1; + } + + rect = (RECT*)lParam; + + iWidth = rect->right - rect->left; + iHeight = rect->bottom - rect->top; + + /* Now remove size of any borders and title bar */ + GetClientRect(hwnd, &rcClient); + GetWindowRect(hwnd, &rcWindow); + iBorderWidthX = (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left); + iBorderWidthY = (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top); + iWidth -= iBorderWidthX; + iHeight -= iBorderWidthY; + + /* Constrain the size to legal values */ + ConstrainSize (sizeHints, &iWidth, &iHeight); + + /* Add back the size of borders and title bar */ + iWidth += iBorderWidthX; + iHeight += iBorderWidthY; + + /* Adjust size according to where we're dragging from */ + switch(wParam) { + case WMSZ_TOP: + case WMSZ_TOPRIGHT: + case WMSZ_BOTTOM: + case WMSZ_BOTTOMRIGHT: + case WMSZ_RIGHT: + rect->right = rect->left + iWidth; + break; + default: + rect->left = rect->right - iWidth; + break; + } + switch(wParam) { + case WMSZ_BOTTOM: + case WMSZ_BOTTOMRIGHT: + case WMSZ_BOTTOMLEFT: + case WMSZ_RIGHT: + case WMSZ_LEFT: + rect->bottom = rect->top + iHeight; + break; + default: + rect->top = rect->bottom - iHeight; + break; + } + return TRUE; +} + +extern Bool winInDestroyWindowsWindow; +static Bool winInRaiseWindow = FALSE; +static void winRaiseWindow(WindowPtr pWin) +{ + if (!winInDestroyWindowsWindow && !winInRaiseWindow) + { + BOOL oldstate = winInRaiseWindow; + XID vlist[1] = { 0 }; + winInRaiseWindow = TRUE; + /* Call configure window directly to make sure it gets processed + * in time + */ + ConfigureWindow(pWin, CWStackMode, vlist, serverClient); + winInRaiseWindow = oldstate; + } +} + +static +void winStartMousePolling(winPrivScreenPtr s_pScreenPriv) +{ + /* + * Timer to poll mouse position. This is needed to make + * programs like xeyes follow the mouse properly when the + * mouse pointer is outside of any X window. + */ + if (g_uipMousePollingTimerID == 0) + g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen, + WIN_POLLING_MOUSE_TIMER_ID, + MOUSE_POLLING_INTERVAL, + NULL); +} + +/* + * winTopLevelWindowProc - Window procedure for all top-level Windows windows. + */ + +LRESULT CALLBACK +winTopLevelWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + POINT ptMouse; + HDC hdcUpdate; + PAINTSTRUCT ps; + WindowPtr pWin = NULL; + winPrivWinPtr pWinPriv = NULL; + ScreenPtr s_pScreen = NULL; + winPrivScreenPtr s_pScreenPriv = NULL; + winScreenInfo *s_pScreenInfo = NULL; + HWND hwndScreen = NULL; + DrawablePtr pDraw = NULL; + winWMMessageRec wmMsg; + Bool fWMMsgInitialized = FALSE; + static Bool s_fTracking = FALSE; + Bool needRestack = FALSE; + LRESULT ret; + +#if CYGDEBUG + winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam); +#endif + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) + { + /* Our X window pointer is valid */ + + /* Get pointers to the drawable and the screen */ + pDraw = &pWin->drawable; + s_pScreen = pWin->drawable.pScreen; + + /* Get a pointer to our window privates */ + pWinPriv = winGetWindowPriv(pWin); + + /* Get pointers to our screen privates and screen info */ + s_pScreenPriv = pWinPriv->pScreenPriv; + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + + /* Get the handle for our screen-sized window */ + hwndScreen = s_pScreenPriv->hwndScreen; + + /* */ + wmMsg.msg = 0; + wmMsg.hwndWindow = hwnd; + wmMsg.iWindow = (Window)GetProp (hwnd, WIN_WID_PROP); + + wmMsg.iX = pDraw->x; + wmMsg.iY = pDraw->y; + wmMsg.iWidth = pDraw->width; + wmMsg.iHeight = pDraw->height; + + fWMMsgInitialized = TRUE; + +#if 0 + /* + * Print some debugging information + */ + + ErrorF ("hWnd %08X\n", hwnd); + ErrorF ("pWin %08X\n", pWin); + ErrorF ("pDraw %08X\n", pDraw); + ErrorF ("\ttype %08X\n", pWin->drawable.type); + ErrorF ("\tclass %08X\n", pWin->drawable.class); + ErrorF ("\tdepth %08X\n", pWin->drawable.depth); + ErrorF ("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel); + ErrorF ("\tid %08X\n", pWin->drawable.id); + ErrorF ("\tx %08X\n", pWin->drawable.x); + ErrorF ("\ty %08X\n", pWin->drawable.y); + ErrorF ("\twidth %08X\n", pWin->drawable.width); + ErrorF ("\thenght %08X\n", pWin->drawable.height); + ErrorF ("\tpScreen %08X\n", pWin->drawable.pScreen); + ErrorF ("\tserialNumber %08X\n", pWin->drawable.serialNumber); + ErrorF ("g_iWindowPrivateKey %p\n", g_iWindowPrivateKey); + ErrorF ("pWinPriv %08X\n", pWinPriv); + ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv); + ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo); + ErrorF ("hwndScreen %08X\n", hwndScreen); +#endif + } + + /* Branch on message type */ + switch (message) + { + case WM_CREATE: + + /* */ + SetProp (hwnd, + WIN_WINDOW_PROP, + (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); + + /* */ + SetProp (hwnd, + WIN_WID_PROP, + (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams)); + + /* + * Make X windows' Z orders sync with Windows windows because + * there can be AlwaysOnTop windows overlapped on the window + * currently being created. + */ + winReorderWindowsMultiWindow (); + + /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */ + { + RECT rWindow; + HRGN hRgnWindow; + GetWindowRect(hwnd, &rWindow); + hRgnWindow = CreateRectRgnIndirect(&rWindow); + SetWindowRgn (hwnd, hRgnWindow, TRUE); + DeleteObject(hRgnWindow); + } + + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)XMING_SIGNATURE); + + return 0; + + case WM_INIT_SYS_MENU: + /* + * Add whatever the setup file wants to for this window + */ + SetupSysMenu ((unsigned long)hwnd); + return 0; + + case WM_SYSCOMMAND: + /* + * Any window menu items go through here + */ + if (HandleCustomWM_COMMAND ((unsigned long)hwnd, LOWORD(wParam))) + { + /* Don't pass customized menus to DefWindowProc */ + return 0; + } + if (wParam == SC_RESTORE || wParam == SC_MAXIMIZE) + { + WINDOWPLACEMENT wndpl; + wndpl.length = sizeof(wndpl); + if (GetWindowPlacement(hwnd, &wndpl) && wndpl.showCmd == SW_SHOWMINIMIZED) + needRestack = TRUE; + } + break; + + case WM_INITMENU: + /* Checks/Unchecks any menu items before they are displayed */ + HandleCustomWM_INITMENU ((unsigned long)hwnd, wParam); + break; + + case WM_ERASEBKGND: + /* + * Pretend that we did erase the background but we don't care, + * since we repaint the entire region anyhow + * This avoids some flickering when resizing. + */ + return TRUE; + + case WM_PAINT: + /* Only paint if our window handle is valid */ + if (hwndScreen == NULL) + break; + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (hwnd, &ps); + /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */ + if (ps.rcPaint.right==0 && ps.rcPaint.bottom==0 && ps.rcPaint.left==0 && ps.rcPaint.top==0) + { + EndPaint (hwnd, &ps); + return 0; + } + + /* Try to copy from the shadow buffer */ + if (!BitBlt (hdcUpdate, + ps.rcPaint.left, ps.rcPaint.top, + ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, + s_pScreenPriv->hdcShadow, + ps.rcPaint.left + pWin->drawable.x, ps.rcPaint.top + pWin->drawable.y, + SRCCOPY)) + { + LPVOID lpMsgBuf; + + /* Display a fancy error message */ + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError (), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, NULL); + + ErrorF ("winTopLevelWindowProc - BitBlt failed: %s\n", + (LPSTR)lpMsgBuf); + LocalFree (lpMsgBuf); + } + + /* EndPaint frees the DC */ + EndPaint (hwnd, &ps); + return 0; + + case WM_MOUSEMOVE: + /* Unpack the client area mouse coordinates */ + ptMouse.x = GET_X_LPARAM(lParam); + ptMouse.y = GET_Y_LPARAM(lParam); + + /* Translate the client area mouse coordinates to screen coordinates */ + ClientToScreen (hwnd, &ptMouse); + + /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */ + ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN); + ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Has the mouse pointer crossed screens? */ + if (s_pScreen != miPointerGetScreen(g_pwinPointer)) + miPointerSetScreen (g_pwinPointer, s_pScreenInfo->dwScreen, + ptMouse.x - s_pScreenInfo->dwXOffset, + ptMouse.y - s_pScreenInfo->dwYOffset); + + /* Are we tracking yet? */ + if (!s_fTracking) + { + TRACKMOUSEEVENT tme; + + /* Setup data structure */ + ZeroMemory (&tme, sizeof (tme)); + tme.cbSize = sizeof (tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hwnd; + + /* Call the tracking function */ + if (!(*g_fpTrackMouseEvent) (&tme)) + ErrorF ("winTopLevelWindowProc - _TrackMouseEvent failed\n"); + + /* Flag that we are tracking now */ + s_fTracking = TRUE; + } + + /* Hide or show the Windows mouse cursor */ + if (g_fSoftwareCursor && g_fCursor) + { + /* Hide Windows cursor */ + g_fCursor = FALSE; + ShowCursor (FALSE); + } + + /* Kill the timer used to poll mouse events */ + if (g_uipMousePollingTimerID != 0) + { + KillTimer (s_pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID); + g_uipMousePollingTimerID = 0; + } + + /* Deliver absolute cursor position to X Server */ + winEnqueueMotion(ptMouse.x - s_pScreenInfo->dwXOffset, + ptMouse.y - s_pScreenInfo->dwYOffset); + + return 0; + + case WM_NCMOUSEMOVE: + /* + * We break instead of returning 0 since we need to call + * DefWindowProc to get the mouse cursor changes + * and min/max/close button highlighting in Windows XP. + * The Platform SDK says that you should return 0 if you + * process this message, but it fails to mention that you + * will give up any default functionality if you do return 0. + */ + + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Non-client mouse movement, show Windows cursor */ + if (g_fSoftwareCursor && !g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + + winStartMousePolling(s_pScreenPriv); + + break; + + case WM_MOUSELEAVE: + /* Mouse has left our client area */ + + /* Flag that we are no longer tracking */ + s_fTracking = FALSE; + + /* Show the mouse cursor, if necessary */ + if (g_fSoftwareCursor && !g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + + winStartMousePolling(s_pScreenPriv); + + return 0; + + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[0] = TRUE; + SetCapture(hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); + + case WM_LBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[0] = FALSE; + ReleaseCapture(); + winStartMousePolling(s_pScreenPriv); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); + + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[1] = TRUE; + SetCapture(hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); + + case WM_MBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[1] = FALSE; + ReleaseCapture(); + winStartMousePolling(s_pScreenPriv); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); + + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[2] = TRUE; + SetCapture(hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); + + case WM_RBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[2] = FALSE; + ReleaseCapture(); + winStartMousePolling(s_pScreenPriv); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); + + case WM_XBUTTONDBLCLK: + case WM_XBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + SetCapture(hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); + + case WM_XBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + ReleaseCapture(); + winStartMousePolling(s_pScreenPriv); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); + + case WM_MOUSEWHEEL: + if (SendMessage(hwnd, WM_NCHITTEST, 0, MAKELONG(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) == HTCLIENT) + { + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + } + else break; + + case WM_SETFOCUS: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + { + /* Get the parent window for transient handling */ + HWND hParent = GetParent(hwnd); + if (hParent && IsIconic(hParent)) ShowWindow (hParent, SW_RESTORE); + } + + winRestoreModeKeyStates (); + + /* Add the keyboard hook if possible */ + if (g_fKeyboardHookLL) + g_fKeyboardHookLL = winInstallKeyboardHookLL (); + return 0; + + case WM_KILLFOCUS: + /* Pop any pressed keys since we are losing keyboard focus */ + winKeybdReleaseKeys (); + + /* Remove our keyboard hook if it is installed */ + winRemoveKeyboardHookLL (); + if (!wParam) + /* Revert the X focus as well, but only if the Windows focus is going to another window */ + DeleteWindowFromAnyEvents(pWin, FALSE); + return 0; + + case WM_SYSDEADCHAR: + case WM_DEADCHAR: + /* + * NOTE: We do nothing with WM_*CHAR messages, + * nor does the root window, so we can just toss these messages. + */ + return 0; + + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + + /* + * Don't pass Alt-F4 key combo to root window, + * let Windows translate to WM_CLOSE and close this top-level window. + * + * NOTE: We purposely don't check the fUseWinKillKey setting because + * it should only apply to the key handling for the root window, + * not for top-level window-manager windows. + * + * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window + * because that is a key combo that no X app should be expecting to + * receive, since it has historically been used to shutdown the X server. + * Passing Ctrl-Alt-Backspace to the root window preserves that + * behavior, assuming that -unixkill has been passed as a parameter. + */ + if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000)) + break; + +#if CYGWINDOWING_DEBUG + if (wParam == VK_ESCAPE) + { + /* Place for debug: put any tests and dumps here */ + WINDOWPLACEMENT windPlace; + RECT rc; + LPRECT pRect; + + windPlace.length = sizeof (WINDOWPLACEMENT); + GetWindowPlacement (hwnd, &windPlace); + pRect = &windPlace.rcNormalPosition; + ErrorF ("\nCYGWINDOWING Dump:\n" + "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x, + pDraw->y, pDraw->width, pDraw->height); + ErrorF ("\twindPlace: (%ld, %ld) - %ldx%ld\n", pRect->left, + pRect->top, pRect->right - pRect->left, + pRect->bottom - pRect->top); + if (GetClientRect (hwnd, &rc)) + { + pRect = &rc; + ErrorF ("\tClientRect: (%ld, %ld) - %ldx%ld\n", pRect->left, + pRect->top, pRect->right - pRect->left, + pRect->bottom - pRect->top); + } + if (GetWindowRect (hwnd, &rc)) + { + pRect = &rc; + ErrorF ("\tWindowRect: (%ld, %ld) - %ldx%ld\n", pRect->left, + pRect->top, pRect->right - pRect->left, + pRect->bottom - pRect->top); + } + ErrorF ("\n"); + } +#endif + + /* Pass the message to the root window */ + return winWindowProc(hwndScreen, message, wParam, lParam); + + case WM_SYSKEYUP: + case WM_KEYUP: + + + /* Pass the message to the root window */ + return winWindowProc(hwndScreen, message, wParam, lParam); + + case WM_HOTKEY: + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_ACTIVATE: + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + + if (LOWORD(wParam) != WA_INACTIVE) + { + /* Raise the window to the top in Z order */ + /* ago: Activate does not mean putting it to front! */ + /* + wmMsg.msg = WM_WM_RAISE; + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + */ + + /* Tell our Window Manager thread to activate the window */ + wmMsg.msg = WM_WM_ACTIVATE; + if (fWMMsgInitialized) + if (!pWin || !pWin->overrideRedirect) /* for OOo menus */ + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + } + /* Prevent the mouse wheel from stalling when another window is minimized */ + if (HIWORD(wParam) == 0 && LOWORD(wParam) == WA_ACTIVE && + (HWND)lParam != NULL && (HWND)lParam != (HWND)GetParent(hwnd)) + SetFocus(hwnd); + return 0; + + case WM_ACTIVATEAPP: + /* + * This message is also sent to the root window + * so we do nothing for individual multiwindow windows + */ + break; + + case WM_CLOSE: + /* Branch on if the window was killed in X already */ + if (pWinPriv->fXKilled) + { + /* Window was killed, go ahead and destroy the window */ + DestroyWindow (hwnd); + } + else + { + /* Tell our Window Manager thread to kill the window */ + wmMsg.msg = WM_WM_KILL; + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + } + return 0; + + case WM_DESTROY: + + /* Branch on if the window was killed in X already */ + if (pWinPriv && !pWinPriv->fXKilled) + { + ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n"); + + /* Tell our Window Manager thread to kill the window */ + wmMsg.msg = WM_WM_KILL; + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + } + + RemoveProp (hwnd, WIN_WINDOW_PROP); + RemoveProp (hwnd, WIN_WID_PROP); + RemoveProp (hwnd, WIN_NEEDMANAGE_PROP); + + break; + + case WM_MOVE: + /* Adjust the X Window to the moved Windows window */ + winAdjustXWindow (pWin, hwnd); + return 0; + + case WM_SHOWWINDOW: + /* Bail out if the window is being hidden */ + if (!wParam) + return 0; + + /* */ + if (!pWin->overrideRedirect) + { + /* Flag that this window needs to be made active when clicked */ + SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); + + if (!(GetWindowLongPtr (hwnd, GWL_EXSTYLE) & WS_EX_APPWINDOW)) + { + HWND zstyle = HWND_NOTOPMOST; + + /* Set the window extended style flags */ + SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW); + + /* Set the transient style flags */ + if (GetParent(hwnd)) SetWindowLongPtr (hwnd, GWL_STYLE, + WS_POPUP | WS_OVERLAPPED | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + /* Set the window standard style flags */ + else SetWindowLongPtr (hwnd, GWL_STYLE, + (WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) + & ~WS_CAPTION & ~WS_SIZEBOX); + + winUpdateWindowPosition (hwnd, FALSE, &zstyle); + SetForegroundWindow (hwnd); + } + wmMsg.msg = WM_WM_MAP3; + } + else /* It is an overridden window so make it top of Z stack */ + { + HWND forHwnd = GetForegroundWindow(); +#if CYGWINDOWING_DEBUG + ErrorF ("overridden window is shown\n"); +#endif + if (forHwnd != NULL) + { + if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)XMING_SIGNATURE) + { + if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) + SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + else + SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + } + } + wmMsg.msg = WM_WM_MAP2; + } + + /* Tell our Window Manager thread to map the window */ + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + + winStartMousePolling(s_pScreenPriv); + + return 0; + + case WM_SIZING: + /* Need to legalize the size according to WM_NORMAL_HINTS */ + /* for applications like xterm */ + return ValidateSizing (hwnd, pWin, wParam, lParam); + + case WM_WINDOWPOSCHANGED: + { + LPWINDOWPOS pWinPos = (LPWINDOWPOS) lParam; + + if (!(pWinPos->flags & SWP_NOZORDER)) + { +#if CYGWINDOWING_DEBUG + winDebug ("\twindow z order was changed\n"); +#endif + if (pWinPos->hwndInsertAfter == HWND_TOP + ||pWinPos->hwndInsertAfter == HWND_TOPMOST + ||pWinPos->hwndInsertAfter == HWND_NOTOPMOST) + { +#if CYGWINDOWING_DEBUG + winDebug ("\traise to top\n"); +#endif + /* Raise the window to the top in Z order */ + winRaiseWindow(pWin); + } + else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) + { + } + else + { + /* Check if this window is top of X windows. */ + HWND hWndAbove = NULL; + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + + for (hWndAbove = pWinPos->hwndInsertAfter; + hWndAbove != NULL; + hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV)) + { + /* Ignore other XWin process's window */ + GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hWndAbove, WIN_WINDOW_PROP) + && !IsWindowVisible (hWndAbove) + && !IsIconic (hWndAbove) ) /* ignore minimized windows */ + break; + } + /* If this is top of X windows in Windows stack, + raise it in X stack. */ + if (hWndAbove == NULL) + { +#if CYGWINDOWING_DEBUG + winDebug ("\traise to top\n"); +#endif + winRaiseWindow(pWin); + } + } + } + } + /* + * Pass the message to DefWindowProc to let the function + * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE. + */ + break; + + case WM_SIZE: + /* see dix/window.c */ +#if CYGWINDOWING_DEBUG + { + char buf[64]; + switch (wParam) + { + case SIZE_MINIMIZED: + strcpy(buf, "SIZE_MINIMIZED"); + break; + case SIZE_MAXIMIZED: + strcpy(buf, "SIZE_MAXIMIZED"); + break; + case SIZE_RESTORED: + strcpy(buf, "SIZE_RESTORED"); + break; + default: + strcpy(buf, "UNKNOWN_FLAG"); + } + ErrorF ("winTopLevelWindowProc - WM_SIZE to %dx%d (%s) - %d ms\n", + (int)LOWORD(lParam), (int)HIWORD(lParam), buf, + (int)(GetTickCount ())); + } +#endif + /* Adjust the X Window to the moved Windows window */ + winAdjustXWindow (pWin, hwnd); + return 0; /* end of WM_SIZE handler */ + + case WM_STYLECHANGING: + /* + When the style changes, adjust the Windows window size so the client area remains the same size, + and adjust the Windows window position so that the client area remains in the same place. + */ + { + RECT newWinRect; + DWORD dwExStyle; + DWORD dwStyle; + DWORD newStyle = ((STYLESTRUCT *)lParam)->styleNew; + WINDOWINFO wi; + + dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); + + winDebug("winTopLevelWindowProc - WM_STYLECHANGING from %08x %08x\n", dwStyle, dwExStyle); + + if (wParam == GWL_EXSTYLE) + dwExStyle = newStyle; + + if (wParam == GWL_STYLE) + dwStyle = newStyle; + + winDebug("winTopLevelWindowProc - WM_STYLECHANGING to %08x %08x\n", dwStyle, dwExStyle); + + /* Get client rect in screen coordinates */ + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(hwnd, &wi); + + winDebug("winTopLevelWindowProc - WM_STYLECHANGING client area {%d, %d, %d, %d}, {%d x %d}\n", wi.rcClient.left, wi.rcClient.top, wi.rcClient.right, wi.rcClient.bottom, wi.rcClient.right - wi.rcClient.left, wi.rcClient.bottom - wi.rcClient.top); + + newWinRect = wi.rcClient; + if (!AdjustWindowRectEx(&newWinRect, dwStyle, FALSE, dwExStyle)) + winDebug("winTopLevelWindowProc - WM_STYLECHANGING AdjustWindowRectEx failed\n"); + + winDebug("winTopLevelWindowProc - WM_STYLECHANGING window area should be {%d, %d, %d, %d}, {%d x %d}\n", newWinRect.left, newWinRect.top, newWinRect.right, newWinRect.bottom, newWinRect.right - newWinRect.left, newWinRect.bottom - newWinRect.top); + + /* + Style change hasn't happened yet, so we can't adjust the window size yet, as the winAdjustXWindow() + which WM_SIZE does will use the current (unchanged) style. Instead make a note to change it when + WM_STYLECHANGED is received... + */ + pWinPriv->hDwp = BeginDeferWindowPos(1); + pWinPriv->hDwp = DeferWindowPos(pWinPriv->hDwp, hwnd, NULL, newWinRect.left, newWinRect.top, newWinRect.right - newWinRect.left, newWinRect.bottom - newWinRect.top, SWP_NOACTIVATE | SWP_NOZORDER); + } + return 0; + + case WM_STYLECHANGED: + { + if (pWinPriv->hDwp) + { + EndDeferWindowPos(pWinPriv->hDwp); + pWinPriv->hDwp = NULL; + } + winDebug("winTopLevelWindowProc - WM_STYLECHANGED done\n"); + } + return 0; + + case WM_MOUSEACTIVATE: + + /* Check if this window needs to be made active when clicked */ + if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - " + "MA_NOACTIVATE\n"); +#endif + + /* */ + return MA_NOACTIVATE; + } + break; + + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) + { + if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle); + return TRUE; + } + break; + + default: + break; + } + + ret = DefWindowProc (hwnd, message, wParam, lParam); + /* + * If the window was minized we get the stack change before the window is restored + * and so it gets lost. Ensure there stacking order is correct. + */ + if (needRestack) + winReorderWindowsMultiWindow(); + return ret; +} diff --git a/xorg-server/hw/xwin/winwindow.h b/xorg-server/hw/xwin/winwindow.h index cf2f93f0a..ebe43091f 100644 --- a/xorg-server/hw/xwin/winwindow.h +++ b/xorg-server/hw/xwin/winwindow.h @@ -79,6 +79,7 @@ typedef struct HWND hWnd; winPrivScreenPtr pScreenPriv; Bool fXKilled; + HDWP hDwp; /* Privates used by primary fb DirectDraw server */ LPDDSURFACEDESC pddsdPrimary; diff --git a/xorg-server/miext/shadow/shpacked.c b/xorg-server/miext/shadow/shpacked.c index e5ebbff64..c37dca175 100644 --- a/xorg-server/miext/shadow/shpacked.c +++ b/xorg-server/miext/shadow/shpacked.c @@ -1,118 +1,118 @@ -/*
- *
- * Copyright © 2000 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include <X11/fonts/font.h>
-#include "dixfontstr.h"
-#include <X11/fonts/fontstruct.h>
-#include "mi.h"
-#include "regionstr.h"
-#include "globals.h"
-#include "gcstruct.h"
-#include "shadow.h"
-#include "fb.h"
-
-void
-shadowUpdatePacked (ScreenPtr pScreen,
- shadowBufPtr pBuf)
-{
- RegionPtr damage = shadowDamage (pBuf);
- PixmapPtr pShadow = pBuf->pPixmap;
- int nbox = RegionNumRects (damage);
- BoxPtr pbox = RegionRects (damage);
- FbBits *shaBase, *shaLine, *sha;
- FbStride shaStride;
- int scrBase, scrLine, scr;
- int shaBpp;
- int shaXoff, shaYoff; /* XXX assumed to be zero */
- int x, y, w, h, width;
- int i;
- FbBits *winBase = NULL, *win;
- CARD32 winSize;
-
- fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
- while (nbox--)
- {
- x = pbox->x1 * shaBpp;
- y = pbox->y1;
- w = (pbox->x2 - pbox->x1) * shaBpp;
- h = pbox->y2 - pbox->y1;
-
- scrLine = (x >> FB_SHIFT);
- shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
-
- x &= FB_MASK;
- w = (w + x + FB_MASK) >> FB_SHIFT;
-
- while (h--)
- {
- winSize = 0;
- scrBase = 0;
- width = w;
- scr = scrLine;
- sha = shaLine;
- while (width) {
- /* how much remains in this window */
- i = scrBase + winSize - scr;
- if (i <= 0 || scr < scrBase)
- {
- winBase = (FbBits *) (*pBuf->window) (pScreen,
- y,
- scr * sizeof (FbBits),
- SHADOW_WINDOW_WRITE,
- &winSize,
- pBuf->closure);
- if(!winBase)
- return;
- scrBase = scr;
- winSize /= sizeof (FbBits);
- i = winSize;
- }
- win = winBase + (scr - scrBase);
- if (i > width)
- i = width;
- width -= i;
- scr += i;
-#define PickBit(a,i) (((a) >> (i)) & 1)
- memcpy(win, sha, i * sizeof(FbBits));
- sha += i;
- }
- shaLine += shaStride;
- y++;
- }
- pbox++;
- }
-}
-
-shadowUpdateProc
-shadowUpdatePackedWeak(void) {
- return shadowUpdatePacked;
-}
+/* + * + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdlib.h> + +#include <X11/X.h> +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/fonts/font.h> +#include "dixfontstr.h" +#include <X11/fonts/fontstruct.h> +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" + +void +shadowUpdatePacked (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage (pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects (damage); + BoxPtr pbox = RegionRects (damage); + FbBits *shaBase, *shaLine, *sha; + FbStride shaStride; + int scrBase, scrLine, scr; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h, width; + int i; + FbBits *winBase = NULL, *win; + CARD32 winSize; + + fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); + while (nbox--) + { + x = pbox->x1 * shaBpp; + y = pbox->y1; + w = (pbox->x2 - pbox->x1) * shaBpp; + h = pbox->y2 - pbox->y1; + + scrLine = (x >> FB_SHIFT); + shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); + + x &= FB_MASK; + w = (w + x + FB_MASK) >> FB_SHIFT; + + while (h--) + { + winSize = 0; + scrBase = 0; + width = w; + scr = scrLine; + sha = shaLine; + while (width) { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) + { + winBase = (FbBits *) (*pBuf->window) (pScreen, + y, + scr * sizeof (FbBits), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if(!winBase) + return; + scrBase = scr; + winSize /= sizeof (FbBits); + i = winSize; + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; +#define PickBit(a,i) (((a) >> (i)) & 1) + memcpy(win, sha, i * sizeof(FbBits)); + sha += i; + } + shaLine += shaStride; + y++; + } + pbox++; + } +} + +shadowUpdateProc +shadowUpdatePackedWeak(void) { + return shadowUpdatePacked; +} diff --git a/xorg-server/miext/shadow/shplanar.c b/xorg-server/miext/shadow/shplanar.c index 381eba986..350405186 100644 --- a/xorg-server/miext/shadow/shplanar.c +++ b/xorg-server/miext/shadow/shplanar.c @@ -1,180 +1,180 @@ -/*
- *
- * Copyright © 2000 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include <X11/fonts/font.h>
-#include "dixfontstr.h"
-#include <X11/fonts/fontstruct.h>
-#include "mi.h"
-#include "regionstr.h"
-#include "globals.h"
-#include "gcstruct.h"
-#include "shadow.h"
-#include "fb.h"
-
-/*
- * 32 4-bit pixels per write
- */
-
-#define PL_SHIFT 7
-#define PL_UNIT (1 << PL_SHIFT)
-#define PL_MASK (PL_UNIT - 1)
-
-/*
- * 32->8 conversion:
- *
- * 7 6 5 4 3 2 1 0
- * A B C D E F G H
- *
- * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * m . . . H . . . G . . . F . . . E . . . D . . . C . . . B . . . A
- * m1 G . . . F . . . E . . . D . . . C . . . B . . . A . . . . . . . m << (7 - (p))
- * m2 . H . . . G . . . F . . . E . . . D . . . C . . . B . . . A . . (m >> (p)) << 2
- * m3 G E C A m1 & 0x80808080
- * m4 H F D B m2 & 0x40404040
- * m5 G H E F C D A B m3 | m4
- * m6 G H E F C D G H A B E F m5 | (m5 >> 20)
- * m7 G H E F C D G H A B C D E F G H m6 | (m6 >> 10)
- */
-
-#if 0
-#define GetBits(p,o,d) {\
- m = sha[o]; \
- m1 = m << (7 - (p)); \
- m2 = (m >> (p)) << 2; \
- m3 = m1 & 0x80808080; \
- m4 = m2 & 0x40404040; \
- m5 = m3 | m4; \
- m6 = m5 | (m5 >> 20); \
- d = m6 | (m6 >> 10); \
-}
-#else
-#define GetBits(p,o,d) {\
- m = sha[o]; \
- m5 = ((m << (7 - (p))) & 0x80808080) | (((m >> (p)) << 2) & 0x40404040); \
- m6 = m5 | (m5 >> 20); \
- d = m6 | (m6 >> 10); \
-}
-#endif
-
-void
-shadowUpdatePlanar4 (ScreenPtr pScreen,
- shadowBufPtr pBuf)
-{
- RegionPtr damage = shadowDamage (pBuf);
- PixmapPtr pShadow = pBuf->pPixmap;
- int nbox = RegionNumRects (damage);
- BoxPtr pbox = RegionRects (damage);
- CARD32 *shaBase, *shaLine, *sha;
- FbStride shaStride;
- int scrBase, scrLine, scr;
- int shaBpp;
- int shaXoff, shaYoff; /* XXX assumed to be zero */
- int x, y, w, h, width;
- int i;
- CARD32 *winBase = NULL, *win;
- CARD32 winSize;
- int plane;
- CARD32 m,m5,m6;
- CARD8 s1, s2, s3, s4;
-
- fbGetStipDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
- while (nbox--)
- {
- x = (pbox->x1) * shaBpp;
- y = (pbox->y1);
- w = (pbox->x2 - pbox->x1) * shaBpp;
- h = pbox->y2 - pbox->y1;
-
- w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT;
- x &= ~PL_MASK;
-
- scrLine = (x >> PL_SHIFT);
- shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
-
- while (h--)
- {
- for (plane = 0; plane < 4; plane++)
- {
- width = w;
- scr = scrLine;
- sha = shaLine;
- winSize = 0;
- scrBase = 0;
- while (width) {
- /* how much remains in this window */
- i = scrBase + winSize - scr;
- if (i <= 0 || scr < scrBase)
- {
- winBase = (CARD32 *) (*pBuf->window) (pScreen,
- y,
- (scr << 4) | (plane),
- SHADOW_WINDOW_WRITE,
- &winSize,
- pBuf->closure);
- if(!winBase)
- return;
- winSize >>= 2;
- scrBase = scr;
- i = winSize;
- }
- win = winBase + (scr - scrBase);
- if (i > width)
- i = width;
- width -= i;
- scr += i;
-
- while (i--)
- {
- GetBits(plane,0,s1);
- GetBits(plane,1,s2);
- GetBits(plane,2,s3);
- GetBits(plane,3,s4);
- *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
- sha += 4;
- }
- }
- }
- shaLine += shaStride;
- y++;
- }
- pbox++;
- }
-}
-
-shadowUpdateProc shadowUpdatePlanar4Weak(void) {
- return shadowUpdatePlanar4;
-}
-
-shadowUpdateProc shadowUpdatePlanar4x8Weak(void) {
- return shadowUpdatePlanar4x8;
-}
+/* + * + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdlib.h> + +#include <X11/X.h> +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/fonts/font.h> +#include "dixfontstr.h" +#include <X11/fonts/fontstruct.h> +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" + +/* + * 32 4-bit pixels per write + */ + +#define PL_SHIFT 7 +#define PL_UNIT (1 << PL_SHIFT) +#define PL_MASK (PL_UNIT - 1) + +/* + * 32->8 conversion: + * + * 7 6 5 4 3 2 1 0 + * A B C D E F G H + * + * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * m . . . H . . . G . . . F . . . E . . . D . . . C . . . B . . . A + * m1 G . . . F . . . E . . . D . . . C . . . B . . . A . . . . . . . m << (7 - (p)) + * m2 . H . . . G . . . F . . . E . . . D . . . C . . . B . . . A . . (m >> (p)) << 2 + * m3 G E C A m1 & 0x80808080 + * m4 H F D B m2 & 0x40404040 + * m5 G H E F C D A B m3 | m4 + * m6 G H E F C D G H A B E F m5 | (m5 >> 20) + * m7 G H E F C D G H A B C D E F G H m6 | (m6 >> 10) + */ + +#if 0 +#define GetBits(p,o,d) {\ + m = sha[o]; \ + m1 = m << (7 - (p)); \ + m2 = (m >> (p)) << 2; \ + m3 = m1 & 0x80808080; \ + m4 = m2 & 0x40404040; \ + m5 = m3 | m4; \ + m6 = m5 | (m5 >> 20); \ + d = m6 | (m6 >> 10); \ +} +#else +#define GetBits(p,o,d) {\ + m = sha[o]; \ + m5 = ((m << (7 - (p))) & 0x80808080) | (((m >> (p)) << 2) & 0x40404040); \ + m6 = m5 | (m5 >> 20); \ + d = m6 | (m6 >> 10); \ +} +#endif + +void +shadowUpdatePlanar4 (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage (pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects (damage); + BoxPtr pbox = RegionRects (damage); + CARD32 *shaBase, *shaLine, *sha; + FbStride shaStride; + int scrBase, scrLine, scr; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h, width; + int i; + CARD32 *winBase = NULL, *win; + CARD32 winSize; + int plane; + CARD32 m,m5,m6; + CARD8 s1, s2, s3, s4; + + fbGetStipDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); + while (nbox--) + { + x = (pbox->x1) * shaBpp; + y = (pbox->y1); + w = (pbox->x2 - pbox->x1) * shaBpp; + h = pbox->y2 - pbox->y1; + + w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT; + x &= ~PL_MASK; + + scrLine = (x >> PL_SHIFT); + shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); + + while (h--) + { + for (plane = 0; plane < 4; plane++) + { + width = w; + scr = scrLine; + sha = shaLine; + winSize = 0; + scrBase = 0; + while (width) { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) + { + winBase = (CARD32 *) (*pBuf->window) (pScreen, + y, + (scr << 4) | (plane), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if(!winBase) + return; + winSize >>= 2; + scrBase = scr; + i = winSize; + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; + + while (i--) + { + GetBits(plane,0,s1); + GetBits(plane,1,s2); + GetBits(plane,2,s3); + GetBits(plane,3,s4); + *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); + sha += 4; + } + } + } + shaLine += shaStride; + y++; + } + pbox++; + } +} + +shadowUpdateProc shadowUpdatePlanar4Weak(void) { + return shadowUpdatePlanar4; +} + +shadowUpdateProc shadowUpdatePlanar4x8Weak(void) { + return shadowUpdatePlanar4x8; +} diff --git a/xorg-server/miext/shadow/shplanar8.c b/xorg-server/miext/shadow/shplanar8.c index 640da5e6f..d0648147a 100644 --- a/xorg-server/miext/shadow/shplanar8.c +++ b/xorg-server/miext/shadow/shplanar8.c @@ -1,175 +1,175 @@ -/*
- *
- * Copyright © 2000 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include <X11/fonts/font.h>
-#include "dixfontstr.h"
-#include <X11/fonts/fontstruct.h>
-#include "mi.h"
-#include "regionstr.h"
-#include "globals.h"
-#include "gcstruct.h"
-#include "shadow.h"
-#include "fb.h"
-
-/*
- * Expose 8bpp depth 4
- */
-
-/*
- * 32->8 conversion:
- *
- * 7 6 5 4 3 2 1 0
- * A B C D E F G H
- *
- * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * m1 D x x x x x x x C x x x x x x x B x x x x x x x A x x x x x x x sha[0] << (7-(p))
- * m2 x x x x H x x x x x x x G x x x x x x x F x x x x x x x E x x x sha[1] << (3-(p))
- * m3 D C B A m1 & 0x80808080
- * m4 H G F E m2 & 0x08080808
- * m5 D H C G B F A E m3 | m4
- * m6 D H C G B F m5 >> 9
- * m7 D H C D G H B C F G A B E F m5 | m6
- * m8 D H C D G H m7 >> 18
- * m9 D H C D G H B C D F G H A B C D E F G H m7 | m8
- */
-
-#define PL_SHIFT 8
-#define PL_UNIT (1 << PL_SHIFT)
-#define PL_MASK (PL_UNIT - 1)
-
-#if 0
-#define GetBits(p,o,d) { \
- CARD32 m1,m2,m3,m4,m5,m6,m7,m8; \
- m1 = sha[o] << (7 - (p)); \
- m2 = sha[(o)+1] << (3 - (p)); \
- m3 = m1 & 0x80808080; \
- m4 = m2 & 0x08080808; \
- m5 = m3 | m4; \
- m6 = m5 >> 9; \
- m7 = m5 | m6; \
- m8 = m7 >> 18; \
- d = m7 | m8; \
-}
-#else
-#define GetBits(p,o,d) { \
- CARD32 m5,m7; \
- m5 = ((sha[o] << (7 - (p))) & 0x80808080) | ((sha[(o)+1] << (3 - (p))) & 0x08080808); \
- m7 = m5 | (m5 >> 9); \
- d = m7 | (m7 >> 18); \
-}
-#endif
-
-void
-shadowUpdatePlanar4x8 (ScreenPtr pScreen,
- shadowBufPtr pBuf)
-{
- RegionPtr damage = shadowDamage (pBuf);
- PixmapPtr pShadow = pBuf->pPixmap;
- int nbox = RegionNumRects (damage);
- BoxPtr pbox = RegionRects (damage);
- CARD32 *shaBase, *shaLine, *sha;
- CARD8 s1, s2, s3, s4;
- FbStride shaStride;
- int scrBase, scrLine, scr;
- int shaBpp;
- int shaXoff, shaYoff; /* XXX assumed to be zero */
- int x, y, w, h, width;
- int i;
- CARD32 *winBase = NULL, *win;
- CARD32 winSize;
- int plane;
-
- fbGetStipDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
- while (nbox--)
- {
- x = pbox->x1 * shaBpp;
- y = pbox->y1;
- w = (pbox->x2 - pbox->x1) * shaBpp;
- h = pbox->y2 - pbox->y1;
-
- w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT;
- x &= ~PL_MASK;
-
- scrLine = (x >> PL_SHIFT);
- shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
-
- while (h--)
- {
- for (plane = 0; plane < 4; plane++)
- {
- width = w;
- scr = scrLine;
- sha = shaLine;
- winSize = 0;
- scrBase = 0;
- while (width) {
- /* how much remains in this window */
- i = scrBase + winSize - scr;
- if (i <= 0 || scr < scrBase)
- {
- winBase = (CARD32 *) (*pBuf->window) (pScreen,
- y,
- (scr << 4) | (plane),
- SHADOW_WINDOW_WRITE,
- &winSize,
- pBuf->closure);
- if(!winBase)
- return;
- winSize >>= 2;
- scrBase = scr;
- i = winSize;
- }
- win = winBase + (scr - scrBase);
- if (i > width)
- i = width;
- width -= i;
- scr += i;
-
- while (i--)
- {
- GetBits(plane,0,s1);
- GetBits(plane,2,s2);
- GetBits(plane,4,s3);
- GetBits(plane,6,s4);
- *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
- sha += 8;
- }
- }
- }
- shaLine += shaStride;
- y++;
- }
- pbox++;
- }
-}
-
+/* + * + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdlib.h> + +#include <X11/X.h> +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/fonts/font.h> +#include "dixfontstr.h" +#include <X11/fonts/fontstruct.h> +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" + +/* + * Expose 8bpp depth 4 + */ + +/* + * 32->8 conversion: + * + * 7 6 5 4 3 2 1 0 + * A B C D E F G H + * + * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * m1 D x x x x x x x C x x x x x x x B x x x x x x x A x x x x x x x sha[0] << (7-(p)) + * m2 x x x x H x x x x x x x G x x x x x x x F x x x x x x x E x x x sha[1] << (3-(p)) + * m3 D C B A m1 & 0x80808080 + * m4 H G F E m2 & 0x08080808 + * m5 D H C G B F A E m3 | m4 + * m6 D H C G B F m5 >> 9 + * m7 D H C D G H B C F G A B E F m5 | m6 + * m8 D H C D G H m7 >> 18 + * m9 D H C D G H B C D F G H A B C D E F G H m7 | m8 + */ + +#define PL_SHIFT 8 +#define PL_UNIT (1 << PL_SHIFT) +#define PL_MASK (PL_UNIT - 1) + +#if 0 +#define GetBits(p,o,d) { \ + CARD32 m1,m2,m3,m4,m5,m6,m7,m8; \ + m1 = sha[o] << (7 - (p)); \ + m2 = sha[(o)+1] << (3 - (p)); \ + m3 = m1 & 0x80808080; \ + m4 = m2 & 0x08080808; \ + m5 = m3 | m4; \ + m6 = m5 >> 9; \ + m7 = m5 | m6; \ + m8 = m7 >> 18; \ + d = m7 | m8; \ +} +#else +#define GetBits(p,o,d) { \ + CARD32 m5,m7; \ + m5 = ((sha[o] << (7 - (p))) & 0x80808080) | ((sha[(o)+1] << (3 - (p))) & 0x08080808); \ + m7 = m5 | (m5 >> 9); \ + d = m7 | (m7 >> 18); \ +} +#endif + +void +shadowUpdatePlanar4x8 (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage (pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects (damage); + BoxPtr pbox = RegionRects (damage); + CARD32 *shaBase, *shaLine, *sha; + CARD8 s1, s2, s3, s4; + FbStride shaStride; + int scrBase, scrLine, scr; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h, width; + int i; + CARD32 *winBase = NULL, *win; + CARD32 winSize; + int plane; + + fbGetStipDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); + while (nbox--) + { + x = pbox->x1 * shaBpp; + y = pbox->y1; + w = (pbox->x2 - pbox->x1) * shaBpp; + h = pbox->y2 - pbox->y1; + + w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT; + x &= ~PL_MASK; + + scrLine = (x >> PL_SHIFT); + shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); + + while (h--) + { + for (plane = 0; plane < 4; plane++) + { + width = w; + scr = scrLine; + sha = shaLine; + winSize = 0; + scrBase = 0; + while (width) { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) + { + winBase = (CARD32 *) (*pBuf->window) (pScreen, + y, + (scr << 4) | (plane), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if(!winBase) + return; + winSize >>= 2; + scrBase = scr; + i = winSize; + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; + + while (i--) + { + GetBits(plane,0,s1); + GetBits(plane,2,s2); + GetBits(plane,4,s3); + GetBits(plane,6,s4); + *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); + sha += 8; + } + } + } + shaLine += shaStride; + y++; + } + pbox++; + } +} + diff --git a/xorg-server/miext/shadow/shrotate.c b/xorg-server/miext/shadow/shrotate.c index 13e9682ba..090120387 100644 --- a/xorg-server/miext/shadow/shrotate.c +++ b/xorg-server/miext/shadow/shrotate.c @@ -1,313 +1,313 @@ -/*
- *
- * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include <X11/fonts/font.h>
-#include "dixfontstr.h"
-#include <X11/fonts/fontstruct.h>
-#include "mi.h"
-#include "regionstr.h"
-#include "globals.h"
-#include "gcstruct.h"
-#include "shadow.h"
-#include "fb.h"
-
-/*
- * These indicate which way the source (shadow) is scanned when
- * walking the screen in a particular direction
- */
-
-#define LEFT_TO_RIGHT 1
-#define RIGHT_TO_LEFT -1
-#define TOP_TO_BOTTOM 2
-#define BOTTOM_TO_TOP -2
-
-void
-shadowUpdateRotatePacked (ScreenPtr pScreen,
- shadowBufPtr pBuf)
-{
- RegionPtr damage = shadowDamage (pBuf);
- PixmapPtr pShadow = pBuf->pPixmap;
- int nbox = RegionNumRects (damage);
- BoxPtr pbox = RegionRects (damage);
- FbBits *shaBits;
- FbStride shaStride;
- int shaBpp;
- int shaXoff, shaYoff;
- int box_x1, box_x2, box_y1, box_y2;
- int sha_x1 = 0, sha_y1 = 0;
- int scr_x1 = 0, scr_x2 = 0, scr_y1 = 0, scr_y2 = 0, scr_w, scr_h;
- int scr_x, scr_y;
- int w;
- int pixelsPerBits;
- int pixelsMask;
- FbStride shaStepOverY = 0, shaStepDownY = 0;
- FbStride shaStepOverX = 0, shaStepDownX = 0;
- FbBits *shaLine, *sha;
- int shaHeight = pShadow->drawable.height;
- int shaWidth = pShadow->drawable.width;
- FbBits shaMask;
- int shaFirstShift, shaShift;
- int o_x_dir;
- int o_y_dir;
- int x_dir;
- int y_dir;
-
- fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff);
- pixelsPerBits = (sizeof (FbBits) * 8) / shaBpp;
- pixelsMask = ~(pixelsPerBits - 1);
- shaMask = FbBitsMask (FB_UNIT-shaBpp, shaBpp);
- /*
- * Compute rotation related constants to walk the shadow
- */
- o_x_dir = LEFT_TO_RIGHT;
- o_y_dir = TOP_TO_BOTTOM;
- if (pBuf->randr & SHADOW_REFLECT_X)
- o_x_dir = -o_x_dir;
- if (pBuf->randr & SHADOW_REFLECT_Y)
- o_y_dir = -o_y_dir;
- switch (pBuf->randr & (SHADOW_ROTATE_ALL)) {
- case SHADOW_ROTATE_0: /* upper left shadow -> upper left screen */
- default:
- x_dir = o_x_dir;
- y_dir = o_y_dir;
- break;
- case SHADOW_ROTATE_90: /* upper right shadow -> upper left screen */
- x_dir = o_y_dir;
- y_dir = -o_x_dir;
- break;
- case SHADOW_ROTATE_180: /* lower right shadow -> upper left screen */
- x_dir = -o_x_dir;
- y_dir = -o_y_dir;
- break;
- case SHADOW_ROTATE_270: /* lower left shadow -> upper left screen */
- x_dir = -o_y_dir;
- y_dir = o_x_dir;
- break;
- }
- switch (x_dir) {
- case LEFT_TO_RIGHT:
- shaStepOverX = shaBpp;
- shaStepOverY = 0;
- break;
- case TOP_TO_BOTTOM:
- shaStepOverX = 0;
- shaStepOverY = shaStride;
- break;
- case RIGHT_TO_LEFT:
- shaStepOverX = -shaBpp;
- shaStepOverY = 0;
- break;
- case BOTTOM_TO_TOP:
- shaStepOverX = 0;
- shaStepOverY = -shaStride;
- break;
- }
- switch (y_dir) {
- case TOP_TO_BOTTOM:
- shaStepDownX = 0;
- shaStepDownY = shaStride;
- break;
- case RIGHT_TO_LEFT:
- shaStepDownX = -shaBpp;
- shaStepDownY = 0;
- break;
- case BOTTOM_TO_TOP:
- shaStepDownX = 0;
- shaStepDownY = -shaStride;
- break;
- case LEFT_TO_RIGHT:
- shaStepDownX = shaBpp;
- shaStepDownY = 0;
- break;
- }
-
- while (nbox--)
- {
- box_x1 = pbox->x1;
- box_y1 = pbox->y1;
- box_x2 = pbox->x2;
- box_y2 = pbox->y2;
- pbox++;
-
- /*
- * Compute screen and shadow locations for this box
- */
- switch (x_dir) {
- case LEFT_TO_RIGHT:
- scr_x1 = box_x1 & pixelsMask;
- scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask;
-
- sha_x1 = scr_x1;
- break;
- case TOP_TO_BOTTOM:
- scr_x1 = box_y1 & pixelsMask;
- scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask;
-
- sha_y1 = scr_x1;
- break;
- case RIGHT_TO_LEFT:
- scr_x1 = (shaWidth - box_x2) & pixelsMask;
- scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask;
-
- sha_x1 = (shaWidth - scr_x1 - 1);
- break;
- case BOTTOM_TO_TOP:
- scr_x1 = (shaHeight - box_y2) & pixelsMask;
- scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask;
-
- sha_y1 = (shaHeight - scr_x1 - 1);
- break;
- }
- switch (y_dir) {
- case TOP_TO_BOTTOM:
- scr_y1 = box_y1;
- scr_y2 = box_y2;
-
- sha_y1 = scr_y1;
- break;
- case RIGHT_TO_LEFT:
- scr_y1 = (shaWidth - box_x2);
- scr_y2 = (shaWidth - box_x1);
-
- sha_x1 = box_x2 - 1;
- break;
- case BOTTOM_TO_TOP:
- scr_y1 = shaHeight - box_y2;
- scr_y2 = shaHeight - box_y1;
-
- sha_y1 = box_y2 - 1;
- break;
- case LEFT_TO_RIGHT:
- scr_y1 = box_x1;
- scr_y2 = box_x2;
-
- sha_x1 = box_x1;
- break;
- }
- scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT;
- scr_h = scr_y2 - scr_y1;
- scr_y = scr_y1;
-
- /* shift amount for first pixel on screen */
- shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp;
-
- /* pointer to shadow data first placed on screen */
- shaLine = (shaBits +
- sha_y1 * shaStride +
- ((sha_x1 * shaBpp) >> FB_SHIFT));
-
- /*
- * Copy the bits, always write across the physical frame buffer
- * to take advantage of write combining.
- */
- while (scr_h--)
- {
- int p;
- FbBits bits;
- FbBits *win;
- int i;
- CARD32 winSize;
-
- sha = shaLine;
- shaShift = shaFirstShift;
- w = scr_w;
- scr_x = scr_x1 * shaBpp >> FB_SHIFT;
-
- while (w)
- {
- /*
- * Map some of this line
- */
- win = (FbBits *) (*pBuf->window) (pScreen,
- scr_y,
- scr_x << 2,
- SHADOW_WINDOW_WRITE,
- &winSize,
- pBuf->closure);
- i = (winSize >> 2);
- if (i > w)
- i = w;
- w -= i;
- scr_x += i;
- /*
- * Copy the portion of the line mapped
- */
- while (i--)
- {
- bits = 0;
- p = pixelsPerBits;
- /*
- * Build one word of output from multiple inputs
- *
- * Note that for 90/270 rotations, this will walk
- * down the shadow hitting each scanline once.
- * This is probably not very efficient.
- */
- while (p--)
- {
- bits = FbScrLeft(bits, shaBpp);
- bits |= FbScrRight (*sha, shaShift) & shaMask;
-
- shaShift -= shaStepOverX;
- if (shaShift >= FB_UNIT)
- {
- shaShift -= FB_UNIT;
- sha--;
- }
- else if (shaShift < 0)
- {
- shaShift += FB_UNIT;
- sha++;
- }
- sha += shaStepOverY;
- }
- *win++ = bits;
- }
- }
- scr_y++;
- shaFirstShift -= shaStepDownX;
- if (shaFirstShift >= FB_UNIT)
- {
- shaFirstShift -= FB_UNIT;
- shaLine--;
- }
- else if (shaFirstShift < 0)
- {
- shaFirstShift += FB_UNIT;
- shaLine++;
- }
- shaLine += shaStepDownY;
- }
- }
-}
-
-shadowUpdateProc shadowUpdateRotatePackedWeak(void) {
- return shadowUpdateRotatePacked;
-}
+/* + * + * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/fonts/font.h> +#include "dixfontstr.h" +#include <X11/fonts/fontstruct.h> +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" + +/* + * These indicate which way the source (shadow) is scanned when + * walking the screen in a particular direction + */ + +#define LEFT_TO_RIGHT 1 +#define RIGHT_TO_LEFT -1 +#define TOP_TO_BOTTOM 2 +#define BOTTOM_TO_TOP -2 + +void +shadowUpdateRotatePacked (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage (pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects (damage); + BoxPtr pbox = RegionRects (damage); + FbBits *shaBits; + FbStride shaStride; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int box_x1, box_x2, box_y1, box_y2; + int sha_x1 = 0, sha_y1 = 0; + int scr_x1 = 0, scr_x2 = 0, scr_y1 = 0, scr_y2 = 0, scr_w, scr_h; + int scr_x, scr_y; + int w; + int pixelsPerBits; + int pixelsMask; + FbStride shaStepOverY = 0, shaStepDownY = 0; + FbStride shaStepOverX = 0, shaStepDownX = 0; + FbBits *shaLine, *sha; + int shaHeight = pShadow->drawable.height; + int shaWidth = pShadow->drawable.width; + FbBits shaMask; + int shaFirstShift, shaShift; + int o_x_dir; + int o_y_dir; + int x_dir; + int y_dir; + + fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff); + pixelsPerBits = (sizeof (FbBits) * 8) / shaBpp; + pixelsMask = ~(pixelsPerBits - 1); + shaMask = FbBitsMask (FB_UNIT-shaBpp, shaBpp); + /* + * Compute rotation related constants to walk the shadow + */ + o_x_dir = LEFT_TO_RIGHT; + o_y_dir = TOP_TO_BOTTOM; + if (pBuf->randr & SHADOW_REFLECT_X) + o_x_dir = -o_x_dir; + if (pBuf->randr & SHADOW_REFLECT_Y) + o_y_dir = -o_y_dir; + switch (pBuf->randr & (SHADOW_ROTATE_ALL)) { + case SHADOW_ROTATE_0: /* upper left shadow -> upper left screen */ + default: + x_dir = o_x_dir; + y_dir = o_y_dir; + break; + case SHADOW_ROTATE_90: /* upper right shadow -> upper left screen */ + x_dir = o_y_dir; + y_dir = -o_x_dir; + break; + case SHADOW_ROTATE_180: /* lower right shadow -> upper left screen */ + x_dir = -o_x_dir; + y_dir = -o_y_dir; + break; + case SHADOW_ROTATE_270: /* lower left shadow -> upper left screen */ + x_dir = -o_y_dir; + y_dir = o_x_dir; + break; + } + switch (x_dir) { + case LEFT_TO_RIGHT: + shaStepOverX = shaBpp; + shaStepOverY = 0; + break; + case TOP_TO_BOTTOM: + shaStepOverX = 0; + shaStepOverY = shaStride; + break; + case RIGHT_TO_LEFT: + shaStepOverX = -shaBpp; + shaStepOverY = 0; + break; + case BOTTOM_TO_TOP: + shaStepOverX = 0; + shaStepOverY = -shaStride; + break; + } + switch (y_dir) { + case TOP_TO_BOTTOM: + shaStepDownX = 0; + shaStepDownY = shaStride; + break; + case RIGHT_TO_LEFT: + shaStepDownX = -shaBpp; + shaStepDownY = 0; + break; + case BOTTOM_TO_TOP: + shaStepDownX = 0; + shaStepDownY = -shaStride; + break; + case LEFT_TO_RIGHT: + shaStepDownX = shaBpp; + shaStepDownY = 0; + break; + } + + while (nbox--) + { + box_x1 = pbox->x1; + box_y1 = pbox->y1; + box_x2 = pbox->x2; + box_y2 = pbox->y2; + pbox++; + + /* + * Compute screen and shadow locations for this box + */ + switch (x_dir) { + case LEFT_TO_RIGHT: + scr_x1 = box_x1 & pixelsMask; + scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask; + + sha_x1 = scr_x1; + break; + case TOP_TO_BOTTOM: + scr_x1 = box_y1 & pixelsMask; + scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask; + + sha_y1 = scr_x1; + break; + case RIGHT_TO_LEFT: + scr_x1 = (shaWidth - box_x2) & pixelsMask; + scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask; + + sha_x1 = (shaWidth - scr_x1 - 1); + break; + case BOTTOM_TO_TOP: + scr_x1 = (shaHeight - box_y2) & pixelsMask; + scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask; + + sha_y1 = (shaHeight - scr_x1 - 1); + break; + } + switch (y_dir) { + case TOP_TO_BOTTOM: + scr_y1 = box_y1; + scr_y2 = box_y2; + + sha_y1 = scr_y1; + break; + case RIGHT_TO_LEFT: + scr_y1 = (shaWidth - box_x2); + scr_y2 = (shaWidth - box_x1); + + sha_x1 = box_x2 - 1; + break; + case BOTTOM_TO_TOP: + scr_y1 = shaHeight - box_y2; + scr_y2 = shaHeight - box_y1; + + sha_y1 = box_y2 - 1; + break; + case LEFT_TO_RIGHT: + scr_y1 = box_x1; + scr_y2 = box_x2; + + sha_x1 = box_x1; + break; + } + scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT; + scr_h = scr_y2 - scr_y1; + scr_y = scr_y1; + + /* shift amount for first pixel on screen */ + shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp; + + /* pointer to shadow data first placed on screen */ + shaLine = (shaBits + + sha_y1 * shaStride + + ((sha_x1 * shaBpp) >> FB_SHIFT)); + + /* + * Copy the bits, always write across the physical frame buffer + * to take advantage of write combining. + */ + while (scr_h--) + { + int p; + FbBits bits; + FbBits *win; + int i; + CARD32 winSize; + + sha = shaLine; + shaShift = shaFirstShift; + w = scr_w; + scr_x = scr_x1 * shaBpp >> FB_SHIFT; + + while (w) + { + /* + * Map some of this line + */ + win = (FbBits *) (*pBuf->window) (pScreen, + scr_y, + scr_x << 2, + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + i = (winSize >> 2); + if (i > w) + i = w; + w -= i; + scr_x += i; + /* + * Copy the portion of the line mapped + */ + while (i--) + { + bits = 0; + p = pixelsPerBits; + /* + * Build one word of output from multiple inputs + * + * Note that for 90/270 rotations, this will walk + * down the shadow hitting each scanline once. + * This is probably not very efficient. + */ + while (p--) + { + bits = FbScrLeft(bits, shaBpp); + bits |= FbScrRight (*sha, shaShift) & shaMask; + + shaShift -= shaStepOverX; + if (shaShift >= FB_UNIT) + { + shaShift -= FB_UNIT; + sha--; + } + else if (shaShift < 0) + { + shaShift += FB_UNIT; + sha++; + } + sha += shaStepOverY; + } + *win++ = bits; + } + } + scr_y++; + shaFirstShift -= shaStepDownX; + if (shaFirstShift >= FB_UNIT) + { + shaFirstShift -= FB_UNIT; + shaLine--; + } + else if (shaFirstShift < 0) + { + shaFirstShift += FB_UNIT; + shaLine++; + } + shaLine += shaStepDownY; + } + } +} + +shadowUpdateProc shadowUpdateRotatePackedWeak(void) { + return shadowUpdateRotatePacked; +} diff --git a/xorg-server/miext/shadow/shrotpack.h b/xorg-server/miext/shadow/shrotpack.h index 1a8af6200..16afff184 100644 --- a/xorg-server/miext/shadow/shrotpack.h +++ b/xorg-server/miext/shadow/shrotpack.h @@ -1,187 +1,187 @@ -/*
- *
- * Copyright © 2000 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.
- */
-
-/*
- * Thanks to Daniel Chemko <dchemko@intrinsyc.com> for making the 90 and 180
- * orientations work.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include <X11/fonts/font.h>
-#include "dixfontstr.h"
-#include <X11/fonts/fontstruct.h>
-#include "mi.h"
-#include "regionstr.h"
-#include "globals.h"
-#include "gcstruct.h"
-#include "shadow.h"
-#include "fb.h"
-
-#define DANDEBUG 0
-
-#if ROTATE == 270
-
-#define SCRLEFT(x,y,w,h) (pScreen->height - ((y) + (h)))
-#define SCRY(x,y,w,h) (x)
-#define SCRWIDTH(x,y,w,h) (h)
-#define FIRSTSHA(x,y,w,h) (((y) + (h) - 1) * shaStride + (x))
-#define STEPDOWN(x,y,w,h) ((w)--)
-#define NEXTY(x,y,w,h) ((x)++)
-#define SHASTEPX(stride) -(stride)
-#define SHASTEPY(stride) (1)
-
-#elif ROTATE == 90
-
-#define SCRLEFT(x,y,w,h) (y)
-#define SCRY(x,y,w,h) (pScreen->width - ((x) + (w)) - 1)
-#define SCRWIDTH(x,y,w,h) (h)
-#define FIRSTSHA(x,y,w,h) ((y) * shaStride + (x + w - 1))
-#define STEPDOWN(x,y,w,h) ((w)--)
-#define NEXTY(x,y,w,h) ((void)(x))
-#define SHASTEPX(stride) (stride)
-#define SHASTEPY(stride) (-1)
-
-#elif ROTATE == 180
-
-#define SCRLEFT(x,y,w,h) (pScreen->width - ((x) + (w)))
-#define SCRY(x,y,w,h) (pScreen->height - ((y) + (h)) - 1)
-#define SCRWIDTH(x,y,w,h) (w)
-#define FIRSTSHA(x,y,w,h) ((y + h - 1) * shaStride + (x + w - 1))
-#define STEPDOWN(x,y,w,h) ((h)--)
-#define NEXTY(x,y,w,h) ((void)(y))
-#define SHASTEPX(stride) (-1)
-#define SHASTEPY(stride) -(stride)
-
-#else
-
-#define SCRLEFT(x,y,w,h) (x)
-#define SCRY(x,y,w,h) (y)
-#define SCRWIDTH(x,y,w,h) (w)
-#define FIRSTSHA(x,y,w,h) ((y) * shaStride + (x))
-#define STEPDOWN(x,y,w,h) ((h)--)
-#define NEXTY(x,y,w,h) ((y)++)
-#define SHASTEPX(stride) (1)
-#define SHASTEPY(stride) (stride)
-
-#endif
-
-void
-FUNC (ScreenPtr pScreen,
- shadowBufPtr pBuf)
-{
- RegionPtr damage = shadowDamage (pBuf);
- PixmapPtr pShadow = pBuf->pPixmap;
- int nbox = RegionNumRects (damage);
- BoxPtr pbox = RegionRects (damage);
- FbBits *shaBits;
- Data *shaBase, *shaLine, *sha;
- FbStride shaStride;
- int scrBase, scrLine, scr;
- int shaBpp;
- int shaXoff, shaYoff; /* XXX assumed to be zero */
- int x, y, w, h, width;
- int i;
- Data *winBase = NULL, *win;
- CARD32 winSize;
-
- fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff);
- shaBase = (Data *) shaBits;
- shaStride = shaStride * sizeof (FbBits) / sizeof (Data);
-#if (DANDEBUG > 1)
- ErrorF ("-> Entering Shadow Update:\r\n |- Origins: pShadow=%x, pScreen=%x, damage=%x\r\n |- Metrics: shaStride=%d, shaBase=%x, shaBpp=%d\r\n | \n", pShadow, pScreen, damage, shaStride, shaBase, shaBpp);
-#endif
- while (nbox--)
- {
- x = pbox->x1;
- y = pbox->y1;
- w = (pbox->x2 - pbox->x1);
- h = pbox->y2 - pbox->y1;
-
-#if (DANDEBUG > 2)
- ErrorF (" |-> Redrawing box - Metrics: X=%d, Y=%d, Width=%d, Height=%d\n", x, y, w, h);
-#endif
- scrLine = SCRLEFT(x,y,w,h);
- shaLine = shaBase + FIRSTSHA(x,y,w,h);
-
- while (STEPDOWN(x,y,w,h))
- {
- winSize = 0;
- scrBase = 0;
- width = SCRWIDTH(x,y,w,h);
- scr = scrLine;
- sha = shaLine;
-#if (DANDEBUG > 3)
- ErrorF (" | |-> StepDown - Metrics: width=%d, scr=%x, sha=%x\n", width, scr, sha);
-#endif
- while (width)
- {
- /* how much remains in this window */
- i = scrBase + winSize - scr;
- if (i <= 0 || scr < scrBase)
- {
- winBase = (Data *) (*pBuf->window) (pScreen,
- SCRY(x,y,w,h),
- scr * sizeof (Data),
- SHADOW_WINDOW_WRITE,
- &winSize,
- pBuf->closure);
- if(!winBase)
- return;
- scrBase = scr;
- winSize /= sizeof (Data);
- i = winSize;
-#if(DANDEBUG > 4)
- ErrorF (" | | |-> Starting New Line - Metrics: winBase=%x, scrBase=%x, winSize=%d\r\n | | | Xstride=%d, Ystride=%d, w=%d h=%d\n", winBase, scrBase, winSize, SHASTEPX(shaStride), SHASTEPY(shaStride), w, h);
-#endif
- }
- win = winBase + (scr - scrBase);
- if (i > width)
- i = width;
- width -= i;
- scr += i;
-#if(DANDEBUG > 5)
- ErrorF (" | | |-> Writing Line - Metrics: win=%x, sha=%x\n", win, sha);
-#endif
- while (i--)
- {
-#if(DANDEBUG > 6)
- ErrorF (" | | |-> Writing Pixel - Metrics: win=%x, sha=%d, remaining=%d\n", win, sha, i);
-#endif
- *win++ = *sha;
- sha += SHASTEPX(shaStride);
- } /* i */
- } /* width */
- shaLine += SHASTEPY(shaStride);
- NEXTY(x,y,w,h);
- } /* STEPDOWN */
- pbox++;
- } /* nbox */
-}
+/* + * + * Copyright © 2000 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. + */ + +/* + * Thanks to Daniel Chemko <dchemko@intrinsyc.com> for making the 90 and 180 + * orientations work. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdlib.h> + +#include <X11/X.h> +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/fonts/font.h> +#include "dixfontstr.h" +#include <X11/fonts/fontstruct.h> +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" + +#define DANDEBUG 0 + +#if ROTATE == 270 + +#define SCRLEFT(x,y,w,h) (pScreen->height - ((y) + (h))) +#define SCRY(x,y,w,h) (x) +#define SCRWIDTH(x,y,w,h) (h) +#define FIRSTSHA(x,y,w,h) (((y) + (h) - 1) * shaStride + (x)) +#define STEPDOWN(x,y,w,h) ((w)--) +#define NEXTY(x,y,w,h) ((x)++) +#define SHASTEPX(stride) -(stride) +#define SHASTEPY(stride) (1) + +#elif ROTATE == 90 + +#define SCRLEFT(x,y,w,h) (y) +#define SCRY(x,y,w,h) (pScreen->width - ((x) + (w)) - 1) +#define SCRWIDTH(x,y,w,h) (h) +#define FIRSTSHA(x,y,w,h) ((y) * shaStride + (x + w - 1)) +#define STEPDOWN(x,y,w,h) ((w)--) +#define NEXTY(x,y,w,h) ((void)(x)) +#define SHASTEPX(stride) (stride) +#define SHASTEPY(stride) (-1) + +#elif ROTATE == 180 + +#define SCRLEFT(x,y,w,h) (pScreen->width - ((x) + (w))) +#define SCRY(x,y,w,h) (pScreen->height - ((y) + (h)) - 1) +#define SCRWIDTH(x,y,w,h) (w) +#define FIRSTSHA(x,y,w,h) ((y + h - 1) * shaStride + (x + w - 1)) +#define STEPDOWN(x,y,w,h) ((h)--) +#define NEXTY(x,y,w,h) ((void)(y)) +#define SHASTEPX(stride) (-1) +#define SHASTEPY(stride) -(stride) + +#else + +#define SCRLEFT(x,y,w,h) (x) +#define SCRY(x,y,w,h) (y) +#define SCRWIDTH(x,y,w,h) (w) +#define FIRSTSHA(x,y,w,h) ((y) * shaStride + (x)) +#define STEPDOWN(x,y,w,h) ((h)--) +#define NEXTY(x,y,w,h) ((y)++) +#define SHASTEPX(stride) (1) +#define SHASTEPY(stride) (stride) + +#endif + +void +FUNC (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage (pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects (damage); + BoxPtr pbox = RegionRects (damage); + FbBits *shaBits; + Data *shaBase, *shaLine, *sha; + FbStride shaStride; + int scrBase, scrLine, scr; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h, width; + int i; + Data *winBase = NULL, *win; + CARD32 winSize; + + fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff); + shaBase = (Data *) shaBits; + shaStride = shaStride * sizeof (FbBits) / sizeof (Data); +#if (DANDEBUG > 1) + ErrorF ("-> Entering Shadow Update:\r\n |- Origins: pShadow=%x, pScreen=%x, damage=%x\r\n |- Metrics: shaStride=%d, shaBase=%x, shaBpp=%d\r\n | \n", pShadow, pScreen, damage, shaStride, shaBase, shaBpp); +#endif + while (nbox--) + { + x = pbox->x1; + y = pbox->y1; + w = (pbox->x2 - pbox->x1); + h = pbox->y2 - pbox->y1; + +#if (DANDEBUG > 2) + ErrorF (" |-> Redrawing box - Metrics: X=%d, Y=%d, Width=%d, Height=%d\n", x, y, w, h); +#endif + scrLine = SCRLEFT(x,y,w,h); + shaLine = shaBase + FIRSTSHA(x,y,w,h); + + while (STEPDOWN(x,y,w,h)) + { + winSize = 0; + scrBase = 0; + width = SCRWIDTH(x,y,w,h); + scr = scrLine; + sha = shaLine; +#if (DANDEBUG > 3) + ErrorF (" | |-> StepDown - Metrics: width=%d, scr=%x, sha=%x\n", width, scr, sha); +#endif + while (width) + { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) + { + winBase = (Data *) (*pBuf->window) (pScreen, + SCRY(x,y,w,h), + scr * sizeof (Data), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if(!winBase) + return; + scrBase = scr; + winSize /= sizeof (Data); + i = winSize; +#if(DANDEBUG > 4) + ErrorF (" | | |-> Starting New Line - Metrics: winBase=%x, scrBase=%x, winSize=%d\r\n | | | Xstride=%d, Ystride=%d, w=%d h=%d\n", winBase, scrBase, winSize, SHASTEPX(shaStride), SHASTEPY(shaStride), w, h); +#endif + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; +#if(DANDEBUG > 5) + ErrorF (" | | |-> Writing Line - Metrics: win=%x, sha=%x\n", win, sha); +#endif + while (i--) + { +#if(DANDEBUG > 6) + ErrorF (" | | |-> Writing Pixel - Metrics: win=%x, sha=%d, remaining=%d\n", win, sha, i); +#endif + *win++ = *sha; + sha += SHASTEPX(shaStride); + } /* i */ + } /* width */ + shaLine += SHASTEPY(shaStride); + NEXTY(x,y,w,h); + } /* STEPDOWN */ + pbox++; + } /* nbox */ +} diff --git a/xorg-server/miext/shadow/shrotpackYX.h b/xorg-server/miext/shadow/shrotpackYX.h index 7005b1457..d7b01ec2a 100644 --- a/xorg-server/miext/shadow/shrotpackYX.h +++ b/xorg-server/miext/shadow/shrotpackYX.h @@ -1,160 +1,160 @@ -/*
- * Copyright © 2004 Philip Blundell
- *
- * 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 Philip Blundell not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Philip Blundell makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * PHILIP BLUNDELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL PHILIP BLUNDELL 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 <X11/X.h>
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "dixfontstr.h"
-#include "mi.h"
-#include "regionstr.h"
-#include "globals.h"
-#include "gcstruct.h"
-#include "shadow.h"
-#include "fb.h"
-
-#if ROTATE == 270
-
-#define WINSTEPX(stride) (stride)
-#define WINSTART(x,y) (((pScreen->height - 1) - y) + (x * winStride))
-#define WINSTEPY() -1
-
-#elif ROTATE == 90
-
-#define WINSTEPX(stride) (-stride)
-#define WINSTEPY() 1
-#define WINSTART(x,y) (((pScreen->width - 1 - x) * winStride) + y)
-
-#else
-
-#error This rotation is not supported here
-
-#endif
-
-#ifdef __arm__
-#define PREFETCH
-#endif
-
-void
-FUNC (ScreenPtr pScreen,
- shadowBufPtr pBuf);
-
-void
-FUNC (ScreenPtr pScreen,
- shadowBufPtr pBuf)
-{
- RegionPtr damage = shadowDamage(pBuf);
- PixmapPtr pShadow = pBuf->pPixmap;
- int nbox = RegionNumRects (damage);
- BoxPtr pbox = RegionRects (damage);
- FbBits *shaBits;
- Data *shaBase, *shaLine, *sha;
- FbStride shaStride, winStride;
- int shaBpp;
- int shaXoff, shaYoff; /* XXX assumed to be zero */
- int x, y, w, h;
- Data *winBase, *win, *winLine;
- CARD32 winSize;
-
- fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff);
- shaBase = (Data *) shaBits;
- shaStride = shaStride * sizeof (FbBits) / sizeof (Data);
-
- winBase = (Data *) (*pBuf->window) (pScreen, 0, 0,
- SHADOW_WINDOW_WRITE,
- &winSize, pBuf->closure);
- winStride = (Data *) (*pBuf->window) (pScreen, 1, 0,
- SHADOW_WINDOW_WRITE,
- &winSize, pBuf->closure) - winBase;
-
- while (nbox--)
- {
- x = pbox->x1;
- y = pbox->y1;
- w = (pbox->x2 - pbox->x1);
- h = pbox->y2 - pbox->y1;
-
- shaLine = shaBase + (y * shaStride) + x;
-#ifdef PREFETCH
- __builtin_prefetch (shaLine);
-#endif
- winLine = winBase + WINSTART(x, y);
-
- while (h--)
- {
- sha = shaLine;
- win = winLine;
-
- while (sha < (shaLine + w - 16))
- {
-#ifdef PREFETCH
- __builtin_prefetch (sha + shaStride);
-#endif
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
-
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
-
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
-
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
- *win = *sha++;
- win += WINSTEPX(winStride);
- }
-
- while (sha < (shaLine + w))
- {
- *win = *sha++;
- win += WINSTEPX(winStride);
- }
-
- y++;
- shaLine += shaStride;
- winLine += WINSTEPY();
- }
- pbox++;
- } /* nbox */
-}
+/* + * Copyright © 2004 Philip Blundell + * + * 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 Philip Blundell not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Philip Blundell makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * PHILIP BLUNDELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL PHILIP BLUNDELL 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 <X11/X.h> +#include "scrnintstr.h" +#include "windowstr.h" +#include "dixfontstr.h" +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" + +#if ROTATE == 270 + +#define WINSTEPX(stride) (stride) +#define WINSTART(x,y) (((pScreen->height - 1) - y) + (x * winStride)) +#define WINSTEPY() -1 + +#elif ROTATE == 90 + +#define WINSTEPX(stride) (-stride) +#define WINSTEPY() 1 +#define WINSTART(x,y) (((pScreen->width - 1 - x) * winStride) + y) + +#else + +#error This rotation is not supported here + +#endif + +#ifdef __arm__ +#define PREFETCH +#endif + +void +FUNC (ScreenPtr pScreen, + shadowBufPtr pBuf); + +void +FUNC (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects (damage); + BoxPtr pbox = RegionRects (damage); + FbBits *shaBits; + Data *shaBase, *shaLine, *sha; + FbStride shaStride, winStride; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h; + Data *winBase, *win, *winLine; + CARD32 winSize; + + fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff); + shaBase = (Data *) shaBits; + shaStride = shaStride * sizeof (FbBits) / sizeof (Data); + + winBase = (Data *) (*pBuf->window) (pScreen, 0, 0, + SHADOW_WINDOW_WRITE, + &winSize, pBuf->closure); + winStride = (Data *) (*pBuf->window) (pScreen, 1, 0, + SHADOW_WINDOW_WRITE, + &winSize, pBuf->closure) - winBase; + + while (nbox--) + { + x = pbox->x1; + y = pbox->y1; + w = (pbox->x2 - pbox->x1); + h = pbox->y2 - pbox->y1; + + shaLine = shaBase + (y * shaStride) + x; +#ifdef PREFETCH + __builtin_prefetch (shaLine); +#endif + winLine = winBase + WINSTART(x, y); + + while (h--) + { + sha = shaLine; + win = winLine; + + while (sha < (shaLine + w - 16)) + { +#ifdef PREFETCH + __builtin_prefetch (sha + shaStride); +#endif + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + *win = *sha++; + win += WINSTEPX(winStride); + } + + while (sha < (shaLine + w)) + { + *win = *sha++; + win += WINSTEPX(winStride); + } + + y++; + shaLine += shaStride; + winLine += WINSTEPY(); + } + pbox++; + } /* nbox */ +} diff --git a/xorg-server/os/Makefile.am b/xorg-server/os/Makefile.am index 91ca110f4..ef9ecddcf 100644 --- a/xorg-server/os/Makefile.am +++ b/xorg-server/os/Makefile.am @@ -51,11 +51,7 @@ dtrace.o: $(top_srcdir)/dix/Xserver.d $(am_libos_la_OBJECTS) noinst_PROGRAMS = os.O +os_O_SOURCES = os.O: dtrace.o $(am_libos_la_OBJECTS) $(AM_V_GEN)ld -r -o $@ dtrace.o .libs/*.o endif - -os.c: - touch $@ - -CLEANFILES = os.c diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am index 5574e7d1e..370e09a18 100644 --- a/xorg-server/test/Makefile.am +++ b/xorg-server/test/Makefile.am @@ -7,7 +7,10 @@ check_LTLIBRARIES = libxservertest.la TESTS=$(noinst_PROGRAMS) AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@ -INCLUDES = @XORG_INCS@ +INCLUDES = $(XORG_INCS) -I$(top_srcdir)/hw/xfree86/parser \ + -I$(top_srcdir)/miext/cw -I$(top_srcdir)/hw/xfree86/ddc \ + -I$(top_srcdir)/hw/xfree86/i2c -I$(top_srcdir)/hw/xfree86/modes \ + -I$(top_srcdir)/hw/xfree86/ramdac TEST_LDADD=libxservertest.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) if SPECIAL_DTRACE_OBJECTS @@ -21,6 +24,7 @@ list_LDADD=$(TEST_LDADD) misc_LDADD=$(TEST_LDADD) fixes_LDADD=$(TEST_LDADD) +nodist_libxservertest_la_SOURCES = $(top_builddir)/hw/xfree86/sdksyms.c libxservertest_la_LIBADD = \ $(XSERVER_LIBS) \ $(top_builddir)/hw/xfree86/loader/libloader.la \ @@ -33,14 +37,8 @@ libxservertest_la_LIBADD = \ $(top_builddir)/hw/xfree86/ddc/libddc.la \ $(top_builddir)/hw/xfree86/i2c/libi2c.la \ $(top_builddir)/hw/xfree86/dixmods/libxorgxkb.la \ - $(top_builddir)/hw/xfree86/libxorg.la \ $(top_builddir)/mi/libmi.la \ $(top_builddir)/os/libos.la \ @XORG_LIBS@ endif endif - -CLEANFILES=libxservertest.c - -libxservertest.c: - touch $@ diff --git a/xorg-server/xfixes/cursor.c b/xorg-server/xfixes/cursor.c index 01eb70d92..ecbed4016 100644 --- a/xorg-server/xfixes/cursor.c +++ b/xorg-server/xfixes/cursor.c @@ -196,8 +196,8 @@ CursorCloseScreen (int index, ScreenPtr pScreen) { CursorScreenPtr cs = GetCursorScreen (pScreen); Bool ret; - CloseScreenProcPtr close_proc; - DisplayCursorProcPtr display_proc; + _X_UNUSED CloseScreenProcPtr close_proc; + _X_UNUSED DisplayCursorProcPtr display_proc; ConstrainCursorHarderProcPtr constrain_proc; Unwrap (cs, pScreen, CloseScreen, close_proc); diff --git a/xorg-server/xfixes/region.c b/xorg-server/xfixes/region.c index f49349629..be2d391dd 100644 --- a/xorg-server/xfixes/region.c +++ b/xorg-server/xfixes/region.c @@ -756,12 +756,10 @@ ProcXFixesSetPictureClipRegion (ClientPtr client) { PicturePtr pPicture; RegionPtr pRegion; - ScreenPtr pScreen; REQUEST(xXFixesSetPictureClipRegionReq); REQUEST_SIZE_MATCH (xXFixesSetPictureClipRegionReq); VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess); - pScreen = pPicture->pDrawable->pScreen; VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess); return SetPictureClipRegion (pPicture, stuff->xOrigin, stuff->yOrigin, diff --git a/xorg-server/xkeyboard-config/compat/xfree86 b/xorg-server/xkeyboard-config/compat/xfree86 index c511ae264..cf4a8b22b 100644 --- a/xorg-server/xkeyboard-config/compat/xfree86 +++ b/xorg-server/xkeyboard-config/compat/xfree86 @@ -1,56 +1,63 @@ -// XFree86 special keysyms
-
-default partial xkb_compatibility "basic" {
-
- interpret.repeat= True;
-
- interpret XF86_Switch_VT_1 {
- action = SwitchScreen(Screen=1, !SameServer);
- };
- interpret XF86_Switch_VT_2 {
- action = SwitchScreen(Screen=2, !SameServer);
- };
- interpret XF86_Switch_VT_3 {
- action = SwitchScreen(Screen=3, !SameServer);
- };
- interpret XF86_Switch_VT_4 {
- action = SwitchScreen(Screen=4, !SameServer);
- };
- interpret XF86_Switch_VT_5 {
- action = SwitchScreen(Screen=5, !SameServer);
- };
- interpret XF86_Switch_VT_6 {
- action = SwitchScreen(Screen=6, !SameServer);
- };
- interpret XF86_Switch_VT_7 {
- action = SwitchScreen(Screen=7, !SameServer);
- };
- interpret XF86_Switch_VT_8 {
- action = SwitchScreen(Screen=8, !SameServer);
- };
- interpret XF86_Switch_VT_9 {
- action = SwitchScreen(Screen=9, !SameServer);
- };
- interpret XF86_Switch_VT_10 {
- action = SwitchScreen(Screen=10, !SameServer);
- };
- interpret XF86_Switch_VT_11 {
- action = SwitchScreen(Screen=11, !SameServer);
- };
- interpret XF86_Switch_VT_12 {
- action = SwitchScreen(Screen=12, !SameServer);
- };
-
- interpret XF86_Ungrab {
- action = Private(type=0x86, data="Ungrab");
- };
- interpret XF86_ClearGrab {
- action = Private(type=0x86, data="ClsGrb");
- };
- interpret XF86_Next_VMode {
- action = Private(type=0x86, data="+VMode");
- };
- interpret XF86_Prev_VMode {
- action = Private(type=0x86, data="-VMode");
- };
-};
+// XFree86 special keysyms + +default partial xkb_compatibility "basic" { + + interpret.repeat= True; + + interpret XF86_Switch_VT_1 { + action = SwitchScreen(Screen=1, !SameServer); + }; + interpret XF86_Switch_VT_2 { + action = SwitchScreen(Screen=2, !SameServer); + }; + interpret XF86_Switch_VT_3 { + action = SwitchScreen(Screen=3, !SameServer); + }; + interpret XF86_Switch_VT_4 { + action = SwitchScreen(Screen=4, !SameServer); + }; + interpret XF86_Switch_VT_5 { + action = SwitchScreen(Screen=5, !SameServer); + }; + interpret XF86_Switch_VT_6 { + action = SwitchScreen(Screen=6, !SameServer); + }; + interpret XF86_Switch_VT_7 { + action = SwitchScreen(Screen=7, !SameServer); + }; + interpret XF86_Switch_VT_8 { + action = SwitchScreen(Screen=8, !SameServer); + }; + interpret XF86_Switch_VT_9 { + action = SwitchScreen(Screen=9, !SameServer); + }; + interpret XF86_Switch_VT_10 { + action = SwitchScreen(Screen=10, !SameServer); + }; + interpret XF86_Switch_VT_11 { + action = SwitchScreen(Screen=11, !SameServer); + }; + interpret XF86_Switch_VT_12 { + action = SwitchScreen(Screen=12, !SameServer); + }; + + interpret XF86_Ungrab { + action = Private(type=0x86, data="Ungrab"); + }; + interpret XF86_ClearGrab { + action = Private(type=0x86, data="ClsGrb"); + }; + interpret XF86LogGrabInfo { + action = Private(type=0x86, data="PrGrbs"); + }; + interpret XF86LogWindowTree { + action = Private(type=0x86, data="PrWins"); + }; + + interpret XF86_Next_VMode { + action = Private(type=0x86, data="+VMode"); + }; + interpret XF86_Prev_VMode { + action = Private(type=0x86, data="-VMode"); + }; +}; diff --git a/xorg-server/xkeyboard-config/symbols/ma b/xorg-server/xkeyboard-config/symbols/ma index f7985ea89..ad3064f3f 100644 --- a/xorg-server/xkeyboard-config/symbols/ma +++ b/xorg-server/xkeyboard-config/symbols/ma @@ -26,23 +26,23 @@ xkb_symbols "tifinagh" { name[Group1]="Berber (Morocco, Tifinagh)"; - key <TLDE> { [ twosuperior, NoAction ] }; + key <TLDE> { [ twosuperior, NoSymbol ] }; key <AE01> { [ ampersand, 1 ] }; - key <AE02> { [ NoAction, 2, asciitilde ] }; + key <AE02> { [ NoSymbol, 2, asciitilde ] }; key <AE03> { [ quotedbl, 3, numbersign ] }; key <AE04> { [apostrophe, 4, braceleft ] }; key <AE05> { [ parenleft, 5, bracketleft ] }; key <AE06> { [ minus, 6, bar ] }; - key <AE07> { [ NoAction , 7 ] }; + key <AE07> { [ NoSymbol , 7 ] }; key <AE08> { [underscore, 8, backslash ] }; - key <AE09> { [NoAction, 9, asciicircum ] }; - key <AE10> { [ NoAction , 0, at ] }; + key <AE09> { [NoSymbol, 9, asciicircum ] }; + key <AE10> { [ NoSymbol , 0, at ] }; key <AE11> { [parenright, degree, bracketright ] }; key <AE12> { [ equal, plus, braceright ] }; key <AD01> { [ 0x1002d30 ] }; key <AD02> { [ 0x1002d63, 0x1002d65 ] }; - key <AD03> { [ 0x1002d3b, NoAction,0x10020ac ] }; + key <AD03> { [ 0x1002d3b, NoSymbol,0x10020ac ] }; key <AD04> { [ 0x1002d54, 0x1002d55 ] }; key <AD05> { [ 0x1002d5c, 0x1002d5f ] }; key <AD06> { [ 0x1002d62 ] }; @@ -63,7 +63,7 @@ xkb_symbols "tifinagh" { key <AC08> { [ 0x1002d3d, 0x1002d3d ] }; key <AC09> { [ 0x1002d4d ] }; key <AC10> { [ 0x1002d4e ] }; - key <AC11> { [ NoAction , percent ] }; + key <AC11> { [ NoSymbol , percent ] }; key <BKSL> { [ asterisk, mu ] }; key <AB01> { [ 0x1002d61 ] }; @@ -88,7 +88,7 @@ xkb_symbols "tifinagh-phonetic" { key <LatA> { [ 0x1002d30 ] }; key <LatZ> { [ 0x1002d63, 0x1002d65 ] }; - key <LatE> { [ 0x1002d3b, NoAction,0x10020ac ] }; + key <LatE> { [ 0x1002d3b, NoSymbol,0x10020ac ] }; key <LatR> { [ 0x1002d54, 0x1002d55 ] }; key <LatT> { [ 0x1002d5c, 0x1002d5f ] }; key <LatY> { [ 0x1002d62 ] }; @@ -192,7 +192,7 @@ xkb_symbols "tifinagh-extended-phonetic" { key <LatA> { [ 0x1002d30 ] }; key <LatZ> { [ 0x1002d63, 0x1002d65 ] }; - key <LatE> { [ 0x1002d3b, NoAction,0x10020ac ] }; + key <LatE> { [ 0x1002d3b, NoSymbol,0x10020ac ] }; key <LatR> { [ 0x1002d54, 0x1002d55 ] }; key <LatT> { [ 0x1002d5c, 0x1002d5f ] }; key <LatY> { [ 0x1002d62 ] }; |