aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-10-27 08:37:52 +0200
committermarha <marha@users.sourceforge.net>2011-10-27 08:37:52 +0200
commit2a9be4af293f20fa33cc34fbc3b72e2235d91090 (patch)
treed41608bda1d56be1aa96857dee20e988b53760a3
parent9d53da0fbb9ae6df9a38ad40df4f53cd28287235 (diff)
parentd662d461634660f5c0f3998b5eb7d7ed3bd5a25f (diff)
downloadvcxsrv-2a9be4af293f20fa33cc34fbc3b72e2235d91090.tar.gz
vcxsrv-2a9be4af293f20fa33cc34fbc3b72e2235d91090.tar.bz2
vcxsrv-2a9be4af293f20fa33cc34fbc3b72e2235d91090.zip
Merge remote-tracking branch 'origin/released'
-rw-r--r--libX11/modules/lc/gen/lcGenConv.c9
-rw-r--r--libXft/src/xftglyphs.c3
-rw-r--r--mesalib/configs/linux-dri6
-rw-r--r--mesalib/configure.ac2
-rw-r--r--mesalib/docs/contents.html1
-rw-r--r--mesalib/docs/relnotes-7.12.html2
-rw-r--r--mesalib/docs/viewperf.html134
-rw-r--r--mesalib/include/GL/gl.h2
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.c286
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.h24
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_upload_mgr.c36
-rw-r--r--mesalib/src/glsl/Makefile1
-rw-r--r--mesalib/src/glsl/SConscript1
-rw-r--r--mesalib/src/glsl/builtin_variables.h6
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp23
-rw-r--r--mesalib/src/glsl/ir_constant_expression.cpp29
-rw-r--r--mesalib/src/glsl/ir_optimization.h6
-rw-r--r--mesalib/src/glsl/ir_variable.cpp20
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp85
-rw-r--r--mesalib/src/glsl/linker.cpp28
-rw-r--r--mesalib/src/glsl/linker.h43
-rw-r--r--mesalib/src/glsl/lower_if_to_cond_assign.cpp3
-rw-r--r--mesalib/src/glsl/main.cpp2
-rw-r--r--mesalib/src/glsl/opt_dead_code.cpp14
-rw-r--r--mesalib/src/glsl/ralloc.c28
-rw-r--r--mesalib/src/glsl/ralloc.h57
-rw-r--r--mesalib/src/glsl/test_optpass.cpp4
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/swrast.c5
-rw-r--r--mesalib/src/mesa/main/APIspec.xml6
-rw-r--r--mesalib/src/mesa/main/attrib.c223
-rw-r--r--mesalib/src/mesa/main/bufferobj.c13
-rw-r--r--mesalib/src/mesa/main/compiler.h2
-rw-r--r--mesalib/src/mesa/main/context.h4
-rw-r--r--mesalib/src/mesa/main/dlist.c2
-rw-r--r--mesalib/src/mesa/main/fbobject.c8
-rw-r--r--mesalib/src/mesa/main/ff_fragment_shader.cpp8
-rw-r--r--mesalib/src/mesa/main/imports.c2
-rw-r--r--mesalib/src/mesa/main/imports.h8
-rw-r--r--mesalib/src/mesa/main/mtypes.h20
-rw-r--r--mesalib/src/mesa/main/pack.c1
-rw-r--r--mesalib/src/mesa/main/pixelstore.c2
-rw-r--r--mesalib/src/mesa/main/state.c2
-rw-r--r--mesalib/src/mesa/main/texcompress.c4
-rw-r--r--mesalib/src/mesa/main/texcompress_fxt1.c4
-rw-r--r--mesalib/src/mesa/main/texcompress_rgtc.c24
-rw-r--r--mesalib/src/mesa/main/texcompress_s3tc.c18
-rw-r--r--mesalib/src/mesa/main/texformat.c4
-rw-r--r--mesalib/src/mesa/main/teximage.c140
-rw-r--r--mesalib/src/mesa/main/teximage.h11
-rw-r--r--mesalib/src/mesa/main/texobj.c41
-rw-r--r--mesalib/src/mesa/main/texstore.c10
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp56
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c58
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.c4
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.h1
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.c245
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c7
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp138
-rw-r--r--mesalib/src/mesa/swrast/s_context.c24
-rw-r--r--mesalib/src/mesa/swrast/s_context.h42
-rw-r--r--mesalib/src/mesa/swrast/s_fragprog.c3
-rw-r--r--mesalib/src/mesa/swrast/s_span.c5
-rw-r--r--mesalib/src/mesa/swrast/s_texcombine.c1
-rw-r--r--mesalib/src/mesa/swrast/s_texfetch_tmp.h8
-rw-r--r--mesalib/src/mesa/swrast/s_texfilter.c6
-rw-r--r--mesalib/src/mesa/swrast/s_texrender.c31
-rw-r--r--mesalib/src/mesa/swrast/s_texture.c175
-rw-r--r--mesalib/src/mesa/swrast/s_triangle.c18
-rw-r--r--mesalib/src/mesa/tnl/t_vb_program.c2
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec.h9
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c7
-rw-r--r--mesalib/src/mesa/vbo/vbo_save.h1
-rw-r--r--mkfontscale/data.h8
-rw-r--r--pixman/Makefile.am4
-rw-r--r--pixman/pixman/pixman-gradient-walker.c175
-rw-r--r--pixman/pixman/pixman-image.c73
-rw-r--r--pixman/pixman/pixman-private.h16
-rw-r--r--xorg-server/Xi/exevents.c20
-rw-r--r--xorg-server/Xi/xiquerydevice.c7
-rw-r--r--xorg-server/composite/compalloc.c11
-rw-r--r--xorg-server/configure.ac6
-rw-r--r--xorg-server/dix/devices.c2
-rw-r--r--xorg-server/dix/eventconvert.c67
-rw-r--r--xorg-server/dix/getevents.c42
-rw-r--r--xorg-server/dix/inpututils.c70
-rw-r--r--xorg-server/dix/ptrveloc.c4
-rw-r--r--xorg-server/hw/kdrive/src/kinput.c139
-rw-r--r--xorg-server/hw/vfb/InitOutput.c2
-rw-r--r--xorg-server/hw/xfree86/common/xf86Config.c16
-rw-r--r--xorg-server/hw/xfree86/common/xf86Events.c9
-rw-r--r--xorg-server/hw/xfree86/common/xf86Helper.c6
-rw-r--r--xorg-server/hw/xfree86/common/xf86Init.c29
-rw-r--r--xorg-server/hw/xfree86/common/xf86Option.c3
-rw-r--r--xorg-server/hw/xfree86/common/xf86Optionstr.h13
-rw-r--r--xorg-server/hw/xfree86/common/xf86Xinput.c5
-rw-r--r--xorg-server/hw/xfree86/doc/ddxDesign.xml4
-rw-r--r--xorg-server/hw/xfree86/loader/loadmod.c41
-rw-r--r--xorg-server/hw/xfree86/man/xorg.conf.man4
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Crtc.c66
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/lnx_init.c14
-rw-r--r--xorg-server/hw/xfree86/parser/Flags.c1009
-rw-r--r--xorg-server/hw/xfree86/parser/Layout.c1116
-rw-r--r--xorg-server/hw/xnest/Events.c2
-rw-r--r--xorg-server/hw/xnest/Keyboard.c519
-rw-r--r--xorg-server/hw/xquartz/darwin.c2
-rw-r--r--xorg-server/hw/xquartz/xpr/appledri.c137
-rw-r--r--xorg-server/hw/xquartz/xpr/appledristr.h298
-rw-r--r--xorg-server/hw/xwin/man/XWinrc.man10
-rw-r--r--xorg-server/include/eventstr.h1
-rw-r--r--xorg-server/include/exevents.h3
-rw-r--r--xorg-server/include/input.h7
-rw-r--r--xorg-server/include/inputstr.h7
-rw-r--r--xorg-server/include/list.h12
-rw-r--r--xorg-server/include/optionstr.h14
-rw-r--r--xorg-server/man/Xserver.man6
-rw-r--r--xorg-server/mi/mieq.c188
-rw-r--r--xorg-server/randr/rrproperty.c19
-rw-r--r--xorg-server/render/mipict.c61
-rw-r--r--xorg-server/render/mipict.h350
-rw-r--r--xorg-server/render/picture.c44
-rw-r--r--xorg-server/render/picturestr.h21
-rw-r--r--xorg-server/test/input.c99
-rw-r--r--xorg-server/test/xi2/protocol-eventconvert.c27
-rw-r--r--xorg-server/xkb/xkbActions.c7
124 files changed, 4282 insertions, 2791 deletions
diff --git a/libX11/modules/lc/gen/lcGenConv.c b/libX11/modules/lc/gen/lcGenConv.c
index 7a113a78a..42d63c529 100644
--- a/libX11/modules/lc/gen/lcGenConv.c
+++ b/libX11/modules/lc/gen/lcGenConv.c
@@ -1784,9 +1784,6 @@ mbtocs(
return( 0 );
}
- if (*from_left > *to_left)
- *from_left = *to_left;
-
while (*from_left && *to_left) {
ch = *inbufptr++;
@@ -1872,7 +1869,7 @@ output:
return -1;
}
- /* nomal end */
+ /* normal end */
*from = (XPointer) inbufptr;
*to = (XPointer) outbufptr;
@@ -2171,7 +2168,7 @@ end:
return -1;
}
- /* nomal end */
+ /* normal end */
*from = (XPointer) inbufptr;
*to = (XPointer) outbufptr;
@@ -2225,7 +2222,7 @@ end:
return -1;
}
- /* nomal end */
+ /* normal end */
*from = (XPointer) src;
*from_left = src_left;
diff --git a/libXft/src/xftglyphs.c b/libXft/src/xftglyphs.c
index 2639d12aa..4a3b9d606 100644
--- a/libXft/src/xftglyphs.c
+++ b/libXft/src/xftglyphs.c
@@ -570,6 +570,9 @@ XftFontLoadGlyphs (Display *dpy,
xftg->metrics.yOff = -TRUNC(ROUND(glyphslot->advance.y));
}
+ // compute the size of the final bitmap
+ ftbit = &glyphslot->bitmap;
+
width = ftbit->width;
height = ftbit->rows;
diff --git a/mesalib/configs/linux-dri b/mesalib/configs/linux-dri
index a3e9baba2..aa2dddc1c 100644
--- a/mesalib/configs/linux-dri
+++ b/mesalib/configs/linux-dri
@@ -58,9 +58,9 @@ SRC_DIRS := glx egl $(SRC_DIRS)
EGL_DRIVERS_DIRS = glx
DRIVER_DIRS = dri
-GALLIUM_WINSYS_DIRS = sw sw/xlib drm/vmware drm/intel drm/i965
-GALLIUM_TARGET_DIRS =
-GALLIUM_STATE_TRACKERS_DIRS = egl
+GALLIUM_WINSYS_DIRS = sw sw/xlib drm/vmware drm/intel drm/i965 svga/drm
+GALLIUM_TARGET_DIRS = dri-vmwgfx
+GALLIUM_STATE_TRACKERS_DIRS = egl dri
DRI_DIRS = i915 i965 nouveau r200 r300 r600 radeon swrast
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index 0864b55af..369614528 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -1858,7 +1858,7 @@ if test "x$with_gallium_drivers" != x; then
xnouveau)
PKG_CHECK_MODULES([NOUVEAU], [libdrm_nouveau >= $LIBDRM_NOUVEAU_REQUIRED])
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50 nvc0"
- gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau" "" "xvmc-nouveau"
+ gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau" "" "xvmc-nouveau" "vdpau-nouveau"
;;
xswrast)
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS softpipe"
diff --git a/mesalib/docs/contents.html b/mesalib/docs/contents.html
index df0fb6474..8882e7318 100644
--- a/mesalib/docs/contents.html
+++ b/mesalib/docs/contents.html
@@ -64,6 +64,7 @@ a:visited {
<LI><A HREF="mangling.html" target="MainFrame">Function Name Mangling</A>
<LI><A href="llvmpipe.html" target="MainFrame">Gallium llvmpipe driver</A>
<LI><A href="postprocess.html" target="MainFrame">Gallium post-processing</A>
+<LI><A href="viewperf.html" target="MainFrame">Viewperf Issues</A>
</ul>
<b>Developer Topics</b>
diff --git a/mesalib/docs/relnotes-7.12.html b/mesalib/docs/relnotes-7.12.html
index 4077dac49..514962112 100644
--- a/mesalib/docs/relnotes-7.12.html
+++ b/mesalib/docs/relnotes-7.12.html
@@ -36,7 +36,7 @@ tbd
<h2>New features</h2>
<ul>
-<li>GL_ARB_ES2_compatibility (r600g)
+<li>GL_ARB_ES2_compatibility (r300g, r600g)
<li>GL_ARB_depth_buffer_float (r600g)
<li>GL_ARB_vertex_type_2_10_10_10_rev (r600g)
<li>GL_EXT_packed_float (i965)
diff --git a/mesalib/docs/viewperf.html b/mesalib/docs/viewperf.html
new file mode 100644
index 000000000..cef584fd8
--- /dev/null
+++ b/mesalib/docs/viewperf.html
@@ -0,0 +1,134 @@
+<HTML>
+
+<TITLE>Viewperf Issues</TITLE>
+
+<link rel="stylesheet" type="text/css" href="mesa.css"></head>
+
+<BODY>
+
+<h1>Viewperf Issues</h1>
+
+<p>
+This page lists known issues with
+<a href="http://www.spec.org/gwpg/gpc.static/vp11info.html" target="_main">SPEC Viewperf 11</a>
+when running on Mesa-based drivers.
+</p>
+
+<p>
+The Viewperf data sets are basically GL API traces that are recorded from
+CAD applications, then replayed in the Viewperf framework.
+</p>
+
+<p>
+The primary problem with these traces is they blindly use features and
+OpenGL extensions that were supported by the OpenGL driver when the trace
+was recorded,
+but there's no checks to see if those features are supported by the driver
+when playing back the traces with Viewperf.
+</p>
+
+<p>
+These issues have been reported to the SPEC organization in the hope that
+they'll be fixed in the future.
+</p>
+
+
+
+<h2>Catia-03 tests 3, 4, 8</h2>
+
+<p>
+These tests use features of the
+<a href="http://www.opengl.org/registry/specs/NV/fragment_program2.txt"
+target="_main">
+GL_NV_fragment_program2</a> and
+<a href="http://www.opengl.org/registry/specs/NV/vertex_program3.txt"
+target="_main">
+GL_NV_vertex_program3</a> extensions without checking if the driver supports
+them.
+</p>
+<p>
+When Mesa tries to compile the vertex/fragment programs it generates errors
+(which Viewperf ignores).
+Subsequent drawing calls become no-ops and the rendering is incorrect.
+</p>
+
+
+
+<h2>sw-02 tests 1, 2, 4</h2>
+
+<p>
+These tests depend on the
+<a href="http://www.opengl.org/registry/specs/NV/primitive_restart.txt"
+target="_main">GL_NV_primitive_restart</a> extension.
+</p>
+
+<p>
+If the Mesa driver doesn't support this extension the rendering will
+be incorrect and the test will fail.
+</p>
+
+
+<h2>Lightwave-01 test 3</h2>
+
+<p>
+This test uses a number of mipmapped textures, but the textures are
+incomplete because the last/smallest mipmap level (1 x 1 pixel) is
+never specified.
+</p>
+
+<p>
+A trace captured with
+<a href="https://github.com/apitrace/apitrace" target="_main">API trace</a>
+shows this sequences of calls like this:
+
+<pre>
+2504 glBindTexture(target = GL_TEXTURE_2D, texture = 55)
+2505 glTexImage2D(target = GL_TEXTURE_2D, level = 0, internalformat = GL_RGBA, width = 512, height = 512, border = 0, format = GL_RGB, type = GL_UNSIGNED_SHORT, pixels = blob(1572864))
+2506 glTexImage2D(target = GL_TEXTURE_2D, level = 1, internalformat = GL_RGBA, width = 256, height = 256, border = 0, format = GL_RGB, type = GL_UNSIGNED_SHORT, pixels = blob(393216))
+2507 glTexImage2D(target = GL_TEXTURE_2D, level = 2, internalformat = GL_RGBA, width = 128, height = 128, border = 0, format = GL_RGB, type = GL_UNSIGNED_SHORT, pixels = blob(98304))
+[...]
+2512 glTexImage2D(target = GL_TEXTURE_2D, level = 7, internalformat = GL_RGBA, width = 4, height = 4, border = 0, format = GL_RGB, type = GL_UNSIGNED_SHORT, pixels = blob(96))
+2513 glTexImage2D(target = GL_TEXTURE_2D, level = 8, internalformat = GL_RGBA, width = 2, height = 2, border = 0, format = GL_RGB, type = GL_UNSIGNED_SHORT, pixels = blob(24))
+2514 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_MIN_FILTER, param = GL_LINEAR_MIPMAP_LINEAR)
+2515 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_WRAP_S, param = GL_REPEAT)
+2516 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_WRAP_T, param = GL_REPEAT)
+2517 glTexParameteri(target = GL_TEXTURE_2D, pname = GL_TEXTURE_MAG_FILTER, param = GL_NEAREST)
+</pre>
+
+<p>
+Note that one would expect call 2514 to be glTexImage(level=9, width=1,
+height=1) but it's not there.
+</p>
+
+<p>
+The minification filter is GL_LINEAR_MIPMAP_LINEAR and the texture's
+GL_TEXTURE_MAX_LEVEL is 1000 (the default) so a full mipmap is expected.
+</p>
+
+<p>
+Later, these incomplete textures are bound before drawing calls.
+According to the GL specification, if a fragment program or fragment shader
+is being used, the sampler should return (0,0,0,1) ("black") when sampling
+from an incomplete texture.
+This is what Mesa does and the resulting rendering is darker than it should
+be.
+</p>
+
+<p>
+It appears that NVIDIA's driver (and possibly AMD's driver) detects this case
+and returns (1,1,1,1) (white) which causes the rendering to appear brighter
+and match the reference image (however, AMD's rendering is <em>much</em>
+brighter than NVIDIA's).
+</p>
+
+<p>
+If the fallback texture created in _mesa_get_fallback_texture() is
+initialized to be full white instead of full black the rendering appears
+correct.
+However, we have no plans to implement this work-around in Mesa.
+
+</p>
+
+
+</BODY>
+</HTML>
diff --git a/mesalib/include/GL/gl.h b/mesalib/include/GL/gl.h
index 998a83ab1..e65e1bc8a 100644
--- a/mesalib/include/GL/gl.h
+++ b/mesalib/include/GL/gl.h
@@ -67,7 +67,7 @@
#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */
# define GLAPI extern
# define GLAPIENTRY __stdcall
-#elif defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+#elif (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# define GLAPI __attribute__((visibility("default")))
# define GLAPIENTRY
#endif /* WIN32 && !CYGWIN */
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c
index b0d538de6..f5cc5cb3b 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.c
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c
@@ -59,7 +59,6 @@ struct blitter_context_priv
float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */
/* Templates for various state objects. */
- struct pipe_sampler_state template_sampler_state;
/* Constant state objects. */
/* Vertex shaders. */
@@ -92,8 +91,8 @@ struct blitter_context_priv
void *velem_uint_state;
void *velem_sint_state;
- /* Sampler state for clamping to a miplevel. */
- void *sampler_state[PIPE_MAX_TEXTURE_LEVELS * 2];
+ /* Sampler state. */
+ void *sampler_state;
/* Rasterizer state. */
void *rs_state;
@@ -126,7 +125,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
struct pipe_blend_state blend;
struct pipe_depth_stencil_alpha_state dsa;
struct pipe_rasterizer_state rs_state;
- struct pipe_sampler_state *sampler_state;
+ struct pipe_sampler_state sampler_state;
struct pipe_vertex_element velem[2];
unsigned i;
@@ -192,13 +191,12 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
/* sampler state */
- sampler_state = &ctx->template_sampler_state;
- sampler_state->wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler_state->wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler_state->wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler_state->normalized_coords = TRUE;
- /* The sampler state objects which sample from a specified mipmap level
- * are created on-demand. */
+ memset(&sampler_state, 0, sizeof(sampler_state));
+ sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler_state.normalized_coords = 1;
+ ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state);
/* rasterizer state */
memset(&rs_state, 0, sizeof(rs_state));
@@ -292,10 +290,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
pipe->delete_fs_state(pipe, ctx->fs_col_int[i]);
}
- for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS * 2; i++)
- if (ctx->sampler_state[i])
- pipe->delete_sampler_state(pipe, ctx->sampler_state[i]);
-
+ pipe->delete_sampler_state(pipe, ctx->sampler_state);
pipe_resource_reference(&ctx->vbuf, NULL);
FREE(ctx);
}
@@ -497,21 +492,22 @@ static void blitter_set_clear_color(struct blitter_context_priv *ctx,
}
}
-static void get_texcoords(struct pipe_resource *src,
- unsigned level,
+static void get_texcoords(struct pipe_sampler_view *src,
+ unsigned src_width0, unsigned src_height0,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
- boolean normalized, float out[4])
+ float out[4])
{
- if(normalized)
- {
- out[0] = x1 / (float)u_minify(src->width0, level);
- out[1] = y1 / (float)u_minify(src->height0, level);
- out[2] = x2 / (float)u_minify(src->width0, level);
- out[3] = y2 / (float)u_minify(src->height0, level);
- }
- else
- {
+ struct pipe_resource *tex = src->texture;
+ unsigned level = src->u.tex.first_level;
+ boolean normalized = tex->target != PIPE_TEXTURE_RECT;
+
+ if (normalized) {
+ out[0] = x1 / (float)u_minify(src_width0, level);
+ out[1] = y1 / (float)u_minify(src_height0, level);
+ out[2] = x2 / (float)u_minify(src_width0, level);
+ out[3] = y2 / (float)u_minify(src_height0, level);
+ } else {
out[0] = x1;
out[1] = y1;
out[2] = x2;
@@ -535,76 +531,52 @@ static void set_texcoords_in_vertices(const float coord[4],
out[1] = coord[3]; /*t3.t*/
}
-static void blitter_set_texcoords_2d(struct blitter_context_priv *ctx,
- struct pipe_resource *src,
- unsigned level,
- unsigned x1, unsigned y1,
- unsigned x2, unsigned y2)
+static void blitter_set_texcoords(struct blitter_context_priv *ctx,
+ struct pipe_sampler_view *src,
+ unsigned src_width0, unsigned src_height0,
+ unsigned layer,
+ unsigned x1, unsigned y1,
+ unsigned x2, unsigned y2)
{
unsigned i;
float coord[4];
+ float face_coord[4][2];
- get_texcoords(src, level, x1, y1, x2, y2, TRUE, coord);
- set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
+ get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, coord);
- for (i = 0; i < 4; i++) {
- ctx->vertices[i][1][2] = 0; /*r*/
- ctx->vertices[i][1][3] = 1; /*q*/
+ if (src->texture->target == PIPE_TEXTURE_CUBE) {
+ set_texcoords_in_vertices(coord, &face_coord[0][0], 2);
+ util_map_texcoords2d_onto_cubemap(layer,
+ /* pointer, stride in floats */
+ &face_coord[0][0], 2,
+ &ctx->vertices[0][1][0], 8);
+ } else {
+ set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
}
-}
-
-static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
- struct pipe_resource *src,
- unsigned level,
- unsigned zslice,
- unsigned x1, unsigned y1,
- unsigned x2, unsigned y2,
- boolean normalized)
-{
- int i;
- float r = normalized ? zslice / (float)u_minify(src->depth0, level) : zslice;
-
- blitter_set_texcoords_2d(ctx, src, level, x1, y1, x2, y2);
-
- for (i = 0; i < 4; i++)
- ctx->vertices[i][1][2] = r; /*r*/
-}
-static void blitter_set_texcoords_1d_array(struct blitter_context_priv *ctx,
- struct pipe_resource *src,
- unsigned level,
- unsigned zslice,
- unsigned x1, unsigned x2)
-{
- int i;
- float r = zslice;
-
- blitter_set_texcoords_2d(ctx, src, level, x1, 0, x2, 0);
-
- for (i = 0; i < 4; i++)
- ctx->vertices[i][1][1] = r; /*r*/
-}
-
-static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
- struct pipe_resource *src,
- unsigned level, unsigned face,
- unsigned x1, unsigned y1,
- unsigned x2, unsigned y2)
-{
- int i;
- float coord[4];
- float st[4][2];
+ /* Set the layer. */
+ switch (src->texture->target) {
+ case PIPE_TEXTURE_3D:
+ {
+ float r = layer / (float)u_minify(src->texture->depth0,
+ src->u.tex.first_level);
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][1][2] = r; /*r*/
+ }
+ break;
- get_texcoords(src, level, x1, y1, x2, y2, TRUE, coord);
- set_texcoords_in_vertices(coord, &st[0][0], 2);
+ case PIPE_TEXTURE_1D_ARRAY:
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][1][1] = layer; /*t*/
+ break;
- util_map_texcoords2d_onto_cubemap(face,
- /* pointer, stride in floats */
- &st[0][0], 2,
- &ctx->vertices[0][1][0], 8);
+ case PIPE_TEXTURE_2D_ARRAY:
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][1][2] = layer; /*r*/
+ break;
- for (i = 0; i < 4; i++)
- ctx->vertices[i][1][3] = 1; /*q*/
+ default:;
+ }
}
static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
@@ -615,31 +587,6 @@ static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
}
static INLINE
-void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
- int miplevel, boolean normalized)
-{
- struct pipe_context *pipe = ctx->base.pipe;
- struct pipe_sampler_state *sampler_state = &ctx->template_sampler_state;
-
- assert(miplevel < PIPE_MAX_TEXTURE_LEVELS);
-
- /* Create the sampler state on-demand. */
- if (!ctx->sampler_state[miplevel * 2 + normalized]) {
- sampler_state->lod_bias = miplevel;
- sampler_state->min_lod = miplevel;
- sampler_state->max_lod = miplevel;
- sampler_state->normalized_coords = normalized;
-
- ctx->sampler_state[miplevel * 2 + normalized] = pipe->create_sampler_state(pipe,
- sampler_state);
- }
-
- /* Return void** so that it can be passed to bind_fragment_sampler_states
- * directly. */
- return &ctx->sampler_state[miplevel * 2 + normalized];
-}
-
-static INLINE
void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs,
boolean int_format)
{
@@ -864,27 +811,16 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
struct pipe_context *pipe = ctx->base.pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_surface *dstsurf, surf_templ;
- struct pipe_framebuffer_state fb_state;
struct pipe_sampler_view viewTempl, *view;
unsigned bind;
- unsigned width = srcbox->width;
- unsigned height = srcbox->height;
boolean is_stencil, is_depth;
- boolean normalized;
/* Give up if textures are not set. */
assert(dst && src);
if (!dst || !src)
return;
- /* Sanity checks. */
- if (dst == src) {
- assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height,
- dstx, dstx + width, dsty, dsty + height));
- }
assert(src->target < PIPE_MAX_TEXTURE_TYPES);
- /* XXX should handle 3d regions */
- assert(srcbox->depth == 1);
/* Is this a ZS format? */
is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
@@ -902,22 +838,60 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
dst->nr_samples, bind) ||
!screen->is_format_supported(screen, src->format, src->target,
src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
- ctx->base.running = TRUE;
+ blitter_set_running_flag(ctx);
util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz,
src, srclevel, srcbox);
- ctx->base.running = FALSE;
+ blitter_unset_running_flag(ctx);
return;
}
- /* Get surface. */
+ /* Initialize the surface. */
memset(&surf_templ, 0, sizeof(surf_templ));
u_surface_default_template(&surf_templ, dst, bind);
surf_templ.format = util_format_linear(dst->format);
surf_templ.u.tex.level = dstlevel;
surf_templ.u.tex.first_layer = dstz;
- surf_templ.u.tex.last_layer = dstz;
+ surf_templ.u.tex.last_layer = dstz + srcbox->depth - 1;
dstsurf = pipe->create_surface(pipe, dst, &surf_templ);
+ /* Initialize the sampler view. */
+ u_sampler_view_default_template(&viewTempl, src,
+ util_format_linear(src->format));
+ viewTempl.u.tex.first_level = srclevel;
+ viewTempl.u.tex.last_level = srclevel;
+ view = pipe->create_sampler_view(pipe, src, &viewTempl);
+
+ /* Copy. */
+ util_blitter_copy_texture_view(blitter, dstsurf, dstx, dsty, view, srcbox,
+ src->width0, src->height0);
+
+ pipe_surface_reference(&dstsurf, NULL);
+ pipe_sampler_view_reference(&view, NULL);
+}
+
+void util_blitter_copy_texture_view(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_sampler_view *src,
+ const struct pipe_box *srcbox,
+ unsigned src_width0, unsigned src_height0)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->base.pipe;
+ struct pipe_framebuffer_state fb_state;
+ enum pipe_texture_target src_target = src->texture->target;
+ unsigned width = srcbox->width;
+ unsigned height = srcbox->height;
+
+ /* Sanity checks. */
+ if (dst->texture == src->texture &&
+ dst->u.tex.level == src->u.tex.first_level) {
+ assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height,
+ dstx, dstx + width, dsty, dsty + height));
+ }
+ /* XXX should handle 3d regions */
+ assert(srcbox->depth == 1);
+
/* Check whether the states are properly saved. */
blitter_set_running_flag(ctx);
blitter_check_saved_vertex_states(ctx);
@@ -926,60 +900,55 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
blitter_check_saved_fb_state(ctx);
/* Initialize framebuffer state. */
- fb_state.width = dstsurf->width;
- fb_state.height = dstsurf->height;
+ fb_state.width = dst->width;
+ fb_state.height = dst->height;
- if (is_depth) {
+ if (util_format_is_depth_or_stencil(dst->format)) {
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
pipe->bind_depth_stencil_alpha_state(pipe,
ctx->dsa_write_depth_keep_stencil);
pipe->bind_fs_state(pipe,
- blitter_get_fs_texfetch_depth(ctx, src->target));
+ blitter_get_fs_texfetch_depth(ctx, src_target));
fb_state.nr_cbufs = 0;
- fb_state.zsbuf = dstsurf;
+ fb_state.zsbuf = dst;
} else {
pipe->bind_blend_state(pipe, ctx->blend_write_color);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_fs_state(pipe,
- blitter_get_fs_texfetch_col(ctx, src->target));
+ blitter_get_fs_texfetch_col(ctx, src_target));
fb_state.nr_cbufs = 1;
- fb_state.cbufs[0] = dstsurf;
+ fb_state.cbufs[0] = dst;
fb_state.zsbuf = 0;
}
- normalized = src->target != PIPE_TEXTURE_RECT;
-
- /* Initialize sampler view. */
- u_sampler_view_default_template(&viewTempl, src, util_format_linear(src->format));
- view = pipe->create_sampler_view(pipe, src, &viewTempl);
-
/* Set rasterizer state, shaders, and textures. */
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_vs_state(pipe, ctx->vs);
if (ctx->has_geometry_shader)
pipe->bind_gs_state(pipe, NULL);
- pipe->bind_fragment_sampler_states(pipe, 1,
- blitter_get_sampler_state(ctx, srclevel, normalized));
+ pipe->bind_fragment_sampler_states(pipe, 1, &ctx->sampler_state);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
- pipe->set_fragment_sampler_views(pipe, 1, &view);
+ pipe->set_fragment_sampler_views(pipe, 1, &src);
pipe->set_framebuffer_state(pipe, &fb_state);
- blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
+ blitter_set_dst_dimensions(ctx, dst->width, dst->height);
- switch (src->target) {
+ switch (src_target) {
/* Draw the quad with the draw_rectangle callback. */
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_RECT:
{
/* Set texture coordinates. - use a pipe color union
- * for interface purposes
+ * for interface purposes.
+ * XXX pipe_color_union is a wrong name since we use that to set
+ * texture coordinates too.
*/
union pipe_color_union coord;
- get_texcoords(src, srclevel, srcbox->x, srcbox->y,
- srcbox->x+width, srcbox->y+height, normalized, coord.f);
+ get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y,
+ srcbox->x+width, srcbox->y+height, coord.f);
/* Draw. */
blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
@@ -990,24 +959,14 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
/* Draw the quad with the generic codepath. */
default:
/* Set texture coordinates. */
- switch (src->target) {
+ switch (src_target) {
case PIPE_TEXTURE_1D_ARRAY:
- blitter_set_texcoords_1d_array(ctx, src, srclevel, srcbox->y,
- srcbox->x, srcbox->x + width);
- break;
-
case PIPE_TEXTURE_2D_ARRAY:
case PIPE_TEXTURE_3D:
- blitter_set_texcoords_3d(ctx, src, srclevel, srcbox->z,
- srcbox->x, srcbox->y,
- srcbox->x + width, srcbox->y + height,
- src->target == PIPE_TEXTURE_3D);
- break;
-
case PIPE_TEXTURE_CUBE:
- blitter_set_texcoords_cube(ctx, src, srclevel, srcbox->z,
- srcbox->x, srcbox->y,
- srcbox->x + width, srcbox->y + height);
+ blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z,
+ srcbox->y, srcbox->x,
+ srcbox->x + width, srcbox->y + height);
break;
default:
@@ -1028,9 +987,6 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
blitter_restore_textures(ctx);
blitter_restore_fb_state(ctx);
blitter_unset_running_flag(ctx);
-
- pipe_surface_reference(&dstsurf, NULL);
- pipe_sampler_view_reference(&view, NULL);
}
/* Clear a region of a color surface to a constant value. */
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.h b/mesalib/src/gallium/auxiliary/util/u_blitter.h
index 798096e74..3e1457ae0 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.h
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.h
@@ -190,6 +190,30 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
boolean ignore_stencil);
/**
+ * Same as util_blitter_copy_texture, but dst and src are pipe_surface and
+ * pipe_sampler_view, respectively. The mipmap level and dstz are part of
+ * the views.
+ *
+ * Drivers can use this to change resource properties (like format, width,
+ * height) by changing how the views interpret them, instead of changing
+ * pipe_resource directly. This is usually needed to accelerate copying of
+ * compressed formats.
+ *
+ * src_width0 and src_height0 are sampler_view-private properties that
+ * override pipe_resource. The blitter uses them for computation of texture
+ * coordinates. The dst dimensions are supplied through pipe_surface::width
+ * and height.
+ *
+ * NOTE: There are no checks whether the blit is actually supported.
+ */
+void util_blitter_copy_texture_view(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_sampler_view *src,
+ const struct pipe_box *srcbox,
+ unsigned src_width0, unsigned src_height0);
+
+/**
* Clear a region of a (color) surface to a constant value.
*
* These states must be saved in the blitter in addition to the state objects
diff --git a/mesalib/src/gallium/auxiliary/util/u_upload_mgr.c b/mesalib/src/gallium/auxiliary/util/u_upload_mgr.c
index 71fe53e3a..a2319d0c4 100644
--- a/mesalib/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/mesalib/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -131,8 +131,9 @@ u_upload_alloc_buffer( struct u_upload_mgr *upload,
upload->bind,
PIPE_USAGE_STREAM,
size );
- if (upload->buffer == NULL)
- goto fail;
+ if (upload->buffer == NULL) {
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
/* Map the new buffer. */
upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
@@ -140,17 +141,16 @@ u_upload_alloc_buffer( struct u_upload_mgr *upload,
PIPE_TRANSFER_WRITE |
PIPE_TRANSFER_FLUSH_EXPLICIT,
&upload->transfer);
-
+ if (upload->map == NULL) {
+ upload->size = 0;
+ pipe_resource_reference(&upload->buffer, NULL);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
+
upload->size = size;
upload->offset = 0;
- return 0;
-
-fail:
- if (upload->buffer)
- pipe_resource_reference( &upload->buffer, NULL );
-
- return PIPE_ERROR_OUT_OF_MEMORY;
+ return PIPE_OK;
}
enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
@@ -170,7 +170,7 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
if (MAX2(upload->offset, alloc_offset) + alloc_size > upload->size) {
enum pipe_error ret = u_upload_alloc_buffer(upload,
alloc_offset + alloc_size);
- if (ret)
+ if (ret != PIPE_OK)
return ret;
*flushed = TRUE;
@@ -187,6 +187,11 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
PIPE_TRANSFER_FLUSH_EXPLICIT |
PIPE_TRANSFER_UNSYNCHRONIZED,
&upload->transfer);
+ if (!upload->map) {
+ pipe_resource_reference(outbuf, NULL);
+ *ptr = NULL;
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
}
assert(offset < upload->buffer->width0);
@@ -214,7 +219,7 @@ enum pipe_error u_upload_data( struct u_upload_mgr *upload,
enum pipe_error ret = u_upload_alloc(upload, min_out_offset, size,
out_offset, outbuf, flushed,
(void**)&ptr);
- if (ret)
+ if (ret != PIPE_OK)
return ret;
memcpy(ptr, data, size);
@@ -247,8 +252,7 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
&transfer);
if (map == NULL) {
- ret = PIPE_ERROR_OUT_OF_MEMORY;
- goto done;
+ return PIPE_ERROR_OUT_OF_MEMORY;
}
if (0)
@@ -261,9 +265,7 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
out_offset,
outbuf, flushed );
-done:
- if (map)
- pipe_buffer_unmap( upload->pipe, transfer );
+ pipe_buffer_unmap( upload->pipe, transfer );
return ret;
}
diff --git a/mesalib/src/glsl/Makefile b/mesalib/src/glsl/Makefile
index b2efb2abc..504f1fb43 100644
--- a/mesalib/src/glsl/Makefile
+++ b/mesalib/src/glsl/Makefile
@@ -53,6 +53,7 @@ CXX_SOURCES = \
ir_variable_refcount.cpp \
linker.cpp \
link_functions.cpp \
+ link_uniforms.cpp \
loop_analysis.cpp \
loop_controls.cpp \
loop_unroll.cpp \
diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript
index b4786c5e5..09c7edbc4 100644
--- a/mesalib/src/glsl/SConscript
+++ b/mesalib/src/glsl/SConscript
@@ -64,6 +64,7 @@ glsl_sources = [
'ir_variable_refcount.cpp',
'linker.cpp',
'link_functions.cpp',
+ 'link_uniforms.cpp',
'loop_analysis.cpp',
'loop_controls.cpp',
'loop_unroll.cpp',
diff --git a/mesalib/src/glsl/builtin_variables.h b/mesalib/src/glsl/builtin_variables.h
index d25bbf42a..237b361d8 100644
--- a/mesalib/src/glsl/builtin_variables.h
+++ b/mesalib/src/glsl/builtin_variables.h
@@ -103,8 +103,8 @@ static const builtin_variable builtin_110_deprecated_uniforms[] = {
{ ir_var_uniform, -1, "gl_LightModelParameters", "gl_LightModel"},
/* Mesa-internal ATI_envmap_bumpmap state. */
- { ir_var_uniform, -1, "vec2", "gl_MESABumpRotMatrix0"},
- { ir_var_uniform, -1, "vec2", "gl_MESABumpRotMatrix1"},
- { ir_var_uniform, -1, "vec4", "gl_MESAFogParamsOptimized"},
+ { ir_var_uniform, -1, "vec2", "gl_BumpRotMatrix0MESA"},
+ { ir_var_uniform, -1, "vec2", "gl_BumpRotMatrix1MESA"},
+ { ir_var_uniform, -1, "vec4", "gl_FogParamsOptimizedMESA"},
};
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index a9075b2b1..e2112fe6d 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -883,8 +883,27 @@ ast_struct_specifier::ast_struct_specifier(char *identifier,
this->declarations.push_degenerate_list_at_head(&declarator_list->link);
}
+/**
+ * Do the set of common optimizations passes
+ *
+ * \param ir List of instructions to be optimized
+ * \param linked Is the shader linked? This enables
+ * optimizations passes that remove code at
+ * global scope and could cause linking to
+ * fail.
+ * \param uniform_locations_assigned Have locations already been assigned for
+ * uniforms? This prevents the declarations
+ * of unused uniforms from being removed.
+ * The setting of this flag only matters if
+ * \c linked is \c true.
+ * \param max_unroll_iterations Maximum number of loop iterations to be
+ * unrolled. Setting to 0 forces all loops
+ * to be unrolled.
+ */
bool
-do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations)
+do_common_optimization(exec_list *ir, bool linked,
+ bool uniform_locations_assigned,
+ unsigned max_unroll_iterations)
{
GLboolean progress = GL_FALSE;
@@ -900,7 +919,7 @@ do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iteration
progress = do_copy_propagation(ir) || progress;
progress = do_copy_propagation_elements(ir) || progress;
if (linked)
- progress = do_dead_code(ir) || progress;
+ progress = do_dead_code(ir, uniform_locations_assigned) || progress;
else
progress = do_dead_code_unlinked(ir) || progress;
progress = do_dead_code_local(ir) || progress;
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index b3fe6cf96..83f084d88 100644
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -39,6 +39,25 @@
#include "ir_visitor.h"
#include "glsl_types.h"
+/* Using C99 rounding functions for roundToEven() implementation is
+ * difficult, because round(), rint, and nearbyint() are affected by
+ * fesetenv(), which the application may have done for its own
+ * purposes. Mesa's IROUND macro is close to what we want, but it
+ * rounds away from 0 on n + 0.5.
+ */
+static int
+round_to_even(float val)
+{
+ int rounded = IROUND(val);
+
+ if (val - floor(val) == 0.5) {
+ if (rounded % 2 != 0)
+ rounded += val > 0 ? -1 : 1;
+ }
+
+ return rounded;
+}
+
static float
dot(ir_constant *op0, ir_constant *op1)
{
@@ -196,6 +215,13 @@ ir_expression::constant_expression_value()
}
break;
+ case ir_unop_round_even:
+ assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.f[c] = round_to_even(op[0]->value.f[c]);
+ }
+ break;
+
case ir_unop_ceil:
assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
for (unsigned c = 0; c < op[0]->type->components(); c++) {
@@ -1324,6 +1350,9 @@ ir_call::constant_expression_value()
* op[1]->value.f[c];
}
}
+ } else if (strcmp(callee, "round") == 0 ||
+ strcmp(callee, "roundEven") == 0) {
+ expr = new(mem_ctx) ir_expression(ir_unop_round_even, op[0]);
} else if (strcmp(callee, "sign") == 0) {
expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
} else if (strcmp(callee, "sin") == 0) {
diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h
index af80e26b9..7b32e84f0 100644
--- a/mesalib/src/glsl/ir_optimization.h
+++ b/mesalib/src/glsl/ir_optimization.h
@@ -37,7 +37,9 @@
#define MOD_TO_FRACT 0x20
#define INT_DIV_TO_MUL_RCP 0x40
-bool do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations);
+bool do_common_optimization(exec_list *ir, bool linked,
+ bool uniform_locations_assigned,
+ unsigned max_unroll_iterations);
bool do_algebraic(exec_list *instructions);
bool do_constant_folding(exec_list *instructions);
@@ -46,7 +48,7 @@ bool do_constant_variable_unlinked(exec_list *instructions);
bool do_copy_propagation(exec_list *instructions);
bool do_copy_propagation_elements(exec_list *instructions);
bool do_constant_propagation(exec_list *instructions);
-bool do_dead_code(exec_list *instructions);
+bool do_dead_code(exec_list *instructions, bool uniform_locations_assigned);
bool do_dead_code_local(exec_list *instructions);
bool do_dead_code_unlinked(exec_list *instructions);
bool do_dead_functions(exec_list *instructions);
diff --git a/mesalib/src/glsl/ir_variable.cpp b/mesalib/src/glsl/ir_variable.cpp
index 6ae3b1f9e..1ee84d219 100644
--- a/mesalib/src/glsl/ir_variable.cpp
+++ b/mesalib/src/glsl/ir_variable.cpp
@@ -166,15 +166,15 @@ static struct gl_builtin_uniform_element gl_NormalScale_elements[] = {
{NULL, {STATE_NORMAL_SCALE}, SWIZZLE_XXXX},
};
-static struct gl_builtin_uniform_element gl_MESABumpRotMatrix0_elements[] = {
+static struct gl_builtin_uniform_element gl_BumpRotMatrix0MESA_elements[] = {
{NULL, {STATE_INTERNAL, STATE_ROT_MATRIX_0}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_MESABumpRotMatrix1_elements[] = {
+static struct gl_builtin_uniform_element gl_BumpRotMatrix1MESA_elements[] = {
{NULL, {STATE_INTERNAL, STATE_ROT_MATRIX_1}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_MESAFogParamsOptimized_elements[] = {
+static struct gl_builtin_uniform_element gl_FogParamsOptimizedMESA_elements[] = {
{NULL, {STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED}, SWIZZLE_XYZW},
};
@@ -232,11 +232,11 @@ MATRIX(gl_TextureMatrixInverseTranspose,
static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = {
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE},
- SWIZZLE_XYZW },
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) },
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE},
- SWIZZLE_XYZW },
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) },
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 2, 2, STATE_MATRIX_INVERSE},
- SWIZZLE_XYZW },
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) },
};
#undef MATRIX
@@ -289,9 +289,9 @@ const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
STATEVAR(gl_NormalMatrix),
STATEVAR(gl_NormalScale),
- STATEVAR(gl_MESABumpRotMatrix0),
- STATEVAR(gl_MESABumpRotMatrix1),
- STATEVAR(gl_MESAFogParamsOptimized),
+ STATEVAR(gl_BumpRotMatrix0MESA),
+ STATEVAR(gl_BumpRotMatrix1MESA),
+ STATEVAR(gl_FogParamsOptimizedMESA),
STATEVAR(gl_CurrentAttribVertMESA),
STATEVAR(gl_CurrentAttribFragMESA),
@@ -615,6 +615,8 @@ generate_130_uniforms(exec_list *instructions,
add_builtin_constant(instructions, symtab, "gl_MaxClipDistances",
state->Const.MaxClipPlanes);
+ add_builtin_constant(instructions, symtab, "gl_MaxVaryingComponents",
+ state->Const.MaxVaryingFloats);
}
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
new file mode 100644
index 000000000..6dd1f5354
--- /dev/null
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "main/core.h"
+#include "ir.h"
+#include "linker.h"
+#include "glsl_symbol_table.h"
+#include "program/hash_table.h"
+
+/**
+ * \file link_uniforms.cpp
+ * Assign locations for GLSL uniforms.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+void
+uniform_field_visitor::process(ir_variable *var)
+{
+ const glsl_type *t = var->type;
+
+ /* Only strdup the name if we actually will need to modify it. */
+ if (t->is_record() || (t->is_array() && t->fields.array->is_record())) {
+ char *name = ralloc_strdup(NULL, var->name);
+ recursion(var->type, &name, strlen(name));
+ ralloc_free(name);
+ } else {
+ this->visit_field(t, var->name);
+ }
+}
+
+void
+uniform_field_visitor::recursion(const glsl_type *t, char **name,
+ unsigned name_length)
+{
+ /* Records need to have each field processed individually.
+ *
+ * Arrays of records need to have each array element processed
+ * individually, then each field of the resulting array elements processed
+ * individually.
+ */
+ if (t->is_record()) {
+ for (unsigned i = 0; i < t->length; i++) {
+ const char *field = t->fields.structure[i].name;
+
+ /* Append '.field' to the current uniform name. */
+ ralloc_asprintf_rewrite_tail(name, name_length, ".%s", field);
+
+ recursion(t->fields.structure[i].type, name,
+ name_length + 1 + strlen(field));
+ }
+ } else if (t->is_array() && t->fields.array->is_record()) {
+ for (unsigned i = 0; i < t->length; i++) {
+ char subscript[13];
+
+ /* Append the subscript to the current uniform name */
+ const unsigned subscript_length = snprintf(subscript, 13, "[%u]", i);
+ ralloc_asprintf_rewrite_tail(name, name_length, "%s", subscript);
+
+ recursion(t->fields.array, name, name_length + subscript_length);
+ }
+ } else {
+ this->visit_field(t, *name);
+ }
+}
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index a7c38a342..beadec6f6 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -1742,14 +1742,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
if (ctx->ShaderCompilerOptions[i].LowerClipDistance)
lower_clip_distance(prog->_LinkedShaders[i]->ir);
- while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32))
+ while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, false, 32))
;
}
- update_array_sizes(prog);
-
- assign_uniform_locations(prog);
-
/* FINISHME: The value of the max_attribute_index parameter is
* FINISHME: implementation dependent based on the value of
* FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be
@@ -1785,6 +1781,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
demote_shader_inputs_and_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX],
ir_var_out);
+
+ /* Eliminate code that is now dead due to unused vertex outputs being
+ * demoted.
+ */
+ while (do_dead_code(prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir, false))
+ ;
}
if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
@@ -1793,14 +1795,30 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
demote_shader_inputs_and_outputs(sh, ir_var_in);
demote_shader_inputs_and_outputs(sh, ir_var_inout);
demote_shader_inputs_and_outputs(sh, ir_var_out);
+
+ /* Eliminate code that is now dead due to unused geometry outputs being
+ * demoted.
+ */
+ while (do_dead_code(prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir, false))
+ ;
}
if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
demote_shader_inputs_and_outputs(sh, ir_var_in);
+
+ /* Eliminate code that is now dead due to unused fragment inputs being
+ * demoted. This shouldn't actually do anything other than remove
+ * declarations of the (now unused) global variables.
+ */
+ while (do_dead_code(prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir, false))
+ ;
}
+ update_array_sizes(prog);
+ assign_uniform_locations(prog);
+
/* OpenGL ES requires that a vertex shader and a fragment shader both be
* present in a linked program. By checking for use of shading language
* version 1.00, we also catch the GL_ARB_ES2_compatibility case.
diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h
index 769cf68b6..78c632961 100644
--- a/mesalib/src/glsl/linker.h
+++ b/mesalib/src/glsl/linker.h
@@ -1,3 +1,4 @@
+/* -*- c++ -*- */
/*
* Copyright © 2010 Intel Corporation
*
@@ -29,4 +30,46 @@ extern bool
link_function_calls(gl_shader_program *prog, gl_shader *main,
gl_shader **shader_list, unsigned num_shaders);
+/**
+ * Class for processing all of the leaf fields of an uniform
+ *
+ * Leaves are, roughly speaking, the parts of the uniform that the application
+ * could query with \c glGetUniformLocation (or that could be returned by
+ * \c glGetActiveUniforms).
+ *
+ * Classes my derive from this class to implement specific functionality.
+ * This class only provides the mechanism to iterate over the leaves. Derived
+ * classes must implement \c ::visit_field and may override \c ::process.
+ */
+class uniform_field_visitor {
+public:
+ /**
+ * Begin processing a uniform
+ *
+ * Classes that overload this function should call \c ::process from the
+ * base class to start the recursive processing of the uniform.
+ *
+ * \param var The uniform variable that is to be processed
+ *
+ * Calls \c ::visit_field for each leaf of the uniform.
+ */
+ void process(ir_variable *var);
+
+protected:
+ /**
+ * Method invoked for each leaf of the uniform
+ *
+ * \param type Type of the field.
+ * \param name Fully qualified name of the field.
+ */
+ virtual void visit_field(const glsl_type *type, const char *name) = 0;
+
+private:
+ /**
+ * \param name_length Length of the current name \b not including the
+ * terminating \c NUL character.
+ */
+ void recursion(const glsl_type *t, char **name, unsigned name_length);
+};
+
#endif /* GLSL_LINKER_H */
diff --git a/mesalib/src/glsl/lower_if_to_cond_assign.cpp b/mesalib/src/glsl/lower_if_to_cond_assign.cpp
index 7b89a1539..2c5d5612d 100644
--- a/mesalib/src/glsl/lower_if_to_cond_assign.cpp
+++ b/mesalib/src/glsl/lower_if_to_cond_assign.cpp
@@ -79,6 +79,9 @@ public:
bool
lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth)
{
+ if (max_depth == UINT_MAX)
+ return false;
+
ir_if_to_cond_assign_visitor v(max_depth);
visit_list_elements(&v, instructions);
diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp
index f0d951514..519abb5b5 100644
--- a/mesalib/src/glsl/main.cpp
+++ b/mesalib/src/glsl/main.cpp
@@ -177,7 +177,7 @@ compile_shader(struct gl_context *ctx, struct gl_shader *shader)
if (!state->error && !shader->ir->is_empty()) {
bool progress;
do {
- progress = do_common_optimization(shader->ir, false, 32);
+ progress = do_common_optimization(shader->ir, false, false, 32);
} while (progress);
validate_ir_tree(shader->ir);
diff --git a/mesalib/src/glsl/opt_dead_code.cpp b/mesalib/src/glsl/opt_dead_code.cpp
index cb500d2d1..5b9546ad4 100644
--- a/mesalib/src/glsl/opt_dead_code.cpp
+++ b/mesalib/src/glsl/opt_dead_code.cpp
@@ -42,7 +42,7 @@ static bool debug = false;
* for usage on an unlinked instruction stream.
*/
bool
-do_dead_code(exec_list *instructions)
+do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
{
ir_variable_refcount_visitor v;
bool progress = false;
@@ -94,10 +94,11 @@ do_dead_code(exec_list *instructions)
*/
/* uniform initializers are precious, and could get used by another
- * stage.
+ * stage. Also, once uniform locations have been assigned, the
+ * declaration cannot be deleted.
*/
if (entry->var->mode == ir_var_uniform &&
- entry->var->constant_value)
+ (uniform_locations_assigned || entry->var->constant_value))
continue;
entry->var->remove();
@@ -132,7 +133,12 @@ do_dead_code_unlinked(exec_list *instructions)
foreach_iter(exec_list_iterator, sigiter, *f) {
ir_function_signature *sig =
(ir_function_signature *) sigiter.get();
- if (do_dead_code(&sig->body))
+ /* The setting of the uniform_locations_assigned flag here is
+ * irrelevent. If there is a uniform declaration encountered
+ * inside the body of the function, something has already gone
+ * terribly, terribly wrong.
+ */
+ if (do_dead_code(&sig->body, false))
progress = true;
}
}
diff --git a/mesalib/src/glsl/ralloc.c b/mesalib/src/glsl/ralloc.c
index fb48a91c5..f5f3934ac 100644
--- a/mesalib/src/glsl/ralloc.c
+++ b/mesalib/src/glsl/ralloc.c
@@ -439,7 +439,28 @@ ralloc_asprintf_append(char **str, const char *fmt, ...)
bool
ralloc_vasprintf_append(char **str, const char *fmt, va_list args)
{
- size_t existing_length, new_length;
+ size_t existing_length;
+ assert(str != NULL);
+ existing_length = *str ? strlen(*str) : 0;
+ return ralloc_vasprintf_rewrite_tail(str, existing_length, fmt, args);
+}
+
+bool
+ralloc_asprintf_rewrite_tail(char **str, size_t start, const char *fmt, ...)
+{
+ bool success;
+ va_list args;
+ va_start(args, fmt);
+ success = ralloc_vasprintf_rewrite_tail(str, start, fmt, args);
+ va_end(args);
+ return success;
+}
+
+bool
+ralloc_vasprintf_rewrite_tail(char **str, size_t start, const char *fmt,
+ va_list args)
+{
+ size_t new_length;
char *ptr;
assert(str != NULL);
@@ -450,14 +471,13 @@ ralloc_vasprintf_append(char **str, const char *fmt, va_list args)
return true;
}
- existing_length = strlen(*str);
new_length = printf_length(fmt, args);
- ptr = resize(*str, existing_length + new_length + 1);
+ ptr = resize(*str, start + new_length + 1);
if (unlikely(ptr == NULL))
return false;
- vsnprintf(ptr + existing_length, new_length + 1, fmt, args);
+ vsnprintf(ptr + start, new_length + 1, fmt, args);
*str = ptr;
return true;
}
diff --git a/mesalib/src/glsl/ralloc.h b/mesalib/src/glsl/ralloc.h
index d5338152f..1324f3466 100644
--- a/mesalib/src/glsl/ralloc.h
+++ b/mesalib/src/glsl/ralloc.h
@@ -314,9 +314,60 @@ char *ralloc_asprintf (const void *ctx, const char *fmt, ...);
char *ralloc_vasprintf(const void *ctx, const char *fmt, va_list args);
/**
+ * Rewrite the tail of an existing string, starting at a given index.
+ *
+ * Overwrites the contents of *str starting at \p start with newly formatted
+ * text, including a new null-terminator. Allocates more memory as necessary.
+ *
+ * This can be used to append formatted text when the length of the existing
+ * string is already known, saving a strlen() call.
+ *
+ * \sa ralloc_asprintf_append
+ *
+ * \param str The string to be updated.
+ * \param start The index to start appending new data at.
+ * \param fmt A printf-style formatting string
+ *
+ * \p str will be updated to the new pointer unless allocation fails.
+ *
+ * \return True unless allocation failed.
+ */
+bool ralloc_asprintf_rewrite_tail(char **str, size_t start,
+ const char *fmt, ...);
+
+/**
+ * Rewrite the tail of an existing string, starting at a given index.
+ *
+ * Overwrites the contents of *str starting at \p start with newly formatted
+ * text, including a new null-terminator. Allocates more memory as necessary.
+ *
+ * This can be used to append formatted text when the length of the existing
+ * string is already known, saving a strlen() call.
+ *
+ * \sa ralloc_vasprintf_append
+ *
+ * \param str The string to be updated.
+ * \param start The index to start appending new data at.
+ * \param fmt A printf-style formatting string
+ * \param args A va_list containing the data to be formatted
+ *
+ * \p str will be updated to the new pointer unless allocation fails.
+ *
+ * \return True unless allocation failed.
+ */
+bool ralloc_vasprintf_rewrite_tail(char **str, size_t start, const char *fmt,
+ va_list args);
+
+/**
* Append formatted text to the supplied string.
*
+ * This is equivalent to
+ * \code
+ * ralloc_asprintf_rewrite_tail(str, strlen(*str), fmt, ...)
+ * \endcode
+ *
* \sa ralloc_asprintf
+ * \sa ralloc_asprintf_rewrite_tail
* \sa ralloc_strcat
*
* \p str will be updated to the new pointer unless allocation fails.
@@ -328,7 +379,13 @@ bool ralloc_asprintf_append (char **str, const char *fmt, ...);
/**
* Append formatted text to the supplied string, given a va_list.
*
+ * This is equivalent to
+ * \code
+ * ralloc_vasprintf_rewrite_tail(str, strlen(*str), fmt, args)
+ * \endcode
+ *
* \sa ralloc_vasprintf
+ * \sa ralloc_vasprintf_rewrite_tail
* \sa ralloc_strcat
*
* \p str will be updated to the new pointer unless allocation fails.
diff --git a/mesalib/src/glsl/test_optpass.cpp b/mesalib/src/glsl/test_optpass.cpp
index 89b7f8338..6abafb5d3 100644
--- a/mesalib/src/glsl/test_optpass.cpp
+++ b/mesalib/src/glsl/test_optpass.cpp
@@ -64,7 +64,7 @@ do_optimization(struct exec_list *ir, const char *optimization)
if (sscanf(optimization, "do_common_optimization ( %d , %d ) ",
&int_0, &int_1) == 2) {
- return do_common_optimization(ir, int_0 != 0, int_1);
+ return do_common_optimization(ir, int_0 != 0, false, int_1);
} else if (strcmp(optimization, "do_algebraic") == 0) {
return do_algebraic(ir);
} else if (strcmp(optimization, "do_constant_folding") == 0) {
@@ -80,7 +80,7 @@ do_optimization(struct exec_list *ir, const char *optimization)
} else if (strcmp(optimization, "do_constant_propagation") == 0) {
return do_constant_propagation(ir);
} else if (strcmp(optimization, "do_dead_code") == 0) {
- return do_dead_code(ir);
+ return do_dead_code(ir, false);
} else if (strcmp(optimization, "do_dead_code_local") == 0) {
return do_dead_code_local(ir);
} else if (strcmp(optimization, "do_dead_code_unlinked") == 0) {
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
index 1bf39435b..b1abc502f 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
@@ -57,6 +57,7 @@
#include "main/texstate.h"
#include "swrast_priv.h"
+#include "swrast/s_context.h"
/**
@@ -72,6 +73,7 @@ static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+ struct swrast_texture_image *swImage;
uint32_t internalFormat;
gl_format texFormat;
@@ -82,6 +84,7 @@ static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base);
texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target);
texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0);
+ swImage = swrast_texture_image(texImage);
_mesa_lock_texture(&dri_ctx->Base, texObj);
@@ -95,7 +98,7 @@ static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
_mesa_init_teximage_fields(&dri_ctx->Base, target, texImage,
w, h, 1, 0, internalFormat, texFormat);
- sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)texImage->Data,
+ sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)swImage->Data,
dPriv->loaderPrivate);
_mesa_unlock_texture(&dri_ctx->Base, texObj);
diff --git a/mesalib/src/mesa/main/APIspec.xml b/mesalib/src/mesa/main/APIspec.xml
index 574480e28..a92bb437c 100644
--- a/mesalib/src/mesa/main/APIspec.xml
+++ b/mesalib/src/mesa/main/APIspec.xml
@@ -631,12 +631,6 @@
<desc name="pname">
<value name="GL_RGB_SCALE"/>
<value name="GL_ALPHA_SCALE"/>
-
- <desc name="param" convert="true" error="GL_INVALID_VALUE">
- <value name="1.0"/>
- <value name="2.0"/>
- <value name="4.0"/>
- </desc>
</desc>
<desc name="pname">
diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c
index e67957d4d..1dc1c1b97 100644
--- a/mesalib/src/mesa/main/attrib.c
+++ b/mesalib/src/mesa/main/attrib.c
@@ -1279,30 +1279,6 @@ _mesa_PopAttrib(void)
/**
- * Helper for incrementing/decrementing vertex buffer object reference
- * counts when pushing/popping the GL_CLIENT_VERTEX_ARRAY_BIT attribute group.
- */
-static void
-adjust_buffer_object_ref_counts(struct gl_array_object *arrayObj, GLint step)
-{
- GLuint i;
-
- arrayObj->Vertex.BufferObj->RefCount += step;
- arrayObj->Weight.BufferObj->RefCount += step;
- arrayObj->Normal.BufferObj->RefCount += step;
- arrayObj->Color.BufferObj->RefCount += step;
- arrayObj->SecondaryColor.BufferObj->RefCount += step;
- arrayObj->FogCoord.BufferObj->RefCount += step;
- arrayObj->Index.BufferObj->RefCount += step;
- arrayObj->EdgeFlag.BufferObj->RefCount += step;
- for (i = 0; i < Elements(arrayObj->TexCoord); i++)
- arrayObj->TexCoord[i].BufferObj->RefCount += step;
- for (i = 0; i < Elements(arrayObj->VertexAttrib); i++)
- arrayObj->VertexAttrib[i].BufferObj->RefCount += step;
-}
-
-
-/**
* Copy gl_pixelstore_attrib from src to dst, updating buffer
* object refcounts.
*/
@@ -1327,6 +1303,151 @@ copy_pixelstore(struct gl_context *ctx,
#define GL_CLIENT_PACK_BIT (1<<20)
#define GL_CLIENT_UNPACK_BIT (1<<21)
+/**
+ * Copy gl_array_object from src to dest.
+ * 'dest' must be in an initialized state.
+ */
+static void
+copy_array_object(struct gl_context *ctx,
+ struct gl_array_object *dest,
+ struct gl_array_object *src)
+{
+ GLuint i;
+
+ /* skip Name */
+ /* skip RefCount */
+
+ /* In theory must be the same anyway, but on recreate make sure it matches */
+ dest->VBOonly = src->VBOonly;
+
+ _mesa_copy_client_array(ctx, &dest->Vertex, &src->Vertex);
+ _mesa_copy_client_array(ctx, &dest->Weight, &src->Weight);
+ _mesa_copy_client_array(ctx, &dest->Normal, &src->Normal);
+ _mesa_copy_client_array(ctx, &dest->Color, &src->Color);
+ _mesa_copy_client_array(ctx, &dest->SecondaryColor, &src->SecondaryColor);
+ _mesa_copy_client_array(ctx, &dest->FogCoord, &src->FogCoord);
+ _mesa_copy_client_array(ctx, &dest->Index, &src->Index);
+ _mesa_copy_client_array(ctx, &dest->EdgeFlag, &src->EdgeFlag);
+#if FEATURE_point_size_array
+ _mesa_copy_client_array(ctx, &dest->PointSize, &src->PointSize);
+#endif
+ for (i = 0; i < Elements(src->TexCoord); i++)
+ _mesa_copy_client_array(ctx, &dest->TexCoord[i], &src->TexCoord[i]);
+ for (i = 0; i < Elements(src->VertexAttrib); i++)
+ _mesa_copy_client_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
+
+ /* _Enabled must be the same than on push */
+ dest->_Enabled = src->_Enabled;
+ dest->_MaxElement = src->_MaxElement;
+}
+
+/**
+ * Copy gl_array_attrib from src to dest.
+ * 'dest' must be in an initialized state.
+ */
+static void
+copy_array_attrib(struct gl_context *ctx,
+ struct gl_array_attrib *dest,
+ struct gl_array_attrib *src)
+{
+ /* skip ArrayObj */
+ /* skip DefaultArrayObj, Objects */
+ dest->ActiveTexture = src->ActiveTexture;
+ dest->LockFirst = src->LockFirst;
+ dest->LockCount = src->LockCount;
+ dest->PrimitiveRestart = src->PrimitiveRestart;
+ dest->RestartIndex = src->RestartIndex;
+ /* skip NewState */
+ /* skip RebindArrays */
+
+ copy_array_object(ctx, dest->ArrayObj, src->ArrayObj);
+
+ /* skip ArrayBufferObj */
+ /* skip ElementArrayBufferObj */
+}
+
+/**
+ * Save the content of src to dest.
+ */
+static void
+save_array_attrib(struct gl_context *ctx,
+ struct gl_array_attrib *dest,
+ struct gl_array_attrib *src)
+{
+ /* Set the Name, needed for restore, but do never overwrite.
+ * Needs to match value in the object hash. */
+ dest->ArrayObj->Name = src->ArrayObj->Name;
+ /* And copy all of the rest. */
+ copy_array_attrib(ctx, dest, src);
+
+ /* Just reference them here */
+ _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj,
+ src->ArrayBufferObj);
+ _mesa_reference_buffer_object(ctx, &dest->ElementArrayBufferObj,
+ src->ElementArrayBufferObj);
+}
+
+/**
+ * Restore the content of src to dest.
+ */
+static void
+restore_array_attrib(struct gl_context *ctx,
+ struct gl_array_attrib *dest,
+ struct gl_array_attrib *src)
+{
+ /* Restore or recreate the array object by its name ... */
+ _mesa_BindVertexArrayAPPLE(src->ArrayObj->Name);
+
+ /* ... and restore its content */
+ copy_array_attrib(ctx, dest, src);
+
+ /* Restore or recreate the buffer objects by the names ... */
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
+ src->ArrayBufferObj->Name);
+ _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ src->ElementArrayBufferObj->Name);
+
+ /* Better safe than sorry?! */
+ dest->RebindArrays = GL_TRUE;
+
+ /* FIXME: Should some bits in ctx->Array->NewState also be set
+ * FIXME: here? It seems like it should be set to inclusive-or
+ * FIXME: of the old ArrayObj->_Enabled and the new _Enabled.
+ * ... just do it.
+ */
+ dest->NewState |= src->ArrayObj->_Enabled | dest->ArrayObj->_Enabled;
+}
+
+/**
+ * init/alloc the fields of 'attrib'.
+ * Needs to the init part matching free_array_attrib_data below.
+ */
+static void
+init_array_attrib_data(struct gl_context *ctx,
+ struct gl_array_attrib *attrib)
+{
+ /* Get a non driver gl_array_object. */
+ attrib->ArrayObj = CALLOC_STRUCT( gl_array_object );
+ _mesa_initialize_array_object(ctx, attrib->ArrayObj, 0);
+}
+
+/**
+ * Free/unreference the fields of 'attrib' but don't delete it (that's
+ * done later in the calling code).
+ * Needs to the cleanup part matching init_array_attrib_data above.
+ */
+static void
+free_array_attrib_data(struct gl_context *ctx,
+ struct gl_array_attrib *attrib)
+{
+ /* We use a non driver array object, so don't just unref since we would
+ * end up using the drivers DeleteArrayObject function for deletion. */
+ _mesa_delete_array_object(ctx, attrib->ArrayObj);
+ attrib->ArrayObj = 0;
+ _mesa_reference_buffer_object(ctx, &attrib->ArrayBufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &attrib->ElementArrayBufferObj, NULL);
+}
+
void GLAPIENTRY
_mesa_PushClientAttrib(GLbitfield mask)
@@ -1360,26 +1481,10 @@ _mesa_PushClientAttrib(GLbitfield mask)
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
struct gl_array_attrib *attr;
- struct gl_array_object *obj;
-
- attr = MALLOC_STRUCT( gl_array_attrib );
- obj = MALLOC_STRUCT( gl_array_object );
-
-#if FEATURE_ARB_vertex_buffer_object
- /* increment ref counts since we're copying pointers to these objects */
- ctx->Array.ArrayBufferObj->RefCount++;
- ctx->Array.ElementArrayBufferObj->RefCount++;
-#endif
-
- memcpy( attr, &ctx->Array, sizeof(struct gl_array_attrib) );
- memcpy( obj, ctx->Array.ArrayObj, sizeof(struct gl_array_object) );
-
- attr->ArrayObj = obj;
-
+ attr = CALLOC_STRUCT( gl_array_attrib );
+ init_array_attrib_data(ctx, attr);
+ save_array_attrib(ctx, attr, &ctx->Array);
save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr);
-
- /* bump reference counts on buffer objects */
- adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, 1);
}
ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
@@ -1426,36 +1531,10 @@ _mesa_PopClientAttrib(void)
ctx->NewState |= _NEW_PACKUNPACK;
break;
case GL_CLIENT_VERTEX_ARRAY_BIT: {
- struct gl_array_attrib * data =
+ struct gl_array_attrib * attr =
(struct gl_array_attrib *) node->data;
-
- adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, -1);
-
- ctx->Array.ActiveTexture = data->ActiveTexture;
- if (data->LockCount != 0)
- _mesa_LockArraysEXT(data->LockFirst, data->LockCount);
- else if (ctx->Array.LockCount)
- _mesa_UnlockArraysEXT();
-
- _mesa_BindVertexArrayAPPLE( data->ArrayObj->Name );
-
-#if FEATURE_ARB_vertex_buffer_object
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
- data->ArrayBufferObj->Name);
- _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
- data->ElementArrayBufferObj->Name);
-#endif
-
- memcpy( ctx->Array.ArrayObj, data->ArrayObj,
- sizeof( struct gl_array_object ) );
-
- FREE( data->ArrayObj );
-
- /* FIXME: Should some bits in ctx->Array->NewState also be set
- * FIXME: here? It seems like it should be set to inclusive-or
- * FIXME: of the old ArrayObj->_Enabled and the new _Enabled.
- */
-
+ restore_array_attrib(ctx, &ctx->Array, attr);
+ free_array_attrib_data(ctx, attr);
ctx->NewState |= _NEW_ARRAY;
break;
}
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c
index 67241eb1e..f2e8f568c 100644
--- a/mesalib/src/mesa/main/bufferobj.c
+++ b/mesalib/src/mesa/main/bufferobj.c
@@ -571,7 +571,7 @@ bind_buffer_object(struct gl_context *ctx, GLenum target, GLuint buffer)
/* Get pointer to old buffer object (to be unbound) */
oldBufObj = *bindTarget;
- if (oldBufObj && oldBufObj->Name == buffer)
+ if (oldBufObj && oldBufObj->Name == buffer && !oldBufObj->DeletePending)
return; /* rebinding the same buffer object- no change */
/*
@@ -773,6 +773,17 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
/* The ID is immediately freed for re-use */
_mesa_HashRemove(ctx->Shared->BufferObjects, ids[i]);
+ /* Make sure we do not run into the classic ABA problem on bind.
+ * We don't want to allow re-binding a buffer object that's been
+ * "deleted" by glDeleteBuffers().
+ *
+ * The explicit rebinding to the default object in the current context
+ * prevents the above in the current context, but another context
+ * sharing the same objects might suffer from this problem.
+ * The alternative would be to do the hash lookup in any case on bind
+ * which would introduce more runtime overhead than this.
+ */
+ bufObj->DeletePending = GL_TRUE;
_mesa_reference_buffer_object(ctx, &bufObj, NULL);
}
}
diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h
index 89d6cda91..921e30222 100644
--- a/mesalib/src/mesa/main/compiler.h
+++ b/mesalib/src/mesa/main/compiler.h
@@ -150,7 +150,7 @@ extern "C" {
* inline a static function that we later use in an alias. - ajax
*/
#ifndef PUBLIC
-# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+# if (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# define PUBLIC __attribute__((visibility("default")))
# define USED __attribute__((used))
# else
diff --git a/mesalib/src/mesa/main/context.h b/mesalib/src/mesa/main/context.h
index a4c7ba2c5..a9df0a866 100644
--- a/mesalib/src/mesa/main/context.h
+++ b/mesalib/src/mesa/main/context.h
@@ -233,7 +233,7 @@ do { \
* glBegin()/glEnd() pair, with return value.
*
* \param ctx GL context.
- * \param retval value to return value in case the assertion fails.
+ * \param retval value to return in case the assertion fails.
*/
#define ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, retval) \
do { \
@@ -274,7 +274,7 @@ do { \
* glBegin()/glEnd() pair and flush the vertices, with return value.
*
* \param ctx GL context.
- * \param retval value to return value in case the assertion fails.
+ * \param retval value to return in case the assertion fails.
*/
#define ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval) \
do { \
diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c
index 625649e9d..d901bddf8 100644
--- a/mesalib/src/mesa/main/dlist.c
+++ b/mesalib/src/mesa/main/dlist.c
@@ -939,7 +939,9 @@ unpack_image(struct gl_context *ctx, GLuint dimensions,
}
return image;
}
+
/* bad access! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "invalid PBO access");
return NULL;
}
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index f9da54e73..c56062ac6 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -2486,6 +2486,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
void GLAPIENTRY
_mesa_GenerateMipmapEXT(GLenum target)
{
+ struct gl_texture_image *srcImage;
struct gl_texture_object *texObj;
GLboolean error;
@@ -2532,6 +2533,13 @@ _mesa_GenerateMipmapEXT(GLenum target)
}
_mesa_lock_texture(ctx, texObj);
+
+ srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel);
+ if (!srcImage) {
+ _mesa_unlock_texture(ctx, texObj);
+ return;
+ }
+
if (target == GL_TEXTURE_CUBE_MAP) {
GLuint face;
for (face = 0; face < 6; face++)
diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp
index 160a97c0c..b5500714b 100644
--- a/mesalib/src/mesa/main/ff_fragment_shader.cpp
+++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp
@@ -1137,8 +1137,8 @@ load_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit )
ir_variable *rot_mat_0_var, *rot_mat_1_var;
ir_dereference_variable *rot_mat_0, *rot_mat_1;
- rot_mat_0_var = p->shader->symbols->get_variable("gl_MESABumpRotMatrix0");
- rot_mat_1_var = p->shader->symbols->get_variable("gl_MESABumpRotMatrix1");
+ rot_mat_0_var = p->shader->symbols->get_variable("gl_BumpRotMatrix0MESA");
+ rot_mat_1_var = p->shader->symbols->get_variable("gl_BumpRotMatrix1MESA");
rot_mat_0 = new(p->mem_ctx) ir_dereference_variable(rot_mat_0_var);
rot_mat_1 = new(p->mem_ctx) ir_dereference_variable(rot_mat_1_var);
@@ -1229,7 +1229,7 @@ emit_fog_instructions(struct texenv_fragment_program *p,
temp = new(p->mem_ctx) ir_dereference_variable(fog_result);
fragcolor = new(p->mem_ctx) ir_swizzle(temp, 0, 1, 2, 3, 3);
- oparams = p->shader->symbols->get_variable("gl_MESAFogParamsOptimized");
+ oparams = p->shader->symbols->get_variable("gl_FogParamsOptimizedMESA");
fogcoord = p->shader->symbols->get_variable("gl_FogFragCoord");
params = p->shader->symbols->get_variable("gl_Fog");
f = new(p->mem_ctx) ir_dereference_variable(fogcoord);
@@ -1464,7 +1464,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key)
validate_ir_tree(p.shader->ir);
- while (do_common_optimization(p.shader->ir, false, 32))
+ while (do_common_optimization(p.shader->ir, false, false, 32))
;
reparent_ir(p.shader->ir, p.shader->ir);
diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c
index 345a1c53e..2469e4265 100644
--- a/mesalib/src/mesa/main/imports.c
+++ b/mesalib/src/mesa/main/imports.c
@@ -514,7 +514,7 @@ _mesa_ffsll(int64_t val)
#endif
#if !defined(__GNUC__) ||\
- ((_GNUC__ == 3 && __GNUC_MINOR__ < 4) && __GNUC__ < 4)
+ ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
/**
* Return number of bits set in given GLuint.
*/
diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h
index 20fa148fe..797f35742 100644
--- a/mesalib/src/mesa/main/imports.h
+++ b/mesalib/src/mesa/main/imports.h
@@ -453,7 +453,7 @@ static inline int32_t
_mesa_next_pow_two_32(uint32_t x)
{
#if defined(__GNUC__) && \
- ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+ ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
uint32_t y = (x != 1);
return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
#else
@@ -472,7 +472,7 @@ static inline int64_t
_mesa_next_pow_two_64(uint64_t x)
{
#if defined(__GNUC__) && \
- ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+ ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
uint64_t y = (x != 1);
if (sizeof(x) == sizeof(long))
return (1 + y) << ((__builtin_clzl(x - y) ^ 63));
@@ -499,7 +499,7 @@ static inline GLuint
_mesa_logbase2(GLuint n)
{
#if defined(__GNUC__) && \
- ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+ ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
return (31 - __builtin_clz(n | 1));
#else
GLuint pos = 0;
@@ -576,7 +576,7 @@ _mesa_init_sqrt_table(void);
#define _mesa_ffs(i) ffs(i)
#define _mesa_ffsll(i) ffsll(i)
-#if ((_GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+#if ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
#define _mesa_bitcount(i) __builtin_popcount(i)
#define _mesa_bitcount_64(i) __builtin_popcountll(i)
#else
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 17c645a7e..411768641 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1261,11 +1261,6 @@ struct gl_texture_image
GLuint Level; /**< Which mipmap level am I? */
/** Cube map face: index into gl_texture_object::Image[] array */
GLuint Face;
-
- GLuint RowStride; /**< Padded width in units of texels */
- GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to
- each 2D slice in 'Data', in texels */
- GLvoid *Data; /**< Image data, accessed via FetchTexel() */
};
@@ -1535,6 +1530,7 @@ struct gl_buffer_object
GLintptr Offset; /**< Mapped offset */
GLsizeiptr Length; /**< Mapped length */
/*@}*/
+ GLboolean DeletePending; /**< true if buffer object is removed from the hash */
GLboolean Written; /**< Ever written to? (for debugging) */
GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
};
@@ -2736,6 +2732,20 @@ struct gl_constants
/* GL_ARB_robustness */
GLenum ResetStrategy;
+
+ /**
+ * Whether the implementation strips out and ignores texture borders.
+ *
+ * Many GPU hardware implementations don't support rendering with texture
+ * borders and mipmapped textures. (Note: not static border color, but the
+ * old 1-pixel border around each edge). Implementations then have to do
+ * slow fallbacks to be correct, or just ignore the border and be fast but
+ * wrong. Setting the flag stripts the border off of TexImage calls,
+ * providing "fast but wrong" at significantly reduced driver complexity.
+ *
+ * Texture borders are deprecated in GL 3.0.
+ **/
+ GLboolean StripTextureBorder;
};
diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c
index 092e541c5..ecdeaf5dc 100644
--- a/mesalib/src/mesa/main/pack.c
+++ b/mesalib/src/mesa/main/pack.c
@@ -3717,6 +3717,7 @@ _mesa_unpack_color_span_ubyte(struct gl_context *ctx,
if (!indexes) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+ free(rgba);
return;
}
diff --git a/mesalib/src/mesa/main/pixelstore.c b/mesalib/src/mesa/main/pixelstore.c
index d957950ed..81474491d 100644
--- a/mesalib/src/mesa/main/pixelstore.c
+++ b/mesalib/src/mesa/main/pixelstore.c
@@ -214,7 +214,7 @@ _mesa_PixelStorei( GLenum pname, GLint param )
void GLAPIENTRY
_mesa_PixelStoref( GLenum pname, GLfloat param )
{
- _mesa_PixelStorei( pname, (GLint) param );
+ _mesa_PixelStorei( pname, IROUND(param) );
}
diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c
index 98ca733c0..80fd03b91 100644
--- a/mesalib/src/mesa/main/state.c
+++ b/mesalib/src/mesa/main/state.c
@@ -461,7 +461,7 @@ static void
update_twoside(struct gl_context *ctx)
{
if (ctx->Shader.CurrentVertexProgram ||
- ctx->VertexProgram.Current) {
+ ctx->VertexProgram._Enabled) {
ctx->VertexProgram._TwoSideEnabled = ctx->VertexProgram.TwoSideEnabled;
} else {
ctx->VertexProgram._TwoSideEnabled = (ctx->Light.Enabled &&
diff --git a/mesalib/src/mesa/main/texcompress.c b/mesalib/src/mesa/main/texcompress.c
index 03e05d5ef..0458b9b68 100644
--- a/mesalib/src/mesa/main/texcompress.c
+++ b/mesalib/src/mesa/main/texcompress.c
@@ -461,8 +461,8 @@ _mesa_decompress_image(gl_format format, GLuint width, GLuint height,
/* setup dummy texture image info */
memset(&texImage, 0, sizeof(texImage));
- texImage.Base.Data = (void *) src;
- texImage.Base.RowStride = srcRowStride;
+ texImage.Data = (void *) src;
+ texImage.RowStride = srcRowStride;
switch (format) {
/* DXT formats */
diff --git a/mesalib/src/mesa/main/texcompress_fxt1.c b/mesalib/src/mesa/main/texcompress_fxt1.c
index 41630a47c..d5c73e3b4 100644
--- a/mesalib/src/mesa/main/texcompress_fxt1.c
+++ b/mesalib/src/mesa/main/texcompress_fxt1.c
@@ -177,7 +177,7 @@ _mesa_fetch_texel_2d_f_rgba_fxt1( const struct swrast_texture_image *texImage,
/* just sample as GLubyte and convert to float here */
GLubyte rgba[4];
(void) k;
- fxt1_decode_1(texImage->Base.Data, texImage->Base.RowStride, i, j, rgba);
+ fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, rgba);
texel[RCOMP] = UBYTE_TO_FLOAT(rgba[RCOMP]);
texel[GCOMP] = UBYTE_TO_FLOAT(rgba[GCOMP]);
texel[BCOMP] = UBYTE_TO_FLOAT(rgba[BCOMP]);
@@ -192,7 +192,7 @@ _mesa_fetch_texel_2d_f_rgb_fxt1( const struct swrast_texture_image *texImage,
/* just sample as GLubyte and convert to float here */
GLubyte rgba[4];
(void) k;
- fxt1_decode_1(texImage->Base.Data, texImage->Base.RowStride, i, j, rgba);
+ fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, rgba);
texel[RCOMP] = UBYTE_TO_FLOAT(rgba[RCOMP]);
texel[GCOMP] = UBYTE_TO_FLOAT(rgba[GCOMP]);
texel[BCOMP] = UBYTE_TO_FLOAT(rgba[BCOMP]);
diff --git a/mesalib/src/mesa/main/texcompress_rgtc.c b/mesalib/src/mesa/main/texcompress_rgtc.c
index b03cd28b8..3586fc39d 100644
--- a/mesalib/src/mesa/main/texcompress_rgtc.c
+++ b/mesalib/src/mesa/main/texcompress_rgtc.c
@@ -325,7 +325,7 @@ _mesa_fetch_texel_2d_f_red_rgtc1(const struct swrast_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLubyte red;
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data,
i, j, &red, 1);
texel[RCOMP] = UBYTE_TO_FLOAT(red);
texel[GCOMP] = 0.0;
@@ -338,7 +338,7 @@ _mesa_fetch_texel_2d_f_signed_red_rgtc1(const struct swrast_texture_image *texIm
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLbyte red;
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data),
i, j, &red, 1);
texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
texel[GCOMP] = 0.0;
@@ -351,9 +351,9 @@ _mesa_fetch_texel_2d_f_rg_rgtc2(const struct swrast_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLubyte red, green;
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data,
i, j, &red, 2);
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data) + 8,
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data + 8,
i, j, &green, 2);
texel[RCOMP] = UBYTE_TO_FLOAT(red);
texel[GCOMP] = UBYTE_TO_FLOAT(green);
@@ -366,9 +366,9 @@ _mesa_fetch_texel_2d_f_signed_rg_rgtc2(const struct swrast_texture_image *texIma
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLbyte red, green;
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data),
i, j, &red, 2);
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data) + 8,
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data) + 8,
i, j, &green, 2);
texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
@@ -381,7 +381,7 @@ _mesa_fetch_texel_2d_f_l_latc1(const struct swrast_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLubyte red;
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data,
i, j, &red, 1);
texel[RCOMP] =
texel[GCOMP] =
@@ -394,7 +394,7 @@ _mesa_fetch_texel_2d_f_signed_l_latc1(const struct swrast_texture_image *texImag
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLbyte red;
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data),
i, j, &red, 1);
texel[RCOMP] =
texel[GCOMP] =
@@ -407,9 +407,9 @@ _mesa_fetch_texel_2d_f_la_latc2(const struct swrast_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLubyte red, green;
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data),
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data,
i, j, &red, 2);
- unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data) + 8,
+ unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data + 8,
i, j, &green, 2);
texel[RCOMP] =
texel[GCOMP] =
@@ -422,9 +422,9 @@ _mesa_fetch_texel_2d_f_signed_la_latc2(const struct swrast_texture_image *texIma
GLint i, GLint j, GLint k, GLfloat *texel)
{
GLbyte red, green;
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data),
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data),
i, j, &red, 2);
- signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data) + 8,
+ signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data) + 8,
i, j, &green, 2);
texel[RCOMP] =
texel[GCOMP] =
diff --git a/mesalib/src/mesa/main/texcompress_s3tc.c b/mesalib/src/mesa/main/texcompress_s3tc.c
index 29386a37d..11c7db4ef 100644
--- a/mesalib/src/mesa/main/texcompress_s3tc.c
+++ b/mesalib/src/mesa/main/texcompress_s3tc.c
@@ -402,8 +402,8 @@ fetch_texel_2d_rgb_dxt1( const struct swrast_texture_image *texImage,
{
(void) k;
if (fetch_ext_rgb_dxt1) {
- fetch_ext_rgb_dxt1(texImage->Base.RowStride,
- (GLubyte *)(texImage)->Base.Data, i, j, texel);
+ fetch_ext_rgb_dxt1(texImage->RowStride,
+ texImage->Data, i, j, texel);
}
else
_mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgb_dxt1");
@@ -430,8 +430,8 @@ fetch_texel_2d_rgba_dxt1( const struct swrast_texture_image *texImage,
{
(void) k;
if (fetch_ext_rgba_dxt1) {
- fetch_ext_rgba_dxt1(texImage->Base.RowStride,
- (GLubyte *)(texImage)->Base.Data, i, j, texel);
+ fetch_ext_rgba_dxt1(texImage->RowStride,
+ texImage->Data, i, j, texel);
}
else
_mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt1\n");
@@ -458,9 +458,8 @@ fetch_texel_2d_rgba_dxt3( const struct swrast_texture_image *texImage,
{
(void) k;
if (fetch_ext_rgba_dxt3) {
- fetch_ext_rgba_dxt3(texImage->Base.RowStride,
- (GLubyte *)(texImage)->Base.Data,
- i, j, texel);
+ fetch_ext_rgba_dxt3(texImage->RowStride,
+ texImage->Data, i, j, texel);
}
else
_mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt3\n");
@@ -487,9 +486,8 @@ fetch_texel_2d_rgba_dxt5( const struct swrast_texture_image *texImage,
{
(void) k;
if (fetch_ext_rgba_dxt5) {
- fetch_ext_rgba_dxt5(texImage->Base.RowStride,
- (GLubyte *)(texImage)->Base.Data,
- i, j, texel);
+ fetch_ext_rgba_dxt5(texImage->RowStride,
+ texImage->Data, i, j, texel);
}
else
_mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt5\n");
diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c
index 7f262d6d8..aebe38ee0 100644
--- a/mesalib/src/mesa/main/texformat.c
+++ b/mesalib/src/mesa/main/texformat.c
@@ -34,6 +34,7 @@
#include "context.h"
+#include "enums.h"
#include "mfeatures.h"
#include "mtypes.h"
#include "texcompress.h"
@@ -897,7 +898,8 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
}
}
- _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
+ _mesa_problem(ctx, "unexpected format %s in _mesa_choose_tex_format()",
+ _mesa_lookup_enum_by_nr(internalFormat));
return MESA_FORMAT_NONE;
}
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 2d06f84bf..acf7187fd 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -58,27 +58,6 @@
/**
- * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE
- * elsewhere.
- */
-void *
-_mesa_alloc_texmemory(GLsizei bytes)
-{
- return _mesa_align_malloc(bytes, 512);
-}
-
-
-/**
- * Free texture memory allocated with _mesa_alloc_texmemory()
- */
-void
-_mesa_free_texmemory(void *m)
-{
- _mesa_align_free(m);
-}
-
-
-/**
* Return the simple base format for a given internal texture format.
* For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
*
@@ -599,29 +578,6 @@ _mesa_new_texture_image( struct gl_context *ctx )
/**
- * Free texture image data.
- * This function is a fallback called via ctx->Driver.FreeTextureImageBuffer().
- *
- * \param texImage texture image.
- *
- * Free the texture image data if it's not marked as client data.
- */
-void
-_mesa_free_texture_image_data(struct gl_context *ctx,
- struct gl_texture_image *texImage)
-{
- (void) ctx;
-
- if (texImage->Data) {
- /* free the old texture data */
- _mesa_free_texmemory(texImage->Data);
- }
-
- texImage->Data = NULL;
-}
-
-
-/**
* Free a gl_texture_image and associated data.
* This function is a fallback called via ctx->Driver.DeleteTextureImage().
*
@@ -638,11 +594,6 @@ _mesa_delete_texture_image(struct gl_context *ctx,
*/
ASSERT(ctx->Driver.FreeTextureImageBuffer);
ctx->Driver.FreeTextureImageBuffer( ctx, texImage );
-
- ASSERT(texImage->Data == NULL);
- if (texImage->ImageOffsets)
- free(texImage->ImageOffsets);
- free(texImage);
}
@@ -1084,18 +1035,12 @@ clear_teximage_fields(struct gl_texture_image *img)
img->Width = 0;
img->Height = 0;
img->Depth = 0;
- img->RowStride = 0;
- if (img->ImageOffsets) {
- free(img->ImageOffsets);
- img->ImageOffsets = NULL;
- }
img->Width2 = 0;
img->Height2 = 0;
img->Depth2 = 0;
img->WidthLog2 = 0;
img->HeightLog2 = 0;
img->DepthLog2 = 0;
- img->Data = NULL;
img->TexFormat = MESA_FORMAT_NONE;
}
@@ -1123,8 +1068,6 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
GLint border, GLenum internalFormat,
gl_format format)
{
- GLint i;
-
ASSERT(img);
ASSERT(width >= 0);
ASSERT(height >= 0);
@@ -1161,19 +1104,6 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
- /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */
- img->RowStride = width;
- /* Allocate the ImageOffsets array and initialize to typical values.
- * We allocate the array for 1D/2D textures too in order to avoid special-
- * case code in the texstore routines.
- */
- if (img->ImageOffsets)
- free(img->ImageOffsets);
- img->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint));
- for (i = 0; i < depth; i++) {
- img->ImageOffsets[i] = i * width * height;
- }
-
img->TexFormat = format;
}
@@ -2316,6 +2246,45 @@ _mesa_choose_texture_format(struct gl_context *ctx,
return f;
}
+/**
+ * Adjust pixel unpack params and image dimensions to strip off the
+ * texture border.
+ *
+ * Gallium and intel don't support texture borders. They've seldem been used
+ * and seldom been implemented correctly anyway.
+ *
+ * \param unpackNew returns the new pixel unpack parameters
+ */
+static void
+strip_texture_border(GLint *border,
+ GLint *width, GLint *height, GLint *depth,
+ const struct gl_pixelstore_attrib *unpack,
+ struct gl_pixelstore_attrib *unpackNew)
+{
+ assert(*border > 0); /* sanity check */
+
+ *unpackNew = *unpack;
+
+ if (unpackNew->RowLength == 0)
+ unpackNew->RowLength = *width;
+
+ if (depth && unpackNew->ImageHeight == 0)
+ unpackNew->ImageHeight = *height;
+
+ unpackNew->SkipPixels += *border;
+ if (height)
+ unpackNew->SkipRows += *border;
+ if (depth)
+ unpackNew->SkipImages += *border;
+
+ assert(*width >= 3);
+ *width = *width - 2 * *border;
+ if (height && *height >= 3)
+ *height = *height - 2 * *border;
+ if (depth && *depth >= 3)
+ *depth = *depth - 2 * *border;
+ *border = 0;
+}
/**
* Common code to implement all the glTexImage1D/2D/3D functions.
@@ -2328,6 +2297,8 @@ teximage(struct gl_context *ctx, GLuint dims,
const GLvoid *pixels)
{
GLboolean error;
+ struct gl_pixelstore_attrib unpack_no_border;
+ const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -2392,6 +2363,16 @@ teximage(struct gl_context *ctx, GLuint dims,
return; /* error was recorded */
}
+ /* Allow a hardware driver to just strip out the border, to provide
+ * reliable but slightly incorrect hardware rendering instead of
+ * rarely-tested software fallback rendering.
+ */
+ if (border && ctx->Const.StripTextureBorder) {
+ strip_texture_border(&border, &width, &height, &depth, unpack,
+ &unpack_no_border);
+ unpack = &unpack_no_border;
+ }
+
if (ctx->NewState & _NEW_PIXEL)
_mesa_update_state(ctx);
@@ -2409,7 +2390,6 @@ teximage(struct gl_context *ctx, GLuint dims,
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
- ASSERT(texImage->Data == NULL);
texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
internalFormat, format,
type);
@@ -2425,19 +2405,19 @@ teximage(struct gl_context *ctx, GLuint dims,
case 1:
ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
width, border, format,
- type, pixels, &ctx->Unpack, texObj,
+ type, pixels, unpack, texObj,
texImage);
break;
case 2:
ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
width, height, border, format,
- type, pixels, &ctx->Unpack, texObj,
+ type, pixels, unpack, texObj,
texImage);
break;
case 3:
ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
width, height, depth, border, format,
- type, pixels, &ctx->Unpack, texObj,
+ type, pixels, unpack, texObj,
texImage);
break;
default:
@@ -2548,7 +2528,6 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
} else {
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
- ASSERT(texImage->Data == NULL);
ctx->Driver.EGLImageTargetTexture2D(ctx, target,
texObj, texImage, image);
@@ -2734,6 +2713,16 @@ copyteximage(struct gl_context *ctx, GLuint dims,
texObj = _mesa_get_current_tex_object(ctx, target);
+ if (border && ctx->Const.StripTextureBorder) {
+ x += border;
+ width -= border * 2;
+ if (dims == 2) {
+ y += border;
+ height -= border * 2;
+ }
+ border = 0;
+ }
+
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
@@ -3370,7 +3359,6 @@ compressedteximage(struct gl_context *ctx, GLuint dims,
gl_format texFormat;
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
- ASSERT(texImage->Data == NULL);
texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
internalFormat, GL_NONE,
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 6ce0fe92c..fd315bea3 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -36,13 +36,6 @@
#include "formats.h"
-extern void *
-_mesa_alloc_texmemory(GLsizei bytes);
-
-extern void
-_mesa_free_texmemory(void *m);
-
-
/** \name Internal functions */
/*@{*/
@@ -62,10 +55,6 @@ extern void
_mesa_delete_texture_image( struct gl_context *ctx,
struct gl_texture_image *teximage );
-extern void
-_mesa_free_texture_image_data( struct gl_context *ctx,
- struct gl_texture_image *texImage );
-
extern void
_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index 1b90cca9b..4d9942ba8 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -543,12 +543,13 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
width /= 2;
}
if (i >= minLevel && i <= maxLevel) {
- if (!t->Image[0][i]) {
- incomplete(t, "1D Image[0][i] == NULL");
+ const struct gl_texture_image *img = t->Image[0][i];
+ if (!img) {
+ incomplete(t, "1D Image[%d] is missing", i);
return;
}
- if (t->Image[0][i]->Width2 != width ) {
- incomplete(t, "1D Image[0][i] bad width");
+ if (img->Width2 != width ) {
+ incomplete(t, "1D Image[%d] bad width %u", i, img->Width2);
return;
}
}
@@ -570,16 +571,17 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
height /= 2;
}
if (i >= minLevel && i <= maxLevel) {
- if (!t->Image[0][i]) {
- incomplete(t, "2D Image[0][i] == NULL");
+ const struct gl_texture_image *img = t->Image[0][i];
+ if (!img) {
+ incomplete(t, "2D Image[%d of %d] is missing", i, maxLevel);
return;
}
- if (t->Image[0][i]->Width2 != width) {
- incomplete(t, "2D Image[0][i] bad width");
+ if (img->Width2 != width) {
+ incomplete(t, "2D Image[%d] bad width %u", i, img->Width2);
return;
}
- if (t->Image[0][i]->Height2 != height) {
- incomplete(t, "2D Image[0][i] bad height");
+ if (img->Height2 != height) {
+ incomplete(t, "2D Image[i] bad height %u", i, img->Height2);
return;
}
if (width==1 && height==1) {
@@ -604,24 +606,25 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
depth /= 2;
}
if (i >= minLevel && i <= maxLevel) {
- if (!t->Image[0][i]) {
- incomplete(t, "3D Image[0][i] == NULL");
+ const struct gl_texture_image *img = t->Image[0][i];
+ if (!img) {
+ incomplete(t, "3D Image[%d] is missing", i);
return;
}
- if (t->Image[0][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
+ if (img->_BaseFormat == GL_DEPTH_COMPONENT) {
incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
return;
}
- if (t->Image[0][i]->Width2 != width) {
- incomplete(t, "3D Image[0][i] bad width");
+ if (img->Width2 != width) {
+ incomplete(t, "3D Image[%d] bad width %u", i, img->Width2);
return;
}
- if (t->Image[0][i]->Height2 != height) {
- incomplete(t, "3D Image[0][i] bad height");
+ if (img->Height2 != height) {
+ incomplete(t, "3D Image[%d] bad height %u", i, img->Height2);
return;
}
- if (t->Image[0][i]->Depth2 != depth) {
- incomplete(t, "3D Image[0][i] bad depth");
+ if (img->Depth2 != depth) {
+ incomplete(t, "3D Image[%d] bad depth %u", i, img->Depth2);
return;
}
}
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c
index cc9fbc020..05c1964d6 100644
--- a/mesalib/src/mesa/main/texstore.c
+++ b/mesalib/src/mesa/main/texstore.c
@@ -4499,6 +4499,9 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
(void) border;
+ if (width == 0)
+ return;
+
/* allocate storage for texture data */
if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
width, 1, 1)) {
@@ -4560,6 +4563,9 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
(void) border;
+ if (width == 0 || height == 0)
+ return;
+
/* allocate storage for texture data */
if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
width, height, 1)) {
@@ -4651,6 +4657,9 @@ _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
(void) border;
+ if (width == 0 || height == 0 || depth == 0)
+ return;
+
/* allocate storage for texture data */
if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
width, height, depth)) {
@@ -4906,7 +4915,6 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
ASSERT(texImage->Width > 0);
ASSERT(texImage->Height > 0);
ASSERT(texImage->Depth == 1);
- ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
/* allocate storage for texture data */
if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index fecab50f7..bdbb6b938 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -40,6 +40,7 @@
#include "../glsl/program.h"
#include "ir_optimization.h"
#include "ast.h"
+#include "linker.h"
#include "main/mtypes.h"
#include "main/shaderobj.h"
@@ -2587,13 +2588,35 @@ check_resources(const struct gl_context *ctx,
}
}
+class add_uniform_to_shader : public uniform_field_visitor {
+public:
+ add_uniform_to_shader(struct gl_shader_program *shader_program,
+ struct gl_program_parameter_list *params)
+ : shader_program(shader_program), params(params), next_sampler(0)
+ {
+ /* empty */
+ }
-static int
-add_uniform_to_shader(ir_variable *var,
- struct gl_program_parameter_list *params,
- unsigned int &next_sampler)
+ int process(ir_variable *var)
+ {
+ this->idx = -1;
+ this->uniform_field_visitor::process(var);
+
+ return this->idx;
+ }
+
+private:
+ virtual void visit_field(const glsl_type *type, const char *name);
+
+ struct gl_shader_program *shader_program;
+ struct gl_program_parameter_list *params;
+ int next_sampler;
+ int idx;
+};
+
+void
+add_uniform_to_shader::visit_field(const glsl_type *type, const char *name)
{
- const glsl_type *type = var->type;
unsigned int size;
if (type->is_vector() || type->is_scalar()) {
@@ -2610,10 +2633,9 @@ add_uniform_to_shader(ir_variable *var,
file = PROGRAM_UNIFORM;
}
- int index = _mesa_lookup_parameter_index(params, -1, var->name);
+ int index = _mesa_lookup_parameter_index(params, -1, name);
if (index < 0) {
- index = _mesa_add_parameter(params, file,
- var->name, size, type->gl_type,
+ index = _mesa_add_parameter(params, file, name, size, type->gl_type,
NULL, NULL, 0x0);
/* Sampler uniform values are stored in prog->SamplerUnits,
@@ -2622,11 +2644,15 @@ add_uniform_to_shader(ir_variable *var,
*/
if (file == PROGRAM_SAMPLER) {
for (unsigned int j = 0; j < size / 4; j++)
- params->ParameterValues[index + j][0].f = next_sampler++;
+ params->ParameterValues[index + j][0].f = this->next_sampler++;
}
}
- return index;
+ /* The first part of the uniform that's processed determines the base
+ * location of the whole uniform (for structures).
+ */
+ if (this->idx < 0)
+ this->idx = index;
}
/**
@@ -2644,7 +2670,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
struct gl_program_parameter_list
*params)
{
- unsigned int next_sampler = 0;
+ add_uniform_to_shader add(shader_program, params);
foreach_list(node, sh->ir) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
@@ -2653,7 +2679,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
|| (strncmp(var->name, "gl_", 3) == 0))
continue;
- int loc = add_uniform_to_shader(var, params, next_sampler);
+ int loc = add.process(var);
/* The location chosen in the Parameters list here (returned from
* _mesa_add_parameter) has to match what the linker chose.
@@ -3212,7 +3238,9 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
- progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress;
+ progress = do_common_optimization(ir, true, true,
+ options->MaxUnrollIterations)
+ || progress;
progress = lower_quadop_vector(ir, true) || progress;
@@ -3321,7 +3349,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader)
/* Do some optimization at compile time to reduce shader IR size
* and reduce later work if the same shader is linked multiple times
*/
- while (do_common_optimization(shader->ir, false, 32))
+ while (do_common_optimization(shader->ir, false, false, 32))
;
validate_ir_tree(shader->ir);
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index 169e235ac..f82346bc6 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -543,45 +543,6 @@ st_AllocTextureImageBuffer(struct gl_context *ctx,
}
}
-
-/**
- * Adjust pixel unpack params and image dimensions to strip off the
- * texture border.
- * Gallium doesn't support texture borders. They've seldem been used
- * and seldom been implemented correctly anyway.
- * \param unpackNew returns the new pixel unpack parameters
- */
-static void
-strip_texture_border(GLint border,
- GLint *width, GLint *height, GLint *depth,
- const struct gl_pixelstore_attrib *unpack,
- struct gl_pixelstore_attrib *unpackNew)
-{
- assert(border > 0); /* sanity check */
-
- *unpackNew = *unpack;
-
- if (unpackNew->RowLength == 0)
- unpackNew->RowLength = *width;
-
- if (depth && unpackNew->ImageHeight == 0)
- unpackNew->ImageHeight = *height;
-
- unpackNew->SkipPixels += border;
- if (height)
- unpackNew->SkipRows += border;
- if (depth)
- unpackNew->SkipImages += border;
-
- assert(*width >= 3);
- *width = *width - 2 * border;
- if (height && *height >= 3)
- *height = *height - 2 * border;
- if (depth && *depth >= 3)
- *depth = *depth - 2 * border;
-}
-
-
/**
* Do glTexImage1/2/3D().
*/
@@ -602,7 +563,6 @@ st_TexImage(struct gl_context * ctx,
struct st_texture_object *stObj = st_texture_object(texObj);
struct st_texture_image *stImage = st_texture_image(texImage);
GLuint dstRowStride = 0;
- struct gl_pixelstore_attrib unpackNB;
enum pipe_transfer_usage transfer_usage = 0;
GLubyte *dstMap;
@@ -627,21 +587,9 @@ st_TexImage(struct gl_context * ctx,
stObj->surface_based = GL_FALSE;
}
- /* gallium does not support texture borders, strip it off */
- if (border) {
- strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB);
- unpack = &unpackNB;
- texImage->Width = width;
- texImage->Height = height;
- texImage->Depth = depth;
- texImage->Border = 0;
- border = 0;
- }
- else {
- assert(texImage->Width == width);
- assert(texImage->Height == height);
- assert(texImage->Depth == depth);
- }
+ assert(texImage->Width == width);
+ assert(texImage->Height == height);
+ assert(texImage->Depth == depth);
stImage->base.Face = _mesa_tex_target_to_face(target);
stImage->base.Level = level;
diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c
index 6d4bc544d..a1817720d 100644
--- a/mesalib/src/mesa/state_tracker/st_context.c
+++ b/mesalib/src/mesa/state_tracker/st_context.c
@@ -144,6 +144,10 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
/* we want all vertex data to be placed in buffer objects */
vbo_use_buffer_objects(ctx);
+
+ /* make sure that no VBOs are left mapped when we're drawing. */
+ vbo_always_unmap_buffers(ctx);
+
/* Need these flags:
*/
st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h
index 0a3220221..c60780989 100644
--- a/mesalib/src/mesa/state_tracker/st_context.h
+++ b/mesalib/src/mesa/state_tracker/st_context.h
@@ -75,6 +75,7 @@ struct st_context
struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */
struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */
struct draw_stage *rastpos_stage; /**< For glRasterPos */
+ GLboolean sw_primitive_restart;
/* On old libGL's for linux we need to invalidate the drawables
diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c
index 574802084..ff3008a5f 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.c
+++ b/mesalib/src/mesa/state_tracker/st_draw.c
@@ -353,9 +353,26 @@ setup_interleaved_attribs(struct gl_context *ctx,
struct pipe_context *pipe = st->pipe;
GLuint attr;
const GLubyte *low_addr = NULL;
-
- /* Find the lowest address of the arrays we're drawing */
+ GLboolean usingVBO; /* all arrays in a VBO? */
+ struct gl_buffer_object *bufobj;
+ GLuint user_buffer_size = 0;
+ GLuint vertex_size = 0; /* bytes per vertex, in bytes */
+ GLsizei stride;
+
+ /* Find the lowest address of the arrays we're drawing,
+ * Init bufobj and stride.
+ */
if (vpv->num_inputs) {
+ const GLuint mesaAttr0 = vp->index_to_input[0];
+ const struct gl_client_array *array = arrays[mesaAttr0];
+
+ /* Since we're doing interleaved arrays, we know there'll be at most
+ * one buffer object and the stride will be the same for all arrays.
+ * Grab them now.
+ */
+ bufobj = array->BufferObj;
+ stride = array->StrideB;
+
low_addr = arrays[vp->index_to_input[0]]->Ptr;
for (attr = 1; attr < vpv->num_inputs; attr++) {
@@ -363,44 +380,24 @@ setup_interleaved_attribs(struct gl_context *ctx,
low_addr = MIN2(low_addr, start);
}
}
+ else {
+ /* not sure we'll ever have zero inputs, but play it safe */
+ bufobj = NULL;
+ stride = 0;
+ low_addr = 0;
+ }
+
+ /* are the arrays in user space? */
+ usingVBO = bufobj && _mesa_is_bufferobj(bufobj);
for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
const struct gl_client_array *array = arrays[mesaAttr];
- struct gl_buffer_object *bufobj = array->BufferObj;
- struct st_buffer_object *stobj = st_buffer_object(bufobj);
unsigned src_offset = (unsigned) (array->Ptr - low_addr);
GLuint element_size = array->_ElementSize;
- GLsizei stride = array->StrideB;
assert(element_size == array->Size * _mesa_sizeof_type(array->Type));
- if (attr == 0) {
- if (bufobj && _mesa_is_bufferobj(bufobj)) {
- vbuffer->buffer = NULL;
- pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
- vbuffer->buffer_offset = pointer_to_offset(low_addr);
- }
- else {
- uint divisor = array->InstanceDivisor;
- uint last_index = divisor ? num_instances / divisor : max_index;
- uint bytes = src_offset + stride * last_index + element_size;
-
- vbuffer->buffer = pipe_user_buffer_create(pipe->screen,
- (void*) low_addr,
- bytes,
- PIPE_BIND_VERTEX_BUFFER);
- vbuffer->buffer_offset = 0;
-
- /* Track user vertex buffers. */
- pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer);
- st->user_attrib[0].element_size = element_size;
- st->user_attrib[0].stride = stride;
- st->num_user_attribs = 1;
- }
- vbuffer->stride = stride; /* in bytes */
- }
-
velements[attr].src_offset = src_offset;
velements[attr].instance_divisor = array->InstanceDivisor;
velements[attr].vertex_buffer_index = 0;
@@ -409,6 +406,54 @@ setup_interleaved_attribs(struct gl_context *ctx,
array->Format,
array->Normalized);
assert(velements[attr].src_format);
+
+ if (!usingVBO) {
+ /* how many bytes referenced by this attribute array? */
+ uint divisor = array->InstanceDivisor;
+ uint last_index = divisor ? num_instances / divisor : max_index;
+ uint bytes = src_offset + stride * last_index + element_size;
+
+ user_buffer_size = MAX2(user_buffer_size, bytes);
+
+ /* update vertex size */
+ vertex_size = MAX2(vertex_size, src_offset + element_size);
+ }
+ }
+
+ /*
+ * Return the vbuffer info and setup user-space attrib info, if needed.
+ */
+ if (vpv->num_inputs == 0) {
+ /* just defensive coding here */
+ vbuffer->buffer = NULL;
+ vbuffer->buffer_offset = 0;
+ vbuffer->stride = 0;
+ st->num_user_attribs = 0;
+ }
+ else if (usingVBO) {
+ /* all interleaved arrays in a VBO */
+ struct st_buffer_object *stobj = st_buffer_object(bufobj);
+
+ vbuffer->buffer = NULL;
+ pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
+ vbuffer->buffer_offset = pointer_to_offset(low_addr);
+ vbuffer->stride = stride;
+ st->num_user_attribs = 0;
+ }
+ else {
+ /* all interleaved arrays in user memory */
+ vbuffer->buffer = pipe_user_buffer_create(pipe->screen,
+ (void*) low_addr,
+ user_buffer_size,
+ PIPE_BIND_VERTEX_BUFFER);
+ vbuffer->buffer_offset = 0;
+ vbuffer->stride = stride;
+
+ /* Track user vertex buffers. */
+ pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer);
+ st->user_attrib[0].element_size = vertex_size;
+ st->user_attrib[0].stride = stride;
+ st->num_user_attribs = 1;
}
}
@@ -582,6 +627,127 @@ check_uniforms(struct gl_context *ctx)
}
}
+/** Helper code for primitive restart fallback */
+#define DO_DRAW(pipe, cur_start, cur_count) \
+ do { \
+ info.start = cur_start; \
+ info.count = cur_count; \
+ if (u_trim_pipe_prim(info.mode, &info.count)) { \
+ if (transfer) \
+ pipe_buffer_unmap(pipe, transfer); \
+ pipe->draw_vbo(pipe, &info); \
+ if (transfer) { \
+ ptr = pipe_buffer_map(pipe, ibuffer->buffer, PIPE_TRANSFER_READ, &transfer); \
+ assert(ptr != NULL); \
+ ptr = ADD_POINTERS(ptr, ibuffer->offset); \
+ } \
+ } \
+ } while(0)
+
+/** More helper code for primitive restart fallback */
+#define PRIM_RESTART_LOOP(elements) \
+ do { \
+ for (i = start; i < end; i++) { \
+ if (elements[i] == info.restart_index) { \
+ if (cur_count > 0) { \
+ /* draw elts up to prev pos */ \
+ DO_DRAW(pipe, cur_start, cur_count); \
+ } \
+ /* begin new prim at next elt */ \
+ cur_start = i + 1; \
+ cur_count = 0; \
+ } \
+ else { \
+ cur_count++; \
+ } \
+ } \
+ if (cur_count > 0) { \
+ DO_DRAW(pipe, cur_start, cur_count); \
+ } \
+ } while (0)
+
+static void
+handle_fallback_primitive_restart(struct pipe_context *pipe,
+ const struct _mesa_index_buffer *ib,
+ struct pipe_index_buffer *ibuffer,
+ struct pipe_draw_info *orig_info)
+{
+ const unsigned start = orig_info->start;
+ const unsigned count = orig_info->count;
+ const unsigned end = start + count;
+ struct pipe_draw_info info = *orig_info;
+ struct pipe_transfer *transfer = NULL;
+ unsigned instance, i, cur_start, cur_count;
+ const void *ptr;
+
+ info.primitive_restart = FALSE;
+
+ if (!info.indexed) {
+ /* Splitting the draw arrays call is handled by the VBO module */
+ if (u_trim_pipe_prim(info.mode, &info.count))
+ pipe->draw_vbo(pipe, &info);
+
+ return;
+ }
+
+ /* info.indexed == TRUE */
+ assert(ibuffer);
+ assert(ibuffer->buffer);
+
+ if (ib) {
+ struct gl_buffer_object *bufobj = ib->obj;
+ if (bufobj && bufobj->Name) {
+ ptr = NULL;
+ }
+ else {
+ ptr = ib->ptr;
+ }
+ } else {
+ ptr = NULL;
+ }
+
+ if (!ptr)
+ ptr = pipe_buffer_map(pipe, ibuffer->buffer, PIPE_TRANSFER_READ, &transfer);
+
+ if (!ptr)
+ return;
+ ptr = ADD_POINTERS(ptr, ibuffer->offset);
+
+ /* Need to loop over instances as well to preserve draw order */
+ for (instance = 0; instance < orig_info->instance_count; instance++) {
+ info.start_instance = instance + orig_info->start_instance;
+ info.instance_count = 1;
+ cur_start = start;
+ cur_count = 0;
+
+ switch (ibuffer->index_size) {
+ case 1:
+ {
+ const ubyte *elt_ub = (const ubyte *)ptr;
+ PRIM_RESTART_LOOP(elt_ub);
+ }
+ break;
+ case 2:
+ {
+ const ushort *elt_us = (const ushort *)ptr;
+ PRIM_RESTART_LOOP(elt_us);
+ }
+ break;
+ case 4:
+ {
+ const uint *elt_ui = (const uint *)ptr;
+ PRIM_RESTART_LOOP(elt_ui);
+ }
+ break;
+ default:
+ assert(0 && "bad index_size in handle_fallback_primitive_restart()");
+ }
+ }
+
+ if (transfer)
+ pipe_buffer_unmap(pipe, transfer);
+}
+
/**
* Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to
@@ -794,7 +960,22 @@ st_draw_vbo(struct gl_context *ctx,
info.max_index = info.start + info.count - 1;
}
- if (u_trim_pipe_prim(info.mode, &info.count))
+ if (info.primitive_restart) {
+ /*
+ * Handle primitive restart for drivers that doesn't support it.
+ *
+ * The VBO module handles restart inside of draw_arrays for us,
+ * but we should still remove the primitive_restart flag on the
+ * info struct, the fallback function does this for us. Just
+ * remove the flag for all drivers in this case as well.
+ */
+ if (st->sw_primitive_restart || !info.indexed)
+ handle_fallback_primitive_restart(pipe, ib, &ibuffer, &info);
+ else
+ /* don't trim, restarts might be inside index list */
+ pipe->draw_vbo(pipe, &info);
+ }
+ else if (u_trim_pipe_prim(info.mode, &info.count))
pipe->draw_vbo(pipe, &info);
}
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index a1f029089..6b9ff6b72 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -222,6 +222,8 @@ void st_init_limits(struct st_context *st)
_mesa_override_glsl_version(st->ctx);
c->UniformBooleanTrue = ~0;
}
+
+ c->StripTextureBorder = GL_TRUE;
}
@@ -555,8 +557,9 @@ void st_init_extensions(struct st_context *st)
#endif
}
- if (screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) {
- ctx->Extensions.NV_primitive_restart = GL_TRUE;
+ ctx->Extensions.NV_primitive_restart = GL_TRUE;
+ if (!screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) {
+ st->sw_primitive_restart = GL_TRUE;
}
if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) {
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 18e8a1db4..145bd7dcd 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -4322,37 +4322,15 @@ compile_tgsi_instruction(struct st_translate *t,
}
/**
- * Emit the TGSI instructions to adjust the WPOS pixel center convention
- * Basically, add (adjX, adjY) to the fragment position.
- */
-static void
-emit_adjusted_wpos(struct st_translate *t,
- const struct gl_program *program,
- float adjX, float adjY)
-{
- struct ureg_program *ureg = t->ureg;
- struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg);
- struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
-
- /* Note that we bias X and Y and pass Z and W through unchanged.
- * The shader might also use gl_FragCoord.w and .z.
- */
- ureg_ADD(ureg, wpos_temp, wpos_input,
- ureg_imm4f(ureg, adjX, adjY, 0.0f, 0.0f));
-
- t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp);
-}
-
-
-/**
- * Emit the TGSI instructions for inverting the WPOS y coordinate.
+ * Emit the TGSI instructions for inverting and adjusting WPOS.
* This code is unavoidable because it also depends on whether
* a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM).
*/
static void
-emit_wpos_inversion(struct st_translate *t,
- const struct gl_program *program,
- bool invert)
+emit_wpos_adjustment( struct st_translate *t,
+ const struct gl_program *program,
+ boolean invert,
+ GLfloat adjX, GLfloat adjY[2])
{
struct ureg_program *ureg = t->ureg;
@@ -4371,35 +4349,55 @@ emit_wpos_inversion(struct st_translate *t,
unsigned wposTransConst = _mesa_add_state_reference(program->Parameters,
wposTransformState);
- struct ureg_src wpostrans = ureg_DECL_constant(ureg, wposTransConst);
- struct ureg_dst wpos_temp;
+ struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst );
+ struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg );
struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
- /* MOV wpos_temp, input[wpos]
- */
- if (wpos_input.File == TGSI_FILE_TEMPORARY)
- wpos_temp = ureg_dst(wpos_input);
- else {
- wpos_temp = ureg_DECL_temporary(ureg);
- ureg_MOV(ureg, wpos_temp, wpos_input);
+ /* First, apply the coordinate shift: */
+ if (adjX || adjY[0] || adjY[1]) {
+ if (adjY[0] != adjY[1]) {
+ /* Adjust the y coordinate by adjY[1] or adjY[0] respectively
+ * depending on whether inversion is actually going to be applied
+ * or not, which is determined by testing against the inversion
+ * state variable used below, which will be either +1 or -1.
+ */
+ struct ureg_dst adj_temp = ureg_DECL_temporary(ureg);
+
+ ureg_CMP(ureg, adj_temp,
+ ureg_scalar(wpostrans, invert ? 2 : 0),
+ ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f),
+ ureg_imm4f(ureg, adjX, adjY[1], 0.0f, 0.0f));
+ ureg_ADD(ureg, wpos_temp, wpos_input, ureg_src(adj_temp));
+ } else {
+ ureg_ADD(ureg, wpos_temp, wpos_input,
+ ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f));
+ }
+ wpos_input = ureg_src(wpos_temp);
+ } else {
+ /* MOV wpos_temp, input[wpos]
+ */
+ ureg_MOV( ureg, wpos_temp, wpos_input );
}
+ /* Now the conditional y flip: STATE_FB_WPOS_Y_TRANSFORM.xy/zw will be
+ * inversion/identity, or the other way around if we're drawing to an FBO.
+ */
if (invert) {
/* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy
*/
- ureg_MAD(ureg,
- ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y),
- wpos_input,
- ureg_scalar(wpostrans, 0),
- ureg_scalar(wpostrans, 1));
+ ureg_MAD( ureg,
+ ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
+ wpos_input,
+ ureg_scalar(wpostrans, 0),
+ ureg_scalar(wpostrans, 1));
} else {
/* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww
*/
- ureg_MAD(ureg,
- ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y),
- wpos_input,
- ureg_scalar(wpostrans, 2),
- ureg_scalar(wpostrans, 3));
+ ureg_MAD( ureg,
+ ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
+ wpos_input,
+ ureg_scalar(wpostrans, 2),
+ ureg_scalar(wpostrans, 3));
}
/* Use wpos_temp as position input from here on:
@@ -4420,8 +4418,37 @@ emit_wpos(struct st_context *st,
const struct gl_fragment_program *fp =
(const struct gl_fragment_program *) program;
struct pipe_screen *pscreen = st->pipe->screen;
+ GLfloat adjX = 0.0f;
+ GLfloat adjY[2] = { 0.0f, 0.0f };
boolean invert = FALSE;
+ /* Query the pixel center conventions supported by the pipe driver and set
+ * adjX, adjY to help out if it cannot handle the requested one internally.
+ *
+ * The bias of the y-coordinate depends on whether y-inversion takes place
+ * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are
+ * drawing to an FBO (causes additional inversion), and whether the the pipe
+ * driver origin and the requested origin differ (the latter condition is
+ * stored in the 'invert' variable).
+ *
+ * For height = 100 (i = integer, h = half-integer, l = lower, u = upper):
+ *
+ * center shift only:
+ * i -> h: +0.5
+ * h -> i: -0.5
+ *
+ * inversion only:
+ * l,i -> u,i: ( 0.0 + 1.0) * -1 + 100 = 99
+ * l,h -> u,h: ( 0.5 + 0.0) * -1 + 100 = 99.5
+ * u,i -> l,i: (99.0 + 1.0) * -1 + 100 = 0
+ * u,h -> l,h: (99.5 + 0.0) * -1 + 100 = 0.5
+ *
+ * inversion and center shift:
+ * l,i -> u,h: ( 0.0 + 0.5) * -1 + 100 = 99.5
+ * l,h -> u,i: ( 0.5 + 0.5) * -1 + 100 = 99
+ * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5
+ * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0
+ */
if (fp->OriginUpperLeft) {
/* Fragment shader wants origin in upper-left */
if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) {
@@ -4449,12 +4476,17 @@ emit_wpos(struct st_context *st,
if (fp->PixelCenterInteger) {
/* Fragment shader wants pixel center integer */
- if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER))
+ if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
/* the driver supports pixel center integer */
+ adjY[1] = 1.0f;
ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
- else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER))
+ }
+ else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) {
/* the driver supports pixel center half integer, need to bias X,Y */
- emit_adjusted_wpos(t, program, 0.5f, invert ? 0.5f : -0.5f);
+ adjX = -0.5f;
+ adjY[0] = -0.5f;
+ adjY[1] = 0.5f;
+ }
else
assert(0);
}
@@ -4465,8 +4497,8 @@ emit_wpos(struct st_context *st,
}
else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
/* the driver supports pixel center integer, need to bias X,Y */
+ adjX = adjY[0] = adjY[1] = 0.5f;
ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
- emit_adjusted_wpos(t, program, 0.5f, invert ? -0.5f : 0.5f);
}
else
assert(0);
@@ -4474,7 +4506,7 @@ emit_wpos(struct st_context *st,
/* we invert after adjustment so that we avoid the MOV to temporary,
* and reuse the adjustment ADD instead */
- emit_wpos_inversion(t, program, invert);
+ emit_wpos_adjustment(t, program, invert, adjX, adjY);
}
/**
@@ -5026,7 +5058,9 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
- progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress;
+ progress = do_common_optimization(ir, true, true,
+ options->MaxUnrollIterations)
+ || progress;
progress = lower_quadop_vector(ir, false) || progress;
diff --git a/mesalib/src/mesa/swrast/s_context.c b/mesalib/src/mesa/swrast/s_context.c
index 5287671d7..9112cf30d 100644
--- a/mesalib/src/mesa/swrast/s_context.c
+++ b/mesalib/src/mesa/swrast/s_context.c
@@ -747,6 +747,12 @@ _swrast_CreateContext( struct gl_context *ctx )
swrast->AllowVertexFog = GL_TRUE;
swrast->AllowPixelFog = GL_TRUE;
+ swrast->Driver.SpanRenderStart = _swrast_span_render_start;
+ swrast->Driver.SpanRenderFinish = _swrast_span_render_finish;
+
+ ctx->Driver.MapTexture = _swrast_map_texture;
+ ctx->Driver.UnmapTexture = _swrast_unmap_texture;
+
/* Optimized Accum buffer */
swrast->_IntegerAccumMode = GL_FALSE;
swrast->_IntegerAccumScaler = 0.0;
@@ -837,6 +843,24 @@ _swrast_render_primitive( struct gl_context *ctx, GLenum prim )
}
+/** called via swrast->Driver.SpanRenderStart() */
+void
+_swrast_span_render_start(struct gl_context *ctx)
+{
+ _swrast_map_textures(ctx);
+ _swrast_map_renderbuffers(ctx);
+}
+
+
+/** called via swrast->Driver.SpanRenderFinish() */
+void
+_swrast_span_render_finish(struct gl_context *ctx)
+{
+ _swrast_unmap_textures(ctx);
+ _swrast_unmap_renderbuffers(ctx);
+}
+
+
void
_swrast_render_start( struct gl_context *ctx )
{
diff --git a/mesalib/src/mesa/swrast/s_context.h b/mesalib/src/mesa/swrast/s_context.h
index ec8451eb8..d3ba37819 100644
--- a/mesalib/src/mesa/swrast/s_context.h
+++ b/mesalib/src/mesa/swrast/s_context.h
@@ -138,20 +138,17 @@ struct swrast_texture_image
/** used for mipmap LOD computation */
GLfloat WidthScale, HeightScale, DepthScale;
-#if 0
- GLubyte *Data; /**< The actual texture data in malloc'd memory */
+ /** These fields only valid when texture memory is mapped */
+ GLint RowStride; /**< Padded width in units of texels */
+ GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to
+ each 2D slice in 'Data', in texels */
+ GLubyte *Data; /**< Image data, accessed via FetchTexel() */
- GLint TexelSize; /**< bytes per texel block */
-#endif
+ /** Malloc'd texture memory */
+ GLubyte *Buffer;
FetchTexelFunc FetchTexel;
StoreTexelFunc Store;
-
-#if 0
- /** These fields only valid when texture memory is mapped */
- GLubyte **SliceMaps; /**< points to OneMap or a malloc'd array */
- GLint RowStride; /**< bytes per row of blocks */
-#endif
};
@@ -339,6 +336,31 @@ swrast_render_finish(struct gl_context *ctx)
}
+extern void
+_swrast_span_render_start(struct gl_context *ctx);
+
+extern void
+_swrast_span_render_finish(struct gl_context *ctx);
+
+extern void
+_swrast_map_textures(struct gl_context *ctx);
+
+extern void
+_swrast_unmap_textures(struct gl_context *ctx);
+
+extern void
+_swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj);
+
+extern void
+_swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj);
+
+
+extern void
+_swrast_map_renderbuffers(struct gl_context *ctx);
+
+extern void
+_swrast_unmap_renderbuffers(struct gl_context *ctx);
+
/**
* Size of an RGBA pixel, in bytes, for given datatype.
diff --git a/mesalib/src/mesa/swrast/s_fragprog.c b/mesalib/src/mesa/swrast/s_fragprog.c
index 7f205a200..1caa0ebc2 100644
--- a/mesalib/src/mesa/swrast/s_fragprog.c
+++ b/mesalib/src/mesa/swrast/s_fragprog.c
@@ -237,7 +237,8 @@ run_program(struct gl_context *ctx, SWspan *span, GLuint start, GLuint end)
else if (depth >= 1.0)
span->array->z[i] = ctx->DrawBuffer->_DepthMax;
else
- span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF);
+ span->array->z[i] =
+ (GLuint) (depth * ctx->DrawBuffer->_DepthMaxF + 0.5F);
}
}
else {
diff --git a/mesalib/src/mesa/swrast/s_span.c b/mesalib/src/mesa/swrast/s_span.c
index e517c9ae1..4124e444e 100644
--- a/mesalib/src/mesa/swrast/s_span.c
+++ b/mesalib/src/mesa/swrast/s_span.c
@@ -1251,7 +1251,10 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
4 * span->end * sizeof(GLchan));
}
- ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB ||
+ ASSERT(rb->_BaseFormat == GL_RGBA ||
+ rb->_BaseFormat == GL_RGB ||
+ rb->_BaseFormat == GL_RED ||
+ rb->_BaseFormat == GL_RG ||
rb->_BaseFormat == GL_ALPHA);
if (ctx->Color.ColorLogicOpEnabled) {
diff --git a/mesalib/src/mesa/swrast/s_texcombine.c b/mesalib/src/mesa/swrast/s_texcombine.c
index c67c356c1..a7cbb4424 100644
--- a/mesalib/src/mesa/swrast/s_texcombine.c
+++ b/mesalib/src/mesa/swrast/s_texcombine.c
@@ -108,6 +108,7 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n,
i--;
}
_mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine");
+ free(rgba);
return;
}
}
diff --git a/mesalib/src/mesa/swrast/s_texfetch_tmp.h b/mesalib/src/mesa/swrast/s_texfetch_tmp.h
index c63b2043c..8b7e930f9 100644
--- a/mesalib/src/mesa/swrast/s_texfetch_tmp.h
+++ b/mesalib/src/mesa/swrast/s_texfetch_tmp.h
@@ -43,7 +43,7 @@
#if DIM == 1
#define TEXEL_ADDR( type, image, i, j, k, size ) \
- ((void) (j), (void) (k), ((type *)(image)->Base.Data + (i) * (size)))
+ ((void) (j), (void) (k), ((type *)(image)->Data + (i) * (size)))
#define FETCH(x) fetch_texel_1d_##x
@@ -51,15 +51,15 @@
#define TEXEL_ADDR( type, image, i, j, k, size ) \
((void) (k), \
- ((type *)(image)->Base.Data + ((image)->Base.RowStride * (j) + (i)) * (size)))
+ ((type *)(image)->Data + ((image)->RowStride * (j) + (i)) * (size)))
#define FETCH(x) fetch_texel_2d_##x
#elif DIM == 3
#define TEXEL_ADDR( type, image, i, j, k, size ) \
- ((type *)(image)->Base.Data + ((image)->Base.ImageOffsets[k] \
- + (image)->Base.RowStride * (j) + (i)) * (size))
+ ((type *)(image)->Data + ((image)->ImageOffsets[k] \
+ + (image)->RowStride * (j) + (i)) * (size))
#define FETCH(x) fetch_texel_3d_##x
diff --git a/mesalib/src/mesa/swrast/s_texfilter.c b/mesalib/src/mesa/swrast/s_texfilter.c
index f8b0fa1aa..9de5c0276 100644
--- a/mesalib/src/mesa/swrast/s_texfilter.c
+++ b/mesalib/src/mesa/swrast/s_texfilter.c
@@ -1375,7 +1375,7 @@ opt_sample_rgb_2d(struct gl_context *ctx,
GLint i = IFLOOR(texcoords[k][0] * width) & colMask;
GLint j = IFLOOR(texcoords[k][1] * height) & rowMask;
GLint pos = (j << shift) | i;
- GLubyte *texel = ((GLubyte *) img->Data) + 3*pos;
+ GLubyte *texel = swImg->Data + 3 * pos;
rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]);
rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]);
rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]);
@@ -1419,7 +1419,7 @@ opt_sample_rgba_2d(struct gl_context *ctx,
const GLint col = IFLOOR(texcoords[i][0] * width) & colMask;
const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask;
const GLint pos = (row << shift) | col;
- const GLuint texel = *((GLuint *) img->Data + pos);
+ const GLuint texel = *((GLuint *) swImg->Data + pos);
rgba[i][RCOMP] = UBYTE_TO_FLOAT( (texel >> 24) );
rgba[i][GCOMP] = UBYTE_TO_FLOAT( (texel >> 16) & 0xff );
rgba[i][BCOMP] = UBYTE_TO_FLOAT( (texel >> 8) & 0xff );
@@ -1442,7 +1442,7 @@ sample_lambda_2d(struct gl_context *ctx,
const GLboolean repeatNoBorderPOT = (tObj->Sampler.WrapS == GL_REPEAT)
&& (tObj->Sampler.WrapT == GL_REPEAT)
- && (tImg->Border == 0 && (tImg->Width == tImg->RowStride))
+ && (tImg->Border == 0 && (tImg->Width == swImg->RowStride))
&& swImg->_IsPowerOfTwo;
ASSERT(lambda != NULL);
diff --git a/mesalib/src/mesa/swrast/s_texrender.c b/mesalib/src/mesa/swrast/s_texrender.c
index 47e458e1c..e2b921512 100644
--- a/mesalib/src/mesa/swrast/s_texrender.c
+++ b/mesalib/src/mesa/swrast/s_texrender.c
@@ -31,6 +31,15 @@ struct texture_renderbuffer
};
+/** cast wrapper */
+static inline struct texture_renderbuffer *
+texture_renderbuffer(struct gl_renderbuffer *rb)
+{
+ return (struct texture_renderbuffer *) rb;
+}
+
+
+
/**
* Get row of values from the renderbuffer that wraps a texture image.
*/
@@ -38,8 +47,7 @@ static void
texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
GLint x, GLint y, void *values)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -107,8 +115,7 @@ static void
texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
const GLint x[], const GLint y[], void *values)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -174,8 +181,7 @@ static void
texture_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
GLint x, GLint y, const void *values, const GLubyte *mask)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -236,8 +242,7 @@ static void
texture_put_row_rgb(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
GLint x, GLint y, const void *values, const GLubyte *mask)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -296,8 +301,7 @@ static void
texture_put_mono_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count,
GLint x, GLint y, const void *value, const GLubyte *mask)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -356,8 +360,7 @@ texture_put_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
const GLint x[], const GLint y[], const void *values,
const GLubyte *mask)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -415,8 +418,7 @@ texture_put_mono_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
GLuint count, const GLint x[], const GLint y[],
const void *value, const GLubyte *mask)
{
- const struct texture_renderbuffer *trb
- = (const struct texture_renderbuffer *) rb;
+ struct texture_renderbuffer *trb = texture_renderbuffer(rb);
const GLint z = trb->Zoffset;
GLuint i;
@@ -610,7 +612,6 @@ update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
trb->Base.DataType = CHAN_TYPE;
trb->Base._BaseFormat = GL_RGBA;
}
- trb->Base.Data = trb->TexImage->Base.Data;
}
diff --git a/mesalib/src/mesa/swrast/s_texture.c b/mesalib/src/mesa/swrast/s_texture.c
index 36b429cfa..fb1edb318 100644
--- a/mesalib/src/mesa/swrast/s_texture.c
+++ b/mesalib/src/mesa/swrast/s_texture.c
@@ -69,14 +69,32 @@ _swrast_alloc_texture_image_buffer(struct gl_context *ctx,
{
struct swrast_texture_image *swImg = swrast_texture_image(texImage);
GLuint bytes = _mesa_format_image_size(format, width, height, depth);
+ GLuint i;
/* This _should_ be true (revisit if these ever fail) */
assert(texImage->Width == width);
assert(texImage->Height == height);
assert(texImage->Depth == depth);
- assert(!texImage->Data);
- texImage->Data = _mesa_align_malloc(bytes, 512);
+ assert(!swImg->Buffer);
+ swImg->Buffer = _mesa_align_malloc(bytes, 512);
+ if (!swImg->Buffer)
+ return GL_FALSE;
+
+ /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */
+ swImg->RowStride = width;
+
+ /* Allocate the ImageOffsets array and initialize to typical values.
+ * We allocate the array for 1D/2D textures too in order to avoid special-
+ * case code in the texstore routines.
+ */
+ swImg->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint));
+ if (!swImg->ImageOffsets)
+ return GL_FALSE;
+
+ for (i = 0; i < depth; i++) {
+ swImg->ImageOffsets[i] = i * width * height;
+ }
if ((width == 1 || _mesa_is_pow_two(texImage->Width2)) &&
(height == 1 || _mesa_is_pow_two(texImage->Height2)) &&
@@ -98,7 +116,7 @@ _swrast_alloc_texture_image_buffer(struct gl_context *ctx,
swImg->DepthScale = (GLfloat) texImage->Depth;
}
- return texImage->Data != NULL;
+ return GL_TRUE;
}
@@ -109,11 +127,16 @@ void
_swrast_free_texture_image_buffer(struct gl_context *ctx,
struct gl_texture_image *texImage)
{
- if (texImage->Data) {
- _mesa_align_free(texImage->Data);
+ struct swrast_texture_image *swImage = swrast_texture_image(texImage);
+ if (swImage->Buffer) {
+ _mesa_align_free(swImage->Buffer);
+ swImage->Buffer = NULL;
}
- texImage->Data = NULL;
+ if (swImage->ImageOffsets) {
+ free(swImage->ImageOffsets);
+ swImage->ImageOffsets = NULL;
+ }
}
@@ -155,6 +178,7 @@ _swrast_map_teximage(struct gl_context *ctx,
GLubyte **mapOut,
GLint *rowStrideOut)
{
+ struct swrast_texture_image *swImage = swrast_texture_image(texImage);
GLubyte *map;
GLint stride, texelSize;
GLuint bw, bh;
@@ -165,9 +189,9 @@ _swrast_map_teximage(struct gl_context *ctx,
stride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
_mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
- assert(texImage->Data);
+ assert(swImage->Buffer);
- map = texImage->Data;
+ map = swImage->Buffer;
if (texImage->TexObject->Target == GL_TEXTURE_3D ||
texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY) {
@@ -200,3 +224,138 @@ _swrast_unmap_teximage(struct gl_context *ctx,
{
/* nop */
}
+
+
+void
+_swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+ const GLuint faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
+ GLuint face, level;
+
+ for (face = 0; face < faces; face++) {
+ for (level = texObj->BaseLevel; level < MAX_TEXTURE_LEVELS; level++) {
+ struct gl_texture_image *texImage = texObj->Image[face][level];
+ if (texImage) {
+ struct swrast_texture_image *swImage =
+ swrast_texture_image(texImage);
+
+ /* XXX we'll eventually call _swrast_map_teximage() here */
+ swImage->Data = swImage->Buffer;
+ assert(swImage->Buffer);
+ }
+ }
+ }
+}
+
+
+void
+_swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+ const GLuint faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
+ GLuint face, level;
+
+ for (face = 0; face < faces; face++) {
+ for (level = texObj->BaseLevel; level < MAX_TEXTURE_LEVELS; level++) {
+ struct gl_texture_image *texImage = texObj->Image[face][level];
+ if (texImage) {
+ struct swrast_texture_image *swImage
+ = swrast_texture_image(texImage);
+
+ /* XXX we'll eventually call _swrast_unmap_teximage() here */
+ swImage->Data = NULL;
+ }
+ }
+ }
+}
+
+
+/**
+ * Map all textures for reading prior to software rendering.
+ */
+void
+_swrast_map_textures(struct gl_context *ctx)
+{
+ GLbitfield enabledUnits = ctx->Texture._EnabledUnits;
+
+ /* loop over enabled texture units */
+ while (enabledUnits) {
+ GLuint unit = _mesa_ffs(enabledUnits) - 1;
+ struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
+
+ _swrast_map_texture(ctx, texObj);
+
+ enabledUnits &= ~(1 << unit);
+ }
+}
+
+
+/**
+ * Unmap all textures for reading prior to software rendering.
+ */
+void
+_swrast_unmap_textures(struct gl_context *ctx)
+{
+ GLbitfield enabledUnits = ctx->Texture._EnabledUnits;
+
+ /* loop over enabled texture units */
+ while (enabledUnits) {
+ GLuint unit = _mesa_ffs(enabledUnits) - 1;
+ struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
+
+ _swrast_unmap_texture(ctx, texObj);
+
+ enabledUnits &= ~(1 << unit);
+ }
+}
+
+
+/**
+ * Map or unmap any textures that we may be rendering to as renderbuffers.
+ */
+static void
+map_unmap_renderbuffers(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ GLboolean map)
+{
+ GLuint i;
+
+ for (i = 0; i < Elements(fb->Attachment); i++) {
+ struct gl_texture_object *texObj = fb->Attachment[i].Texture;
+ if (texObj) {
+ const GLuint level = fb->Attachment[i].TextureLevel;
+ const GLuint face = fb->Attachment[i].CubeMapFace;
+ struct gl_texture_image *texImage = texObj->Image[face][level];
+ if (texImage) {
+ struct swrast_texture_image *swImage
+ = swrast_texture_image(texImage);
+
+ if (map) {
+ /* XXX we'll eventually call _swrast_map_teximage() here */
+ swImage->Data = swImage->Buffer;
+ }
+ else {
+ /* XXX we'll eventually call _swrast_unmap_teximage() here */
+ swImage->Data = NULL;
+ }
+ }
+ }
+ }
+}
+
+
+void
+_swrast_map_renderbuffers(struct gl_context *ctx)
+{
+ map_unmap_renderbuffers(ctx, ctx->DrawBuffer, GL_TRUE);
+ if (ctx->ReadBuffer != ctx->DrawBuffer)
+ map_unmap_renderbuffers(ctx, ctx->ReadBuffer, GL_TRUE);
+}
+
+
+void
+_swrast_unmap_renderbuffers(struct gl_context *ctx)
+{
+ map_unmap_renderbuffers(ctx, ctx->DrawBuffer, GL_FALSE);
+ if (ctx->ReadBuffer != ctx->DrawBuffer)
+ map_unmap_renderbuffers(ctx, ctx->ReadBuffer, GL_FALSE);
+}
diff --git a/mesalib/src/mesa/swrast/s_triangle.c b/mesalib/src/mesa/swrast/s_triangle.c
index 839c4fd08..b4f8e7479 100644
--- a/mesalib/src/mesa/swrast/s_triangle.c
+++ b/mesalib/src/mesa/swrast/s_triangle.c
@@ -127,10 +127,12 @@ _swrast_culltriangle( struct gl_context *ctx,
ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \
const struct gl_texture_image *texImg = \
obj->Image[0][obj->BaseLevel]; \
+ const struct swrast_texture_image *swImg = \
+ swrast_texture_image_const(texImg); \
const GLfloat twidth = (GLfloat) texImg->Width; \
const GLfloat theight = (GLfloat) texImg->Height; \
const GLint twidth_log2 = texImg->WidthLog2; \
- const GLubyte *texture = (const GLubyte *) texImg->Data; \
+ const GLubyte *texture = (const GLubyte *) swImg->Data; \
const GLint smask = texImg->Width - 1; \
const GLint tmask = texImg->Height - 1; \
ASSERT(texImg->TexFormat == MESA_FORMAT_RGB888); \
@@ -181,10 +183,12 @@ _swrast_culltriangle( struct gl_context *ctx,
ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \
const struct gl_texture_image *texImg = \
obj->Image[0][obj->BaseLevel]; \
+ const struct swrast_texture_image *swImg = \
+ swrast_texture_image_const(texImg); \
const GLfloat twidth = (GLfloat) texImg->Width; \
const GLfloat theight = (GLfloat) texImg->Height; \
const GLint twidth_log2 = texImg->WidthLog2; \
- const GLubyte *texture = (const GLubyte *) texImg->Data; \
+ const GLubyte *texture = (const GLubyte *) swImg->Data; \
const GLint smask = texImg->Width - 1; \
const GLint tmask = texImg->Height - 1; \
ASSERT(texImg->TexFormat == MESA_FORMAT_RGB888); \
@@ -533,9 +537,11 @@ affine_span(struct gl_context *ctx, SWspan *span,
ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \
const struct gl_texture_image *texImg = \
obj->Image[0][obj->BaseLevel]; \
+ const struct swrast_texture_image *swImg = \
+ swrast_texture_image_const(texImg); \
const GLfloat twidth = (GLfloat) texImg->Width; \
const GLfloat theight = (GLfloat) texImg->Height; \
- info.texture = (const GLchan *) texImg->Data; \
+ info.texture = (const GLchan *) swImg->Data; \
info.twidth_log2 = texImg->WidthLog2; \
info.smask = texImg->Width - 1; \
info.tmask = texImg->Height - 1; \
@@ -800,7 +806,9 @@ fast_persp_span(struct gl_context *ctx, SWspan *span,
ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \
const struct gl_texture_image *texImg = \
obj->Image[0][obj->BaseLevel]; \
- info.texture = (const GLchan *) texImg->Data; \
+ const struct swrast_texture_image *swImg = \
+ swrast_texture_image_const(texImg); \
+ info.texture = (const GLchan *) swImg->Data; \
info.twidth_log2 = texImg->WidthLog2; \
info.smask = texImg->Width - 1; \
info.tmask = texImg->Height - 1; \
@@ -1062,7 +1070,7 @@ _swrast_choose_triangle( struct gl_context *ctx )
&& texObj2D->_Swizzle == SWIZZLE_NOOP
&& swImg->_IsPowerOfTwo
&& texImg->Border == 0
- && texImg->Width == texImg->RowStride
+ && texImg->Width == swImg->RowStride
&& (format == MESA_FORMAT_RGB888 || format == MESA_FORMAT_RGBA8888)
&& minFilter == magFilter
&& ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
diff --git a/mesalib/src/mesa/tnl/t_vb_program.c b/mesalib/src/mesa/tnl/t_vb_program.c
index 367dfd5bb..836e8e8fa 100644
--- a/mesalib/src/mesa/tnl/t_vb_program.c
+++ b/mesalib/src/mesa/tnl/t_vb_program.c
@@ -68,6 +68,8 @@ struct vp_stage_data {
GLubyte *clipmask; /**< clip flags */
GLubyte ormask, andmask; /**< for clipping */
+ GLboolean vertex_textures;
+
struct gl_program_machine machine;
};
diff --git a/mesalib/src/mesa/vbo/vbo_exec.h b/mesalib/src/mesa/vbo/vbo_exec.h
index 9a1b5a127..0b72579a8 100644
--- a/mesalib/src/mesa/vbo/vbo_exec.h
+++ b/mesalib/src/mesa/vbo/vbo_exec.h
@@ -78,9 +78,6 @@ struct vbo_exec_copied_vtx {
};
-typedef void (*vbo_attrfv_func)( const GLfloat * );
-
-
struct vbo_exec_context
{
struct gl_context *ctx;
@@ -113,8 +110,6 @@ struct vbo_exec_context
* values are squashed down to the 32 attributes passed to the
* vertex program below:
*/
- enum vp_mode program_mode;
- GLuint enabled_flags;
const struct gl_client_array *inputs[VERT_ATTRIB_MAX];
} vtx;
@@ -126,10 +121,6 @@ struct vbo_exec_context
} eval;
struct {
- enum vp_mode program_mode;
- GLuint enabled_flags;
- GLuint array_obj;
-
/* These just mirror the current arrayobj (todo: make arrayobj
* look like this and remove the mirror):
*/
diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c
index 4e4f2c947..7023380a1 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_array.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_array.c
@@ -422,8 +422,6 @@ bind_array_obj(struct gl_context *ctx)
assert(i < Elements(exec->array.generic_array));
exec->array.generic_array[i] = &arrayObj->VertexAttrib[i];
}
-
- exec->array.array_obj = arrayObj->Name;
}
@@ -444,10 +442,7 @@ recalculate_input_bindings(struct gl_context *ctx)
GLbitfield const_inputs = 0x0;
GLuint i;
- exec->array.program_mode = get_program_mode(ctx);
- exec->array.enabled_flags = ctx->Array.ArrayObj->_Enabled;
-
- switch (exec->array.program_mode) {
+ switch (get_program_mode(ctx)) {
case VP_NONE:
/* When no vertex program is active (or the vertex program is generated
* from fixed-function state). We put the material values into the
diff --git a/mesalib/src/mesa/vbo/vbo_save.h b/mesalib/src/mesa/vbo/vbo_save.h
index a064090cf..a85a7cbf6 100644
--- a/mesalib/src/mesa/vbo/vbo_save.h
+++ b/mesalib/src/mesa/vbo/vbo_save.h
@@ -146,7 +146,6 @@ struct vbo_save_context {
GLuint vert_count;
GLuint max_vert;
GLboolean dangling_attr_ref;
- GLboolean have_materials;
GLuint opcode_vertex_list;
diff --git a/mkfontscale/data.h b/mkfontscale/data.h
index 6fb43ae79..aecb04859 100644
--- a/mkfontscale/data.h
+++ b/mkfontscale/data.h
@@ -27,7 +27,9 @@
URW++, and both strings appear in the notice. */
static const char *notice_foundries[][2] =
- {{"Bigelow", "b&h"},
+ {{"Iorsh", "culmus"},
+ {"Gnat", "culmus"},
+ {"Bigelow", "b&h"},
{"Adobe", "adobe"},
{"Bitstream", "bitstream"},
{"Monotype", "monotype"},
@@ -42,9 +44,7 @@ static const char *notice_foundries[][2] =
{"Microsoft", "microsoft"},
{"Omega", "omega"},
{"Font21", "hwan"},
- {"HanYang System", "hanyang"},
- {"Iorsh", "culmus"},
- {"Gnat", "culmus"}};
+ {"HanYang System", "hanyang"}};
/* This table is partly taken from ttmkfdir by Joerg Pommnitz. */
diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index ff87e26a3..df8677a2f 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -87,6 +87,8 @@ release-upload: release-check $(tar_gz) $(tar_bz2) $(sha1_tgz) $(sha1_tbz2) $(md
scp $(tar_gz) $(tar_bz2) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR)
ssh $(RELEASE_CAIRO_HOST) "rm -f $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-[0-9]* && ln -s $(tar_gz) $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-$(VERSION)"
+RELEASE_TYPE = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo "stable release in the" ; else echo "development snapshot leading up to a stable"; fi)
+
release-publish-message: $(HASHFILES) ensure-prev
@echo "Please follow the instructions in RELEASING to push stuff out and"
@echo "send out the announcement mails. Here is the excerpt you need:"
@@ -94,7 +96,7 @@ release-publish-message: $(HASHFILES) ensure-prev
@echo "Lists: $(RELEASE_ANNOUNCE_LIST)"
@echo "Subject: [ANNOUNCE] $(PACKAGE) release $(VERSION) now available"
@echo "============================== CUT HERE =============================="
- @echo "A new $(PACKAGE) release $(VERSION) is now available"
+ @echo "A new $(PACKAGE) release $(VERSION) is now available. This is a $(RELEASE_TYPE)"
@echo ""
@echo "tar.gz:"
@echo " $(RELEASE_CAIRO_URL)/$(tar_gz)"
diff --git a/pixman/pixman/pixman-gradient-walker.c b/pixman/pixman/pixman-gradient-walker.c
index dd666b412..048039e89 100644
--- a/pixman/pixman/pixman-gradient-walker.c
+++ b/pixman/pixman/pixman-gradient-walker.c
@@ -31,7 +31,7 @@
void
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
gradient_t * gradient,
- unsigned int spread)
+ pixman_repeat_t repeat)
{
walker->num_stops = gradient->n_stops;
walker->stops = gradient->stops;
@@ -42,112 +42,54 @@ _pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
walker->left_rb = 0;
walker->right_ag = 0;
walker->right_rb = 0;
- walker->spread = spread;
+ walker->repeat = repeat;
walker->need_reset = TRUE;
}
-void
-_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
- pixman_fixed_32_32_t pos)
+static void
+gradient_walker_reset (pixman_gradient_walker_t *walker,
+ pixman_fixed_48_16_t pos)
{
int32_t x, left_x, right_x;
- pixman_color_t *left_c, *right_c;
+ pixman_color_t *left_c, *right_c;
int n, count = walker->num_stops;
- pixman_gradient_stop_t * stops = walker->stops;
-
- static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
+ pixman_gradient_stop_t *stops = walker->stops;
- switch (walker->spread)
+ if (walker->repeat == PIXMAN_REPEAT_NORMAL)
{
- case PIXMAN_REPEAT_NORMAL:
- x = (int32_t)pos & 0xFFFF;
- for (n = 0; n < count; n++)
- if (x < stops[n].x)
- break;
- if (n == 0)
- {
- left_x = stops[count - 1].x - 0x10000;
- left_c = &stops[count - 1].color;
- }
- else
- {
- left_x = stops[n - 1].x;
- left_c = &stops[n - 1].color;
- }
-
- if (n == count)
- {
- right_x = stops[0].x + 0x10000;
- right_c = &stops[0].color;
- }
- else
- {
- right_x = stops[n].x;
- right_c = &stops[n].color;
- }
- left_x += (pos - x);
- right_x += (pos - x);
- break;
-
- case PIXMAN_REPEAT_PAD:
- for (n = 0; n < count; n++)
- if (pos < stops[n].x)
- break;
-
- if (n == 0)
- {
- left_x = INT32_MIN;
- left_c = &stops[0].color;
- }
- else
- {
- left_x = stops[n - 1].x;
- left_c = &stops[n - 1].color;
- }
-
- if (n == count)
- {
- right_x = INT32_MAX;
- right_c = &stops[n - 1].color;
- }
- else
- {
- right_x = stops[n].x;
- right_c = &stops[n].color;
- }
- break;
-
- case PIXMAN_REPEAT_REFLECT:
- x = (int32_t)pos & 0xFFFF;
+ x = (int32_t)pos & 0xffff;
+ }
+ else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
+ {
+ x = (int32_t)pos & 0xffff;
if ((int32_t)pos & 0x10000)
x = 0x10000 - x;
- for (n = 0; n < count; n++)
- if (x < stops[n].x)
- break;
-
- if (n == 0)
- {
- left_x = -stops[0].x;
- left_c = &stops[0].color;
- }
- else
- {
- left_x = stops[n - 1].x;
- left_c = &stops[n - 1].color;
- }
-
- if (n == count)
- {
- right_x = 0x20000 - stops[n - 1].x;
- right_c = &stops[n - 1].color;
- }
- else
- {
- right_x = stops[n].x;
- right_c = &stops[n].color;
- }
-
+ }
+ else
+ {
+ x = pos;
+ }
+
+ for (n = 0; n < count; n++)
+ {
+ if (x < stops[n].x)
+ break;
+ }
+
+ left_x = stops[n - 1].x;
+ left_c = &stops[n - 1].color;
+
+ right_x = stops[n].x;
+ right_c = &stops[n].color;
+
+ if (walker->repeat == PIXMAN_REPEAT_NORMAL)
+ {
+ left_x += (pos - x);
+ right_x += (pos - x);
+ }
+ else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
+ {
if ((int32_t)pos & 0x10000)
{
pixman_color_t *tmp_c;
@@ -165,32 +107,6 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
}
left_x += (pos - x);
right_x += (pos - x);
- break;
-
- default: /* REPEAT_NONE */
- for (n = 0; n < count; n++)
- if (pos < stops[n].x)
- break;
-
- if (n == 0)
- {
- left_x = INT32_MIN;
- right_x = stops[0].x;
- left_c = right_c = (pixman_color_t*) &transparent_black;
- }
- else if (n == count)
- {
- left_x = stops[n - 1].x;
- right_x = INT32_MAX;
- left_c = right_c = (pixman_color_t*) &transparent_black;
- }
- else
- {
- left_x = stops[n - 1].x;
- right_x = stops[n].x;
- left_c = &stops[n - 1].color;
- right_c = &stops[n].color;
- }
}
walker->left_x = left_x;
@@ -201,8 +117,8 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
if (walker->left_x == walker->right_x ||
- ( walker->left_ag == walker->right_ag &&
- walker->left_rb == walker->right_rb ) )
+ (walker->left_ag == walker->right_ag &&
+ walker->left_rb == walker->right_rb))
{
walker->stepper = 0;
}
@@ -215,20 +131,15 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
walker->need_reset = FALSE;
}
-#define PIXMAN_GRADIENT_WALKER_NEED_RESET(w, x) \
- ( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
-
-
-/* the following assumes that PIXMAN_GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
uint32_t
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
- pixman_fixed_32_32_t x)
+ pixman_fixed_48_16_t x)
{
int dist, idist;
uint32_t t1, t2, a, color;
- if (PIXMAN_GRADIENT_WALKER_NEED_RESET (walker, x))
- _pixman_gradient_walker_reset (walker, x);
+ if (walker->need_reset || x < walker->left_x || x >= walker->right_x)
+ gradient_walker_reset (walker, x);
dist = ((int)(x - walker->left_x) * walker->stepper) >> 16;
idist = 256 - dist;
diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c
index afe587f31..09d7cbc4e 100644
--- a/pixman/pixman/pixman-image.c
+++ b/pixman/pixman/pixman-image.c
@@ -31,6 +31,50 @@
#include "pixman-private.h"
+static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
+
+static void
+gradient_property_changed (pixman_image_t *image)
+{
+ gradient_t *gradient = &image->gradient;
+ int n = gradient->n_stops;
+ pixman_gradient_stop_t *stops = gradient->stops;
+ pixman_gradient_stop_t *begin = &(gradient->stops[-1]);
+ pixman_gradient_stop_t *end = &(gradient->stops[n]);
+
+ switch (gradient->common.repeat)
+ {
+ default:
+ case PIXMAN_REPEAT_NONE:
+ begin->x = INT32_MIN;
+ begin->color = transparent_black;
+ end->x = INT32_MAX;
+ end->color = transparent_black;
+ break;
+
+ case PIXMAN_REPEAT_NORMAL:
+ begin->x = stops[n - 1].x - pixman_fixed_1;
+ begin->color = stops[n - 1].color;
+ end->x = stops[0].x + pixman_fixed_1;
+ end->color = stops[0].color;
+ break;
+
+ case PIXMAN_REPEAT_REFLECT:
+ begin->x = - stops[0].x;
+ begin->color = stops[0].color;
+ end->x = pixman_int_to_fixed (2) - stops[n - 1].x;
+ end->color = stops[n - 1].color;
+ break;
+
+ case PIXMAN_REPEAT_PAD:
+ begin->x = INT32_MIN;
+ begin->color = stops[0].color;
+ end->x = INT32_MAX;
+ end->color = stops[n - 1].color;
+ break;
+ }
+}
+
pixman_bool_t
_pixman_init_gradient (gradient_t * gradient,
const pixman_gradient_stop_t *stops,
@@ -38,14 +82,27 @@ _pixman_init_gradient (gradient_t * gradient,
{
return_val_if_fail (n_stops > 0, FALSE);
- gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
+ /* We allocate two extra stops, one before the beginning of the stop list,
+ * and one after the end. These stops are initialized to whatever color
+ * would be used for positions outside the range of the stop list.
+ *
+ * This saves a bit of computation in the gradient walker.
+ *
+ * The pointer we store in the gradient_t struct still points to the
+ * first user-supplied struct, so when freeing, we will have to
+ * subtract one.
+ */
+ gradient->stops =
+ pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t));
if (!gradient->stops)
return FALSE;
+ gradient->stops += 1;
memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
-
gradient->n_stops = n_stops;
+ gradient->common.property_changed = gradient_property_changed;
+
return TRUE;
}
@@ -102,7 +159,17 @@ _pixman_image_fini (pixman_image_t *image)
image->type == CONICAL)
{
if (image->gradient.stops)
- free (image->gradient.stops);
+ {
+ /* See _pixman_init_gradient() for an explanation of the - 1 */
+ free (image->gradient.stops - 1);
+ }
+
+ /* This will trigger if someone adds a property_changed
+ * method to the linear/radial/conical gradient overwriting
+ * the general one.
+ */
+ assert (
+ image->common.property_changed == gradient_property_changed);
}
if (image->type == BITS && image->bits.free_me)
diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h
index cbd48f3d1..1443bfb3d 100644
--- a/pixman/pixman/pixman-private.h
+++ b/pixman/pixman/pixman-private.h
@@ -299,29 +299,29 @@ typedef struct
uint32_t left_rb;
uint32_t right_ag;
uint32_t right_rb;
- int32_t left_x;
- int32_t right_x;
- int32_t stepper;
+ pixman_fixed_t left_x;
+ pixman_fixed_t right_x;
+ pixman_fixed_t stepper;
pixman_gradient_stop_t *stops;
int num_stops;
- unsigned int spread;
+ pixman_repeat_t repeat;
- int need_reset;
+ pixman_bool_t need_reset;
} pixman_gradient_walker_t;
void
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
gradient_t * gradient,
- unsigned int spread);
+ pixman_repeat_t repeat);
void
_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
- pixman_fixed_32_32_t pos);
+ pixman_fixed_48_16_t pos);
uint32_t
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
- pixman_fixed_32_32_t x);
+ pixman_fixed_48_16_t x);
/*
* Edges
diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c
index ea393d224..1fe284dfc 100644
--- a/xorg-server/Xi/exevents.c
+++ b/xorg-server/Xi/exevents.c
@@ -653,7 +653,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dc
* Send an XI2 DeviceChangedEvent to all interested clients.
*/
void
-XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce)
+XISendDeviceChangedEvent(DeviceIntPtr device, DeviceChangedEvent *dce)
{
xXIDeviceChangedEvent *dcce;
int rc;
@@ -667,7 +667,7 @@ XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChanged
/* we don't actually swap if there's a NullClient, swapping is done
* later when event is delivered. */
- SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1);
+ SendEventToAllWindows(device, XI_DeviceChangedMask, (xEvent*)dcce, 1);
free(dcce);
}
@@ -701,7 +701,8 @@ ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
/* FIXME: the classes may have changed since we generated the event. */
DeepCopyDeviceClasses(slave, device, dce);
- XISendDeviceChangedEvent(slave, device, dce);
+ dce->deviceid = device->id;
+ XISendDeviceChangedEvent(device, dce);
}
/**
@@ -1106,6 +1107,8 @@ SetScrollValuator(DeviceIntPtr dev, int axnum, enum ScrollType type, double incr
{
AxisInfoPtr ax;
int *current_ax;
+ InternalEvent dce;
+ DeviceIntPtr master;
if (!dev || !dev->valuator || axnum >= dev->valuator->numAxes)
return FALSE;
@@ -1142,7 +1145,16 @@ SetScrollValuator(DeviceIntPtr dev, int axnum, enum ScrollType type, double incr
ax->scroll.type = type;
ax->scroll.increment = increment;
ax->scroll.flags = flags;
- /* FIXME: generate DeviceChanged Events */
+
+ master = GetMaster(dev, MASTER_ATTACHED);
+ CreateClassesChangedEvent(&dce, master, dev, DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE);
+ XISendDeviceChangedEvent(dev, &dce.changed_event);
+
+ /* if the current slave is us, update the master. If not, we'll update
+ * whenever the next slave switch happens anyway. CMDC sends the event
+ * for us */
+ if (master && master->lastSlave == dev)
+ ChangeMasterDeviceClasses(master, &dce.changed_event);
return TRUE;
}
diff --git a/xorg-server/Xi/xiquerydevice.c b/xorg-server/Xi/xiquerydevice.c
index 9961d1b6f..5f543f620 100644
--- a/xorg-server/Xi/xiquerydevice.c
+++ b/xorg-server/Xi/xiquerydevice.c
@@ -41,6 +41,7 @@
#include "xserver-properties.h"
#include "exevents.h"
#include "xace.h"
+#include "inpututils.h"
#include "xiquerydevice.h"
@@ -351,8 +352,7 @@ ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber,
info->min.frac = 0;
info->max.integral = v->axes[axisnumber].max_value;
info->max.frac = 0;
- info->value.integral = (int)v->axisVal[axisnumber];
- info->value.frac = (int)(v->axisVal[axisnumber] * (1 << 16) * (1 << 16));
+ info->value = double_to_fp3232(v->axisVal[axisnumber]);
info->resolution = v->axes[axisnumber].resolution;
info->number = axisnumber;
info->mode = valuator_get_mode(dev, axisnumber);
@@ -402,8 +402,7 @@ ListScrollInfo(DeviceIntPtr dev, xXIScrollInfo *info, int axisnumber)
ErrorF("[Xi] Unknown scroll type %d. This is a bug.\n", axis->scroll.type);
break;
}
- info->increment.integral = (int)axis->scroll.increment;
- info->increment.frac = (unsigned int)(axis->scroll.increment * (1UL << 16) * (1UL << 16));
+ info->increment = double_to_fp3232(axis->scroll.increment);
info->sourceid = v->sourceid;
info->flags = 0;
diff --git a/xorg-server/composite/compalloc.c b/xorg-server/composite/compalloc.c
index c4430af43..5b53e6931 100644
--- a/xorg-server/composite/compalloc.c
+++ b/xorg-server/composite/compalloc.c
@@ -196,11 +196,7 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
anyMarked = compMarkWindows (pWin, &pLayerWin);
- /* Make sure our borderClip is correct for ValidateTree */
RegionNull(&cw->borderClip);
- RegionCopy(&cw->borderClip, &pWin->borderClip);
- cw->borderClipX = pWin->drawable.x;
- cw->borderClipY = pWin->drawable.y;
cw->update = CompositeRedirectAutomatic;
cw->clients = 0;
cw->oldx = COMP_ORIGIN_INVALID;
@@ -658,6 +654,13 @@ compAllocPixmap (WindowPtr pWin)
DamageRegister (&pWin->drawable, cw->damage);
cw->damageRegistered = TRUE;
}
+
+ /* Make sure our borderClip is up to date */
+ RegionUninit(&cw->borderClip);
+ RegionCopy(&cw->borderClip, &pWin->borderClip);
+ cw->borderClipX = pWin->drawable.x;
+ cw->borderClipY = pWin->drawable.y;
+
return TRUE;
}
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index 4bfa82c24..63d59f92d 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -87,6 +87,12 @@ XORG_PROG_RAWCPP
# easier overrides at build time.
XSERVER_CFLAGS='$(CWARNFLAGS)'
+dnl Explicitly add -fno-strict-aliasing since this option should disappear
+dnl from util-macros CWARNFLAGS
+if test "x$GCC" = xyes ; then
+ XSERVER_CFLAGS="$XSERVER_CFLAGS -fno-strict-aliasing"
+fi
+
dnl Check for dtrace program (needed to build Xserver dtrace probes)
dnl Also checks for <sys/sdt.h>, since some Linux distros have an
dnl ISDN trace program named dtrace
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c
index 73c4d1460..c8ae230cd 100644
--- a/xorg-server/dix/devices.c
+++ b/xorg-server/dix/devices.c
@@ -2368,7 +2368,7 @@ RecalculateMasterButtons(DeviceIntPtr slave)
event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code;
}
- XISendDeviceChangedEvent(master, master, &event);
+ XISendDeviceChangedEvent(master, &event);
}
}
diff --git a/xorg-server/dix/eventconvert.c b/xorg-server/dix/eventconvert.c
index 5269e53bc..d7b161e02 100644
--- a/xorg-server/dix/eventconvert.c
+++ b/xorg-server/dix/eventconvert.c
@@ -43,10 +43,13 @@
#include "inputstr.h"
#include "misc.h"
#include "eventstr.h"
+#include "exevents.h"
#include "exglobals.h"
#include "eventconvert.h"
+#include "inpututils.h"
#include "xiquerydevice.h"
#include "xkbsrv.h"
+#include "inpututils.h"
static int countValuators(DeviceEvent *ev, int *first);
@@ -482,6 +485,40 @@ appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumbe
}
static int
+appendScrollInfo(DeviceChangedEvent *dce, xXIScrollInfo *info, int axisnumber)
+{
+ if (dce->valuators[axisnumber].scroll.type == SCROLL_TYPE_NONE)
+ return 0;
+
+ info->type = XIScrollClass;
+ info->length = sizeof(xXIScrollInfo)/4;
+ info->number = axisnumber;
+ switch(dce->valuators[axisnumber].scroll.type)
+ {
+ case SCROLL_TYPE_VERTICAL:
+ info->scroll_type = XIScrollTypeVertical;
+ break;
+ case SCROLL_TYPE_HORIZONTAL:
+ info->scroll_type = XIScrollTypeHorizontal;
+ break;
+ default:
+ ErrorF("[Xi] Unknown scroll type %d. This is a bug.\n", dce->valuators[axisnumber].scroll.type);
+ break;
+ }
+ info->increment = double_to_fp3232(dce->valuators[axisnumber].scroll.increment);
+ info->sourceid = dce->sourceid;
+
+ info->flags = 0;
+
+ if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_DONT_EMULATE)
+ info->flags |= XIScrollFlagNoEmulation;
+ if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_PREFERRED)
+ info->flags |= XIScrollFlagPreferred;
+
+ return info->length * 4;
+}
+
+static int
eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
{
xXIDeviceChangedEvent *dcce;
@@ -496,8 +533,16 @@ eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
}
if (dce->num_valuators)
+ {
+ int i;
+
len += sizeof(xXIValuatorInfo) * dce->num_valuators;
+ for (i = 0; i < dce->num_valuators; i++)
+ if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE)
+ len += sizeof(xXIScrollInfo);
+ }
+
nkeys = (dce->keys.max_keycode > 0) ?
dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
if (nkeys > 0)
@@ -543,6 +588,15 @@ eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
dcce->num_classes += dce->num_valuators;
for (i = 0; i < dce->num_valuators; i++)
ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i);
+
+ for (i = 0; i < dce->num_valuators; i++)
+ {
+ if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE)
+ {
+ dcce->num_classes++;
+ ptr += appendScrollInfo(dce, (xXIScrollInfo*)ptr, i);
+ }
+ }
}
*xi = (xEvent*)dcce;
@@ -633,9 +687,7 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
if (BitIsOn(ev->valuators.mask, i))
{
SetBit(ptr, i);
- axisval->integral = trunc(ev->valuators.data[i]);
- axisval->frac = (ev->valuators.data[i] - axisval->integral) *
- (1 << 16) * (1 << 16);
+ *axisval = double_to_fp3232(ev->valuators.data[i]);
axisval++;
}
}
@@ -679,13 +731,8 @@ eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
if (BitIsOn(ev->valuators.mask, i))
{
SetBit(ptr, i);
- axisval->integral = trunc(ev->valuators.data[i]);
- axisval->frac = (ev->valuators.data[i] - axisval->integral) *
- (1 << 16) * (1 << 16);
- axisval_raw->integral = trunc(ev->valuators.data_raw[i]);
- axisval_raw->frac =
- (ev->valuators.data_raw[i] - axisval_raw->integral) *
- (1 << 16) * (1 << 16);
+ *axisval = double_to_fp3232(ev->valuators.data[i]);
+ *axisval_raw = double_to_fp3232(ev->valuators.data_raw[i]);
axisval++;
axisval_raw++;
}
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c
index f000620e3..226d5cd43 100644
--- a/xorg-server/dix/getevents.c
+++ b/xorg-server/dix/getevents.c
@@ -224,7 +224,7 @@ void
CreateClassesChangedEvent(InternalEvent* event,
DeviceIntPtr master,
DeviceIntPtr slave,
- int type)
+ int flags)
{
int i;
DeviceChangedEvent *dce;
@@ -233,13 +233,12 @@ CreateClassesChangedEvent(InternalEvent* event,
dce = &event->changed_event;
memset(dce, 0, sizeof(DeviceChangedEvent));
dce->deviceid = slave->id;
- dce->masterid = master->id;
+ dce->masterid = master ? master->id : 0;
dce->header = ET_Internal;
dce->length = sizeof(DeviceChangedEvent);
dce->type = ET_DeviceChanged;
dce->time = ms;
- dce->flags = type;
- dce->flags |= DEVCHANGE_SLAVE_SWITCH;
+ dce->flags = flags;
dce->sourceid = slave->id;
if (slave->button)
@@ -258,6 +257,7 @@ CreateClassesChangedEvent(InternalEvent* event,
dce->valuators[i].resolution = slave->valuator->axes[i].resolution;
dce->valuators[i].mode = slave->valuator->axes[i].mode;
dce->valuators[i].name = slave->valuator->axes[i].label;
+ dce->valuators[i].scroll = slave->valuator->axes[i].scroll;
}
}
if (slave->key)
@@ -688,7 +688,7 @@ UpdateFromMaster(InternalEvent* events, DeviceIntPtr dev, int type, int *num_eve
if (master && master->last.slave != dev)
{
- CreateClassesChangedEvent(events, master, dev, type);
+ CreateClassesChangedEvent(events, master, dev, type | DEVCHANGE_SLAVE_SWITCH);
if (IsPointerDevice(master))
{
updateSlaveDeviceCoords(master, dev);
@@ -1249,6 +1249,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
*
* @param events The pointer to the event list to fill the events
* @param dev The device to generate the events for
+ * @param type The real type of the event
* @param axis The axis number to generate events for
* @param mask State before this event in absolute coords
* @param[in,out] last Last scroll state posted in absolute coords (modified
@@ -1260,6 +1261,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
static int
emulate_scroll_button_events(InternalEvent *events,
DeviceIntPtr dev,
+ int type,
int axis,
const ValuatorMask *mask,
ValuatorMask *last,
@@ -1272,6 +1274,7 @@ emulate_scroll_button_events(InternalEvent *events,
int num_events = 0;
double total;
int b;
+ int flags = 0;
if (dev->valuator->axes[axis].scroll.type == SCROLL_TYPE_NONE)
return 0;
@@ -1282,6 +1285,9 @@ emulate_scroll_button_events(InternalEvent *events,
ax = &dev->valuator->axes[axis];
incr = ax->scroll.increment;
+ if (type != ButtonPress && type != ButtonRelease)
+ flags |= POINTER_EMULATED;
+
if (!valuator_mask_isset(last, axis))
valuator_mask_set_double(last, axis, 0);
@@ -1309,14 +1315,20 @@ emulate_scroll_button_events(InternalEvent *events,
*/
if (num_events + 4 < max_events)
{
- nev_tmp = fill_pointer_events(events, dev, ButtonPress, b, ms,
- POINTER_EMULATED, NULL);
- events += nev_tmp;
- num_events += nev_tmp;
- nev_tmp = fill_pointer_events(events, dev, ButtonRelease, b, ms,
- POINTER_EMULATED, NULL);
- events += nev_tmp;
- num_events += nev_tmp;
+ if (type != ButtonRelease)
+ {
+ nev_tmp = fill_pointer_events(events, dev, ButtonPress, b, ms,
+ flags, NULL);
+ events += nev_tmp;
+ num_events += nev_tmp;
+ }
+ if (type != ButtonPress)
+ {
+ nev_tmp = fill_pointer_events(events, dev, ButtonRelease, b, ms,
+ flags, NULL);
+ events += nev_tmp;
+ num_events += nev_tmp;
+ }
}
}
@@ -1361,6 +1373,7 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
ValuatorMask mask;
ValuatorMask scroll;
int i;
+ int realtype = type;
/* refuse events from disabled devices */
if (!pDev->enabled)
@@ -1413,6 +1426,7 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
valuator_mask_set_double(&mask, axis, val);
type = MotionNotify;
buttons = 0;
+ flags |= POINTER_EMULATED;
}
}
@@ -1432,7 +1446,7 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
valuator_mask_set_double(&scroll, i, pDev->last.valuators[i]);
- nev_tmp = emulate_scroll_button_events(events, pDev, i, &scroll,
+ nev_tmp = emulate_scroll_button_events(events, pDev, realtype, i, &scroll,
pDev->last.scroll, ms,
GetMaximumEventsNum() - num_events);
events += nev_tmp;
diff --git a/xorg-server/dix/inpututils.c b/xorg-server/dix/inpututils.c
index 5c76361b3..5797f9256 100644
--- a/xorg-server/dix/inpututils.c
+++ b/xorg-server/dix/inpututils.c
@@ -38,6 +38,7 @@
#include "inpututils.h"
#include "eventstr.h"
#include "scrnintstr.h"
+#include "optionstr.h"
/* Check if a button map change is okay with the device.
* Returns -1 for BadValue, as it collides with MappingBusy. */
@@ -539,6 +540,42 @@ valuator_mask_get(const ValuatorMask *mask, int valuator)
}
/**
+ * Set value to the requested valuator. If the mask bit is set for this
+ * valuator, value contains the requested valuator value and TRUE is
+ * returned.
+ * If the mask bit is not set for this valuator, value is unchanged and
+ * FALSE is returned.
+ */
+Bool
+valuator_mask_fetch_double(const ValuatorMask *mask, int valuator, double *value)
+{
+ if (valuator_mask_isset(mask, valuator))
+ {
+ *value = valuator_mask_get_double(mask, valuator);
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+/**
+ * Set value to the requested valuator. If the mask bit is set for this
+ * valuator, value contains the requested valuator value and TRUE is
+ * returned.
+ * If the mask bit is not set for this valuator, value is unchanged and
+ * FALSE is returned.
+ */
+Bool
+valuator_mask_fetch(const ValuatorMask *mask, int valuator, int *value)
+{
+ if (valuator_mask_isset(mask, valuator))
+ {
+ *value = valuator_mask_get(mask, valuator);
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+/**
* Remove the valuator from the mask.
*/
void
@@ -634,8 +671,9 @@ point_on_screen(ScreenPtr pScreen, int x, int y)
static void
input_option_free(InputOption *o)
{
- free(o->key);
- free(o->value);
+ free(o->opt_name);
+ free(o->opt_val);
+ free(o->opt_comment);
free(o);
}
@@ -665,7 +703,7 @@ input_option_new(InputOption* list, const char *key, const char *value)
if (list)
{
- nt_list_for_each_entry(opt, list, next)
+ nt_list_for_each_entry(opt, list, list.next)
{
if (strcmp(input_option_get_key(opt), key) == 0)
{
@@ -679,13 +717,13 @@ input_option_new(InputOption* list, const char *key, const char *value)
if (!opt)
return NULL;
- nt_list_init(opt, next);
+ nt_list_init(opt, list.next);
input_option_set_key(opt, key);
input_option_set_value(opt, value);
if (list)
{
- nt_list_append(opt, list, InputOption, next);
+ nt_list_append(opt, list, InputOption, list.next);
return list;
} else
return opt;
@@ -696,9 +734,9 @@ input_option_free_element(InputOption *list, const char *key)
{
InputOption *element;
- nt_list_for_each_entry(element, list, next) {
+ nt_list_for_each_entry(element, list, list.next) {
if (strcmp(input_option_get_key(element), key) == 0) {
- nt_list_del(element, list, InputOption, next);
+ nt_list_del(element, list, InputOption, list.next);
input_option_free(element);
break;
}
@@ -714,8 +752,8 @@ input_option_free_list(InputOption **opt)
{
InputOption *element, *tmp;
- nt_list_for_each_entry_safe(element, tmp, *opt, next) {
- nt_list_del(element, *opt, InputOption, next);
+ nt_list_for_each_entry_safe(element, tmp, *opt, list.next) {
+ nt_list_del(element, *opt, InputOption, list.next);
input_option_free(element);
}
*opt = NULL;
@@ -732,7 +770,7 @@ input_option_find(InputOption *list, const char *key)
{
InputOption *element;
- nt_list_for_each_entry(element, list, next) {
+ nt_list_for_each_entry(element, list, list.next) {
if (strcmp(input_option_get_key(element), key) == 0)
return element;
}
@@ -743,29 +781,29 @@ input_option_find(InputOption *list, const char *key)
const char*
input_option_get_key(const InputOption *opt)
{
- return opt->key;
+ return opt->opt_name;
}
const char*
input_option_get_value(const InputOption *opt)
{
- return opt->value;
+ return opt->opt_val;
}
void
input_option_set_key(InputOption *opt, const char *key)
{
- free(opt->key);
+ free(opt->opt_name);
if (key)
- opt->key = strdup(key);
+ opt->opt_name = strdup(key);
}
void
input_option_set_value(InputOption *opt, const char *value)
{
- free(opt->value);
+ free(opt->opt_val);
if (value)
- opt->value = strdup(value);
+ opt->opt_val = strdup(value);
}
diff --git a/xorg-server/dix/ptrveloc.c b/xorg-server/dix/ptrveloc.c
index fc5cf49b8..1ba531c96 100644
--- a/xorg-server/dix/ptrveloc.c
+++ b/xorg-server/dix/ptrveloc.c
@@ -658,13 +658,13 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t){
DebugAccelF("(dix prtacc) query: last tracker in effect\n");
used_offset = vel->num_tracker-1;
}
-#ifdef PTRACCEL_DEBUGGING
if(used_offset >= 0){
+#ifdef PTRACCEL_DEBUGGING
MotionTracker *tracker = TRACKER(vel, used_offset);
DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
used_offset, tracker->dx, tracker->dy, cur_t - tracker->time);
- }
#endif
+ }
return result;
}
diff --git a/xorg-server/hw/kdrive/src/kinput.c b/xorg-server/hw/kdrive/src/kinput.c
index 3d87996be..27e33043f 100644
--- a/xorg-server/hw/kdrive/src/kinput.c
+++ b/xorg-server/hw/kdrive/src/kinput.c
@@ -49,6 +49,7 @@
#include "eventstr.h"
#include "xserver-properties.h"
#include "inpututils.h"
+#include "optionstr.h"
#define AtomFromName(x) MakeAtom(x, strlen(x), 1)
@@ -364,7 +365,7 @@ KdEnableInput (void)
}
static KdKeyboardDriver *
-KdFindKeyboardDriver (char *name)
+KdFindKeyboardDriver (const char *name)
{
KdKeyboardDriver *ret;
@@ -381,7 +382,7 @@ KdFindKeyboardDriver (char *name)
}
static KdPointerDriver *
-KdFindPointerDriver (char *name)
+KdFindPointerDriver (const char *name)
{
KdPointerDriver *ret;
@@ -1063,33 +1064,39 @@ KdRemovePointer (KdPointerInfo *pi)
static Bool
KdGetOptions (InputOption **options, char *string)
{
- InputOption *newopt = NULL, **tmpo = NULL;
+ InputOption *newopt = NULL;
+ char *key = NULL,
+ *value = NULL;
int tam_key = 0;
- newopt = calloc(1, sizeof (InputOption));
- if (!newopt)
- return FALSE;
-
- for (tmpo = options; *tmpo; tmpo = &(*tmpo)->next)
- ; /* Hello, I'm here */
- *tmpo = newopt;
-
if (strchr(string, '='))
{
tam_key = (strchr(string, '=') - string);
- newopt->key = (char *)malloc(tam_key);
- strncpy(newopt->key, string, tam_key);
- newopt->key[tam_key] = '\0';
- newopt->value = strdup(strchr(string, '=') + 1);
+ key = malloc(tam_key + 1);
+ if (!key)
+ goto out;
+
+ strncpy(key, string, tam_key);
+ key[tam_key] = '\0';
+ value = strdup(strchr(string, '=') + 1);
+ if (!value)
+ goto out;
}
else
{
- newopt->key = strdup(string);
- newopt->value = NULL;
+ key = strdup(string);
+ value = NULL;
}
- newopt->next = NULL;
- return TRUE;
+ newopt = input_option_new(*options, key, value);
+ if (newopt)
+ *options = newopt;
+
+out:
+ free(key);
+ free(value);
+
+ return (newopt != NULL);
}
static void
@@ -1097,23 +1104,26 @@ KdParseKbdOptions (KdKeyboardInfo *ki)
{
InputOption *option = NULL;
- for (option = ki->options; option; option = option->next)
+ nt_list_for_each_entry(option, ki->options, list.next)
{
- if (strcasecmp(option->key, "XkbRules") == 0)
- ki->xkbRules = option->value;
- else if (strcasecmp(option->key, "XkbModel") == 0)
- ki->xkbModel = option->value;
- else if (strcasecmp(option->key, "XkbLayout") == 0)
- ki->xkbLayout = option->value;
- else if (strcasecmp(option->key, "XkbVariant") == 0)
- ki->xkbVariant = option->value;
- else if (strcasecmp(option->key, "XkbOptions") == 0)
- ki->xkbOptions = option->value;
- else if (!strcasecmp (option->key, "device"))
- ki->path = strdup(option->value);
+ const char *key = input_option_get_key(option);
+ const char *value = input_option_get_value(option);
+
+ if (strcasecmp(key, "XkbRules") == 0)
+ ki->xkbRules = strdup(value);
+ else if (strcasecmp(key, "XkbModel") == 0)
+ ki->xkbModel = strdup(value);
+ else if (strcasecmp(key, "XkbLayout") == 0)
+ ki->xkbLayout = strdup(value);
+ else if (strcasecmp(key, "XkbVariant") == 0)
+ ki->xkbVariant = strdup(value);
+ else if (strcasecmp(key, "XkbOptions") == 0)
+ ki->xkbOptions = strdup(value);
+ else if (!strcasecmp (key, "device"))
+ ki->path = strdup(value);
else
ErrorF("Kbd option key (%s) of value (%s) not assigned!\n",
- option->key, option->value);
+ key, value);
}
}
@@ -1194,23 +1204,26 @@ KdParsePointerOptions (KdPointerInfo *pi)
{
InputOption *option = NULL;
- for (option = pi->options; option; option = option->next)
+ nt_list_for_each_entry(option, pi->options, list.next)
{
- if (!strcmp (option->key, "emulatemiddle"))
+ const char *key = input_option_get_key(option);
+ const char *value = input_option_get_value(option);
+
+ if (!strcmp (key, "emulatemiddle"))
pi->emulateMiddleButton = TRUE;
- else if (!strcmp (option->key, "noemulatemiddle"))
+ else if (!strcmp (key, "noemulatemiddle"))
pi->emulateMiddleButton = FALSE;
- else if (!strcmp (option->key, "transformcoord"))
+ else if (!strcmp (key, "transformcoord"))
pi->transformCoordinates = TRUE;
- else if (!strcmp (option->key, "rawcoord"))
+ else if (!strcmp (key, "rawcoord"))
pi->transformCoordinates = FALSE;
- else if (!strcasecmp (option->key, "device"))
- pi->path = strdup(option->value);
- else if (!strcasecmp (option->key, "protocol"))
- pi->protocol = strdup(option->value);
+ else if (!strcasecmp (key, "device"))
+ pi->path = strdup(value);
+ else if (!strcasecmp (key, "protocol"))
+ pi->protocol = strdup(value);
else
ErrorF("Pointer option key (%s) of value (%s) not assigned!\n",
- option->key, option->value);
+ key, value);
}
}
@@ -2241,14 +2254,17 @@ NewInputDeviceRequest(InputOption *options, InputAttributes *attrs,
KdPointerInfo *pi = NULL;
KdKeyboardInfo *ki = NULL;
- for (option = options; option; option = option->next) {
- if (strcmp(option->key, "type") == 0) {
- if (strcmp(option->value, "pointer") == 0) {
+ nt_list_for_each_entry(option, options, list.next) {
+ const char *key = input_option_get_key(option);
+ const char *value = input_option_get_value(option);
+
+ if (strcmp(key, "type") == 0) {
+ if (strcmp(value, "pointer") == 0) {
pi = KdNewPointer();
if (!pi)
return BadAlloc;
}
- else if (strcmp(option->value, "keyboard") == 0) {
+ else if (strcmp(value, "keyboard") == 0) {
ki = KdNewKeyboard();
if (!ki)
return BadAlloc;
@@ -2259,16 +2275,16 @@ NewInputDeviceRequest(InputOption *options, InputAttributes *attrs,
}
}
#ifdef CONFIG_HAL
- else if (strcmp(option->key, "_source") == 0 &&
- strcmp(option->value, "server/hal") == 0)
+ else if (strcmp(key, "_source") == 0 &&
+ strcmp(value, "server/hal") == 0)
{
ErrorF("Ignoring device from HAL.\n");
return BadValue;
}
#endif
#ifdef CONFIG_UDEV
- else if (strcmp(option->key, "_source") == 0 &&
- strcmp(option->value, "server/udev") == 0)
+ else if (strcmp(key, "_source") == 0 &&
+ strcmp(value, "server/udev") == 0)
{
ErrorF("Ignoring device from udev.\n");
return BadValue;
@@ -2283,16 +2299,19 @@ NewInputDeviceRequest(InputOption *options, InputAttributes *attrs,
/* FIXME: change this code below to use KdParseKbdOptions and
* KdParsePointerOptions */
- for (option = options; option; option = option->next) {
- if (strcmp(option->key, "device") == 0) {
- if (pi && option->value)
- pi->path = strdup(option->value);
- else if (ki && option->value)
- ki->path = strdup(option->value);
+ nt_list_for_each_entry(option, options, list.next) {
+ const char *key = input_option_get_key(option);
+ const char *value = input_option_get_value(option);
+
+ if (strcmp(key, "device") == 0) {
+ if (pi && value)
+ pi->path = strdup(value);
+ else if (ki && value)
+ ki->path = strdup(value);
}
- else if (strcmp(option->key, "driver") == 0) {
+ else if (strcmp(key, "driver") == 0) {
if (pi) {
- pi->driver = KdFindPointerDriver(option->value);
+ pi->driver = KdFindPointerDriver(value);
if (!pi->driver) {
ErrorF("couldn't find driver!\n");
KdFreePointer(pi);
@@ -2301,7 +2320,7 @@ NewInputDeviceRequest(InputOption *options, InputAttributes *attrs,
pi->options = options;
}
else if (ki) {
- ki->driver = KdFindKeyboardDriver(option->value);
+ ki->driver = KdFindKeyboardDriver(value);
if (!ki->driver) {
ErrorF("couldn't find driver!\n");
KdFreeKeyboard(ki);
diff --git a/xorg-server/hw/vfb/InitOutput.c b/xorg-server/hw/vfb/InitOutput.c
index 0e701e518..121854781 100644
--- a/xorg-server/hw/vfb/InitOutput.c
+++ b/xorg-server/hw/vfb/InitOutput.c
@@ -863,6 +863,8 @@ vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
(1 << DirectColor)),
10, TrueColor, 0x3ff00000, 0x000ffc00, 0x000003ff);
break;
+ default:
+ return FALSE;
}
miSetPixmapDepths ();
diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c
index 5c46152b2..cb4be4210 100644
--- a/xorg-server/hw/xfree86/common/xf86Config.c
+++ b/xorg-server/hw/xfree86/common/xf86Config.c
@@ -1194,8 +1194,12 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
if (Pointer)
foundPointer = configInput(Pointer, confInput, from);
if (foundPointer) {
- Pointer->options = xf86addNewOption(Pointer->options,
- xnfstrdup("CorePointer"), "on");
+ Pointer->options = xf86AddNewOption(Pointer->options,
+ "CorePointer", "on");
+ Pointer->options = xf86AddNewOption(Pointer->options,
+ "driver", confInput->inp_driver);
+ Pointer->options = xf86AddNewOption(Pointer->options,
+ "identifier", confInput->inp_identifier);
servlayoutp->inputs = addDevice(servlayoutp->inputs, Pointer);
}
}
@@ -1284,8 +1288,12 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
if (Keyboard)
foundKeyboard = configInput(Keyboard, confInput, from);
if (foundKeyboard) {
- Keyboard->options = xf86addNewOption(Keyboard->options,
- xnfstrdup("CoreKeyboard"), "on");
+ Keyboard->options = xf86AddNewOption(Keyboard->options,
+ "CoreKeyboard", "on");
+ Keyboard->options = xf86AddNewOption(Keyboard->options,
+ "driver", confInput->inp_driver);
+ Keyboard->options = xf86AddNewOption(Keyboard->options,
+ "identifier", confInput->inp_identifier);
servlayoutp->inputs = addDevice(servlayoutp->inputs, Keyboard);
}
}
diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c
index c4a4db9be..41ffabde3 100644
--- a/xorg-server/hw/xfree86/common/xf86Events.c
+++ b/xorg-server/hw/xfree86/common/xf86Events.c
@@ -601,16 +601,15 @@ xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data)
InputHandlerProc
xf86SetConsoleHandler(InputHandlerProc proc, pointer data)
{
- static InputHandlerProc handler = NULL;
- InputHandlerProc old_handler = handler;
+ static IHPtr handler = NULL;
+ IHPtr old_handler = handler;
if (old_handler)
xf86RemoveGeneralHandler(old_handler);
- xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
- handler = proc;
+ handler = xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
- return old_handler;
+ return (old_handler) ? old_handler->ihproc : NULL;
}
static void
diff --git a/xorg-server/hw/xfree86/common/xf86Helper.c b/xorg-server/hw/xfree86/common/xf86Helper.c
index cf577522a..d99522cf6 100644
--- a/xorg-server/hw/xfree86/common/xf86Helper.c
+++ b/xorg-server/hw/xfree86/common/xf86Helper.c
@@ -1553,13 +1553,7 @@ xf86LoadOneModule(char *name, pointer opt)
void
xf86UnloadSubModule(pointer mod)
{
- /*
- * This is disabled for now. The loader isn't smart enough yet to undo
- * relocations.
- */
-#if 0
UnloadSubModule(mod);
-#endif
}
Bool
diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c
index 74e0bc220..a0fdf29ad 100644
--- a/xorg-server/hw/xfree86/common/xf86Init.c
+++ b/xorg-server/hw/xfree86/common/xf86Init.c
@@ -811,21 +811,6 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
NULL);
}
-static InputInfoPtr
-duplicateDevice(InputInfoPtr pInfo)
-{
- InputInfoPtr dup = calloc(1, sizeof(InputInfoRec));
- if (dup) {
- dup->name = strdup(pInfo->name);
- dup->driver = strdup(pInfo->driver);
- dup->options = xf86OptionListDuplicate(pInfo->options);
- /* type_name is a const string */
- dup->type_name = pInfo->type_name;
- dup->fd = -1;
- }
- return dup;
-}
-
/**
* Initialize all supported input devices present and referenced in the
* xorg.conf.
@@ -842,20 +827,8 @@ InitInput(int argc, char **argv)
/* Initialize all configured input devices */
for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
- InputInfoPtr dup;
- /* Replace obsolete keyboard driver with kbd */
- if (!xf86NameCmp((*pInfo)->driver, "keyboard")) {
- strcpy((*pInfo)->driver, "kbd");
- }
-
- /* Data passed into xf86NewInputDevice will be freed on shutdown.
- * Duplicate from xf86ConfigLayout.inputs, otherwise we don't have any
- * xorg.conf input devices in the second generation
- */
- dup = duplicateDevice(*pInfo);
-
/* If one fails, the others will too */
- if (xf86NewInputDevice(dup, &dev, TRUE) == BadAlloc)
+ if (NewInputDeviceRequest((*pInfo)->options, NULL, &dev) == BadAlloc)
break;
}
diff --git a/xorg-server/hw/xfree86/common/xf86Option.c b/xorg-server/hw/xfree86/common/xf86Option.c
index 73b6573f1..9c528782f 100644
--- a/xorg-server/hw/xfree86/common/xf86Option.c
+++ b/xorg-server/hw/xfree86/common/xf86Option.c
@@ -44,6 +44,7 @@
#include "xf86Xinput.h"
#include "xf86Optrec.h"
#include "xf86Parser.h"
+#include "optionstr.h"
static Bool ParseOptionValue(int scrnIndex, XF86OptionPtr options, OptionInfoPtr p,
Bool markUsed);
@@ -298,7 +299,7 @@ xf86CheckPercentOption(XF86OptionPtr optlist, const char *name, double deflt)
return LookupPercentOption(optlist, name, deflt, FALSE);
}
/*
- * addNewOption() has the required property of replacing the option value
+ * xf86AddNewOption() has the required property of replacing the option value
* if the option is already present.
*/
XF86OptionPtr
diff --git a/xorg-server/hw/xfree86/common/xf86Optionstr.h b/xorg-server/hw/xfree86/common/xf86Optionstr.h
index 8cc82d34c..fc9385617 100644
--- a/xorg-server/hw/xfree86/common/xf86Optionstr.h
+++ b/xorg-server/hw/xfree86/common/xf86Optionstr.h
@@ -24,16 +24,7 @@
#ifndef XF86OPTIONSTR_H
#define XF86OPTIONSTR_H
-
-/*
- * all records that need to be linked lists should contain a GenericList as
- * their first field.
- */
-typedef struct generic_list_rec
-{
- void *next;
-}
-GenericListRec, *GenericListPtr, *glp;
+#include "list.h"
/*
* All options are stored using this data type.
@@ -48,6 +39,6 @@ typedef struct _XF86OptionRec
}
XF86OptionRec;
-typedef struct _XF86OptionRec *XF86OptionPtr;
+typedef struct _InputOption *XF86OptionPtr;
#endif
diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c
index ea1f92761..425b35957 100644
--- a/xorg-server/hw/xfree86/common/xf86Xinput.c
+++ b/xorg-server/hw/xfree86/common/xf86Xinput.c
@@ -68,6 +68,7 @@
#include "exglobals.h"
#include "eventstr.h"
#include "inpututils.h"
+#include "optionstr.h"
#include <string.h> /* InputClassMatches */
#ifdef HAVE_FNMATCH_H
@@ -908,7 +909,7 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
if (!pInfo)
return BadAlloc;
- nt_list_for_each_entry(option, options, next) {
+ nt_list_for_each_entry(option, options, list.next) {
if (strcasecmp(input_option_get_key(option), "driver") == 0) {
if (pInfo->driver) {
rval = BadRequest;
@@ -946,7 +947,7 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
}
}
- nt_list_for_each_entry(option, options, next) {
+ nt_list_for_each_entry(option, options, list.next) {
/* Copy option key/value strings from the provided list */
pInfo->options = xf86AddNewOption(pInfo->options,
input_option_get_key(option),
diff --git a/xorg-server/hw/xfree86/doc/ddxDesign.xml b/xorg-server/hw/xfree86/doc/ddxDesign.xml
index a4baad557..0d5e952a2 100644
--- a/xorg-server/hw/xfree86/doc/ddxDesign.xml
+++ b/xorg-server/hw/xfree86/doc/ddxDesign.xml
@@ -189,7 +189,7 @@ following changes:
<varlistentry><term><emphasis>Keyboard</emphasis></term>
<listitem><literallayout>
&k.identifier; "Implicit Core Keyboard"
- &k.driver; "keyboard"
+ &k.driver; "kbd"
</literallayout></listitem></varlistentry>
<varlistentry><term><emphasis>Pointer</emphasis></term>
<listitem><literallayout>
@@ -206,7 +206,7 @@ following changes:
is no &k.serverlayout; section, if the <option>-screen</option> command
line options is used, or if the &k.serverlayout; section doesn't
reference any &k.inputdevice; sections. In this case, the first
- sections with drivers "keyboard" and "mouse" are used as the core
+ sections with drivers "kbd" and "mouse" are used as the core
keyboard and pointer respectively.
</para>
</sect2>
diff --git a/xorg-server/hw/xfree86/loader/loadmod.c b/xorg-server/hw/xfree86/loader/loadmod.c
index 9f820993a..a21f43d63 100644
--- a/xorg-server/hw/xfree86/loader/loadmod.c
+++ b/xorg-server/hw/xfree86/loader/loadmod.c
@@ -94,6 +94,8 @@ const ModuleVersions LoaderVersionInfo = {
ABI_FONT_VERSION
};
+static int ModuleDuplicated[] = {};
+
static void
FreeStringList(char **paths)
{
@@ -785,7 +787,6 @@ ModuleDescPtr
DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
{
ModuleDescPtr ret;
- int errmaj, errmin;
if (!mod)
return NULL;
@@ -794,14 +795,11 @@ DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
if (ret == NULL)
return NULL;
- if (!(ret->handle = LoaderOpen(mod->path, &errmaj, &errmin))) {
- free(ret);
- return NULL;
- }
+ ret->handle = mod->handle;
ret->SetupProc = mod->SetupProc;
ret->TearDownProc = mod->TearDownProc;
- ret->TearDownData = NULL;
+ ret->TearDownData = ModuleDuplicated;
ret->child = DuplicateModule(mod->child, ret);
ret->sib = DuplicateModule(mod->sib, parent);
ret->parent = parent;
@@ -1072,11 +1070,16 @@ UnloadModuleOrDriver(ModuleDescPtr mod)
if (mod == NULL || mod->name == NULL)
return;
- xf86MsgVerb(X_INFO, 3, "UnloadModule: \"%s\"\n", mod->name);
+ if (mod->parent)
+ xf86MsgVerb(X_INFO, 3, "UnloadSubModule: \"%s\"\n", mod->name);
+ else
+ xf86MsgVerb(X_INFO, 3, "UnloadModule: \"%s\"\n", mod->name);
- if ((mod->TearDownProc) && (mod->TearDownData))
- mod->TearDownProc(mod->TearDownData);
- LoaderUnload(mod->name, mod->handle);
+ if (mod->TearDownData != ModuleDuplicated) {
+ if ((mod->TearDownProc) && (mod->TearDownData))
+ mod->TearDownProc(mod->TearDownData);
+ LoaderUnload(mod->name, mod->handle);
+ }
if (mod->child)
UnloadModuleOrDriver(mod->child);
@@ -1092,23 +1095,8 @@ UnloadSubModule(pointer _mod)
{
ModuleDescPtr mod = (ModuleDescPtr)_mod;
- if (mod == NULL || mod->name == NULL)
- return;
-
- xf86MsgVerb(X_INFO, 3, "UnloadSubModule: \"%s\"\n", mod->name);
-
- if ((mod->TearDownProc) && (mod->TearDownData))
- mod->TearDownProc(mod->TearDownData);
- LoaderUnload(mod->name, mod->handle);
-
RemoveChild(mod);
-
- if (mod->child)
- UnloadModuleOrDriver(mod->child);
-
- free(mod->path);
- free(mod->name);
- free(mod);
+ UnloadModuleOrDriver(mod);
}
static void
@@ -1135,6 +1123,7 @@ RemoveChild(ModuleDescPtr child)
}
if (mdp == child)
prevsib->sib = child->sib;
+ child->sib = NULL;
return;
}
diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man
index 7f98851b6..996798f1c 100644
--- a/xorg-server/hw/xfree86/man/xorg.conf.man
+++ b/xorg-server/hw/xfree86/man/xorg.conf.man
@@ -379,7 +379,9 @@ is a number used to order the fontfile FPEs. Examples:
.I misc:unscaled:pri=10 \-> /usr/share/X11/fonts/misc
.fi
.PP
-.RE .RE .RE
+.RE
+.RE
+.RE
.PP
.RS 7
Font server identifiers:
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c
index cbe0b5cf6..aac33d32f 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.c
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c
@@ -1915,19 +1915,25 @@ xf86SetScrnInfoModes (ScrnInfoPtr scrn)
break;
}
- if (scrn->modes != NULL) {
- /* For some reason, scrn->modes is circular, unlike the other mode
- * lists. How great is that?
- */
- for (last = scrn->modes; last && last->next; last = last->next)
- ;
- last->next = scrn->modes;
- scrn->modes->prev = last;
- if (mode) {
- while (scrn->modes != mode)
- scrn->modes = scrn->modes->next;
- }
+ if (!scrn->modes) {
+ scrn->modes = xf86ModesAdd(scrn->modes,
+ xf86CVTMode(scrn->display->virtualX,
+ scrn->display->virtualY,
+ 60, 0, 0));
+ }
+
+ /* For some reason, scrn->modes is circular, unlike the other mode
+ * lists. How great is that?
+ */
+ for (last = scrn->modes; last && last->next; last = last->next)
+ ;
+ last->next = scrn->modes;
+ scrn->modes->prev = last;
+ if (mode) {
+ while (scrn->modes != mode)
+ scrn->modes = scrn->modes->next;
}
+
scrn->currentMode = scrn->modes;
#ifdef XFreeXDGA
if (scrn->pScreen)
@@ -2060,13 +2066,28 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
if (o == p)
continue;
- for (mode = output->probed_modes; mode; mode = mode->next) {
- Rotation r = output->initial_rotation;
- if (xf86ModeWidth(mode, r) == pref_width &&
- xf86ModeHeight(mode, r) == pref_height) {
+ /*
+ * First see if the preferred mode matches on the next
+ * output as well. This catches the common case of identical
+ * monitors and makes sure they all have the same timings
+ * and refresh. If that fails, we fall back to trying to
+ * match just width & height.
+ */
+ mode = xf86OutputHasPreferredMode(output, pref_width,
+ pref_height);
+ if (mode && xf86ModesEqual(mode, preferred[p])) {
preferred[o] = mode;
match = TRUE;
- }
+ } else {
+ for (mode = output->probed_modes; mode;
+ mode = mode->next) {
+ Rotation r = output->initial_rotation;
+ if (xf86ModeWidth(mode, r) == pref_width &&
+ xf86ModeHeight(mode, r) == pref_height) {
+ preferred[o] = mode;
+ match = TRUE;
+ }
+ }
}
all_match &= match;
@@ -2514,16 +2535,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
width, height);
}
- if (have_outputs) {
- /* Mirror output modes to scrn mode list */
- xf86SetScrnInfoModes (scrn);
- } else {
- /* Clear any existing modes from scrn->modes */
- while (scrn->modes != NULL)
- xf86DeleteMode(&scrn->modes, scrn->modes);
- scrn->modes = xf86ModesAdd(scrn->modes,
- xf86CVTMode(width, height, 60, 0, 0));
- }
+ xf86SetScrnInfoModes (scrn);
success = TRUE;
bailout:
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 9c9174034..f18271f38 100644
--- a/xorg-server/hw/xfree86/os-support/linux/lnx_init.c
+++ b/xorg-server/hw/xfree86/os-support/linux/lnx_init.c
@@ -45,15 +45,12 @@ static char vtname[11];
static struct termios tty_attr; /* tty state to restore */
static int tty_mode; /* kbd mode to restore */
-static void *console_handler;
-
static void
drain_console(int fd, void *closure)
{
errno = 0;
if (tcflush(fd, TCIOFLUSH) == -1 && errno == EIO) {
- xf86RemoveGeneralHandler(console_handler);
- console_handler = NULL;
+ xf86SetConsoleHandler(NULL, NULL);
}
}
@@ -257,10 +254,11 @@ xf86CloseConsole(void)
return;
}
- if (console_handler) {
- xf86RemoveGeneralHandler(console_handler);
- console_handler = NULL;
- };
+ /*
+ * unregister the drain_console handler
+ * - what to do if someone else changed it in the meantime?
+ */
+ xf86SetConsoleHandler(NULL, NULL);
/* Back to text mode ... */
SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT));
diff --git a/xorg-server/hw/xfree86/parser/Flags.c b/xorg-server/hw/xfree86/parser/Flags.c
index 17e079a8c..f0a61707b 100644
--- a/xorg-server/hw/xfree86/parser/Flags.c
+++ b/xorg-server/hw/xfree86/parser/Flags.c
@@ -1,504 +1,505 @@
-/*
- * Copyright (c) 1997 Metro Link Incorporated
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of the Metro Link shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from Metro Link.
- *
- */
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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).
- */
-
-
-/* View/edit this file with tab stops set to 4 */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86Parser.h"
-#include "xf86tokens.h"
-#include "Configint.h"
-#include <X11/Xfuncproto.h>
-#include "Xprintf.h"
-
-extern LexRec val;
-
-static xf86ConfigSymTabRec ServerFlagsTab[] =
-{
- {ENDSECTION, "endsection"},
- {NOTRAPSIGNALS, "notrapsignals"},
- {DONTZAP, "dontzap"},
- {DONTZOOM, "dontzoom"},
- {DISABLEVIDMODE, "disablevidmodeextension"},
- {ALLOWNONLOCAL, "allownonlocalxvidtune"},
- {DISABLEMODINDEV, "disablemodindev"},
- {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"},
- {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"},
- {OPTION, "option"},
- {BLANKTIME, "blanktime"},
- {STANDBYTIME, "standbytime"},
- {SUSPENDTIME, "suspendtime"},
- {OFFTIME, "offtime"},
- {DEFAULTLAYOUT, "defaultserverlayout"},
- {-1, ""},
-};
-
-#define CLEANUP xf86freeFlags
-
-XF86ConfFlagsPtr
-xf86parseFlagsSection (void)
-{
- int token;
- parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
-
- while ((token = xf86getToken (ServerFlagsTab)) != ENDSECTION)
- {
- int hasvalue = FALSE;
- int strvalue = FALSE;
- int tokentype;
- switch (token)
- {
- case COMMENT:
- ptr->flg_comment = xf86addComment(ptr->flg_comment, val.str);
- break;
- /*
- * these old keywords are turned into standard generic options.
- * we fall through here on purpose
- */
- case DEFAULTLAYOUT:
- strvalue = TRUE;
- case BLANKTIME:
- case STANDBYTIME:
- case SUSPENDTIME:
- case OFFTIME:
- hasvalue = TRUE;
- case NOTRAPSIGNALS:
- case DONTZAP:
- case DONTZOOM:
- case DISABLEVIDMODE:
- case ALLOWNONLOCAL:
- case DISABLEMODINDEV:
- case MODINDEVALLOWNONLOCAL:
- case ALLOWMOUSEOPENFAIL:
- {
- int i = 0;
- while (ServerFlagsTab[i].token != -1)
- {
- char *tmp;
-
- if (ServerFlagsTab[i].token == token)
- {
- char *valstr = NULL;
- tmp = strdup (ServerFlagsTab[i].name);
- if (hasvalue)
- {
- tokentype = xf86getSubToken(&(ptr->flg_comment));
- if (strvalue) {
- if (tokentype != STRING)
- Error (QUOTE_MSG, tmp);
- valstr = val.str;
- } else {
- if (tokentype != NUMBER)
- Error (NUMBER_MSG, tmp);
- if (asprintf(&valstr, "%d", val.num) == -1)
- valstr = NULL;
- }
- }
- ptr->flg_option_lst = xf86addNewOption
- (ptr->flg_option_lst, tmp, valstr);
- }
- i++;
- }
- }
- break;
- case OPTION:
- ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst);
- break;
-
- case EOF_TOKEN:
- Error (UNEXPECTED_EOF_MSG, NULL);
- break;
- default:
- Error (INVALID_KEYWORD_MSG, xf86tokenString ());
- break;
- }
- }
-
-#ifdef DEBUG
- printf ("Flags section parsed\n");
-#endif
-
- return ptr;
-}
-
-#undef CLEANUP
-
-void
-xf86printServerFlagsSection (FILE * f, XF86ConfFlagsPtr flags)
-{
- XF86OptionPtr p;
-
- if ((!flags) || (!flags->flg_option_lst))
- return;
- p = flags->flg_option_lst;
- fprintf (f, "Section \"ServerFlags\"\n");
- if (flags->flg_comment)
- fprintf (f, "%s", flags->flg_comment);
- xf86printOptionList(f, p, 1);
- fprintf (f, "EndSection\n\n");
-}
-
-static XF86OptionPtr
-addNewOption2 (XF86OptionPtr head, char *name, char *val, int used)
-{
- XF86OptionPtr new, old = NULL;
-
- /* Don't allow duplicates, free old strings */
- if (head != NULL && (old = xf86findOption(head, name)) != NULL) {
- new = old;
- free(new->opt_name);
- free(new->opt_val);
- }
- else
- new = calloc (1, sizeof (XF86OptionRec));
- new->opt_name = name;
- new->opt_val = val;
- new->opt_used = used;
-
- if (old)
- return head;
- return ((XF86OptionPtr) xf86addListItem ((glp) head, (glp) new));
-}
-
-XF86OptionPtr
-xf86addNewOption (XF86OptionPtr head, char *name, char *val)
-{
- return addNewOption2(head, name, val, 0);
-}
-
-void
-xf86freeFlags (XF86ConfFlagsPtr flags)
-{
- if (flags == NULL)
- return;
- xf86optionListFree (flags->flg_option_lst);
- TestFree(flags->flg_comment);
- free (flags);
-}
-
-XF86OptionPtr
-xf86optionListDup (XF86OptionPtr opt)
-{
- XF86OptionPtr newopt = NULL;
- char *val;
-
- while (opt)
- {
- val = opt->opt_val ? strdup(opt->opt_val) : NULL;
- newopt = xf86addNewOption(newopt, strdup(opt->opt_name), val);
- newopt->opt_used = opt->opt_used;
- if (opt->opt_comment)
- newopt->opt_comment = strdup(opt->opt_comment);
- opt = opt->list.next;
- }
- return newopt;
-}
-
-void
-xf86optionListFree (XF86OptionPtr opt)
-{
- XF86OptionPtr prev;
-
- while (opt)
- {
- TestFree (opt->opt_name);
- TestFree (opt->opt_val);
- TestFree (opt->opt_comment);
- prev = opt;
- opt = opt->list.next;
- free (prev);
- }
-}
-
-char *
-xf86optionName(XF86OptionPtr opt)
-{
- if (opt)
- return opt->opt_name;
- return 0;
-}
-
-char *
-xf86optionValue(XF86OptionPtr opt)
-{
- if (opt)
- return opt->opt_val;
- return 0;
-}
-
-XF86OptionPtr
-xf86newOption(char *name, char *value)
-{
- XF86OptionPtr opt;
-
- opt = calloc(1, sizeof (XF86OptionRec));
- if (!opt)
- return NULL;
-
- opt->opt_used = 0;
- opt->list.next = 0;
- opt->opt_name = name;
- opt->opt_val = value;
-
- return opt;
-}
-
-XF86OptionPtr
-xf86nextOption(XF86OptionPtr list)
-{
- if (!list)
- return NULL;
- return list->list.next;
-}
-
-/*
- * this function searches the given option list for the named option and
- * returns a pointer to the option rec if found. If not found, it returns
- * NULL
- */
-
-XF86OptionPtr
-xf86findOption (XF86OptionPtr list, const char *name)
-{
- while (list)
- {
- if (xf86nameCompare (list->opt_name, name) == 0)
- return list;
- list = list->list.next;
- }
- return NULL;
-}
-
-/*
- * this function searches the given option list for the named option. If
- * found and the option has a parameter, a pointer to the parameter is
- * returned. If the option does not have a parameter an empty string is
- * returned. If the option is not found, a NULL is returned.
- */
-
-char *
-xf86findOptionValue (XF86OptionPtr list, const char *name)
-{
- XF86OptionPtr p = xf86findOption (list, name);
-
- if (p)
- {
- if (p->opt_val)
- return p->opt_val;
- else
- return "";
- }
- return NULL;
-}
-
-XF86OptionPtr
-xf86optionListCreate( const char **options, int count, int used )
-{
- XF86OptionPtr p = NULL;
- char *t1, *t2;
- int i;
-
- if (count == -1)
- {
- for (count = 0; options[count]; count++)
- ;
- }
- if( (count % 2) != 0 )
- {
- fprintf( stderr, "xf86optionListCreate: count must be an even number.\n" );
- return NULL;
- }
- for (i = 0; i < count; i += 2)
- {
- t1 = strdup(options[i]);
- t2 = strdup(options[i + 1]);
- p = addNewOption2 (p, t1, t2, used);
- }
-
- return p;
-}
-
-/* the 2 given lists are merged. If an option with the same name is present in
- * both, the option from the user list - specified in the second argument -
- * is used. The end result is a single valid list of options. Duplicates
- * are freed, and the original lists are no longer guaranteed to be complete.
- */
-XF86OptionPtr
-xf86optionListMerge (XF86OptionPtr head, XF86OptionPtr tail)
-{
- XF86OptionPtr a, b, ap = NULL, bp = NULL;
-
- a = tail;
- b = head;
- while (tail && b) {
- if (xf86nameCompare (a->opt_name, b->opt_name) == 0) {
- if (b == head)
- head = a;
- else
- bp->list.next = a;
- if (a == tail)
- tail = a->list.next;
- else
- ap->list.next = a->list.next;
- a->list.next = b->list.next;
- b->list.next = NULL;
- xf86optionListFree (b);
- b = a->list.next;
- bp = a;
- a = tail;
- ap = NULL;
- } else {
- ap = a;
- if (!(a = a->list.next)) {
- a = tail;
- bp = b;
- b = b->list.next;
- ap = NULL;
- }
- }
- }
-
- if (head) {
- for (a = head; a->list.next; a = a->list.next)
- ;
- a->list.next = tail;
- } else
- head = tail;
-
- return head;
-}
-
-char *
-xf86uLongToString(unsigned long i)
-{
- char *s;
-
- if (asprintf(&s, "%lu", i) == -1)
- return NULL;
- return s;
-}
-
-XF86OptionPtr
-xf86parseOption(XF86OptionPtr head)
-{
- XF86OptionPtr option, cnew, old;
- char *name, *comment = NULL;
- int token;
-
- if ((token = xf86getSubToken(&comment)) != STRING) {
- xf86parseError(BAD_OPTION_MSG, NULL);
- free(comment);
- return head;
- }
-
- name = val.str;
- if ((token = xf86getSubToken(&comment)) == STRING) {
- option = xf86newOption(name, val.str);
- option->opt_comment = comment;
- if ((token = xf86getToken(NULL)) == COMMENT)
- option->opt_comment = xf86addComment(option->opt_comment, val.str);
- else
- xf86unGetToken(token);
- }
- else {
- option = xf86newOption(name, NULL);
- option->opt_comment = comment;
- if (token == COMMENT)
- option->opt_comment = xf86addComment(option->opt_comment, val.str);
- else
- xf86unGetToken(token);
- }
-
- old = NULL;
-
- /* Don't allow duplicates */
- if (head != NULL && (old = xf86findOption(head, name)) != NULL) {
- cnew = old;
- free(option->opt_name);
- TestFree(option->opt_val);
- TestFree(option->opt_comment);
- free(option);
- }
- else
- cnew = option;
-
- if (old == NULL)
- return ((XF86OptionPtr)xf86addListItem((glp)head, (glp)cnew));
-
- return head;
-}
-
-void
-xf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs)
-{
- int i;
-
- if (!list)
- return;
- while (list) {
- for (i = 0; i < tabs; i++)
- fputc('\t', fp);
- if (list->opt_val)
- fprintf(fp, "Option \"%s\" \"%s\"", list->opt_name, list->opt_val);
- else
- fprintf(fp, "Option \"%s\"", list->opt_name);
- if (list->opt_comment)
- fprintf(fp, "%s", list->opt_comment);
- else
- fputc('\n', fp);
- list = list->list.next;
- }
-}
+/*
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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).
+ */
+
+
+/* View/edit this file with tab stops set to 4 */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+#include <X11/Xfuncproto.h>
+#include "Xprintf.h"
+#include "optionstr.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec ServerFlagsTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {NOTRAPSIGNALS, "notrapsignals"},
+ {DONTZAP, "dontzap"},
+ {DONTZOOM, "dontzoom"},
+ {DISABLEVIDMODE, "disablevidmodeextension"},
+ {ALLOWNONLOCAL, "allownonlocalxvidtune"},
+ {DISABLEMODINDEV, "disablemodindev"},
+ {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"},
+ {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"},
+ {OPTION, "option"},
+ {BLANKTIME, "blanktime"},
+ {STANDBYTIME, "standbytime"},
+ {SUSPENDTIME, "suspendtime"},
+ {OFFTIME, "offtime"},
+ {DEFAULTLAYOUT, "defaultserverlayout"},
+ {-1, ""},
+};
+
+#define CLEANUP xf86freeFlags
+
+XF86ConfFlagsPtr
+xf86parseFlagsSection (void)
+{
+ int token;
+ parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
+
+ while ((token = xf86getToken (ServerFlagsTab)) != ENDSECTION)
+ {
+ int hasvalue = FALSE;
+ int strvalue = FALSE;
+ int tokentype;
+ switch (token)
+ {
+ case COMMENT:
+ ptr->flg_comment = xf86addComment(ptr->flg_comment, val.str);
+ break;
+ /*
+ * these old keywords are turned into standard generic options.
+ * we fall through here on purpose
+ */
+ case DEFAULTLAYOUT:
+ strvalue = TRUE;
+ case BLANKTIME:
+ case STANDBYTIME:
+ case SUSPENDTIME:
+ case OFFTIME:
+ hasvalue = TRUE;
+ case NOTRAPSIGNALS:
+ case DONTZAP:
+ case DONTZOOM:
+ case DISABLEVIDMODE:
+ case ALLOWNONLOCAL:
+ case DISABLEMODINDEV:
+ case MODINDEVALLOWNONLOCAL:
+ case ALLOWMOUSEOPENFAIL:
+ {
+ int i = 0;
+ while (ServerFlagsTab[i].token != -1)
+ {
+ char *tmp;
+
+ if (ServerFlagsTab[i].token == token)
+ {
+ char *valstr = NULL;
+ tmp = strdup (ServerFlagsTab[i].name);
+ if (hasvalue)
+ {
+ tokentype = xf86getSubToken(&(ptr->flg_comment));
+ if (strvalue) {
+ if (tokentype != STRING)
+ Error (QUOTE_MSG, tmp);
+ valstr = val.str;
+ } else {
+ if (tokentype != NUMBER)
+ Error (NUMBER_MSG, tmp);
+ if (asprintf(&valstr, "%d", val.num) == -1)
+ valstr = NULL;
+ }
+ }
+ ptr->flg_option_lst = xf86addNewOption
+ (ptr->flg_option_lst, tmp, valstr);
+ }
+ i++;
+ }
+ }
+ break;
+ case OPTION:
+ ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst);
+ break;
+
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86tokenString ());
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ printf ("Flags section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+xf86printServerFlagsSection (FILE * f, XF86ConfFlagsPtr flags)
+{
+ XF86OptionPtr p;
+
+ if ((!flags) || (!flags->flg_option_lst))
+ return;
+ p = flags->flg_option_lst;
+ fprintf (f, "Section \"ServerFlags\"\n");
+ if (flags->flg_comment)
+ fprintf (f, "%s", flags->flg_comment);
+ xf86printOptionList(f, p, 1);
+ fprintf (f, "EndSection\n\n");
+}
+
+static XF86OptionPtr
+addNewOption2 (XF86OptionPtr head, char *name, char *val, int used)
+{
+ XF86OptionPtr new, old = NULL;
+
+ /* Don't allow duplicates, free old strings */
+ if (head != NULL && (old = xf86findOption(head, name)) != NULL) {
+ new = old;
+ free(new->opt_name);
+ free(new->opt_val);
+ }
+ else
+ new = calloc (1, sizeof (*new));
+ new->opt_name = name;
+ new->opt_val = val;
+ new->opt_used = used;
+
+ if (old)
+ return head;
+ return ((XF86OptionPtr) xf86addListItem ((glp) head, (glp) new));
+}
+
+XF86OptionPtr
+xf86addNewOption (XF86OptionPtr head, char *name, char *val)
+{
+ return addNewOption2(head, name, val, 0);
+}
+
+void
+xf86freeFlags (XF86ConfFlagsPtr flags)
+{
+ if (flags == NULL)
+ return;
+ xf86optionListFree (flags->flg_option_lst);
+ TestFree(flags->flg_comment);
+ free (flags);
+}
+
+XF86OptionPtr
+xf86optionListDup (XF86OptionPtr opt)
+{
+ XF86OptionPtr newopt = NULL;
+ char *val;
+
+ while (opt)
+ {
+ val = opt->opt_val ? strdup(opt->opt_val) : NULL;
+ newopt = xf86addNewOption(newopt, strdup(opt->opt_name), val);
+ newopt->opt_used = opt->opt_used;
+ if (opt->opt_comment)
+ newopt->opt_comment = strdup(opt->opt_comment);
+ opt = opt->list.next;
+ }
+ return newopt;
+}
+
+void
+xf86optionListFree (XF86OptionPtr opt)
+{
+ XF86OptionPtr prev;
+
+ while (opt)
+ {
+ TestFree (opt->opt_name);
+ TestFree (opt->opt_val);
+ TestFree (opt->opt_comment);
+ prev = opt;
+ opt = opt->list.next;
+ free (prev);
+ }
+}
+
+char *
+xf86optionName(XF86OptionPtr opt)
+{
+ if (opt)
+ return opt->opt_name;
+ return 0;
+}
+
+char *
+xf86optionValue(XF86OptionPtr opt)
+{
+ if (opt)
+ return opt->opt_val;
+ return 0;
+}
+
+XF86OptionPtr
+xf86newOption(char *name, char *value)
+{
+ XF86OptionPtr opt;
+
+ opt = calloc(1, sizeof (*opt));
+ if (!opt)
+ return NULL;
+
+ opt->opt_used = 0;
+ opt->list.next = 0;
+ opt->opt_name = name;
+ opt->opt_val = value;
+
+ return opt;
+}
+
+XF86OptionPtr
+xf86nextOption(XF86OptionPtr list)
+{
+ if (!list)
+ return NULL;
+ return list->list.next;
+}
+
+/*
+ * this function searches the given option list for the named option and
+ * returns a pointer to the option rec if found. If not found, it returns
+ * NULL
+ */
+
+XF86OptionPtr
+xf86findOption (XF86OptionPtr list, const char *name)
+{
+ while (list)
+ {
+ if (xf86nameCompare (list->opt_name, name) == 0)
+ return list;
+ list = list->list.next;
+ }
+ return NULL;
+}
+
+/*
+ * this function searches the given option list for the named option. If
+ * found and the option has a parameter, a pointer to the parameter is
+ * returned. If the option does not have a parameter an empty string is
+ * returned. If the option is not found, a NULL is returned.
+ */
+
+char *
+xf86findOptionValue (XF86OptionPtr list, const char *name)
+{
+ XF86OptionPtr p = xf86findOption (list, name);
+
+ if (p)
+ {
+ if (p->opt_val)
+ return p->opt_val;
+ else
+ return "";
+ }
+ return NULL;
+}
+
+XF86OptionPtr
+xf86optionListCreate( const char **options, int count, int used )
+{
+ XF86OptionPtr p = NULL;
+ char *t1, *t2;
+ int i;
+
+ if (count == -1)
+ {
+ for (count = 0; options[count]; count++)
+ ;
+ }
+ if( (count % 2) != 0 )
+ {
+ fprintf( stderr, "xf86optionListCreate: count must be an even number.\n" );
+ return NULL;
+ }
+ for (i = 0; i < count; i += 2)
+ {
+ t1 = strdup(options[i]);
+ t2 = strdup(options[i + 1]);
+ p = addNewOption2 (p, t1, t2, used);
+ }
+
+ return p;
+}
+
+/* the 2 given lists are merged. If an option with the same name is present in
+ * both, the option from the user list - specified in the second argument -
+ * is used. The end result is a single valid list of options. Duplicates
+ * are freed, and the original lists are no longer guaranteed to be complete.
+ */
+XF86OptionPtr
+xf86optionListMerge (XF86OptionPtr head, XF86OptionPtr tail)
+{
+ XF86OptionPtr a, b, ap = NULL, bp = NULL;
+
+ a = tail;
+ b = head;
+ while (tail && b) {
+ if (xf86nameCompare (a->opt_name, b->opt_name) == 0) {
+ if (b == head)
+ head = a;
+ else
+ bp->list.next = a;
+ if (a == tail)
+ tail = a->list.next;
+ else
+ ap->list.next = a->list.next;
+ a->list.next = b->list.next;
+ b->list.next = NULL;
+ xf86optionListFree (b);
+ b = a->list.next;
+ bp = a;
+ a = tail;
+ ap = NULL;
+ } else {
+ ap = a;
+ if (!(a = a->list.next)) {
+ a = tail;
+ bp = b;
+ b = b->list.next;
+ ap = NULL;
+ }
+ }
+ }
+
+ if (head) {
+ for (a = head; a->list.next; a = a->list.next)
+ ;
+ a->list.next = tail;
+ } else
+ head = tail;
+
+ return head;
+}
+
+char *
+xf86uLongToString(unsigned long i)
+{
+ char *s;
+
+ if (asprintf(&s, "%lu", i) == -1)
+ return NULL;
+ return s;
+}
+
+XF86OptionPtr
+xf86parseOption(XF86OptionPtr head)
+{
+ XF86OptionPtr option, cnew, old;
+ char *name, *comment = NULL;
+ int token;
+
+ if ((token = xf86getSubToken(&comment)) != STRING) {
+ xf86parseError(BAD_OPTION_MSG, NULL);
+ free(comment);
+ return head;
+ }
+
+ name = val.str;
+ if ((token = xf86getSubToken(&comment)) == STRING) {
+ option = xf86newOption(name, val.str);
+ option->opt_comment = comment;
+ if ((token = xf86getToken(NULL)) == COMMENT)
+ option->opt_comment = xf86addComment(option->opt_comment, val.str);
+ else
+ xf86unGetToken(token);
+ }
+ else {
+ option = xf86newOption(name, NULL);
+ option->opt_comment = comment;
+ if (token == COMMENT)
+ option->opt_comment = xf86addComment(option->opt_comment, val.str);
+ else
+ xf86unGetToken(token);
+ }
+
+ old = NULL;
+
+ /* Don't allow duplicates */
+ if (head != NULL && (old = xf86findOption(head, name)) != NULL) {
+ cnew = old;
+ free(option->opt_name);
+ TestFree(option->opt_val);
+ TestFree(option->opt_comment);
+ free(option);
+ }
+ else
+ cnew = option;
+
+ if (old == NULL)
+ return ((XF86OptionPtr)xf86addListItem((glp)head, (glp)cnew));
+
+ return head;
+}
+
+void
+xf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs)
+{
+ int i;
+
+ if (!list)
+ return;
+ while (list) {
+ for (i = 0; i < tabs; i++)
+ fputc('\t', fp);
+ if (list->opt_val)
+ fprintf(fp, "Option \"%s\" \"%s\"", list->opt_name, list->opt_val);
+ else
+ fprintf(fp, "Option \"%s\"", list->opt_name);
+ if (list->opt_comment)
+ fprintf(fp, "%s", list->opt_comment);
+ else
+ fputc('\n', fp);
+ list = list->list.next;
+ }
+}
diff --git a/xorg-server/hw/xfree86/parser/Layout.c b/xorg-server/hw/xfree86/parser/Layout.c
index 60e83390f..4487b0df6 100644
--- a/xorg-server/hw/xfree86/parser/Layout.c
+++ b/xorg-server/hw/xfree86/parser/Layout.c
@@ -1,558 +1,558 @@
-/*
- *
- * Copyright (c) 1997 Metro Link Incorporated
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of the Metro Link shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from Metro Link.
- *
- */
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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).
- */
-
-
-/* View/edit this file with tab stops set to 4 */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86Parser.h"
-#include "xf86tokens.h"
-#include "Configint.h"
-#include <string.h>
-
-
-/* Needed for auto server layout */
-extern int xf86CheckBoolOption(void* optlist, const char *name, int deflt);
-
-extern LexRec val;
-
-static xf86ConfigSymTabRec LayoutTab[] =
-{
- {ENDSECTION, "endsection"},
- {SCREEN, "screen"},
- {IDENTIFIER, "identifier"},
- {INACTIVE, "inactive"},
- {INPUTDEVICE, "inputdevice"},
- {OPTION, "option"},
- {-1, ""},
-};
-
-static xf86ConfigSymTabRec AdjTab[] =
-{
- {RIGHTOF, "rightof"},
- {LEFTOF, "leftof"},
- {ABOVE, "above"},
- {BELOW, "below"},
- {RELATIVE, "relative"},
- {ABSOLUTE, "absolute"},
- {-1, ""},
-};
-
-#define CLEANUP xf86freeLayoutList
-
-XF86ConfLayoutPtr
-xf86parseLayoutSection (void)
-{
- int has_ident = FALSE;
- int token;
- parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
-
- while ((token = xf86getToken (LayoutTab)) != ENDSECTION)
- {
- switch (token)
- {
- case COMMENT:
- ptr->lay_comment = xf86addComment(ptr->lay_comment, val.str);
- break;
- case IDENTIFIER:
- if (xf86getSubToken (&(ptr->lay_comment)) != STRING)
- Error (QUOTE_MSG, "Identifier");
- if (has_ident == TRUE)
- Error (MULTIPLE_MSG, "Identifier");
- ptr->lay_identifier = val.str;
- has_ident = TRUE;
- break;
- case INACTIVE:
- {
- XF86ConfInactivePtr iptr;
-
- iptr = calloc (1, sizeof (XF86ConfInactiveRec));
- iptr->list.next = NULL;
- if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
- free (iptr);
- Error (INACTIVE_MSG, NULL);
- }
- iptr->inactive_device_str = val.str;
- ptr->lay_inactive_lst = (XF86ConfInactivePtr)
- xf86addListItem ((glp) ptr->lay_inactive_lst, (glp) iptr);
- }
- break;
- case SCREEN:
- {
- XF86ConfAdjacencyPtr aptr;
- int absKeyword = 0;
-
- aptr = calloc (1, sizeof (XF86ConfAdjacencyRec));
- aptr->list.next = NULL;
- aptr->adj_scrnum = -1;
- aptr->adj_where = CONF_ADJ_OBSOLETE;
- aptr->adj_x = 0;
- aptr->adj_y = 0;
- aptr->adj_refscreen = NULL;
- if ((token = xf86getSubToken (&(ptr->lay_comment))) == NUMBER)
- aptr->adj_scrnum = val.num;
- else
- xf86unGetToken (token);
- token = xf86getSubToken(&(ptr->lay_comment));
- if (token != STRING) {
- free(aptr);
- Error (SCREEN_MSG, NULL);
- }
- aptr->adj_screen_str = val.str;
-
- token = xf86getSubTokenWithTab(&(ptr->lay_comment), AdjTab);
- switch (token)
- {
- case RIGHTOF:
- aptr->adj_where = CONF_ADJ_RIGHTOF;
- break;
- case LEFTOF:
- aptr->adj_where = CONF_ADJ_LEFTOF;
- break;
- case ABOVE:
- aptr->adj_where = CONF_ADJ_ABOVE;
- break;
- case BELOW:
- aptr->adj_where = CONF_ADJ_BELOW;
- break;
- case RELATIVE:
- aptr->adj_where = CONF_ADJ_RELATIVE;
- break;
- case ABSOLUTE:
- aptr->adj_where = CONF_ADJ_ABSOLUTE;
- absKeyword = 1;
- break;
- case EOF_TOKEN:
- free(aptr);
- Error (UNEXPECTED_EOF_MSG, NULL);
- break;
- default:
- xf86unGetToken (token);
- token = xf86getSubToken(&(ptr->lay_comment));
- if (token == STRING)
- aptr->adj_where = CONF_ADJ_OBSOLETE;
- else
- aptr->adj_where = CONF_ADJ_ABSOLUTE;
- }
- switch (aptr->adj_where)
- {
- case CONF_ADJ_ABSOLUTE:
- if (absKeyword)
- token = xf86getSubToken(&(ptr->lay_comment));
- if (token == NUMBER)
- {
- aptr->adj_x = val.num;
- token = xf86getSubToken(&(ptr->lay_comment));
- if (token != NUMBER) {
- free(aptr);
- Error(INVALID_SCR_MSG, NULL);
- }
- aptr->adj_y = val.num;
- } else {
- if (absKeyword) {
- free(aptr);
- Error(INVALID_SCR_MSG, NULL);
- } else
- xf86unGetToken (token);
- }
- break;
- case CONF_ADJ_RIGHTOF:
- case CONF_ADJ_LEFTOF:
- case CONF_ADJ_ABOVE:
- case CONF_ADJ_BELOW:
- case CONF_ADJ_RELATIVE:
- token = xf86getSubToken(&(ptr->lay_comment));
- if (token != STRING) {
- free(aptr);
- Error(INVALID_SCR_MSG, NULL);
- }
- aptr->adj_refscreen = val.str;
- if (aptr->adj_where == CONF_ADJ_RELATIVE)
- {
- token = xf86getSubToken(&(ptr->lay_comment));
- if (token != NUMBER) {
- free(aptr);
- Error(INVALID_SCR_MSG, NULL);
- }
- aptr->adj_x = val.num;
- token = xf86getSubToken(&(ptr->lay_comment));
- if (token != NUMBER) {
- free(aptr);
- Error(INVALID_SCR_MSG, NULL);
- }
- aptr->adj_y = val.num;
- }
- break;
- case CONF_ADJ_OBSOLETE:
- /* top */
- aptr->adj_top_str = val.str;
-
- /* bottom */
- if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
- free(aptr);
- Error (SCREEN_MSG, NULL);
- }
- aptr->adj_bottom_str = val.str;
-
- /* left */
- if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
- free(aptr);
- Error (SCREEN_MSG, NULL);
- }
- aptr->adj_left_str = val.str;
-
- /* right */
- if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
- free(aptr);
- Error (SCREEN_MSG, NULL);
- }
- aptr->adj_right_str = val.str;
-
- }
- ptr->lay_adjacency_lst = (XF86ConfAdjacencyPtr)
- xf86addListItem ((glp) ptr->lay_adjacency_lst, (glp) aptr);
- }
- break;
- case INPUTDEVICE:
- {
- XF86ConfInputrefPtr iptr;
-
- iptr = calloc (1, sizeof (XF86ConfInputrefRec));
- iptr->list.next = NULL;
- iptr->iref_option_lst = NULL;
- if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
- free(iptr);
- Error (INPUTDEV_MSG, NULL);
- }
- iptr->iref_inputdev_str = val.str;
- while ((token = xf86getSubToken (&(ptr->lay_comment))) == STRING)
- {
- iptr->iref_option_lst =
- xf86addNewOption (iptr->iref_option_lst, val.str, NULL);
- }
- xf86unGetToken (token);
- ptr->lay_input_lst = (XF86ConfInputrefPtr)
- xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
- }
- break;
- case OPTION:
- ptr->lay_option_lst = xf86parseOption(ptr->lay_option_lst);
- break;
- case EOF_TOKEN:
- Error (UNEXPECTED_EOF_MSG, NULL);
- break;
- default:
- Error (INVALID_KEYWORD_MSG, xf86tokenString ());
- break;
- }
- }
-
- if (!has_ident)
- Error (NO_IDENT_MSG, NULL);
-
-#ifdef DEBUG
- printf ("Layout section parsed\n");
-#endif
-
- return ptr;
-}
-
-#undef CLEANUP
-
-void
-xf86printLayoutSection (FILE * cf, XF86ConfLayoutPtr ptr)
-{
- XF86ConfAdjacencyPtr aptr;
- XF86ConfInactivePtr iptr;
- XF86ConfInputrefPtr inptr;
- XF86OptionPtr optr;
-
- while (ptr)
- {
- fprintf (cf, "Section \"ServerLayout\"\n");
- if (ptr->lay_comment)
- fprintf (cf, "%s", ptr->lay_comment);
- if (ptr->lay_identifier)
- fprintf (cf, "\tIdentifier \"%s\"\n", ptr->lay_identifier);
-
- for (aptr = ptr->lay_adjacency_lst; aptr; aptr = aptr->list.next)
- {
- fprintf (cf, "\tScreen ");
- if (aptr->adj_scrnum >= 0)
- fprintf (cf, "%2d", aptr->adj_scrnum);
- else
- fprintf (cf, " ");
- fprintf (cf, " \"%s\"", aptr->adj_screen_str);
- switch(aptr->adj_where)
- {
- case CONF_ADJ_OBSOLETE:
- fprintf (cf, " \"%s\"", aptr->adj_top_str);
- fprintf (cf, " \"%s\"", aptr->adj_bottom_str);
- fprintf (cf, " \"%s\"", aptr->adj_right_str);
- fprintf (cf, " \"%s\"\n", aptr->adj_left_str);
- break;
- case CONF_ADJ_ABSOLUTE:
- if (aptr->adj_x != -1)
- fprintf (cf, " %d %d\n", aptr->adj_x, aptr->adj_y);
- else
- fprintf (cf, "\n");
- break;
- case CONF_ADJ_RIGHTOF:
- fprintf (cf, " RightOf \"%s\"\n", aptr->adj_refscreen);
- break;
- case CONF_ADJ_LEFTOF:
- fprintf (cf, " LeftOf \"%s\"\n", aptr->adj_refscreen);
- break;
- case CONF_ADJ_ABOVE:
- fprintf (cf, " Above \"%s\"\n", aptr->adj_refscreen);
- break;
- case CONF_ADJ_BELOW:
- fprintf (cf, " Below \"%s\"\n", aptr->adj_refscreen);
- break;
- case CONF_ADJ_RELATIVE:
- fprintf (cf, " Relative \"%s\" %d %d\n", aptr->adj_refscreen,
- aptr->adj_x, aptr->adj_y);
- break;
- }
- }
- for (iptr = ptr->lay_inactive_lst; iptr; iptr = iptr->list.next)
- fprintf (cf, "\tInactive \"%s\"\n", iptr->inactive_device_str);
- for (inptr = ptr->lay_input_lst; inptr; inptr = inptr->list.next)
- {
- fprintf (cf, "\tInputDevice \"%s\"", inptr->iref_inputdev_str);
- for (optr = inptr->iref_option_lst; optr; optr = optr->list.next)
- {
- fprintf(cf, " \"%s\"", optr->opt_name);
- }
- fprintf(cf, "\n");
- }
- xf86printOptionList(cf, ptr->lay_option_lst, 1);
- fprintf (cf, "EndSection\n\n");
- ptr = ptr->list.next;
- }
-}
-
-static void
-xf86freeAdjacencyList (XF86ConfAdjacencyPtr ptr)
-{
- XF86ConfAdjacencyPtr prev;
-
- while (ptr)
- {
- TestFree (ptr->adj_screen_str);
- TestFree (ptr->adj_top_str);
- TestFree (ptr->adj_bottom_str);
- TestFree (ptr->adj_left_str);
- TestFree (ptr->adj_right_str);
-
- prev = ptr;
- ptr = ptr->list.next;
- free (prev);
- }
-
-}
-
-static void
-xf86freeInputrefList (XF86ConfInputrefPtr ptr)
-{
- XF86ConfInputrefPtr prev;
-
- while (ptr)
- {
- TestFree (ptr->iref_inputdev_str);
- xf86optionListFree (ptr->iref_option_lst);
- prev = ptr;
- ptr = ptr->list.next;
- free (prev);
- }
-
-}
-
-void
-xf86freeLayoutList (XF86ConfLayoutPtr ptr)
-{
- XF86ConfLayoutPtr prev;
-
- while (ptr)
- {
- TestFree (ptr->lay_identifier);
- TestFree (ptr->lay_comment);
- xf86freeAdjacencyList (ptr->lay_adjacency_lst);
- xf86freeInputrefList (ptr->lay_input_lst);
- prev = ptr;
- ptr = ptr->list.next;
- free (prev);
- }
-}
-
-int
-xf86layoutAddInputDevices(XF86ConfigPtr config, XF86ConfLayoutPtr layout)
-{
- int count = 0;
- XF86ConfInputPtr input = config->conf_input_lst;
- XF86ConfInputrefPtr inptr;
-
- /* add all AutoServerLayout devices to the server layout */
- while (input)
- {
- if (xf86CheckBoolOption(input->inp_option_lst, "AutoServerLayout", FALSE))
- {
- XF86ConfInputrefPtr iref = layout->lay_input_lst;
-
- /* avoid duplicates if referenced but lists AutoServerLayout too */
- while (iref)
- {
- if (strcmp(iref->iref_inputdev_str, input->inp_identifier) == 0)
- break;
- iref = iref->list.next;
- }
-
- if (!iref)
- {
- XF86ConfInputrefPtr iptr;
- iptr = calloc(1, sizeof(XF86ConfInputrefRec));
- iptr->iref_inputdev_str = input->inp_identifier;
- layout->lay_input_lst = (XF86ConfInputrefPtr)
- xf86addListItem((glp)layout->lay_input_lst, (glp)iptr);
- count++;
- }
- }
- input = input->list.next;
- }
-
- inptr = layout->lay_input_lst;
- while (inptr)
- {
- input = xf86findInput (inptr->iref_inputdev_str,
- config->conf_input_lst);
- if (!input)
- {
- xf86validationError (UNDEFINED_INPUT_MSG,
- inptr->iref_inputdev_str, layout->lay_identifier);
- return -1;
- }
- else
- inptr->iref_inputdev = input;
- inptr = inptr->list.next;
- }
-
- return count;
-}
-
-int
-xf86validateLayout (XF86ConfigPtr p)
-{
- XF86ConfLayoutPtr layout = p->conf_layout_lst;
- XF86ConfAdjacencyPtr adj;
- XF86ConfInactivePtr iptr;
- XF86ConfScreenPtr screen;
- XF86ConfDevicePtr device;
-
- while (layout)
- {
- adj = layout->lay_adjacency_lst;
- while (adj)
- {
- /* the first one can't be "" but all others can */
- screen = xf86findScreen (adj->adj_screen_str, p->conf_screen_lst);
- if (!screen)
- {
- xf86validationError (UNDEFINED_SCREEN_MSG,
- adj->adj_screen_str, layout->lay_identifier);
- return FALSE;
- }
- else
- adj->adj_screen = screen;
-
- adj = adj->list.next;
- }
- iptr = layout->lay_inactive_lst;
- while (iptr)
- {
- device = xf86findDevice (iptr->inactive_device_str,
- p->conf_device_lst);
- if (!device)
- {
- xf86validationError (UNDEFINED_DEVICE_LAY_MSG,
- iptr->inactive_device_str, layout->lay_identifier);
- return FALSE;
- }
- else
- iptr->inactive_device = device;
- iptr = iptr->list.next;
- }
-
- if (xf86layoutAddInputDevices(p, layout) == -1)
- return FALSE;
-
- layout = layout->list.next;
- }
- return TRUE;
-}
-
-XF86ConfLayoutPtr
-xf86findLayout (const char *name, XF86ConfLayoutPtr list)
-{
- while (list)
- {
- if (xf86nameCompare (list->lay_identifier, name) == 0)
- return list;
- list = list->list.next;
- }
- return NULL;
-}
-
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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).
+ */
+
+
+/* View/edit this file with tab stops set to 4 */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+#include <string.h>
+#include "optionstr.h"
+
+/* Needed for auto server layout */
+extern int xf86CheckBoolOption(void* optlist, const char *name, int deflt);
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec LayoutTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {SCREEN, "screen"},
+ {IDENTIFIER, "identifier"},
+ {INACTIVE, "inactive"},
+ {INPUTDEVICE, "inputdevice"},
+ {OPTION, "option"},
+ {-1, ""},
+};
+
+static xf86ConfigSymTabRec AdjTab[] =
+{
+ {RIGHTOF, "rightof"},
+ {LEFTOF, "leftof"},
+ {ABOVE, "above"},
+ {BELOW, "below"},
+ {RELATIVE, "relative"},
+ {ABSOLUTE, "absolute"},
+ {-1, ""},
+};
+
+#define CLEANUP xf86freeLayoutList
+
+XF86ConfLayoutPtr
+xf86parseLayoutSection (void)
+{
+ int has_ident = FALSE;
+ int token;
+ parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
+
+ while ((token = xf86getToken (LayoutTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case COMMENT:
+ ptr->lay_comment = xf86addComment(ptr->lay_comment, val.str);
+ break;
+ case IDENTIFIER:
+ if (xf86getSubToken (&(ptr->lay_comment)) != STRING)
+ Error (QUOTE_MSG, "Identifier");
+ if (has_ident == TRUE)
+ Error (MULTIPLE_MSG, "Identifier");
+ ptr->lay_identifier = val.str;
+ has_ident = TRUE;
+ break;
+ case INACTIVE:
+ {
+ XF86ConfInactivePtr iptr;
+
+ iptr = calloc (1, sizeof (XF86ConfInactiveRec));
+ iptr->list.next = NULL;
+ if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
+ free (iptr);
+ Error (INACTIVE_MSG, NULL);
+ }
+ iptr->inactive_device_str = val.str;
+ ptr->lay_inactive_lst = (XF86ConfInactivePtr)
+ xf86addListItem ((glp) ptr->lay_inactive_lst, (glp) iptr);
+ }
+ break;
+ case SCREEN:
+ {
+ XF86ConfAdjacencyPtr aptr;
+ int absKeyword = 0;
+
+ aptr = calloc (1, sizeof (XF86ConfAdjacencyRec));
+ aptr->list.next = NULL;
+ aptr->adj_scrnum = -1;
+ aptr->adj_where = CONF_ADJ_OBSOLETE;
+ aptr->adj_x = 0;
+ aptr->adj_y = 0;
+ aptr->adj_refscreen = NULL;
+ if ((token = xf86getSubToken (&(ptr->lay_comment))) == NUMBER)
+ aptr->adj_scrnum = val.num;
+ else
+ xf86unGetToken (token);
+ token = xf86getSubToken(&(ptr->lay_comment));
+ if (token != STRING) {
+ free(aptr);
+ Error (SCREEN_MSG, NULL);
+ }
+ aptr->adj_screen_str = val.str;
+
+ token = xf86getSubTokenWithTab(&(ptr->lay_comment), AdjTab);
+ switch (token)
+ {
+ case RIGHTOF:
+ aptr->adj_where = CONF_ADJ_RIGHTOF;
+ break;
+ case LEFTOF:
+ aptr->adj_where = CONF_ADJ_LEFTOF;
+ break;
+ case ABOVE:
+ aptr->adj_where = CONF_ADJ_ABOVE;
+ break;
+ case BELOW:
+ aptr->adj_where = CONF_ADJ_BELOW;
+ break;
+ case RELATIVE:
+ aptr->adj_where = CONF_ADJ_RELATIVE;
+ break;
+ case ABSOLUTE:
+ aptr->adj_where = CONF_ADJ_ABSOLUTE;
+ absKeyword = 1;
+ break;
+ case EOF_TOKEN:
+ free(aptr);
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ xf86unGetToken (token);
+ token = xf86getSubToken(&(ptr->lay_comment));
+ if (token == STRING)
+ aptr->adj_where = CONF_ADJ_OBSOLETE;
+ else
+ aptr->adj_where = CONF_ADJ_ABSOLUTE;
+ }
+ switch (aptr->adj_where)
+ {
+ case CONF_ADJ_ABSOLUTE:
+ if (absKeyword)
+ token = xf86getSubToken(&(ptr->lay_comment));
+ if (token == NUMBER)
+ {
+ aptr->adj_x = val.num;
+ token = xf86getSubToken(&(ptr->lay_comment));
+ if (token != NUMBER) {
+ free(aptr);
+ Error(INVALID_SCR_MSG, NULL);
+ }
+ aptr->adj_y = val.num;
+ } else {
+ if (absKeyword) {
+ free(aptr);
+ Error(INVALID_SCR_MSG, NULL);
+ } else
+ xf86unGetToken (token);
+ }
+ break;
+ case CONF_ADJ_RIGHTOF:
+ case CONF_ADJ_LEFTOF:
+ case CONF_ADJ_ABOVE:
+ case CONF_ADJ_BELOW:
+ case CONF_ADJ_RELATIVE:
+ token = xf86getSubToken(&(ptr->lay_comment));
+ if (token != STRING) {
+ free(aptr);
+ Error(INVALID_SCR_MSG, NULL);
+ }
+ aptr->adj_refscreen = val.str;
+ if (aptr->adj_where == CONF_ADJ_RELATIVE)
+ {
+ token = xf86getSubToken(&(ptr->lay_comment));
+ if (token != NUMBER) {
+ free(aptr);
+ Error(INVALID_SCR_MSG, NULL);
+ }
+ aptr->adj_x = val.num;
+ token = xf86getSubToken(&(ptr->lay_comment));
+ if (token != NUMBER) {
+ free(aptr);
+ Error(INVALID_SCR_MSG, NULL);
+ }
+ aptr->adj_y = val.num;
+ }
+ break;
+ case CONF_ADJ_OBSOLETE:
+ /* top */
+ aptr->adj_top_str = val.str;
+
+ /* bottom */
+ if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
+ free(aptr);
+ Error (SCREEN_MSG, NULL);
+ }
+ aptr->adj_bottom_str = val.str;
+
+ /* left */
+ if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
+ free(aptr);
+ Error (SCREEN_MSG, NULL);
+ }
+ aptr->adj_left_str = val.str;
+
+ /* right */
+ if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
+ free(aptr);
+ Error (SCREEN_MSG, NULL);
+ }
+ aptr->adj_right_str = val.str;
+
+ }
+ ptr->lay_adjacency_lst = (XF86ConfAdjacencyPtr)
+ xf86addListItem ((glp) ptr->lay_adjacency_lst, (glp) aptr);
+ }
+ break;
+ case INPUTDEVICE:
+ {
+ XF86ConfInputrefPtr iptr;
+
+ iptr = calloc (1, sizeof (XF86ConfInputrefRec));
+ iptr->list.next = NULL;
+ iptr->iref_option_lst = NULL;
+ if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
+ free(iptr);
+ Error (INPUTDEV_MSG, NULL);
+ }
+ iptr->iref_inputdev_str = val.str;
+ while ((token = xf86getSubToken (&(ptr->lay_comment))) == STRING)
+ {
+ iptr->iref_option_lst =
+ xf86addNewOption (iptr->iref_option_lst, val.str, NULL);
+ }
+ xf86unGetToken (token);
+ ptr->lay_input_lst = (XF86ConfInputrefPtr)
+ xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
+ }
+ break;
+ case OPTION:
+ ptr->lay_option_lst = xf86parseOption(ptr->lay_option_lst);
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86tokenString ());
+ break;
+ }
+ }
+
+ if (!has_ident)
+ Error (NO_IDENT_MSG, NULL);
+
+#ifdef DEBUG
+ printf ("Layout section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+xf86printLayoutSection (FILE * cf, XF86ConfLayoutPtr ptr)
+{
+ XF86ConfAdjacencyPtr aptr;
+ XF86ConfInactivePtr iptr;
+ XF86ConfInputrefPtr inptr;
+ XF86OptionPtr optr;
+
+ while (ptr)
+ {
+ fprintf (cf, "Section \"ServerLayout\"\n");
+ if (ptr->lay_comment)
+ fprintf (cf, "%s", ptr->lay_comment);
+ if (ptr->lay_identifier)
+ fprintf (cf, "\tIdentifier \"%s\"\n", ptr->lay_identifier);
+
+ for (aptr = ptr->lay_adjacency_lst; aptr; aptr = aptr->list.next)
+ {
+ fprintf (cf, "\tScreen ");
+ if (aptr->adj_scrnum >= 0)
+ fprintf (cf, "%2d", aptr->adj_scrnum);
+ else
+ fprintf (cf, " ");
+ fprintf (cf, " \"%s\"", aptr->adj_screen_str);
+ switch(aptr->adj_where)
+ {
+ case CONF_ADJ_OBSOLETE:
+ fprintf (cf, " \"%s\"", aptr->adj_top_str);
+ fprintf (cf, " \"%s\"", aptr->adj_bottom_str);
+ fprintf (cf, " \"%s\"", aptr->adj_right_str);
+ fprintf (cf, " \"%s\"\n", aptr->adj_left_str);
+ break;
+ case CONF_ADJ_ABSOLUTE:
+ if (aptr->adj_x != -1)
+ fprintf (cf, " %d %d\n", aptr->adj_x, aptr->adj_y);
+ else
+ fprintf (cf, "\n");
+ break;
+ case CONF_ADJ_RIGHTOF:
+ fprintf (cf, " RightOf \"%s\"\n", aptr->adj_refscreen);
+ break;
+ case CONF_ADJ_LEFTOF:
+ fprintf (cf, " LeftOf \"%s\"\n", aptr->adj_refscreen);
+ break;
+ case CONF_ADJ_ABOVE:
+ fprintf (cf, " Above \"%s\"\n", aptr->adj_refscreen);
+ break;
+ case CONF_ADJ_BELOW:
+ fprintf (cf, " Below \"%s\"\n", aptr->adj_refscreen);
+ break;
+ case CONF_ADJ_RELATIVE:
+ fprintf (cf, " Relative \"%s\" %d %d\n", aptr->adj_refscreen,
+ aptr->adj_x, aptr->adj_y);
+ break;
+ }
+ }
+ for (iptr = ptr->lay_inactive_lst; iptr; iptr = iptr->list.next)
+ fprintf (cf, "\tInactive \"%s\"\n", iptr->inactive_device_str);
+ for (inptr = ptr->lay_input_lst; inptr; inptr = inptr->list.next)
+ {
+ fprintf (cf, "\tInputDevice \"%s\"", inptr->iref_inputdev_str);
+ for (optr = inptr->iref_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf(cf, " \"%s\"", optr->opt_name);
+ }
+ fprintf(cf, "\n");
+ }
+ xf86printOptionList(cf, ptr->lay_option_lst, 1);
+ fprintf (cf, "EndSection\n\n");
+ ptr = ptr->list.next;
+ }
+}
+
+static void
+xf86freeAdjacencyList (XF86ConfAdjacencyPtr ptr)
+{
+ XF86ConfAdjacencyPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->adj_screen_str);
+ TestFree (ptr->adj_top_str);
+ TestFree (ptr->adj_bottom_str);
+ TestFree (ptr->adj_left_str);
+ TestFree (ptr->adj_right_str);
+
+ prev = ptr;
+ ptr = ptr->list.next;
+ free (prev);
+ }
+
+}
+
+static void
+xf86freeInputrefList (XF86ConfInputrefPtr ptr)
+{
+ XF86ConfInputrefPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->iref_inputdev_str);
+ xf86optionListFree (ptr->iref_option_lst);
+ prev = ptr;
+ ptr = ptr->list.next;
+ free (prev);
+ }
+
+}
+
+void
+xf86freeLayoutList (XF86ConfLayoutPtr ptr)
+{
+ XF86ConfLayoutPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->lay_identifier);
+ TestFree (ptr->lay_comment);
+ xf86freeAdjacencyList (ptr->lay_adjacency_lst);
+ xf86freeInputrefList (ptr->lay_input_lst);
+ prev = ptr;
+ ptr = ptr->list.next;
+ free (prev);
+ }
+}
+
+int
+xf86layoutAddInputDevices(XF86ConfigPtr config, XF86ConfLayoutPtr layout)
+{
+ int count = 0;
+ XF86ConfInputPtr input = config->conf_input_lst;
+ XF86ConfInputrefPtr inptr;
+
+ /* add all AutoServerLayout devices to the server layout */
+ while (input)
+ {
+ if (xf86CheckBoolOption(input->inp_option_lst, "AutoServerLayout", FALSE))
+ {
+ XF86ConfInputrefPtr iref = layout->lay_input_lst;
+
+ /* avoid duplicates if referenced but lists AutoServerLayout too */
+ while (iref)
+ {
+ if (strcmp(iref->iref_inputdev_str, input->inp_identifier) == 0)
+ break;
+ iref = iref->list.next;
+ }
+
+ if (!iref)
+ {
+ XF86ConfInputrefPtr iptr;
+ iptr = calloc(1, sizeof(XF86ConfInputrefRec));
+ iptr->iref_inputdev_str = input->inp_identifier;
+ layout->lay_input_lst = (XF86ConfInputrefPtr)
+ xf86addListItem((glp)layout->lay_input_lst, (glp)iptr);
+ count++;
+ }
+ }
+ input = input->list.next;
+ }
+
+ inptr = layout->lay_input_lst;
+ while (inptr)
+ {
+ input = xf86findInput (inptr->iref_inputdev_str,
+ config->conf_input_lst);
+ if (!input)
+ {
+ xf86validationError (UNDEFINED_INPUT_MSG,
+ inptr->iref_inputdev_str, layout->lay_identifier);
+ return -1;
+ }
+ else
+ inptr->iref_inputdev = input;
+ inptr = inptr->list.next;
+ }
+
+ return count;
+}
+
+int
+xf86validateLayout (XF86ConfigPtr p)
+{
+ XF86ConfLayoutPtr layout = p->conf_layout_lst;
+ XF86ConfAdjacencyPtr adj;
+ XF86ConfInactivePtr iptr;
+ XF86ConfScreenPtr screen;
+ XF86ConfDevicePtr device;
+
+ while (layout)
+ {
+ adj = layout->lay_adjacency_lst;
+ while (adj)
+ {
+ /* the first one can't be "" but all others can */
+ screen = xf86findScreen (adj->adj_screen_str, p->conf_screen_lst);
+ if (!screen)
+ {
+ xf86validationError (UNDEFINED_SCREEN_MSG,
+ adj->adj_screen_str, layout->lay_identifier);
+ return FALSE;
+ }
+ else
+ adj->adj_screen = screen;
+
+ adj = adj->list.next;
+ }
+ iptr = layout->lay_inactive_lst;
+ while (iptr)
+ {
+ device = xf86findDevice (iptr->inactive_device_str,
+ p->conf_device_lst);
+ if (!device)
+ {
+ xf86validationError (UNDEFINED_DEVICE_LAY_MSG,
+ iptr->inactive_device_str, layout->lay_identifier);
+ return FALSE;
+ }
+ else
+ iptr->inactive_device = device;
+ iptr = iptr->list.next;
+ }
+
+ if (xf86layoutAddInputDevices(p, layout) == -1)
+ return FALSE;
+
+ layout = layout->list.next;
+ }
+ return TRUE;
+}
+
+XF86ConfLayoutPtr
+xf86findLayout (const char *name, XF86ConfLayoutPtr list)
+{
+ while (list)
+ {
+ if (xf86nameCompare (list->lay_identifier, name) == 0)
+ return list;
+ list = list->list.next;
+ }
+ return NULL;
+}
+
diff --git a/xorg-server/hw/xnest/Events.c b/xorg-server/hw/xnest/Events.c
index 2399313c6..619427ded 100644
--- a/xorg-server/hw/xnest/Events.c
+++ b/xorg-server/hw/xnest/Events.c
@@ -198,8 +198,6 @@ xnestCollectEvents(void)
case DestroyNotify:
if (xnestParentWindow != (Window) 0 &&
X.xdestroywindow.window == xnestParentWindow)
- CloseWellKnownConnections();
- OsCleanup(1);
exit (0);
break;
diff --git a/xorg-server/hw/xnest/Keyboard.c b/xorg-server/hw/xnest/Keyboard.c
index 9dba46ccd..5ef376b91 100644
--- a/xorg-server/hw/xnest/Keyboard.c
+++ b/xorg-server/hw/xnest/Keyboard.c
@@ -1,251 +1,268 @@
-/*
-
-Copyright 1993 by Davor Matic
-
-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. Davor Matic makes no representations about
-the suitability of this software for any purpose. It is provided "as
-is" without express or implied warranty.
-
-*/
-
-#ifdef HAVE_XNEST_CONFIG_H
-#include <xnest-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include "screenint.h"
-#include "inputstr.h"
-#include "misc.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-
-#include "Xnest.h"
-
-#include "Display.h"
-#include "Screen.h"
-#include "Keyboard.h"
-#include "Args.h"
-#include "Events.h"
-
-#include <X11/extensions/XKB.h>
-#include "xkbsrv.h"
-#include <X11/extensions/XKBconfig.h>
-
-extern Bool
-XkbQueryExtension(
- Display * /* dpy */,
- int * /* opcodeReturn */,
- int * /* eventBaseReturn */,
- int * /* errorBaseReturn */,
- int * /* majorRtrn */,
- int * /* minorRtrn */
-);
-
-extern XkbDescPtr XkbGetKeyboard(
- Display * /* dpy */,
- unsigned int /* which */,
- unsigned int /* deviceSpec */
-);
-
-extern Status XkbGetControls(
- Display * /* dpy */,
- unsigned long /* which */,
- XkbDescPtr /* desc */
-);
-
-DeviceIntPtr xnestKeyboardDevice = NULL;
-
-void
-xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
-{
- XBell(xnestDisplay, volume);
-}
-
-void
-DDXRingBell(int volume, int pitch, int duration)
-{
- XBell(xnestDisplay, volume);
-}
-
-void
-xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
-{
-#if 0
- unsigned long value_mask;
- XKeyboardControl values;
- int i;
-
- value_mask = KBKeyClickPercent |
- KBBellPercent |
- KBBellPitch |
- KBBellDuration |
- KBAutoRepeatMode;
-
- values.key_click_percent = ctrl->click;
- values.bell_percent = ctrl->bell;
- values.bell_pitch = ctrl->bell_pitch;
- values.bell_duration = ctrl->bell_duration;
- values.auto_repeat_mode = ctrl->autoRepeat ?
- AutoRepeatModeOn : AutoRepeatModeOff;
-
- XChangeKeyboardControl(xnestDisplay, value_mask, &values);
-
- /*
- value_mask = KBKey | KBAutoRepeatMode;
- At this point, we need to walk through the vector and compare it
- to the current server vector. If there are differences, report them.
- */
-
- value_mask = KBLed | KBLedMode;
- for (i = 1; i <= 32; i++) {
- values.led = i;
- values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
- XChangeKeyboardControl(xnestDisplay, value_mask, &values);
- }
-#endif
-}
-
-int
-xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
-{
- KeySym *keymap;
- int mapWidth;
- int min_keycode, max_keycode;
- KeySymsRec keySyms;
- int i;
- XKeyboardState values;
- XkbDescPtr xkb;
- int op, event, error, major, minor;
-
- switch (onoff)
- {
- case DEVICE_INIT:
- XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
-#ifdef _XSERVER64
- {
- KeySym64 *keymap64;
- int i, len;
- keymap64 = XGetKeyboardMapping(xnestDisplay,
- min_keycode,
- max_keycode - min_keycode + 1,
- &mapWidth);
- len = (max_keycode - min_keycode + 1) * mapWidth;
- keymap = (KeySym *)malloc(len * sizeof(KeySym));
- for(i = 0; i < len; ++i)
- keymap[i] = keymap64[i];
- XFree(keymap64);
- }
-#else
- keymap = XGetKeyboardMapping(xnestDisplay,
- min_keycode,
- max_keycode - min_keycode + 1,
- &mapWidth);
-#endif
-
- keySyms.minKeyCode = min_keycode;
- keySyms.maxKeyCode = max_keycode;
- keySyms.mapWidth = mapWidth;
- keySyms.map = keymap;
-
- if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
- ErrorF("Unable to initialize XKEYBOARD extension.\n");
- goto XkbError;
- }
- xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
- if (xkb == NULL || xkb->geom == NULL) {
- ErrorF("Couldn't get keyboard.\n");
- goto XkbError;
- }
- XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
-
- InitKeyboardDeviceStruct(pDev, NULL,
- xnestBell, xnestChangeKeyboardControl);
- XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
- XkbFreeKeyboard(xkb, 0, False);
- free(keymap);
- break;
- case DEVICE_ON:
- xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
- for (i = 0; i < xnestNumScreens; i++)
- XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
- break;
- case DEVICE_OFF:
- xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
- for (i = 0; i < xnestNumScreens; i++)
- XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
- break;
- case DEVICE_CLOSE:
- break;
- }
- return Success;
-
-XkbError:
- XGetKeyboardControl(xnestDisplay, &values);
- memmove((char *)defaultKeyboardControl.autoRepeats,
- (char *)values.auto_repeats,
- sizeof(values.auto_repeats));
-
- InitKeyboardDeviceStruct(pDev, NULL,
- xnestBell, xnestChangeKeyboardControl);
- free(keymap);
- return Success;
-}
-
-Bool
-LegalModifier(unsigned int key, DeviceIntPtr pDev)
-{
- return TRUE;
-}
-
-void
-xnestUpdateModifierState(unsigned int state)
-{
- DeviceIntPtr pDev = xnestKeyboardDevice;
- KeyClassPtr keyc = pDev->key;
- int i;
- CARD8 mask;
- int xkb_state;
-
- if (!pDev)
- return;
-
- xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
- state = state & 0xff;
-
- if (xkb_state == state)
- return;
-
- for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
- int key;
-
- /* Modifier is down, but shouldn't be
- */
- if ((xkb_state & mask) && !(state & mask)) {
- int count = keyc->modifierKeyCount[i];
-
- for (key = 0; key < MAP_LENGTH; key++)
- if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
- if (key_is_down(pDev, key, KEY_PROCESSED))
- xnestQueueKeyEvent(KeyRelease, key);
-
- if (--count == 0)
- break;
- }
- }
-
- /* Modifier shoud be down, but isn't
- */
- if (!(xkb_state & mask) && (state & mask))
- for (key = 0; key < MAP_LENGTH; key++)
- if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
- xnestQueueKeyEvent(KeyPress, key);
- break;
- }
- }
-}
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifdef HAVE_XNEST_CONFIG_H
+#include <xnest-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "screenint.h"
+#include "inputstr.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "Keyboard.h"
+#include "Args.h"
+#include "Events.h"
+
+#include <X11/extensions/XKB.h>
+#include "xkbsrv.h"
+#include <X11/extensions/XKBconfig.h>
+
+extern Bool
+XkbQueryExtension(
+ Display * /* dpy */,
+ int * /* opcodeReturn */,
+ int * /* eventBaseReturn */,
+ int * /* errorBaseReturn */,
+ int * /* majorRtrn */,
+ int * /* minorRtrn */
+);
+
+extern XkbDescPtr XkbGetKeyboard(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ unsigned int /* deviceSpec */
+);
+
+extern Status XkbGetControls(
+ Display * /* dpy */,
+ unsigned long /* which */,
+ XkbDescPtr /* desc */
+);
+
+DeviceIntPtr xnestKeyboardDevice = NULL;
+
+void
+xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
+{
+ XBell(xnestDisplay, volume);
+}
+
+void
+DDXRingBell(int volume, int pitch, int duration)
+{
+ XBell(xnestDisplay, volume);
+}
+
+void
+xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
+{
+#if 0
+ unsigned long value_mask;
+ XKeyboardControl values;
+ int i;
+
+ value_mask = KBKeyClickPercent |
+ KBBellPercent |
+ KBBellPitch |
+ KBBellDuration |
+ KBAutoRepeatMode;
+
+ values.key_click_percent = ctrl->click;
+ values.bell_percent = ctrl->bell;
+ values.bell_pitch = ctrl->bell_pitch;
+ values.bell_duration = ctrl->bell_duration;
+ values.auto_repeat_mode = ctrl->autoRepeat ?
+ AutoRepeatModeOn : AutoRepeatModeOff;
+
+ XChangeKeyboardControl(xnestDisplay, value_mask, &values);
+
+ /*
+ value_mask = KBKey | KBAutoRepeatMode;
+ At this point, we need to walk through the vector and compare it
+ to the current server vector. If there are differences, report them.
+ */
+
+ value_mask = KBLed | KBLedMode;
+ for (i = 1; i <= 32; i++) {
+ values.led = i;
+ values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
+ XChangeKeyboardControl(xnestDisplay, value_mask, &values);
+ }
+#endif
+}
+
+int
+xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
+{
+ XModifierKeymap *modifier_keymap;
+ KeySym *keymap;
+ int mapWidth;
+ int min_keycode, max_keycode;
+ KeySymsRec keySyms;
+ CARD8 modmap[MAP_LENGTH];
+ int i, j;
+ XKeyboardState values;
+ XkbDescPtr xkb;
+ int op, event, error, major, minor;
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+ XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
+#ifdef _XSERVER64
+ {
+ KeySym64 *keymap64;
+ int len;
+ keymap64 = XGetKeyboardMapping(xnestDisplay,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &mapWidth);
+ len = (max_keycode - min_keycode + 1) * mapWidth;
+ keymap = (KeySym *)malloc(len * sizeof(KeySym));
+ for(i = 0; i < len; ++i)
+ keymap[i] = keymap64[i];
+ XFree(keymap64);
+ }
+#else
+ keymap = XGetKeyboardMapping(xnestDisplay,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &mapWidth);
+#endif
+
+ memset(modmap, 0, sizeof(modmap));
+ modifier_keymap = XGetModifierMapping(xnestDisplay);
+ for (j = 0; j < 8; j++)
+ for(i = 0; i < modifier_keymap->max_keypermod; i++) {
+ CARD8 keycode;
+ if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i]))
+ modmap[keycode] |= 1<<j;
+ }
+ XFreeModifiermap(modifier_keymap);
+
+ keySyms.minKeyCode = min_keycode;
+ keySyms.maxKeyCode = max_keycode;
+ keySyms.mapWidth = mapWidth;
+ keySyms.map = keymap;
+
+ if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
+ ErrorF("Unable to initialize XKEYBOARD extension.\n");
+ goto XkbError;
+ }
+ xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
+ if (xkb == NULL || xkb->geom == NULL) {
+ ErrorF("Couldn't get keyboard.\n");
+ goto XkbError;
+ }
+ XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
+
+ InitKeyboardDeviceStruct(pDev, NULL,
+ xnestBell, xnestChangeKeyboardControl);
+
+ XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
+ keySyms.maxKeyCode - keySyms.minKeyCode + 1,
+ modmap, serverClient);
+
+ XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
+ XkbFreeKeyboard(xkb, 0, False);
+ free(keymap);
+ break;
+ case DEVICE_ON:
+ xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
+ for (i = 0; i < xnestNumScreens; i++)
+ XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
+ break;
+ case DEVICE_OFF:
+ xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
+ for (i = 0; i < xnestNumScreens; i++)
+ XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
+ break;
+ case DEVICE_CLOSE:
+ break;
+ }
+ return Success;
+
+XkbError:
+ XGetKeyboardControl(xnestDisplay, &values);
+ memmove((char *)defaultKeyboardControl.autoRepeats,
+ (char *)values.auto_repeats,
+ sizeof(values.auto_repeats));
+
+ InitKeyboardDeviceStruct(pDev, NULL,
+ xnestBell, xnestChangeKeyboardControl);
+ free(keymap);
+ return Success;
+}
+
+Bool
+LegalModifier(unsigned int key, DeviceIntPtr pDev)
+{
+ return TRUE;
+}
+
+void
+xnestUpdateModifierState(unsigned int state)
+{
+ DeviceIntPtr pDev = xnestKeyboardDevice;
+ KeyClassPtr keyc = pDev->key;
+ int i;
+ CARD8 mask;
+ int xkb_state;
+
+ if (!pDev)
+ return;
+
+ xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
+ state = state & 0xff;
+
+ if (xkb_state == state)
+ return;
+
+ for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
+ int key;
+
+ /* Modifier is down, but shouldn't be
+ */
+ if ((xkb_state & mask) && !(state & mask)) {
+ int count = keyc->modifierKeyCount[i];
+
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
+ if (key_is_down(pDev, key, KEY_PROCESSED))
+ xnestQueueKeyEvent(KeyRelease, key);
+
+ if (--count == 0)
+ break;
+ }
+ }
+
+ /* Modifier shoud be down, but isn't
+ */
+ if (!(xkb_state & mask) && (state & mask))
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
+ xnestQueueKeyEvent(KeyPress, key);
+ break;
+ }
+ }
+}
diff --git a/xorg-server/hw/xquartz/darwin.c b/xorg-server/hw/xquartz/darwin.c
index b483000f8..465a96d12 100644
--- a/xorg-server/hw/xquartz/darwin.c
+++ b/xorg-server/hw/xquartz/darwin.c
@@ -621,7 +621,7 @@ void OsVendorInit(void)
char *lf;
char *home = getenv("HOME");
assert(home);
- assert(0 < asprintf(&lf, "%s/Library/Logs/X11.%s.log", home, bundle_id_prefix));
+ assert(0 < asprintf(&lf, "%s/Library/Logs/%s.X11.log", home, bundle_id_prefix));
LogInit(lf, ".old");
free(lf);
diff --git a/xorg-server/hw/xquartz/xpr/appledri.c b/xorg-server/hw/xquartz/xpr/appledri.c
index 1304d5a43..6b4a8a383 100644
--- a/xorg-server/hw/xquartz/xpr/appledri.c
+++ b/xorg-server/hw/xquartz/xpr/appledri.c
@@ -2,7 +2,7 @@
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc.
-Copyright (c) 2002, 2009 Apple Computer, Inc.
+Copyright (c) 2002, 2009-2011 Apple Inc.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -102,6 +102,9 @@ ProcAppleDRIQueryVersion(
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
+ swaps(&rep.majorVersion);
+ swaps(&rep.minorVersion);
+ swapl(&rep.patchVersion);
}
WriteToClient(client, sizeof(xAppleDRIQueryVersionReply), (char *)&rep);
return Success;
@@ -133,6 +136,11 @@ ProcAppleDRIQueryDirectRenderingCapable(
if (!LocalClient(client))
rep.isCapable = 0;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ }
+
WriteToClient(client,
sizeof(xAppleDRIQueryDirectRenderingCapableReply), (char *)&rep);
return Success;
@@ -157,6 +165,13 @@ ProcAppleDRIAuthConnection(
ErrorF("Failed to authenticate %u\n", (unsigned int)stuff->magic);
rep.authenticated = 0;
}
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.authenticated); /* Yes, this is a CARD32 ... sigh */
+ }
+
WriteToClient(client, sizeof(xAppleDRIAuthConnectionReply), (char *)&rep);
return Success;
}
@@ -216,6 +231,14 @@ ProcAppleDRICreateSurface(
rep.key_1 = key[1];
rep.uid = sid;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.key_0);
+ swapl(&rep.key_1);
+ swapl(&rep.uid);
+ }
+
WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep);
return Success;
}
@@ -277,9 +300,8 @@ ProcAppleDRICreatePixmap(ClientPtr client)
rep.stringLength = strlen(path) + 1;
- /* No need for swapping, because this only runs if LocalClient is true. */
rep.type = X_Reply;
- rep.length = sizeof(rep) + rep.stringLength;
+ rep.length = bytes_to_int32(rep.stringLength);
rep.sequenceNumber = client->sequence;
rep.width = width;
rep.height = height;
@@ -290,8 +312,19 @@ ProcAppleDRICreatePixmap(ClientPtr client)
if(sizeof(rep) != sz_xAppleDRICreatePixmapReply)
ErrorF("error sizeof(rep) is %zu\n", sizeof(rep));
- WriteReplyToClient(client, sizeof(rep), &rep);
- (void)WriteToClient(client, rep.stringLength, path);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.stringLength);
+ swapl(&rep.width);
+ swapl(&rep.height);
+ swapl(&rep.pitch);
+ swapl(&rep.bpp);
+ swapl(&rep.size);
+ }
+
+ WriteToClient(client, sizeof(rep), &rep);
+ WriteToClient(client, rep.stringLength, path);
return Success;
}
@@ -377,21 +410,107 @@ SProcAppleDRIQueryVersion(
}
static int
+SProcAppleDRIQueryDirectRenderingCapable(
+ register ClientPtr client
+)
+{
+ REQUEST(xAppleDRIQueryDirectRenderingCapableReq);
+ swaps(&stuff->length);
+ swapl(&stuff->screen);
+ return ProcAppleDRIQueryDirectRenderingCapable(client);
+}
+
+static int
+SProcAppleDRIAuthConnection(
+ register ClientPtr client
+)
+{
+ REQUEST(xAppleDRIAuthConnectionReq);
+ swaps(&stuff->length);
+ swapl(&stuff->screen);
+ swapl(&stuff->magic);
+ return ProcAppleDRIAuthConnection(client);
+}
+
+static int
+SProcAppleDRICreateSurface(
+ register ClientPtr client
+)
+{
+ REQUEST(xAppleDRICreateSurfaceReq);
+ swaps(&stuff->length);
+ swapl(&stuff->screen);
+ swapl(&stuff->drawable);
+ swapl(&stuff->client_id);
+ return ProcAppleDRICreateSurface(client);
+}
+
+static int
+SProcAppleDRIDestroySurface(
+ register ClientPtr client
+)
+{
+ REQUEST(xAppleDRIDestroySurfaceReq);
+ swaps(&stuff->length);
+ swapl(&stuff->screen);
+ swapl(&stuff->drawable);
+ return ProcAppleDRIDestroySurface(client);
+}
+
+static int
+SProcAppleDRICreatePixmap(
+ register ClientPtr client
+)
+{
+ REQUEST(xAppleDRICreatePixmapReq);
+ swaps(&stuff->length);
+ swapl(&stuff->screen);
+ swapl(&stuff->drawable);
+ return ProcAppleDRICreatePixmap(client);
+}
+
+static int
+SProcAppleDRIDestroyPixmap(
+ register ClientPtr client
+)
+{
+ REQUEST(xAppleDRIDestroyPixmapReq);
+ swaps(&stuff->length);
+ swapl(&stuff->drawable);
+ return ProcAppleDRIDestroyPixmap(client);
+}
+
+static int
SProcAppleDRIDispatch (
register ClientPtr client
)
{
REQUEST(xReq);
- /* It is bound to be non-local when there is byte swapping */
+ switch (stuff->data)
+ {
+ case X_AppleDRIQueryVersion:
+ return SProcAppleDRIQueryVersion(client);
+ case X_AppleDRIQueryDirectRenderingCapable:
+ return SProcAppleDRIQueryDirectRenderingCapable(client);
+ }
+
if (!LocalClient(client))
return DRIErrorBase + AppleDRIClientNotLocal;
- /* only local clients are allowed DRI access */
switch (stuff->data)
{
- case X_AppleDRIQueryVersion:
- return SProcAppleDRIQueryVersion(client);
+ case X_AppleDRIAuthConnection:
+ return SProcAppleDRIAuthConnection(client);
+ case X_AppleDRICreateSurface:
+ return SProcAppleDRICreateSurface(client);
+ case X_AppleDRIDestroySurface:
+ return SProcAppleDRIDestroySurface(client);
+ case X_AppleDRICreatePixmap:
+ return SProcAppleDRICreatePixmap(client);
+ case X_AppleDRIDestroyPixmap:
+ return SProcAppleDRIDestroyPixmap(client);
+
default:
return BadRequest;
}
diff --git a/xorg-server/hw/xquartz/xpr/appledristr.h b/xorg-server/hw/xquartz/xpr/appledristr.h
index c569719b7..b5ffe5b46 100644
--- a/xorg-server/hw/xquartz/xpr/appledristr.h
+++ b/xorg-server/hw/xquartz/xpr/appledristr.h
@@ -42,209 +42,225 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define APPLEDRINAME "Apple-DRI"
-#define APPLE_DRI_MAJOR_VERSION 1 /* current version numbers */
+#define APPLE_DRI_MAJOR_VERSION 1 /* current version numbers */
#define APPLE_DRI_MINOR_VERSION 0
#define APPLE_DRI_PATCH_VERSION 0
-typedef struct _AppleDRIQueryVersion {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIQueryVersion */
- CARD16 length B16;
+typedef struct _AppleDRIQueryVersion
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRIQueryVersion */
+ CARD16 length B16;
} xAppleDRIQueryVersionReq;
#define sz_xAppleDRIQueryVersionReq 4
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD16 majorVersion B16; /* major version of DRI protocol */
- CARD16 minorVersion B16; /* minor version of DRI protocol */
- CARD32 patchVersion B32; /* patch version of DRI protocol */
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 majorVersion B16; /* major version of DRI protocol */
+ CARD16 minorVersion B16; /* minor version of DRI protocol */
+ CARD32 patchVersion B32; /* patch version of DRI protocol */
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
} xAppleDRIQueryVersionReply;
#define sz_xAppleDRIQueryVersionReply 32
-typedef struct _AppleDRIQueryDirectRenderingCapable {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */
- CARD16 length B16;
- CARD32 screen B32;
+typedef struct _AppleDRIQueryDirectRenderingCapable
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */
+ CARD16 length B16;
+ CARD32 screen B32;
} xAppleDRIQueryDirectRenderingCapableReq;
#define sz_xAppleDRIQueryDirectRenderingCapableReq 8
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- BOOL isCapable;
- BOOL pad2;
- BOOL pad3;
- BOOL pad4;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
- CARD32 pad7 B32;
- CARD32 pad8 B32;
- CARD32 pad9 B32;
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ BOOL isCapable;
+ BOOL pad2;
+ BOOL pad3;
+ BOOL pad4;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+ CARD32 pad7 B32;
+ CARD32 pad8 B32;
+ CARD32 pad9 B32;
} xAppleDRIQueryDirectRenderingCapableReply;
#define sz_xAppleDRIQueryDirectRenderingCapableReply 32
-typedef struct _AppleDRIAuthConnection {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICloseConnection */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 magic B32;
+typedef struct _AppleDRIAuthConnection
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRICloseConnection */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 magic B32;
} xAppleDRIAuthConnectionReq;
#define sz_xAppleDRIAuthConnectionReq 12
-typedef struct {
- BYTE type;
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 authenticated B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
+typedef struct
+{
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 authenticated B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
} xAppleDRIAuthConnectionReply;
#define zx_xAppleDRIAuthConnectionReply 32
-typedef struct _AppleDRICreateSurface {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICreateSurface */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
- CARD32 client_id B32;
+typedef struct _AppleDRICreateSurface
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRICreateSurface */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 drawable B32;
+ CARD32 client_id B32;
} xAppleDRICreateSurfaceReq;
#define sz_xAppleDRICreateSurfaceReq 16
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 key_0 B32;
- CARD32 key_1 B32;
- CARD32 uid B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 key_0 B32;
+ CARD32 key_1 B32;
+ CARD32 uid B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
} xAppleDRICreateSurfaceReply;
#define sz_xAppleDRICreateSurfaceReply 32
-typedef struct _AppleDRIDestroySurface {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIDestroySurface */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
+typedef struct _AppleDRIDestroySurface
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRIDestroySurface */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 drawable B32;
} xAppleDRIDestroySurfaceReq;
#define sz_xAppleDRIDestroySurfaceReq 12
-typedef struct _AppleDRINotify {
- BYTE type; /* always eventBase + event type */
- BYTE kind;
- CARD16 sequenceNumber B16;
- CARD32 time B32; /* time of change */
- CARD32 pad1 B32;
- CARD32 arg B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
+typedef struct _AppleDRINotify
+{
+ BYTE type; /* always eventBase + event type */
+ BYTE kind;
+ CARD16 sequenceNumber B16;
+ CARD32 time B32; /* time of change */
+ CARD32 pad1 B32;
+ CARD32 arg B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
} xAppleDRINotifyEvent;
#define sz_xAppleDRINotifyEvent 32
-typedef struct {
- CARD8 reqType;
- CARD8 driReqType;
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
- BOOL doubleSwap;
- CARD8 pad1, pad2, pad3;
+typedef struct
+{
+ CARD8 reqType;
+ CARD8 driReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 drawable B32;
+ BOOL doubleSwap;
+ CARD8 pad1, pad2, pad3;
} xAppleDRICreateSharedBufferReq;
#define sz_xAppleDRICreateSharedBufferReq 16
-typedef struct {
- BYTE type;
- BYTE data1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 stringLength B32; /* 0 on error */
- CARD32 width B32;
- CARD32 height B32;
- CARD32 pad1 B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
+typedef struct
+{
+ BYTE type;
+ BYTE data1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 stringLength B32; /* 0 on error */
+ CARD32 width B32;
+ CARD32 height B32;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
} xAppleDRICreateSharedBufferReply;
#define sz_xAppleDRICreateSharedBufferReply 32
-typedef struct {
- CARD8 reqType;
- CARD8 driReqType;
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
+typedef struct
+{
+ CARD8 reqType;
+ CARD8 driReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 drawable B32;
} xAppleDRISwapBuffersReq;
#define sz_xAppleDRISwapBuffersReq 12
-typedef struct {
- CARD8 reqType; /*1*/
- CARD8 driReqType; /*2*/
- CARD16 length B16; /*4*/
- CARD32 screen B32; /*8*/
- CARD32 drawable B32; /*12*/
+typedef struct
+{
+ CARD8 reqType; /*1 */
+ CARD8 driReqType; /*2 */
+ CARD16 length B16; /*4 */
+ CARD32 screen B32; /*8 */
+ CARD32 drawable B32; /*12 */
} xAppleDRICreatePixmapReq;
#define sz_xAppleDRICreatePixmapReq 12
-typedef struct {
- BYTE type; /*1*/
- BOOL pad1; /*2*/
- CARD16 sequenceNumber B16; /*4*/
- CARD32 length B32; /*8*/
- CARD32 width B32; /*12*/
- CARD32 height B32; /*16*/
- CARD32 pitch B32; /*20*/
- CARD32 bpp B32; /*24*/
- CARD32 size B32; /*28*/
- CARD32 stringLength B32; /*32*/
+typedef struct
+{
+ BYTE type; /*1 */
+ BOOL pad1; /*2 */
+ CARD16 sequenceNumber B16; /*4 */
+ CARD32 length B32; /*8 */
+ CARD32 width B32; /*12 */
+ CARD32 height B32; /*16 */
+ CARD32 pitch B32; /*20 */
+ CARD32 bpp B32; /*24 */
+ CARD32 size B32; /*28 */
+ CARD32 stringLength B32; /*32 */
} xAppleDRICreatePixmapReply;
#define sz_xAppleDRICreatePixmapReply 32
-typedef struct {
- CARD8 reqType; /*1*/
- CARD8 driReqType; /*2*/
- CARD16 length B16; /*4*/
- CARD32 drawable B32; /*8*/
+typedef struct
+{
+ CARD8 reqType; /*1 */
+ CARD8 driReqType; /*2 */
+ CARD16 length B16; /*4 */
+ CARD32 drawable B32; /*8 */
} xAppleDRIDestroyPixmapReq;
#define sz_xAppleDRIDestroyPixmapReq 8
#ifdef _APPLEDRI_SERVER_
-void AppleDRISendEvent (
+void AppleDRISendEvent(
#if NeedFunctionPrototypes
- int /* type */,
- unsigned int /* mask */,
- int /* which */,
- int /* arg */
+ int /* type */ ,
+ unsigned int /* mask */ ,
+ int /* which */ ,
+ int /* arg */
#endif
-);
+ );
#endif /* _APPLEDRI_SERVER_ */
#endif /* _APPLEDRISTR_H_ */
diff --git a/xorg-server/hw/xwin/man/XWinrc.man b/xorg-server/hw/xwin/man/XWinrc.man
index e4c454fba..71d8dad23 100644
--- a/xorg-server/hw/xwin/man/XWinrc.man
+++ b/xorg-server/hw/xwin/man/XWinrc.man
@@ -88,15 +88,15 @@ this may be useful if you want no dialogs.
This instruction defines a menu and asigns a \fIMenu_Name\fP to it.
\fIMenu_Item_Line\fP are lines of any of the following types:
.TP 8
-.B \t SEPARATOR
+.B SEPARATOR
.TP 8
-.B \t \fIItem_Label\fP EXEC \fICommand\fP
+.B \fIItem_Label\fP EXEC \fICommand\fP
.TP 8
-.B \t \fIItem_Label\fP MENU \fIpreviously-defined-menu-name\fP
+.B \fIItem_Label\fP MENU \fIpreviously-defined-menu-name\fP
.TP 8
-.B \t \fIItem_Label\fP ALWAYSONTOP
+.B \fIItem_Label\fP ALWAYSONTOP
.TP 8
-.B \t \fIItem_Label\fP RELOAD
+.B \fIItem_Label\fP RELOAD
.br
The \fIItem_Label\fP is the string that is written in the menu item.
.br
diff --git a/xorg-server/include/eventstr.h b/xorg-server/include/eventstr.h
index 2de077fd2..4d836fb14 100644
--- a/xorg-server/include/eventstr.h
+++ b/xorg-server/include/eventstr.h
@@ -153,6 +153,7 @@ struct _DeviceChangedEvent
uint32_t resolution; /**< Resolution counts/m */
uint8_t mode; /**< Relative or Absolute */
Atom name; /**< Axis name */
+ ScrollInfo scroll; /**< Smooth scrolling info */
} valuators[MAX_VALUATORS];
struct {
diff --git a/xorg-server/include/exevents.h b/xorg-server/include/exevents.h
index 4fe6c61a9..720fb2e5a 100644
--- a/xorg-server/include/exevents.h
+++ b/xorg-server/include/exevents.h
@@ -322,8 +322,7 @@ extern int
XIShouldNotify(ClientPtr client, DeviceIntPtr dev);
extern void
-XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master,
- DeviceChangedEvent *dce);
+XISendDeviceChangedEvent(DeviceIntPtr device, DeviceChangedEvent *dce);
extern int
XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h
index b7de5ca3d..4eee47ce4 100644
--- a/xorg-server/include/input.h
+++ b/xorg-server/include/input.h
@@ -427,7 +427,8 @@ extern _X_EXPORT void FreeEventList(InternalEvent *list, int num_events);
extern void CreateClassesChangedEvent(InternalEvent *event,
DeviceIntPtr master,
DeviceIntPtr slave,
- int type);
+ int flags);
+
extern InternalEvent * UpdateFromMaster(
InternalEvent *events,
DeviceIntPtr pDev,
@@ -597,6 +598,10 @@ extern _X_EXPORT void valuator_mask_copy(ValuatorMask *dest,
extern _X_EXPORT int valuator_mask_get(const ValuatorMask *mask, int valnum);
extern _X_EXPORT double valuator_mask_get_double(const ValuatorMask *mask,
int valnum);
+extern _X_EXPORT Bool valuator_mask_fetch(const ValuatorMask *mask,
+ int valnum, int *val);
+extern _X_EXPORT Bool valuator_mask_fetch_double(const ValuatorMask *mask,
+ int valnum, double *val);
/* InputOption handling interface */
extern _X_EXPORT InputOption* input_option_new(InputOption *list, const char *key, const char *value);
diff --git a/xorg-server/include/inputstr.h b/xorg-server/include/inputstr.h
index 9d4108ef5..7a1554075 100644
--- a/xorg-server/include/inputstr.h
+++ b/xorg-server/include/inputstr.h
@@ -621,11 +621,4 @@ static inline WindowPtr DeepestSpriteWin(SpritePtr sprite)
return sprite->spriteTrace[sprite->spriteTraceGood - 1];
}
-struct _InputOption {
- char *key;
- char *value;
- struct _InputOption *next;
-};
-
-
#endif /* INPUTSTRUCT_H */
diff --git a/xorg-server/include/list.h b/xorg-server/include/list.h
index 7825dce52..4706e178b 100644
--- a/xorg-server/include/list.h
+++ b/xorg-server/include/list.h
@@ -438,4 +438,16 @@ list_is_empty(struct list *head)
nt_list_init(__e, _member); \
} while(0)
+/**
+ * DO NOT USE THIS.
+ * This is a remainder of the xfree86 DDX attempt of having a set of generic
+ * list functions. Unfortunately, the xf86OptionRec uses it and we can't
+ * easily get rid of it. Do not use for new code.
+ */
+typedef struct generic_list_rec
+{
+ void *next;
+}
+GenericListRec, *GenericListPtr, *glp;
+
#endif
diff --git a/xorg-server/include/optionstr.h b/xorg-server/include/optionstr.h
new file mode 100644
index 000000000..a71d245fa
--- /dev/null
+++ b/xorg-server/include/optionstr.h
@@ -0,0 +1,14 @@
+#ifndef OPTIONSTR_H_
+#define OPTIONSTR_H_
+#include "list.h"
+
+
+struct _InputOption {
+ GenericListRec list;
+ char *opt_name;
+ char *opt_val;
+ int opt_used;
+ char *opt_comment;
+};
+
+#endif /* INPUTSTRUCT_H */
diff --git a/xorg-server/man/Xserver.man b/xorg-server/man/Xserver.man
index 02cca5263..0cd9b941c 100644
--- a/xorg-server/man/Xserver.man
+++ b/xorg-server/man/Xserver.man
@@ -100,6 +100,12 @@ specifies a file which contains a collection of authorization records used
to authenticate access. See also the \fIxdm\fP(1) and
\fIXsecurity\fP(__miscmansuffix__) manual pages.
.TP 8
+.BI \-background\ none
+Asks the driver not to clear the background on startup, if the driver supports that.
+May be useful for smooth transition with eg. fbdev driver.
+For security reasons this is not the default as the screen contents might
+show a previous user session.
+.TP 8
.B \-br
sets the default root window to solid black instead of the standard root weave
pattern. This is the default unless -retro or -wr is specified.
diff --git a/xorg-server/mi/mieq.c b/xorg-server/mi/mieq.c
index 7cc0e7c51..3d51a567b 100644
--- a/xorg-server/mi/mieq.c
+++ b/xorg-server/mi/mieq.c
@@ -59,7 +59,12 @@ in this Software without prior written authorization from The Open Group.
# include <X11/extensions/dpmsconst.h>
#endif
-#define QUEUE_SIZE 512
+/* Maximum size should be initial size multiplied by a power of 2 */
+#define QUEUE_INITIAL_SIZE 256
+#define QUEUE_RESERVED_SIZE 64
+#define QUEUE_MAXIMUM_SIZE 4096
+#define QUEUE_DROP_BACKTRACE_FREQUENCY 100
+#define QUEUE_DROP_BACKTRACE_MAX 10
#define EnqueueScreen(dev) dev->spriteInfo->sprite->pEnqueueScreen
#define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen
@@ -74,7 +79,9 @@ typedef struct _EventQueue {
HWEventQueueType head, tail; /* long for SetInputCheck */
CARD32 lastEventTime; /* to avoid time running backwards */
int lastMotion; /* device ID if last event motion? */
- EventRec events[QUEUE_SIZE]; /* static allocation for signals */
+ EventRec *events; /* our queue as an array */
+ size_t nevents; /* the number of buckets in our queue */
+ size_t dropped; /* counter for number of consecutive dropped events */
mieqHandler handlers[128]; /* custom event handler */
} EventQueueRec, *EventQueuePtr;
@@ -99,25 +106,87 @@ static inline void wait_for_server_init(void) {
}
#endif
+static size_t
+mieqNumEnqueued(EventQueuePtr eventQueue) {
+ size_t n_enqueued = 0;
+ if (eventQueue->nevents) {
+ /* % is not well-defined with negative numbers... sigh */
+ n_enqueued = eventQueue->tail - eventQueue->head + eventQueue->nevents;
+ if (n_enqueued >= eventQueue->nevents)
+ n_enqueued -= eventQueue->nevents;
+ }
+ return n_enqueued;
+}
+
+/* Pre-condition: Called with miEventQueueMutex held */
+static Bool
+mieqGrowQueue(EventQueuePtr eventQueue, size_t new_nevents) {
+ size_t i, n_enqueued, first_hunk;
+ EventRec *new_events;
+
+ if (!eventQueue) {
+ ErrorF("[mi] mieqGrowQueue called with a NULL eventQueue\n");
+ return FALSE;
+ }
+
+ if (new_nevents <= eventQueue->nevents)
+ return FALSE;
+
+ new_events = calloc(new_nevents, sizeof(EventRec));
+ if (new_events == NULL) {
+ ErrorF("[mi] mieqGrowQueue memory allocation error.\n");
+ return FALSE;
+ }
+
+ n_enqueued = mieqNumEnqueued(eventQueue);
+
+ /* We block signals, so an mieqEnqueue triggered by SIGIO does not
+ * write to our queue as we are modifying it.
+ */
+ OsBlockSignals();
+
+ /* First copy the existing events */
+ first_hunk = eventQueue->nevents - eventQueue->head;
+ memcpy(new_events,
+ &eventQueue->events[eventQueue->head],
+ first_hunk * sizeof(EventRec));
+ memcpy(&new_events[first_hunk],
+ eventQueue->events,
+ eventQueue->head * sizeof(EventRec));
+
+ /* Initialize the new portion */
+ for (i = eventQueue->nevents; i < new_nevents; i++) {
+ InternalEvent* evlist = InitEventList(1);
+ if (!evlist) {
+ size_t j;
+ for (j = 0; j < i; j++)
+ FreeEventList(new_events[j].events, 1);
+ free(new_events);
+ OsReleaseSignals();
+ return FALSE;
+ }
+ new_events[i].events = evlist;
+ }
+
+ /* And update our record */
+ eventQueue->tail = n_enqueued;
+ eventQueue->head = 0;
+ eventQueue->nevents = new_nevents;
+ free(eventQueue->events);
+ eventQueue->events = new_events;
+
+ OsReleaseSignals();
+ return TRUE;
+}
+
Bool
mieqInit(void)
{
- int i;
-
- miEventQueue.head = miEventQueue.tail = 0;
+ memset(&miEventQueue, 0, sizeof(miEventQueue));
miEventQueue.lastEventTime = GetTimeInMillis ();
- miEventQueue.lastMotion = FALSE;
- for (i = 0; i < 128; i++)
- miEventQueue.handlers[i] = NULL;
- for (i = 0; i < QUEUE_SIZE; i++)
- {
- if (miEventQueue.events[i].events == NULL) {
- InternalEvent* evlist = InitEventList(1);
- if (!evlist)
- FatalError("Could not allocate event queue.\n");
- miEventQueue.events[i].events = evlist;
- }
- }
+
+ if(!mieqGrowQueue(&miEventQueue, QUEUE_INITIAL_SIZE))
+ FatalError("Could not allocate event queue.\n");
SetInputCheck(&miEventQueue.head, &miEventQueue.tail);
return TRUE;
@@ -127,13 +196,34 @@ void
mieqFini(void)
{
int i;
- for (i = 0; i < QUEUE_SIZE; i++)
+ for (i = 0; i < miEventQueue.nevents; i++)
{
if (miEventQueue.events[i].events != NULL) {
FreeEventList(miEventQueue.events[i].events, 1);
miEventQueue.events[i].events = NULL;
}
}
+ free(miEventQueue.events);
+}
+
+/* This function will determine if the given event is allowed to used the reserved
+ * queue space.
+ */
+static Bool
+mieqReservedCandidate(InternalEvent *e) {
+ switch(e->any.type) {
+ case ET_KeyRelease:
+ case ET_ButtonRelease:
+#if XFreeXDGA
+ case ET_DGAEvent:
+#endif
+ case ET_RawKeyRelease:
+ case ET_RawButtonRelease:
+ case ET_XQuartz:
+ return TRUE;
+ default:
+ return FALSE;
+ }
}
/*
@@ -151,6 +241,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
int isMotion = 0;
int evlen;
Time time;
+ size_t n_enqueued;
#ifdef XQUARTZ
wait_for_server_init();
@@ -159,32 +250,40 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
verify_internal_event(e);
+ n_enqueued = mieqNumEnqueued(&miEventQueue);
+
/* avoid merging events from different devices */
if (e->any.type == ET_Motion)
isMotion = pDev->id;
if (isMotion && isMotion == miEventQueue.lastMotion &&
oldtail != miEventQueue.head) {
- oldtail = (oldtail - 1) % QUEUE_SIZE;
- }
- else {
- static int stuck = 0;
+ oldtail = (oldtail - 1) % miEventQueue.nevents;
+ } else if ((n_enqueued + 1 == miEventQueue.nevents) ||
+ ((n_enqueued + 1 >= miEventQueue.nevents - QUEUE_RESERVED_SIZE) && !mieqReservedCandidate(e))) {
/* Toss events which come in late. Usually this means your server's
* stuck in an infinite loop somewhere, but SIGIO is still getting
- * handled. */
- if (((oldtail + 1) % QUEUE_SIZE) == miEventQueue.head) {
- if (!stuck) {
- ErrorF("[mi] EQ overflowing. The server is probably stuck "
- "in an infinite loop.\n");
- xorg_backtrace();
- stuck = 1;
+ * handled.
+ */
+ miEventQueue.dropped++;
+ if (miEventQueue.dropped == 1) {
+ ErrorF("[mi] EQ overflowing. Additional events will be discarded until existing events are processed.\n");
+ xorg_backtrace();
+ ErrorF("[mi] These backtraces from mieqEnqueue may point to a culprit higher up the stack.\n");
+ ErrorF("[mi] mieq is *NOT* the cause. It is a victim.\n");
+ } else if (miEventQueue.dropped % QUEUE_DROP_BACKTRACE_FREQUENCY == 0 &&
+ miEventQueue.dropped / QUEUE_DROP_BACKTRACE_FREQUENCY <= QUEUE_DROP_BACKTRACE_MAX) {
+ ErrorF("[mi] EQ overflow continuing. %lu events have been dropped.\n", miEventQueue.dropped);
+ if (miEventQueue.dropped / QUEUE_DROP_BACKTRACE_FREQUENCY == QUEUE_DROP_BACKTRACE_MAX) {
+ ErrorF("[mi] No further overflow reports will be reported until the clog is cleared.\n");
}
+ xorg_backtrace();
+ }
+
#ifdef XQUARTZ
- pthread_mutex_unlock(&miEventQueueMutex);
+ pthread_mutex_unlock(&miEventQueueMutex);
#endif
- return;
- }
- stuck = 0;
+ return;
}
evlen = e->any.length;
@@ -203,7 +302,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
miEventQueue.events[oldtail].pDev = pDev;
miEventQueue.lastMotion = isMotion;
- miEventQueue.tail = (oldtail + 1) % QUEUE_SIZE;
+ miEventQueue.tail = (oldtail + 1) % miEventQueue.nevents;
#ifdef XQUARTZ
pthread_mutex_unlock(&miEventQueueMutex);
#endif
@@ -437,11 +536,28 @@ mieqProcessInputEvents(void)
static InternalEvent event;
DeviceIntPtr dev = NULL,
master = NULL;
+ size_t n_enqueued;
#ifdef XQUARTZ
pthread_mutex_lock(&miEventQueueMutex);
#endif
-
+
+ /* Grow our queue if we are reaching capacity: < 2 * QUEUE_RESERVED_SIZE remaining */
+ n_enqueued = mieqNumEnqueued(&miEventQueue);
+ if (n_enqueued >= (miEventQueue.nevents - (2 * QUEUE_RESERVED_SIZE)) &&
+ miEventQueue.nevents < QUEUE_MAXIMUM_SIZE) {
+ ErrorF("[mi] Increasing EQ size to %lu to prevent dropped events.\n", miEventQueue.nevents << 1);
+ if (!mieqGrowQueue(&miEventQueue, miEventQueue.nevents << 1)) {
+ ErrorF("[mi] Increasing the size of EQ failed.\n");
+ }
+ }
+
+ if (miEventQueue.dropped) {
+ ErrorF("[mi] EQ processing has resumed after %lu dropped events.\n", miEventQueue.dropped);
+ ErrorF("[mi] This may be caused my a misbehaving driver monopolizing the server's resources.\n");
+ miEventQueue.dropped = 0;
+ }
+
while (miEventQueue.head != miEventQueue.tail) {
e = &miEventQueue.events[miEventQueue.head];
@@ -449,7 +565,7 @@ mieqProcessInputEvents(void)
dev = e->pDev;
screen = e->pScreen;
- miEventQueue.head = (miEventQueue.head + 1) % QUEUE_SIZE;
+ miEventQueue.head = (miEventQueue.head + 1) % miEventQueue.nevents;
#ifdef XQUARTZ
pthread_mutex_unlock(&miEventQueueMutex);
diff --git a/xorg-server/randr/rrproperty.c b/xorg-server/randr/rrproperty.c
index 6ed24d3aa..d0a90203b 100644
--- a/xorg-server/randr/rrproperty.c
+++ b/xorg-server/randr/rrproperty.c
@@ -549,18 +549,31 @@ int
ProcRRDeleteOutputProperty (ClientPtr client)
{
REQUEST(xRRDeleteOutputPropertyReq);
- RROutputPtr output;
-
+ RROutputPtr output;
+ RRPropertyPtr prop;
+
REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq);
UpdateCurrentTime();
VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
-
+
if (!ValidAtom(stuff->property))
{
client->errorValue = stuff->property;
return BadAtom;
}
+ prop = RRQueryOutputProperty(output, stuff->property);
+ if (!prop)
+ {
+ client->errorValue = stuff->property;
+ return BadName;
+ }
+
+ if (prop->immutable)
+ {
+ client->errorValue = stuff->property;
+ return BadAccess;
+ }
RRDeleteOutputProperty(output, stuff->property);
return Success;
diff --git a/xorg-server/render/mipict.c b/xorg-server/render/mipict.c
index 61b368472..caa76e396 100644
--- a/xorg-server/render/mipict.c
+++ b/xorg-server/render/mipict.c
@@ -569,6 +569,64 @@ miRenderPixelToColor (PictFormatPtr format,
}
}
+void
+miTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points)
+{
+ xTriangle *tris, *tri;
+ int ntri;
+
+ ntri = npoints - 2;
+ tris = malloc(ntri * sizeof (xTriangle));
+ if (!tris)
+ return;
+
+ for (tri = tris; npoints >= 3; npoints--, points++, tri++)
+ {
+ tri->p1 = points[0];
+ tri->p2 = points[1];
+ tri->p3 = points[2];
+ }
+ CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
+ free(tris);
+}
+
+void
+miTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points)
+{
+ xTriangle *tris, *tri;
+ xPointFixed *first;
+ int ntri;
+
+ ntri = npoints - 2;
+ tris = malloc(ntri * sizeof (xTriangle));
+ if (!tris)
+ return;
+
+ first = points++;
+ for (tri = tris; npoints >= 3; npoints--, points++, tri++)
+ {
+ tri->p1 = *first;
+ tri->p2 = points[0];
+ tri->p3 = points[1];
+ }
+ CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
+ free(tris);
+}
+
Bool
miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
{
@@ -602,5 +660,8 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
ps->AddTraps = 0; /* requires DDX support */
ps->AddTriangles = 0; /* requires DDX support */
+ ps->TriStrip = miTriStrip; /* converts call to CompositeTriangles */
+ ps->TriFan = miTriFan;
+
return TRUE;
}
diff --git a/xorg-server/render/mipict.h b/xorg-server/render/mipict.h
index f2df601e4..4399a6fad 100644
--- a/xorg-server/render/mipict.h
+++ b/xorg-server/render/mipict.h
@@ -1,165 +1,185 @@
-/*
- *
- * Copyright © 2000 SuSE, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. SuSE makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Keith Packard, SuSE, Inc.
- */
-
-#ifndef _MIPICT_H_
-#define _MIPICT_H_
-
-#include "picturestr.h"
-
-#define MI_MAX_INDEXED 256 /* XXX depth must be <= 8 */
-
-#if MI_MAX_INDEXED <= 256
-typedef CARD8 miIndexType;
-#endif
-
-typedef struct _miIndexed {
- Bool color;
- CARD32 rgba[MI_MAX_INDEXED];
- miIndexType ent[32768];
-} miIndexedRec, *miIndexedPtr;
-
-#define miCvtR8G8B8to15(s) ((((s) >> 3) & 0x001f) | \
- (((s) >> 6) & 0x03e0) | \
- (((s) >> 9) & 0x7c00))
-#define miIndexToEnt15(mif,rgb15) ((mif)->ent[rgb15])
-#define miIndexToEnt24(mif,rgb24) miIndexToEnt15(mif,miCvtR8G8B8to15(rgb24))
-
-#define miIndexToEntY24(mif,rgb24) ((mif)->ent[CvtR8G8B8toY15(rgb24)])
-
-extern _X_EXPORT int
-miCreatePicture (PicturePtr pPicture);
-
-extern _X_EXPORT void
-miDestroyPicture (PicturePtr pPicture);
-
-extern _X_EXPORT void
-miDestroyPictureClip (PicturePtr pPicture);
-
-extern _X_EXPORT int
-miChangePictureClip (PicturePtr pPicture,
- int type,
- pointer value,
- int n);
-
-extern _X_EXPORT void
-miChangePicture (PicturePtr pPicture,
- Mask mask);
-
-extern _X_EXPORT void
-miValidatePicture (PicturePtr pPicture,
- Mask mask);
-
-extern _X_EXPORT int
-miChangePictureTransform (PicturePtr pPicture,
- PictTransform *transform);
-
-extern _X_EXPORT int
-miChangePictureFilter (PicturePtr pPicture,
- int filter,
- xFixed *params,
- int nparams);
-
-extern _X_EXPORT void
-miCompositeSourceValidate (PicturePtr pPicture);
-
-extern _X_EXPORT Bool
-miComputeCompositeRegion (RegionPtr pRegion,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height);
-
-extern _X_EXPORT Bool
-miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
-
-extern _X_EXPORT Bool
-miRealizeGlyph (ScreenPtr pScreen,
- GlyphPtr glyph);
-
-extern _X_EXPORT void
-miUnrealizeGlyph (ScreenPtr pScreen,
- GlyphPtr glyph);
-
-extern _X_EXPORT void
-miGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs);
-
-extern _X_EXPORT void
-miRenderColorToPixel (PictFormatPtr pPict,
- xRenderColor *color,
- CARD32 *pixel);
-
-extern _X_EXPORT void
-miRenderPixelToColor (PictFormatPtr pPict,
- CARD32 pixel,
- xRenderColor *color);
-
-extern _X_EXPORT Bool
-miIsSolidAlpha (PicturePtr pSrc);
-
-extern _X_EXPORT void
-miCompositeRects (CARD8 op,
- PicturePtr pDst,
- xRenderColor *color,
- int nRect,
- xRectangle *rects);
-
-extern _X_EXPORT void
-miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
-
-extern _X_EXPORT void
-miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds);
-
-extern _X_EXPORT void
-miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds);
-
-extern _X_EXPORT Bool
-miInitIndexed (ScreenPtr pScreen,
- PictFormatPtr pFormat);
-
-extern _X_EXPORT void
-miCloseIndexed (ScreenPtr pScreen,
- PictFormatPtr pFormat);
-
-extern _X_EXPORT void
-miUpdateIndexed (ScreenPtr pScreen,
- PictFormatPtr pFormat,
- int ndef,
- xColorItem *pdef);
-
-#endif /* _MIPICT_H_ */
+/*
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _MIPICT_H_
+#define _MIPICT_H_
+
+#include "picturestr.h"
+
+#define MI_MAX_INDEXED 256 /* XXX depth must be <= 8 */
+
+#if MI_MAX_INDEXED <= 256
+typedef CARD8 miIndexType;
+#endif
+
+typedef struct _miIndexed {
+ Bool color;
+ CARD32 rgba[MI_MAX_INDEXED];
+ miIndexType ent[32768];
+} miIndexedRec, *miIndexedPtr;
+
+#define miCvtR8G8B8to15(s) ((((s) >> 3) & 0x001f) | \
+ (((s) >> 6) & 0x03e0) | \
+ (((s) >> 9) & 0x7c00))
+#define miIndexToEnt15(mif,rgb15) ((mif)->ent[rgb15])
+#define miIndexToEnt24(mif,rgb24) miIndexToEnt15(mif,miCvtR8G8B8to15(rgb24))
+
+#define miIndexToEntY24(mif,rgb24) ((mif)->ent[CvtR8G8B8toY15(rgb24)])
+
+extern _X_EXPORT int
+miCreatePicture (PicturePtr pPicture);
+
+extern _X_EXPORT void
+miDestroyPicture (PicturePtr pPicture);
+
+extern _X_EXPORT void
+miDestroyPictureClip (PicturePtr pPicture);
+
+extern _X_EXPORT int
+miChangePictureClip (PicturePtr pPicture,
+ int type,
+ pointer value,
+ int n);
+
+extern _X_EXPORT void
+miChangePicture (PicturePtr pPicture,
+ Mask mask);
+
+extern _X_EXPORT void
+miValidatePicture (PicturePtr pPicture,
+ Mask mask);
+
+extern _X_EXPORT int
+miChangePictureTransform (PicturePtr pPicture,
+ PictTransform *transform);
+
+extern _X_EXPORT int
+miChangePictureFilter (PicturePtr pPicture,
+ int filter,
+ xFixed *params,
+ int nparams);
+
+extern _X_EXPORT void
+miCompositeSourceValidate (PicturePtr pPicture);
+
+extern _X_EXPORT Bool
+miComputeCompositeRegion (RegionPtr pRegion,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+extern _X_EXPORT Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+extern _X_EXPORT Bool
+miRealizeGlyph (ScreenPtr pScreen,
+ GlyphPtr glyph);
+
+extern _X_EXPORT void
+miUnrealizeGlyph (ScreenPtr pScreen,
+ GlyphPtr glyph);
+
+extern _X_EXPORT void
+miGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+extern _X_EXPORT void
+miRenderColorToPixel (PictFormatPtr pPict,
+ xRenderColor *color,
+ CARD32 *pixel);
+
+extern _X_EXPORT void
+miRenderPixelToColor (PictFormatPtr pPict,
+ CARD32 pixel,
+ xRenderColor *color);
+
+extern _X_EXPORT Bool
+miIsSolidAlpha (PicturePtr pSrc);
+
+extern _X_EXPORT void
+miCompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+extern _X_EXPORT void
+miTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points);
+
+extern _X_EXPORT void
+miTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points);
+
+extern _X_EXPORT void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
+
+extern _X_EXPORT void
+miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds);
+
+extern _X_EXPORT void
+miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds);
+
+extern _X_EXPORT Bool
+miInitIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+extern _X_EXPORT void
+miCloseIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+extern _X_EXPORT void
+miUpdateIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef);
+
+#endif /* _MIPICT_H_ */
diff --git a/xorg-server/render/picture.c b/xorg-server/render/picture.c
index 5640c4d96..f13459665 100644
--- a/xorg-server/render/picture.c
+++ b/xorg-server/render/picture.c
@@ -1715,23 +1715,14 @@ CompositeTriStrip (CARD8 op,
int npoints,
xPointFixed *points)
{
- xTriangle *tris, *tri;
- int ntri;
-
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
if (npoints < 3)
return;
- ntri = npoints - 2;
- tris = malloc(ntri * sizeof (xTriangle));
- if (!tris)
- return;
- for (tri = tris; npoints >= 3; npoints--, points++, tri++)
- {
- tri->p1 = points[0];
- tri->p2 = points[1];
- tri->p3 = points[2];
- }
- CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
- free(tris);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
}
void
@@ -1744,25 +1735,14 @@ CompositeTriFan (CARD8 op,
int npoints,
xPointFixed *points)
{
- xTriangle *tris, *tri;
- xPointFixed *first;
- int ntri;
-
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
if (npoints < 3)
return;
- ntri = npoints - 2;
- tris = malloc(ntri * sizeof (xTriangle));
- if (!tris)
- return;
- first = points++;
- for (tri = tris; npoints >= 3; npoints--, points++, tri++)
- {
- tri->p1 = *first;
- tri->p2 = points[0];
- tri->p3 = points[1];
- }
- CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
- free(tris);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
}
void
diff --git a/xorg-server/render/picturestr.h b/xorg-server/render/picturestr.h
index 7b7f9112d..1f3f5a433 100644
--- a/xorg-server/render/picturestr.h
+++ b/xorg-server/render/picturestr.h
@@ -260,6 +260,24 @@ typedef void (*TrianglesProcPtr) (CARD8 op,
int ntri,
xTriangle *tris);
+typedef void (*TriStripProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+typedef void (*TriFanProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
typedef Bool (*InitIndexedProcPtr) (ScreenPtr pScreen,
PictFormatPtr pFormat);
@@ -348,6 +366,9 @@ typedef struct _PictureScreen {
RealizeGlyphProcPtr RealizeGlyph;
UnrealizeGlyphProcPtr UnrealizeGlyph;
+#define PICTURE_SCREEN_VERSION 2
+ TriStripProcPtr TriStrip;
+ TriFanProcPtr TriFan;
} PictureScreenRec, *PictureScreenPtr;
extern _X_EXPORT DevPrivateKeyRec PictureScreenPrivateKeyRec;
diff --git a/xorg-server/test/input.c b/xorg-server/test/input.c
index bc41c226d..5b4c8c193 100644
--- a/xorg-server/test/input.c
+++ b/xorg-server/test/input.c
@@ -40,6 +40,7 @@
#include "dixgrabs.h"
#include "eventstr.h"
#include "inpututils.h"
+#include "mi.h"
#include "assert.h"
/**
@@ -1199,14 +1200,19 @@ static void dix_input_valuator_masks(void)
assert(valuator_mask_num_valuators(mask) == num_vals);
for (i = 0; i < nvaluators; i++)
{
+ double val;
if (i < first_val || i >= first_val + num_vals)
+ {
assert(!valuator_mask_isset(mask, i));
- else
+ assert(!valuator_mask_fetch_double(mask, i, &val));
+ } else
{
assert(valuator_mask_isset(mask, i));
assert(valuator_mask_get(mask, i) == val_ranged[i - first_val]);
assert(valuator_mask_get_double(mask, i) ==
val_ranged[i - first_val]);
+ assert(valuator_mask_fetch_double(mask, i, &val));
+ assert(val_ranged[i - first_val] == val);
}
}
@@ -1218,10 +1224,18 @@ static void dix_input_valuator_masks(void)
for (i = 0; i < nvaluators; i++)
{
+ double a, b;
assert(valuator_mask_isset(mask, i) == valuator_mask_isset(copy, i));
+
+ if (!valuator_mask_isset(mask, i))
+ continue;
+
assert(valuator_mask_get(mask, i) == valuator_mask_get(copy, i));
assert(valuator_mask_get_double(mask, i) ==
valuator_mask_get_double(copy, i));
+ assert(valuator_mask_fetch_double(mask, i, &a));
+ assert(valuator_mask_fetch_double(copy, i, &b));
+ assert(a == b);
}
valuator_mask_free(&mask);
@@ -1467,8 +1481,6 @@ _test_double_fp16_values(double orig_d)
{
FP1616 first_fp16, final_fp16;
double final_d;
- char first_fp16_s[64];
- char final_fp16_s[64];
if (orig_d > 0x7FFF) {
printf("Test out of range\n");
@@ -1479,10 +1491,15 @@ _test_double_fp16_values(double orig_d)
final_d = fp1616_to_double(first_fp16);
final_fp16 = double_to_fp1616(final_d);
- snprintf(first_fp16_s, sizeof(first_fp16_s), "%d + %u * 2^-16", (first_fp16 & 0xffff0000) >> 16, first_fp16 & 0xffff);
- snprintf(final_fp16_s, sizeof(final_fp16_s), "%d + %u * 2^-16", (final_fp16 & 0xffff0000) >> 16, final_fp16 & 0xffff);
-
- printf("FP16: original double: %f first fp16: %s, re-encoded double: %f, final fp16: %s\n", orig_d, first_fp16_s, final_d, final_fp16_s);
+ /* {
+ * char first_fp16_s[64];
+ * char final_fp16_s[64];
+ * snprintf(first_fp16_s, sizeof(first_fp16_s), "%d + %u * 2^-16", (first_fp16 & 0xffff0000) >> 16, first_fp16 & 0xffff);
+ * snprintf(final_fp16_s, sizeof(final_fp16_s), "%d + %u * 2^-16", (final_fp16 & 0xffff0000) >> 16, final_fp16 & 0xffff);
+ *
+ * printf("FP16: original double: %f first fp16: %s, re-encoded double: %f, final fp16: %s\n", orig_d, first_fp16_s, final_d, final_fp16_s);
+ * }
+ */
/* since we lose precision, we only do rough range testing */
assert(final_d > orig_d - 0.1);
@@ -1590,6 +1607,73 @@ dix_double_fp_conversion(void)
}
}
+/* The mieq test verifies that events added to the queue come out in the same
+ * order that they went in.
+ */
+static uint32_t mieq_test_event_last_processed;
+
+static void
+mieq_test_event_handler(int screenNum, InternalEvent *ie, DeviceIntPtr dev) {
+ RawDeviceEvent *e = (RawDeviceEvent *)ie;
+
+ assert(e->type == ET_RawMotion);
+ assert(e->flags > mieq_test_event_last_processed);
+ mieq_test_event_last_processed = e->flags;
+}
+
+static void _mieq_test_generate_events(uint32_t start, uint32_t count) {
+ count += start;
+ while (start < count) {
+ RawDeviceEvent e = {0};
+ e.header = ET_Internal;
+ e.type = ET_RawMotion;
+ e.length = sizeof(e);
+ e.time = GetTimeInMillis();
+ e.flags = start;
+
+ mieqEnqueue(NULL, (InternalEvent*)&e);
+
+ start++;
+ }
+}
+
+#define mieq_test_generate_events(c) { _mieq_test_generate_events(next, c); next += c; }
+
+static void
+mieq_test(void) {
+ uint32_t next = 1;
+
+ mieq_test_event_last_processed = 0;
+ mieqInit();
+ mieqSetHandler(ET_RawMotion, mieq_test_event_handler);
+
+ /* Enough to fit the buffer but trigger a grow */
+ mieq_test_generate_events(180);
+
+ /* We should resize to 512 now */
+ mieqProcessInputEvents();
+
+ /* Some should now get dropped */
+ mieq_test_generate_events(500);
+
+ /* Tell us how many got dropped, 1024 now */
+ mieqProcessInputEvents();
+
+ /* Now make it 2048 */
+ mieq_test_generate_events(900);
+ mieqProcessInputEvents();
+
+ /* Now make it 4096 (max) */
+ mieq_test_generate_events(1950);
+ mieqProcessInputEvents();
+
+ /* Now overflow one last time with the maximal queue and reach the verbosity limit */
+ mieq_test_generate_events(10000);
+ mieqProcessInputEvents();
+
+ mieqFini();
+}
+
int main(int argc, char** argv)
{
dix_double_fp_conversion();
@@ -1608,6 +1692,7 @@ int main(int argc, char** argv)
dix_valuator_alloc();
dix_get_master();
input_option_test();
+ mieq_test();
return 0;
}
diff --git a/xorg-server/test/xi2/protocol-eventconvert.c b/xorg-server/test/xi2/protocol-eventconvert.c
index bfa23b51f..ba2d96ad1 100644
--- a/xorg-server/test/xi2/protocol-eventconvert.c
+++ b/xorg-server/test/xi2/protocol-eventconvert.c
@@ -30,6 +30,7 @@
#include "eventstr.h"
#include "eventconvert.h"
#include "exevents.h"
+#include "inpututils.h"
#include <X11/extensions/XI2proto.h>
static void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
@@ -104,8 +105,7 @@ static void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
value = (FP3232*)(((unsigned char*)&out[1]) + out->valuators_len * 4);
value += nvals;
- vi.integral = trunc(in->valuators.data[i]);
- vi.frac = in->valuators.data[i] - vi.integral;
+ vi = double_to_fp3232(in->valuators.data[i]);
vo.integral = value->integral;
vo.frac = value->frac;
@@ -120,8 +120,7 @@ static void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
raw_value = value + bits_set;
- vi.integral = trunc(in->valuators.data_raw[i]);
- vi.frac = in->valuators.data_raw[i] - vi.integral;
+ vi = double_to_fp3232(in->valuators.data_raw[i]);
vo.integral = raw_value->integral;
vo.frac = raw_value->frac;
@@ -748,6 +747,26 @@ static void test_values_XIDeviceChangedEvent(DeviceChangedEvent *in,
}
break;
+ case XIScrollClass:
+ {
+ xXIScrollInfo *s = (xXIScrollInfo*)any;
+ assert(s->length ==
+ bytes_to_int32(sizeof(xXIScrollInfo)));
+
+ assert(s->sourceid == in->sourceid);
+ assert(s->number < in->num_valuators);
+ switch(s->type)
+ {
+ case XIScrollTypeVertical:
+ assert(in->valuators[s->number].scroll.type == SCROLL_TYPE_VERTICAL);
+ break;
+ case XIScrollTypeHorizontal:
+ assert(in->valuators[s->number].scroll.type == SCROLL_TYPE_HORIZONTAL);
+ break;
+ }
+ if (s->flags & XIScrollFlagPreferred)
+ assert(in->valuators[s->number].scroll.flags & SCROLL_FLAG_PREFERRED);
+ }
default:
printf("Invalid class type.\n\n");
assert(1);
diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c
index 529b53c37..78a3319b8 100644
--- a/xorg-server/xkb/xkbActions.c
+++ b/xorg-server/xkb/xkbActions.c
@@ -344,15 +344,18 @@ _XkbFilterLockState( XkbSrvInfoPtr xkbi,
filter->keycode = keycode;
filter->active = 1;
filter->filterOthers = 0;
- filter->priv = 0;
+ filter->priv = xkbi->state.locked_mods&pAction->mods.mask;
filter->filter = _XkbFilterLockState;
filter->upAction = *pAction;
- xkbi->state.locked_mods^= pAction->mods.mask;
+ if (!(filter->upAction.mods.flags&XkbSA_LockNoLock))
+ xkbi->state.locked_mods|= pAction->mods.mask;
xkbi->setMods = pAction->mods.mask;
}
else if (filter->keycode==keycode) {
filter->active = 0;
xkbi->clearMods = filter->upAction.mods.mask;
+ if (!(filter->upAction.mods.flags&XkbSA_LockNoUnlock))
+ xkbi->state.locked_mods&= ~filter->priv;
}
return 1;
}