diff options
author | marha <marha@users.sourceforge.net> | 2012-01-11 08:55:02 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2012-01-11 08:57:05 +0100 |
commit | a73c45b7c72c6e426e1c75dd939f5481227b6979 (patch) | |
tree | aba5ced82f492a7e28dfa683144dfbd6293d9613 | |
parent | d60b5206a10c9d547a7230a991593b516e412204 (diff) | |
parent | 38e661c7d82fa0b34fbe9b3f3261295787bb6427 (diff) | |
download | vcxsrv-a73c45b7c72c6e426e1c75dd939f5481227b6979.tar.gz vcxsrv-a73c45b7c72c6e426e1c75dd939f5481227b6979.tar.bz2 vcxsrv-a73c45b7c72c6e426e1c75dd939f5481227b6979.zip |
Merge remote-tracking branch 'origin/released'
Conflicts:
pixman/pixman/pixman-trap.c
xorg-server/Xext/xace.c
xorg-server/dix/dispatch.c
xorg-server/hw/xwin/winclipboardthread.c
xorg-server/hw/xwin/winengine.c
xorg-server/hw/xwin/winwin32rootlesswindow.c
xorg-server/include/dixstruct.h
xorg-server/os/connection.c
99 files changed, 5364 insertions, 4571 deletions
diff --git a/mesalib/Makefile b/mesalib/Makefile index c73894789..4a41948b5 100644 --- a/mesalib/Makefile +++ b/mesalib/Makefile @@ -184,7 +184,7 @@ ultrix-gcc: # Rules for making release tarballs -PACKAGE_VERSION=7.12-devel +PACKAGE_VERSION=8.0-devel PACKAGE_DIR = Mesa-$(PACKAGE_VERSION) PACKAGE_NAME = MesaLib-$(PACKAGE_VERSION) diff --git a/mesalib/configs/default b/mesalib/configs/default index 33e5f024d..2ca6fe45d 100644 --- a/mesalib/configs/default +++ b/mesalib/configs/default @@ -8,8 +8,8 @@ CONFIG_NAME = default # Version info -MESA_MAJOR=7 -MESA_MINOR=12 +MESA_MAJOR=8 +MESA_MINOR=0 MESA_TINY=0 MESA_VERSION = $(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY) diff --git a/mesalib/docs/envvars.html b/mesalib/docs/envvars.html index 4b5e89926..5a988847b 100644 --- a/mesalib/docs/envvars.html +++ b/mesalib/docs/envvars.html @@ -140,6 +140,8 @@ Mesa EGL supports different sets of environment variables. See the <li>SOFTPIPE_DUMP_GS - if set, the softpipe driver will print geometry shaders to stderr <li>SOFTPIPE_NO_RAST - if set, rasterization is no-op'd. For profiling purposes. +<li>SOFTPIPE_USE_LLVM - if set, the softpipe driver will try to use LLVM JIT for + vertex shading procesing. </ul> diff --git a/mesalib/docs/relnotes-7.12.html b/mesalib/docs/relnotes-8.0.html index 471bbdac7..4aa175366 100644 --- a/mesalib/docs/relnotes-7.12.html +++ b/mesalib/docs/relnotes-8.0.html @@ -10,17 +10,17 @@ <body bgcolor="#eeeeee"> -<H1>Mesa 7.12 Release Notes / (release date TBD)</H1> +<H1>Mesa 8.0 Release Notes / (release date TBD)</H1> <p> -Mesa 7.12 is a new development release. +Mesa 8.0 is a new development release. People who are concerned with stability and reliability should stick -with a previous release or wait for Mesa 7.12.1. +with a previous release or wait for Mesa 8.0.1. </p> <p> -Mesa 7.12 implements the OpenGL 2.1 API, but the version reported by +Mesa 8.0 implements the OpenGL 3.0 API, but the version reported by glGetString(GL_VERSION) depends on the particular driver being used. -Some drivers don't support all the features required in OpenGL 2.1. +Some drivers don't support all the features required in OpenGL 3.0. </p> <p> See the <a href="install.html">Compiling/Installing page</a> for prerequisites diff --git a/mesalib/docs/relnotes.html b/mesalib/docs/relnotes.html index 7e02172ed..1dd5442d0 100644 --- a/mesalib/docs/relnotes.html +++ b/mesalib/docs/relnotes.html @@ -13,7 +13,7 @@ The release notes summarize what's new or changed in each Mesa release. </p> <UL> -<LI><A HREF="relnotes-7.12.html">7.12 release notes</A> +<LI><A HREF="relnotes-8.0.html">8.0 release notes</A> <LI><A HREF="relnotes-7.11.html">7.11 release notes</A> <LI><A HREF="relnotes-7.10.3.html">7.10.3 release notes</A> <LI><A HREF="relnotes-7.10.2.html">7.10.2 release notes</A> diff --git a/mesalib/scons/gallium.py b/mesalib/scons/gallium.py index 3cebaf58d..221d1848f 100644 --- a/mesalib/scons/gallium.py +++ b/mesalib/scons/gallium.py @@ -507,6 +507,7 @@ def generate(env): createInstallMethods(env) env.PkgCheckModules('X11', ['x11', 'xext', 'xdamage', 'xfixes']) + env.PkgCheckModules('XCB', ['x11-xcb', 'xcb-glx']) env.PkgCheckModules('XF86VIDMODE', ['xxf86vm']) env.PkgCheckModules('DRM', ['libdrm']) env.PkgCheckModules('DRM_INTEL', ['libdrm_intel']) diff --git a/mesalib/src/gallium/auxiliary/util/u_blit.c b/mesalib/src/gallium/auxiliary/util/u_blit.c index bba0031d7..a10fd17cb 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blit.c +++ b/mesalib/src/gallium/auxiliary/util/u_blit.c @@ -62,7 +62,6 @@ struct blit_state struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; struct pipe_viewport_state viewport; - struct pipe_clip_state clip; struct pipe_vertex_element velem[2]; enum pipe_texture_target internal_target; @@ -109,6 +108,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); ctx->rasterizer.cull_face = PIPE_FACE_NONE; ctx->rasterizer.gl_rasterization_rules = 1; + ctx->rasterizer.depth_clip = 1; /* samplers */ memset(&ctx->sampler, 0, sizeof(ctx->sampler)); @@ -535,7 +535,6 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); cso_save_geometry_shader(ctx->cso); - cso_save_clip(ctx->cso); cso_save_vertex_elements(ctx->cso); cso_save_vertex_buffers(ctx->cso); @@ -545,7 +544,6 @@ util_blit_pixels_writemask(struct blit_state *ctx, dst_is_depth ? &ctx->depthstencil_write : &ctx->depthstencil_keep); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); - cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); cso_set_stream_outputs(ctx->cso, 0, NULL, 0); @@ -621,7 +619,6 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); cso_restore_geometry_shader(ctx->cso); - cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); cso_restore_vertex_buffers(ctx->cso); cso_restore_stream_outputs(ctx->cso); @@ -731,7 +728,6 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); cso_save_geometry_shader(ctx->cso); - cso_save_clip(ctx->cso); cso_save_vertex_elements(ctx->cso); cso_save_vertex_buffers(ctx->cso); @@ -739,7 +735,6 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_set_blend(ctx->cso, &ctx->blend); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil_keep); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); - cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); cso_set_stream_outputs(ctx->cso, 0, NULL, 0); @@ -803,7 +798,6 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); cso_restore_geometry_shader(ctx->cso); - cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); cso_restore_vertex_buffers(ctx->cso); cso_restore_stream_outputs(ctx->cso); diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c index 80fdfe0a9..59940d9cb 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.c +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c @@ -104,9 +104,6 @@ struct blitter_context_priv /* Viewport state. */ struct pipe_viewport_state viewport; - /* Clip state. */ - struct pipe_clip_state clip; - /* Destination surface dimensions. */ unsigned dst_width; unsigned dst_height; @@ -193,7 +190,6 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) ctx->dsa_write_depth_stencil = pipe->create_depth_stencil_alpha_state(pipe, &dsa); - dsa.depth.enabled = 0; dsa.depth.writemask = 0; ctx->dsa_keep_depth_write_stencil = @@ -212,6 +208,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) rs_state.cull_face = PIPE_FACE_NONE; rs_state.gl_rasterization_rules = 1; rs_state.flatshade = 1; + rs_state.depth_clip = 1; ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); if (ctx->has_stream_out) { @@ -439,7 +436,6 @@ static void blitter_restore_fragment_states(struct blitter_context_priv *ctx) * (depending on the operation) */ pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref); pipe->set_viewport_state(pipe, &ctx->base.saved_viewport); - pipe->set_clip_state(pipe, &ctx->base.saved_clip); } static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx) @@ -516,9 +512,6 @@ static void blitter_set_rectangle(struct blitter_context_priv *ctx, ctx->viewport.translate[2] = 0.0f; ctx->viewport.translate[3] = 0.0f; ctx->base.pipe->set_viewport_state(ctx->base.pipe, &ctx->viewport); - - /* clip */ - ctx->base.pipe->set_clip_state(ctx->base.pipe, &ctx->clip); } static void blitter_set_clear_color(struct blitter_context_priv *ctx, diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.h b/mesalib/src/gallium/auxiliary/util/u_blitter.h index 4dd64c516..d4d30852b 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.h +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.h @@ -94,7 +94,6 @@ struct blitter_context struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */ struct pipe_stencil_ref saved_stencil_ref; /**< stencil ref */ struct pipe_viewport_state saved_viewport; - struct pipe_clip_state saved_clip; int saved_num_sampler_states; void *saved_sampler_states[PIPE_MAX_SAMPLERS]; @@ -365,13 +364,6 @@ void util_blitter_save_viewport(struct blitter_context *blitter, } static INLINE -void util_blitter_save_clip(struct blitter_context *blitter, - struct pipe_clip_state *state) -{ - blitter->saved_clip = *state; -} - -static INLINE void util_blitter_save_fragment_sampler_states( struct blitter_context *blitter, int num_sampler_states, diff --git a/mesalib/src/gallium/auxiliary/util/u_dump_state.c b/mesalib/src/gallium/auxiliary/util/u_dump_state.c index e44c6194c..c728bc402 100644 --- a/mesalib/src/gallium/auxiliary/util/u_dump_state.c +++ b/mesalib/src/gallium/auxiliary/util/u_dump_state.c @@ -303,6 +303,8 @@ util_dump_rasterizer_state(FILE *stream, const struct pipe_rasterizer_state *sta util_dump_member(stream, bool, state, flatshade); util_dump_member(stream, bool, state, light_twoside); + util_dump_member(stream, bool, state, clamp_vertex_color); + util_dump_member(stream, bool, state, clamp_fragment_color); util_dump_member(stream, uint, state, front_ccw); util_dump_member(stream, uint, state, cull_face); util_dump_member(stream, uint, state, fill_front); @@ -326,6 +328,9 @@ util_dump_rasterizer_state(FILE *stream, const struct pipe_rasterizer_state *sta util_dump_member(stream, bool, state, line_last_pixel); util_dump_member(stream, bool, state, flatshade_first); util_dump_member(stream, bool, state, gl_rasterization_rules); + util_dump_member(stream, bool, state, rasterizer_discard); + util_dump_member(stream, bool, state, depth_clip); + util_dump_member(stream, uint, state, clip_plane_enable); util_dump_member(stream, float, state, line_width); util_dump_member(stream, float, state, point_size); @@ -413,8 +418,6 @@ util_dump_clip_state(FILE *stream, const struct pipe_clip_state *state) util_dump_array_end(stream); util_dump_member_end(stream); - util_dump_member(stream, uint, state, nr); - util_dump_struct_end(stream); } diff --git a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c index 7cce815be..a28d41825 100644 --- a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -63,7 +63,6 @@ struct gen_mipmap_state struct pipe_depth_stencil_alpha_state depthstencil; struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; - struct pipe_clip_state clip; struct pipe_vertex_element velem[2]; void *vs; @@ -1283,6 +1282,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); ctx->rasterizer.cull_face = PIPE_FACE_NONE; ctx->rasterizer.gl_rasterization_rules = 1; + ctx->rasterizer.depth_clip = 1; /* sampler state */ memset(&ctx->sampler, 0, sizeof(ctx->sampler)); @@ -1564,14 +1564,12 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_save_vertex_shader(ctx->cso); cso_save_geometry_shader(ctx->cso); cso_save_viewport(ctx->cso); - cso_save_clip(ctx->cso); cso_save_vertex_elements(ctx->cso); /* bind our state */ cso_set_blend(ctx->cso, &ctx->blend); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); - cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); cso_set_stream_outputs(ctx->cso, 0, NULL, 0); @@ -1688,7 +1686,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_vertex_shader(ctx->cso); cso_restore_geometry_shader(ctx->cso); cso_restore_viewport(ctx->cso); - cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); cso_restore_stream_outputs(ctx->cso); } diff --git a/mesalib/src/gallium/auxiliary/util/u_sampler.c b/mesalib/src/gallium/auxiliary/util/u_sampler.c index 3dcf4fcd0..227641bda 100644 --- a/mesalib/src/gallium/auxiliary/util/u_sampler.c +++ b/mesalib/src/gallium/auxiliary/util/u_sampler.c @@ -1,103 +1,109 @@ -/**************************************************************************
- *
- * Copyright 2010 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 VMWARE 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 "u_format.h"
-#include "u_sampler.h"
-
-
-static void
-default_template(struct pipe_sampler_view *view,
- const struct pipe_resource *texture,
- enum pipe_format format,
- unsigned expand_green_blue)
-{
- /* XXX: Check if format is compatible with texture->format.
- */
-
- view->format = format;
- view->u.tex.first_level = 0;
- view->u.tex.last_level = texture->last_level;
- view->u.tex.first_layer = 0;
- view->u.tex.last_layer = texture->target == PIPE_TEXTURE_3D ?
- texture->depth0 - 1 : texture->array_size - 1;
- view->swizzle_r = PIPE_SWIZZLE_RED;
- view->swizzle_g = PIPE_SWIZZLE_GREEN;
- view->swizzle_b = PIPE_SWIZZLE_BLUE;
- view->swizzle_a = PIPE_SWIZZLE_ALPHA;
-
- /* Override default green and blue component expansion to the requested
- * one.
- *
- * Gallium expands nonexistent components to (0,0,0,1), DX9 expands
- * to (1,1,1,1). Since alpha is always expanded to 1, and red is
- * always present, we only really care about green and blue
- * components.
- *
- * To make it look less hackish, one would have to add
- * UTIL_FORMAT_SWIZZLE_EXPAND to indicate components for expansion
- * and then override without exceptions or favoring one component
- * over another.
- */
- if (format != PIPE_FORMAT_A8_UNORM) {
- const struct util_format_description *desc = util_format_description(format);
-
- assert(desc);
- if (desc) {
- if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0) {
- view->swizzle_g = expand_green_blue;
- }
- if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0) {
- view->swizzle_b = expand_green_blue;
- }
- }
- }
-}
-
-void
-u_sampler_view_default_template(struct pipe_sampler_view *view,
- const struct pipe_resource *texture,
- enum pipe_format format)
-{
- /* Expand to (0, 0, 0, 1) */
- default_template(view,
- texture,
- format,
- PIPE_SWIZZLE_ZERO);
-}
-
-void
-u_sampler_view_default_dx9_template(struct pipe_sampler_view *view,
- const struct pipe_resource *texture,
- enum pipe_format format)
-{
- /* Expand to (1, 1, 1, 1) */
- default_template(view,
- texture,
- format,
- PIPE_SWIZZLE_ONE);
-}
+/************************************************************************** + * + * Copyright 2010 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 VMWARE 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 "u_format.h" +#include "u_sampler.h" + + +/** + * Initialize a pipe_sampler_view. 'view' is considered to have + * uninitialized contents. + */ +static void +default_template(struct pipe_sampler_view *view, + const struct pipe_resource *texture, + enum pipe_format format, + unsigned expand_green_blue) +{ + memset(view, 0, sizeof(*view)); + + /* XXX: Check if format is compatible with texture->format. + */ + + view->format = format; + view->u.tex.first_level = 0; + view->u.tex.last_level = texture->last_level; + view->u.tex.first_layer = 0; + view->u.tex.last_layer = texture->target == PIPE_TEXTURE_3D ? + texture->depth0 - 1 : texture->array_size - 1; + view->swizzle_r = PIPE_SWIZZLE_RED; + view->swizzle_g = PIPE_SWIZZLE_GREEN; + view->swizzle_b = PIPE_SWIZZLE_BLUE; + view->swizzle_a = PIPE_SWIZZLE_ALPHA; + + /* Override default green and blue component expansion to the requested + * one. + * + * Gallium expands nonexistent components to (0,0,0,1), DX9 expands + * to (1,1,1,1). Since alpha is always expanded to 1, and red is + * always present, we only really care about green and blue + * components. + * + * To make it look less hackish, one would have to add + * UTIL_FORMAT_SWIZZLE_EXPAND to indicate components for expansion + * and then override without exceptions or favoring one component + * over another. + */ + if (format != PIPE_FORMAT_A8_UNORM) { + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (desc) { + if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0) { + view->swizzle_g = expand_green_blue; + } + if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0) { + view->swizzle_b = expand_green_blue; + } + } + } +} + +void +u_sampler_view_default_template(struct pipe_sampler_view *view, + const struct pipe_resource *texture, + enum pipe_format format) +{ + /* Expand to (0, 0, 0, 1) */ + default_template(view, + texture, + format, + PIPE_SWIZZLE_ZERO); +} + +void +u_sampler_view_default_dx9_template(struct pipe_sampler_view *view, + const struct pipe_resource *texture, + enum pipe_format format) +{ + /* Expand to (1, 1, 1, 1) */ + default_template(view, + texture, + format, + PIPE_SWIZZLE_ONE); +} diff --git a/mesalib/src/gallium/auxiliary/util/u_surface.c b/mesalib/src/gallium/auxiliary/util/u_surface.c index c7fbd3657..a541a38ff 100644 --- a/mesalib/src/gallium/auxiliary/util/u_surface.c +++ b/mesalib/src/gallium/auxiliary/util/u_surface.c @@ -42,17 +42,21 @@ #include "util/u_surface.h" #include "util/u_pack_color.h" + +/** + * Initialize a pipe_surface object. 'view' is considered to have + * uninitialized contents. + */ void -u_surface_default_template(struct pipe_surface *view, +u_surface_default_template(struct pipe_surface *surf, const struct pipe_resource *texture, unsigned bind) { - view->format = texture->format; - view->u.tex.level = 0; - view->u.tex.first_layer = 0; - view->u.tex.last_layer = 0; + memset(surf, 0, sizeof(*surf)); + + surf->format = texture->format; /* XXX should filter out all non-rt/ds bind flags ? */ - view->usage = bind; + surf->usage = bind; } /** @@ -108,7 +112,6 @@ util_create_rgba_surface(struct pipe_context *pipe, return FALSE; /* create surface */ - memset(&surf_templ, 0, sizeof(surf_templ)); u_surface_default_template(&surf_templ, *textureOut, bind); /* create surface / view into texture */ *surfaceOut = pipe->create_surface(pipe, diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 1aebca40f..cde7052b0 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -2010,6 +2010,29 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, else var->interpolation = INTERP_QUALIFIER_NONE; + if (var->interpolation != INTERP_QUALIFIER_NONE && + !(state->target == vertex_shader && var->mode == ir_var_out) && + !(state->target == fragment_shader && var->mode == ir_var_in)) { + const char *qual_string = NULL; + switch (var->interpolation) { + case INTERP_QUALIFIER_FLAT: + qual_string = "flat"; + break; + case INTERP_QUALIFIER_NOPERSPECTIVE: + qual_string = "noperspective"; + break; + case INTERP_QUALIFIER_SMOOTH: + qual_string = "smooth"; + break; + } + + _mesa_glsl_error(loc, state, + "interpolation qualifier `%s' can only be applied to " + "vertex shader outputs and fragment shader inputs.", + qual_string); + + } + var->pixel_center_integer = qual->flags.q.pixel_center_integer; var->origin_upper_left = qual->flags.q.origin_upper_left; if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer) diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 88c81c41b..e8472d446 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -1576,9 +1576,9 @@ tfeedback_decl::assign_location(struct gl_context *ctx, } else { /* Regular variable (scalar, vector, or matrix) */ if (this->is_subscripted) { - linker_error(prog, "Transform feedback varying %s found, " - "but it's an array ([] expected).", - this->orig_name); + linker_error(prog, "Transform feedback varying %s requested, " + "but %s is not an array.", + this->orig_name, this->var_name); return false; } this->location = output_var->location; diff --git a/mesalib/src/glsl/opt_copy_propagation_elements.cpp b/mesalib/src/glsl/opt_copy_propagation_elements.cpp index a91e624cb..ebfd4fd3f 100644 --- a/mesalib/src/glsl/opt_copy_propagation_elements.cpp +++ b/mesalib/src/glsl/opt_copy_propagation_elements.cpp @@ -108,6 +108,7 @@ public: virtual ir_visitor_status visit_leave(class ir_assignment *); virtual ir_visitor_status visit_enter(class ir_call *); virtual ir_visitor_status visit_enter(class ir_if *); + virtual ir_visitor_status visit_leave(class ir_swizzle *); void handle_rvalue(ir_rvalue **rvalue); @@ -179,6 +180,15 @@ ir_copy_propagation_elements_visitor::visit_leave(ir_assignment *ir) return visit_continue; } +ir_visitor_status +ir_copy_propagation_elements_visitor::visit_leave(ir_swizzle *ir) +{ + /* Don't visit the values of swizzles since they are handled while + * visiting the swizzle itself. + */ + return visit_continue; +} + /** * Replaces dereferences of ACP RHS variables with ACP LHS variables. * @@ -451,7 +461,20 @@ ir_copy_propagation_elements_visitor::add_copy(ir_assignment *ir) swizzle[i] = orig_swizzle[j++]; } - entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, ir->write_mask, + int write_mask = ir->write_mask; + if (lhs->var == rhs->var) { + /* If this is a copy from the variable to itself, then we need + * to be sure not to include the updated channels from this + * instruction in the set of new source channels to be + * copy-propagated from. + */ + for (int i = 0; i < 4; i++) { + if (ir->write_mask & (1 << orig_swizzle[i])) + write_mask &= ~(1 << i); + } + } + + entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, write_mask, swizzle); this->acp->push_tail(entry); } diff --git a/mesalib/src/mesa/main/accum.c b/mesalib/src/mesa/main/accum.c index a8c30c223..df6f219bf 100644 --- a/mesalib/src/mesa/main/accum.c +++ b/mesalib/src/mesa/main/accum.c @@ -117,19 +117,6 @@ _mesa_init_accum_dispatch(struct _glapi_table *disp) } -#endif /* FEATURE_accum */ - - -void -_mesa_init_accum( struct gl_context *ctx ) -{ - /* Accumulate buffer group */ - ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 ); -} - - - - /** * Clear the accumulation buffer by mapping the renderbuffer and * writing the clear color to it. Called by the driver's implementation @@ -507,3 +494,14 @@ _mesa_accum(struct gl_context *ctx, GLenum op, GLfloat value) break; } } + + +#endif /* FEATURE_accum */ + + +void +_mesa_init_accum( struct gl_context *ctx ) +{ + /* Accumulate buffer group */ + ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 ); +} diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 912170aba..aefcaf350 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -2579,6 +2579,44 @@ find_attachment(const struct gl_framebuffer *fb, } +/** + * Helper function for checking if the datatypes of color buffers are + * compatible for glBlitFramebuffer. From the 3.1 spec, page 198: + * + * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT + * and any of the following conditions hold: + * - The read buffer contains fixed-point or floating-point values and any + * draw buffer contains neither fixed-point nor floating-point values. + * - The read buffer contains unsigned integer values and any draw buffer + * does not contain unsigned integer values. + * - The read buffer contains signed integer values and any draw buffer + * does not contain signed integer values." + */ +static GLboolean +compatible_color_datatypes(gl_format srcFormat, gl_format dstFormat) +{ + GLenum srcType = _mesa_get_format_datatype(srcFormat); + GLenum dstType = _mesa_get_format_datatype(dstFormat); + + if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) { + assert(srcType == GL_UNSIGNED_NORMALIZED || + srcType == GL_SIGNED_NORMALIZED || + srcType == GL_FLOAT); + /* Boil any of those types down to GL_FLOAT */ + srcType = GL_FLOAT; + } + + if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) { + assert(dstType == GL_UNSIGNED_NORMALIZED || + dstType == GL_SIGNED_NORMALIZED || + dstType == GL_FLOAT); + /* Boil any of those types down to GL_FLOAT */ + dstType = GL_FLOAT; + } + + return srcType == dstType; +} + /** * Blit rectangular region, optionally from one framebuffer to another. @@ -2663,6 +2701,12 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, colorReadRb = colorDrawRb = NULL; mask &= ~GL_COLOR_BUFFER_BIT; } + else if (!compatible_color_datatypes(colorReadRb->Format, + colorDrawRb->Format)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBlitFramebufferEXT(color buffer datatypes mismatch)"); + return; + } } else { colorReadRb = colorDrawRb = NULL; @@ -2683,10 +2727,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, if ((readRb == NULL) || (drawRb == NULL)) { mask &= ~GL_STENCIL_BUFFER_BIT; } - else if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) != - _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) { + else if (readRb->Format != drawRb->Format) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glBlitFramebufferEXT(stencil buffer size mismatch)"); + "glBlitFramebufferEXT(stencil buffer format mismatch)"); return; } } @@ -2706,10 +2749,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, if ((readRb == NULL) || (drawRb == NULL)) { mask &= ~GL_DEPTH_BUFFER_BIT; } - else if (_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) != - _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) { + else if (readRb->Format != drawRb->Format) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glBlitFramebufferEXT(depth buffer size mismatch)"); + "glBlitFramebufferEXT(depth buffer format mismatch)"); return; } } @@ -2718,7 +2760,7 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, drawFb->Visual.samples > 0 && readFb->Visual.samples != drawFb->Visual.samples) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glBlitFramebufferEXT(mismatched samples"); + "glBlitFramebufferEXT(mismatched samples)"); return; } @@ -2742,6 +2784,19 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, } } + if (filter == GL_LINEAR && (mask & GL_COLOR_BUFFER_BIT)) { + /* 3.1 spec, page 199: + * "Calling BlitFramebuffer will result in an INVALID_OPERATION error + * if filter is LINEAR and read buffer contains integer data." + */ + GLenum type = _mesa_get_format_datatype(colorReadRb->Format); + if (type == GL_INT || type == GL_UNSIGNED_INT) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBlitFramebufferEXT(integer color type)"); + return; + } + } + if (!ctx->Extensions.EXT_framebuffer_blit) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT"); return; diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c index a22ff5a61..ff98c69cd 100644 --- a/mesalib/src/mesa/main/format_unpack.c +++ b/mesalib/src/mesa/main/format_unpack.c @@ -29,6 +29,22 @@ #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" + +/* Expand 1, 2, 3, 4, 5, 6-bit values to fill 8 bits */ + +#define EXPAND_1_8(X) ( (X) ? 0xff : 0x0 ) + +#define EXPAND_2_8(X) ( ((X) << 6) | ((X) << 4) | ((X) << 2) | (X) ) + +#define EXPAND_3_8(X) ( ((X) << 5) | ((X) << 2) | ((X) >> 1) ) + +#define EXPAND_4_8(X) ( ((X) << 4) | (X) ) + +#define EXPAND_5_8(X) ( ((X) << 3) | ((X) >> 2) ) + +#define EXPAND_6_8(X) ( ((X) << 2) | ((X) >> 4) ) + + /** * Convert an 8-bit sRGB value from non-linear space to a * linear RGB value in [0, 1]. @@ -57,6 +73,10 @@ nonlinear_to_linear(GLubyte cs8) } +/**********************************************************************/ +/* Unpack, returning GLfloat colors */ +/**********************************************************************/ + typedef void (*unpack_rgba_func)(const void *src, GLfloat dst[][4], GLuint n); @@ -1566,6 +1586,9 @@ get_unpack_rgba_function(gl_format format) } +/** + * Unpack rgba colors, returning as GLfloat values. + */ void _mesa_unpack_rgba_row(gl_format format, GLuint n, const void *src, GLfloat dst[][4]) @@ -1574,6 +1597,482 @@ _mesa_unpack_rgba_row(gl_format format, GLuint n, unpack(src, dst, n); } + +/**********************************************************************/ +/* Unpack, returning GLubyte colors */ +/**********************************************************************/ + + +static void +unpack_ubyte_RGBA8888(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = (s[i] >> 24); + dst[i][GCOMP] = (s[i] >> 16) & 0xff; + dst[i][BCOMP] = (s[i] >> 8) & 0xff; + dst[i][ACOMP] = (s[i] ) & 0xff; + } +} + +static void +unpack_ubyte_RGBA8888_REV(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = (s[i] ) & 0xff; + dst[i][GCOMP] = (s[i] >> 8) & 0xff; + dst[i][BCOMP] = (s[i] >> 16) & 0xff; + dst[i][ACOMP] = (s[i] >> 24); + } +} + +static void +unpack_ubyte_ARGB8888(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = (s[i] >> 16) & 0xff; + dst[i][GCOMP] = (s[i] >> 8) & 0xff; + dst[i][BCOMP] = (s[i] ) & 0xff; + dst[i][ACOMP] = (s[i] >> 24); + } +} + +static void +unpack_ubyte_ARGB8888_REV(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = (s[i] >> 8) & 0xff; + dst[i][GCOMP] = (s[i] >> 16) & 0xff; + dst[i][BCOMP] = (s[i] >> 24); + dst[i][ACOMP] = (s[i] ) & 0xff; + } +} + +static void +unpack_ubyte_RGBX8888(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = (s[i] >> 24); + dst[i][GCOMP] = (s[i] >> 16) & 0xff; + dst[i][BCOMP] = (s[i] >> 8) & 0xff; + dst[i][ACOMP] = 0xff; + } +} + +static void +unpack_ubyte_RGBX8888_REV(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = (s[i] ) & 0xff; + dst[i][GCOMP] = (s[i] >> 8) & 0xff; + dst[i][BCOMP] = (s[i] >> 16) & 0xff; + dst[i][ACOMP] = 0xff; + } +} + +static void +unpack_ubyte_XRGB8888(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = (s[i] >> 16) & 0xff; + dst[i][GCOMP] = (s[i] >> 8) & 0xff; + dst[i][BCOMP] = (s[i] ) & 0xff; + dst[i][ACOMP] = 0xff; + } +} + +static void +unpack_ubyte_XRGB8888_REV(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = (s[i] >> 8) & 0xff; + dst[i][GCOMP] = (s[i] >> 16) & 0xff; + dst[i][BCOMP] = (s[i] >> 24); + dst[i][ACOMP] = 0xff; + } +} + +static void +unpack_ubyte_RGB888(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLubyte *s = (const GLubyte *) src; + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = s[i*3+2]; + dst[i][GCOMP] = s[i*3+1]; + dst[i][BCOMP] = s[i*3+0]; + dst[i][ACOMP] = 0xff; + } +} + +static void +unpack_ubyte_BGR888(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLubyte *s = (const GLubyte *) src; + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = s[i*3+0]; + dst[i][GCOMP] = s[i*3+1]; + dst[i][BCOMP] = s[i*3+2]; + dst[i][ACOMP] = 0xff; + } +} + +static void +unpack_ubyte_RGB565(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = EXPAND_5_8((s[i] >> 11) & 0x1f); + dst[i][GCOMP] = EXPAND_6_8((s[i] >> 5 ) & 0x3f); + dst[i][BCOMP] = EXPAND_5_8( s[i] & 0x1f); + dst[i][ACOMP] = 0xff; + } +} + +static void +unpack_ubyte_RGB565_REV(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + GLuint t = (s[i] >> 8) | (s[i] << 8); /* byte swap */ + dst[i][RCOMP] = EXPAND_5_8((t >> 11) & 0x1f); + dst[i][GCOMP] = EXPAND_6_8((t >> 5 ) & 0x3f); + dst[i][BCOMP] = EXPAND_5_8( t & 0x1f); + dst[i][ACOMP] = 0xff; + } +} + +static void +unpack_ubyte_ARGB4444(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = EXPAND_4_8((s[i] >> 8) & 0xf); + dst[i][GCOMP] = EXPAND_4_8((s[i] >> 4) & 0xf); + dst[i][BCOMP] = EXPAND_4_8((s[i] ) & 0xf); + dst[i][ACOMP] = EXPAND_4_8((s[i] >> 12) & 0xf); + } +} + +static void +unpack_ubyte_ARGB4444_REV(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = EXPAND_4_8((s[i] ) & 0xf); + dst[i][GCOMP] = EXPAND_4_8((s[i] >> 12) & 0xf); + dst[i][BCOMP] = EXPAND_4_8((s[i] >> 8) & 0xf); + dst[i][ACOMP] = EXPAND_4_8((s[i] >> 4) & 0xf); + } +} + +static void +unpack_ubyte_RGBA5551(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = EXPAND_5_8((s[i] >> 11) & 0x1f); + dst[i][GCOMP] = EXPAND_5_8((s[i] >> 6) & 0x1f); + dst[i][BCOMP] = EXPAND_5_8((s[i] >> 1) & 0x1f); + dst[i][ACOMP] = EXPAND_1_8((s[i] ) & 0x01); + } +} + +static void +unpack_ubyte_ARGB1555(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = EXPAND_5_8((s[i] >> 10) & 0x1f); + dst[i][GCOMP] = EXPAND_5_8((s[i] >> 5) & 0x1f); + dst[i][BCOMP] = EXPAND_5_8((s[i] >> 0) & 0x1f); + dst[i][ACOMP] = EXPAND_1_8((s[i] >> 15) & 0x01); + } +} + +static void +unpack_ubyte_ARGB1555_REV(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + GLushort tmp = (s[i] << 8) | (s[i] >> 8); /* byteswap */ + dst[i][RCOMP] = EXPAND_5_8((tmp >> 10) & 0x1f); + dst[i][GCOMP] = EXPAND_5_8((tmp >> 5) & 0x1f); + dst[i][BCOMP] = EXPAND_5_8((tmp >> 0) & 0x1f); + dst[i][ACOMP] = EXPAND_1_8((tmp >> 15) & 0x01); + } +} + +static void +unpack_ubyte_AL44(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLubyte *s = ((const GLubyte *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = + dst[i][GCOMP] = + dst[i][BCOMP] = EXPAND_4_8(s[i] & 0xf); + dst[i][ACOMP] = EXPAND_4_8(s[i] >> 4); + } +} + +static void +unpack_ubyte_AL88(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = + dst[i][GCOMP] = + dst[i][BCOMP] = EXPAND_4_8(s[i] & 0xff); + dst[i][ACOMP] = EXPAND_4_8(s[i] >> 8); + } +} + +static void +unpack_ubyte_AL88_REV(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = + dst[i][GCOMP] = + dst[i][BCOMP] = EXPAND_4_8(s[i] >> 8); + dst[i][ACOMP] = EXPAND_4_8(s[i] & 0xff); + } +} + +static void +unpack_ubyte_RGB332(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLubyte *s = ((const GLubyte *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = EXPAND_3_8((s[i] >> 5) & 0x7); + dst[i][GCOMP] = EXPAND_3_8((s[i] >> 2) & 0x7); + dst[i][BCOMP] = EXPAND_2_8((s[i] ) & 0x3); + dst[i][ACOMP] = 0xff; + } +} + +static void +unpack_ubyte_A8(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLubyte *s = ((const GLubyte *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = + dst[i][GCOMP] = + dst[i][BCOMP] = 0; + dst[i][ACOMP] = s[i]; + } +} + +static void +unpack_ubyte_L8(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLubyte *s = ((const GLubyte *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = + dst[i][GCOMP] = + dst[i][BCOMP] = s[i]; + dst[i][ACOMP] = 0xff; + } +} + + +static void +unpack_ubyte_I8(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLubyte *s = ((const GLubyte *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = + dst[i][GCOMP] = + dst[i][BCOMP] = + dst[i][ACOMP] = s[i]; + } +} + +static void +unpack_ubyte_R8(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLubyte *s = ((const GLubyte *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][0] = s[i]; + dst[i][1] = + dst[i][2] = 0; + dst[i][3] = 0xff; + } +} + +static void +unpack_ubyte_GR88(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = s[i] & 0xff; + dst[i][GCOMP] = s[i] >> 8; + dst[i][BCOMP] = 0; + dst[i][ACOMP] = 0xff; + } +} + +static void +unpack_ubyte_RG88(const void *src, GLubyte dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = s[i] >> 8; + dst[i][GCOMP] = s[i] & 0xff; + dst[i][BCOMP] = 0; + dst[i][ACOMP] = 0xff; + } +} + + +/** + * Unpack rgba colors, returning as GLubyte values. This should usually + * only be used for unpacking formats that use 8 bits or less per channel. + */ +void +_mesa_unpack_ubyte_rgba_row(gl_format format, GLuint n, + const void *src, GLubyte dst[][4]) +{ + switch (format) { + case MESA_FORMAT_RGBA8888: + unpack_ubyte_RGBA8888(src, dst, n); + break; + case MESA_FORMAT_RGBA8888_REV: + unpack_ubyte_RGBA8888_REV(src, dst, n); + break; + case MESA_FORMAT_ARGB8888: + unpack_ubyte_ARGB8888(src, dst, n); + break; + case MESA_FORMAT_ARGB8888_REV: + unpack_ubyte_ARGB8888_REV(src, dst, n); + break; + case MESA_FORMAT_RGBX8888: + unpack_ubyte_RGBX8888(src, dst, n); + break; + case MESA_FORMAT_RGBX8888_REV: + unpack_ubyte_RGBX8888_REV(src, dst, n); + break; + case MESA_FORMAT_XRGB8888: + unpack_ubyte_XRGB8888(src, dst, n); + break; + case MESA_FORMAT_XRGB8888_REV: + unpack_ubyte_XRGB8888_REV(src, dst, n); + break; + case MESA_FORMAT_RGB888: + unpack_ubyte_RGB888(src, dst, n); + break; + case MESA_FORMAT_BGR888: + unpack_ubyte_BGR888(src, dst, n); + break; + case MESA_FORMAT_RGB565: + unpack_ubyte_RGB565(src, dst, n); + break; + case MESA_FORMAT_RGB565_REV: + unpack_ubyte_RGB565_REV(src, dst, n); + break; + case MESA_FORMAT_ARGB4444: + unpack_ubyte_ARGB4444(src, dst, n); + break; + case MESA_FORMAT_ARGB4444_REV: + unpack_ubyte_ARGB4444_REV(src, dst, n); + break; + case MESA_FORMAT_RGBA5551: + unpack_ubyte_RGBA5551(src, dst, n); + break; + case MESA_FORMAT_ARGB1555: + unpack_ubyte_ARGB1555(src, dst, n); + break; + case MESA_FORMAT_ARGB1555_REV: + unpack_ubyte_ARGB1555_REV(src, dst, n); + break; + case MESA_FORMAT_AL44: + unpack_ubyte_AL44(src, dst, n); + break; + case MESA_FORMAT_AL88: + unpack_ubyte_AL88(src, dst, n); + break; + case MESA_FORMAT_AL88_REV: + unpack_ubyte_AL88_REV(src, dst, n); + break; + case MESA_FORMAT_RGB332: + unpack_ubyte_RGB332(src, dst, n); + break; + case MESA_FORMAT_A8: + unpack_ubyte_A8(src, dst, n); + break; + case MESA_FORMAT_L8: + unpack_ubyte_L8(src, dst, n); + break; + case MESA_FORMAT_I8: + unpack_ubyte_I8(src, dst, n); + break; + case MESA_FORMAT_R8: + unpack_ubyte_R8(src, dst, n); + break; + case MESA_FORMAT_GR88: + unpack_ubyte_GR88(src, dst, n); + break; + case MESA_FORMAT_RG88: + unpack_ubyte_RG88(src, dst, n); + break; + default: + /* get float values, convert to ubyte */ + { + GLfloat *tmp = (GLfloat *) malloc(n * 4 * sizeof(GLfloat)); + if (tmp) { + GLuint i; + _mesa_unpack_rgba_row(format, n, src, (GLfloat (*)[4]) tmp); + for (i = 0; i < n; i++) { + UNCLAMPED_FLOAT_TO_UBYTE(dst[i][0], tmp[i*4+0]); + UNCLAMPED_FLOAT_TO_UBYTE(dst[i][1], tmp[i*4+1]); + UNCLAMPED_FLOAT_TO_UBYTE(dst[i][2], tmp[i*4+2]); + UNCLAMPED_FLOAT_TO_UBYTE(dst[i][3], tmp[i*4+3]); + } + free(tmp); + } + } + break; + } +} + + +/**********************************************************************/ +/* Unpack, returning GLuint colors */ +/**********************************************************************/ + static void unpack_int_rgba_RGBA_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) { @@ -1770,8 +2269,8 @@ unpack_int_rgba_ARGB2101010_UINT(const GLuint *src, GLuint dst[][4], GLuint n) } void -_mesa_unpack_int_rgba_row(gl_format format, GLuint n, - const void *src, GLuint dst[][4]) +_mesa_unpack_uint_rgba_row(gl_format format, GLuint n, + const void *src, GLuint dst[][4]) { switch (format) { /* Since there won't be any sign extension happening, there's no need to diff --git a/mesalib/src/mesa/main/format_unpack.h b/mesalib/src/mesa/main/format_unpack.h index c5348d30d..aad800dd1 100644 --- a/mesalib/src/mesa/main/format_unpack.h +++ b/mesalib/src/mesa/main/format_unpack.h @@ -28,10 +28,13 @@ extern void _mesa_unpack_rgba_row(gl_format format, GLuint n, const void *src, GLfloat dst[][4]); +extern void +_mesa_unpack_ubyte_rgba_row(gl_format format, GLuint n, + const void *src, GLubyte dst[][4]); void -_mesa_unpack_int_rgba_row(gl_format format, GLuint n, - const void *src, GLuint dst[][4]); +_mesa_unpack_uint_rgba_row(gl_format format, GLuint n, + const void *src, GLuint dst[][4]); extern void _mesa_unpack_rgba_block(gl_format format, diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index cca0014b1..96317dbf4 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -1951,7 +1951,7 @@ _mesa_test_formats(void) { GLuint i; - assert(Elements(format_info) == MESA_FORMAT_COUNT); + STATIC_ASSERT(Elements(format_info) == MESA_FORMAT_COUNT); for (i = 0; i < MESA_FORMAT_COUNT; i++) { const struct gl_format_info *info = _mesa_get_format_info(i); diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index 38b9c64ed..0c0e5394d 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -273,7 +273,7 @@ slow_read_rgba_pixels( struct gl_context *ctx, for (j = 0; j < height; j++) { if (_mesa_is_integer_format(format)) { - _mesa_unpack_int_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba); + _mesa_unpack_uint_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba); _mesa_pack_rgba_span_int(ctx, width, (GLuint (*)[4]) rgba, format, type, dst); } else { diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 52a9bd452..9372d6dec 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -923,7 +923,7 @@ validate_samplers(const struct gl_program *prog, char *errMsg) GLbitfield samplersUsed = prog->SamplersUsed; GLuint i; - assert(Elements(targetName) == NUM_TEXTURE_TARGETS); + STATIC_ASSERT(Elements(targetName) == NUM_TEXTURE_TARGETS); if (samplersUsed == 0x0) return GL_TRUE; diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c index 276fac149..c3e93b5a5 100644 --- a/mesalib/src/mesa/main/shared.c +++ b/mesalib/src/mesa/main/shared.c @@ -113,7 +113,7 @@ _mesa_alloc_shared_state(struct gl_context *ctx) GL_TEXTURE_2D, GL_TEXTURE_1D }; - assert(Elements(targets) == NUM_TEXTURE_TARGETS); + STATIC_ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS); shared->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]); } diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c index 7cd285803..8e9537fae 100644 --- a/mesalib/src/mesa/main/texstate.c +++ b/mesalib/src/mesa/main/texstate.c @@ -695,7 +695,7 @@ alloc_proxy_textures( struct gl_context *ctx ) }; GLint tgt; - ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS); + STATIC_ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS); for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { if (!(ctx->Texture.ProxyTex[tgt] diff --git a/mesalib/src/mesa/main/version.h b/mesalib/src/mesa/main/version.h index 32e141f0e..d288c4d55 100644 --- a/mesalib/src/mesa/main/version.h +++ b/mesalib/src/mesa/main/version.h @@ -32,10 +32,10 @@ struct gl_context; /* Mesa version */ -#define MESA_MAJOR 7 -#define MESA_MINOR 12 +#define MESA_MAJOR 8 +#define MESA_MINOR 0 #define MESA_PATCH 0 -#define MESA_VERSION_STRING "7.12-devel" +#define MESA_VERSION_STRING "8.0-devel" /* To make version comparison easy */ #define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) diff --git a/mesalib/src/mesa/program/nvvertparse.c b/mesalib/src/mesa/program/nvvertparse.c index 91fe2c48b..7b46bef91 100644 --- a/mesalib/src/mesa/program/nvvertparse.c +++ b/mesalib/src/mesa/program/nvvertparse.c @@ -1424,6 +1424,7 @@ _mesa_parse_nv_vertex_program(struct gl_context *ctx, GLenum dstTarget, index = _mesa_add_state_reference(program->Base.Parameters, state_tokens); assert(index == i); + (void)index; } program->Base.NumParameters = program->Base.Parameters->NumParameters; diff --git a/mesalib/src/mesa/program/symbol_table.c b/mesalib/src/mesa/program/symbol_table.c index 45aeb97b1..4f6f31f31 100644 --- a/mesalib/src/mesa/program/symbol_table.c +++ b/mesalib/src/mesa/program/symbol_table.c @@ -1,488 +1,489 @@ -/*
- * Copyright © 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "main/imports.h"
-#include "symbol_table.h"
-#include "hash_table.h"
-
-struct symbol {
- /**
- * Link to the next symbol in the table with the same name
- *
- * The linked list of symbols with the same name is ordered by scope
- * from inner-most to outer-most.
- */
- struct symbol *next_with_same_name;
-
-
- /**
- * Link to the next symbol in the table with the same scope
- *
- * The linked list of symbols with the same scope is unordered. Symbols
- * in this list my have unique names.
- */
- struct symbol *next_with_same_scope;
-
-
- /**
- * Header information for the list of symbols with the same name.
- */
- struct symbol_header *hdr;
-
-
- /**
- * Name space of the symbol
- *
- * Name space are arbitrary user assigned integers. No two symbols can
- * exist in the same name space at the same scope level.
- */
- int name_space;
-
- /** Scope depth where this symbol was defined. */
- unsigned depth;
-
- /**
- * Arbitrary user supplied data.
- */
- void *data;
-};
-
-
-/**
- */
-struct symbol_header {
- /** Linkage in list of all headers in a given symbol table. */
- struct symbol_header *next;
-
- /** Symbol name. */
- char *name;
-
- /** Linked list of symbols with the same name. */
- struct symbol *symbols;
-};
-
-
-/**
- * Element of the scope stack.
- */
-struct scope_level {
- /** Link to next (inner) scope level. */
- struct scope_level *next;
-
- /** Linked list of symbols with the same scope. */
- struct symbol *symbols;
-};
-
-
-/**
- *
- */
-struct _mesa_symbol_table {
- /** Hash table containing all symbols in the symbol table. */
- struct hash_table *ht;
-
- /** Top of scope stack. */
- struct scope_level *current_scope;
-
- /** List of all symbol headers in the table. */
- struct symbol_header *hdr;
-
- /** Current scope depth. */
- unsigned depth;
-};
-
-
-struct _mesa_symbol_table_iterator {
- /**
- * Name space of symbols returned by this iterator.
- */
- int name_space;
-
-
- /**
- * Currently iterated symbol
- *
- * The next call to \c _mesa_symbol_table_iterator_get will return this
- * value. It will also update this value to the value that should be
- * returned by the next call.
- */
- struct symbol *curr;
-};
-
-
-static void
-check_symbol_table(struct _mesa_symbol_table *table)
-{
-#if 1
- struct scope_level *scope;
-
- for (scope = table->current_scope; scope != NULL; scope = scope->next) {
- struct symbol *sym;
-
- for (sym = scope->symbols
- ; sym != NULL
- ; sym = sym->next_with_same_name) {
- const struct symbol_header *const hdr = sym->hdr;
- struct symbol *sym2;
-
- for (sym2 = hdr->symbols
- ; sym2 != NULL
- ; sym2 = sym2->next_with_same_name) {
- assert(sym2->hdr == hdr);
- }
- }
- }
-#endif
-}
-
-void
-_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
-{
- struct scope_level *const scope = table->current_scope;
- struct symbol *sym = scope->symbols;
-
- table->current_scope = scope->next;
- table->depth--;
-
- free(scope);
-
- while (sym != NULL) {
- struct symbol *const next = sym->next_with_same_scope;
- struct symbol_header *const hdr = sym->hdr;
-
- assert(hdr->symbols == sym);
-
- hdr->symbols = sym->next_with_same_name;
-
- free(sym);
-
- sym = next;
- }
-
- check_symbol_table(table);
-}
-
-
-void
-_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
-{
- struct scope_level *const scope = calloc(1, sizeof(*scope));
-
- scope->next = table->current_scope;
- table->current_scope = scope;
- table->depth++;
-}
-
-
-static struct symbol_header *
-find_symbol(struct _mesa_symbol_table *table, const char *name)
-{
- return (struct symbol_header *) hash_table_find(table->ht, name);
-}
-
-
-struct _mesa_symbol_table_iterator *
-_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
- int name_space, const char *name)
-{
- struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
- struct symbol_header *const hdr = find_symbol(table, name);
-
- iter->name_space = name_space;
-
- if (hdr != NULL) {
- struct symbol *sym;
-
- for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
- assert(sym->hdr == hdr);
-
- if ((name_space == -1) || (sym->name_space == name_space)) {
- iter->curr = sym;
- break;
- }
- }
- }
-
- return iter;
-}
-
-
-void
-_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
-{
- free(iter);
-}
-
-
-void *
-_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
-{
- return (iter->curr == NULL) ? NULL : iter->curr->data;
-}
-
-
-int
-_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
-{
- struct symbol_header *hdr;
-
- if (iter->curr == NULL) {
- return 0;
- }
-
- hdr = iter->curr->hdr;
- iter->curr = iter->curr->next_with_same_name;
-
- while (iter->curr != NULL) {
- assert(iter->curr->hdr == hdr);
-
- if ((iter->name_space == -1)
- || (iter->curr->name_space == iter->name_space)) {
- return 1;
- }
-
- iter->curr = iter->curr->next_with_same_name;
- }
-
- return 0;
-}
-
-
-/**
- * Determine the scope "distance" of a symbol from the current scope
- *
- * \return
- * A non-negative number for the number of scopes between the current scope
- * and the scope where a symbol was defined. A value of zero means the current
- * scope. A negative number if the symbol does not exist.
- */
-int
-_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
- int name_space, const char *name)
-{
- struct symbol_header *const hdr = find_symbol(table, name);
- struct symbol *sym;
-
- if (hdr != NULL) {
- for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
- assert(sym->hdr == hdr);
-
- if ((name_space == -1) || (sym->name_space == name_space)) {
- assert(sym->depth <= table->depth);
- return sym->depth - table->depth;
- }
- }
- }
-
- return -1;
-}
-
-
-void *
-_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
- int name_space, const char *name)
-{
- struct symbol_header *const hdr = find_symbol(table, name);
-
- if (hdr != NULL) {
- struct symbol *sym;
-
-
- for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
- assert(sym->hdr == hdr);
-
- if ((name_space == -1) || (sym->name_space == name_space)) {
- return sym->data;
- }
- }
- }
-
- return NULL;
-}
-
-
-int
-_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
- int name_space, const char *name,
- void *declaration)
-{
- struct symbol_header *hdr;
- struct symbol *sym;
-
- check_symbol_table(table);
-
- hdr = find_symbol(table, name);
-
- check_symbol_table(table);
-
- if (hdr == NULL) {
- hdr = calloc(1, sizeof(*hdr));
- hdr->name = strdup(name);
-
- hash_table_insert(table->ht, hdr, hdr->name);
- hdr->next = table->hdr;
- table->hdr = hdr;
- }
-
- check_symbol_table(table);
-
- /* If the symbol already exists in this namespace at this scope, it cannot
- * be added to the table.
- */
- for (sym = hdr->symbols
- ; (sym != NULL) && (sym->name_space != name_space)
- ; sym = sym->next_with_same_name) {
- /* empty */
- }
-
- if (sym && (sym->depth == table->depth))
- return -1;
-
- sym = calloc(1, sizeof(*sym));
- sym->next_with_same_name = hdr->symbols;
- sym->next_with_same_scope = table->current_scope->symbols;
- sym->hdr = hdr;
- sym->name_space = name_space;
- sym->data = declaration;
- sym->depth = table->depth;
-
- assert(sym->hdr == hdr);
-
- hdr->symbols = sym;
- table->current_scope->symbols = sym;
-
- check_symbol_table(table);
- return 0;
-}
-
-
-int
-_mesa_symbol_table_add_global_symbol(struct _mesa_symbol_table *table,
- int name_space, const char *name,
- void *declaration)
-{
- struct symbol_header *hdr;
- struct symbol *sym;
- struct symbol *curr;
- struct scope_level *top_scope;
-
- check_symbol_table(table);
-
- hdr = find_symbol(table, name);
-
- check_symbol_table(table);
-
- if (hdr == NULL) {
- hdr = calloc(1, sizeof(*hdr));
- hdr->name = strdup(name);
-
- hash_table_insert(table->ht, hdr, hdr->name);
- hdr->next = table->hdr;
- table->hdr = hdr;
- }
-
- check_symbol_table(table);
-
- /* If the symbol already exists in this namespace at this scope, it cannot
- * be added to the table.
- */
- for (sym = hdr->symbols
- ; (sym != NULL) && (sym->name_space != name_space)
- ; sym = sym->next_with_same_name) {
- /* empty */
- }
-
- if (sym && sym->depth == 0)
- return -1;
-
- /* Find the top-level scope */
- for (top_scope = table->current_scope
- ; top_scope->next != NULL
- ; top_scope = top_scope->next) {
- /* empty */
- }
-
- sym = calloc(1, sizeof(*sym));
- sym->next_with_same_scope = top_scope->symbols;
- sym->hdr = hdr;
- sym->name_space = name_space;
- sym->data = declaration;
-
- assert(sym->hdr == hdr);
-
- /* Since next_with_same_name is ordered by scope, we need to append the
- * new symbol to the _end_ of the list.
- */
- if (hdr->symbols == NULL) {
- hdr->symbols = sym;
- } else {
- for (curr = hdr->symbols
- ; curr->next_with_same_name != NULL
- ; curr = curr->next_with_same_name) {
- /* empty */
- }
- curr->next_with_same_name = sym;
- }
- top_scope->symbols = sym;
-
- check_symbol_table(table);
- return 0;
-}
-
-
-
-struct _mesa_symbol_table *
-_mesa_symbol_table_ctor(void)
-{
- struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
-
- if (table != NULL) {
- table->ht = hash_table_ctor(32, hash_table_string_hash,
- hash_table_string_compare);
-
- _mesa_symbol_table_push_scope(table);
- }
-
- return table;
-}
-
-
-void
-_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
-{
- struct symbol_header *hdr;
- struct symbol_header *next;
-
- while (table->current_scope != NULL) {
- _mesa_symbol_table_pop_scope(table);
- }
-
- for (hdr = table->hdr; hdr != NULL; hdr = next) {
- next = hdr->next;
- free(hdr->name);
- free(hdr);
- }
-
- hash_table_dtor(table->ht);
- free(table);
-}
+/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "main/imports.h" +#include "symbol_table.h" +#include "hash_table.h" + +struct symbol { + /** + * Link to the next symbol in the table with the same name + * + * The linked list of symbols with the same name is ordered by scope + * from inner-most to outer-most. + */ + struct symbol *next_with_same_name; + + + /** + * Link to the next symbol in the table with the same scope + * + * The linked list of symbols with the same scope is unordered. Symbols + * in this list my have unique names. + */ + struct symbol *next_with_same_scope; + + + /** + * Header information for the list of symbols with the same name. + */ + struct symbol_header *hdr; + + + /** + * Name space of the symbol + * + * Name space are arbitrary user assigned integers. No two symbols can + * exist in the same name space at the same scope level. + */ + int name_space; + + /** Scope depth where this symbol was defined. */ + unsigned depth; + + /** + * Arbitrary user supplied data. + */ + void *data; +}; + + +/** + */ +struct symbol_header { + /** Linkage in list of all headers in a given symbol table. */ + struct symbol_header *next; + + /** Symbol name. */ + char *name; + + /** Linked list of symbols with the same name. */ + struct symbol *symbols; +}; + + +/** + * Element of the scope stack. + */ +struct scope_level { + /** Link to next (inner) scope level. */ + struct scope_level *next; + + /** Linked list of symbols with the same scope. */ + struct symbol *symbols; +}; + + +/** + * + */ +struct _mesa_symbol_table { + /** Hash table containing all symbols in the symbol table. */ + struct hash_table *ht; + + /** Top of scope stack. */ + struct scope_level *current_scope; + + /** List of all symbol headers in the table. */ + struct symbol_header *hdr; + + /** Current scope depth. */ + unsigned depth; +}; + + +struct _mesa_symbol_table_iterator { + /** + * Name space of symbols returned by this iterator. + */ + int name_space; + + + /** + * Currently iterated symbol + * + * The next call to \c _mesa_symbol_table_iterator_get will return this + * value. It will also update this value to the value that should be + * returned by the next call. + */ + struct symbol *curr; +}; + + +static void +check_symbol_table(struct _mesa_symbol_table *table) +{ +#if 1 + struct scope_level *scope; + + for (scope = table->current_scope; scope != NULL; scope = scope->next) { + struct symbol *sym; + + for (sym = scope->symbols + ; sym != NULL + ; sym = sym->next_with_same_name) { + const struct symbol_header *const hdr = sym->hdr; + struct symbol *sym2; + + for (sym2 = hdr->symbols + ; sym2 != NULL + ; sym2 = sym2->next_with_same_name) { + assert(sym2->hdr == hdr); + } + } + } +#endif +} + +void +_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table) +{ + struct scope_level *const scope = table->current_scope; + struct symbol *sym = scope->symbols; + + table->current_scope = scope->next; + table->depth--; + + free(scope); + + while (sym != NULL) { + struct symbol *const next = sym->next_with_same_scope; + struct symbol_header *const hdr = sym->hdr; + + assert(hdr->symbols == sym); + + hdr->symbols = sym->next_with_same_name; + + free(sym); + + sym = next; + } + + check_symbol_table(table); +} + + +void +_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table) +{ + struct scope_level *const scope = calloc(1, sizeof(*scope)); + + scope->next = table->current_scope; + table->current_scope = scope; + table->depth++; +} + + +static struct symbol_header * +find_symbol(struct _mesa_symbol_table *table, const char *name) +{ + return (struct symbol_header *) hash_table_find(table->ht, name); +} + + +struct _mesa_symbol_table_iterator * +_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table, + int name_space, const char *name) +{ + struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter)); + struct symbol_header *const hdr = find_symbol(table, name); + + iter->name_space = name_space; + + if (hdr != NULL) { + struct symbol *sym; + + for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { + assert(sym->hdr == hdr); + + if ((name_space == -1) || (sym->name_space == name_space)) { + iter->curr = sym; + break; + } + } + } + + return iter; +} + + +void +_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter) +{ + free(iter); +} + + +void * +_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter) +{ + return (iter->curr == NULL) ? NULL : iter->curr->data; +} + + +int +_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter) +{ + struct symbol_header *hdr; + + if (iter->curr == NULL) { + return 0; + } + + hdr = iter->curr->hdr; + iter->curr = iter->curr->next_with_same_name; + + while (iter->curr != NULL) { + assert(iter->curr->hdr == hdr); + (void)hdr; + + if ((iter->name_space == -1) + || (iter->curr->name_space == iter->name_space)) { + return 1; + } + + iter->curr = iter->curr->next_with_same_name; + } + + return 0; +} + + +/** + * Determine the scope "distance" of a symbol from the current scope + * + * \return + * A non-negative number for the number of scopes between the current scope + * and the scope where a symbol was defined. A value of zero means the current + * scope. A negative number if the symbol does not exist. + */ +int +_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table, + int name_space, const char *name) +{ + struct symbol_header *const hdr = find_symbol(table, name); + struct symbol *sym; + + if (hdr != NULL) { + for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { + assert(sym->hdr == hdr); + + if ((name_space == -1) || (sym->name_space == name_space)) { + assert(sym->depth <= table->depth); + return sym->depth - table->depth; + } + } + } + + return -1; +} + + +void * +_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table, + int name_space, const char *name) +{ + struct symbol_header *const hdr = find_symbol(table, name); + + if (hdr != NULL) { + struct symbol *sym; + + + for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { + assert(sym->hdr == hdr); + + if ((name_space == -1) || (sym->name_space == name_space)) { + return sym->data; + } + } + } + + return NULL; +} + + +int +_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table, + int name_space, const char *name, + void *declaration) +{ + struct symbol_header *hdr; + struct symbol *sym; + + check_symbol_table(table); + + hdr = find_symbol(table, name); + + check_symbol_table(table); + + if (hdr == NULL) { + hdr = calloc(1, sizeof(*hdr)); + hdr->name = strdup(name); + + hash_table_insert(table->ht, hdr, hdr->name); + hdr->next = table->hdr; + table->hdr = hdr; + } + + check_symbol_table(table); + + /* If the symbol already exists in this namespace at this scope, it cannot + * be added to the table. + */ + for (sym = hdr->symbols + ; (sym != NULL) && (sym->name_space != name_space) + ; sym = sym->next_with_same_name) { + /* empty */ + } + + if (sym && (sym->depth == table->depth)) + return -1; + + sym = calloc(1, sizeof(*sym)); + sym->next_with_same_name = hdr->symbols; + sym->next_with_same_scope = table->current_scope->symbols; + sym->hdr = hdr; + sym->name_space = name_space; + sym->data = declaration; + sym->depth = table->depth; + + assert(sym->hdr == hdr); + + hdr->symbols = sym; + table->current_scope->symbols = sym; + + check_symbol_table(table); + return 0; +} + + +int +_mesa_symbol_table_add_global_symbol(struct _mesa_symbol_table *table, + int name_space, const char *name, + void *declaration) +{ + struct symbol_header *hdr; + struct symbol *sym; + struct symbol *curr; + struct scope_level *top_scope; + + check_symbol_table(table); + + hdr = find_symbol(table, name); + + check_symbol_table(table); + + if (hdr == NULL) { + hdr = calloc(1, sizeof(*hdr)); + hdr->name = strdup(name); + + hash_table_insert(table->ht, hdr, hdr->name); + hdr->next = table->hdr; + table->hdr = hdr; + } + + check_symbol_table(table); + + /* If the symbol already exists in this namespace at this scope, it cannot + * be added to the table. + */ + for (sym = hdr->symbols + ; (sym != NULL) && (sym->name_space != name_space) + ; sym = sym->next_with_same_name) { + /* empty */ + } + + if (sym && sym->depth == 0) + return -1; + + /* Find the top-level scope */ + for (top_scope = table->current_scope + ; top_scope->next != NULL + ; top_scope = top_scope->next) { + /* empty */ + } + + sym = calloc(1, sizeof(*sym)); + sym->next_with_same_scope = top_scope->symbols; + sym->hdr = hdr; + sym->name_space = name_space; + sym->data = declaration; + + assert(sym->hdr == hdr); + + /* Since next_with_same_name is ordered by scope, we need to append the + * new symbol to the _end_ of the list. + */ + if (hdr->symbols == NULL) { + hdr->symbols = sym; + } else { + for (curr = hdr->symbols + ; curr->next_with_same_name != NULL + ; curr = curr->next_with_same_name) { + /* empty */ + } + curr->next_with_same_name = sym; + } + top_scope->symbols = sym; + + check_symbol_table(table); + return 0; +} + + + +struct _mesa_symbol_table * +_mesa_symbol_table_ctor(void) +{ + struct _mesa_symbol_table *table = calloc(1, sizeof(*table)); + + if (table != NULL) { + table->ht = hash_table_ctor(32, hash_table_string_hash, + hash_table_string_compare); + + _mesa_symbol_table_push_scope(table); + } + + return table; +} + + +void +_mesa_symbol_table_dtor(struct _mesa_symbol_table *table) +{ + struct symbol_header *hdr; + struct symbol_header *next; + + while (table->current_scope != NULL) { + _mesa_symbol_table_pop_scope(table); + } + + for (hdr = table->hdr; hdr != NULL; hdr = next) { + next = hdr->next; + free(hdr->name); + free(hdr); + } + + hash_table_dtor(table->ht); + free(table); +} diff --git a/mesalib/src/mesa/state_tracker/st_atom_clip.c b/mesalib/src/mesa/state_tracker/st_atom_clip.c index 236d3cf40..2a5110098 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_clip.c +++ b/mesalib/src/mesa/state_tracker/st_atom_clip.c @@ -35,6 +35,7 @@ #include "pipe/p_context.h" #include "st_atom.h" #include "st_program.h" +#include "util/u_debug.h" #include "cso_cache/cso_context.h" @@ -44,10 +45,9 @@ static void update_clip( struct st_context *st ) { struct pipe_clip_state clip; const struct gl_context *ctx = st->ctx; - GLuint i; bool use_eye = FALSE; - memset(&clip, 0, sizeof(clip)); + assert(sizeof(clip.ucp) <= sizeof(ctx->Transform._ClipUserPlane)); /* if we have a vertex shader that writes clip vertex we need to pass the pre-projection transformed coordinates into the driver. */ @@ -56,21 +56,11 @@ static void update_clip( struct st_context *st ) use_eye = TRUE; } - for (i = 0; i < PIPE_MAX_CLIP_PLANES; i++) { - if (ctx->Transform.ClipPlanesEnabled & (1 << i)) { - memcpy(clip.ucp[clip.nr], - use_eye ? ctx->Transform.EyeUserPlane[i] : ctx->Transform._ClipUserPlane[i], - sizeof(clip.ucp[0])); - clip.nr++; - } - } - - clip.depth_clamp = ctx->Transform.DepthClamp != GL_FALSE; - - if (memcmp(&clip, &st->state.clip, sizeof(clip)) != 0) { - st->state.clip = clip; - cso_set_clip(st->cso_context, &clip); - } + memcpy(clip.ucp, + use_eye ? ctx->Transform.EyeUserPlane + : ctx->Transform._ClipUserPlane, sizeof(clip.ucp)); + st->state.clip = clip; + cso_set_clip(st->cso_context, &clip); } diff --git a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c index 2d6ad45ba..f3d28e675 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c @@ -261,6 +261,10 @@ static void update_raster_state( struct st_context *st ) /* _NEW_RASTERIZER_DISCARD */ raster->rasterizer_discard = ctx->RasterDiscard; + /* _NEW_TRANSFORM */ + raster->depth_clip = ctx->Transform.DepthClamp == GL_FALSE; + raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled; + cso_set_rasterizer(st->cso_context, raster); } @@ -276,7 +280,8 @@ const struct st_tracked_state st_update_rasterizer = { _NEW_PROGRAM | _NEW_SCISSOR | _NEW_FRAG_CLAMP | - _NEW_RASTERIZER_DISCARD), /* mesa state dependencies*/ + _NEW_RASTERIZER_DISCARD | + _NEW_TRANSFORM), /* mesa state dependencies*/ ST_NEW_VERTEX_PROGRAM, /* state tracker dependencies */ }, update_raster_state /* update function */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c index af33bcf86..a97096802 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c @@ -870,6 +870,7 @@ st_init_bitmap(struct st_context *st) /* init baseline rasterizer state once */ memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer)); st->bitmap.rasterizer.gl_rasterization_rules = 1; + st->bitmap.rasterizer.depth_clip = 1; /* find a usable texture format */ if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM, diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c index 23700eeb7..a8365a708 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_clear.c +++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c @@ -68,6 +68,7 @@ st_init_clear(struct st_context *st) memset(&st->clear, 0, sizeof(st->clear)); st->clear.raster.gl_rasterization_rules = 1; + st->clear.raster.depth_clip = 1; st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE); } @@ -248,7 +249,6 @@ clear_with_quad(struct gl_context *ctx, cso_save_depth_stencil_alpha(st->cso_context); cso_save_rasterizer(st->cso_context); cso_save_viewport(st->cso_context); - cso_save_clip(st->cso_context); cso_save_fragment_shader(st->cso_context); cso_save_stream_outputs(st->cso_context); cso_save_vertex_shader(st->cso_context); @@ -326,7 +326,6 @@ clear_with_quad(struct gl_context *ctx, cso_set_viewport(st->cso_context, &vp); } - cso_set_clip(st->cso_context, &st->clear.clip); set_fragment_shader(st); set_vertex_shader(st); cso_set_geometry_shader_handle(st->cso_context, NULL); @@ -346,7 +345,6 @@ clear_with_quad(struct gl_context *ctx, cso_restore_depth_stencil_alpha(st->cso_context); cso_restore_rasterizer(st->cso_context); cso_restore_viewport(st->cso_context); - cso_restore_clip(st->cso_context); cso_restore_fragment_shader(st->cso_context); cso_restore_vertex_shader(st->cso_context); cso_restore_geometry_shader(st->cso_context); diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index 0609a54ea..13c4f3369 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -686,6 +686,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, memset(&rasterizer, 0, sizeof(rasterizer)); rasterizer.clamp_fragment_color = ctx->Color._ClampFragmentColor; rasterizer.gl_rasterization_rules = 1; + rasterizer.depth_clip = !ctx->Transform.DepthClamp; rasterizer.scissor = ctx->Scissor.Enabled; cso_set_rasterizer(cso, &rasterizer); } diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index c60780989..9db50b3f4 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -167,7 +167,6 @@ struct st_context struct { struct pipe_rasterizer_state raster; struct pipe_viewport_state viewport; - struct pipe_clip_state clip; void *vs; void *fs; float vertices[4][2][4]; /**< vertex pos + color */ diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index 4c8c67fca..a9d405436 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -592,7 +592,7 @@ void st_init_extensions(struct st_context *st) st->sw_primitive_restart = GL_TRUE; } - if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) { + if (screen->get_param(screen, PIPE_CAP_DEPTH_CLIP_DISABLE)) { ctx->Extensions.ARB_depth_clamp = GL_TRUE; } diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index c0af3ce11..b83cb2339 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -222,7 +222,6 @@ st_framebuffer_validate(struct st_framebuffer *stfb, continue; } - memset(&surf_tmpl, 0, sizeof(surf_tmpl)); u_surface_default_template(&surf_tmpl, textures[i], PIPE_BIND_RENDER_TARGET); ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl); diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c index 8d7469dfb..8d08b2b0f 100644 --- a/mesalib/src/mesa/state_tracker/st_program.c +++ b/mesalib/src/mesa/state_tracker/st_program.c @@ -441,7 +441,7 @@ st_translate_interp(enum glsl_interp_qualifier glsl_qual, bool is_color) switch (glsl_qual) { case INTERP_QUALIFIER_NONE: if (is_color) - return TGSI_INTERPOLATE_LINEAR; + return TGSI_INTERPOLATE_COLOR; return TGSI_INTERPOLATE_PERSPECTIVE; case INTERP_QUALIFIER_SMOOTH: return TGSI_INTERPOLATE_PERSPECTIVE; diff --git a/mesalib/src/mesa/swrast/s_blit.c b/mesalib/src/mesa/swrast/s_blit.c index 1063024fb..6d0b889c1 100644 --- a/mesalib/src/mesa/swrast/s_blit.c +++ b/mesalib/src/mesa/swrast/s_blit.c @@ -423,9 +423,66 @@ resample_linear_row_ub(GLint srcWidth, GLint dstWidth, } +/** + * Bilinear interpolation of two source rows. floating point pixels. + */ +static void +resample_linear_row_float(GLint srcWidth, GLint dstWidth, + const GLvoid *srcBuffer0, const GLvoid *srcBuffer1, + GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight) +{ + const GLfloat (*srcColor0)[4] = (const GLfloat (*)[4]) srcBuffer0; + const GLfloat (*srcColor1)[4] = (const GLfloat (*)[4]) srcBuffer1; + GLfloat (*dstColor)[4] = (GLfloat (*)[4]) dstBuffer; + const GLfloat dstWidthF = (GLfloat) dstWidth; + GLint dstCol; + + for (dstCol = 0; dstCol < dstWidth; dstCol++) { + const GLfloat srcCol = (dstCol * srcWidth) / dstWidthF; + GLint srcCol0 = IFLOOR(srcCol); + GLint srcCol1 = srcCol0 + 1; + GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */ + GLfloat red, green, blue, alpha; + + ASSERT(srcCol0 >= 0); + ASSERT(srcCol0 < srcWidth); + ASSERT(srcCol1 <= srcWidth); + + if (srcCol1 == srcWidth) { + /* last column fudge */ + srcCol1--; + colWeight = 0.0; + } + + if (flip) { + srcCol0 = srcWidth - 1 - srcCol0; + srcCol1 = srcWidth - 1 - srcCol1; + } + + red = lerp_2d(colWeight, rowWeight, + srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP], + srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]); + green = lerp_2d(colWeight, rowWeight, + srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP], + srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]); + blue = lerp_2d(colWeight, rowWeight, + srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP], + srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]); + alpha = lerp_2d(colWeight, rowWeight, + srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP], + srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]); + + dstColor[dstCol][RCOMP] = red; + dstColor[dstCol][GCOMP] = green; + dstColor[dstCol][BCOMP] = blue; + dstColor[dstCol][ACOMP] = alpha; + } +} + + /** - * Bilinear filtered blit (color only). + * Bilinear filtered blit (color only, non-integer values). */ static void blit_linear(struct gl_context *ctx, @@ -456,23 +513,25 @@ blit_linear(struct gl_context *ctx, GLint srcBufferY0 = -1, srcBufferY1 = -1; GLvoid *dstBuffer; - switch (readRb->DataType) { - case GL_UNSIGNED_BYTE: + gl_format readFormat = _mesa_get_srgb_format_linear(readRb->Format); + gl_format drawFormat = _mesa_get_srgb_format_linear(drawRb->Format); + GLuint bpp = _mesa_get_format_bytes(readFormat); + + GLenum pixelType; + + GLubyte *srcMap, *dstMap; + GLint srcRowStride, dstRowStride; + + + /* Determine datatype for resampling */ + if (_mesa_get_format_max_bits(readFormat) == 8 && + _mesa_get_format_datatype(readFormat) == GL_UNSIGNED_NORMALIZED) { + pixelType = GL_UNSIGNED_BYTE; pixelSize = 4 * sizeof(GLubyte); - break; - case GL_UNSIGNED_SHORT: - pixelSize = 4 * sizeof(GLushort); - break; - case GL_UNSIGNED_INT: - pixelSize = 4 * sizeof(GLuint); - break; - case GL_FLOAT: + } + else { + pixelType = GL_FLOAT; pixelSize = 4 * sizeof(GLfloat); - break; - default: - _mesa_problem(ctx, "unexpected buffer type (0x%x) in blit_nearest", - readRb->DataType); - return; } /* Allocate the src/dst row buffers. @@ -497,6 +556,45 @@ blit_linear(struct gl_context *ctx, return; } + /* + * Map src / dst renderbuffers + */ + if (readRb == drawRb) { + /* map whole buffer for read/write */ + ctx->Driver.MapRenderbuffer(ctx, readRb, + 0, 0, readRb->Width, readRb->Height, + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, + &srcMap, &srcRowStride); + if (!srcMap) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); + return; + } + + dstMap = srcMap; + dstRowStride = srcRowStride; + } + else { + /* different src/dst buffers */ + /* XXX with a bit of work we could just map the regions to be + * read/written instead of the whole buffers. + */ + ctx->Driver.MapRenderbuffer(ctx, readRb, + 0, 0, readRb->Width, readRb->Height, + GL_MAP_READ_BIT, &srcMap, &srcRowStride); + if (!srcMap) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); + return; + } + ctx->Driver.MapRenderbuffer(ctx, drawRb, + 0, 0, drawRb->Width, drawRb->Height, + GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); + if (!dstMap) { + ctx->Driver.UnmapRenderbuffer(ctx, readRb); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); + return; + } + } + for (dstRow = 0; dstRow < dstHeight; dstRow++) { const GLint dstY = dstYpos + dstRow; const GLfloat srcRow = (dstRow * srcHeight) / dstHeightF; @@ -531,36 +629,73 @@ blit_linear(struct gl_context *ctx, srcBuffer0 = srcBuffer1; srcBuffer1 = tmp; /* get y1 row */ - readRb->GetRow(ctx, readRb, srcWidth, srcXpos, srcY1, srcBuffer1); + { + GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp; + if (pixelType == GL_UNSIGNED_BYTE) { + _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, + src, srcBuffer1); + } + else { + _mesa_unpack_rgba_row(readFormat, srcWidth, + src, srcBuffer1); + } + } srcBufferY0 = srcY0; srcBufferY1 = srcY1; } else { /* get both new rows */ - readRb->GetRow(ctx, readRb, srcWidth, srcXpos, srcY0, srcBuffer0); - readRb->GetRow(ctx, readRb, srcWidth, srcXpos, srcY1, srcBuffer1); + { + GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp; + GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp; + if (pixelType == GL_UNSIGNED_BYTE) { + _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, + src0, srcBuffer0); + _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, + src1, srcBuffer1); + } + else { + _mesa_unpack_rgba_row(readFormat, srcWidth, src0, srcBuffer0); + _mesa_unpack_rgba_row(readFormat, srcWidth, src1, srcBuffer1); + } + } srcBufferY0 = srcY0; srcBufferY1 = srcY1; } - if (readRb->DataType == GL_UNSIGNED_BYTE) { + if (pixelType == GL_UNSIGNED_BYTE) { resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1, dstBuffer, invertX, rowWeight); } else { - _mesa_problem(ctx, "Unsupported color channel type in sw blit"); - break; + resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, srcBuffer1, + dstBuffer, invertX, rowWeight); } /* store pixel row in destination */ - drawRb->PutRow(ctx, drawRb, dstWidth, dstXpos, dstY, dstBuffer, NULL); + { + GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp; + if (pixelType == GL_UNSIGNED_BYTE) { + _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, dst); + } + else { + _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, dst); + } + } } free(srcBuffer0); free(srcBuffer1); free(dstBuffer); + + ctx->Driver.UnmapRenderbuffer(ctx, readRb); + if (drawRb != readRb) { + ctx->Driver.UnmapRenderbuffer(ctx, drawRb); + } } + + /** * Software fallback for glBlitFramebufferEXT(). */ @@ -626,10 +761,8 @@ _swrast_BlitFramebuffer(struct gl_context *ctx, else { ASSERT(filter == GL_LINEAR); if (mask & GL_COLOR_BUFFER_BIT) { /* depth/stencil not allowed */ - swrast_render_start(ctx); blit_linear(ctx, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1); - swrast_render_finish(ctx); } } diff --git a/pixman/pixman/pixman-combine.c.template b/pixman/pixman/pixman-combine.c.template index c17bcea5d..cd008d967 100644 --- a/pixman/pixman/pixman-combine.c.template +++ b/pixman/pixman/pixman-combine.c.template @@ -522,7 +522,7 @@ combine_multiply_ca (pixman_implementation_t *imp, UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \ \ *(dest + i) = result + \ - (DIV_ONE_UNc (sa * da) << A_SHIFT) + \ + (DIV_ONE_UNc (sa * (comp4_t)da) << A_SHIFT) + \ (blend_ ## name (RED_c (d), da, RED_c (s), sa) << R_SHIFT) + \ (blend_ ## name (GREEN_c (d), da, GREEN_c (s), sa) << G_SHIFT) + \ (blend_ ## name (BLUE_c (d), da, BLUE_c (s), sa)); \ @@ -552,7 +552,7 @@ combine_multiply_ca (pixman_implementation_t *imp, UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida); \ \ result += \ - (DIV_ONE_UNc (ALPHA_c (m) * da) << A_SHIFT) + \ + (DIV_ONE_UNc (ALPHA_c (m) * (comp4_t)da) << A_SHIFT) + \ (blend_ ## name (RED_c (d), da, RED_c (s), RED_c (m)) << R_SHIFT) + \ (blend_ ## name (GREEN_c (d), da, GREEN_c (s), GREEN_c (m)) << G_SHIFT) + \ (blend_ ## name (BLUE_c (d), da, BLUE_c (s), BLUE_c (m))); \ @@ -926,7 +926,7 @@ PDF_SEPARABLE_BLEND_MODE (exclusion) blend_ ## name (c, dc, da, sc, sa); \ \ *(dest + i) = result + \ - (DIV_ONE_UNc (sa * da) << A_SHIFT) + \ + (DIV_ONE_UNc (sa * (comp4_t)da) << A_SHIFT) + \ (DIV_ONE_UNc (c[0]) << R_SHIFT) + \ (DIV_ONE_UNc (c[1]) << G_SHIFT) + \ (DIV_ONE_UNc (c[2])); \ diff --git a/pixman/pixman/pixman-combine.h.template b/pixman/pixman/pixman-combine.h.template index c5b6dcdc6..20f784b5b 100644 --- a/pixman/pixman/pixman-combine.h.template +++ b/pixman/pixman/pixman-combine.h.template @@ -1,226 +1,226 @@ -
-#define COMPONENT_SIZE
-#define MASK
-#define ONE_HALF
-
-#define A_SHIFT
-#define R_SHIFT
-#define G_SHIFT
-#define A_MASK
-#define R_MASK
-#define G_MASK
-
-#define RB_MASK
-#define AG_MASK
-#define RB_ONE_HALF
-#define RB_MASK_PLUS_ONE
-
-#define ALPHA_c(x) ((x) >> A_SHIFT)
-#define RED_c(x) (((x) >> R_SHIFT) & MASK)
-#define GREEN_c(x) (((x) >> G_SHIFT) & MASK)
-#define BLUE_c(x) ((x) & MASK)
-
-/*
- * Helper macros.
- */
-
-#define MUL_UNc(a, b, t) \
- ((t) = (a) * (b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
-
-#define DIV_UNc(a, b) \
- (((comp2_t) (a) * MASK) / (b))
-
-#define ADD_UNc(x, y, t) \
- ((t) = (x) + (y), \
- (comp4_t) (comp1_t) ((t) | (0 - ((t) >> G_SHIFT))))
-
-#define DIV_ONE_UNc(x) \
- (((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT)
-
-/*
- * The methods below use some tricks to be able to do two color
- * components at the same time.
- */
-
-/*
- * x_rb = (x_rb * a) / 255
- */
-#define UNc_rb_MUL_UNc(x, a, t) \
- do \
- { \
- t = ((x) & RB_MASK) * (a); \
- t += RB_ONE_HALF; \
- x = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
- x &= RB_MASK; \
- } while (0)
-
-/*
- * x_rb = min (x_rb + y_rb, 255)
- */
-#define UNc_rb_ADD_UNc_rb(x, y, t) \
- do \
- { \
- t = ((x) + (y)); \
- t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \
- x = (t & RB_MASK); \
- } while (0)
-
-/*
- * x_rb = (x_rb * a_rb) / 255
- */
-#define UNc_rb_MUL_UNc_rb(x, a, t) \
- do \
- { \
- t = (x & MASK) * (a & MASK); \
- t |= (x & R_MASK) * ((a >> R_SHIFT) & MASK); \
- t += RB_ONE_HALF; \
- t = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
- x = t & RB_MASK; \
- } while (0)
-
-/*
- * x_c = (x_c * a) / 255
- */
-#define UNcx4_MUL_UNc(x, a) \
- do \
- { \
- comp4_t r1__, r2__, t__; \
- \
- r1__ = (x); \
- UNc_rb_MUL_UNc (r1__, (a), t__); \
- \
- r2__ = (x) >> G_SHIFT; \
- UNc_rb_MUL_UNc (r2__, (a), t__); \
- \
- (x) = r1__ | (r2__ << G_SHIFT); \
- } while (0)
-
-/*
- * x_c = (x_c * a) / 255 + y_c
- */
-#define UNcx4_MUL_UNc_ADD_UNcx4(x, a, y) \
- do \
- { \
- comp4_t r1__, r2__, r3__, t__; \
- \
- r1__ = (x); \
- r2__ = (y) & RB_MASK; \
- UNc_rb_MUL_UNc (r1__, (a), t__); \
- UNc_rb_ADD_UNc_rb (r1__, r2__, t__); \
- \
- r2__ = (x) >> G_SHIFT; \
- r3__ = ((y) >> G_SHIFT) & RB_MASK; \
- UNc_rb_MUL_UNc (r2__, (a), t__); \
- UNc_rb_ADD_UNc_rb (r2__, r3__, t__); \
- \
- (x) = r1__ | (r2__ << G_SHIFT); \
- } while (0)
-
-/*
- * x_c = (x_c * a + y_c * b) / 255
- */
-#define UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc(x, a, y, b) \
- do \
- { \
- comp4_t r1__, r2__, r3__, t__; \
- \
- r1__ = (x); \
- r2__ = (y); \
- UNc_rb_MUL_UNc (r1__, (a), t__); \
- UNc_rb_MUL_UNc (r2__, (b), t__); \
- UNc_rb_ADD_UNc_rb (r1__, r2__, t__); \
- \
- r2__ = ((x) >> G_SHIFT); \
- r3__ = ((y) >> G_SHIFT); \
- UNc_rb_MUL_UNc (r2__, (a), t__); \
- UNc_rb_MUL_UNc (r3__, (b), t__); \
- UNc_rb_ADD_UNc_rb (r2__, r3__, t__); \
- \
- (x) = r1__ | (r2__ << G_SHIFT); \
- } while (0)
-
-/*
- * x_c = (x_c * a_c) / 255
- */
-#define UNcx4_MUL_UNcx4(x, a) \
- do \
- { \
- comp4_t r1__, r2__, r3__, t__; \
- \
- r1__ = (x); \
- r2__ = (a); \
- UNc_rb_MUL_UNc_rb (r1__, r2__, t__); \
- \
- r2__ = (x) >> G_SHIFT; \
- r3__ = (a) >> G_SHIFT; \
- UNc_rb_MUL_UNc_rb (r2__, r3__, t__); \
- \
- (x) = r1__ | (r2__ << G_SHIFT); \
- } while (0)
-
-/*
- * x_c = (x_c * a_c) / 255 + y_c
- */
-#define UNcx4_MUL_UNcx4_ADD_UNcx4(x, a, y) \
- do \
- { \
- comp4_t r1__, r2__, r3__, t__; \
- \
- r1__ = (x); \
- r2__ = (a); \
- UNc_rb_MUL_UNc_rb (r1__, r2__, t__); \
- r2__ = (y) & RB_MASK; \
- UNc_rb_ADD_UNc_rb (r1__, r2__, t__); \
- \
- r2__ = ((x) >> G_SHIFT); \
- r3__ = ((a) >> G_SHIFT); \
- UNc_rb_MUL_UNc_rb (r2__, r3__, t__); \
- r3__ = ((y) >> G_SHIFT) & RB_MASK; \
- UNc_rb_ADD_UNc_rb (r2__, r3__, t__); \
- \
- (x) = r1__ | (r2__ << G_SHIFT); \
- } while (0)
-
-/*
- * x_c = (x_c * a_c + y_c * b) / 255
- */
-#define UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc(x, a, y, b) \
- do \
- { \
- comp4_t r1__, r2__, r3__, t__; \
- \
- r1__ = (x); \
- r2__ = (a); \
- UNc_rb_MUL_UNc_rb (r1__, r2__, t__); \
- r2__ = (y); \
- UNc_rb_MUL_UNc (r2__, (b), t__); \
- UNc_rb_ADD_UNc_rb (r1__, r2__, t__); \
- \
- r2__ = (x) >> G_SHIFT; \
- r3__ = (a) >> G_SHIFT; \
- UNc_rb_MUL_UNc_rb (r2__, r3__, t__); \
- r3__ = (y) >> G_SHIFT; \
- UNc_rb_MUL_UNc (r3__, (b), t__); \
- UNc_rb_ADD_UNc_rb (r2__, r3__, t__); \
- \
- x = r1__ | (r2__ << G_SHIFT); \
- } while (0)
-
-/*
- x_c = min(x_c + y_c, 255)
-*/
-#define UNcx4_ADD_UNcx4(x, y) \
- do \
- { \
- comp4_t r1__, r2__, r3__, t__; \
- \
- r1__ = (x) & RB_MASK; \
- r2__ = (y) & RB_MASK; \
- UNc_rb_ADD_UNc_rb (r1__, r2__, t__); \
- \
- r2__ = ((x) >> G_SHIFT) & RB_MASK; \
- r3__ = ((y) >> G_SHIFT) & RB_MASK; \
- UNc_rb_ADD_UNc_rb (r2__, r3__, t__); \
- \
- x = r1__ | (r2__ << G_SHIFT); \
- } while (0)
+ +#define COMPONENT_SIZE +#define MASK +#define ONE_HALF + +#define A_SHIFT +#define R_SHIFT +#define G_SHIFT +#define A_MASK +#define R_MASK +#define G_MASK + +#define RB_MASK +#define AG_MASK +#define RB_ONE_HALF +#define RB_MASK_PLUS_ONE + +#define ALPHA_c(x) ((x) >> A_SHIFT) +#define RED_c(x) (((x) >> R_SHIFT) & MASK) +#define GREEN_c(x) (((x) >> G_SHIFT) & MASK) +#define BLUE_c(x) ((x) & MASK) + +/* + * Helper macros. + */ + +#define MUL_UNc(a, b, t) \ + ((t) = (a) * (comp2_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT )) + +#define DIV_UNc(a, b) \ + (((comp2_t) (a) * MASK + ((b) / 2)) / (b)) + +#define ADD_UNc(x, y, t) \ + ((t) = (x) + (y), \ + (comp4_t) (comp1_t) ((t) | (0 - ((t) >> G_SHIFT)))) + +#define DIV_ONE_UNc(x) \ + (((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT) + +/* + * The methods below use some tricks to be able to do two color + * components at the same time. + */ + +/* + * x_rb = (x_rb * a) / 255 + */ +#define UNc_rb_MUL_UNc(x, a, t) \ + do \ + { \ + t = ((x) & RB_MASK) * (a); \ + t += RB_ONE_HALF; \ + x = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \ + x &= RB_MASK; \ + } while (0) + +/* + * x_rb = min (x_rb + y_rb, 255) + */ +#define UNc_rb_ADD_UNc_rb(x, y, t) \ + do \ + { \ + t = ((x) + (y)); \ + t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \ + x = (t & RB_MASK); \ + } while (0) + +/* + * x_rb = (x_rb * a_rb) / 255 + */ +#define UNc_rb_MUL_UNc_rb(x, a, t) \ + do \ + { \ + t = (x & MASK) * (a & MASK); \ + t |= (x & R_MASK) * ((a >> R_SHIFT) & MASK); \ + t += RB_ONE_HALF; \ + t = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \ + x = t & RB_MASK; \ + } while (0) + +/* + * x_c = (x_c * a) / 255 + */ +#define UNcx4_MUL_UNc(x, a) \ + do \ + { \ + comp4_t r1__, r2__, t__; \ + \ + r1__ = (x); \ + UNc_rb_MUL_UNc (r1__, (a), t__); \ + \ + r2__ = (x) >> G_SHIFT; \ + UNc_rb_MUL_UNc (r2__, (a), t__); \ + \ + (x) = r1__ | (r2__ << G_SHIFT); \ + } while (0) + +/* + * x_c = (x_c * a) / 255 + y_c + */ +#define UNcx4_MUL_UNc_ADD_UNcx4(x, a, y) \ + do \ + { \ + comp4_t r1__, r2__, r3__, t__; \ + \ + r1__ = (x); \ + r2__ = (y) & RB_MASK; \ + UNc_rb_MUL_UNc (r1__, (a), t__); \ + UNc_rb_ADD_UNc_rb (r1__, r2__, t__); \ + \ + r2__ = (x) >> G_SHIFT; \ + r3__ = ((y) >> G_SHIFT) & RB_MASK; \ + UNc_rb_MUL_UNc (r2__, (a), t__); \ + UNc_rb_ADD_UNc_rb (r2__, r3__, t__); \ + \ + (x) = r1__ | (r2__ << G_SHIFT); \ + } while (0) + +/* + * x_c = (x_c * a + y_c * b) / 255 + */ +#define UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc(x, a, y, b) \ + do \ + { \ + comp4_t r1__, r2__, r3__, t__; \ + \ + r1__ = (x); \ + r2__ = (y); \ + UNc_rb_MUL_UNc (r1__, (a), t__); \ + UNc_rb_MUL_UNc (r2__, (b), t__); \ + UNc_rb_ADD_UNc_rb (r1__, r2__, t__); \ + \ + r2__ = ((x) >> G_SHIFT); \ + r3__ = ((y) >> G_SHIFT); \ + UNc_rb_MUL_UNc (r2__, (a), t__); \ + UNc_rb_MUL_UNc (r3__, (b), t__); \ + UNc_rb_ADD_UNc_rb (r2__, r3__, t__); \ + \ + (x) = r1__ | (r2__ << G_SHIFT); \ + } while (0) + +/* + * x_c = (x_c * a_c) / 255 + */ +#define UNcx4_MUL_UNcx4(x, a) \ + do \ + { \ + comp4_t r1__, r2__, r3__, t__; \ + \ + r1__ = (x); \ + r2__ = (a); \ + UNc_rb_MUL_UNc_rb (r1__, r2__, t__); \ + \ + r2__ = (x) >> G_SHIFT; \ + r3__ = (a) >> G_SHIFT; \ + UNc_rb_MUL_UNc_rb (r2__, r3__, t__); \ + \ + (x) = r1__ | (r2__ << G_SHIFT); \ + } while (0) + +/* + * x_c = (x_c * a_c) / 255 + y_c + */ +#define UNcx4_MUL_UNcx4_ADD_UNcx4(x, a, y) \ + do \ + { \ + comp4_t r1__, r2__, r3__, t__; \ + \ + r1__ = (x); \ + r2__ = (a); \ + UNc_rb_MUL_UNc_rb (r1__, r2__, t__); \ + r2__ = (y) & RB_MASK; \ + UNc_rb_ADD_UNc_rb (r1__, r2__, t__); \ + \ + r2__ = ((x) >> G_SHIFT); \ + r3__ = ((a) >> G_SHIFT); \ + UNc_rb_MUL_UNc_rb (r2__, r3__, t__); \ + r3__ = ((y) >> G_SHIFT) & RB_MASK; \ + UNc_rb_ADD_UNc_rb (r2__, r3__, t__); \ + \ + (x) = r1__ | (r2__ << G_SHIFT); \ + } while (0) + +/* + * x_c = (x_c * a_c + y_c * b) / 255 + */ +#define UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc(x, a, y, b) \ + do \ + { \ + comp4_t r1__, r2__, r3__, t__; \ + \ + r1__ = (x); \ + r2__ = (a); \ + UNc_rb_MUL_UNc_rb (r1__, r2__, t__); \ + r2__ = (y); \ + UNc_rb_MUL_UNc (r2__, (b), t__); \ + UNc_rb_ADD_UNc_rb (r1__, r2__, t__); \ + \ + r2__ = (x) >> G_SHIFT; \ + r3__ = (a) >> G_SHIFT; \ + UNc_rb_MUL_UNc_rb (r2__, r3__, t__); \ + r3__ = (y) >> G_SHIFT; \ + UNc_rb_MUL_UNc (r3__, (b), t__); \ + UNc_rb_ADD_UNc_rb (r2__, r3__, t__); \ + \ + x = r1__ | (r2__ << G_SHIFT); \ + } while (0) + +/* + x_c = min(x_c + y_c, 255) +*/ +#define UNcx4_ADD_UNcx4(x, y) \ + do \ + { \ + comp4_t r1__, r2__, r3__, t__; \ + \ + r1__ = (x) & RB_MASK; \ + r2__ = (y) & RB_MASK; \ + UNc_rb_ADD_UNc_rb (r1__, r2__, t__); \ + \ + r2__ = ((x) >> G_SHIFT) & RB_MASK; \ + r3__ = ((y) >> G_SHIFT) & RB_MASK; \ + UNc_rb_ADD_UNc_rb (r2__, r3__, t__); \ + \ + x = r1__ | (r2__ << G_SHIFT); \ + } while (0) diff --git a/pixman/pixman/pixman-fast-path.c b/pixman/pixman/pixman-fast-path.c index 038dcf722..eac8dea66 100644 --- a/pixman/pixman/pixman-fast-path.c +++ b/pixman/pixman/pixman-fast-path.c @@ -1969,9 +1969,9 @@ static const pixman_fast_path_t c_fast_paths[] = }; #ifdef WORDS_BIGENDIAN -#define A1_FILL_MASK(n, offs) (((1 << (n)) - 1) << (32 - (offs) - (n))) +#define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (32 - (offs) - (n))) #else -#define A1_FILL_MASK(n, offs) (((1 << (n)) - 1) << (offs)) +#define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (offs)) #endif static force_inline void diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c index 913853ceb..8599a1eb1 100644 --- a/pixman/pixman/pixman-image.c +++ b/pixman/pixman/pixman-image.c @@ -299,13 +299,12 @@ compute_image_info (pixman_image_t *image) image->common.transform->matrix[1][1] == 0) { pixman_fixed_t m01 = image->common.transform->matrix[0][1]; - if (m01 == -image->common.transform->matrix[1][0]) - { - if (m01 == -pixman_fixed_1) - flags |= FAST_PATH_ROTATE_90_TRANSFORM; - else if (m01 == pixman_fixed_1) - flags |= FAST_PATH_ROTATE_270_TRANSFORM; - } + pixman_fixed_t m10 = image->common.transform->matrix[1][0]; + + if (m01 == -1 && m10 == 1) + flags |= FAST_PATH_ROTATE_90_TRANSFORM; + else if (m01 == 1 && m10 == -1) + flags |= FAST_PATH_ROTATE_270_TRANSFORM; } } @@ -631,7 +630,7 @@ pixman_image_set_transform (pixman_image_t * image, } if (common->transform && - memcmp (common->transform, transform, sizeof (pixman_transform_t) == 0)) + memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0) { return TRUE; } diff --git a/pixman/pixman/pixman-mmx.c b/pixman/pixman/pixman-mmx.c index 42a7ba7cc..f5c37b551 100644 --- a/pixman/pixman/pixman-mmx.c +++ b/pixman/pixman/pixman-mmx.c @@ -77,17 +77,38 @@ _mm_empty (void) /* --------------- MMX primitives ------------------------------------- */ -#ifdef __GNUC__ +/* If __m64 is defined as a struct or union, then define M64_MEMBER to be + * the name of the member used to access the data. + * If __m64 requires using mm_cvt* intrinsics functions to convert between + * uint64_t and __m64 values, then define USE_CVT_INTRINSICS. + * If __m64 and uint64_t values can just be cast to each other directly, + * then define USE_M64_CASTS. + */ +#ifdef _MSC_VER +# define M64_MEMBER m64_u64 +#elif defined(__ICC) +# define USE_CVT_INTRINSICS +#elif defined(__GNUC__) +# define USE_M64_CASTS +#elif defined(__SUNPRO_C) +# if (__SUNPRO_C >= 0x5120) && !defined(__NOVECTORSIZE__) +/* Solaris Studio 12.3 (Sun C 5.12) introduces __attribute__(__vector_size__) + * support, and defaults to using it to define __m64, unless __NOVECTORSIZE__ + * is defined. If it is used, then the mm_cvt* intrinsics must be used. + */ +# define USE_CVT_INTRINSICS +# else +/* For Studio 12.2 or older, or when __attribute__(__vector_size__) is + * disabled, __m64 is defined as a struct containing "unsigned long long l_". + */ +# define M64_MEMBER l_ +# endif +#endif + +#if defined(USE_M64_CASTS) || defined(USE_CVT_INTRINSICS) typedef uint64_t mmxdatafield; #else typedef __m64 mmxdatafield; -/* If __m64 is defined as a struct or union, define M64_MEMBER to be the - name of the member used to access the data */ -# ifdef _MSC_VER -# define M64_MEMBER m64_u64 -# elif defined(__SUNPRO_C) -# define M64_MEMBER l_ -# endif #endif typedef struct @@ -113,7 +134,7 @@ typedef struct # define MMXDATA_INIT(field, val) { val ## UI64 } #elif defined(M64_MEMBER) /* __m64 is a struct, not an integral type */ # define MMXDATA_INIT(field, val) field = { val ## ULL } -#else /* __m64 is an integral type */ +#else /* mmxdatafield is an integral type */ # define MMXDATA_INIT(field, val) field = val ## ULL #endif @@ -136,12 +157,10 @@ static const mmx_data_t c = MMXDATA_INIT (.mmx_000000000000ffff, 0x000000000000ffff), }; -#ifdef __GNUC__ -# ifdef __ICC -# define MC(x) to_m64 (c.mmx_ ## x) -# else -# define MC(x) ((__m64)c.mmx_ ## x) -# endif +#ifdef USE_CVT_INTRINSICS +# define MC(x) to_m64 (c.mmx_ ## x) +#elif defined(USE_M64_CASTS) +# define MC(x) ((__m64)c.mmx_ ## x) #else # define MC(x) c.mmx_ ## x #endif @@ -149,14 +168,14 @@ static const mmx_data_t c = static force_inline __m64 to_m64 (uint64_t x) { -#ifdef __ICC +#ifdef USE_CVT_INTRINSICS return _mm_cvtsi64_m64 (x); #elif defined M64_MEMBER /* __m64 is a struct, not an integral type */ __m64 res; res.M64_MEMBER = x; return res; -#else /* __m64 is an integral type */ +#else /* USE_M64_CASTS */ return (__m64)x; #endif } @@ -167,12 +186,12 @@ to_m64 (uint64_t x) static force_inline uint64_t to_uint64 (__m64 x) { -#ifdef __ICC +#ifdef USE_CVT_INTRINSICS return _mm_cvtm64_si64 (x); #elif defined M64_MEMBER /* __m64 is a struct, not an integral type */ uint64_t res = x.M64_MEMBER; return res; -#else /* __m64 is an integral type */ +#else /* USE_M64_CASTS */ return (uint64_t)x; #endif } diff --git a/pixman/pixman/pixman-utils.c b/pixman/pixman/pixman-utils.c index d2af51a30..2ec2594e1 100644 --- a/pixman/pixman/pixman-utils.c +++ b/pixman/pixman/pixman-utils.c @@ -220,16 +220,33 @@ pixman_expand (uint64_t * dst, for (i = width - 1; i >= 0; i--) { const uint32_t pixel = src[i]; - const uint8_t a = (pixel >> a_shift) & a_mask, - r = (pixel >> r_shift) & r_mask, - g = (pixel >> g_shift) & g_mask, - b = (pixel >> b_shift) & b_mask; - const uint64_t - a16 = a_size ? unorm_to_unorm (a, a_size, 16) : 0xffff, - r16 = unorm_to_unorm (r, r_size, 16), - g16 = unorm_to_unorm (g, g_size, 16), - b16 = unorm_to_unorm (b, b_size, 16); + uint8_t a, r, g, b; + uint64_t a16, r16, g16, b16; + + if (a_size) + { + a = (pixel >> a_shift) & a_mask; + a16 = unorm_to_unorm (a, a_size, 16); + } + else + { + a16 = 0xffff; + } + if (r_size) + { + r = (pixel >> r_shift) & r_mask; + g = (pixel >> g_shift) & g_mask; + b = (pixel >> b_shift) & b_mask; + r16 = unorm_to_unorm (r, r_size, 16); + g16 = unorm_to_unorm (g, g_size, 16); + b16 = unorm_to_unorm (b, b_size, 16); + } + else + { + r16 = g16 = b16 = 0; + } + dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16; } } diff --git a/pixman/pixman/pixman.h b/pixman/pixman/pixman.h index 18d951312..20ff49695 100644 --- a/pixman/pixman/pixman.h +++ b/pixman/pixman/pixman.h @@ -908,10 +908,14 @@ struct pixman_triangle }; /* whether 't' is a well defined not obviously empty trapezoid */ -#define pixman_trapezoid_valid(t) \ - ((t)->left.p1.y != (t)->left.p2.y && \ - (t)->right.p1.y != (t)->right.p2.y && \ - (int) ((t)->bottom - (t)->top) > 0) +#define pixman_trapezoid_valid(t) \ + ((t)->left.p1.y != (t)->left.p2.y && \ + (t)->right.p1.y != (t)->right.p2.y && \ + (int) ((t)->bottom - (t)->top) > 0 && \ + (t)->bottom <= (t)->left.p2.y && \ + (t)->bottom <= (t)->right.p2.y && \ + (t)->top >= (t)->left.p1.y && \ + (t)->top >= (t)->right.p1.y) struct pixman_span_fix { diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c index 55b6c735c..feea308c2 100644 --- a/pixman/test/blitters-test.c +++ b/pixman/test/blitters-test.c @@ -103,7 +103,7 @@ free_random_image (uint32_t initcrc, mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt)); } - for (i = 0; i < 32; i++) + for (i = 0; i * PIXMAN_FORMAT_BPP (fmt) < 32; i++) mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt)); for (i = 0; i < stride * height / 4; i++) @@ -424,6 +424,6 @@ main (int argc, const char *argv[]) } return fuzzer_test_main("blitters", 2000000, - 0x29137844, + 0xA364B5BF, test_composite, argc, argv); } diff --git a/pixman/test/composite-traps-test.c b/pixman/test/composite-traps-test.c index ff03b50d9..de518d820 100644 --- a/pixman/test/composite-traps-test.c +++ b/pixman/test/composite-traps-test.c @@ -251,6 +251,6 @@ test_composite (int testnum, int main (int argc, const char *argv[]) { - return fuzzer_test_main("composite traps", 40000, 0xE3112106, + return fuzzer_test_main("composite traps", 40000, 0x4346479C, test_composite, argc, argv); } diff --git a/pixman/test/region-contains-test.c b/pixman/test/region-contains-test.c index 2372686fc..9524e2888 100644 --- a/pixman/test/region-contains-test.c +++ b/pixman/test/region-contains-test.c @@ -73,7 +73,7 @@ random_coord (pixman_region32_t *region, pixman_bool_t x) case 3: return begin; default: - return (begin + end) / 2; + return (end - begin) / 2 + begin; } return 0; } @@ -163,7 +163,7 @@ main (int argc, const char *argv[]) { return fuzzer_test_main ("region_contains", 1000000, - 0xD7C297CC, + 0xD2BF8C73, test_region_contains_rectangle, argc, argv); } diff --git a/pixman/test/stress-test.c b/pixman/test/stress-test.c index 08bf1d4df..3174621e6 100644 --- a/pixman/test/stress-test.c +++ b/pixman/test/stress-test.c @@ -166,7 +166,8 @@ fake_reader (const void *src, int size) uint32_t r = lcg_rand_u32 (); assert (size == 1 || size == 2 || size == 4); - return r & ((1 << (size * 8)) - 1); + + return r >> (32 - (size * 8)); } static void diff --git a/xorg-server/Xext/xace.c b/xorg-server/Xext/xace.c index 77b713ffb..69cb2bbdb 100644 --- a/xorg-server/Xext/xace.c +++ b/xorg-server/Xext/xace.c @@ -1,329 +1,333 @@ -/************************************************************
-
-Author: Eamon Walsh <ewalsh@tycho.nsa.gov>
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-this permission notice appear in supporting documentation. This permission
-notice shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#else
-#define XACE
-#endif
-
-#include <stdarg.h>
-#include "scrnintstr.h"
-#include "extnsionst.h"
-#include "pixmapstr.h"
-#include "regionstr.h"
-#include "gcstruct.h"
-#include "xacestr.h"
-
-#define XSERV_t
-#define TRANS_SERVER
-#include <X11/Xtrans/Xtrans.h>
-#include "../os/osdep.h"
-
-_X_EXPORT CallbackListPtr XaceHooks[XACE_NUM_HOOKS] = {0};
-
-/* Special-cased hook functions. Called by Xserver.
- */
-int XaceHookDispatch(ClientPtr client, int major)
-{
- /* Call the audit begin callback, there is no return value. */
- XaceAuditRec rec = { client, 0 };
- CallCallbacks(&XaceHooks[XACE_AUDIT_BEGIN], &rec);
-
- if (major < 128) {
- /* Call the core dispatch hook */
- XaceCoreDispatchRec rec = { client, Success /* default allow */ };
- CallCallbacks(&XaceHooks[XACE_CORE_DISPATCH], &rec);
- return rec.status;
- } else {
- /* Call the extension dispatch hook */
- ExtensionEntry *ext = GetExtensionEntry(major);
- XaceExtAccessRec rec = { client, ext, DixUseAccess, Success };
- if (ext)
- CallCallbacks(&XaceHooks[XACE_EXT_DISPATCH], &rec);
- /* On error, pretend extension doesn't exist */
- return (rec.status == Success) ? Success : BadRequest;
- }
-}
-
-int XaceHookPropertyAccess(ClientPtr client, WindowPtr pWin,
- PropertyPtr *ppProp, Mask access_mode)
-{
- XacePropertyAccessRec rec = { client, pWin, ppProp, access_mode, Success };
- CallCallbacks(&XaceHooks[XACE_PROPERTY_ACCESS], &rec);
- return rec.status;
-}
-
-int XaceHookSelectionAccess(ClientPtr client,
- Selection **ppSel, Mask access_mode)
-{
- XaceSelectionAccessRec rec = { client, ppSel, access_mode, Success };
- CallCallbacks(&XaceHooks[XACE_SELECTION_ACCESS], &rec);
- return rec.status;
-}
-
-void XaceHookAuditEnd(ClientPtr ptr, int result)
-{
- XaceAuditRec rec = { ptr, result };
- /* call callbacks, there is no return value. */
- CallCallbacks(&XaceHooks[XACE_AUDIT_END], &rec);
-}
-
-/* Entry point for hook functions. Called by Xserver.
- */
-int XaceHook(int hook, ...)
-{
- union {
- XaceResourceAccessRec res;
- XaceDeviceAccessRec dev;
- XaceSendAccessRec send;
- XaceReceiveAccessRec recv;
- XaceClientAccessRec client;
- XaceExtAccessRec ext;
- XaceServerAccessRec server;
- XaceScreenAccessRec screen;
- XaceAuthAvailRec auth;
- XaceKeyAvailRec key;
- } u;
- int *prv = NULL; /* points to return value from callback */
- va_list ap; /* argument list */
- va_start(ap, hook);
-
- /* Marshal arguments for passing to callback.
- * Each callback has its own case, which sets up a structure to hold
- * the arguments and integer return parameter, or in some cases just
- * sets calldata directly to a single argument (with no return result)
- */
- switch (hook)
- {
- case XACE_RESOURCE_ACCESS:
- u.res.client = va_arg(ap, ClientPtr);
- u.res.id = va_arg(ap, XID);
- u.res.rtype = va_arg(ap, RESTYPE);
- u.res.res = va_arg(ap, pointer);
- u.res.ptype = va_arg(ap, RESTYPE);
- u.res.parent = va_arg(ap, pointer);
- u.res.access_mode = va_arg(ap, Mask);
- u.res.status = Success; /* default allow */
- prv = &u.res.status;
- break;
- case XACE_DEVICE_ACCESS:
- u.dev.client = va_arg(ap, ClientPtr);
- u.dev.dev = va_arg(ap, DeviceIntPtr);
- u.dev.access_mode = va_arg(ap, Mask);
- u.dev.status = Success; /* default allow */
- prv = &u.dev.status;
- break;
- case XACE_SEND_ACCESS:
- u.send.client = va_arg(ap, ClientPtr);
- u.send.dev = va_arg(ap, DeviceIntPtr);
- u.send.pWin = va_arg(ap, WindowPtr);
- u.send.events = va_arg(ap, xEventPtr);
- u.send.count = va_arg(ap, int);
- u.send.status = Success; /* default allow */
- prv = &u.send.status;
- break;
- case XACE_RECEIVE_ACCESS:
- u.recv.client = va_arg(ap, ClientPtr);
- u.recv.pWin = va_arg(ap, WindowPtr);
- u.recv.events = va_arg(ap, xEventPtr);
- u.recv.count = va_arg(ap, int);
- u.recv.status = Success; /* default allow */
- prv = &u.recv.status;
- break;
- case XACE_CLIENT_ACCESS:
- u.client.client = va_arg(ap, ClientPtr);
- u.client.target = va_arg(ap, ClientPtr);
- u.client.access_mode = va_arg(ap, Mask);
- u.client.status = Success; /* default allow */
- prv = &u.client.status;
- break;
- case XACE_EXT_ACCESS:
- u.ext.client = va_arg(ap, ClientPtr);
- u.ext.ext = va_arg(ap, ExtensionEntry*);
- u.ext.access_mode = DixGetAttrAccess;
- u.ext.status = Success; /* default allow */
- prv = &u.ext.status;
- break;
- case XACE_SERVER_ACCESS:
- u.server.client = va_arg(ap, ClientPtr);
- u.server.access_mode = va_arg(ap, Mask);
- u.server.status = Success; /* default allow */
- prv = &u.server.status;
- break;
- case XACE_SCREEN_ACCESS:
- case XACE_SCREENSAVER_ACCESS:
- u.screen.client = va_arg(ap, ClientPtr);
- u.screen.screen = va_arg(ap, ScreenPtr);
- u.screen.access_mode = va_arg(ap, Mask);
- u.screen.status = Success; /* default allow */
- prv = &u.screen.status;
- break;
- case XACE_AUTH_AVAIL:
- u.auth.client = va_arg(ap, ClientPtr);
- u.auth.authId = va_arg(ap, XID);
- break;
- case XACE_KEY_AVAIL:
- u.key.event = va_arg(ap, xEventPtr);
- u.key.keybd = va_arg(ap, DeviceIntPtr);
- u.key.count = va_arg(ap, int);
- break;
- default:
- va_end(ap);
- return 0; /* unimplemented hook number */
- }
- va_end(ap);
-
- /* call callbacks and return result, if any. */
- CallCallbacks(&XaceHooks[hook], &u);
- return prv ? *prv : Success;
-}
-
-/* XaceCensorImage
- *
- * Called after pScreen->GetImage to prevent pieces or trusted windows from
- * being returned in image data from an untrusted window.
- *
- * Arguments:
- * client is the client doing the GetImage.
- * pVisibleRegion is the visible region of the window.
- * widthBytesLine is the width in bytes of one horizontal line in pBuf.
- * pDraw is the source window.
- * x, y, w, h is the rectangle of image data from pDraw in pBuf.
- * format is the format of the image data in pBuf: ZPixmap or XYPixmap.
- * pBuf is the image data.
- *
- * Returns: nothing.
- *
- * Side Effects:
- * Any part of the rectangle (x, y, w, h) that is outside the visible
- * region of the window will be destroyed (overwritten) in pBuf.
- */
-void
-XaceCensorImage(
- ClientPtr client,
- RegionPtr pVisibleRegion,
- long widthBytesLine,
- DrawablePtr pDraw,
- int x, int y, int w, int h,
- unsigned int format,
- char *pBuf)
-{
- RegionRec imageRegion; /* region representing x,y,w,h */
- RegionRec censorRegion; /* region to obliterate */
- BoxRec imageBox;
- int nRects;
-
- imageBox.x1 = x;
- imageBox.y1 = y;
- imageBox.x2 = x + w;
- imageBox.y2 = y + h;
- RegionInit(&imageRegion, &imageBox, 1);
- RegionNull(&censorRegion);
-
- /* censorRegion = imageRegion - visibleRegion */
- RegionSubtract(&censorRegion, &imageRegion, pVisibleRegion);
- nRects = RegionNumRects(&censorRegion);
- if (nRects > 0)
- { /* we have something to censor */
- GCPtr pScratchGC = NULL;
- PixmapPtr pPix = NULL;
- xRectangle *pRects = NULL;
- Bool failed = FALSE;
- int depth = 1;
- int bitsPerPixel = 1;
- int i;
- BoxPtr pBox;
-
- /* convert region to list-of-rectangles for PolyFillRect */
-
- pRects = malloc(nRects * sizeof(xRectangle));
- if (!pRects)
- {
- failed = TRUE;
- goto failSafe;
- }
- for (pBox = RegionRects(&censorRegion), i = 0;
- i < nRects;
- i++, pBox++)
- {
- pRects[i].x = pBox->x1;
- pRects[i].y = pBox->y1 - imageBox.y1;
- pRects[i].width = pBox->x2 - pBox->x1;
- pRects[i].height = pBox->y2 - pBox->y1;
- }
-
- /* use pBuf as a fake pixmap */
-
- if (format == ZPixmap)
- {
- depth = pDraw->depth;
- bitsPerPixel = pDraw->bitsPerPixel;
- }
-
- pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
- depth, bitsPerPixel,
- widthBytesLine, (pointer)pBuf);
- if (!pPix)
- {
- failed = TRUE;
- goto failSafe;
- }
-
- pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
- if (!pScratchGC)
- {
- failed = TRUE;
- goto failSafe;
- }
-
- ValidateGC(&pPix->drawable, pScratchGC);
- (* pScratchGC->ops->PolyFillRect)(&pPix->drawable,
- pScratchGC, nRects, pRects);
-
- failSafe:
- if (failed)
- {
- /* Censoring was not completed above. To be safe, wipe out
- * all the image data so that nothing trusted gets out.
- */
- memset(pBuf, 0, (int)(widthBytesLine * h));
- }
- free(pRects);
- if (pScratchGC) FreeScratchGC(pScratchGC);
- if (pPix) FreeScratchPixmapHeader(pPix);
- }
- RegionUninit(&imageRegion);
- RegionUninit(&censorRegion);
-} /* XaceCensorImage */
-
-/*
- * Xtrans wrappers for use by modules
- */
-int XaceGetConnectionNumber(ClientPtr client)
-{
- XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn;
- return _XSERVTransGetConnectionNumber(ci);
-}
-
-int XaceIsLocal(ClientPtr client)
-{
- XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn;
- return _XSERVTransIsLocal(ci);
-}
+/************************************************************ + +Author: Eamon Walsh <ewalsh@tycho.nsa.gov> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +this permission notice appear in supporting documentation. This permission +notice shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +********************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#else +#define XACE +#endif + +#include <stdarg.h> +#include "scrnintstr.h" +#include "extnsionst.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "gcstruct.h" +#include "xacestr.h" + +#define XSERV_t +#define TRANS_SERVER +#include <X11/Xtrans/Xtrans.h> +#include "../os/osdep.h" + +_X_EXPORT CallbackListPtr XaceHooks[XACE_NUM_HOOKS] = {0}; + +/* Special-cased hook functions. Called by Xserver. + */ +int XaceHookDispatch(ClientPtr client, int major) +{ + /* Call the audit begin callback, there is no return value. */ + XaceAuditRec rec = { client, 0 }; + CallCallbacks(&XaceHooks[XACE_AUDIT_BEGIN], &rec); + + if (major < 128) { + /* Call the core dispatch hook */ + XaceCoreDispatchRec rec = { client, Success /* default allow */ }; + CallCallbacks(&XaceHooks[XACE_CORE_DISPATCH], &rec); + return rec.status; + } else { + /* Call the extension dispatch hook */ + ExtensionEntry *ext = GetExtensionEntry(major); + XaceExtAccessRec rec = { client, ext, DixUseAccess, Success }; + if (ext) + CallCallbacks(&XaceHooks[XACE_EXT_DISPATCH], &rec); + /* On error, pretend extension doesn't exist */ + return (rec.status == Success) ? Success : BadRequest; + } +} + +int XaceHookPropertyAccess(ClientPtr client, WindowPtr pWin, + PropertyPtr *ppProp, Mask access_mode) +{ + XacePropertyAccessRec rec = { client, pWin, ppProp, access_mode, Success }; + CallCallbacks(&XaceHooks[XACE_PROPERTY_ACCESS], &rec); + return rec.status; +} + +int XaceHookSelectionAccess(ClientPtr client, + Selection **ppSel, Mask access_mode) +{ + XaceSelectionAccessRec rec = { client, ppSel, access_mode, Success }; + CallCallbacks(&XaceHooks[XACE_SELECTION_ACCESS], &rec); + return rec.status; +} + +void XaceHookAuditEnd(ClientPtr ptr, int result) +{ + XaceAuditRec rec = { ptr, result }; + /* call callbacks, there is no return value. */ + CallCallbacks(&XaceHooks[XACE_AUDIT_END], &rec); +} + +/* Entry point for hook functions. Called by Xserver. + */ +int XaceHook(int hook, ...) +{ + union { + XaceResourceAccessRec res; + XaceDeviceAccessRec dev; + XaceSendAccessRec send; + XaceReceiveAccessRec recv; + XaceClientAccessRec client; + XaceExtAccessRec ext; + XaceServerAccessRec server; + XaceScreenAccessRec screen; + XaceAuthAvailRec auth; + XaceKeyAvailRec key; + } u; + int *prv = NULL; /* points to return value from callback */ + va_list ap; /* argument list */ + + if (!XaceHooks[hook]) + return Success; + + va_start(ap, hook); + + /* Marshal arguments for passing to callback. + * Each callback has its own case, which sets up a structure to hold + * the arguments and integer return parameter, or in some cases just + * sets calldata directly to a single argument (with no return result) + */ + switch (hook) + { + case XACE_RESOURCE_ACCESS: + u.res.client = va_arg(ap, ClientPtr); + u.res.id = va_arg(ap, XID); + u.res.rtype = va_arg(ap, RESTYPE); + u.res.res = va_arg(ap, pointer); + u.res.ptype = va_arg(ap, RESTYPE); + u.res.parent = va_arg(ap, pointer); + u.res.access_mode = va_arg(ap, Mask); + u.res.status = Success; /* default allow */ + prv = &u.res.status; + break; + case XACE_DEVICE_ACCESS: + u.dev.client = va_arg(ap, ClientPtr); + u.dev.dev = va_arg(ap, DeviceIntPtr); + u.dev.access_mode = va_arg(ap, Mask); + u.dev.status = Success; /* default allow */ + prv = &u.dev.status; + break; + case XACE_SEND_ACCESS: + u.send.client = va_arg(ap, ClientPtr); + u.send.dev = va_arg(ap, DeviceIntPtr); + u.send.pWin = va_arg(ap, WindowPtr); + u.send.events = va_arg(ap, xEventPtr); + u.send.count = va_arg(ap, int); + u.send.status = Success; /* default allow */ + prv = &u.send.status; + break; + case XACE_RECEIVE_ACCESS: + u.recv.client = va_arg(ap, ClientPtr); + u.recv.pWin = va_arg(ap, WindowPtr); + u.recv.events = va_arg(ap, xEventPtr); + u.recv.count = va_arg(ap, int); + u.recv.status = Success; /* default allow */ + prv = &u.recv.status; + break; + case XACE_CLIENT_ACCESS: + u.client.client = va_arg(ap, ClientPtr); + u.client.target = va_arg(ap, ClientPtr); + u.client.access_mode = va_arg(ap, Mask); + u.client.status = Success; /* default allow */ + prv = &u.client.status; + break; + case XACE_EXT_ACCESS: + u.ext.client = va_arg(ap, ClientPtr); + u.ext.ext = va_arg(ap, ExtensionEntry*); + u.ext.access_mode = DixGetAttrAccess; + u.ext.status = Success; /* default allow */ + prv = &u.ext.status; + break; + case XACE_SERVER_ACCESS: + u.server.client = va_arg(ap, ClientPtr); + u.server.access_mode = va_arg(ap, Mask); + u.server.status = Success; /* default allow */ + prv = &u.server.status; + break; + case XACE_SCREEN_ACCESS: + case XACE_SCREENSAVER_ACCESS: + u.screen.client = va_arg(ap, ClientPtr); + u.screen.screen = va_arg(ap, ScreenPtr); + u.screen.access_mode = va_arg(ap, Mask); + u.screen.status = Success; /* default allow */ + prv = &u.screen.status; + break; + case XACE_AUTH_AVAIL: + u.auth.client = va_arg(ap, ClientPtr); + u.auth.authId = va_arg(ap, XID); + break; + case XACE_KEY_AVAIL: + u.key.event = va_arg(ap, xEventPtr); + u.key.keybd = va_arg(ap, DeviceIntPtr); + u.key.count = va_arg(ap, int); + break; + default: + va_end(ap); + return 0; /* unimplemented hook number */ + } + va_end(ap); + + /* call callbacks and return result, if any. */ + CallCallbacks(&XaceHooks[hook], &u); + return prv ? *prv : Success; +} + +/* XaceCensorImage + * + * Called after pScreen->GetImage to prevent pieces or trusted windows from + * being returned in image data from an untrusted window. + * + * Arguments: + * client is the client doing the GetImage. + * pVisibleRegion is the visible region of the window. + * widthBytesLine is the width in bytes of one horizontal line in pBuf. + * pDraw is the source window. + * x, y, w, h is the rectangle of image data from pDraw in pBuf. + * format is the format of the image data in pBuf: ZPixmap or XYPixmap. + * pBuf is the image data. + * + * Returns: nothing. + * + * Side Effects: + * Any part of the rectangle (x, y, w, h) that is outside the visible + * region of the window will be destroyed (overwritten) in pBuf. + */ +void +XaceCensorImage( + ClientPtr client, + RegionPtr pVisibleRegion, + long widthBytesLine, + DrawablePtr pDraw, + int x, int y, int w, int h, + unsigned int format, + char *pBuf) +{ + RegionRec imageRegion; /* region representing x,y,w,h */ + RegionRec censorRegion; /* region to obliterate */ + BoxRec imageBox; + int nRects; + + imageBox.x1 = x; + imageBox.y1 = y; + imageBox.x2 = x + w; + imageBox.y2 = y + h; + RegionInit(&imageRegion, &imageBox, 1); + RegionNull(&censorRegion); + + /* censorRegion = imageRegion - visibleRegion */ + RegionSubtract(&censorRegion, &imageRegion, pVisibleRegion); + nRects = RegionNumRects(&censorRegion); + if (nRects > 0) + { /* we have something to censor */ + GCPtr pScratchGC = NULL; + PixmapPtr pPix = NULL; + xRectangle *pRects = NULL; + Bool failed = FALSE; + int depth = 1; + int bitsPerPixel = 1; + int i; + BoxPtr pBox; + + /* convert region to list-of-rectangles for PolyFillRect */ + + pRects = malloc(nRects * sizeof(xRectangle)); + if (!pRects) + { + failed = TRUE; + goto failSafe; + } + for (pBox = RegionRects(&censorRegion), i = 0; + i < nRects; + i++, pBox++) + { + pRects[i].x = pBox->x1; + pRects[i].y = pBox->y1 - imageBox.y1; + pRects[i].width = pBox->x2 - pBox->x1; + pRects[i].height = pBox->y2 - pBox->y1; + } + + /* use pBuf as a fake pixmap */ + + if (format == ZPixmap) + { + depth = pDraw->depth; + bitsPerPixel = pDraw->bitsPerPixel; + } + + pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h, + depth, bitsPerPixel, + widthBytesLine, (pointer)pBuf); + if (!pPix) + { + failed = TRUE; + goto failSafe; + } + + pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen); + if (!pScratchGC) + { + failed = TRUE; + goto failSafe; + } + + ValidateGC(&pPix->drawable, pScratchGC); + (* pScratchGC->ops->PolyFillRect)(&pPix->drawable, + pScratchGC, nRects, pRects); + + failSafe: + if (failed) + { + /* Censoring was not completed above. To be safe, wipe out + * all the image data so that nothing trusted gets out. + */ + memset(pBuf, 0, (int)(widthBytesLine * h)); + } + free(pRects); + if (pScratchGC) FreeScratchGC(pScratchGC); + if (pPix) FreeScratchPixmapHeader(pPix); + } + RegionUninit(&imageRegion); + RegionUninit(&censorRegion); +} /* XaceCensorImage */ + +/* + * Xtrans wrappers for use by modules + */ +int XaceGetConnectionNumber(ClientPtr client) +{ + XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn; + return _XSERVTransGetConnectionNumber(ci); +} + +int XaceIsLocal(ClientPtr client) +{ + XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn; + return _XSERVTransIsLocal(ci); +} diff --git a/xorg-server/Xext/xf86bigfont.c b/xorg-server/Xext/xf86bigfont.c index 4b63a13a1..5053852a4 100644 --- a/xorg-server/Xext/xf86bigfont.c +++ b/xorg-server/Xext/xf86bigfont.c @@ -300,7 +300,7 @@ ProcXF86BigfontQueryVersion( #endif reply.capabilities = #ifdef HAS_SHM - (LocalClient(client) && !client->swapped ? XF86Bigfont_CAP_LocalShm : 0) + (client->local && !client->swapped ? XF86Bigfont_CAP_LocalShm : 0) #else 0 #endif @@ -367,7 +367,7 @@ ProcXF86BigfontQueryFont( #else switch (client->req_len) { case 2: /* client with version 1.0 libX11 */ - stuff_flags = (LocalClient(client) && !client->swapped ? XF86Bigfont_FLAGS_Shm : 0); + stuff_flags = (client->local && !client->swapped ? XF86Bigfont_FLAGS_Shm : 0); break; case 3: /* client with version 1.1 libX11 */ stuff_flags = stuff->flags; diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index 297d8b129..92edae3e3 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -1161,13 +1161,11 @@ TouchEventRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, DeliverTouchEvents(sourcedev, ti, tel + i, ev->resource); } - /* If there are no other listeners left, then don't bother sending an - * ownership change event to no-one; if the touchpoint is pending + /* If there are no other listeners left, and the touchpoint is pending * finish, then we can just kill it now. */ - if (ti->num_listeners == 1) + if (ti->num_listeners == 1 && ti->pending_finish) { - if (ti->pending_finish) - TouchEndTouch(sourcedev, ti); + TouchEndTouch(sourcedev, ti); goto out; } @@ -1180,9 +1178,9 @@ TouchEventRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, ti->num_grabs--; } - /* If the current owner was removed, deliver the TouchOwnership or TouchBegin - event to the new owner. */ - if (was_owner) + /* If the current owner was removed and there are further listeners, deliver + * the TouchOwnership or TouchBegin event to the new owner. */ + if (ti->num_listeners > 0 && was_owner) TouchPuntToNextOwner(sourcedev, ti, ev); out: @@ -1807,8 +1805,10 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev, rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev); listener->state = LISTENER_HAS_END; } - if (ti->num_listeners > 1 && - (ev->device_event.flags & (TOUCH_ACCEPT|TOUCH_REJECT)) == 0) + if ((ti->num_listeners > 1 || + (listener->type == LISTENER_GRAB && + xi2mask_isset(xi2mask, dev, XI_TouchOwnership))) && + (ev->device_event.flags & (TOUCH_ACCEPT|TOUCH_REJECT)) == 0) { ev->any.type = ET_TouchUpdate; ev->device_event.flags |= TOUCH_PENDING_END; diff --git a/xorg-server/Xi/xiproperty.c b/xorg-server/Xi/xiproperty.c index 88de11959..c612af22c 100644 --- a/xorg-server/Xi/xiproperty.c +++ b/xorg-server/Xi/xiproperty.c @@ -706,7 +706,7 @@ XIDeleteDeviceProperty (DeviceIntPtr device, Atom property, Bool fromClient) int XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type, int format, int mode, unsigned long len, - const pointer value, Bool sendevent) + const void *value, Bool sendevent) { XIPropertyPtr prop; int size_in_bytes; diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 6de92b435..a203ab285 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -776,7 +776,7 @@ XPROTO="xproto >= 7.0.22" RANDRPROTO="randrproto >= 1.2.99.3" RENDERPROTO="renderproto >= 0.11" XEXTPROTO="xextproto >= 7.1.99" -INPUTPROTO="inputproto >= 2.1.99.3" +INPUTPROTO="inputproto >= 2.1.99.5" KBPROTO="kbproto >= 1.0.3" FONTSPROTO="fontsproto" FIXESPROTO="fixesproto >= 5.0" @@ -1024,6 +1024,13 @@ if test "x$RES" = xyes && test "x$CLIENTIDS" = xyes; then else CLIENTIDS=no fi +if test "x$CLIENTIDS" = xyes; then + case $host_os in + openbsd*) + SYS_LIBS="$SYS_LIBS -lkvm" + ;; + esac +fi AC_MSG_RESULT([$CLIENTIDS]) AM_CONDITIONAL(CLIENTIDS, [test "x$CLIENTIDS" = xyes]) diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index 29fb78160..8b15fb07f 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -432,10 +432,14 @@ Dispatch(void) client->minorOp = ext->MinorOpcode(client);
}
#ifdef XSERVER_DTRACE
- StartMajorOp=client->majorOp;
- XSERVER_REQUEST_START(LookupMajorName(client->majorOp), client->majorOp,
- ((xReq *)client->requestBuffer)->length,
- client->index, client->requestBuffer);
+ if (XSERVER_REQUEST_START_ENABLED())
+ {
+ StartMajorOp=client->majorOp;
+ XSERVER_REQUEST_START(LookupMajorName(client->majorOp),
+ client->majorOp,
+ ((xReq *)client->requestBuffer)->length,
+ client->index, client->requestBuffer);
+ }
#endif
if (result > (maxBigRequestSize << 2))
result = BadLength;
@@ -446,26 +450,32 @@ Dispatch(void) XaceHookAuditEnd(client, result);
}
#ifdef XSERVER_DTRACE
- if (result!=Success)
- {
- char Message[255];
- sprintf(Message,"ERROR: %s (0x%x)",LookupMajorName(client->majorOp),client->errorValue);
- XSERVER_REQUEST_DONE(Message, client->majorOp,
- client->sequence, client->index, result);
- }
- else
+ if (XSERVER_REQUEST_DONE_ENABLED())
{
- if (StartMajorOp!=client->majorOp)
+ if (result!=Success)
{
char Message[255];
- sprintf(Message,"Changed request: %s -> %s",LookupMajorName(StartMajorOp),LookupMajorName(client->majorOp));
- XSERVER_REQUEST_DONE(Message, client->majorOp,
- client->sequence, client->index, result);
+ sprintf(Message,"ERROR: %s (0x%x)",LookupMajorName(client->majorOp),client->errorValue);
+ XSERVER_REQUEST_DONE(Message,
+ client->majorOp, client->sequence,
+ client->index, result);
}
else
{
- XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp), client->majorOp,
- client->sequence, client->index, result);
+ if (StartMajorOp!=client->majorOp)
+ {
+ char Message[255];
+ sprintf(Message,"Changed request: %s -> %s",LookupMajorName(StartMajorOp),LookupMajorName(client->majorOp));
+ XSERVER_REQUEST_DONE(Message,
+ client->majorOp, client->sequence,
+ client->index, result);
+ }
+ else
+ {
+ XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp),
+ client->majorOp, client->sequence,
+ client->index, result);
+ }
}
}
#endif
@@ -3619,12 +3629,14 @@ ProcInitialConnection(ClientPtr client) REQUEST(xReq);
xConnClientPrefix *prefix;
int whichbyte = 1;
+ char order;
prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
- if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+ order = prefix->byteOrder;
+ if (order != 'l' && order != 'B' && order != 'r' && order != 'R')
return client->noClientException = -1;
- if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
- (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+ if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
+ (!(*(char *) &whichbyte) && (order == 'l' || order == 'r')))
{
client->swapped = TRUE;
SwapConnClientPrefix(prefix);
@@ -3636,6 +3648,10 @@ ProcInitialConnection(ClientPtr client) {
swaps(&stuff->length);
}
+ if (order == 'r' || order == 'R')
+ {
+ client->local = FALSE;
+ }
ResetCurrentRequest(client);
return Success;
}
diff --git a/xorg-server/dix/dixutils.c b/xorg-server/dix/dixutils.c index 00bbde67c..da26dc144 100644 --- a/xorg-server/dix/dixutils.c +++ b/xorg-server/dix/dixutils.c @@ -202,13 +202,12 @@ dixLookupDrawable(DrawablePtr *pDraw, XID id, ClientPtr client, int rc; *pDraw = NULL; - client->errorValue = id; - - if (id == INVALID) - return BadDrawable; rc = dixLookupResourceByClass((pointer *)&pTmp, id, RC_DRAWABLE, client, access); + if (rc != Success) + client->errorValue = id; + if (rc == BadValue) return BadDrawable; if (rc != Success) @@ -225,7 +224,15 @@ dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access) { int rc; rc = dixLookupDrawable((DrawablePtr*)pWin, id, client, M_WINDOW, access); - return (rc == BadDrawable) ? BadWindow : rc; + /* dixLookupDrawable returns BadMatch iff id is a valid Drawable + but is not a Window. Users of dixLookupWindow expect a BadWindow + error in this case; they don't care that it's a valid non-Window XID */ + if (rc == BadMatch) + rc = BadWindow; + /* Similarly, users of dixLookupWindow don't want BadDrawable. */ + if (rc == BadDrawable) + rc = BadWindow; + return rc; } int diff --git a/xorg-server/dix/enterleave.c b/xorg-server/dix/enterleave.c index a39e64001..89a82ab99 100644 --- a/xorg-server/dix/enterleave.c +++ b/xorg-server/dix/enterleave.c @@ -1292,14 +1292,17 @@ DeviceFocusEvents(DeviceIntPtr dev, NotifyPointer); DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from); /* next call catches the root too, if the screen changed */ - DeviceFocusOutEvents(dev, from->parent, NullWindow, mode, + DeviceFocusOutEvents(dev, from, NullWindow, mode, NotifyNonlinearVirtual); } /* Notify all the roots */ for (i = 0; i < nscreens; i++) DeviceFocusEvent(dev, XI_FocusIn, mode, in, screenInfo.screens[i]->root); if (to == PointerRootWin) + { DeviceFocusInEvents(dev, GetCurrentRootWindow(dev), sprite->win, mode, NotifyPointer); + DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyPointer, sprite->win); + } } else { @@ -1321,7 +1324,7 @@ DeviceFocusEvents(DeviceIntPtr dev, if (IsParent(to, from)) { DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyAncestor, from); - DeviceFocusOutEvents(dev, from->parent, to, mode, + DeviceFocusOutEvents(dev, from, to, mode, NotifyVirtual); DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyInferior, to); if ((IsParent(to, sprite->win)) && @@ -1353,7 +1356,7 @@ DeviceFocusEvents(DeviceIntPtr dev, NotifyPointer); DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from); if (from->parent != NullWindow) - DeviceFocusOutEvents(dev, from->parent, common, mode, + DeviceFocusOutEvents(dev, from, common, mode, NotifyNonlinearVirtual); if (to->parent != NullWindow) DeviceFocusInEvents(dev, common, to, mode, NotifyNonlinearVirtual); diff --git a/xorg-server/dix/eventconvert.c b/xorg-server/dix/eventconvert.c index 84c7f5f1d..d608b0438 100644 --- a/xorg-server/dix/eventconvert.c +++ b/xorg-server/dix/eventconvert.c @@ -691,6 +691,10 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi) else xde->flags = ev->flags; + if (IsTouchEvent((InternalEvent*)ev) && + ev->flags & TOUCH_POINTER_EMULATED) + xde->flags |= XITouchEmulatingPointer; + if (ev->key_repeat) xde->flags |= XIKeyRepeat; diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c index cdb00ccb4..f1aa7f01a 100644 --- a/xorg-server/dix/getevents.c +++ b/xorg-server/dix/getevents.c @@ -1349,7 +1349,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, storeLastValuators(pDev, &mask, 0, 1, devx, devy); /* Update the MD's co-ordinates, which are always in desktop space. */ - if (!IsMaster(pDev) || !IsFloating(pDev)) { + if (!IsMaster(pDev) && !IsFloating(pDev)) { DeviceIntPtr master = GetMaster(pDev, MASTER_POINTER); master->last.valuators[0] = screenx; master->last.valuators[1] = screeny; diff --git a/xorg-server/dix/property.c b/xorg-server/dix/property.c index 53b9821a9..d933d5cec 100644 --- a/xorg-server/dix/property.c +++ b/xorg-server/dix/property.c @@ -1,644 +1,644 @@ -/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "windowstr.h"
-#include "propertyst.h"
-#include "dixstruct.h"
-#include "dispatch.h"
-#include "swaprep.h"
-#include "xace.h"
-
-/*****************************************************************
- * Property Stuff
- *
- * dixLookupProperty, dixChangeProperty, DeleteProperty
- *
- * Properties belong to windows. The list of properties should not be
- * traversed directly. Instead, use the three functions listed above.
- *
- *****************************************************************/
-
-#ifdef notdef
-static void
-PrintPropertys(WindowPtr pWin)
-{
- PropertyPtr pProp;
- int j;
-
- pProp = pWin->userProps;
- while (pProp)
- {
- ErrorF("[dix] %x %x\n", pProp->propertyName, pProp->type);
- ErrorF("[dix] property format: %d\n", pProp->format);
- ErrorF("[dix] property data: \n");
- for (j=0; j<(pProp->format/8)*pProp->size; j++)
- ErrorF("[dix] %c\n", pProp->data[j]);
- pProp = pProp->next;
- }
-}
-#endif
-
-int
-dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName,
- ClientPtr client, Mask access_mode)
-{
- PropertyPtr pProp;
- int rc = BadMatch;
- client->errorValue = propertyName;
-
- for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
- if (pProp->propertyName == propertyName)
- break;
-
- if (pProp)
- rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode);
- *result = pProp;
- return rc;
-}
-
-static void
-deliverPropertyNotifyEvent(WindowPtr pWin, int state, Atom atom)
-{
- xEvent event;
-
- memset(&event, 0, sizeof(xEvent));
- event.u.u.type = PropertyNotify;
- event.u.property.window = pWin->drawable.id;
- event.u.property.state = state;
- event.u.property.atom = atom;
- event.u.property.time = currentTime.milliseconds;
- DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
-}
-
-int
-ProcRotateProperties(ClientPtr client)
-{
- int i, j, delta, rc;
- REQUEST(xRotatePropertiesReq);
- WindowPtr pWin;
- Atom * atoms;
- PropertyPtr * props; /* array of pointer */
- PropertyPtr pProp, saved;
-
- REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
- UpdateCurrentTime();
- rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess);
- if (rc != Success || stuff->nAtoms <= 0)
- return rc;
-
- atoms = (Atom *) & stuff[1];
- props = malloc(stuff->nAtoms * sizeof(PropertyPtr));
- saved = malloc(stuff->nAtoms * sizeof(PropertyRec));
- if (!props || !saved) {
- rc = BadAlloc;
- goto out;
- }
-
- for (i = 0; i < stuff->nAtoms; i++)
- {
- if (!ValidAtom(atoms[i])) {
- rc = BadAtom;
- client->errorValue = atoms[i];
- goto out;
- }
- for (j = i + 1; j < stuff->nAtoms; j++)
- if (atoms[j] == atoms[i])
- {
- rc = BadMatch;
- goto out;
- }
-
- rc = dixLookupProperty(&pProp, pWin, atoms[i], client,
- DixReadAccess|DixWriteAccess);
- if (rc != Success)
- goto out;
-
- props[i] = pProp;
- saved[i] = *pProp;
- }
- delta = stuff->nPositions;
-
- /* If the rotation is a complete 360 degrees, then moving the properties
- around and generating PropertyNotify events should be skipped. */
-
- if (abs(delta) % stuff->nAtoms)
- {
- while (delta < 0) /* faster if abs value is small */
- delta += stuff->nAtoms;
- for (i = 0; i < stuff->nAtoms; i++)
- {
- j = (i + delta) % stuff->nAtoms;
- deliverPropertyNotifyEvent(pWin, PropertyNewValue, atoms[i]);
-
- /* Preserve name and devPrivates */
- props[j]->type = saved[i].type;
- props[j]->format = saved[i].format;
- props[j]->size = saved[i].size;
- props[j]->data = saved[i].data;
- }
- }
-out:
- free(saved);
- free(props);
- return rc;
-}
-
-int
-ProcChangeProperty(ClientPtr client)
-{
- WindowPtr pWin;
- char format, mode;
- unsigned long len;
- int sizeInBytes, totalSize, err;
- REQUEST(xChangePropertyReq);
-
- REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
- UpdateCurrentTime();
- format = stuff->format;
- mode = stuff->mode;
- if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
- (mode != PropModePrepend))
- {
- client->errorValue = mode;
- return BadValue;
- }
- if ((format != 8) && (format != 16) && (format != 32))
- {
- client->errorValue = format;
- return BadValue;
- }
- len = stuff->nUnits;
- if (len > bytes_to_int32(0xffffffff - sizeof(xChangePropertyReq)))
- return BadLength;
- sizeInBytes = format>>3;
- totalSize = len * sizeInBytes;
- REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize);
-
- err = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess);
- if (err != Success)
- return err;
- if (!ValidAtom(stuff->property))
- {
- client->errorValue = stuff->property;
- return BadAtom;
- }
- if (!ValidAtom(stuff->type))
- {
- client->errorValue = stuff->type;
- return BadAtom;
- }
-
- err = dixChangeWindowProperty(client, pWin, stuff->property, stuff->type,
- (int)format, (int)mode, len, &stuff[1],
- TRUE);
- if (err != Success)
- return err;
- else
- return Success;
-}
-
-int
-dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
- Atom type, int format, int mode, unsigned long len,
- pointer value, Bool sendevent)
-{
- PropertyPtr pProp;
- PropertyRec savedProp;
- int sizeInBytes, totalSize, rc;
- unsigned char *data;
- Mask access_mode;
-
- sizeInBytes = format>>3;
- totalSize = len * sizeInBytes;
- access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess;
-
- /* first see if property already exists */
- rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode);
-
- if (rc == BadMatch) /* just add to list */
- {
- if (!pWin->optional && !MakeWindowOptional (pWin))
- return BadAlloc;
- pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY);
- if (!pProp)
- return BadAlloc;
- data = malloc(totalSize);
- if (!data && len)
- {
- dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
- return BadAlloc;
- }
- memcpy(data, value, totalSize);
- pProp->propertyName = property;
- pProp->type = type;
- pProp->format = format;
- pProp->data = data;
- pProp->size = len;
- rc = XaceHookPropertyAccess(pClient, pWin, &pProp,
- DixCreateAccess|DixWriteAccess);
- if (rc != Success) {
- free(data);
- dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
- pClient->errorValue = property;
- return rc;
- }
- pProp->next = pWin->optional->userProps;
- pWin->optional->userProps = pProp;
- }
- else if (rc == Success)
- {
- /* To append or prepend to a property the request format and type
- must match those of the already defined property. The
- existing format and type are irrelevant when using the mode
- "PropModeReplace" since they will be written over. */
-
- if ((format != pProp->format) && (mode != PropModeReplace))
- return BadMatch;
- if ((pProp->type != type) && (mode != PropModeReplace))
- return BadMatch;
-
- /* save the old values for later */
- savedProp = *pProp;
-
- if (mode == PropModeReplace)
- {
- data = malloc(totalSize);
- if (!data && len)
- return BadAlloc;
- memcpy(data, value, totalSize);
- pProp->data = data;
- pProp->size = len;
- pProp->type = type;
- pProp->format = format;
- }
- else if (len == 0)
- {
- /* do nothing */
- }
- else if (mode == PropModeAppend)
- {
- data = malloc((pProp->size + len) * sizeInBytes);
- if (!data)
- return BadAlloc;
- memcpy(data, pProp->data, pProp->size * sizeInBytes);
- memcpy(data + pProp->size * sizeInBytes, value, totalSize);
- pProp->data = data;
- pProp->size += len;
- }
- else if (mode == PropModePrepend)
- {
- data = malloc(sizeInBytes * (len + pProp->size));
- if (!data)
- return BadAlloc;
- memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes);
- memcpy(data, value, totalSize);
- pProp->data = data;
- pProp->size += len;
- }
-
- /* Allow security modules to check the new content */
- access_mode |= DixPostAccess;
- rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode);
- if (rc == Success)
- {
- if (savedProp.data != pProp->data)
- free(savedProp.data);
- }
- else
- {
- if (savedProp.data != pProp->data)
- free(pProp->data);
- *pProp = savedProp;
- return rc;
- }
- }
- else
- return rc;
-
- if (sendevent)
- deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName);
-
- return Success;
-}
-
-int
-ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
- int mode, unsigned long len, pointer value,
- Bool sendevent)
-{
- return dixChangeWindowProperty(serverClient, pWin, property, type, format,
- mode, len, value, sendevent);
-}
-
-int
-DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
-{
- PropertyPtr pProp, prevProp;
- int rc;
-
- rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess);
- if (rc == BadMatch)
- return Success; /* Succeed if property does not exist */
-
- if (rc == Success) {
- if (pWin->optional->userProps == pProp) {
- /* Takes care of head */
- if (!(pWin->optional->userProps = pProp->next))
- CheckWindowOptionalNeed (pWin);
- } else {
- /* Need to traverse to find the previous element */
- prevProp = pWin->optional->userProps;
- while (prevProp->next != pProp)
- prevProp = prevProp->next;
- prevProp->next = pProp->next;
- }
-
- deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName);
- free(pProp->data);
- dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
- }
- return rc;
-}
-
-void
-DeleteAllWindowProperties(WindowPtr pWin)
-{
- PropertyPtr pProp, pNextProp;
-
- pProp = wUserProps (pWin);
- while (pProp)
- {
- deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName);
- pNextProp = pProp->next;
- free(pProp->data);
- dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
- pProp = pNextProp;
- }
-
- if (pWin->optional)
- pWin->optional->userProps = NULL;
-}
-
-static int
-NullPropertyReply(
- ClientPtr client,
- ATOM propertyType,
- int format,
- xGetPropertyReply *reply)
-{
- reply->nItems = 0;
- reply->length = 0;
- reply->bytesAfter = 0;
- reply->propertyType = propertyType;
- reply->format = format;
- WriteReplyToClient(client, sizeof(xGenericReply), reply);
- return Success;
-}
-
-/*****************
- * GetProperty
- * If type Any is specified, returns the property from the specified
- * window regardless of its type. If a type is specified, returns the
- * property only if its type equals the specified type.
- * If delete is True and a property is returned, the property is also
- * deleted from the window and a PropertyNotify event is generated on the
- * window.
- *****************/
-
-int
-ProcGetProperty(ClientPtr client)
-{
- PropertyPtr pProp, prevProp;
- unsigned long n, len, ind;
- int rc;
- WindowPtr pWin;
- xGetPropertyReply reply;
- Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess;
- REQUEST(xGetPropertyReq);
-
- REQUEST_SIZE_MATCH(xGetPropertyReq);
- if (stuff->delete) {
- UpdateCurrentTime();
- win_mode |= DixSetPropAccess;
- prop_mode |= DixDestroyAccess;
- }
- rc = dixLookupWindow(&pWin, stuff->window, client, win_mode);
- if (rc != Success)
- return (rc == BadMatch) ? BadWindow : rc;
-
- if (!ValidAtom(stuff->property))
- {
- client->errorValue = stuff->property;
- return BadAtom;
- }
- if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
- {
- client->errorValue = stuff->delete;
- return BadValue;
- }
- if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
- {
- client->errorValue = stuff->type;
- return BadAtom;
- }
-
- memset(&reply, 0, sizeof(xGetPropertyReply));
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode);
- if (rc == BadMatch)
- return NullPropertyReply(client, None, 0, &reply);
- else if (rc != Success)
- return rc;
-
- /* If the request type and actual type don't match. Return the
- property information, but not the data. */
-
- if (((stuff->type != pProp->type) &&
- (stuff->type != AnyPropertyType))
- )
- {
- reply.bytesAfter = pProp->size;
- reply.format = pProp->format;
- reply.length = 0;
- reply.nItems = 0;
- reply.propertyType = pProp->type;
- WriteReplyToClient(client, sizeof(xGenericReply), &reply);
- return Success;
- }
-
-/*
- * Return type, format, value to client
- */
- n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
- ind = stuff->longOffset << 2;
-
- /* If longOffset is invalid such that it causes "len" to
- be negative, it's a value error. */
-
- if (n < ind)
- {
- client->errorValue = stuff->longOffset;
- return BadValue;
- }
-
- len = min(n - ind, 4 * stuff->longLength);
-
- reply.bytesAfter = n - (ind + len);
- reply.format = pProp->format;
- reply.length = bytes_to_int32(len);
- reply.nItems = len / (pProp->format / 8 );
- reply.propertyType = pProp->type;
-
- if (stuff->delete && (reply.bytesAfter == 0))
- deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName);
-
- WriteReplyToClient(client, sizeof(xGenericReply), &reply);
- if (len)
- {
- switch (reply.format) {
- case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
- case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
- default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
- }
- WriteSwappedDataToClient(client, len,
- (char *)pProp->data + ind);
- }
-
- if (stuff->delete && (reply.bytesAfter == 0)) {
- /* Delete the Property */
- if (pWin->optional->userProps == pProp) {
- /* Takes care of head */
- if (!(pWin->optional->userProps = pProp->next))
- CheckWindowOptionalNeed (pWin);
- } else {
- /* Need to traverse to find the previous element */
- prevProp = pWin->optional->userProps;
- while (prevProp->next != pProp)
- prevProp = prevProp->next;
- prevProp->next = pProp->next;
- }
-
- free(pProp->data);
- dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY);
- }
- return Success;
-}
-
-int
-ProcListProperties(ClientPtr client)
-{
- Atom *pAtoms = NULL, *temppAtoms;
- xListPropertiesReply xlpr;
- int rc, numProps = 0;
- WindowPtr pWin;
- PropertyPtr pProp, realProp;
- REQUEST(xResourceReq);
-
- REQUEST_SIZE_MATCH(xResourceReq);
- rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess);
- if (rc != Success)
- return rc;
-
- for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
- numProps++;
-
- if (numProps && !(pAtoms = malloc(numProps * sizeof(Atom))))
- return BadAlloc;
-
- numProps = 0;
- temppAtoms = pAtoms;
- for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) {
- realProp = pProp;
- rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess);
- if (rc == Success && realProp == pProp) {
- *temppAtoms++ = pProp->propertyName;
- numProps++;
- }
- }
-
- xlpr.type = X_Reply;
- xlpr.nProperties = numProps;
- xlpr.length = bytes_to_int32(numProps * sizeof(Atom));
- xlpr.sequenceNumber = client->sequence;
- WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
- if (numProps)
- {
- client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
- WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
- }
- free(pAtoms);
- return Success;
-}
-
-int
-ProcDeleteProperty(ClientPtr client)
-{
- WindowPtr pWin;
- REQUEST(xDeletePropertyReq);
- int result;
-
- REQUEST_SIZE_MATCH(xDeletePropertyReq);
- UpdateCurrentTime();
- result = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess);
- if (result != Success)
- return result;
- if (!ValidAtom(stuff->property))
- {
- client->errorValue = stuff->property;
- return BadAtom;
- }
-
- return DeleteProperty(client, pWin, stuff->property);
-}
+/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "windowstr.h" +#include "propertyst.h" +#include "dixstruct.h" +#include "dispatch.h" +#include "swaprep.h" +#include "xace.h" + +/***************************************************************** + * Property Stuff + * + * dixLookupProperty, dixChangeProperty, DeleteProperty + * + * Properties belong to windows. The list of properties should not be + * traversed directly. Instead, use the three functions listed above. + * + *****************************************************************/ + +#ifdef notdef +static void +PrintPropertys(WindowPtr pWin) +{ + PropertyPtr pProp; + int j; + + pProp = pWin->userProps; + while (pProp) + { + ErrorF("[dix] %x %x\n", pProp->propertyName, pProp->type); + ErrorF("[dix] property format: %d\n", pProp->format); + ErrorF("[dix] property data: \n"); + for (j=0; j<(pProp->format/8)*pProp->size; j++) + ErrorF("[dix] %c\n", pProp->data[j]); + pProp = pProp->next; + } +} +#endif + +int +dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName, + ClientPtr client, Mask access_mode) +{ + PropertyPtr pProp; + int rc = BadMatch; + client->errorValue = propertyName; + + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) + if (pProp->propertyName == propertyName) + break; + + if (pProp) + rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode); + *result = pProp; + return rc; +} + +static void +deliverPropertyNotifyEvent(WindowPtr pWin, int state, Atom atom) +{ + xEvent event; + + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = PropertyNotify; + event.u.property.window = pWin->drawable.id; + event.u.property.state = state; + event.u.property.atom = atom; + event.u.property.time = currentTime.milliseconds; + DeliverEvents(pWin, &event, 1, (WindowPtr)NULL); +} + +int +ProcRotateProperties(ClientPtr client) +{ + int i, j, delta, rc; + REQUEST(xRotatePropertiesReq); + WindowPtr pWin; + Atom * atoms; + PropertyPtr * props; /* array of pointer */ + PropertyPtr pProp, saved; + + REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2); + UpdateCurrentTime(); + rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); + if (rc != Success || stuff->nAtoms <= 0) + return rc; + + atoms = (Atom *) & stuff[1]; + props = malloc(stuff->nAtoms * sizeof(PropertyPtr)); + saved = malloc(stuff->nAtoms * sizeof(PropertyRec)); + if (!props || !saved) { + rc = BadAlloc; + goto out; + } + + for (i = 0; i < stuff->nAtoms; i++) + { + if (!ValidAtom(atoms[i])) { + rc = BadAtom; + client->errorValue = atoms[i]; + goto out; + } + for (j = i + 1; j < stuff->nAtoms; j++) + if (atoms[j] == atoms[i]) + { + rc = BadMatch; + goto out; + } + + rc = dixLookupProperty(&pProp, pWin, atoms[i], client, + DixReadAccess|DixWriteAccess); + if (rc != Success) + goto out; + + props[i] = pProp; + saved[i] = *pProp; + } + delta = stuff->nPositions; + + /* If the rotation is a complete 360 degrees, then moving the properties + around and generating PropertyNotify events should be skipped. */ + + if (abs(delta) % stuff->nAtoms) + { + while (delta < 0) /* faster if abs value is small */ + delta += stuff->nAtoms; + for (i = 0; i < stuff->nAtoms; i++) + { + j = (i + delta) % stuff->nAtoms; + deliverPropertyNotifyEvent(pWin, PropertyNewValue, atoms[i]); + + /* Preserve name and devPrivates */ + props[j]->type = saved[i].type; + props[j]->format = saved[i].format; + props[j]->size = saved[i].size; + props[j]->data = saved[i].data; + } + } +out: + free(saved); + free(props); + return rc; +} + +int +ProcChangeProperty(ClientPtr client) +{ + WindowPtr pWin; + char format, mode; + unsigned long len; + int sizeInBytes, totalSize, err; + REQUEST(xChangePropertyReq); + + REQUEST_AT_LEAST_SIZE(xChangePropertyReq); + UpdateCurrentTime(); + format = stuff->format; + mode = stuff->mode; + if ((mode != PropModeReplace) && (mode != PropModeAppend) && + (mode != PropModePrepend)) + { + client->errorValue = mode; + return BadValue; + } + if ((format != 8) && (format != 16) && (format != 32)) + { + client->errorValue = format; + return BadValue; + } + len = stuff->nUnits; + if (len > bytes_to_int32(0xffffffff - sizeof(xChangePropertyReq))) + return BadLength; + sizeInBytes = format>>3; + totalSize = len * sizeInBytes; + REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize); + + err = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); + if (err != Success) + return err; + if (!ValidAtom(stuff->property)) + { + client->errorValue = stuff->property; + return BadAtom; + } + if (!ValidAtom(stuff->type)) + { + client->errorValue = stuff->type; + return BadAtom; + } + + err = dixChangeWindowProperty(client, pWin, stuff->property, stuff->type, + (int)format, (int)mode, len, &stuff[1], + TRUE); + if (err != Success) + return err; + else + return Success; +} + +int +dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, + Atom type, int format, int mode, unsigned long len, + pointer value, Bool sendevent) +{ + PropertyPtr pProp; + PropertyRec savedProp; + int sizeInBytes, totalSize, rc; + unsigned char *data; + Mask access_mode; + + sizeInBytes = format>>3; + totalSize = len * sizeInBytes; + access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess; + + /* first see if property already exists */ + rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode); + + if (rc == BadMatch) /* just add to list */ + { + if (!pWin->optional && !MakeWindowOptional (pWin)) + return BadAlloc; + pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY); + if (!pProp) + return BadAlloc; + data = malloc(totalSize); + if (!data && len) + { + dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); + return BadAlloc; + } + memcpy(data, value, totalSize); + pProp->propertyName = property; + pProp->type = type; + pProp->format = format; + pProp->data = data; + pProp->size = len; + rc = XaceHookPropertyAccess(pClient, pWin, &pProp, + DixCreateAccess|DixWriteAccess); + if (rc != Success) { + free(data); + dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); + pClient->errorValue = property; + return rc; + } + pProp->next = pWin->optional->userProps; + pWin->optional->userProps = pProp; + } + else if (rc == Success) + { + /* To append or prepend to a property the request format and type + must match those of the already defined property. The + existing format and type are irrelevant when using the mode + "PropModeReplace" since they will be written over. */ + + if ((format != pProp->format) && (mode != PropModeReplace)) + return BadMatch; + if ((pProp->type != type) && (mode != PropModeReplace)) + return BadMatch; + + /* save the old values for later */ + savedProp = *pProp; + + if (mode == PropModeReplace) + { + data = malloc(totalSize); + if (!data && len) + return BadAlloc; + memcpy(data, value, totalSize); + pProp->data = data; + pProp->size = len; + pProp->type = type; + pProp->format = format; + } + else if (len == 0) + { + /* do nothing */ + } + else if (mode == PropModeAppend) + { + data = malloc((pProp->size + len) * sizeInBytes); + if (!data) + return BadAlloc; + memcpy(data, pProp->data, pProp->size * sizeInBytes); + memcpy(data + pProp->size * sizeInBytes, value, totalSize); + pProp->data = data; + pProp->size += len; + } + else if (mode == PropModePrepend) + { + data = malloc(sizeInBytes * (len + pProp->size)); + if (!data) + return BadAlloc; + memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes); + memcpy(data, value, totalSize); + pProp->data = data; + pProp->size += len; + } + + /* Allow security modules to check the new content */ + access_mode |= DixPostAccess; + rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode); + if (rc == Success) + { + if (savedProp.data != pProp->data) + free(savedProp.data); + } + else + { + if (savedProp.data != pProp->data) + free(pProp->data); + *pProp = savedProp; + return rc; + } + } + else + return rc; + + if (sendevent) + deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName); + + return Success; +} + +int +ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format, + int mode, unsigned long len, pointer value, + Bool sendevent) +{ + return dixChangeWindowProperty(serverClient, pWin, property, type, format, + mode, len, value, sendevent); +} + +int +DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName) +{ + PropertyPtr pProp, prevProp; + int rc; + + rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess); + if (rc == BadMatch) + return Success; /* Succeed if property does not exist */ + + if (rc == Success) { + if (pWin->optional->userProps == pProp) { + /* Takes care of head */ + if (!(pWin->optional->userProps = pProp->next)) + CheckWindowOptionalNeed (pWin); + } else { + /* Need to traverse to find the previous element */ + prevProp = pWin->optional->userProps; + while (prevProp->next != pProp) + prevProp = prevProp->next; + prevProp->next = pProp->next; + } + + deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); + free(pProp->data); + dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); + } + return rc; +} + +void +DeleteAllWindowProperties(WindowPtr pWin) +{ + PropertyPtr pProp, pNextProp; + + pProp = wUserProps (pWin); + while (pProp) + { + deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); + pNextProp = pProp->next; + free(pProp->data); + dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); + pProp = pNextProp; + } + + if (pWin->optional) + pWin->optional->userProps = NULL; +} + +static int +NullPropertyReply( + ClientPtr client, + ATOM propertyType, + int format, + xGetPropertyReply *reply) +{ + reply->nItems = 0; + reply->length = 0; + reply->bytesAfter = 0; + reply->propertyType = propertyType; + reply->format = format; + WriteReplyToClient(client, sizeof(xGenericReply), reply); + return Success; +} + +/***************** + * GetProperty + * If type Any is specified, returns the property from the specified + * window regardless of its type. If a type is specified, returns the + * property only if its type equals the specified type. + * If delete is True and a property is returned, the property is also + * deleted from the window and a PropertyNotify event is generated on the + * window. + *****************/ + +int +ProcGetProperty(ClientPtr client) +{ + PropertyPtr pProp, prevProp; + unsigned long n, len, ind; + int rc; + WindowPtr pWin; + xGetPropertyReply reply; + Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess; + REQUEST(xGetPropertyReq); + + REQUEST_SIZE_MATCH(xGetPropertyReq); + if (stuff->delete) { + UpdateCurrentTime(); + win_mode |= DixSetPropAccess; + prop_mode |= DixDestroyAccess; + } + rc = dixLookupWindow(&pWin, stuff->window, client, win_mode); + if (rc != Success) + return rc; + + if (!ValidAtom(stuff->property)) + { + client->errorValue = stuff->property; + return BadAtom; + } + if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) + { + client->errorValue = stuff->delete; + return BadValue; + } + if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) + { + client->errorValue = stuff->type; + return BadAtom; + } + + memset(&reply, 0, sizeof(xGetPropertyReply)); + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode); + if (rc == BadMatch) + return NullPropertyReply(client, None, 0, &reply); + else if (rc != Success) + return rc; + + /* If the request type and actual type don't match. Return the + property information, but not the data. */ + + if (((stuff->type != pProp->type) && + (stuff->type != AnyPropertyType)) + ) + { + reply.bytesAfter = pProp->size; + reply.format = pProp->format; + reply.length = 0; + reply.nItems = 0; + reply.propertyType = pProp->type; + WriteReplyToClient(client, sizeof(xGenericReply), &reply); + return Success; + } + +/* + * Return type, format, value to client + */ + n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */ + ind = stuff->longOffset << 2; + + /* If longOffset is invalid such that it causes "len" to + be negative, it's a value error. */ + + if (n < ind) + { + client->errorValue = stuff->longOffset; + return BadValue; + } + + len = min(n - ind, 4 * stuff->longLength); + + reply.bytesAfter = n - (ind + len); + reply.format = pProp->format; + reply.length = bytes_to_int32(len); + reply.nItems = len / (pProp->format / 8 ); + reply.propertyType = pProp->type; + + if (stuff->delete && (reply.bytesAfter == 0)) + deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); + + WriteReplyToClient(client, sizeof(xGenericReply), &reply); + if (len) + { + switch (reply.format) { + case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break; + case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break; + default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break; + } + WriteSwappedDataToClient(client, len, + (char *)pProp->data + ind); + } + + if (stuff->delete && (reply.bytesAfter == 0)) { + /* Delete the Property */ + if (pWin->optional->userProps == pProp) { + /* Takes care of head */ + if (!(pWin->optional->userProps = pProp->next)) + CheckWindowOptionalNeed (pWin); + } else { + /* Need to traverse to find the previous element */ + prevProp = pWin->optional->userProps; + while (prevProp->next != pProp) + prevProp = prevProp->next; + prevProp->next = pProp->next; + } + + free(pProp->data); + dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); + } + return Success; +} + +int +ProcListProperties(ClientPtr client) +{ + Atom *pAtoms = NULL, *temppAtoms; + xListPropertiesReply xlpr; + int rc, numProps = 0; + WindowPtr pWin; + PropertyPtr pProp, realProp; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess); + if (rc != Success) + return rc; + + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) + numProps++; + + if (numProps && !(pAtoms = malloc(numProps * sizeof(Atom)))) + return BadAlloc; + + numProps = 0; + temppAtoms = pAtoms; + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { + realProp = pProp; + rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess); + if (rc == Success && realProp == pProp) { + *temppAtoms++ = pProp->propertyName; + numProps++; + } + } + + xlpr.type = X_Reply; + xlpr.nProperties = numProps; + xlpr.length = bytes_to_int32(numProps * sizeof(Atom)); + xlpr.sequenceNumber = client->sequence; + WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); + if (numProps) + { + client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; + WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); + } + free(pAtoms); + return Success; +} + +int +ProcDeleteProperty(ClientPtr client) +{ + WindowPtr pWin; + REQUEST(xDeletePropertyReq); + int result; + + REQUEST_SIZE_MATCH(xDeletePropertyReq); + UpdateCurrentTime(); + result = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); + if (result != Success) + return result; + if (!ValidAtom(stuff->property)) + { + client->errorValue = stuff->property; + return BadAtom; + } + + return DeleteProperty(client, pWin, stuff->property); +} diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c index 0741a7294..85e38e058 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c @@ -586,7 +586,7 @@ ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client) } rep.isCapable = isCapable; - if (!LocalClient(client) || client->swapped) + if (!client->local || client->swapped) rep.isCapable = 0; if (client->swapped) { @@ -1253,7 +1253,7 @@ ProcXF86DRIDispatch (register ClientPtr client) } } - if (!LocalClient(client)) + if (!client->local) return DRIErrorBase + XF86DRIClientNotLocal; switch (stuff->data) diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am index 4f0877290..72be8891c 100644 --- a/xorg-server/hw/xfree86/Makefile.am +++ b/xorg-server/hw/xfree86/Makefile.am @@ -11,9 +11,7 @@ if XF86UTILS XF86UTILS_SUBDIR = utils endif -if XAA XAA_SUBDIR = xaa -endif if VGAHW VGAHW_SUBDIR = vgahw diff --git a/xorg-server/hw/xfree86/common/compiler.h b/xorg-server/hw/xfree86/common/compiler.h index 9c9bac6ba..01034916c 100644 --- a/xorg-server/hw/xfree86/common/compiler.h +++ b/xorg-server/hw/xfree86/common/compiler.h @@ -397,25 +397,6 @@ extern _X_EXPORT unsigned int inl(unsigned int port); #include <machine/pio.h> #endif /* __NetBSD__ */ -# elif defined(linux) && defined(__ia64__) - -# include <inttypes.h> - -# include <sys/io.h> - -# undef outb -# undef outw -# undef outl -# undef inb -# undef inw -# undef inl -extern _X_EXPORT void outb(unsigned long port, unsigned char val); -extern _X_EXPORT void outw(unsigned long port, unsigned short val); -extern _X_EXPORT void outl(unsigned long port, unsigned int val); -extern _X_EXPORT unsigned int inb(unsigned long port); -extern _X_EXPORT unsigned int inw(unsigned long port); -extern _X_EXPORT unsigned int inl(unsigned long port); - # elif (defined(linux) || defined(__FreeBSD__)) && defined(__amd64__) # include <inttypes.h> diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c index 280a6ec93..fd40f28da 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.c +++ b/xorg-server/hw/xfree86/common/xf86Xinput.c @@ -970,15 +970,16 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs, pInfo->attrs = DuplicateInputAttributes(attrs); } - if (!pInfo->driver || !pInfo->name) { - xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n"); + if (!pInfo->name) { + xf86Msg(X_INFO, "No identifier specified, ignoring this device.\n"); rval = BadRequest; goto unwind; } - if (!pInfo->name) { - xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n"); - rval = BadMatch; + if (!pInfo->driver) { + xf86Msg(X_INFO, "No input driver specified, ignoring this device.\n"); + xf86Msg(X_INFO, "This device may have been added with another device file.\n"); + rval = BadRequest; goto unwind; } diff --git a/xorg-server/hw/xfree86/ddc/ddcProperty.c b/xorg-server/hw/xfree86/ddc/ddcProperty.c index 5d6eec927..c3aced5c2 100644 --- a/xorg-server/hw/xfree86/ddc/ddcProperty.c +++ b/xorg-server/hw/xfree86/ddc/ddcProperty.c @@ -33,7 +33,6 @@ #include <string.h> #define EDID1_ATOM_NAME "XFree86_DDC_EDID1_RAWDATA" -#define EDID2_ATOM_NAME "XFree86_DDC_EDID2_RAWDATA" static void edidMakeAtom(int i, const char *name, CARD8 *data, int size) @@ -52,59 +51,21 @@ edidMakeAtom(int i, const char *name, CARD8 *data, int size) static void addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) { - int i, scrnIndex = pScrn->scrnIndex; - Bool makeEDID1prop = FALSE; - Bool makeEDID2prop = FALSE; + int scrnIndex = pScrn->scrnIndex; if (DDC->flags & MONITOR_DISPLAYID) { /* Don't bother, use RANDR already */ return; } else if (DDC->ver.version == 1) { - makeEDID1prop = TRUE; - } else if (DDC->ver.version == 2) { - int checksum1; - int checksum2; - makeEDID2prop = TRUE; + int size = 128 + + (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0); - /* Some monitors (eg Panasonic PanaSync4) - * report version==2 because they used EDID v2 spec document, - * although they use EDID v1 data structure :-( - * - * Try using checksum to determine when we have such a monitor. - */ - checksum2 = 0; - for (i = 0; i < 256; i++) - checksum2 += DDC->rawData[i]; - if (checksum2 % 256) { - xf86DrvMsg(scrnIndex, X_INFO, "Monitor EDID v2 checksum failed\n"); - xf86DrvMsg(scrnIndex, X_INFO, - "XFree86_DDC_EDID2_RAWDATA property may be bad\n"); - checksum1 = 0; - for (i = 0; i < 128; i++) - checksum1 += DDC->rawData[i]; - if (!(checksum1 % 256)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Monitor EDID v1 checksum passed,\n"); - xf86DrvMsg(scrnIndex, X_INFO, - "XFree86_DDC_EDID1_RAWDATA property created\n"); - makeEDID1prop = TRUE; - } - } + edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC->rawData, size); } else { xf86DrvMsg(scrnIndex, X_PROBED, "unexpected EDID version %d.%d\n", DDC->ver.version, DDC->ver.revision); return; } - - if (makeEDID1prop) { - int size = 128 + - (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0); - - edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC->rawData, size); - } - - if (makeEDID2prop) - edidMakeAtom(scrnIndex, EDID2_ATOM_NAME, DDC->rawData, 256); } Bool diff --git a/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c b/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c index f1c740723..4b17f152e 100644 --- a/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c +++ b/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c @@ -1,1035 +1,1035 @@ -/*
- * Copyright (c) 1995 Jon Tombs
- * Copyright (c) 1995, 1996, 1999 XFree86 Inc
- * Copyright (c) 1999 - The XFree86 Project Inc.
- *
- * Written by Mark Vojkovich
- */
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "dixevents.h"
-#include "pixmapstr.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-#include <X11/extensions/xf86dgaproto.h>
-#include "swaprep.h"
-#include "dgaproc.h"
-#include "protocol-versions.h"
-
-#include <string.h>
-
-#include "modinit.h"
-
-#define DGA_PROTOCOL_OLD_SUPPORT 1
-
-
-static void XDGAResetProc(ExtensionEntry *extEntry);
-
-static void DGAClientStateChange (CallbackListPtr*, pointer, pointer);
-
-unsigned char DGAReqCode = 0;
-int DGAErrorBase;
-int DGAEventBase;
-
-static DevPrivateKeyRec DGAScreenPrivateKeyRec;
-#define DGAScreenPrivateKey (&DGAScreenPrivateKeyRec)
-#define DGAScreenPrivateKeyRegistered (DGAScreenPrivateKeyRec.initialized)
-static DevPrivateKeyRec DGAClientPrivateKeyRec;
-#define DGAClientPrivateKey (&DGAClientPrivateKeyRec)
-static int DGACallbackRefCount = 0;
-
-/* This holds the client's version information */
-typedef struct {
- int major;
- int minor;
-} DGAPrivRec, *DGAPrivPtr;
-
-#define DGA_GETCLIENT(idx) ((ClientPtr) \
- dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey))
-#define DGA_SETCLIENT(idx,p) \
- dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p)
-
-#define DGA_GETPRIV(c) ((DGAPrivPtr) \
- dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
-#define DGA_SETPRIV(c,p) \
- dixSetPrivate(&(c)->devPrivates, DGAClientPrivateKey, p)
-
-
-static void
-XDGAResetProc (ExtensionEntry *extEntry)
-{
- DeleteCallback (&ClientStateCallback, DGAClientStateChange, NULL);
- DGACallbackRefCount = 0;
-}
-
-
-static int
-ProcXDGAQueryVersion(ClientPtr client)
-{
- xXDGAQueryVersionReply rep;
-
- REQUEST_SIZE_MATCH(xXDGAQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SERVER_XDGA_MAJOR_VERSION;
- rep.minorVersion = SERVER_XDGA_MINOR_VERSION;
-
- WriteToClient(client, sizeof(xXDGAQueryVersionReply), (char *)&rep);
- return Success;
-}
-
-
-static int
-ProcXDGAOpenFramebuffer(ClientPtr client)
-{
- REQUEST(xXDGAOpenFramebufferReq);
- xXDGAOpenFramebufferReply rep;
- char *deviceName;
- int nameSize;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if(!DGAOpenFramebuffer(stuff->screen, &deviceName,
- (unsigned char**)(&rep.mem1),
- (int*)&rep.size, (int*)&rep.offset, (int*)&rep.extra))
- {
- return BadAlloc;
- }
-
- nameSize = deviceName ? (strlen(deviceName) + 1) : 0;
- rep.length = bytes_to_int32(nameSize);
-
- WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *)&rep);
- if(rep.length)
- WriteToClient(client, nameSize, deviceName);
-
- return Success;
-}
-
-
-static int
-ProcXDGACloseFramebuffer(ClientPtr client)
-{
- REQUEST(xXDGACloseFramebufferReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq);
-
- DGACloseFramebuffer(stuff->screen);
-
- return Success;
-}
-
-static int
-ProcXDGAQueryModes(ClientPtr client)
-{
- int i, num, size;
- REQUEST(xXDGAQueryModesReq);
- xXDGAQueryModesReply rep;
- xXDGAModeInfo info;
- XDGAModePtr mode;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXDGAQueryModesReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.number = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DGAAvailable(stuff->screen)) {
- rep.number = 0;
- rep.length = 0;
- WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
- return Success;
- }
-
- if(!(num = DGAGetModes(stuff->screen))) {
- WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
- return Success;
- }
-
- if(!(mode = (XDGAModePtr)malloc(num * sizeof(XDGAModeRec))))
- return BadAlloc;
-
- for(i = 0; i < num; i++)
- DGAGetModeInfo(stuff->screen, mode + i, i + 1);
-
- size = num * sz_xXDGAModeInfo;
- for(i = 0; i < num; i++)
- size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */
-
- rep.number = num;
- rep.length = bytes_to_int32(size);
-
- WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
-
- for(i = 0; i < num; i++) {
- size = strlen(mode[i].name) + 1;
-
- info.byte_order = mode[i].byteOrder;
- info.depth = mode[i].depth;
- info.num = mode[i].num;
- info.bpp = mode[i].bitsPerPixel;
- info.name_size = (size + 3) & ~3L;
- info.vsync_num = mode[i].VSync_num;
- info.vsync_den = mode[i].VSync_den;
- info.flags = mode[i].flags;
- info.image_width = mode[i].imageWidth;
- info.image_height = mode[i].imageHeight;
- info.pixmap_width = mode[i].pixmapWidth;
- info.pixmap_height = mode[i].pixmapHeight;
- info.bytes_per_scanline = mode[i].bytesPerScanline;
- info.red_mask = mode[i].red_mask;
- info.green_mask = mode[i].green_mask;
- info.blue_mask = mode[i].blue_mask;
- info.visual_class = mode[i].visualClass;
- info.viewport_width = mode[i].viewportWidth;
- info.viewport_height = mode[i].viewportHeight;
- info.viewport_xstep = mode[i].xViewportStep;
- info.viewport_ystep = mode[i].yViewportStep;
- info.viewport_xmax = mode[i].maxViewportX;
- info.viewport_ymax = mode[i].maxViewportY;
- info.viewport_flags = mode[i].viewportFlags;
- info.reserved1 = mode[i].reserved1;
- info.reserved2 = mode[i].reserved2;
-
- WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info));
- WriteToClient(client, size, mode[i].name);
- }
-
- free(mode);
-
- return Success;
-}
-
-
-static void
-DGAClientStateChange (
- CallbackListPtr* pcbl,
- pointer nulldata,
- pointer calldata
-){
- NewClientInfoRec* pci = (NewClientInfoRec*) calldata;
- ClientPtr client = NULL;
- int i;
-
- for(i = 0; i < screenInfo.numScreens; i++) {
- if(DGA_GETCLIENT(i) == pci->client) {
- client = pci->client;
- break;
- }
- }
-
- if(client &&
- ((client->clientState == ClientStateGone) ||
- (client->clientState == ClientStateRetained))) {
- XDGAModeRec mode;
- PixmapPtr pPix;
-
- DGA_SETCLIENT(i, NULL);
- DGASelectInput(i, NULL, 0);
- DGASetMode(i, 0, &mode, &pPix);
-
- if(--DGACallbackRefCount == 0)
- DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
- }
-}
-
-static int
-ProcXDGASetMode(ClientPtr client)
-{
- REQUEST(xXDGASetModeReq);
- xXDGASetModeReply rep;
- XDGAModeRec mode;
- xXDGAModeInfo info;
- PixmapPtr pPix;
- ClientPtr owner;
- int size;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
- owner = DGA_GETCLIENT(stuff->screen);
-
- REQUEST_SIZE_MATCH(xXDGASetModeReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.offset = 0;
- rep.flags = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- if(owner && owner != client)
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- if(!stuff->mode) {
- if(owner) {
- if(--DGACallbackRefCount == 0)
- DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
- }
- DGA_SETCLIENT(stuff->screen, NULL);
- DGASelectInput(stuff->screen, NULL, 0);
- DGASetMode(stuff->screen, 0, &mode, &pPix);
- WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
- return Success;
- }
-
- if(Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
- return BadValue;
-
- if(!owner) {
- if(DGACallbackRefCount++ == 0)
- AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
- }
-
- DGA_SETCLIENT(stuff->screen, client);
-
- if(pPix) {
- if(AddResource(stuff->pid, RT_PIXMAP, (pointer)(pPix))) {
- pPix->drawable.id = (int)stuff->pid;
- rep.flags = DGA_PIXMAP_AVAILABLE;
- }
- }
-
- size = strlen(mode.name) + 1;
-
- info.byte_order = mode.byteOrder;
- info.depth = mode.depth;
- info.num = mode.num;
- info.bpp = mode.bitsPerPixel;
- info.name_size = (size + 3) & ~3L;
- info.vsync_num = mode.VSync_num;
- info.vsync_den = mode.VSync_den;
- info.flags = mode.flags;
- info.image_width = mode.imageWidth;
- info.image_height = mode.imageHeight;
- info.pixmap_width = mode.pixmapWidth;
- info.pixmap_height = mode.pixmapHeight;
- info.bytes_per_scanline = mode.bytesPerScanline;
- info.red_mask = mode.red_mask;
- info.green_mask = mode.green_mask;
- info.blue_mask = mode.blue_mask;
- info.visual_class = mode.visualClass;
- info.viewport_width = mode.viewportWidth;
- info.viewport_height = mode.viewportHeight;
- info.viewport_xstep = mode.xViewportStep;
- info.viewport_ystep = mode.yViewportStep;
- info.viewport_xmax = mode.maxViewportX;
- info.viewport_ymax = mode.maxViewportY;
- info.viewport_flags = mode.viewportFlags;
- info.reserved1 = mode.reserved1;
- info.reserved2 = mode.reserved2;
-
- rep.length = bytes_to_int32(sz_xXDGAModeInfo + info.name_size);
-
- WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
- WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info));
- WriteToClient(client, size, mode.name);
-
- return Success;
-}
-
-static int
-ProcXDGASetViewport(ClientPtr client)
-{
- REQUEST(xXDGASetViewportReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGASetViewportReq);
-
- DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags);
-
- return Success;
-}
-
-static int
-ProcXDGAInstallColormap(ClientPtr client)
-{
- ColormapPtr cmap;
- int rc;
- REQUEST(xXDGAInstallColormapReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
-
- rc = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, RT_COLORMAP,
- client, DixInstallAccess);
- if (rc != Success)
- return rc;
- DGAInstallCmap(cmap);
- return Success;
-}
-
-
-static int
-ProcXDGASelectInput(ClientPtr client)
-{
- REQUEST(xXDGASelectInputReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGASelectInputReq);
-
- if(DGA_GETCLIENT(stuff->screen) == client)
- DGASelectInput(stuff->screen, client, stuff->mask);
-
- return Success;
-}
-
-
-static int
-ProcXDGAFillRectangle(ClientPtr client)
-{
- REQUEST(xXDGAFillRectangleReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
-
- if(Success != DGAFillRect(stuff->screen, stuff->x, stuff->y,
- stuff->width, stuff->height, stuff->color))
- return BadMatch;
-
- return Success;
-}
-
-static int
-ProcXDGACopyArea(ClientPtr client)
-{
- REQUEST(xXDGACopyAreaReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGACopyAreaReq);
-
- if(Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy,
- stuff->width, stuff->height, stuff->dstx, stuff->dsty))
- return BadMatch;
-
- return Success;
-}
-
-
-static int
-ProcXDGACopyTransparentArea(ClientPtr client)
-{
- REQUEST(xXDGACopyTransparentAreaReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq);
-
- if(Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy,
- stuff->width, stuff->height, stuff->dstx, stuff->dsty, stuff->key))
- return BadMatch;
-
- return Success;
-}
-
-
-static int
-ProcXDGAGetViewportStatus(ClientPtr client)
-{
- REQUEST(xXDGAGetViewportStatusReq);
- xXDGAGetViewportStatusReply rep;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rep.status = DGAGetViewportStatus(stuff->screen);
-
- WriteToClient(client, sizeof(xXDGAGetViewportStatusReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXDGASync(ClientPtr client)
-{
- REQUEST(xXDGASyncReq);
- xXDGASyncReply rep;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGASyncReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- DGASync(stuff->screen);
-
- WriteToClient(client, sizeof(xXDGASyncReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXDGASetClientVersion(ClientPtr client)
-{
- REQUEST(xXDGASetClientVersionReq);
-
- DGAPrivPtr pPriv;
-
- REQUEST_SIZE_MATCH(xXDGASetClientVersionReq);
- if ((pPriv = DGA_GETPRIV(client)) == NULL) {
- pPriv = malloc(sizeof(DGAPrivRec));
- /* XXX Need to look into freeing this */
- if (!pPriv)
- return BadAlloc;
- DGA_SETPRIV(client, pPriv);
- }
- pPriv->major = stuff->major;
- pPriv->minor = stuff->minor;
-
- return Success;
-}
-
-static int
-ProcXDGAChangePixmapMode(ClientPtr client)
-{
- REQUEST(xXDGAChangePixmapModeReq);
- xXDGAChangePixmapModeReply rep;
- int x, y;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- x = stuff->x;
- y = stuff->y;
-
- if(!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags))
- return BadMatch;
-
- rep.x = x;
- rep.y = y;
- WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *)&rep);
-
- return Success;
-}
-
-
-static int
-ProcXDGACreateColormap(ClientPtr client)
-{
- REQUEST(xXDGACreateColormapReq);
- int result;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGACreateColormapReq);
-
- if(!stuff->mode)
- return BadValue;
-
- result = DGACreateColormap(stuff->screen, client, stuff->id,
- stuff->mode, stuff->alloc);
- if(result != Success)
- return result;
-
- return Success;
-}
-
-/*
- *
- * Support for the old DGA protocol, used to live in xf86dga.c
- *
- */
-
-#ifdef DGA_PROTOCOL_OLD_SUPPORT
-
-
-
-static int
-ProcXF86DGAGetVideoLL(ClientPtr client)
-{
- REQUEST(xXF86DGAGetVideoLLReq);
- xXF86DGAGetVideoLLReply rep;
- XDGAModeRec mode;
- int num, offset, flags;
- char *name;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if(!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- if(!(num = DGAGetOldDGAMode(stuff->screen)))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- /* get the parameters for the mode that best matches */
- DGAGetModeInfo(stuff->screen, &mode, num);
-
- if(!DGAOpenFramebuffer(stuff->screen, &name,
- (unsigned char**)(&rep.offset),
- (int*)(&rep.bank_size), &offset, &flags))
- return BadAlloc;
-
- rep.offset += mode.offset;
- rep.width = mode.bytesPerScanline / (mode.bitsPerPixel >> 3);
- rep.ram_size = rep.bank_size >> 10;
-
- WriteToClient(client, SIZEOF(xXF86DGAGetVideoLLReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DGADirectVideo(ClientPtr client)
-{
- int num;
- PixmapPtr pix;
- XDGAModeRec mode;
- ClientPtr owner;
- REQUEST(xXF86DGADirectVideoReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
- REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
-
- if (!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- owner = DGA_GETCLIENT(stuff->screen);
-
- if (owner && owner != client)
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- if (stuff->enable & XF86DGADirectGraphics) {
- if(!(num = DGAGetOldDGAMode(stuff->screen)))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
- } else
- num = 0;
-
- if(Success != DGASetMode(stuff->screen, num, &mode, &pix))
- return DGAErrorBase + XF86DGAScreenNotActive;
-
- DGASetInputMode (stuff->screen,
- (stuff->enable & XF86DGADirectKeyb) != 0,
- (stuff->enable & XF86DGADirectMouse) != 0);
-
- /* We need to track the client and attach the teardown callback */
- if (stuff->enable &
- (XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) {
- if (!owner) {
- if (DGACallbackRefCount++ == 0)
- AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
- }
-
- DGA_SETCLIENT(stuff->screen, client);
- } else {
- if (owner) {
- if (--DGACallbackRefCount == 0)
- DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
- }
-
- DGA_SETCLIENT(stuff->screen, NULL);
- }
-
- return Success;
-}
-
-static int
-ProcXF86DGAGetViewPortSize(ClientPtr client)
-{
- int num;
- XDGAModeRec mode;
- REQUEST(xXF86DGAGetViewPortSizeReq);
- xXF86DGAGetViewPortSizeReply rep;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- if(!(num = DGAGetOldDGAMode(stuff->screen)))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- DGAGetModeInfo(stuff->screen, &mode, num);
-
- rep.width = mode.viewportWidth;
- rep.height = mode.viewportHeight;
-
- WriteToClient(client, SIZEOF(xXF86DGAGetViewPortSizeReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DGASetViewPort(ClientPtr client)
-{
- REQUEST(xXF86DGASetViewPortReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
-
- if (!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- if (!DGAActive(stuff->screen))
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- if (DGASetViewport(stuff->screen, stuff->x, stuff->y, DGA_FLIP_RETRACE)
- != Success)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- return Success;
-}
-
-static int
-ProcXF86DGAGetVidPage(ClientPtr client)
-{
- REQUEST(xXF86DGAGetVidPageReq);
- xXF86DGAGetVidPageReply rep;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.vpage = 0; /* silently fail */
-
- WriteToClient(client, SIZEOF(xXF86DGAGetVidPageReply), (char *)&rep);
- return Success;
-}
-
-
-static int
-ProcXF86DGASetVidPage(ClientPtr client)
-{
- REQUEST(xXF86DGASetVidPageReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq);
-
- /* silently fail */
-
- return Success;
-}
-
-
-static int
-ProcXF86DGAInstallColormap(ClientPtr client)
-{
- ColormapPtr pcmp;
- int rc;
- REQUEST(xXF86DGAInstallColormapReq);
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq);
-
- if (!DGAActive(stuff->screen))
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP,
- client, DixInstallAccess);
- if (rc == Success) {
- DGAInstallCmap(pcmp);
- return Success;
- } else {
- return rc;
- }
-}
-
-static int
-ProcXF86DGAQueryDirectVideo(ClientPtr client)
-{
- REQUEST(xXF86DGAQueryDirectVideoReq);
- xXF86DGAQueryDirectVideoReply rep;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.flags = 0;
-
- if (DGAAvailable(stuff->screen))
- rep.flags = XF86DGADirectPresent;
-
- WriteToClient(client, SIZEOF(xXF86DGAQueryDirectVideoReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DGAViewPortChanged(ClientPtr client)
-{
- REQUEST(xXF86DGAViewPortChangedReq);
- xXF86DGAViewPortChangedReply rep;
-
- if (stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq);
-
- if (!DGAActive(stuff->screen))
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.result = 1;
-
- WriteToClient(client, SIZEOF(xXF86DGAViewPortChangedReply), (char *)&rep);
- return Success;
-}
-
-#endif /* DGA_PROTOCOL_OLD_SUPPORT */
-
-static int
-SProcXDGADispatch (ClientPtr client)
-{
- return DGAErrorBase + XF86DGAClientNotLocal;
-}
-
-#if 0
-#define DGA_REQ_DEBUG
-#endif
-
-#ifdef DGA_REQ_DEBUG
-static char *dgaMinor[] = {
- "QueryVersion",
- "GetVideoLL",
- "DirectVideo",
- "GetViewPortSize",
- "SetViewPort",
- "GetVidPage",
- "SetVidPage",
- "InstallColormap",
- "QueryDirectVideo",
- "ViewPortChanged",
- "10",
- "11",
- "QueryModes",
- "SetMode",
- "SetViewport",
- "InstallColormap",
- "SelectInput",
- "FillRectangle",
- "CopyArea",
- "CopyTransparentArea",
- "GetViewportStatus",
- "Sync",
- "OpenFramebuffer",
- "CloseFramebuffer",
- "SetClientVersion",
- "ChangePixmapMode",
- "CreateColormap",
-};
-#endif
-
-static int
-ProcXDGADispatch (ClientPtr client)
-{
- REQUEST(xReq);
-
- if (!LocalClient(client))
- return DGAErrorBase + XF86DGAClientNotLocal;
-
-#ifdef DGA_REQ_DEBUG
- if (stuff->data <= X_XDGACreateColormap)
- fprintf (stderr, " DGA %s\n", dgaMinor[stuff->data]);
-#endif
-
- switch (stuff->data){
- /*
- * DGA2 Protocol
- */
- case X_XDGAQueryVersion:
- return ProcXDGAQueryVersion(client);
- case X_XDGAQueryModes:
- return ProcXDGAQueryModes(client);
- case X_XDGASetMode:
- return ProcXDGASetMode(client);
- case X_XDGAOpenFramebuffer:
- return ProcXDGAOpenFramebuffer(client);
- case X_XDGACloseFramebuffer:
- return ProcXDGACloseFramebuffer(client);
- case X_XDGASetViewport:
- return ProcXDGASetViewport(client);
- case X_XDGAInstallColormap:
- return ProcXDGAInstallColormap(client);
- case X_XDGASelectInput:
- return ProcXDGASelectInput(client);
- case X_XDGAFillRectangle:
- return ProcXDGAFillRectangle(client);
- case X_XDGACopyArea:
- return ProcXDGACopyArea(client);
- case X_XDGACopyTransparentArea:
- return ProcXDGACopyTransparentArea(client);
- case X_XDGAGetViewportStatus:
- return ProcXDGAGetViewportStatus(client);
- case X_XDGASync:
- return ProcXDGASync(client);
- case X_XDGASetClientVersion:
- return ProcXDGASetClientVersion(client);
- case X_XDGAChangePixmapMode:
- return ProcXDGAChangePixmapMode(client);
- case X_XDGACreateColormap:
- return ProcXDGACreateColormap(client);
- /*
- * Old DGA Protocol
- */
-#ifdef DGA_PROTOCOL_OLD_SUPPORT
- case X_XF86DGAGetVideoLL:
- return ProcXF86DGAGetVideoLL(client);
- case X_XF86DGADirectVideo:
- return ProcXF86DGADirectVideo(client);
- case X_XF86DGAGetViewPortSize:
- return ProcXF86DGAGetViewPortSize(client);
- case X_XF86DGASetViewPort:
- return ProcXF86DGASetViewPort(client);
- case X_XF86DGAGetVidPage:
- return ProcXF86DGAGetVidPage(client);
- case X_XF86DGASetVidPage:
- return ProcXF86DGASetVidPage(client);
- case X_XF86DGAInstallColormap:
- return ProcXF86DGAInstallColormap(client);
- case X_XF86DGAQueryDirectVideo:
- return ProcXF86DGAQueryDirectVideo(client);
- case X_XF86DGAViewPortChanged:
- return ProcXF86DGAViewPortChanged(client);
-#endif /* DGA_PROTOCOL_OLD_SUPPORT */
- default:
- return BadRequest;
- }
-}
-
-void
-XFree86DGARegister(INITARGS)
-{
- XDGAEventBase = &DGAEventBase;
-}
-
-void
-XFree86DGAExtensionInit(INITARGS)
-{
- ExtensionEntry* extEntry;
-
- if (!dixRegisterPrivateKey(&DGAClientPrivateKeyRec, PRIVATE_CLIENT, 0))
- return;
-
- if (!dixRegisterPrivateKey(&DGAScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
- return;
-
- if ((extEntry = AddExtension(XF86DGANAME,
- XF86DGANumberEvents,
- XF86DGANumberErrors,
- ProcXDGADispatch,
- SProcXDGADispatch,
- XDGAResetProc,
- StandardMinorOpcode))) {
- int i;
-
- DGAReqCode = (unsigned char)extEntry->base;
- DGAErrorBase = extEntry->errorBase;
- DGAEventBase = extEntry->eventBase;
- for (i = KeyPress; i <= MotionNotify; i++)
- SetCriticalEvent (DGAEventBase + i);
- }
-}
+/* + * Copyright (c) 1995 Jon Tombs + * Copyright (c) 1995, 1996, 1999 XFree86 Inc + * Copyright (c) 1999 - The XFree86 Project Inc. + * + * Written by Mark Vojkovich + */ + + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "dixstruct.h" +#include "dixevents.h" +#include "pixmapstr.h" +#include "extnsionst.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "scrnintstr.h" +#include "servermd.h" +#include <X11/extensions/xf86dgaproto.h> +#include "swaprep.h" +#include "dgaproc.h" +#include "protocol-versions.h" + +#include <string.h> + +#include "modinit.h" + +#define DGA_PROTOCOL_OLD_SUPPORT 1 + + +static void XDGAResetProc(ExtensionEntry *extEntry); + +static void DGAClientStateChange (CallbackListPtr*, pointer, pointer); + +unsigned char DGAReqCode = 0; +int DGAErrorBase; +int DGAEventBase; + +static DevPrivateKeyRec DGAScreenPrivateKeyRec; +#define DGAScreenPrivateKey (&DGAScreenPrivateKeyRec) +#define DGAScreenPrivateKeyRegistered (DGAScreenPrivateKeyRec.initialized) +static DevPrivateKeyRec DGAClientPrivateKeyRec; +#define DGAClientPrivateKey (&DGAClientPrivateKeyRec) +static int DGACallbackRefCount = 0; + +/* This holds the client's version information */ +typedef struct { + int major; + int minor; +} DGAPrivRec, *DGAPrivPtr; + +#define DGA_GETCLIENT(idx) ((ClientPtr) \ + dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey)) +#define DGA_SETCLIENT(idx,p) \ + dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p) + +#define DGA_GETPRIV(c) ((DGAPrivPtr) \ + dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey)) +#define DGA_SETPRIV(c,p) \ + dixSetPrivate(&(c)->devPrivates, DGAClientPrivateKey, p) + + +static void +XDGAResetProc (ExtensionEntry *extEntry) +{ + DeleteCallback (&ClientStateCallback, DGAClientStateChange, NULL); + DGACallbackRefCount = 0; +} + + +static int +ProcXDGAQueryVersion(ClientPtr client) +{ + xXDGAQueryVersionReply rep; + + REQUEST_SIZE_MATCH(xXDGAQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = SERVER_XDGA_MAJOR_VERSION; + rep.minorVersion = SERVER_XDGA_MINOR_VERSION; + + WriteToClient(client, sizeof(xXDGAQueryVersionReply), (char *)&rep); + return Success; +} + + +static int +ProcXDGAOpenFramebuffer(ClientPtr client) +{ + REQUEST(xXDGAOpenFramebufferReq); + xXDGAOpenFramebufferReply rep; + char *deviceName; + int nameSize; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if (!DGAAvailable(stuff->screen)) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if(!DGAOpenFramebuffer(stuff->screen, &deviceName, + (unsigned char**)(&rep.mem1), + (int*)&rep.size, (int*)&rep.offset, (int*)&rep.extra)) + { + return BadAlloc; + } + + nameSize = deviceName ? (strlen(deviceName) + 1) : 0; + rep.length = bytes_to_int32(nameSize); + + WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *)&rep); + if(rep.length) + WriteToClient(client, nameSize, deviceName); + + return Success; +} + + +static int +ProcXDGACloseFramebuffer(ClientPtr client) +{ + REQUEST(xXDGACloseFramebufferReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if (!DGAAvailable(stuff->screen)) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq); + + DGACloseFramebuffer(stuff->screen); + + return Success; +} + +static int +ProcXDGAQueryModes(ClientPtr client) +{ + int i, num, size; + REQUEST(xXDGAQueryModesReq); + xXDGAQueryModesReply rep; + xXDGAModeInfo info; + XDGAModePtr mode; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + REQUEST_SIZE_MATCH(xXDGAQueryModesReq); + rep.type = X_Reply; + rep.length = 0; + rep.number = 0; + rep.sequenceNumber = client->sequence; + + if (!DGAAvailable(stuff->screen)) { + rep.number = 0; + rep.length = 0; + WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep); + return Success; + } + + if(!(num = DGAGetModes(stuff->screen))) { + WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep); + return Success; + } + + if(!(mode = (XDGAModePtr)malloc(num * sizeof(XDGAModeRec)))) + return BadAlloc; + + for(i = 0; i < num; i++) + DGAGetModeInfo(stuff->screen, mode + i, i + 1); + + size = num * sz_xXDGAModeInfo; + for(i = 0; i < num; i++) + size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */ + + rep.number = num; + rep.length = bytes_to_int32(size); + + WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep); + + for(i = 0; i < num; i++) { + size = strlen(mode[i].name) + 1; + + info.byte_order = mode[i].byteOrder; + info.depth = mode[i].depth; + info.num = mode[i].num; + info.bpp = mode[i].bitsPerPixel; + info.name_size = (size + 3) & ~3L; + info.vsync_num = mode[i].VSync_num; + info.vsync_den = mode[i].VSync_den; + info.flags = mode[i].flags; + info.image_width = mode[i].imageWidth; + info.image_height = mode[i].imageHeight; + info.pixmap_width = mode[i].pixmapWidth; + info.pixmap_height = mode[i].pixmapHeight; + info.bytes_per_scanline = mode[i].bytesPerScanline; + info.red_mask = mode[i].red_mask; + info.green_mask = mode[i].green_mask; + info.blue_mask = mode[i].blue_mask; + info.visual_class = mode[i].visualClass; + info.viewport_width = mode[i].viewportWidth; + info.viewport_height = mode[i].viewportHeight; + info.viewport_xstep = mode[i].xViewportStep; + info.viewport_ystep = mode[i].yViewportStep; + info.viewport_xmax = mode[i].maxViewportX; + info.viewport_ymax = mode[i].maxViewportY; + info.viewport_flags = mode[i].viewportFlags; + info.reserved1 = mode[i].reserved1; + info.reserved2 = mode[i].reserved2; + + WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info)); + WriteToClient(client, size, mode[i].name); + } + + free(mode); + + return Success; +} + + +static void +DGAClientStateChange ( + CallbackListPtr* pcbl, + pointer nulldata, + pointer calldata +){ + NewClientInfoRec* pci = (NewClientInfoRec*) calldata; + ClientPtr client = NULL; + int i; + + for(i = 0; i < screenInfo.numScreens; i++) { + if(DGA_GETCLIENT(i) == pci->client) { + client = pci->client; + break; + } + } + + if(client && + ((client->clientState == ClientStateGone) || + (client->clientState == ClientStateRetained))) { + XDGAModeRec mode; + PixmapPtr pPix; + + DGA_SETCLIENT(i, NULL); + DGASelectInput(i, NULL, 0); + DGASetMode(i, 0, &mode, &pPix); + + if(--DGACallbackRefCount == 0) + DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL); + } +} + +static int +ProcXDGASetMode(ClientPtr client) +{ + REQUEST(xXDGASetModeReq); + xXDGASetModeReply rep; + XDGAModeRec mode; + xXDGAModeInfo info; + PixmapPtr pPix; + ClientPtr owner; + int size; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + owner = DGA_GETCLIENT(stuff->screen); + + REQUEST_SIZE_MATCH(xXDGASetModeReq); + rep.type = X_Reply; + rep.length = 0; + rep.offset = 0; + rep.flags = 0; + rep.sequenceNumber = client->sequence; + + if (!DGAAvailable(stuff->screen)) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + if(owner && owner != client) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + if(!stuff->mode) { + if(owner) { + if(--DGACallbackRefCount == 0) + DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL); + } + DGA_SETCLIENT(stuff->screen, NULL); + DGASelectInput(stuff->screen, NULL, 0); + DGASetMode(stuff->screen, 0, &mode, &pPix); + WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep); + return Success; + } + + if(Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix)) + return BadValue; + + if(!owner) { + if(DGACallbackRefCount++ == 0) + AddCallback (&ClientStateCallback, DGAClientStateChange, NULL); + } + + DGA_SETCLIENT(stuff->screen, client); + + if(pPix) { + if(AddResource(stuff->pid, RT_PIXMAP, (pointer)(pPix))) { + pPix->drawable.id = (int)stuff->pid; + rep.flags = DGA_PIXMAP_AVAILABLE; + } + } + + size = strlen(mode.name) + 1; + + info.byte_order = mode.byteOrder; + info.depth = mode.depth; + info.num = mode.num; + info.bpp = mode.bitsPerPixel; + info.name_size = (size + 3) & ~3L; + info.vsync_num = mode.VSync_num; + info.vsync_den = mode.VSync_den; + info.flags = mode.flags; + info.image_width = mode.imageWidth; + info.image_height = mode.imageHeight; + info.pixmap_width = mode.pixmapWidth; + info.pixmap_height = mode.pixmapHeight; + info.bytes_per_scanline = mode.bytesPerScanline; + info.red_mask = mode.red_mask; + info.green_mask = mode.green_mask; + info.blue_mask = mode.blue_mask; + info.visual_class = mode.visualClass; + info.viewport_width = mode.viewportWidth; + info.viewport_height = mode.viewportHeight; + info.viewport_xstep = mode.xViewportStep; + info.viewport_ystep = mode.yViewportStep; + info.viewport_xmax = mode.maxViewportX; + info.viewport_ymax = mode.maxViewportY; + info.viewport_flags = mode.viewportFlags; + info.reserved1 = mode.reserved1; + info.reserved2 = mode.reserved2; + + rep.length = bytes_to_int32(sz_xXDGAModeInfo + info.name_size); + + WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep); + WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info)); + WriteToClient(client, size, mode.name); + + return Success; +} + +static int +ProcXDGASetViewport(ClientPtr client) +{ + REQUEST(xXDGASetViewportReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if(DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXDGASetViewportReq); + + DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags); + + return Success; +} + +static int +ProcXDGAInstallColormap(ClientPtr client) +{ + ColormapPtr cmap; + int rc; + REQUEST(xXDGAInstallColormapReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if(DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXDGAInstallColormapReq); + + rc = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, RT_COLORMAP, + client, DixInstallAccess); + if (rc != Success) + return rc; + DGAInstallCmap(cmap); + return Success; +} + + +static int +ProcXDGASelectInput(ClientPtr client) +{ + REQUEST(xXDGASelectInputReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if(DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXDGASelectInputReq); + + if(DGA_GETCLIENT(stuff->screen) == client) + DGASelectInput(stuff->screen, client, stuff->mask); + + return Success; +} + + +static int +ProcXDGAFillRectangle(ClientPtr client) +{ + REQUEST(xXDGAFillRectangleReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if(DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXDGAFillRectangleReq); + + if(Success != DGAFillRect(stuff->screen, stuff->x, stuff->y, + stuff->width, stuff->height, stuff->color)) + return BadMatch; + + return Success; +} + +static int +ProcXDGACopyArea(ClientPtr client) +{ + REQUEST(xXDGACopyAreaReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if(DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXDGACopyAreaReq); + + if(Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy, + stuff->width, stuff->height, stuff->dstx, stuff->dsty)) + return BadMatch; + + return Success; +} + + +static int +ProcXDGACopyTransparentArea(ClientPtr client) +{ + REQUEST(xXDGACopyTransparentAreaReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if(DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq); + + if(Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy, + stuff->width, stuff->height, stuff->dstx, stuff->dsty, stuff->key)) + return BadMatch; + + return Success; +} + + +static int +ProcXDGAGetViewportStatus(ClientPtr client) +{ + REQUEST(xXDGAGetViewportStatusReq); + xXDGAGetViewportStatusReply rep; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if(DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rep.status = DGAGetViewportStatus(stuff->screen); + + WriteToClient(client, sizeof(xXDGAGetViewportStatusReply), (char *)&rep); + return Success; +} + +static int +ProcXDGASync(ClientPtr client) +{ + REQUEST(xXDGASyncReq); + xXDGASyncReply rep; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if(DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXDGASyncReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + DGASync(stuff->screen); + + WriteToClient(client, sizeof(xXDGASyncReply), (char *)&rep); + return Success; +} + +static int +ProcXDGASetClientVersion(ClientPtr client) +{ + REQUEST(xXDGASetClientVersionReq); + + DGAPrivPtr pPriv; + + REQUEST_SIZE_MATCH(xXDGASetClientVersionReq); + if ((pPriv = DGA_GETPRIV(client)) == NULL) { + pPriv = malloc(sizeof(DGAPrivRec)); + /* XXX Need to look into freeing this */ + if (!pPriv) + return BadAlloc; + DGA_SETPRIV(client, pPriv); + } + pPriv->major = stuff->major; + pPriv->minor = stuff->minor; + + return Success; +} + +static int +ProcXDGAChangePixmapMode(ClientPtr client) +{ + REQUEST(xXDGAChangePixmapModeReq); + xXDGAChangePixmapModeReply rep; + int x, y; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if(DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + x = stuff->x; + y = stuff->y; + + if(!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags)) + return BadMatch; + + rep.x = x; + rep.y = y; + WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *)&rep); + + return Success; +} + + +static int +ProcXDGACreateColormap(ClientPtr client) +{ + REQUEST(xXDGACreateColormapReq); + int result; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if(DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXDGACreateColormapReq); + + if(!stuff->mode) + return BadValue; + + result = DGACreateColormap(stuff->screen, client, stuff->id, + stuff->mode, stuff->alloc); + if(result != Success) + return result; + + return Success; +} + +/* + * + * Support for the old DGA protocol, used to live in xf86dga.c + * + */ + +#ifdef DGA_PROTOCOL_OLD_SUPPORT + + + +static int +ProcXF86DGAGetVideoLL(ClientPtr client) +{ + REQUEST(xXF86DGAGetVideoLLReq); + xXF86DGAGetVideoLLReply rep; + XDGAModeRec mode; + int num, offset, flags; + char *name; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if(!DGAAvailable(stuff->screen)) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + if(!(num = DGAGetOldDGAMode(stuff->screen))) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + /* get the parameters for the mode that best matches */ + DGAGetModeInfo(stuff->screen, &mode, num); + + if(!DGAOpenFramebuffer(stuff->screen, &name, + (unsigned char**)(&rep.offset), + (int*)(&rep.bank_size), &offset, &flags)) + return BadAlloc; + + rep.offset += mode.offset; + rep.width = mode.bytesPerScanline / (mode.bitsPerPixel >> 3); + rep.ram_size = rep.bank_size >> 10; + + WriteToClient(client, SIZEOF(xXF86DGAGetVideoLLReply), (char *)&rep); + return Success; +} + +static int +ProcXF86DGADirectVideo(ClientPtr client) +{ + int num; + PixmapPtr pix; + XDGAModeRec mode; + ClientPtr owner; + REQUEST(xXF86DGADirectVideoReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq); + + if (!DGAAvailable(stuff->screen)) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + owner = DGA_GETCLIENT(stuff->screen); + + if (owner && owner != client) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + if (stuff->enable & XF86DGADirectGraphics) { + if(!(num = DGAGetOldDGAMode(stuff->screen))) + return DGAErrorBase + XF86DGANoDirectVideoMode; + } else + num = 0; + + if(Success != DGASetMode(stuff->screen, num, &mode, &pix)) + return DGAErrorBase + XF86DGAScreenNotActive; + + DGASetInputMode (stuff->screen, + (stuff->enable & XF86DGADirectKeyb) != 0, + (stuff->enable & XF86DGADirectMouse) != 0); + + /* We need to track the client and attach the teardown callback */ + if (stuff->enable & + (XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) { + if (!owner) { + if (DGACallbackRefCount++ == 0) + AddCallback (&ClientStateCallback, DGAClientStateChange, NULL); + } + + DGA_SETCLIENT(stuff->screen, client); + } else { + if (owner) { + if (--DGACallbackRefCount == 0) + DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL); + } + + DGA_SETCLIENT(stuff->screen, NULL); + } + + return Success; +} + +static int +ProcXF86DGAGetViewPortSize(ClientPtr client) +{ + int num; + XDGAModeRec mode; + REQUEST(xXF86DGAGetViewPortSizeReq); + xXF86DGAGetViewPortSizeReply rep; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if (!DGAAvailable(stuff->screen)) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + if(!(num = DGAGetOldDGAMode(stuff->screen))) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + DGAGetModeInfo(stuff->screen, &mode, num); + + rep.width = mode.viewportWidth; + rep.height = mode.viewportHeight; + + WriteToClient(client, SIZEOF(xXF86DGAGetViewPortSizeReply), (char *)&rep); + return Success; +} + +static int +ProcXF86DGASetViewPort(ClientPtr client) +{ + REQUEST(xXF86DGASetViewPortReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if (DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq); + + if (!DGAAvailable(stuff->screen)) + return DGAErrorBase + XF86DGANoDirectVideoMode; + + if (!DGAActive(stuff->screen)) + return DGAErrorBase + XF86DGADirectNotActivated; + + if (DGASetViewport(stuff->screen, stuff->x, stuff->y, DGA_FLIP_RETRACE) + != Success) + return DGAErrorBase + XF86DGADirectNotActivated; + + return Success; +} + +static int +ProcXF86DGAGetVidPage(ClientPtr client) +{ + REQUEST(xXF86DGAGetVidPageReq); + xXF86DGAGetVidPageReply rep; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.vpage = 0; /* silently fail */ + + WriteToClient(client, SIZEOF(xXF86DGAGetVidPageReply), (char *)&rep); + return Success; +} + + +static int +ProcXF86DGASetVidPage(ClientPtr client) +{ + REQUEST(xXF86DGASetVidPageReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq); + + /* silently fail */ + + return Success; +} + + +static int +ProcXF86DGAInstallColormap(ClientPtr client) +{ + ColormapPtr pcmp; + int rc; + REQUEST(xXF86DGAInstallColormapReq); + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if (DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq); + + if (!DGAActive(stuff->screen)) + return DGAErrorBase + XF86DGADirectNotActivated; + + rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, + client, DixInstallAccess); + if (rc == Success) { + DGAInstallCmap(pcmp); + return Success; + } else { + return rc; + } +} + +static int +ProcXF86DGAQueryDirectVideo(ClientPtr client) +{ + REQUEST(xXF86DGAQueryDirectVideoReq); + xXF86DGAQueryDirectVideoReply rep; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.flags = 0; + + if (DGAAvailable(stuff->screen)) + rep.flags = XF86DGADirectPresent; + + WriteToClient(client, SIZEOF(xXF86DGAQueryDirectVideoReply), (char *)&rep); + return Success; +} + +static int +ProcXF86DGAViewPortChanged(ClientPtr client) +{ + REQUEST(xXF86DGAViewPortChangedReq); + xXF86DGAViewPortChangedReply rep; + + if (stuff->screen >= screenInfo.numScreens) + return BadValue; + + if (DGA_GETCLIENT(stuff->screen) != client) + return DGAErrorBase + XF86DGADirectNotActivated; + + REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq); + + if (!DGAActive(stuff->screen)) + return DGAErrorBase + XF86DGADirectNotActivated; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.result = 1; + + WriteToClient(client, SIZEOF(xXF86DGAViewPortChangedReply), (char *)&rep); + return Success; +} + +#endif /* DGA_PROTOCOL_OLD_SUPPORT */ + +static int +SProcXDGADispatch (ClientPtr client) +{ + return DGAErrorBase + XF86DGAClientNotLocal; +} + +#if 0 +#define DGA_REQ_DEBUG +#endif + +#ifdef DGA_REQ_DEBUG +static char *dgaMinor[] = { + "QueryVersion", + "GetVideoLL", + "DirectVideo", + "GetViewPortSize", + "SetViewPort", + "GetVidPage", + "SetVidPage", + "InstallColormap", + "QueryDirectVideo", + "ViewPortChanged", + "10", + "11", + "QueryModes", + "SetMode", + "SetViewport", + "InstallColormap", + "SelectInput", + "FillRectangle", + "CopyArea", + "CopyTransparentArea", + "GetViewportStatus", + "Sync", + "OpenFramebuffer", + "CloseFramebuffer", + "SetClientVersion", + "ChangePixmapMode", + "CreateColormap", +}; +#endif + +static int +ProcXDGADispatch (ClientPtr client) +{ + REQUEST(xReq); + + if (!client->local) + return DGAErrorBase + XF86DGAClientNotLocal; + +#ifdef DGA_REQ_DEBUG + if (stuff->data <= X_XDGACreateColormap) + fprintf (stderr, " DGA %s\n", dgaMinor[stuff->data]); +#endif + + switch (stuff->data){ + /* + * DGA2 Protocol + */ + case X_XDGAQueryVersion: + return ProcXDGAQueryVersion(client); + case X_XDGAQueryModes: + return ProcXDGAQueryModes(client); + case X_XDGASetMode: + return ProcXDGASetMode(client); + case X_XDGAOpenFramebuffer: + return ProcXDGAOpenFramebuffer(client); + case X_XDGACloseFramebuffer: + return ProcXDGACloseFramebuffer(client); + case X_XDGASetViewport: + return ProcXDGASetViewport(client); + case X_XDGAInstallColormap: + return ProcXDGAInstallColormap(client); + case X_XDGASelectInput: + return ProcXDGASelectInput(client); + case X_XDGAFillRectangle: + return ProcXDGAFillRectangle(client); + case X_XDGACopyArea: + return ProcXDGACopyArea(client); + case X_XDGACopyTransparentArea: + return ProcXDGACopyTransparentArea(client); + case X_XDGAGetViewportStatus: + return ProcXDGAGetViewportStatus(client); + case X_XDGASync: + return ProcXDGASync(client); + case X_XDGASetClientVersion: + return ProcXDGASetClientVersion(client); + case X_XDGAChangePixmapMode: + return ProcXDGAChangePixmapMode(client); + case X_XDGACreateColormap: + return ProcXDGACreateColormap(client); + /* + * Old DGA Protocol + */ +#ifdef DGA_PROTOCOL_OLD_SUPPORT + case X_XF86DGAGetVideoLL: + return ProcXF86DGAGetVideoLL(client); + case X_XF86DGADirectVideo: + return ProcXF86DGADirectVideo(client); + case X_XF86DGAGetViewPortSize: + return ProcXF86DGAGetViewPortSize(client); + case X_XF86DGASetViewPort: + return ProcXF86DGASetViewPort(client); + case X_XF86DGAGetVidPage: + return ProcXF86DGAGetVidPage(client); + case X_XF86DGASetVidPage: + return ProcXF86DGASetVidPage(client); + case X_XF86DGAInstallColormap: + return ProcXF86DGAInstallColormap(client); + case X_XF86DGAQueryDirectVideo: + return ProcXF86DGAQueryDirectVideo(client); + case X_XF86DGAViewPortChanged: + return ProcXF86DGAViewPortChanged(client); +#endif /* DGA_PROTOCOL_OLD_SUPPORT */ + default: + return BadRequest; + } +} + +void +XFree86DGARegister(INITARGS) +{ + XDGAEventBase = &DGAEventBase; +} + +void +XFree86DGAExtensionInit(INITARGS) +{ + ExtensionEntry* extEntry; + + if (!dixRegisterPrivateKey(&DGAClientPrivateKeyRec, PRIVATE_CLIENT, 0)) + return; + + if (!dixRegisterPrivateKey(&DGAScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) + return; + + if ((extEntry = AddExtension(XF86DGANAME, + XF86DGANumberEvents, + XF86DGANumberErrors, + ProcXDGADispatch, + SProcXDGADispatch, + XDGAResetProc, + StandardMinorOpcode))) { + int i; + + DGAReqCode = (unsigned char)extEntry->base; + DGAErrorBase = extEntry->errorBase; + DGAEventBase = extEntry->eventBase; + for (i = KeyPress; i <= MotionNotify; i++) + SetCriticalEvent (DGAEventBase + i); + } +} diff --git a/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c b/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c index 6d3d5fcbc..6e5e3f94c 100644 --- a/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c +++ b/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c @@ -1527,7 +1527,7 @@ ProcXF86VidModeGetPermissions(ClientPtr client) rep.sequenceNumber = client->sequence; rep.permissions = XF86VM_READ_PERMISSION; if (xf86GetVidModeEnabled() && - (xf86GetVidModeAllowNonLocal() || LocalClient (client))) { + (xf86GetVidModeAllowNonLocal() || client->local)) { rep.permissions |= XF86VM_WRITE_PERMISSION; } if(client->swapped) { @@ -1597,7 +1597,7 @@ ProcXF86VidModeDispatch(ClientPtr client) default: if (!xf86GetVidModeEnabled()) return VidModeErrorBase + XF86VidModeExtensionDisabled; - if (xf86GetVidModeAllowNonLocal() || LocalClient (client)) { + if (xf86GetVidModeAllowNonLocal() || client->local) { switch (stuff->data) { case X_XF86VidModeAddModeLine: return ProcXF86VidModeAddModeLine(client); @@ -2017,7 +2017,7 @@ SProcXF86VidModeDispatch(ClientPtr client) default: if (!xf86GetVidModeEnabled()) return VidModeErrorBase + XF86VidModeExtensionDisabled; - if (xf86GetVidModeAllowNonLocal() || LocalClient(client)) { + if (xf86GetVidModeAllowNonLocal() || client->local) { switch (stuff->data) { case X_XF86VidModeAddModeLine: return SProcXF86VidModeAddModeLine(client); diff --git a/xorg-server/hw/xfree86/dri/xf86dri.c b/xorg-server/hw/xfree86/dri/xf86dri.c index c35ba2f94..723e52622 100644 --- a/xorg-server/hw/xfree86/dri/xf86dri.c +++ b/xorg-server/hw/xfree86/dri/xf86dri.c @@ -130,7 +130,7 @@ ProcXF86DRIQueryDirectRenderingCapable( } rep.isCapable = isCapable; - if (!LocalClient(client) || client->swapped) + if (!client->local || client->swapped) rep.isCapable = 0; if (client->swapped) { @@ -557,7 +557,7 @@ ProcXF86DRIDispatch ( return ProcXF86DRIQueryDirectRenderingCapable(client); } - if (!LocalClient(client)) + if (!client->local) return DRIErrorBase + XF86DRIClientNotLocal; switch (stuff->data) diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c index 73ef7f25e..21331559f 100644 --- a/xorg-server/hw/xfree86/dri2/dri2ext.c +++ b/xorg-server/hw/xfree86/dri2/dri2ext.c @@ -547,7 +547,7 @@ ProcDRI2Dispatch (ClientPtr client) return ProcDRI2QueryVersion(client); } - if (!LocalClient(client)) + if (!client->local) return BadRequest; switch (stuff->data) { diff --git a/xorg-server/hw/xfree86/loader/loadmod.c b/xorg-server/hw/xfree86/loader/loadmod.c index 5b9f8d1c3..5b9c11950 100644 --- a/xorg-server/hw/xfree86/loader/loadmod.c +++ b/xorg-server/hw/xfree86/loader/loadmod.c @@ -1090,6 +1090,9 @@ UnloadSubModule(pointer _mod) { ModuleDescPtr mod = (ModuleDescPtr)_mod; + /* Some drivers are calling us on built-in submodules, ignore them */ + if (mod == (ModuleDescPtr)1) + return; RemoveChild(mod); UnloadModuleOrDriver(mod); } diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_init.c b/xorg-server/hw/xfree86/os-support/linux/lnx_init.c index 5f3e3a9fb..2176985f9 100644 --- a/xorg-server/hw/xfree86/os-support/linux/lnx_init.c +++ b/xorg-server/hw/xfree86/os-support/linux/lnx_init.c @@ -212,10 +212,20 @@ xf86OpenConsole(void) tcgetattr(xf86Info.consoleFd, &tty_attr); SYSCALL(ioctl(xf86Info.consoleFd, KDGKBMODE, &tty_mode)); - SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW)); +#ifdef K_OFF + /* disable kernel special keys and buffering */ + SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSKBMODE, K_OFF)); if (ret < 0) - FatalError("xf86OpenConsole: KDSKBMODE K_RAW failed %s\n", - strerror(errno)); +#endif + { + SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW)); + if (ret < 0) + FatalError("xf86OpenConsole: KDSKBMODE K_RAW failed %s\n", + strerror(errno)); + + /* need to keep the buffer clean, else the kernel gets angry */ + xf86SetConsoleHandler(drain_console, NULL); + } nTty = tty_attr; nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP); @@ -228,9 +238,6 @@ xf86OpenConsole(void) cfsetospeed(&nTty, 9600); tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty); - /* need to keep the buffer clean, else the kernel gets angry */ - xf86SetConsoleHandler(drain_console, NULL); - /* we really should have a InitOSInputDevices() function instead * of Init?$#*&Device(). So I just place it here */ } diff --git a/xorg-server/hw/xfree86/vgahw/vgaHW.h b/xorg-server/hw/xfree86/vgahw/vgaHW.h index e943aa391..d1ba9da89 100644 --- a/xorg-server/hw/xfree86/vgahw/vgaHW.h +++ b/xorg-server/hw/xfree86/vgahw/vgaHW.h @@ -170,10 +170,10 @@ typedef struct _vgaHWRec { #define BITS_PER_GUN 6 #define COLORMAP_SIZE 256 -#define DACDelay(hw) \ - do { \ - pci_io_read8((hw)->io, (hw)->IOBase + VGA_IN_STAT_1_OFFSET); \ - pci_io_read8((hw)->io, (hw)->IOBase + VGA_IN_STAT_1_OFFSET); \ +#define DACDelay(hw) \ + do { \ + (hw)->readST01((hw)); \ + (hw)->readST01((hw)); \ } while (0) /* Function Prototypes */ diff --git a/xorg-server/hw/xfree86/xaa/Makefile.am b/xorg-server/hw/xfree86/xaa/Makefile.am index 7ebe0b91e..78d934876 100644 --- a/xorg-server/hw/xfree86/xaa/Makefile.am +++ b/xorg-server/hw/xfree86/xaa/Makefile.am @@ -8,6 +8,8 @@ MSB_FIXED = mf-xaaBitmap.c mf-xaaStipple.c mf-xaaTEGlyph.c MSB_3_FIXED = mf3-xaaBitmap.c mf3-xaaStipple.c POLYSEG = s-xaaLine.c s-xaaDashLine.c +if XAA + libxaa_la_LDFLAGS = -module -avoid-version if COMPOSITE libxaa_la_LIBADD = $(top_builddir)/miext/cw/libcw.la @@ -60,6 +62,8 @@ ${MSB_3_FIXED}: $(AM_V_GEN)echo "#define FIXEDBASE" >> $@ $(AM_V_GEN)echo '#include "$(srcdir)/${@:mf3-%=%}"' >> $@ +endif # XAA + DISTCLEANFILES = $(POLYSEG) \ $(LSB_FIRST) $(LSB_FIXED) $(MSB_FIRST) $(MSB_FIXED) \ $(LSB_3_FIRST) $(LSB_3_FIXED) $(MSB_3_FIRST) $(MSB_3_FIXED) diff --git a/xorg-server/hw/xquartz/GL/indirect.c b/xorg-server/hw/xquartz/GL/indirect.c index 27d6daebd..e6ff37668 100644 --- a/xorg-server/hw/xquartz/GL/indirect.c +++ b/xorg-server/hw/xquartz/GL/indirect.c @@ -48,9 +48,6 @@ #include <glxserver.h> #include <glxutil.h> -typedef unsigned long long GLuint64EXT; -typedef long long GLint64EXT; -#include <dispatch.h> #include <glapi.h> #include "x-hash.h" diff --git a/xorg-server/hw/xquartz/applewm.c b/xorg-server/hw/xquartz/applewm.c index 55976c454..7077a6c6a 100644 --- a/xorg-server/hw/xquartz/applewm.c +++ b/xorg-server/hw/xquartz/applewm.c @@ -630,7 +630,7 @@ ProcAppleWMDispatch ( return ProcAppleWMQueryVersion(client); } - if (!LocalClient(client)) + if (!client->local) return WMErrorBase + AppleWMClientNotLocal; switch (stuff->data) @@ -693,7 +693,7 @@ SProcAppleWMDispatch ( REQUEST(xReq); /* It is bound to be non-local when there is byte swapping */ - if (!LocalClient(client)) + if (!client->local) return WMErrorBase + AppleWMClientNotLocal; /* only local clients are allowed WM access */ diff --git a/xorg-server/hw/xquartz/xpr/appledri.c b/xorg-server/hw/xquartz/xpr/appledri.c index 44c132abc..091145be3 100644 --- a/xorg-server/hw/xquartz/xpr/appledri.c +++ b/xorg-server/hw/xquartz/xpr/appledri.c @@ -133,7 +133,7 @@ ProcAppleDRIQueryDirectRenderingCapable( } rep.isCapable = isCapable; - if (!LocalClient(client)) + if (!client->local) rep.isCapable = 0; if (client->swapped) { @@ -365,7 +365,7 @@ ProcAppleDRIDispatch ( return ProcAppleDRIQueryDirectRenderingCapable(client); } - if (!LocalClient(client)) + if (!client->local) return DRIErrorBase + AppleDRIClientNotLocal; switch (stuff->data) diff --git a/xorg-server/hw/xwin/Makefile.am b/xorg-server/hw/xwin/Makefile.am index 70f6cf7a6..f593ac12f 100644 --- a/xorg-server/hw/xwin/Makefile.am +++ b/xorg-server/hw/xwin/Makefile.am @@ -176,7 +176,8 @@ install-exec-hook: EXTRA_DIST = \ $(xwinconfig_DATA) \ X.ico \ - XWin.rc + XWin.rc \ + XWin.exe.manifest relink: $(AM_V_at)rm -f XWin$(EXEEXT) && $(MAKE) XWin$(EXEEXT) diff --git a/xorg-server/hw/xwin/winclipboard.h b/xorg-server/hw/xwin/winclipboard.h index e55f6023d..41acfecce 100644 --- a/xorg-server/hw/xwin/winclipboard.h +++ b/xorg-server/hw/xwin/winclipboard.h @@ -41,7 +41,6 @@ #include <sys/select.h> #else #include <X11/Xwinsock.h> -#define HAS_WINSOCK #endif #include <fcntl.h> #include <setjmp.h> diff --git a/xorg-server/hw/xwin/winclipboardthread.c b/xorg-server/hw/xwin/winclipboardthread.c index 6a076a4d3..c160453c8 100644 --- a/xorg-server/hw/xwin/winclipboardthread.c +++ b/xorg-server/hw/xwin/winclipboardthread.c @@ -1,525 +1,527 @@ -/*
- *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II BE LIABLE FOR
- *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- *Except as contained in this notice, the name of the copyright holder(s)
- *and author(s) shall not be used in advertising or otherwise to promote
- *the sale, use or other dealings in this Software without prior written
- *authorization from the copyright holder(s) and author(s).
- *
- * Authors: Harold L Hunt II
- * Colin Harrison
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include <sys/types.h>
-#include "winclipboard.h"
-#ifdef __CYGWIN__
-#include <errno.h>
-#endif
-#include "misc.h"
-#include "winmsg.h"
-
-#ifdef _MSC_VER
-#define snprintf _snprintf
-#endif
-
-/*
- * References to external symbols
- */
-
-extern Bool g_fUnicodeClipboard;
-extern unsigned long serverGeneration;
-extern Bool g_fClipboardLaunched;
-extern Bool g_fClipboardStarted;
-extern HWND g_hwndClipboard;
-extern void *g_pClipboardDisplay;
-extern Window g_iClipboardWindow;
-extern Bool g_fClipboardPrimary;
-
-
-/*
- * Global variables
- */
-
-static jmp_buf g_jmpEntry;
-static XIOErrorHandler g_winClipboardOldIOErrorHandler;
-static pthread_t g_winClipboardProcThread;
-
-Bool g_fUnicodeSupport = FALSE;
-Bool g_fUseUnicode = FALSE;
-
-
-/*
- * Local function prototypes
- */
-
-static int
-winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr);
-
-static int
-winClipboardIOErrorHandler (Display *pDisplay);
-
-static void
-winClipboardThreadExit(void *arg);
-
-/*
- * Main thread function
- */
-
-void *
-winClipboardProc (void *pvNotUsed)
-{
- Atom atomClipboard, atomClipboardManager;
- int iReturn;
- HWND hwnd = NULL;
- int iConnectionNumber = 0;
-#ifdef HAS_DEVWINDOWS
- int fdMessageQueue = 0;
-#else
- struct timeval tvTimeout;
-#endif
- fd_set fdsRead;
- int iMaxDescriptor;
- Display *pDisplay = NULL;
- Window iWindow = None;
- int iRetries;
- Bool fUseUnicode;
- char szDisplay[512];
- int iSelectError;
-
- pthread_cleanup_push(&winClipboardThreadExit, NULL);
-
- winDebug ("winClipboardProc - Hello\n");
-
- /* Do we have Unicode support? */
- g_fUnicodeSupport = winClipboardDetectUnicodeSupport ();
-
- /* Do we use Unicode clipboard? */
- fUseUnicode = g_fUnicodeClipboard && g_fUnicodeSupport;
-
- /* Save the Unicode support flag in a global */
- g_fUseUnicode = fUseUnicode;
-
- /* Create Windows messaging window */
- hwnd = winClipboardCreateMessagingWindow ();
-
- /* Save copy of HWND in screen privates */
- g_hwndClipboard = hwnd;
-
- /* Set error handler */
- XSetErrorHandler (winClipboardErrorHandler);
- g_winClipboardProcThread = pthread_self();
- g_winClipboardOldIOErrorHandler = XSetIOErrorHandler (winClipboardIOErrorHandler);
-
- /* Set jump point for Error exits */
- iReturn = setjmp (g_jmpEntry);
-
- /* Check if we should continue operations */
- if (iReturn != WIN_JMP_ERROR_IO
- && iReturn != WIN_JMP_OKAY)
- {
- /* setjmp returned an unknown value, exit */
- ErrorF ("winClipboardProc - setjmp returned: %d exiting\n",
- iReturn);
- goto thread_errorexit;
- }
- else if (iReturn == WIN_JMP_ERROR_IO)
- {
- /* TODO: Cleanup the Win32 window and free any allocated memory */
- ErrorF ("winClipboardProc - setjmp returned for IO Error Handler.\n");
- //goto thread_errorexit;
- }
-
- /* Use our generated cookie for authentication */
- winSetAuthorization();
-
- /* Initialize retry count */
- iRetries = 0;
-
- /* Setup the display connection string x */
- /*
- * NOTE: Always connect to screen 0 since we require that screen
- * numbers start at 0 and increase without gaps. We only need
- * to connect to one screen on the display to get events
- * for all screens on the display. That is why there is only
- * one clipboard client thread.
- */
- winGetDisplayName(szDisplay,0);
-
- /* Print the display connection string */
- winDebug ("winClipboardProc - DISPLAY=%s\n", szDisplay);
-
- /* Open the X display */
- do
- {
- pDisplay = XOpenDisplay (szDisplay);
- if (pDisplay == NULL)
- {
- ErrorF ("winClipboardProc - Could not open display, "
- "try: %d, sleeping: %d\n",
- iRetries + 1, WIN_CONNECT_DELAY);
- ++iRetries;
- sleep (WIN_CONNECT_DELAY);
- continue;
- }
- else
- break;
- }
- while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
-
- /* Make sure that the display opened */
- if (pDisplay == NULL)
- {
- ErrorF ("winClipboardProc - Failed opening the display, giving up\n");
- goto thread_errorexit;
- }
-
- /* Save the display in the screen privates */
- g_pClipboardDisplay = pDisplay;
-
- winDebug ("winClipboardProc - XOpenDisplay () returned and "
- "successfully opened the display.\n");
-
- /* Get our connection number */
- iConnectionNumber = ConnectionNumber (pDisplay);
-
- winDebug("Clipboard is using socket %d\n",iConnectionNumber);
-
-#ifdef HAS_DEVWINDOWS
- /* Open a file descriptor for the windows message queue */
- fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, _O_RDONLY);
- if (fdMessageQueue == -1)
- {
- ErrorF ("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME);
- goto thread_errorexit;
- }
-
- /* Find max of our file descriptors */
- iMaxDescriptor = max (fdMessageQueue, iConnectionNumber) + 1;
-#else
- iMaxDescriptor = iConnectionNumber + 1;
-#endif
-
- /* Create atoms */
- atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False);
- atomClipboardManager = XInternAtom (pDisplay, "CLIPBOARD_MANAGER", False);
- XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False);
- XInternAtom (pDisplay, "UTF8_STRING", False);
- XInternAtom (pDisplay, "COMPOUND_TEXT", False);
- XInternAtom (pDisplay, "TARGETS", False);
-
- /* Create a messaging window */
- iWindow = XCreateSimpleWindow (pDisplay,
- DefaultRootWindow (pDisplay),
- 1, 1,
- 500, 500,
- 0,
- BlackPixel (pDisplay, 0),
- BlackPixel (pDisplay, 0));
- if (iWindow == 0)
- {
- ErrorF ("winClipboardProc - Could not create an X window.\n");
- goto thread_errorexit;
- }
-
- XStoreName(pDisplay, iWindow, "xwinclip");
-
- /* Select event types to watch */
- if (XSelectInput (pDisplay,
- iWindow,
- PropertyChangeMask) == BadWindow)
- ErrorF ("winClipboardProc - XSelectInput generated BadWindow "
- "on messaging window\n");
-
- /* Save the window in the screen privates */
- g_iClipboardWindow = iWindow;
-
- /* Assert ownership of selections if Win32 clipboard is owned */
- if (NULL != GetClipboardOwner ())
- {
- if (g_fClipboardPrimary)
- {
- /* PRIMARY */
- winDebug("winClipboardProc - asserted ownership.\n");
- iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY,
- iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow /*||
- XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow*/)
- {
- ErrorF ("winClipboardProc - Could not set PRIMARY owner\n");
- goto thread_errorexit;
- }
- }
-
- /* CLIPBOARD */
- iReturn = XSetSelectionOwner (pDisplay, atomClipboard,
- iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow /*||
- XGetSelectionOwner (pDisplay, atomClipboard) != iWindow*/)
- {
- ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n");
- goto thread_errorexit;
- }
- }
-
- /* Pre-flush X events */
- /*
- * NOTE: Apparently you'll freeze if you don't do this,
- * because there may be events in local data structures
- * already.
- */
- /*winClipboardFlushXEvents (hwnd,
- iWindow,
- pDisplay,
- fUseUnicode);
- */
- /* Pre-flush Windows messages */
- winDebug ("Start flushing \n");
- if (!winClipboardFlushWindowsMessageQueue (hwnd))
- {
- ErrorF ("winClipboardFlushWindowsMessageQueue - returned 0\n");
- goto thread_errorexit;
- }
-
- winDebug ("winClipboardProc - Started\n");
- /* Signal that the clipboard client has started */
- g_fClipboardStarted = TRUE;
-
- /* Loop for X events */
- while (1)
- {
- /* Setup the file descriptor set */
- /*
- * NOTE: You have to do this before every call to select
- * because select modifies the mask to indicate
- * which descriptors are ready.
- */
- FD_ZERO (&fdsRead);
- FD_SET (iConnectionNumber, &fdsRead);
-#ifdef HAS_DEVWINDOWS
- FD_SET (fdMessageQueue, &fdsRead);
-#else
- tvTimeout.tv_sec = 0;
- tvTimeout.tv_usec = 100;
-#endif
-
- /* Wait for a Windows event or an X event */
- iReturn = select (iMaxDescriptor, /* Highest fds number */
- &fdsRead, /* Read mask */
- NULL, /* No write mask */
- NULL, /* No exception mask */
-#ifdef HAS_DEVWINDOWS
- NULL /* No timeout */
-#else
- &tvTimeout /* Set timeout */
-#endif
- );
-
-#ifndef HAS_WINSOCK
- iSelectError = errno;
-#else
- iSelectError = WSAGetLastError();
-#endif
-
- if (iReturn < 0)
- {
-#ifndef HAS_WINSOCK
- if (iSelectError == EINTR)
-#else
- if (iSelectError == WSAEINTR)
-#endif
- continue;
-
- ErrorF ("winClipboardProc - Call to select () failed: %d. "
- "Bailing.\n", iReturn);
- break;
- }
-
- /* Branch on which descriptor became active */
-// if (FD_ISSET (iConnectionNumber, &fdsRead))
-// { Also do it when no read since winClipboardFlushXEvents
-// is sending the output.
- /* Process X events */
- /* Exit when we see that server is shutting down */
- iReturn = winClipboardFlushXEvents (hwnd,
- iWindow,
- pDisplay,
- fUseUnicode,
- FALSE
- );
- if (WIN_XEVENTS_SHUTDOWN == iReturn)
- {
- ErrorF ("winClipboardProc - winClipboardFlushXEvents "
- "trapped shutdown event, exiting main loop.\n");
- break;
- }
-// }
-
-#ifdef HAS_DEVWINDOWS
- /* Check for Windows event ready */
- if (FD_ISSET (fdMessageQueue, &fdsRead))
-#else
- if (1)
-#endif
- {
- /* Process Windows messages */
- if (!winClipboardFlushWindowsMessageQueue (hwnd))
- {
- ErrorF ("winClipboardProc - "
- "winClipboardFlushWindowsMessageQueue trapped "
- "WM_QUIT message, exiting main loop.\n");
- break;
- }
- }
- }
-
- /* Close our X window */
- if (pDisplay && iWindow)
- {
- iReturn = XDestroyWindow (pDisplay, iWindow);
- if (iReturn == BadWindow)
- ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n");
-#ifdef WINDBG
- else
- winDebug ("winClipboardProc - XDestroyWindow succeeded.\n");
-#endif
- }
-
-
-#ifdef HAS_DEVWINDOWS
- /* Close our Win32 message handle */
- if (fdMessageQueue)
- close (fdMessageQueue);
-#endif
-
-#if 0
- /*
- * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26. The
- * XSync and XSelectInput calls did not help.
- */
-
- /* Discard any remaining events */
- XSync (pDisplay, TRUE);
-
- /* Select event types to watch */
- XSelectInput (pDisplay,
- DefaultRootWindow (pDisplay),
- None);
-
- /* Close our X display */
- if (pDisplay)
- {
- XCloseDisplay (pDisplay);
- }
-#endif
-
- goto commonexit;
-
-thread_errorexit:
- if (g_pClipboardDisplay && g_iClipboardWindow)
- {
- iReturn = XDestroyWindow (g_pClipboardDisplay, g_iClipboardWindow);
- if (iReturn == BadWindow)
- ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n");
-#ifdef WINDBG
- else
- winDebug ("winClipboardProc - XDestroyWindow succeeded.\n");
-#endif
- }
- winDebug ("Clipboard thread died.\n");
-
-commonexit:
- g_iClipboardWindow = None;
- g_pClipboardDisplay = NULL;
- g_fClipboardLaunched = FALSE;
- g_fClipboardStarted = FALSE;
-
- pthread_cleanup_pop(0);
-
- return NULL;
-}
-
-
-/*
- * winClipboardErrorHandler - Our application specific error handler
- */
-
-static int
-winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr)
-{
- char pszErrorMsg[100];
-
- XGetErrorText (pDisplay,
- pErr->error_code,
- pszErrorMsg,
- sizeof (pszErrorMsg));
- ErrorF ("winClipboardErrorHandler - ERROR: \n\t%s\n"
- " errorCode %d\n"
- " serial %lu\n"
- " resourceID 0x%x\n"
- " majorCode %d\n"
- " minorCode %d\n"
- , pszErrorMsg
- , pErr->error_code
- , pErr->serial
- , pErr->resourceid
- , pErr->request_code
- , pErr->minor_code);
- return 0;
-}
-
-
-/*
- * winClipboardIOErrorHandler - Our application specific IO error handler
- */
-
-static int
-winClipboardIOErrorHandler (Display *pDisplay)
-{
- ErrorF ("winClipboardIOErrorHandler!\n\n");
-
- if (pthread_equal(pthread_self(),g_winClipboardProcThread))
- {
- /* Restart at the main entry point */
- longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
- }
-
- if (g_winClipboardOldIOErrorHandler)
- g_winClipboardOldIOErrorHandler(pDisplay);
-
- return 0;
-}
-
-/*
- * winClipboardThreadExit - Thread exit handler
- */
-
-static void
-winClipboardThreadExit(void *arg)
-{
- /* clipboard thread has exited, stop server as well */
- AbortDDX(EXIT_ERR_ABORT);
- TerminateProcess(GetCurrentProcess(),1);
-}
+/* + *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the copyright holder(s) + *and author(s) shall not be used in advertising or otherwise to promote + *the sale, use or other dealings in this Software without prior written + *authorization from the copyright holder(s) and author(s). + * + * Authors: Harold L Hunt II + * Colin Harrison + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#else +#define HAS_WINSOCK 1 +#endif +#include <sys/types.h> +#include "winclipboard.h" +#ifdef __CYGWIN__ +#include <errno.h> +#endif +#include "misc.h" +#include "winmsg.h" + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +/* + * References to external symbols + */ + +extern Bool g_fUnicodeClipboard; +extern unsigned long serverGeneration; +extern Bool g_fClipboardLaunched; +extern Bool g_fClipboardStarted; +extern HWND g_hwndClipboard; +extern void *g_pClipboardDisplay; +extern Window g_iClipboardWindow; +extern Bool g_fClipboardPrimary; + + +/* + * Global variables + */ + +static jmp_buf g_jmpEntry; +static XIOErrorHandler g_winClipboardOldIOErrorHandler; +static pthread_t g_winClipboardProcThread; + +Bool g_fUnicodeSupport = FALSE; +Bool g_fUseUnicode = FALSE; + + +/* + * Local function prototypes + */ + +static int +winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winClipboardIOErrorHandler (Display *pDisplay); + +static void +winClipboardThreadExit(void *arg); + +/* + * Main thread function + */ + +void * +winClipboardProc (void *pvNotUsed) +{ + Atom atomClipboard, atomClipboardManager; + int iReturn; + HWND hwnd = NULL; + int iConnectionNumber = 0; +#ifdef HAS_DEVWINDOWS + int fdMessageQueue = 0; +#else + struct timeval tvTimeout; +#endif + fd_set fdsRead; + int iMaxDescriptor; + Display *pDisplay = NULL; + Window iWindow = None; + int iRetries; + Bool fUseUnicode; + char szDisplay[512]; + int iSelectError; + + pthread_cleanup_push(&winClipboardThreadExit, NULL); + + winDebug ("winClipboardProc - Hello\n"); + + /* Do we have Unicode support? */ + g_fUnicodeSupport = winClipboardDetectUnicodeSupport (); + + /* Do we use Unicode clipboard? */ + fUseUnicode = g_fUnicodeClipboard && g_fUnicodeSupport; + + /* Save the Unicode support flag in a global */ + g_fUseUnicode = fUseUnicode; + + /* Create Windows messaging window */ + hwnd = winClipboardCreateMessagingWindow (); + + /* Save copy of HWND in screen privates */ + g_hwndClipboard = hwnd; + + /* Set error handler */ + XSetErrorHandler (winClipboardErrorHandler); + g_winClipboardProcThread = pthread_self(); + g_winClipboardOldIOErrorHandler = XSetIOErrorHandler (winClipboardIOErrorHandler); + + /* Set jump point for Error exits */ + iReturn = setjmp (g_jmpEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO + && iReturn != WIN_JMP_OKAY) + { + /* setjmp returned an unknown value, exit */ + ErrorF ("winClipboardProc - setjmp returned: %d exiting\n", + iReturn); + goto thread_errorexit; + } + else if (iReturn == WIN_JMP_ERROR_IO) + { + /* TODO: Cleanup the Win32 window and free any allocated memory */ + ErrorF ("winClipboardProc - setjmp returned for IO Error Handler.\n"); + //goto thread_errorexit; + } + + /* Use our generated cookie for authentication */ + winSetAuthorization(); + + /* Initialize retry count */ + iRetries = 0; + + /* Setup the display connection string x */ + /* + * NOTE: Always connect to screen 0 since we require that screen + * numbers start at 0 and increase without gaps. We only need + * to connect to one screen on the display to get events + * for all screens on the display. That is why there is only + * one clipboard client thread. + */ + winGetDisplayName(szDisplay,0); + + /* Print the display connection string */ + winDebug ("winClipboardProc - DISPLAY=%s\n", szDisplay); + + /* Open the X display */ + do + { + pDisplay = XOpenDisplay (szDisplay); + if (pDisplay == NULL) + { + ErrorF ("winClipboardProc - Could not open display, " + "try: %d, sleeping: %d\n", + iRetries + 1, WIN_CONNECT_DELAY); + ++iRetries; + sleep (WIN_CONNECT_DELAY); + continue; + } + else + break; + } + while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); + + /* Make sure that the display opened */ + if (pDisplay == NULL) + { + ErrorF ("winClipboardProc - Failed opening the display, giving up\n"); + goto thread_errorexit; + } + + /* Save the display in the screen privates */ + g_pClipboardDisplay = pDisplay; + + winDebug ("winClipboardProc - XOpenDisplay () returned and " + "successfully opened the display.\n"); + + /* Get our connection number */ + iConnectionNumber = ConnectionNumber (pDisplay); + + winDebug("Clipboard is using socket %d\n",iConnectionNumber); + +#ifdef HAS_DEVWINDOWS + /* Open a file descriptor for the windows message queue */ + fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, _O_RDONLY); + if (fdMessageQueue == -1) + { + ErrorF ("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME); + goto thread_errorexit; + } + + /* Find max of our file descriptors */ + iMaxDescriptor = max (fdMessageQueue, iConnectionNumber) + 1; +#else + iMaxDescriptor = iConnectionNumber + 1; +#endif + + /* Create atoms */ + atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False); + atomClipboardManager = XInternAtom (pDisplay, "CLIPBOARD_MANAGER", False); + XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False); + XInternAtom (pDisplay, "UTF8_STRING", False); + XInternAtom (pDisplay, "COMPOUND_TEXT", False); + XInternAtom (pDisplay, "TARGETS", False); + + /* Create a messaging window */ + iWindow = XCreateSimpleWindow (pDisplay, + DefaultRootWindow (pDisplay), + 1, 1, + 500, 500, + 0, + BlackPixel (pDisplay, 0), + BlackPixel (pDisplay, 0)); + if (iWindow == 0) + { + ErrorF ("winClipboardProc - Could not create an X window.\n"); + goto thread_errorexit; + } + + XStoreName(pDisplay, iWindow, "xwinclip"); + + /* Select event types to watch */ + if (XSelectInput (pDisplay, + iWindow, + PropertyChangeMask) == BadWindow) + ErrorF ("winClipboardProc - XSelectInput generated BadWindow " + "on messaging window\n"); + + /* Save the window in the screen privates */ + g_iClipboardWindow = iWindow; + + /* Assert ownership of selections if Win32 clipboard is owned */ + if (NULL != GetClipboardOwner ()) + { + if (g_fClipboardPrimary) + { + /* PRIMARY */ + winDebug("winClipboardProc - asserted ownership.\n"); + iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow /*|| + XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow*/) + { + ErrorF ("winClipboardProc - Could not set PRIMARY owner\n"); + goto thread_errorexit; + } + } + + /* CLIPBOARD */ + iReturn = XSetSelectionOwner (pDisplay, atomClipboard, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow /*|| + XGetSelectionOwner (pDisplay, atomClipboard) != iWindow*/) + { + ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n"); + goto thread_errorexit; + } + } + + /* Pre-flush X events */ + /* + * NOTE: Apparently you'll freeze if you don't do this, + * because there may be events in local data structures + * already. + */ + /*winClipboardFlushXEvents (hwnd, + iWindow, + pDisplay, + fUseUnicode); + */ + /* Pre-flush Windows messages */ + winDebug ("Start flushing \n"); + if (!winClipboardFlushWindowsMessageQueue (hwnd)) + { + ErrorF ("winClipboardFlushWindowsMessageQueue - returned 0\n"); + goto thread_errorexit; + } + + winDebug ("winClipboardProc - Started\n"); + /* Signal that the clipboard client has started */ + g_fClipboardStarted = TRUE; + + /* Loop for X events */ + while (1) + { + /* Setup the file descriptor set */ + /* + * NOTE: You have to do this before every call to select + * because select modifies the mask to indicate + * which descriptors are ready. + */ + FD_ZERO (&fdsRead); + FD_SET (iConnectionNumber, &fdsRead); +#ifdef HAS_DEVWINDOWS + FD_SET (fdMessageQueue, &fdsRead); +#else + tvTimeout.tv_sec = 0; + tvTimeout.tv_usec = 100; +#endif + + /* Wait for a Windows event or an X event */ + iReturn = select (iMaxDescriptor, /* Highest fds number */ + &fdsRead, /* Read mask */ + NULL, /* No write mask */ + NULL, /* No exception mask */ +#ifdef HAS_DEVWINDOWS + NULL /* No timeout */ +#else + &tvTimeout /* Set timeout */ +#endif + ); + +#ifndef HAS_WINSOCK + iSelectError = errno; +#else + iSelectError = WSAGetLastError(); +#endif + + if (iReturn < 0) + { +#ifndef HAS_WINSOCK + if (iSelectError == EINTR) +#else + if (iSelectError == WSAEINTR) +#endif + continue; + + ErrorF ("winClipboardProc - Call to select () failed: %d. " + "Bailing.\n", iReturn); + break; + } + + /* Branch on which descriptor became active */ +// if (FD_ISSET (iConnectionNumber, &fdsRead)) +// { Also do it when no read since winClipboardFlushXEvents +// is sending the output. + /* Process X events */ + /* Exit when we see that server is shutting down */ + iReturn = winClipboardFlushXEvents (hwnd, + iWindow, + pDisplay, + fUseUnicode, + FALSE + ); + if (WIN_XEVENTS_SHUTDOWN == iReturn) + { + ErrorF ("winClipboardProc - winClipboardFlushXEvents " + "trapped shutdown event, exiting main loop.\n"); + break; + } +// } + +#ifdef HAS_DEVWINDOWS + /* Check for Windows event ready */ + if (FD_ISSET (fdMessageQueue, &fdsRead)) +#else + if (1) +#endif + { + /* Process Windows messages */ + if (!winClipboardFlushWindowsMessageQueue (hwnd)) + { + ErrorF ("winClipboardProc - " + "winClipboardFlushWindowsMessageQueue trapped " + "WM_QUIT message, exiting main loop.\n"); + break; + } + } + } + + /* Close our X window */ + if (pDisplay && iWindow) + { + iReturn = XDestroyWindow (pDisplay, iWindow); + if (iReturn == BadWindow) + ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n"); +#ifdef WINDBG + else + winDebug ("winClipboardProc - XDestroyWindow succeeded.\n"); +#endif + } + + +#ifdef HAS_DEVWINDOWS + /* Close our Win32 message handle */ + if (fdMessageQueue) + close (fdMessageQueue); +#endif + +#if 0 + /* + * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26. The + * XSync and XSelectInput calls did not help. + */ + + /* Discard any remaining events */ + XSync (pDisplay, TRUE); + + /* Select event types to watch */ + XSelectInput (pDisplay, + DefaultRootWindow (pDisplay), + None); + + /* Close our X display */ + if (pDisplay) + { + XCloseDisplay (pDisplay); + } +#endif + + goto commonexit; + +thread_errorexit: + if (g_pClipboardDisplay && g_iClipboardWindow) + { + iReturn = XDestroyWindow (g_pClipboardDisplay, g_iClipboardWindow); + if (iReturn == BadWindow) + ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n"); +#ifdef WINDBG + else + winDebug ("winClipboardProc - XDestroyWindow succeeded.\n"); +#endif + } + winDebug ("Clipboard thread died.\n"); + +commonexit: + g_iClipboardWindow = None; + g_pClipboardDisplay = NULL; + g_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; + + pthread_cleanup_pop(0); + + return NULL; +} + + +/* + * winClipboardErrorHandler - Our application specific error handler + */ + +static int +winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("winClipboardErrorHandler - ERROR: \n\t%s\n" + " errorCode %d\n" + " serial %lu\n" + " resourceID 0x%x\n" + " majorCode %d\n" + " minorCode %d\n" + , pszErrorMsg + , pErr->error_code + , pErr->serial + , pErr->resourceid + , pErr->request_code + , pErr->minor_code); + return 0; +} + + +/* + * winClipboardIOErrorHandler - Our application specific IO error handler + */ + +static int +winClipboardIOErrorHandler (Display *pDisplay) +{ + ErrorF ("winClipboardIOErrorHandler!\n\n"); + + if (pthread_equal(pthread_self(),g_winClipboardProcThread)) + { + /* Restart at the main entry point */ + longjmp (g_jmpEntry, WIN_JMP_ERROR_IO); + } + + if (g_winClipboardOldIOErrorHandler) + g_winClipboardOldIOErrorHandler(pDisplay); + + return 0; +} + +/* + * winClipboardThreadExit - Thread exit handler + */ + +static void +winClipboardThreadExit(void *arg) +{ + /* clipboard thread has exited, stop server as well */ + AbortDDX(EXIT_ERR_ABORT); + TerminateProcess(GetCurrentProcess(),1); +} diff --git a/xorg-server/hw/xwin/winengine.c b/xorg-server/hw/xwin/winengine.c index d9d0d476c..4b39bcfc2 100644 --- a/xorg-server/hw/xwin/winengine.c +++ b/xorg-server/hw/xwin/winengine.c @@ -1,352 +1,349 @@ -/*
- *Copyright (C) 2001-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from Harold L Hunt II.
- *
- * Authors: Harold L Hunt II
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include "winmsg.h"
-
-/*
- * Global variables for function pointers into
- * dynamically loaded libraries
- */
-FARPROC g_fpDirectDrawCreate = NULL;
-FARPROC g_fpDirectDrawCreateClipper = NULL;
-
-/*
- module handle for dynamically loaded directdraw library
-*/
-static HMODULE g_hmodDirectDraw = NULL;
-
-/*
- * Detect engines supported by current Windows version
- * DirectDraw version and hardware
- */
-
-void
-winDetectSupportedEngines (void)
-{
- OSVERSIONINFO osvi;
-
- /* Initialize the engine support flags */
- g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI;
-
-#ifdef XWIN_NATIVEGDI
- g_dwEnginesSupported |= WIN_SERVER_NATIVE_GDI;
-#endif
-
- /* Get operating system version information */
- ZeroMemory (&osvi, sizeof (osvi));
- osvi.dwOSVersionInfoSize = sizeof (osvi);
- GetVersionEx (&osvi);
-
- /* Branch on platform ID */
- switch (osvi.dwPlatformId)
- {
- case VER_PLATFORM_WIN32_NT:
- /* Engine 4 is supported on NT only */
- winDebug ("winDetectSupportedEngines - Windows NT/2000/XP\n");
- break;
-
- case VER_PLATFORM_WIN32_WINDOWS:
- /* Engine 4 is supported on NT only */
- winDebug ("winDetectSupportedEngines - Windows 95/98/Me\n");
- break;
- }
-
- /* Do we have DirectDraw? */
- if (g_hmodDirectDraw != NULL)
- {
- LPDIRECTDRAW lpdd = NULL;
- LPDIRECTDRAW4 lpdd4 = NULL;
- HRESULT ddrval;
-
- /* Was the DirectDrawCreate function found? */
- if (g_fpDirectDrawCreate == NULL)
- {
- /* No DirectDraw support */
- return;
- }
-
- /* DirectDrawCreate exists, try to call it */
- /* Create a DirectDraw object, store the address at lpdd */
- ddrval = (*g_fpDirectDrawCreate) (NULL,
- (void**) &lpdd,
- NULL);
- if (FAILED (ddrval))
- {
- /* No DirectDraw support */
- winDebug ("winDetectSupportedEngines - DirectDraw not installed\n");
- return;
- }
- else
- {
- /* We have DirectDraw */
- winDebug ("winDetectSupportedEngines - DirectDraw installed\n");
- g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD;
-
-#ifdef XWIN_PRIMARYFB
- /* Allow PrimaryDD engine if NT */
- if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
- {
- g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD;
- winDebug ("winDetectSupportedEngines - Allowing PrimaryDD\n");
- }
-#endif
- }
-
- /* Try to query for DirectDraw4 interface */
- ddrval = IDirectDraw_QueryInterface (lpdd,
- &IID_IDirectDraw4,
- (LPVOID*) &lpdd4);
- if (SUCCEEDED (ddrval))
- {
- /* We have DirectDraw4 */
- winDebug ("winDetectSupportedEngines - DirectDraw4 installed\n");
- g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL;
- }
-
- /* Cleanup DirectDraw interfaces */
- if (lpdd4 != NULL)
- IDirectDraw_Release (lpdd4);
- if (lpdd != NULL)
- IDirectDraw_Release (lpdd);
- }
-
- winDebug ("winDetectSupportedEngines - Returning, supported engines %08x\n",
- (unsigned int) g_dwEnginesSupported);
-}
-
-
-/*
- * Set the engine type, depending on the engines
- * supported for this screen, and whether the user
- * suggested an engine type
- */
-
-Bool
-winSetEngine (ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- HDC hdc;
- DWORD dwBPP;
-
- /* Get a DC */
- hdc = GetDC (NULL);
- if (hdc == NULL)
- {
- ErrorF ("winSetEngine - Couldn't get an HDC\n");
- return FALSE;
- }
-
- /*
- * pScreenInfo->dwBPP may be 0 to indicate that the current screen
- * depth is to be used. Thus, we must query for the current display
- * depth here.
- */
- dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
-
- /* Release the DC */
- ReleaseDC (NULL, hdc);
- hdc = NULL;
-
- /* ShadowGDI is the only engine that supports windowed PseudoColor */
- if (dwBPP == 8 && !pScreenInfo->fFullScreen)
- {
- winDebug ("winSetEngine - Windowed && PseudoColor => ShadowGDI\n");
- pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
-
- /* Set engine function pointers */
- winSetEngineFunctionsShadowGDI (pScreen);
- return TRUE;
- }
-
- /* ShadowGDI is the only engine that supports Multi Window Mode */
- if (
-#ifdef XWIN_MULTIWINDOWEXTWM
- pScreenInfo->fMWExtWM
-#else
- FALSE
-#endif
-#ifdef XWIN_MULTIWINDOW
- || pScreenInfo->fMultiWindow
-#else
- || FALSE
-#endif
- )
- {
- winDebug ("winSetEngine - Multi Window or Rootless => ShadowGDI\n");
- pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
-
- /* Set engine function pointers */
- winSetEngineFunctionsShadowGDI (pScreen);
- return TRUE;
- }
-
- /* If there is a user's choice, we'll use that */
- if (pScreenInfo->dwEnginePreferred)
- {
- winDebug ("winSetEngine - Using user's preference: %d\n",
- (int) pScreenInfo->dwEnginePreferred);
- pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred;
-
- /* Setup engine function pointers */
- switch (pScreenInfo->dwEngine)
- {
- case WIN_SERVER_SHADOW_GDI:
- winSetEngineFunctionsShadowGDI (pScreen);
- break;
- case WIN_SERVER_SHADOW_DD:
- winSetEngineFunctionsShadowDD (pScreen);
- break;
- case WIN_SERVER_SHADOW_DDNL:
- winSetEngineFunctionsShadowDDNL (pScreen);
- break;
-#ifdef XWIN_PRIMARYFB
- case WIN_SERVER_PRIMARY_DD:
- winSetEngineFunctionsPrimaryDD (pScreen);
- break;
-#endif
-#ifdef XWIN_NATIVEGDI
- case WIN_SERVER_NATIVE_GDI:
- winSetEngineFunctionsNativeGDI (pScreen);
- break;
-#endif
- default:
- FatalError ("winSetEngine - Invalid engine type %d\n",pScreenInfo->dwEngine);
- }
- return TRUE;
- }
-
- /* ShadowDDNL has good performance, so why not */
- if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL)
- {
- winDebug ("winSetEngine - Using Shadow DirectDraw NonLocking\n");
- pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL;
-
- /* Set engine function pointers */
- winSetEngineFunctionsShadowDDNL (pScreen);
- return TRUE;
- }
-
- /* ShadowDD is next in line */
- if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DD)
- {
- winDebug ("winSetEngine - Using Shadow DirectDraw\n");
- pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DD;
-
- /* Set engine function pointers */
- winSetEngineFunctionsShadowDD (pScreen);
- return TRUE;
- }
-
- /* ShadowGDI is next in line */
- if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI)
- {
- winDebug ("winSetEngine - Using Shadow GDI DIB\n");
- pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
-
- /* Set engine function pointers */
- winSetEngineFunctionsShadowGDI (pScreen);
- return TRUE;
- }
-
- return TRUE;
-}
-
-
-/*
- * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper
- */
-
-Bool
-winGetDDProcAddresses (void)
-{
- Bool fReturn = TRUE;
-
- /* Load the DirectDraw library */
- g_hmodDirectDraw = LoadLibraryEx ("ddraw.dll", NULL, 0);
- if (g_hmodDirectDraw == NULL)
- {
- ErrorF ("winGetDDProcAddresses - Could not load ddraw.dll\n");
- fReturn = TRUE;
- goto winGetDDProcAddresses_Exit;
- }
-
- /* Try to get the DirectDrawCreate address */
- g_fpDirectDrawCreate = GetProcAddress (g_hmodDirectDraw,
- "DirectDrawCreate");
- if (g_fpDirectDrawCreate == NULL)
- {
- ErrorF ("winGetDDProcAddresses - Could not get DirectDrawCreate "
- "address\n");
- fReturn = TRUE;
- goto winGetDDProcAddresses_Exit;
- }
-
- /* Try to get the DirectDrawCreateClipper address */
- g_fpDirectDrawCreateClipper = GetProcAddress (g_hmodDirectDraw,
- "DirectDrawCreateClipper");
- if (g_fpDirectDrawCreateClipper == NULL)
- {
- ErrorF ("winGetDDProcAddresses - Could not get "
- "DirectDrawCreateClipper address\n");
- fReturn = FALSE;
- goto winGetDDProcAddresses_Exit;
- }
-
- /*
- * Note: Do not unload ddraw.dll here. Do it in GiveUp
- */
-
- winGetDDProcAddresses_Exit:
- /* Unload the DirectDraw library if we failed to initialize */
- if (!fReturn && g_hmodDirectDraw != NULL)
- {
- FreeLibrary (g_hmodDirectDraw);
- g_hmodDirectDraw = NULL;
- }
-
- return fReturn;
-}
-
-void
-winReleaseDDProcAddresses(void)
-{
- if (g_hmodDirectDraw != NULL)
- {
- FreeLibrary (g_hmodDirectDraw);
- g_hmodDirectDraw = NULL;
- g_fpDirectDrawCreate = NULL;
- g_fpDirectDrawCreateClipper = NULL;
- }
-}
+/* + *Copyright (C) 2001-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "winmsg.h" + +/* + * Global variables for function pointers into + * dynamically loaded libraries + */ +FARPROC g_fpDirectDrawCreate = NULL; +FARPROC g_fpDirectDrawCreateClipper = NULL; + +/* + module handle for dynamically loaded directdraw library +*/ +static HMODULE g_hmodDirectDraw = NULL; + +/* + * Detect engines supported by current Windows version + * DirectDraw version and hardware + */ + +void +winDetectSupportedEngines (void) +{ + OSVERSIONINFO osvi; + + /* Initialize the engine support flags */ + g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI; + +#ifdef XWIN_NATIVEGDI + g_dwEnginesSupported |= WIN_SERVER_NATIVE_GDI; +#endif + + /* Get operating system version information */ + ZeroMemory (&osvi, sizeof (osvi)); + osvi.dwOSVersionInfoSize = sizeof (osvi); + GetVersionEx (&osvi); + + /* Branch on platform ID */ + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_NT: + /* Engine 4 is supported on NT only */ + winDebug ("winDetectSupportedEngines - Windows NT/2000/XP\n"); + break; + + case VER_PLATFORM_WIN32_WINDOWS: + /* Engine 4 is supported on NT only */ + winDebug ("winDetectSupportedEngines - Windows 95/98/Me\n"); + break; + } + + /* Do we have DirectDraw? */ + if (g_hmodDirectDraw != NULL) + { + LPDIRECTDRAW lpdd = NULL; + LPDIRECTDRAW4 lpdd4 = NULL; + HRESULT ddrval; + + /* Was the DirectDrawCreate function found? */ + if (g_fpDirectDrawCreate == NULL) + { + /* No DirectDraw support */ + return; + } + + /* DirectDrawCreate exists, try to call it */ + /* Create a DirectDraw object, store the address at lpdd */ + ddrval = (*g_fpDirectDrawCreate) (NULL, + (void**) &lpdd, + NULL); + if (FAILED (ddrval)) + { + /* No DirectDraw support */ + winDebug ("winDetectSupportedEngines - DirectDraw not installed\n"); + return; + } + else + { + /* We have DirectDraw */ + winDebug ("winDetectSupportedEngines - DirectDraw installed\n"); + g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD; + +#ifdef XWIN_PRIMARYFB + /* Allow PrimaryDD engine if NT */ + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD; + winDebug ("winDetectSupportedEngines - Allowing PrimaryDD\n"); + } +#endif + } + + /* Try to query for DirectDraw4 interface */ + ddrval = IDirectDraw_QueryInterface (lpdd, + &IID_IDirectDraw4, + (LPVOID*) &lpdd4); + if (SUCCEEDED (ddrval)) + { + /* We have DirectDraw4 */ + winDebug ("winDetectSupportedEngines - DirectDraw4 installed\n"); + g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL; + } + + /* Cleanup DirectDraw interfaces */ + if (lpdd4 != NULL) + IDirectDraw_Release (lpdd4); + if (lpdd != NULL) + IDirectDraw_Release (lpdd); + } + + winDebug ("winDetectSupportedEngines - Returning, supported engines %08x\n", + (unsigned int) g_dwEnginesSupported); +} + + +/* + * Set the engine type, depending on the engines + * supported for this screen, and whether the user + * suggested an engine type + */ + +Bool +winSetEngine (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc; + DWORD dwBPP; + + /* Get a DC */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winSetEngine - Couldn't get an HDC\n"); + return FALSE; + } + + /* + * pScreenInfo->dwBPP may be 0 to indicate that the current screen + * depth is to be used. Thus, we must query for the current display + * depth here. + */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + + /* Release the DC */ + ReleaseDC (NULL, hdc); + hdc = NULL; + + /* ShadowGDI is the only engine that supports windowed PseudoColor */ + if (dwBPP == 8 && !pScreenInfo->fFullScreen) + { + winDebug ("winSetEngine - Windowed && PseudoColor => ShadowGDI\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowGDI (pScreen); + return TRUE; + } + + /* ShadowGDI is the only engine that supports Multi Window Mode */ + if ( + FALSE +#ifdef XWIN_MULTIWINDOWEXTWM + || pScreenInfo->fMWExtWM +#endif +#ifdef XWIN_MULTIWINDOW + || pScreenInfo->fMultiWindow +#endif + ) + { + winDebug ("winSetEngine - Multi Window or Rootless => ShadowGDI\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowGDI (pScreen); + return TRUE; + } + + /* If there is a user's choice, we'll use that */ + if (pScreenInfo->dwEnginePreferred) + { + winDebug ("winSetEngine - Using user's preference: %d\n", + (int) pScreenInfo->dwEnginePreferred); + pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred; + + /* Setup engine function pointers */ + switch (pScreenInfo->dwEngine) + { + case WIN_SERVER_SHADOW_GDI: + winSetEngineFunctionsShadowGDI (pScreen); + break; + case WIN_SERVER_SHADOW_DD: + winSetEngineFunctionsShadowDD (pScreen); + break; + case WIN_SERVER_SHADOW_DDNL: + winSetEngineFunctionsShadowDDNL (pScreen); + break; +#ifdef XWIN_PRIMARYFB + case WIN_SERVER_PRIMARY_DD: + winSetEngineFunctionsPrimaryDD (pScreen); + break; +#endif +#ifdef XWIN_NATIVEGDI + case WIN_SERVER_NATIVE_GDI: + winSetEngineFunctionsNativeGDI (pScreen); + break; +#endif + default: + FatalError ("winSetEngine - Invalid engine type %d\n",pScreenInfo->dwEngine); + } + return TRUE; + } + + /* ShadowDDNL has good performance, so why not */ + if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) + { + winDebug ("winSetEngine - Using Shadow DirectDraw NonLocking\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowDDNL (pScreen); + return TRUE; + } + + /* ShadowDD is next in line */ + if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DD) + { + winDebug ("winSetEngine - Using Shadow DirectDraw\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DD; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowDD (pScreen); + return TRUE; + } + + /* ShadowGDI is next in line */ + if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) + { + winDebug ("winSetEngine - Using Shadow GDI DIB\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowGDI (pScreen); + return TRUE; + } + + return TRUE; +} + + +/* + * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper + */ + +Bool +winGetDDProcAddresses (void) +{ + Bool fReturn = TRUE; + + /* Load the DirectDraw library */ + g_hmodDirectDraw = LoadLibraryEx ("ddraw.dll", NULL, 0); + if (g_hmodDirectDraw == NULL) + { + ErrorF ("winGetDDProcAddresses - Could not load ddraw.dll\n"); + fReturn = TRUE; + goto winGetDDProcAddresses_Exit; + } + + /* Try to get the DirectDrawCreate address */ + g_fpDirectDrawCreate = GetProcAddress (g_hmodDirectDraw, + "DirectDrawCreate"); + if (g_fpDirectDrawCreate == NULL) + { + ErrorF ("winGetDDProcAddresses - Could not get DirectDrawCreate " + "address\n"); + fReturn = TRUE; + goto winGetDDProcAddresses_Exit; + } + + /* Try to get the DirectDrawCreateClipper address */ + g_fpDirectDrawCreateClipper = GetProcAddress (g_hmodDirectDraw, + "DirectDrawCreateClipper"); + if (g_fpDirectDrawCreateClipper == NULL) + { + ErrorF ("winGetDDProcAddresses - Could not get " + "DirectDrawCreateClipper address\n"); + fReturn = FALSE; + goto winGetDDProcAddresses_Exit; + } + + /* + * Note: Do not unload ddraw.dll here. Do it in GiveUp + */ + + winGetDDProcAddresses_Exit: + /* Unload the DirectDraw library if we failed to initialize */ + if (!fReturn && g_hmodDirectDraw != NULL) + { + FreeLibrary (g_hmodDirectDraw); + g_hmodDirectDraw = NULL; + } + + return fReturn; +} + +void +winReleaseDDProcAddresses(void) +{ + if (g_hmodDirectDraw != NULL) + { + FreeLibrary (g_hmodDirectDraw); + g_hmodDirectDraw = NULL; + g_fpDirectDrawCreate = NULL; + g_fpDirectDrawCreateClipper = NULL; + } +} diff --git a/xorg-server/hw/xwin/winmultiwindowwm.c b/xorg-server/hw/xwin/winmultiwindowwm.c index bbc1f47b5..be777664d 100644 --- a/xorg-server/hw/xwin/winmultiwindowwm.c +++ b/xorg-server/hw/xwin/winmultiwindowwm.c @@ -1142,11 +1142,13 @@ winInitWM (void **ppWMInfo, XMsgProcArgPtr pXMsgArg = (XMsgProcArgPtr) malloc (sizeof(XMsgProcArgRec)); /* Bail if the input parameters are bad */ - if (pArg == NULL || pWMInfo == NULL) - { - ErrorF ("winInitWM - malloc failed.\n"); - return FALSE; - } + if (pArg == NULL || pWMInfo == NULL || pXMsgArg == NULL) { + ErrorF ("winInitWM - malloc failed.\n"); + free(pArg); + free(pWMInfo); + free(pXMsgArg); + return FALSE; + } /* Zero the allocated memory */ ZeroMemory (pArg, sizeof (WMProcArgRec)); diff --git a/xorg-server/hw/xwin/winnativegdi.c b/xorg-server/hw/xwin/winnativegdi.c index ef95f834a..c6238d43b 100644 --- a/xorg-server/hw/xwin/winnativegdi.c +++ b/xorg-server/hw/xwin/winnativegdi.c @@ -313,7 +313,6 @@ static Bool winActivateAppNativeGDI (ScreenPtr pScreen) { winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; /* * Are we active? @@ -321,7 +320,8 @@ winActivateAppNativeGDI (ScreenPtr pScreen) */ if (pScreenPriv != NULL && pScreenPriv->fActive - && pScreenInfo->fFullScreen) + && pScreenPriv->pScreenInfo + && pScreenPriv->pScreenInfo->fFullScreen) { /* * Activating, attempt to bring our window @@ -336,7 +336,8 @@ winActivateAppNativeGDI (ScreenPtr pScreen) */ if (pScreenPriv != NULL && !pScreenPriv->fActive - && pScreenInfo->fFullScreen) + && pScreenPriv->pScreenInfo + && pScreenPriv->pScreenInfo->fFullScreen) { /* * Deactivating, stuff our window onto the diff --git a/xorg-server/hw/xwin/winpfbdd.c b/xorg-server/hw/xwin/winpfbdd.c index a8ea9fb90..3ea61ade2 100644 --- a/xorg-server/hw/xwin/winpfbdd.c +++ b/xorg-server/hw/xwin/winpfbdd.c @@ -457,12 +457,12 @@ static Bool winActivateAppPrimaryDD (ScreenPtr pScreen) { winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; RECT rcSrc, rcClient; HRESULT ddrval = DD_OK; /* Check for errors */ if (pScreenPriv == NULL + || pScreenPriv->pScreenInfo == NULL || pScreenPriv->pddsPrimary == NULL || pScreenPriv->pddsOffscreen == NULL) return FALSE; @@ -496,8 +496,8 @@ winActivateAppPrimaryDD (ScreenPtr pScreen) /* Setup a source rectangle */ rcSrc.left = 0; rcSrc.top = 0; - rcSrc.right = pScreenInfo->dwWidth; - rcSrc.bottom = pScreenInfo->dwHeight; + rcSrc.right = pScreenPriv->pScreenInfo->dwWidth; + rcSrc.bottom = pScreenPriv->pScreenInfo->dwHeight; ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, &rcClient, diff --git a/xorg-server/hw/xwin/winshadgdi.c b/xorg-server/hw/xwin/winshadgdi.c index 545d1f0e0..a11ca43bd 100644 --- a/xorg-server/hw/xwin/winshadgdi.c +++ b/xorg-server/hw/xwin/winshadgdi.c @@ -270,7 +270,6 @@ winQueryRGBBitsAndMasks (ScreenPtr pScreen) else { ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); - free (pbmih); fReturn = FALSE; } diff --git a/xorg-server/hw/xwin/winwin32rootless.c b/xorg-server/hw/xwin/winwin32rootless.c index d630f1d90..9f828503f 100644 --- a/xorg-server/hw/xwin/winwin32rootless.c +++ b/xorg-server/hw/xwin/winwin32rootless.c @@ -488,7 +488,7 @@ winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid) winDebug ("winMWExtWMRestackFrame (%08x)\n", (int) pRLWinPriv); - if (pScreenPriv->fRestacking) return; + if (pScreenPriv && pScreenPriv->fRestacking) return; if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; diff --git a/xorg-server/hw/xwin/winwin32rootlesswindow.c b/xorg-server/hw/xwin/winwin32rootlesswindow.c index bfb35e70f..bcfb2798e 100644 --- a/xorg-server/hw/xwin/winwin32rootlesswindow.c +++ b/xorg-server/hw/xwin/winwin32rootlesswindow.c @@ -1,471 +1,472 @@ -/*
- *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- *
- *Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- *"Software"), to deal in the Software without restriction, including
- *without limitation the rights to use, copy, modify, merge, publish,
- *distribute, sublicense, and/or sell copies of the Software, and to
- *permit persons to whom the Software is furnished to do so, subject to
- *the following conditions:
- *
- *The above copyright notice and this permission notice shall be
- *included in all copies or substantial portions of the Software.
- *
- *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
- *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- *Except as contained in this notice, the name of the XFree86 Project
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from the XFree86 Project.
- *
- * Authors: Kensuke Matsuzaki
- * Earle F. Philhower, III
- * Harold L Hunt II
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include "winprefs.h"
-
-#if 0
-/*
- * winMWExtWMReorderWindows
- */
-
-void
-winMWExtWMReorderWindows (ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- HWND hwnd = NULL;
- win32RootlessWindowPtr pRLWin = NULL;
- win32RootlessWindowPtr pRLWinSib = NULL;
- DWORD dwCurrentProcessID = GetCurrentProcessId ();
- DWORD dwWindowProcessID = 0;
- XID vlist[2];
-
-#if CYGMULTIWINDOW_DEBUG && FALSE
- winDebug ("winMWExtWMReorderWindows\n");
-#endif
-
- pScreenPriv->fRestacking = TRUE;
-
- if (pScreenPriv->fWindowOrderChanged)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMReorderWindows - Need to restack\n");
-#endif
- hwnd = GetTopWindow (NULL);
-
- while (hwnd)
- {
- GetWindowThreadProcessId (hwnd, &dwWindowProcessID);
-
- if ((dwWindowProcessID == dwCurrentProcessID)
- && GetProp (hwnd, WIN_WINDOW_PROP))
- {
- pRLWinSib = pRLWin;
- pRLWin = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP);
-
- if (pRLWinSib)
- {
- vlist[0] = pRLWinSib->pFrame->win->drawable.id;
- vlist[1] = Below;
-
- ConfigureWindow (pRLWin->pFrame->win, CWSibling | CWStackMode,
- vlist, wClient(pRLWin->pFrame->win));
- }
- else
- {
- /* 1st window - raise to the top */
- vlist[0] = Above;
-
- ConfigureWindow (pRLWin->pFrame->win, CWStackMode,
- vlist, wClient(pRLWin->pFrame->win));
- }
- }
- hwnd = GetNextWindow (hwnd, GW_HWNDNEXT);
- }
- }
-
- pScreenPriv->fRestacking = FALSE;
- pScreenPriv->fWindowOrderChanged = FALSE;
-}
-#endif
-
-
-/*
- * winMWExtWMMoveXWindow
- */
-
-void
-winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y)
-{
- CARD32 *vlist = malloc(sizeof(CARD32)*2);
-
- vlist[0] = x;
- vlist[1] = y;
- ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
- free(vlist);
-}
-
-
-/*
- * winMWExtWMResizeXWindow
- */
-
-void
-winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h)
-{
- CARD32 *vlist = malloc(sizeof(CARD32)*2);
-
- vlist[0] = w;
- vlist[1] = h;
- ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin));
- free(vlist);
-}
-
-
-/*
- * winMWExtWMMoveResizeXWindow
- */
-
-void
-winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h)
-{
- CARD32 *vlist = malloc(sizeof(long)*4);
-
- vlist[0] = x;
- vlist[1] = y;
- vlist[2] = w;
- vlist[3] = h;
-
- ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, vlist, wClient(pWin));
- free(vlist);
-}
-
-
-/*
- * winMWExtWMUpdateIcon
- * Change the Windows window icon
- */
-
-void
-winMWExtWMUpdateIcon (Window id)
-{
- WindowPtr pWin;
- HICON hIcon, hiconOld;
-
- dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
- hIcon = winOverrideIcon ((unsigned long)pWin);
-
- if (!hIcon)
- hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
-
- if (hIcon)
- {
- win32RootlessWindowPtr pRLWinPriv
- = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
-
- if (pRLWinPriv->hWnd)
- {
-
- hiconOld = (HICON) SendMessage (pRLWinPriv->hWnd,
- WM_SETICON, ICON_BIG, (LPARAM) hIcon);
- winDestroyIcon(hiconOld);
- }
- hIcon=NULL;
- }
-}
-
-
-/*
- * winMWExtWMDecorateWindow - Update window style. Called by EnumWindows.
- */
-
-wBOOL CALLBACK
-winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam)
-{
- win32RootlessWindowPtr pRLWinPriv = NULL;
- ScreenPtr pScreen = NULL;
- winPrivScreenPtr pScreenPriv = NULL;
- winScreenInfo *pScreenInfo = NULL;
-
- /* Check if the Windows window property for our X window pointer is valid */
- if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
- {
- pScreen = pRLWinPriv->pFrame->win->drawable.pScreen;
- if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
- if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
- if (pRLWinPriv && pScreenInfo) winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo);
- }
- return TRUE;
-}
-
-
-/*
- * winMWExtWMUpdateWindowDecoration - Update window style.
- */
-
-void
-winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv,
- winScreenInfoPtr pScreenInfo)
-{
- Bool fDecorate = FALSE;
- DWORD dwExStyle = 0;
- DWORD dwStyle = 0;
- WINDOWPLACEMENT wndPlace;
- UINT showCmd = 0;
-
- wndPlace.length = sizeof (WINDOWPLACEMENT);
-
- /* Get current window placement */
- GetWindowPlacement (pRLWinPriv->hWnd, &wndPlace);
-
-#ifdef XWIN_MULTIWINDOWINTWM
- if (winIsInternalWMRunning(pScreenInfo))
- {
- if (!pRLWinPriv->pFrame->win->overrideRedirect)
- fDecorate = TRUE;
- }
-#endif
- if (wndPlace.showCmd == SW_HIDE)
- return;
-
- if (IsWindowVisible (pRLWinPriv->hWnd))
- showCmd = SWP_SHOWWINDOW;
-
- showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER;
-
- winDebug ("winMWExtWMUpdateWindowDecoration %08x %s\n",
- (int)pRLWinPriv, fDecorate?"Decorate":"Bare");
-
- /* Get the standard and extended window style information */
- dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE);
- dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE);
-
- if (fDecorate)
- {
- RECT rcNew;
- int iDx, iDy;
- winWMMessageRec wmMsg;
- winScreenPriv(pScreenInfo->pScreen);
-
- /* */
- if (!(dwExStyle & WS_EX_APPWINDOW))
- {
- winDebug ("\tBare=>Decorate\n");
- /* Setup a rectangle with the X window position and size */
- SetRect (&rcNew,
- pRLWinPriv->pFrame->x,
- pRLWinPriv->pFrame->y,
- pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
- pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
-
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
-#endif
- /* */
- AdjustWindowRectEx (&rcNew,
- WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
- FALSE,
- WS_EX_APPWINDOW);
-
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
-#endif
- /* Calculate position deltas */
- iDx = pRLWinPriv->pFrame->x - rcNew.left;
- iDy = pRLWinPriv->pFrame->y - rcNew.top;
-
- /* Calculate new rectangle */
- rcNew.left += iDx;
- rcNew.right += iDx;
- rcNew.top += iDy;
- rcNew.bottom += iDy;
-
- /* Set the window extended style flags */
- SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
-
- /* Set the window standard style flags */
- SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
- WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW);
-
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tWindowStyle: %08x %08x\n",
- WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
- WS_EX_APPWINDOW);
-#endif
- /* Position the Windows window */
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tMoved {%d, %d, %d, %d}, {%d, %d}\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
-#endif
- SetWindowPos (pRLWinPriv->hWnd, NULL,
- rcNew.left, rcNew.top,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
- showCmd);
-
-
- wmMsg.hwndWindow = pRLWinPriv->hWnd;
- wmMsg.iWindow = (Window)pRLWinPriv->pFrame->win->drawable.id;
- wmMsg.msg = WM_WM_NAME_EVENT;
- winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
-
- winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv ,
- wBoundingShape(pRLWinPriv->pFrame->win));
- }
- }
- else
- {
- RECT rcNew;
-
- /* */
- if (dwExStyle & WS_EX_APPWINDOW)
- {
- winDebug ("\tDecorate=>Bare\n");
- /* Setup a rectangle with the X window position and size */
- SetRect (&rcNew,
- pRLWinPriv->pFrame->x,
- pRLWinPriv->pFrame->y,
- pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
- pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
-#if 0
- /* */
- AdjustWindowRectEx (&rcNew,
- WS_POPUP | WS_CLIPCHILDREN,
- FALSE,
- WS_EX_TOOLWINDOW);
-
- /* Calculate position deltas */
- iDx = pRLWinPriv->pFrame->x - rcNew.left;
- iDy = pRLWinPriv->pFrame->y - rcNew.top;
-
- /* Calculate new rectangle */
- rcNew.left += iDx;
- rcNew.right += iDx;
- rcNew.top += iDy;
- rcNew.bottom += iDy;
-#endif
-
- /* Hide window temporary to remove from taskbar. */
- ShowWindow( pRLWinPriv->hWnd, SW_HIDE );
-
- /* Set the window extended style flags */
- SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
-
- /* Set the window standard style flags */
- SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
- WS_POPUP | WS_CLIPCHILDREN);
-
- /* Position the Windows window */
- SetWindowPos (pRLWinPriv->hWnd, NULL,
- rcNew.left, rcNew.top,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
- showCmd);
-
- winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv ,
- wBoundingShape(pRLWinPriv->pFrame->win));
- }
- }
-}
-
-#ifdef XWIN_MULTIWINDOWINTWM
-/*
- * winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
- */
-Bool
-winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
-{
- return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning;
-}
-#endif
-
-/*
- * winMWExtWMRestackWindows
- */
-
-void
-winMWExtWMRestackWindows (ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- WindowPtr pRoot = pScreen->root;
- WindowPtr pWin = NULL;
- WindowPtr pWinPrev = NULL;
- win32RootlessWindowPtr pRLWin = NULL;
- win32RootlessWindowPtr pRLWinPrev = NULL;
- int nWindow = 0;
- HDWP hWinPosInfo = NULL;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMRestackWindows\n");
-#endif
-
- pScreenPriv->fRestacking = TRUE;
-
- if (pRoot != NULL)
- {
- for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
- nWindow ++;
-
- hWinPosInfo = BeginDeferWindowPos(nWindow);
-
- for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
- {
- if (pWin->realized)
- {
- UINT uFlags;
-
- pRLWin = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
- if (pRLWin == NULL) continue;
-
- if (pWinPrev)
- pRLWinPrev = (win32RootlessWindowPtr) RootlessFrameForWindow (pWinPrev, FALSE);
-
- uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW;
- if (pRLWinPrev != NULL) uFlags |= SWP_NOACTIVATE;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n",
- pRLWin->hWnd,
- pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP);
-#endif
- hWinPosInfo = DeferWindowPos (hWinPosInfo, pRLWin->hWnd,
- pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP,
- 0, 0, 0, 0,
- uFlags);
- if (hWinPosInfo == NULL)
- {
- ErrorF ("winMWExtWMRestackWindows - DeferWindowPos () failed: %d\n",
- (int) GetLastError ());
- return;
- }
- pWinPrev = pWin;
- }
- }
- if (!EndDeferWindowPos (hWinPosInfo))
- {
- ErrorF ("winMWExtWMRestackWindows - EndDeferWindowPos () failed: %d\n",
- (int) GetLastError ());
- return;
- }
- }
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMRestackWindows - done\n");
-#endif
- pScreenPriv->fRestacking = FALSE;
-}
+/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Kensuke Matsuzaki + * Earle F. Philhower, III + * Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "winprefs.h" + +#if 0 +/* + * winMWExtWMReorderWindows + */ + +void +winMWExtWMReorderWindows (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + HWND hwnd = NULL; + win32RootlessWindowPtr pRLWin = NULL; + win32RootlessWindowPtr pRLWinSib = NULL; + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + XID vlist[2]; + +#if CYGMULTIWINDOW_DEBUG && FALSE + winDebug ("winMWExtWMReorderWindows\n"); +#endif + + pScreenPriv->fRestacking = TRUE; + + if (pScreenPriv->fWindowOrderChanged) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMReorderWindows - Need to restack\n"); +#endif + hwnd = GetTopWindow (NULL); + + while (hwnd) + { + GetWindowThreadProcessId (hwnd, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hwnd, WIN_WINDOW_PROP)) + { + pRLWinSib = pRLWin; + pRLWin = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP); + + if (pRLWinSib) + { + vlist[0] = pRLWinSib->pFrame->win->drawable.id; + vlist[1] = Below; + + ConfigureWindow (pRLWin->pFrame->win, CWSibling | CWStackMode, + vlist, wClient(pRLWin->pFrame->win)); + } + else + { + /* 1st window - raise to the top */ + vlist[0] = Above; + + ConfigureWindow (pRLWin->pFrame->win, CWStackMode, + vlist, wClient(pRLWin->pFrame->win)); + } + } + hwnd = GetNextWindow (hwnd, GW_HWNDNEXT); + } + } + + pScreenPriv->fRestacking = FALSE; + pScreenPriv->fWindowOrderChanged = FALSE; +} +#endif + + +/* + * winMWExtWMMoveXWindow + */ + +void +winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y) +{ + CARD32 *vlist = malloc(sizeof(CARD32)*2); + + vlist[0] = x; + vlist[1] = y; + ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); + free(vlist); +} + + +/* + * winMWExtWMResizeXWindow + */ + +void +winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h) +{ + CARD32 *vlist = malloc(sizeof(CARD32)*2); + + vlist[0] = w; + vlist[1] = h; + ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin)); + free(vlist); +} + + +/* + * winMWExtWMMoveResizeXWindow + */ + +void +winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h) +{ + CARD32 *vlist = malloc(sizeof(long)*4); + + vlist[0] = x; + vlist[1] = y; + vlist[2] = w; + vlist[3] = h; + + ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, vlist, wClient(pWin)); + free(vlist); +} + + +/* + * winMWExtWMUpdateIcon + * Change the Windows window icon + */ + +void +winMWExtWMUpdateIcon (Window id) +{ + WindowPtr pWin; + HICON hIcon, hiconOld; + + dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); + hIcon = winOverrideIcon ((unsigned long)pWin); + + if (!hIcon) + hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); + + if (hIcon) + { + win32RootlessWindowPtr pRLWinPriv + = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + + if (pRLWinPriv->hWnd) + { + + hiconOld = (HICON) SendMessage (pRLWinPriv->hWnd, + WM_SETICON, ICON_BIG, (LPARAM) hIcon); + winDestroyIcon(hiconOld); + } + hIcon=NULL; + } +} + + +/* + * winMWExtWMDecorateWindow - Update window style. Called by EnumWindows. + */ + +wBOOL CALLBACK +winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam) +{ + win32RootlessWindowPtr pRLWinPriv = NULL; + ScreenPtr pScreen = NULL; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) + { + if (pRLWinPriv != NULL && pRLWinPriv->pFrame != NULL && pRLWinPriv->pFrame->win != NULL) + pScreen = pRLWinPriv->pFrame->win->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + if (pRLWinPriv && pScreenInfo) winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo); + } + return TRUE; +} + + +/* + * winMWExtWMUpdateWindowDecoration - Update window style. + */ + +void +winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv, + winScreenInfoPtr pScreenInfo) +{ + Bool fDecorate = FALSE; + DWORD dwExStyle = 0; + DWORD dwStyle = 0; + WINDOWPLACEMENT wndPlace; + UINT showCmd = 0; + + wndPlace.length = sizeof (WINDOWPLACEMENT); + + /* Get current window placement */ + GetWindowPlacement (pRLWinPriv->hWnd, &wndPlace); + +#ifdef XWIN_MULTIWINDOWINTWM + if (winIsInternalWMRunning(pScreenInfo)) + { + if (!pRLWinPriv->pFrame->win->overrideRedirect) + fDecorate = TRUE; + } +#endif + if (wndPlace.showCmd == SW_HIDE) + return; + + if (IsWindowVisible (pRLWinPriv->hWnd)) + showCmd = SWP_SHOWWINDOW; + + showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER; + + winDebug ("winMWExtWMUpdateWindowDecoration %08x %s\n", + (int)pRLWinPriv, fDecorate?"Decorate":"Bare"); + + /* Get the standard and extended window style information */ + dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); + + if (fDecorate) + { + RECT rcNew; + int iDx, iDy; + winWMMessageRec wmMsg; + winScreenPriv(pScreenInfo->pScreen); + + /* */ + if (!(dwExStyle & WS_EX_APPWINDOW)) + { + winDebug ("\tBare=>Decorate\n"); + /* Setup a rectangle with the X window position and size */ + SetRect (&rcNew, + pRLWinPriv->pFrame->x, + pRLWinPriv->pFrame->y, + pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width, + pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + /* */ + AdjustWindowRectEx (&rcNew, + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, + FALSE, + WS_EX_APPWINDOW); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + /* Calculate position deltas */ + iDx = pRLWinPriv->pFrame->x - rcNew.left; + iDy = pRLWinPriv->pFrame->y - rcNew.top; + + /* Calculate new rectangle */ + rcNew.left += iDx; + rcNew.right += iDx; + rcNew.top += iDy; + rcNew.bottom += iDy; + + /* Set the window extended style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW); + + /* Set the window standard style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindowStyle: %08x %08x\n", + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, + WS_EX_APPWINDOW); +#endif + /* Position the Windows window */ +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tMoved {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + SetWindowPos (pRLWinPriv->hWnd, NULL, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + showCmd); + + + wmMsg.hwndWindow = pRLWinPriv->hWnd; + wmMsg.iWindow = (Window)pRLWinPriv->pFrame->win->drawable.id; + wmMsg.msg = WM_WM_NAME_EVENT; + winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); + + winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv , + wBoundingShape(pRLWinPriv->pFrame->win)); + } + } + else + { + RECT rcNew; + + /* */ + if (dwExStyle & WS_EX_APPWINDOW) + { + winDebug ("\tDecorate=>Bare\n"); + /* Setup a rectangle with the X window position and size */ + SetRect (&rcNew, + pRLWinPriv->pFrame->x, + pRLWinPriv->pFrame->y, + pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width, + pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height); +#if 0 + /* */ + AdjustWindowRectEx (&rcNew, + WS_POPUP | WS_CLIPCHILDREN, + FALSE, + WS_EX_TOOLWINDOW); + + /* Calculate position deltas */ + iDx = pRLWinPriv->pFrame->x - rcNew.left; + iDy = pRLWinPriv->pFrame->y - rcNew.top; + + /* Calculate new rectangle */ + rcNew.left += iDx; + rcNew.right += iDx; + rcNew.top += iDy; + rcNew.bottom += iDy; +#endif + + /* Hide window temporary to remove from taskbar. */ + ShowWindow( pRLWinPriv->hWnd, SW_HIDE ); + + /* Set the window extended style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); + + /* Set the window standard style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, + WS_POPUP | WS_CLIPCHILDREN); + + /* Position the Windows window */ + SetWindowPos (pRLWinPriv->hWnd, NULL, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + showCmd); + + winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv , + wBoundingShape(pRLWinPriv->pFrame->win)); + } + } +} + +#ifdef XWIN_MULTIWINDOWINTWM +/* + * winIsInternalWMRunning (winScreenInfoPtr pScreenInfo) + */ +Bool +winIsInternalWMRunning (winScreenInfoPtr pScreenInfo) +{ + return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning; +} +#endif + +/* + * winMWExtWMRestackWindows + */ + +void +winMWExtWMRestackWindows (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + WindowPtr pRoot = pScreen->root; + WindowPtr pWin = NULL; + WindowPtr pWinPrev = NULL; + win32RootlessWindowPtr pRLWin = NULL; + win32RootlessWindowPtr pRLWinPrev = NULL; + int nWindow = 0; + HDWP hWinPosInfo = NULL; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackWindows\n"); +#endif + + pScreenPriv->fRestacking = TRUE; + + if (pRoot != NULL) + { + for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) + nWindow ++; + + hWinPosInfo = BeginDeferWindowPos(nWindow); + + for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) + { + if (pWin->realized) + { + UINT uFlags; + + pRLWin = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + if (pRLWin == NULL) continue; + + if (pWinPrev) + pRLWinPrev = (win32RootlessWindowPtr) RootlessFrameForWindow (pWinPrev, FALSE); + + uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW; + if (pRLWinPrev != NULL) uFlags |= SWP_NOACTIVATE; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n", + pRLWin->hWnd, + pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP); +#endif + hWinPosInfo = DeferWindowPos (hWinPosInfo, pRLWin->hWnd, + pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP, + 0, 0, 0, 0, + uFlags); + if (hWinPosInfo == NULL) + { + ErrorF ("winMWExtWMRestackWindows - DeferWindowPos () failed: %d\n", + (int) GetLastError ()); + return; + } + pWinPrev = pWin; + } + } + if (!EndDeferWindowPos (hWinPosInfo)) + { + ErrorF ("winMWExtWMRestackWindows - EndDeferWindowPos () failed: %d\n", + (int) GetLastError ()); + return; + } + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackWindows - done\n"); +#endif + pScreenPriv->fRestacking = FALSE; +} diff --git a/xorg-server/hw/xwin/winwindowswm.c b/xorg-server/hw/xwin/winwindowswm.c index 05879eb9d..15579ce35 100644 --- a/xorg-server/hw/xwin/winwindowswm.c +++ b/xorg-server/hw/xwin/winwindowswm.c @@ -523,7 +523,7 @@ ProcWindowsWMDispatch (ClientPtr client) return ProcWindowsWMQueryVersion(client); } - if (!LocalClient(client)) + if (!client->local) return WMErrorBase + WindowsWMClientNotLocal; switch (stuff->data) @@ -573,7 +573,7 @@ SProcWindowsWMDispatch (ClientPtr client) REQUEST(xReq); /* It is bound to be non-local when there is byte swapping */ - if (!LocalClient(client)) + if (!client->local) return WMErrorBase + WindowsWMClientNotLocal; /* only local clients are allowed WM access */ diff --git a/xorg-server/include/dixstruct.h b/xorg-server/include/dixstruct.h index 130549cdf..a9fddfb5a 100644 --- a/xorg-server/include/dixstruct.h +++ b/xorg-server/include/dixstruct.h @@ -90,23 +90,23 @@ typedef struct _Client { Mask clientAsMask; pointer requestBuffer; pointer osPrivate; /* for OS layer, including scheduler */ - Bool swapped; + char swapped; + char local; + char big_requests; + char closeDownMode; + char clientGone; + char noClientException; /* this client died or needs to be + * killed */ + char clientState; ReplySwapPtr pSwapReplyFunc; XID errorValue; unsigned short sequence; //MH - int closeDownMode; - int clientGone; - int noClientException; /* this client died or needs to be - * killed */ int ignoreCount; /* count for Attend/IgnoreClient */ - SaveSetElt *saveSet; int numSaved; - int (**requestVector) ( - ClientPtr /* pClient */); + SaveSetElt *saveSet; + int (**requestVector) (ClientPtr /* pClient */); CARD32 req_len; /* length of current request */ - Bool big_requests; /* supports large requests */ int priority; - ClientState clientState; PrivateRec *devPrivates; unsigned short xkbClientFlags; unsigned short mapNotifyMask; @@ -114,16 +114,16 @@ typedef struct _Client { unsigned short vMajor,vMinor; KeyCode minKC,maxKC; - unsigned long replyBytesRemaining; + unsigned int replyBytesRemaining; int smart_priority; - long smart_start_tick; - long smart_stop_tick; - long smart_check_tick; + int smart_start_tick; + int smart_stop_tick; + int smart_check_tick; DeviceIntPtr clientPtr; ClientIdPtr clientIds; unsigned short majorOp, minorOp; -} ClientRec; +} ClientRec; /* * Scheduling interface diff --git a/xorg-server/include/exevents.h b/xorg-server/include/exevents.h index bd1697066..31acb30ea 100644 --- a/xorg-server/include/exevents.h +++ b/xorg-server/include/exevents.h @@ -92,7 +92,7 @@ extern _X_EXPORT int XIChangeDeviceProperty( int /* format*/, int /* mode*/, unsigned long /* len*/, - const pointer /* value*/, + const void* /* value*/, Bool /* sendevent*/ ); diff --git a/xorg-server/include/os.h b/xorg-server/include/os.h index f62ada207..b8c0d3b45 100644 --- a/xorg-server/include/os.h +++ b/xorg-server/include/os.h @@ -355,8 +355,6 @@ typedef struct sockaddr * sockaddrPtr; extern _X_EXPORT int InvalidHost(sockaddrPtr /*saddr*/, int /*len*/, ClientPtr client); -extern _X_EXPORT int LocalClient(ClientPtr /* client */); - extern _X_EXPORT int LocalClientCred(ClientPtr, int *, int *); #define LCC_UID_SET (1 << 0) diff --git a/xorg-server/include/windowstr.h b/xorg-server/include/windowstr.h index 04553f831..d5640213e 100644 --- a/xorg-server/include/windowstr.h +++ b/xorg-server/include/windowstr.h @@ -87,8 +87,8 @@ typedef struct _WindowOpt { struct _OtherClients *otherClients; /* default: NULL */ struct _GrabRec *passiveGrabs; /* default: NULL */ PropertyPtr userProps; /* default: NULL */ - unsigned long backingBitPlanes; /* default: ~0L */ - unsigned long backingPixel; /* default: 0 */ + CARD32 backingBitPlanes; /* default: ~0L */ + CARD32 backingPixel; /* default: 0 */ RegionPtr boundingShape; /* default: NULL */ RegionPtr clipShape; /* default: NULL */ RegionPtr inputShape; /* default: NULL */ diff --git a/xorg-server/mi/mibitblt.c b/xorg-server/mi/mibitblt.c index 2dfff1451..fc6eb8d6e 100644 --- a/xorg-server/mi/mibitblt.c +++ b/xorg-server/mi/mibitblt.c @@ -648,7 +648,7 @@ miGetImage( DrawablePtr pDraw, int sx, int sy, int w, int h, depth = pDraw->depth; if(format == ZPixmap) { - if ( (((1<<depth)-1)&planeMask) != (1<<depth)-1 ) + if ( (((1LL<<depth)-1)&planeMask) != (1LL<<depth)-1 ) { ChangeGCVal gcv; xPoint pt; diff --git a/xorg-server/os/access.c b/xorg-server/os/access.c index 0ec8ebdf7..dbce71112 100644 --- a/xorg-server/os/access.c +++ b/xorg-server/os/access.c @@ -1220,13 +1220,6 @@ ComputeLocalClient(ClientPtr client) return FALSE; } -Bool LocalClient(ClientPtr client) -{ - if (!client->osPrivate) - return FALSE; - return ((OsCommPtr)client->osPrivate)->local_client; -} - /* * Return the uid and gid of a connected local client * @@ -1384,7 +1377,7 @@ AuthorizedClient(ClientPtr client) if (rc != Success) return rc; - return LocalClient(client) ? Success : BadAccess; + return client->local ? Success : BadAccess; } /* Add a host to the access control list. This is the external interface diff --git a/xorg-server/os/backtrace.c b/xorg-server/os/backtrace.c index 58b4b1f34..298bf1898 100644 --- a/xorg-server/os/backtrace.c +++ b/xorg-server/os/backtrace.c @@ -46,7 +46,11 @@ void xorg_backtrace(void) ErrorF("\nBacktrace:\n"); size = backtrace(array, 64); for (i = 0; i < size; i++) { - dladdr(array[i], &info); + int rc = dladdr(array[i], &info); + if (rc == 0) { + ErrorF("%d: ?? [%p]\n", i, array[i]); + continue; + } mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)"; if (info.dli_saddr) ErrorF("%d: %s (%s+0x%lx) [%p]\n", i, mod, diff --git a/xorg-server/os/client.c b/xorg-server/os/client.c index 8f4707b09..fbccf22ed 100644 --- a/xorg-server/os/client.c +++ b/xorg-server/os/client.c @@ -64,6 +64,15 @@ #include <procfs.h> #endif +#ifdef __OpenBSD__ +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/types.h> + +#include <kvm.h> +#include <limits.h> +#endif + /** * Try to determine a PID for a client from its connection * information. This should be called only once when new client has @@ -172,7 +181,39 @@ void DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs) if (cmdargs && sp) *cmdargs = strdup(sp); } -#else /* not Solaris */ +#elif defined(__OpenBSD__) + /* on OpenBSD use kvm_getargv() */ + { + kvm_t *kd; + char errbuf[_POSIX2_LINE_MAX]; + char **argv; + struct kinfo_proc *kp; + size_t len = 0; + int i, n; + + kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, errbuf); + if (kd == NULL) + return; + kp = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &n); + if (n != 1) + return; + argv = kvm_getargv(kd, kp, 0); + *cmdname = strdup(argv[0]); + i = 1; + while (argv[i] != NULL) { + len += strlen(argv[i]) + 1; + i++; + } + *cmdargs = calloc(1, len); + i = 1; + while (argv[i] != NULL) { + strlcat(*cmdargs, argv[i], len); + strlcat(*cmdargs, " ", len); + i++; + } + kvm_close(kd); + } +#else /* Linux using /proc/pid/cmdline */ /* Check if /proc/pid/cmdline exists. It's not supported on all * operating systems. */ diff --git a/xorg-server/os/connection.c b/xorg-server/os/connection.c index 237bda811..1d80f22b3 100644 --- a/xorg-server/os/connection.c +++ b/xorg-server/os/connection.c @@ -774,7 +774,7 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time) free(oc); return NullClient; } - oc->local_client = ComputeLocalClient(client); + client->local = ComputeLocalClient(client); #if !defined(WIN32) ConnectionTranslation[fd] = client->index; #else @@ -902,6 +902,8 @@ EstablishNewConnections(ClientPtr clientUnused, pointer closure) * Fail a connection due to lack of client or file descriptor space ************/ +#define BOTIMEOUT 200 /* in milliseconds */ + static void ErrorConnMax(XtransConnInfo trans_conn) { @@ -909,7 +911,7 @@ ErrorConnMax(XtransConnInfo trans_conn) xConnSetupPrefix csp; char pad[3]; struct iovec iov[3]; - char byteOrder = 0; + char order = 0; int whichbyte = 1; struct timeval waittime; fd_set mask; @@ -922,16 +924,16 @@ ErrorConnMax(XtransConnInfo trans_conn) FD_SET(fd, &mask); (void)Select(fd + 1, &mask, NULL, NULL, &waittime); /* try to read the byte-order of the connection */ - (void)_XSERVTransRead(trans_conn, &byteOrder, 1); - if ((byteOrder == 'l') || (byteOrder == 'B')) + (void)_XSERVTransRead(trans_conn, &order, 1); + if (order == 'l' || order == 'B' || order == 'r' || order == 'R') { csp.success = xFalse; csp.lengthReason = sizeof(NOROOM) - 1; csp.length = (sizeof(NOROOM) + 2) >> 2; csp.majorVersion = X_PROTOCOL; csp.minorVersion = X_PROTOCOL_REVISION; - if (((*(char *) &whichbyte) && (byteOrder == 'B')) || - (!(*(char *) &whichbyte) && (byteOrder == 'l'))) + if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) || + (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) { swaps(&csp.majorVersion); swaps(&csp.minorVersion); @@ -1070,7 +1072,7 @@ CloseDownConnection(ClientPtr client) ErrorF("CloseDownConnection: client index = %d, socket fd = %d\n", client->index, oc->fd); #endif - if (oc->output && oc->output->count) + if (oc->output) FlushClient(client, oc, (char *)NULL, 0); #ifdef XDMCP XdmcpCloseDisplay(oc->fd); diff --git a/xorg-server/os/io.c b/xorg-server/os/io.c index 8a2207081..ad549c534 100644 --- a/xorg-server/os/io.c +++ b/xorg-server/os/io.c @@ -84,6 +84,23 @@ SOFTWARE. CallbackListPtr ReplyCallback; CallbackListPtr FlushCallback; +typedef struct _connectionInput { + struct _connectionInput *next; + char *buffer; /* contains current client input */ + char *bufptr; /* pointer to current start of data */ + int bufcnt; /* count of bytes in buffer */ + int lenLastReq; + int size; + unsigned int ignoreBytes; /* bytes to ignore before the next request */ +} ConnectionInput, *ConnectionInputPtr; + +typedef struct _connectionOutput { + struct _connectionOutput *next; + unsigned char *buf; + int size; + int count; +} ConnectionOutput, *ConnectionOutputPtr; + static ConnectionInputPtr AllocateInputBuffer(void); static ConnectionOutputPtr AllocateOutputBuffer(void); @@ -112,6 +129,8 @@ static OsCommPtr AvailableInput = (OsCommPtr)NULL; ((xBigReq *)(req))->length) #define MAX_TIMES_PER 10 +#define BUFSIZE 4096 +#define BUFWATERMARK 8192 /* * A lot of the code in this file manipulates a ConnectionInputPtr: @@ -889,7 +908,7 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) long notWritten; long todo; - if (!oco) + if (!oco || !oco->count) return 0; written = 0; padsize = padlength[extraCount & 3]; diff --git a/xorg-server/os/osdep.h b/xorg-server/os/osdep.h index 71a7e44e3..c9add48ee 100644 --- a/xorg-server/os/osdep.h +++ b/xorg-server/os/osdep.h @@ -52,10 +52,6 @@ SOFTWARE. #ifndef _OSDEP_H_ #define _OSDEP_H_ 1 -#define BOTIMEOUT 200 /* in milliseconds */ -#define BUFSIZE 4096 -#define BUFWATERMARK 8192 - #if defined(XDMCP) || defined(HASXDMAUTH) #include <X11/Xdmcp.h> #endif @@ -112,22 +108,8 @@ typedef Bool (*AddAuthorFunc)(unsigned name_length, const char *name, unsigned data_length, char *data); #endif -typedef struct _connectionInput { - struct _connectionInput *next; - char *buffer; /* contains current client input */ - char *bufptr; /* pointer to current start of data */ - int bufcnt; /* count of bytes in buffer */ - int lenLastReq; - int size; - unsigned int ignoreBytes; /* bytes to ignore before the next request */ -} ConnectionInput, *ConnectionInputPtr; - -typedef struct _connectionOutput { - struct _connectionOutput *next; - int size; - unsigned char *buf; - int count; -} ConnectionOutput, *ConnectionOutputPtr; +typedef struct _connectionInput *ConnectionInputPtr; +typedef struct _connectionOutput *ConnectionOutputPtr; struct _osComm; @@ -166,7 +148,6 @@ typedef struct _osComm { XID auth_id; /* authorization id */ CARD32 conn_time; /* timestamp if not established, else 0 */ struct _XtransConnInfo *trans_conn; /* transport connection object */ - Bool local_client; } OsCommRec, *OsCommPtr; extern int FlushClient( diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c index 10575c509..8f3c3dd2b 100644 --- a/xorg-server/xkb/xkbActions.c +++ b/xorg-server/xkb/xkbActions.c @@ -784,7 +784,7 @@ DeviceIntPtr kbd; filter->active= 0; return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); } - return 0; + return 1; } static int |