From 156e37d3879b316329e3e05579414031da2647e2 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 14 Nov 2011 09:38:56 +0100 Subject: libX11 libXext libXinerama libXmu libfontenc libxcb mesa pixman git update 14 nov 2011 --- libX11/configure.ac | 2 +- libX11/src/KeysymStr.c | 3 +- libX11/src/Xresinternal.h | 4 +- libX11/src/util/Makefile.am | 51 +- libX11/src/util/makekeys.c | 633 +-- libXext/include/X11/extensions/extutil.h | 2 +- libXext/src/DPMS.c | 2 +- libXext/src/MITMisc.c | 2 +- libXext/src/XAppgroup.c | 2 +- libXext/src/XEVI.c | 426 +- libXext/src/XLbx.c | 4 +- libXext/src/XMultibuf.c | 4 +- libXext/src/XSecurity.c | 618 +-- libXext/src/XShape.c | 2 +- libXext/src/XShm.c | 4 +- libXext/src/XSync.c | 4 +- libXext/src/Xcup.c | 2 +- libXext/src/Xdbe.c | 4 +- libXext/src/Xge.c | 2 +- libXext/src/extutil.c | 2 +- libXinerama/src/Xinerama.c | 2 +- libXmu/include/X11/Xmu/EditresP.h | 2 +- libXmu/src/Atoms.c | 12 +- libXmu/src/DefErrMsg.c | 2 +- libXmu/src/EditresCom.c | 54 +- libXmu/src/StrToGrav.c | 2 +- libXmu/src/sharedlib.c | 6 - libfontenc/src/encparse.c | 5 +- libfontenc/src/fontenc.c | 4 - libxcb/xcb-proto/xcb-proto.pc.in | 2 + mesalib/bin/mklib | 2 +- mesalib/docs/viewperf.html | 13 + mesalib/src/gallium/auxiliary/util/u_blit.c | 16 +- .../src/gallium/auxiliary/util/u_format_pack.py | 5 + mesalib/src/glsl/Makefile.sources | 2 +- mesalib/src/glsl/builtin_variables.cpp | 1001 +++++ mesalib/src/glsl/builtin_variables.h | 110 - mesalib/src/glsl/glcpp/glcpp-parse.y | 3 + mesalib/src/glsl/ir_constant_expression.cpp | 6 + mesalib/src/glsl/ir_variable.cpp | 916 ---- mesalib/src/mesa/SConscript | 2 +- mesalib/src/mesa/main/api_noop.c | 1089 ----- mesalib/src/mesa/main/api_noop.h | 61 - mesalib/src/mesa/main/eval.h | 4 - mesalib/src/mesa/main/fbobject.c | 58 +- mesalib/src/mesa/main/mtypes.h | 1 + mesalib/src/mesa/main/uniform_query.cpp | 2 +- mesalib/src/mesa/sources.mak | 2 +- mesalib/src/mesa/state_tracker/st_cb_bitmap.c | 15 +- mesalib/src/mesa/state_tracker/st_cb_drawtex.c | 2 - mesalib/src/mesa/swrast/s_readpix.c | 6 +- mesalib/src/mesa/swrast/s_texture.c | 1 - mesalib/src/mesa/vbo/vbo_exec.h | 1 + mesalib/src/mesa/vbo/vbo_exec_api.c | 149 +- mesalib/src/mesa/vbo/vbo_exec_draw.c | 62 +- mesalib/src/mesa/vbo/vbo_noop.c | 519 +++ mesalib/src/mesa/vbo/vbo_noop.h | 45 + mesalib/src/mesa/vbo/vbo_save.h | 3 + mesalib/src/mesa/vbo/vbo_save_api.c | 171 +- pixman/test/Makefile.win32 | 21 +- xkbcomp/alias.c | 10 +- xkbcomp/configure.ac | 2 +- xkbcomp/geometry.c | 10 +- xkbcomp/parseutils.c | 4 +- xkbcomp/symbols.c | 4612 ++++++++++---------- xkbcomp/utils.h | 4 +- xkbcomp/xkbcomp.c | 14 +- 67 files changed, 5283 insertions(+), 5525 deletions(-) create mode 100644 mesalib/src/glsl/builtin_variables.cpp delete mode 100644 mesalib/src/glsl/builtin_variables.h delete mode 100644 mesalib/src/glsl/ir_variable.cpp delete mode 100644 mesalib/src/mesa/main/api_noop.c delete mode 100644 mesalib/src/mesa/main/api_noop.h create mode 100644 mesalib/src/mesa/vbo/vbo_noop.c create mode 100644 mesalib/src/mesa/vbo/vbo_noop.h diff --git a/libX11/configure.ac b/libX11/configure.ac index 71662b857..c1f64b697 100644 --- a/libX11/configure.ac +++ b/libX11/configure.ac @@ -1,7 +1,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) -AC_INIT([libX11], [1.4.4], +AC_INIT([libX11], [1.4.99.1], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libX11]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([src/config.h include/X11/XlibConf.h]) diff --git a/libX11/src/KeysymStr.c b/libX11/src/KeysymStr.c index 486b5d156..101f29733 100644 --- a/libX11/src/KeysymStr.c +++ b/libX11/src/KeysymStr.c @@ -31,11 +31,10 @@ in this Software without prior written authorization from The Open Group. #include "Xlibint.h" #include #include +#include "Xresinternal.h" #include /* sprintf */ -typedef unsigned long Signature; - #define NEEDVTABLE #include "ks_tables.h" #include "Key.h" diff --git a/libX11/src/Xresinternal.h b/libX11/src/Xresinternal.h index b4b1b00f8..c2f355fe6 100644 --- a/libX11/src/Xresinternal.h +++ b/libX11/src/Xresinternal.h @@ -2,8 +2,10 @@ #ifndef _XRESINTERNAL_H_ #define _XRESINTERNAL_H_ +#include + /* type defines */ -typedef unsigned long Signature; +typedef uint32_t Signature; /* prototypes */ extern XrmQuark _XrmInternalStringToQuark( diff --git a/libX11/src/util/Makefile.am b/libX11/src/util/Makefile.am index 4c611316f..dfe91f1ae 100644 --- a/libX11/src/util/Makefile.am +++ b/libX11/src/util/Makefile.am @@ -1,24 +1,27 @@ - -noinst_PROGRAMS=makekeys - -makekeys_CFLAGS = \ - $(X11_CFLAGS) \ - $(CWARNFLAGS) - -CC = @CC_FOR_BUILD@ -CPPFLAGS = @CPPFLAGS_FOR_BUILD@ -CFLAGS = @CFLAGS_FOR_BUILD@ -LDFLAGS = @LDFLAGS_FOR_BUILD@ - -EXTRA_DIST = mkks.sh - -if LINT -# Check source code with tools like lint & sparse - -ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) - -lint: - $(LINT) $(ALL_LINT_FLAGS) makekeys.c - -endif LINT + +noinst_PROGRAMS=makekeys + +makekeys_CFLAGS = \ + $(X11_CFLAGS) \ + $(CWARNFLAGS) + +makekeys_CPPFLAGS = \ + -I$(top_srcdir)/include + +CC = @CC_FOR_BUILD@ +CPPFLAGS = @CPPFLAGS_FOR_BUILD@ +CFLAGS = @CFLAGS_FOR_BUILD@ +LDFLAGS = @LDFLAGS_FOR_BUILD@ + +EXTRA_DIST = mkks.sh + +if LINT +# Check source code with tools like lint & sparse + +ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) + +lint: + $(LINT) $(ALL_LINT_FLAGS) makekeys.c + +endif LINT diff --git a/libX11/src/util/makekeys.c b/libX11/src/util/makekeys.c index 85ce75268..36d4d4b63 100644 --- a/libX11/src/util/makekeys.c +++ b/libX11/src/util/makekeys.c @@ -1,316 +1,317 @@ -/* - -Copyright 1990, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -*/ - -/* Constructs hash tables for XStringToKeysym and XKeysymToString. */ - -#include -#include -#include -#include -#include - -typedef unsigned long Signature; - -#define KTNUM 4000 - -static struct info { - char *name; - KeySym val; -} info[KTNUM]; - -#define MIN_REHASH 15 -#define MATCHES 10 - -static char tab[KTNUM]; -static unsigned short offsets[KTNUM]; -static unsigned short indexes[KTNUM]; -static KeySym values[KTNUM]; -static char buf[1024]; -static int ksnum = 0; - -static int -parse_line(const char *buf, char *key, KeySym *val, char *prefix) -{ - int i; - char alias[128]; - char *tmp, *tmpa; - - /* See if we can catch a straight XK_foo 0x1234-style definition first; - * the trickery around tmp is to account for prefices. */ - i = sscanf(buf, "#define %127s 0x%lx", key, val); - if (i == 2 && (tmp = strstr(key, "XK_"))) { - memcpy(prefix, key, tmp - key); - prefix[tmp - key] = '\0'; - tmp += 3; - memmove(key, tmp, strlen(tmp) + 1); - return 1; - } - - /* Now try to catch alias (XK_foo XK_bar) definitions, and resolve them - * immediately: if the target is in the form XF86XK_foo, we need to - * canonicalise this to XF86foo before we do the lookup. */ - i = sscanf(buf, "#define %127s %127s", key, alias); - if (i == 2 && (tmp = strstr(key, "XK_")) && (tmpa = strstr(alias, "XK_"))) { - memcpy(prefix, key, tmp - key); - prefix[tmp - key] = '\0'; - tmp += 3; - memmove(key, tmp, strlen(tmp) + 1); - memmove(tmpa, tmpa + 3, strlen(tmpa + 3) + 1); - - for (i = ksnum - 1; i >= 0; i--) { - if (strcmp(info[i].name, alias) == 0) { - *val = info[i].val; - return 1; - } - } - - fprintf(stderr, "can't find matching definition %s for keysym %s%s\n", - alias, prefix, key); - } - - return 0; -} - -int -main(int argc, char *argv[]) -{ - int max_rehash; - Signature sig; - int i, j, k, l, z; - FILE *fptr; - char *name; - char c; - int first; - int best_max_rehash; - int best_z = 0; - int num_found; - KeySym val; - char key[128], prefix[128]; - - for (l = 1; l < argc; l++) { - fptr = fopen(argv[l], "r"); - if (!fptr) { - fprintf(stderr, "couldn't open %s\n", argv[l]); - continue; - } - - while (fgets(buf, sizeof(buf), fptr)) { - if (!parse_line(buf, key, &val, prefix)) - continue; - - if (val == XK_VoidSymbol) - val = 0; - if (val > 0x1fffffff) { - fprintf(stderr, "ignoring illegal keysym (%s, %lx)\n", key, - val); - continue; - } - - name = malloc(strlen(prefix) + strlen(key) + 1); - if (!name) { - fprintf(stderr, "makekeys: out of memory!\n"); - exit(1); - } - sprintf(name, "%s%s", prefix, key); - info[ksnum].name = name; - info[ksnum].val = val; - ksnum++; - if (ksnum == KTNUM) { - fprintf(stderr, "makekeys: too many keysyms!\n"); - exit(1); - } - } - - fclose(fptr); - } - - printf("/* This file is generated from keysymdef.h. */\n"); - printf("/* Do not edit. */\n"); - printf("\n"); - - best_max_rehash = ksnum; - num_found = 0; - for (z = ksnum; z < KTNUM; z++) { - max_rehash = 0; - for (name = tab, i = z; --i >= 0;) - *name++ = 0; - for (i = 0; i < ksnum; i++) { - name = info[i].name; - sig = 0; - while ((c = *name++)) - sig = (sig << 1) + c; - first = j = sig % z; - for (k = 0; tab[j]; k++) { - j += first + 1; - if (j >= z) - j -= z; - if (j == first) - goto next1; - } - tab[j] = 1; - if (k > max_rehash) - max_rehash = k; - } - if (max_rehash < MIN_REHASH) { - if (max_rehash < best_max_rehash) { - best_max_rehash = max_rehash; - best_z = z; - } - num_found++; - if (num_found >= MATCHES) - break; - } -next1: ; - } - - z = best_z; - if (z == 0) { - fprintf(stderr, "makekeys: failed to find small enough hash!\n" - "Try increasing KTNUM in makekeys.c\n"); - exit(1); - } - printf("#ifdef NEEDKTABLE\n"); - printf("const unsigned char _XkeyTable[] = {\n"); - printf("0,\n"); - k = 1; - for (i = 0; i < ksnum; i++) { - name = info[i].name; - sig = 0; - while ((c = *name++)) - sig = (sig << 1) + c; - first = j = sig % z; - while (offsets[j]) { - j += first + 1; - if (j >= z) - j -= z; - } - offsets[j] = k; - indexes[i] = k; - val = info[i].val; - printf("0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, ", - (sig >> 8) & 0xff, sig & 0xff, - (val >> 24) & 0xff, (val >> 16) & 0xff, - (val >> 8) & 0xff, val & 0xff); - for (name = info[i].name, k += 7; (c = *name++); k++) - printf("'%c',", c); - printf((i == (ksnum-1)) ? "0\n" : "0,\n"); - } - printf("};\n"); - printf("\n"); - printf("#define KTABLESIZE %d\n", z); - printf("#define KMAXHASH %d\n", best_max_rehash + 1); - printf("\n"); - printf("static const unsigned short hashString[KTABLESIZE] = {\n"); - for (i = 0; i < z;) { - printf("0x%.4x", offsets[i]); - i++; - if (i == z) - break; - printf((i & 7) ? ", " : ",\n"); - } - printf("\n"); - printf("};\n"); - printf("#endif /* NEEDKTABLE */\n"); - - best_max_rehash = ksnum; - num_found = 0; - for (z = ksnum; z < KTNUM; z++) { - max_rehash = 0; - for (name = tab, i = z; --i >= 0;) - *name++ = 0; - for (i = 0; i < ksnum; i++) { - val = info[i].val; - first = j = val % z; - for (k = 0; tab[j]; k++) { - if (values[j] == val) - goto skip1; - j += first + 1; - if (j >= z) - j -= z; - if (j == first) - goto next2; - } - tab[j] = 1; - values[j] = val; - if (k > max_rehash) - max_rehash = k; -skip1: ; - } - if (max_rehash < MIN_REHASH) { - if (max_rehash < best_max_rehash) { - best_max_rehash = max_rehash; - best_z = z; - } - num_found++; - if (num_found >= MATCHES) - break; - } -next2: ; - } - - z = best_z; - if (z == 0) { - fprintf(stderr, "makekeys: failed to find small enough hash!\n" - "Try increasing KTNUM in makekeys.c\n"); - exit(1); - } - for (i = z; --i >= 0;) - offsets[i] = 0; - for (i = 0; i < ksnum; i++) { - val = info[i].val; - first = j = val % z; - while (offsets[j]) { - if (values[j] == val) - goto skip2; - j += first + 1; - if (j >= z) - j -= z; - } - offsets[j] = indexes[i] + 2; - values[j] = val; -skip2: ; - } - printf("\n"); - printf("#ifdef NEEDVTABLE\n"); - printf("#define VTABLESIZE %d\n", z); - printf("#define VMAXHASH %d\n", best_max_rehash + 1); - printf("\n"); - printf("static const unsigned short hashKeysym[VTABLESIZE] = {\n"); - for (i = 0; i < z;) { - printf("0x%.4x", offsets[i]); - i++; - if (i == z) - break; - printf((i & 7) ? ", " : ",\n"); - } - printf("\n"); - printf("};\n"); - printf("#endif /* NEEDVTABLE */\n"); - - exit(0); -} +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +/* Constructs hash tables for XStringToKeysym and XKeysymToString. */ + +#include +#include +#include +#include +#include +#include + +#include "../Xresinternal.h" + +#define KTNUM 4000 + +static struct info { + char *name; + KeySym val; +} info[KTNUM]; + +#define MIN_REHASH 15 +#define MATCHES 10 + +static char tab[KTNUM]; +static unsigned short offsets[KTNUM]; +static unsigned short indexes[KTNUM]; +static KeySym values[KTNUM]; +static char buf[1024]; +static int ksnum = 0; + +static int +parse_line(const char *buf, char *key, KeySym *val, char *prefix) +{ + int i; + char alias[128]; + char *tmp, *tmpa; + + /* See if we can catch a straight XK_foo 0x1234-style definition first; + * the trickery around tmp is to account for prefices. */ + i = sscanf(buf, "#define %127s 0x%lx", key, val); + if (i == 2 && (tmp = strstr(key, "XK_"))) { + memcpy(prefix, key, tmp - key); + prefix[tmp - key] = '\0'; + tmp += 3; + memmove(key, tmp, strlen(tmp) + 1); + return 1; + } + + /* Now try to catch alias (XK_foo XK_bar) definitions, and resolve them + * immediately: if the target is in the form XF86XK_foo, we need to + * canonicalise this to XF86foo before we do the lookup. */ + i = sscanf(buf, "#define %127s %127s", key, alias); + if (i == 2 && (tmp = strstr(key, "XK_")) && (tmpa = strstr(alias, "XK_"))) { + memcpy(prefix, key, tmp - key); + prefix[tmp - key] = '\0'; + tmp += 3; + memmove(key, tmp, strlen(tmp) + 1); + memmove(tmpa, tmpa + 3, strlen(tmpa + 3) + 1); + + for (i = ksnum - 1; i >= 0; i--) { + if (strcmp(info[i].name, alias) == 0) { + *val = info[i].val; + return 1; + } + } + + fprintf(stderr, "can't find matching definition %s for keysym %s%s\n", + alias, prefix, key); + } + + return 0; +} + +int +main(int argc, char *argv[]) +{ + int max_rehash; + Signature sig; + int i, j, k, l, z; + FILE *fptr; + char *name; + char c; + int first; + int best_max_rehash; + int best_z = 0; + int num_found; + KeySym val; + char key[128], prefix[128]; + + for (l = 1; l < argc; l++) { + fptr = fopen(argv[l], "r"); + if (!fptr) { + fprintf(stderr, "couldn't open %s\n", argv[l]); + continue; + } + + while (fgets(buf, sizeof(buf), fptr)) { + if (!parse_line(buf, key, &val, prefix)) + continue; + + if (val == XK_VoidSymbol) + val = 0; + if (val > 0x1fffffff) { + fprintf(stderr, "ignoring illegal keysym (%s, %lx)\n", key, + val); + continue; + } + + name = malloc(strlen(prefix) + strlen(key) + 1); + if (!name) { + fprintf(stderr, "makekeys: out of memory!\n"); + exit(1); + } + sprintf(name, "%s%s", prefix, key); + info[ksnum].name = name; + info[ksnum].val = val; + ksnum++; + if (ksnum == KTNUM) { + fprintf(stderr, "makekeys: too many keysyms!\n"); + exit(1); + } + } + + fclose(fptr); + } + + printf("/* This file is generated from keysymdef.h. */\n"); + printf("/* Do not edit. */\n"); + printf("\n"); + + best_max_rehash = ksnum; + num_found = 0; + for (z = ksnum; z < KTNUM; z++) { + max_rehash = 0; + for (name = tab, i = z; --i >= 0;) + *name++ = 0; + for (i = 0; i < ksnum; i++) { + name = info[i].name; + sig = 0; + while ((c = *name++)) + sig = (sig << 1) + c; + first = j = sig % z; + for (k = 0; tab[j]; k++) { + j += first + 1; + if (j >= z) + j -= z; + if (j == first) + goto next1; + } + tab[j] = 1; + if (k > max_rehash) + max_rehash = k; + } + if (max_rehash < MIN_REHASH) { + if (max_rehash < best_max_rehash) { + best_max_rehash = max_rehash; + best_z = z; + } + num_found++; + if (num_found >= MATCHES) + break; + } +next1: ; + } + + z = best_z; + if (z == 0) { + fprintf(stderr, "makekeys: failed to find small enough hash!\n" + "Try increasing KTNUM in makekeys.c\n"); + exit(1); + } + printf("#ifdef NEEDKTABLE\n"); + printf("const unsigned char _XkeyTable[] = {\n"); + printf("0,\n"); + k = 1; + for (i = 0; i < ksnum; i++) { + name = info[i].name; + sig = 0; + while ((c = *name++)) + sig = (sig << 1) + c; + first = j = sig % z; + while (offsets[j]) { + j += first + 1; + if (j >= z) + j -= z; + } + offsets[j] = k; + indexes[i] = k; + val = info[i].val; + printf("0x%.2"PRIx32", 0x%.2"PRIx32", 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, ", + (sig >> 8) & 0xff, sig & 0xff, + (val >> 24) & 0xff, (val >> 16) & 0xff, + (val >> 8) & 0xff, val & 0xff); + for (name = info[i].name, k += 7; (c = *name++); k++) + printf("'%c',", c); + printf((i == (ksnum-1)) ? "0\n" : "0,\n"); + } + printf("};\n"); + printf("\n"); + printf("#define KTABLESIZE %d\n", z); + printf("#define KMAXHASH %d\n", best_max_rehash + 1); + printf("\n"); + printf("static const unsigned short hashString[KTABLESIZE] = {\n"); + for (i = 0; i < z;) { + printf("0x%.4x", offsets[i]); + i++; + if (i == z) + break; + printf((i & 7) ? ", " : ",\n"); + } + printf("\n"); + printf("};\n"); + printf("#endif /* NEEDKTABLE */\n"); + + best_max_rehash = ksnum; + num_found = 0; + for (z = ksnum; z < KTNUM; z++) { + max_rehash = 0; + for (name = tab, i = z; --i >= 0;) + *name++ = 0; + for (i = 0; i < ksnum; i++) { + val = info[i].val; + first = j = val % z; + for (k = 0; tab[j]; k++) { + if (values[j] == val) + goto skip1; + j += first + 1; + if (j >= z) + j -= z; + if (j == first) + goto next2; + } + tab[j] = 1; + values[j] = val; + if (k > max_rehash) + max_rehash = k; +skip1: ; + } + if (max_rehash < MIN_REHASH) { + if (max_rehash < best_max_rehash) { + best_max_rehash = max_rehash; + best_z = z; + } + num_found++; + if (num_found >= MATCHES) + break; + } +next2: ; + } + + z = best_z; + if (z == 0) { + fprintf(stderr, "makekeys: failed to find small enough hash!\n" + "Try increasing KTNUM in makekeys.c\n"); + exit(1); + } + for (i = z; --i >= 0;) + offsets[i] = 0; + for (i = 0; i < ksnum; i++) { + val = info[i].val; + first = j = val % z; + while (offsets[j]) { + if (values[j] == val) + goto skip2; + j += first + 1; + if (j >= z) + j -= z; + } + offsets[j] = indexes[i] + 2; + values[j] = val; +skip2: ; + } + printf("\n"); + printf("#ifdef NEEDVTABLE\n"); + printf("#define VTABLESIZE %d\n", z); + printf("#define VMAXHASH %d\n", best_max_rehash + 1); + printf("\n"); + printf("static const unsigned short hashKeysym[VTABLESIZE] = {\n"); + for (i = 0; i < z;) { + printf("0x%.4x", offsets[i]); + i++; + if (i == z) + break; + printf((i & 7) ? ", " : ",\n"); + } + printf("\n"); + printf("};\n"); + printf("#endif /* NEEDVTABLE */\n"); + + exit(0); +} diff --git a/libXext/include/X11/extensions/extutil.h b/libXext/include/X11/extensions/extutil.h index 7f05affd8..29404d5ae 100644 --- a/libXext/include/X11/extensions/extutil.h +++ b/libXext/include/X11/extensions/extutil.h @@ -123,7 +123,7 @@ extern void XextDestroyExtension( extern XExtDisplayInfo *XextAddDisplay( XExtensionInfo* /* extinfo */, Display* /* dpy */, - char* /* ext_name */, + _Xconst char* /* ext_name */, XExtensionHooks* /* hooks */, int /* nevents */, XPointer /* data */ diff --git a/libXext/src/DPMS.c b/libXext/src/DPMS.c index 07818a07e..a4f0595a8 100644 --- a/libXext/src/DPMS.c +++ b/libXext/src/DPMS.c @@ -42,7 +42,7 @@ Equipment Corporation. static XExtensionInfo _dpms_info_data; static XExtensionInfo *dpms_info = &_dpms_info_data; -static char *dpms_extension_name = DPMSExtensionName; +static const char *dpms_extension_name = DPMSExtensionName; #define DPMSCheckExtension(dpy,i,val) \ XextCheckExtension (dpy, i, dpms_extension_name, val) diff --git a/libXext/src/MITMisc.c b/libXext/src/MITMisc.c index bc452dba7..b8c21b6f6 100644 --- a/libXext/src/MITMisc.c +++ b/libXext/src/MITMisc.c @@ -37,7 +37,7 @@ in this Software without prior written authorization from The Open Group. static XExtensionInfo _mit_info_data; static XExtensionInfo *mit_info = &_mit_info_data; -static /* const */ char *mit_extension_name = MITMISCNAME; +static const char *mit_extension_name = MITMISCNAME; #define MITCheckExtension(dpy,i,val) \ XextCheckExtension (dpy, i, mit_extension_name, val) diff --git a/libXext/src/XAppgroup.c b/libXext/src/XAppgroup.c index 16650b6a9..b5642f3ba 100644 --- a/libXext/src/XAppgroup.c +++ b/libXext/src/XAppgroup.c @@ -52,7 +52,7 @@ struct xagstuff { static XExtensionInfo _xag_info_data; static XExtensionInfo *xag_info = &_xag_info_data; -static char *xag_extension_name = XAGNAME; +static const char *xag_extension_name = XAGNAME; #define XagCheckExtension(dpy,i,val) \ XextCheckExtension (dpy, i, xag_extension_name, val) diff --git a/libXext/src/XEVI.c b/libXext/src/XEVI.c index caf988977..eb09daa9a 100644 --- a/libXext/src/XEVI.c +++ b/libXext/src/XEVI.c @@ -1,213 +1,213 @@ -/************************************************************ -Copyright (c) 1997 by Silicon Graphics Computer Systems, Inc. -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting -documentation, and that the name of Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH -THE USE OR PERFORMANCE OF THIS SOFTWARE. -********************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -static XExtensionInfo *xevi_info;/* needs to move to globals.c */ -static /* const */ char *xevi_extension_name = EVINAME; -#define XeviCheckExtension(dpy,i,val) \ - XextCheckExtension (dpy, i, xevi_extension_name, val) -/***************************************************************************** - * * - * private utility routines * - * * - *****************************************************************************/ -static /* const */ XExtensionHooks xevi_extension_hooks = { - NULL, /* create_gc */ - NULL, /* copy_gc */ - NULL, /* flush_gc */ - NULL, /* free_gc */ - NULL, /* create_font */ - NULL, /* free_font */ - NULL, /* close_display */ - NULL, /* wire_to_event */ - NULL, /* event_to_wire */ - NULL, /* error */ - NULL, /* error_string */ -}; -static XEXT_GENERATE_FIND_DISPLAY (find_display, xevi_info, - xevi_extension_name, - &xevi_extension_hooks, 0, NULL) -Bool XeviQueryExtension (Display *dpy) -{ - XExtDisplayInfo *info = find_display (dpy); - if (XextHasExtension(info)) { - return True; - } else { - return False; - } -} -Bool XeviQueryVersion(Display *dpy, int *majorVersion, int *minorVersion) -{ - XExtDisplayInfo *info = find_display (dpy); - xEVIQueryVersionReply rep; - register xEVIQueryVersionReq *req; - XeviCheckExtension (dpy, info, False); - LockDisplay(dpy); - GetReq(EVIQueryVersion, req); - req->reqType = info->codes->major_opcode; - req->xeviReqType = X_EVIQueryVersion; - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - *majorVersion = rep.majorVersion; - *minorVersion = rep.minorVersion; - UnlockDisplay(dpy); - SyncHandle(); - return True; -} -static Bool notInList(VisualID32 *visual, int sz_visual, VisualID newVisualid) -{ - while (sz_visual-- > 0) { - if (*visual == newVisualid) - return False; - visual++; - } - return True; -} -Status XeviGetVisualInfo( - register Display *dpy, - VisualID *visual, - int n_visual, - ExtendedVisualInfo **evi_return, - int *n_info_return) -{ - XExtDisplayInfo *info = find_display (dpy); - register xEVIGetVisualInfoReq *req; - xEVIGetVisualInfoReply rep; - int sz_info, sz_xInfo, sz_conflict, sz_xConflict; - VisualID32 *temp_conflict, *temp_visual, *xConflictPtr; - VisualID *conflict; - xExtendedVisualInfo *temp_xInfo; - XVisualInfo *vinfo; - register ExtendedVisualInfo *infoPtr; - register xExtendedVisualInfo *xInfoPtr; - register int n_data, visualIndex, vinfoIndex; - Bool isValid; - XeviCheckExtension (dpy, info, 0); - if (!n_info_return || !evi_return) { - return BadValue; - } - *n_info_return = 0; - *evi_return = NULL; - vinfo = XGetVisualInfo(dpy, 0, NULL, &sz_info); - if (!vinfo) { - return BadValue; - } - if (!n_visual || !visual) { /* copy the all visual */ - temp_visual = (VisualID32 *)Xmalloc(sz_VisualID32 * sz_info); - n_visual = 0; - for (vinfoIndex = 0; vinfoIndex < sz_info; vinfoIndex++) - if (notInList(temp_visual, n_visual, vinfo[vinfoIndex].visualid)) - temp_visual[n_visual++] = vinfo[vinfoIndex].visualid; - } - else { /* check if the visual is valid */ - for (visualIndex = 0; visualIndex < n_visual; visualIndex++) { - isValid = False; - for (vinfoIndex = 0; vinfoIndex < sz_info; vinfoIndex++) { - if (visual[visualIndex] == vinfo[vinfoIndex].visualid) { - isValid = True; - break; - } - } - if (!isValid) { - XFree(vinfo); - return BadValue; - } - } - temp_visual = (VisualID32 *)Xmalloc(sz_VisualID32 * n_visual); - for (visualIndex = 0; visualIndex < n_visual; visualIndex++) - temp_visual[visualIndex] = visual[visualIndex]; - } - XFree(vinfo); - LockDisplay(dpy); - GetReq(EVIGetVisualInfo, req); - req->reqType = info->codes->major_opcode; - req->xeviReqType = X_EVIGetVisualInfo; - req->n_visual = n_visual; - SetReqLen(req, n_visual, 1); - Data(dpy, (char *)temp_visual, n_visual * sz_VisualID32); - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - Xfree(temp_visual); - return BadAccess; - } - Xfree(temp_visual); - sz_info = rep.n_info * sizeof(ExtendedVisualInfo); - sz_xInfo = rep.n_info * sz_xExtendedVisualInfo; - sz_conflict = rep.n_conflicts * sizeof(VisualID); - sz_xConflict = rep.n_conflicts * sz_VisualID32; - infoPtr = *evi_return = (ExtendedVisualInfo *)Xmalloc(sz_info + sz_conflict); - xInfoPtr = temp_xInfo = (xExtendedVisualInfo *)Xmalloc(sz_xInfo); - xConflictPtr = temp_conflict = (VisualID32 *)Xmalloc(sz_xConflict); - if (!*evi_return || !temp_xInfo || !temp_conflict) { - _XEatData(dpy, (sz_xInfo + sz_xConflict + 3) & ~3); - UnlockDisplay(dpy); - SyncHandle(); - if (evi_return) - Xfree(evi_return); - if (temp_xInfo) - Xfree(temp_xInfo); - if (temp_conflict) - Xfree(temp_conflict); - return BadAlloc; - } - _XRead(dpy, (char *)temp_xInfo, sz_xInfo); - _XRead(dpy, (char *)temp_conflict, sz_xConflict); - UnlockDisplay(dpy); - SyncHandle(); - n_data = rep.n_info; - conflict = (VisualID *)(infoPtr + n_data); - while (n_data-- > 0) { - infoPtr->core_visual_id = xInfoPtr->core_visual_id; - infoPtr->screen = xInfoPtr->screen; - infoPtr->level = xInfoPtr->level; - infoPtr->transparency_type = xInfoPtr->transparency_type; - infoPtr->transparency_value = xInfoPtr->transparency_value; - infoPtr->min_hw_colormaps = xInfoPtr->min_hw_colormaps; - infoPtr->max_hw_colormaps = xInfoPtr->max_hw_colormaps; - infoPtr->num_colormap_conflicts = xInfoPtr->num_colormap_conflicts; - infoPtr->colormap_conflicts = conflict; - conflict += infoPtr->num_colormap_conflicts; - infoPtr++; - xInfoPtr++; - } - n_data = rep.n_conflicts; - conflict = (VisualID *)(infoPtr); - while (n_data-- > 0) - *conflict++ = *xConflictPtr++; - Xfree(temp_xInfo); - Xfree(temp_conflict); - *n_info_return = rep.n_info; - return Success; -} +/************************************************************ +Copyright (c) 1997 by Silicon Graphics Computer Systems, Inc. +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright +notice and this permission notice appear in supporting +documentation, and that the name of Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +static XExtensionInfo *xevi_info;/* needs to move to globals.c */ +static const char *xevi_extension_name = EVINAME; +#define XeviCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xevi_extension_name, val) +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ +static /* const */ XExtensionHooks xevi_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + NULL, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; +static XEXT_GENERATE_FIND_DISPLAY (find_display, xevi_info, + xevi_extension_name, + &xevi_extension_hooks, 0, NULL) +Bool XeviQueryExtension (Display *dpy) +{ + XExtDisplayInfo *info = find_display (dpy); + if (XextHasExtension(info)) { + return True; + } else { + return False; + } +} +Bool XeviQueryVersion(Display *dpy, int *majorVersion, int *minorVersion) +{ + XExtDisplayInfo *info = find_display (dpy); + xEVIQueryVersionReply rep; + register xEVIQueryVersionReq *req; + XeviCheckExtension (dpy, info, False); + LockDisplay(dpy); + GetReq(EVIQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->xeviReqType = X_EVIQueryVersion; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} +static Bool notInList(VisualID32 *visual, int sz_visual, VisualID newVisualid) +{ + while (sz_visual-- > 0) { + if (*visual == newVisualid) + return False; + visual++; + } + return True; +} +Status XeviGetVisualInfo( + register Display *dpy, + VisualID *visual, + int n_visual, + ExtendedVisualInfo **evi_return, + int *n_info_return) +{ + XExtDisplayInfo *info = find_display (dpy); + register xEVIGetVisualInfoReq *req; + xEVIGetVisualInfoReply rep; + int sz_info, sz_xInfo, sz_conflict, sz_xConflict; + VisualID32 *temp_conflict, *temp_visual, *xConflictPtr; + VisualID *conflict; + xExtendedVisualInfo *temp_xInfo; + XVisualInfo *vinfo; + register ExtendedVisualInfo *infoPtr; + register xExtendedVisualInfo *xInfoPtr; + register int n_data, visualIndex, vinfoIndex; + Bool isValid; + XeviCheckExtension (dpy, info, 0); + if (!n_info_return || !evi_return) { + return BadValue; + } + *n_info_return = 0; + *evi_return = NULL; + vinfo = XGetVisualInfo(dpy, 0, NULL, &sz_info); + if (!vinfo) { + return BadValue; + } + if (!n_visual || !visual) { /* copy the all visual */ + temp_visual = (VisualID32 *)Xmalloc(sz_VisualID32 * sz_info); + n_visual = 0; + for (vinfoIndex = 0; vinfoIndex < sz_info; vinfoIndex++) + if (notInList(temp_visual, n_visual, vinfo[vinfoIndex].visualid)) + temp_visual[n_visual++] = vinfo[vinfoIndex].visualid; + } + else { /* check if the visual is valid */ + for (visualIndex = 0; visualIndex < n_visual; visualIndex++) { + isValid = False; + for (vinfoIndex = 0; vinfoIndex < sz_info; vinfoIndex++) { + if (visual[visualIndex] == vinfo[vinfoIndex].visualid) { + isValid = True; + break; + } + } + if (!isValid) { + XFree(vinfo); + return BadValue; + } + } + temp_visual = (VisualID32 *)Xmalloc(sz_VisualID32 * n_visual); + for (visualIndex = 0; visualIndex < n_visual; visualIndex++) + temp_visual[visualIndex] = visual[visualIndex]; + } + XFree(vinfo); + LockDisplay(dpy); + GetReq(EVIGetVisualInfo, req); + req->reqType = info->codes->major_opcode; + req->xeviReqType = X_EVIGetVisualInfo; + req->n_visual = n_visual; + SetReqLen(req, n_visual, 1); + Data(dpy, (char *)temp_visual, n_visual * sz_VisualID32); + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + Xfree(temp_visual); + return BadAccess; + } + Xfree(temp_visual); + sz_info = rep.n_info * sizeof(ExtendedVisualInfo); + sz_xInfo = rep.n_info * sz_xExtendedVisualInfo; + sz_conflict = rep.n_conflicts * sizeof(VisualID); + sz_xConflict = rep.n_conflicts * sz_VisualID32; + infoPtr = *evi_return = (ExtendedVisualInfo *)Xmalloc(sz_info + sz_conflict); + xInfoPtr = temp_xInfo = (xExtendedVisualInfo *)Xmalloc(sz_xInfo); + xConflictPtr = temp_conflict = (VisualID32 *)Xmalloc(sz_xConflict); + if (!*evi_return || !temp_xInfo || !temp_conflict) { + _XEatData(dpy, (sz_xInfo + sz_xConflict + 3) & ~3); + UnlockDisplay(dpy); + SyncHandle(); + if (evi_return) + Xfree(evi_return); + if (temp_xInfo) + Xfree(temp_xInfo); + if (temp_conflict) + Xfree(temp_conflict); + return BadAlloc; + } + _XRead(dpy, (char *)temp_xInfo, sz_xInfo); + _XRead(dpy, (char *)temp_conflict, sz_xConflict); + UnlockDisplay(dpy); + SyncHandle(); + n_data = rep.n_info; + conflict = (VisualID *)(infoPtr + n_data); + while (n_data-- > 0) { + infoPtr->core_visual_id = xInfoPtr->core_visual_id; + infoPtr->screen = xInfoPtr->screen; + infoPtr->level = xInfoPtr->level; + infoPtr->transparency_type = xInfoPtr->transparency_type; + infoPtr->transparency_value = xInfoPtr->transparency_value; + infoPtr->min_hw_colormaps = xInfoPtr->min_hw_colormaps; + infoPtr->max_hw_colormaps = xInfoPtr->max_hw_colormaps; + infoPtr->num_colormap_conflicts = xInfoPtr->num_colormap_conflicts; + infoPtr->colormap_conflicts = conflict; + conflict += infoPtr->num_colormap_conflicts; + infoPtr++; + xInfoPtr++; + } + n_data = rep.n_conflicts; + conflict = (VisualID *)(infoPtr); + while (n_data-- > 0) + *conflict++ = *xConflictPtr++; + Xfree(temp_xInfo); + Xfree(temp_conflict); + *n_info_return = rep.n_info; + return Success; +} diff --git a/libXext/src/XLbx.c b/libXext/src/XLbx.c index b3ba1b2ea..fda00ea63 100644 --- a/libXext/src/XLbx.c +++ b/libXext/src/XLbx.c @@ -33,7 +33,7 @@ static XExtensionInfo _lbx_info_data; static XExtensionInfo *lbx_info = &_lbx_info_data; -static /* const */ char *lbx_extension_name = LBXNAME; +static const char *lbx_extension_name = LBXNAME; #define LbxCheckExtension(dpy,i,val) \ XextCheckExtension (dpy, i, lbx_extension_name, val) @@ -55,7 +55,7 @@ static /* const */ XExtensionHooks lbx_extension_hooks = { error_string, /* error_string */ }; -static /* const */ char *lbx_error_list[] = { +static const char *lbx_error_list[] = { "BadLbxClient", /* BadLbxClient */ }; diff --git a/libXext/src/XMultibuf.c b/libXext/src/XMultibuf.c index fb995f840..7a746bac5 100644 --- a/libXext/src/XMultibuf.c +++ b/libXext/src/XMultibuf.c @@ -37,7 +37,7 @@ in this Software without prior written authorization from The Open Group. static XExtensionInfo _multibuf_info_data; static XExtensionInfo *multibuf_info = &_multibuf_info_data; -static /* const */ char *multibuf_extension_name = MULTIBUFFER_PROTOCOL_NAME; +static const char *multibuf_extension_name = MULTIBUFFER_PROTOCOL_NAME; #define MbufCheckExtension(dpy,i,val) \ XextCheckExtension (dpy, i, multibuf_extension_name, val) @@ -72,7 +72,7 @@ static /* const */ XExtensionHooks multibuf_extension_hooks = { error_string, /* error_string */ }; -static /* const */ char *multibuf_error_list[] = { +static const char *multibuf_error_list[] = { "BadBuffer", /* MultibufferBadBuffer */ }; diff --git a/libXext/src/XSecurity.c b/libXext/src/XSecurity.c index 4ce7c4d01..f8c7da13b 100644 --- a/libXext/src/XSecurity.c +++ b/libXext/src/XSecurity.c @@ -1,309 +1,309 @@ -/* - -Copyright 1996, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include - -static XExtensionInfo _Security_info_data; -static XExtensionInfo *Security_info = &_Security_info_data; -static char *Security_extension_name = SECURITY_EXTENSION_NAME; - -#define SecurityCheckExtension(dpy,i,val) \ - XextCheckExtension (dpy, i, Security_extension_name, val) -#define SecuritySimpleCheckExtension(dpy,i) \ - XextSimpleCheckExtension (dpy, i, Security_extension_name) - -#define SecurityGetReq(name,req,info) GetReq (name, req); \ - req->reqType = info->codes->major_opcode; \ - req->securityReqType = X_##name; - -/***************************************************************************** - * * - * private utility routines * - * * - *****************************************************************************/ - -/* - * find_display - locate the display info block - */ -static int close_display(Display *dpy, XExtCodes *codes); -static Bool wire_to_event(Display *dpy, XEvent *event, xEvent *wire); -static Status event_to_wire(Display *dpy, XEvent *event, xEvent *wire); -static char *error_string(Display *dpy, int code, XExtCodes *codes, - char *buf, int n); - -static XExtensionHooks Security_extension_hooks = { - NULL, /* create_gc */ - NULL, /* copy_gc */ - NULL, /* flush_gc */ - NULL, /* free_gc */ - NULL, /* create_font */ - NULL, /* free_font */ - close_display, /* close_display */ - wire_to_event, /* wire_to_event */ - event_to_wire, /* event_to_wire */ - NULL, /* error */ - error_string /* error_string */ -}; - -static char *security_error_list[] = { - "BadAuthorization", - "BadAuthorizationProtocol" -}; - -static XEXT_GENERATE_FIND_DISPLAY (find_display, Security_info, - Security_extension_name, - &Security_extension_hooks, - XSecurityNumberEvents, NULL) - -static XEXT_GENERATE_CLOSE_DISPLAY (close_display, Security_info) - -static -XEXT_GENERATE_ERROR_STRING(error_string, Security_extension_name, - XSecurityNumberErrors, security_error_list) - -static Bool -wire_to_event(Display *dpy, XEvent *event, xEvent *wire) -{ - XExtDisplayInfo *info = find_display(dpy); - - SecurityCheckExtension (dpy, info, False); - - switch ((wire->u.u.type & 0x7F) - info->codes->first_event) - { - case XSecurityAuthorizationRevoked: - { - xSecurityAuthorizationRevokedEvent *rwire = - (xSecurityAuthorizationRevokedEvent *)wire; - XSecurityAuthorizationRevokedEvent *revent = - (XSecurityAuthorizationRevokedEvent *)event; - - revent->type = rwire->type & 0x7F; - revent->serial = _XSetLastRequestRead(dpy, - (xGenericReply *) wire); - revent->send_event = (rwire->type & 0x80) != 0; - revent->display = dpy; - revent->auth_id = rwire->authId; - return True; - } - } - return False; -} - -static Status -event_to_wire(Display *dpy, XEvent *event, xEvent *wire) -{ - XExtDisplayInfo *info = find_display(dpy); - - SecurityCheckExtension(dpy, info, False); - - switch ((event->type & 0x7F) - info->codes->first_event) - { - case XSecurityAuthorizationRevoked: - { - xSecurityAuthorizationRevokedEvent *rwire = - (xSecurityAuthorizationRevokedEvent *)wire; - XSecurityAuthorizationRevokedEvent *revent = - (XSecurityAuthorizationRevokedEvent *)event; - rwire->type = revent->type | (revent->send_event ? 0x80 : 0); - rwire->sequenceNumber = revent->serial & 0xFFFF; - return True; - } - } - return False; -} - -/***************************************************************************** - * * - * Security public interfaces * - * * - *****************************************************************************/ - -Status XSecurityQueryExtension ( - Display *dpy, - int *major_version_return, - int *minor_version_return) -{ - XExtDisplayInfo *info = find_display (dpy); - xSecurityQueryVersionReply rep; - register xSecurityQueryVersionReq *req; - - if (!XextHasExtension (info)) - return (Status)0; /* failure */ - - LockDisplay (dpy); - SecurityGetReq (SecurityQueryVersion, req, info); - req->majorVersion = SECURITY_MAJOR_VERSION; - req->minorVersion = SECURITY_MINOR_VERSION; - - if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { - UnlockDisplay (dpy); - SyncHandle (); - return (Status)0; /* failure */ - } - *major_version_return = rep.majorVersion; - *minor_version_return = rep.minorVersion; - UnlockDisplay (dpy); - - SyncHandle (); - - if (*major_version_return != SECURITY_MAJOR_VERSION) - return (Status)0; /* failure */ - else - return (Status)1; /* success */ -} - -Xauth * -XSecurityAllocXauth(void) -{ - return Xcalloc(1, sizeof(Xauth)); -} - -void -XSecurityFreeXauth(Xauth *auth) -{ - XFree(auth); -} - -static int -Ones(Mask mask) -{ - register Mask y; - - y = (mask >> 1) &033333333333; - y = mask - y - ((y >>1) & 033333333333); - return (((y + (y >> 3)) & 030707070707) % 077); -} - -Xauth * -XSecurityGenerateAuthorization( - Display *dpy, - Xauth *auth_in, - unsigned long valuemask, - XSecurityAuthorizationAttributes *attributes, - XSecurityAuthorization *auth_id_return) -{ - XExtDisplayInfo *info = find_display (dpy); - register xSecurityGenerateAuthorizationReq *req; - xSecurityGenerateAuthorizationReply rep; - Xauth *auth_return; - unsigned long values[3]; - unsigned long *value = values; - unsigned int nvalues; - - *auth_id_return = 0; /* in case we fail */ - - /* make sure extension is available */ - - SecurityCheckExtension (dpy, info, (Xauth *)NULL); - - LockDisplay(dpy); - SecurityGetReq(SecurityGenerateAuthorization, req, info); - - req->nbytesAuthProto = auth_in->name_length; - req->nbytesAuthData = auth_in->data_length; - - /* adjust length to account for auth name and data */ - req->length += (auth_in->name_length + (unsigned)3) >> 2; - req->length += (auth_in->data_length + (unsigned)3) >> 2; - - /* adjust length to account for list of values */ - req->valueMask = valuemask & XSecurityAllAuthorizationAttributes; - nvalues = Ones(req->valueMask); - req->length += nvalues; - - /* send auth name and data */ - Data(dpy, auth_in->name, auth_in->name_length); - Data(dpy, auth_in->data, auth_in->data_length); - - /* send values */ - if (valuemask & XSecurityTimeout) *value++ = attributes->timeout; - if (valuemask & XSecurityTrustLevel) *value++ = attributes->trust_level; - if (valuemask & XSecurityGroup) *value++ = attributes->group; - if (valuemask & XSecurityEventMask) *value++ = attributes->event_mask; - - nvalues <<= 2; - Data32(dpy, (long *)values, (long)nvalues); - - if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { - UnlockDisplay (dpy); - SyncHandle (); - return (Xauth *)NULL; - } - - *auth_id_return = rep.authId; - - /* Allocate space for the Xauth struct and the auth name and data all - * in one hunk. This lets XSecurityFreeXauth not have to care - * about whether the auth was allocated here or in - * XSecurityAllocXauth; in both cases, you just free one pointer. - */ - - if ((auth_return = (Xauth *)Xcalloc(1, - (sizeof(Xauth) + auth_in->name_length + rep.dataLength)))) - { - auth_return->data_length = rep.dataLength; - auth_return->data = (char *)&auth_return[1]; - _XReadPad(dpy, auth_return->data, (long)rep.dataLength); - - auth_return->name_length = auth_in->name_length; - auth_return->name = auth_return->data + auth_return->data_length; - memcpy(auth_return->name, auth_in->name, auth_return->name_length); - } - else - { - _XEatData(dpy, (unsigned long) (rep.dataLength + 3) & ~3); - } - - UnlockDisplay (dpy); - SyncHandle (); - return auth_return; - -} /* XSecurityGenerateAuthorization */ - -Status -XSecurityRevokeAuthorization( - Display *dpy, - XSecurityAuthorization auth_id) -{ - XExtDisplayInfo *info = find_display (dpy); - xSecurityRevokeAuthorizationReq *req; - - SecurityCheckExtension (dpy, info, 0); - LockDisplay(dpy); - SecurityGetReq(SecurityRevokeAuthorization, req, info); - req->authId = auth_id; - UnlockDisplay (dpy); - SyncHandle (); - return 1; -} /* XSecurityRevokeAuthorization */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include + +static XExtensionInfo _Security_info_data; +static XExtensionInfo *Security_info = &_Security_info_data; +static const char *Security_extension_name = SECURITY_EXTENSION_NAME; + +#define SecurityCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, Security_extension_name, val) +#define SecuritySimpleCheckExtension(dpy,i) \ + XextSimpleCheckExtension (dpy, i, Security_extension_name) + +#define SecurityGetReq(name,req,info) GetReq (name, req); \ + req->reqType = info->codes->major_opcode; \ + req->securityReqType = X_##name; + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +/* + * find_display - locate the display info block + */ +static int close_display(Display *dpy, XExtCodes *codes); +static Bool wire_to_event(Display *dpy, XEvent *event, xEvent *wire); +static Status event_to_wire(Display *dpy, XEvent *event, xEvent *wire); +static char *error_string(Display *dpy, int code, XExtCodes *codes, + char *buf, int n); + +static XExtensionHooks Security_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + wire_to_event, /* wire_to_event */ + event_to_wire, /* event_to_wire */ + NULL, /* error */ + error_string /* error_string */ +}; + +static const char *security_error_list[] = { + "BadAuthorization", + "BadAuthorizationProtocol" +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, Security_info, + Security_extension_name, + &Security_extension_hooks, + XSecurityNumberEvents, NULL) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, Security_info) + +static +XEXT_GENERATE_ERROR_STRING(error_string, Security_extension_name, + XSecurityNumberErrors, security_error_list) + +static Bool +wire_to_event(Display *dpy, XEvent *event, xEvent *wire) +{ + XExtDisplayInfo *info = find_display(dpy); + + SecurityCheckExtension (dpy, info, False); + + switch ((wire->u.u.type & 0x7F) - info->codes->first_event) + { + case XSecurityAuthorizationRevoked: + { + xSecurityAuthorizationRevokedEvent *rwire = + (xSecurityAuthorizationRevokedEvent *)wire; + XSecurityAuthorizationRevokedEvent *revent = + (XSecurityAuthorizationRevokedEvent *)event; + + revent->type = rwire->type & 0x7F; + revent->serial = _XSetLastRequestRead(dpy, + (xGenericReply *) wire); + revent->send_event = (rwire->type & 0x80) != 0; + revent->display = dpy; + revent->auth_id = rwire->authId; + return True; + } + } + return False; +} + +static Status +event_to_wire(Display *dpy, XEvent *event, xEvent *wire) +{ + XExtDisplayInfo *info = find_display(dpy); + + SecurityCheckExtension(dpy, info, False); + + switch ((event->type & 0x7F) - info->codes->first_event) + { + case XSecurityAuthorizationRevoked: + { + xSecurityAuthorizationRevokedEvent *rwire = + (xSecurityAuthorizationRevokedEvent *)wire; + XSecurityAuthorizationRevokedEvent *revent = + (XSecurityAuthorizationRevokedEvent *)event; + rwire->type = revent->type | (revent->send_event ? 0x80 : 0); + rwire->sequenceNumber = revent->serial & 0xFFFF; + return True; + } + } + return False; +} + +/***************************************************************************** + * * + * Security public interfaces * + * * + *****************************************************************************/ + +Status XSecurityQueryExtension ( + Display *dpy, + int *major_version_return, + int *minor_version_return) +{ + XExtDisplayInfo *info = find_display (dpy); + xSecurityQueryVersionReply rep; + register xSecurityQueryVersionReq *req; + + if (!XextHasExtension (info)) + return (Status)0; /* failure */ + + LockDisplay (dpy); + SecurityGetReq (SecurityQueryVersion, req, info); + req->majorVersion = SECURITY_MAJOR_VERSION; + req->minorVersion = SECURITY_MINOR_VERSION; + + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return (Status)0; /* failure */ + } + *major_version_return = rep.majorVersion; + *minor_version_return = rep.minorVersion; + UnlockDisplay (dpy); + + SyncHandle (); + + if (*major_version_return != SECURITY_MAJOR_VERSION) + return (Status)0; /* failure */ + else + return (Status)1; /* success */ +} + +Xauth * +XSecurityAllocXauth(void) +{ + return Xcalloc(1, sizeof(Xauth)); +} + +void +XSecurityFreeXauth(Xauth *auth) +{ + XFree(auth); +} + +static int +Ones(Mask mask) +{ + register Mask y; + + y = (mask >> 1) &033333333333; + y = mask - y - ((y >>1) & 033333333333); + return (((y + (y >> 3)) & 030707070707) % 077); +} + +Xauth * +XSecurityGenerateAuthorization( + Display *dpy, + Xauth *auth_in, + unsigned long valuemask, + XSecurityAuthorizationAttributes *attributes, + XSecurityAuthorization *auth_id_return) +{ + XExtDisplayInfo *info = find_display (dpy); + register xSecurityGenerateAuthorizationReq *req; + xSecurityGenerateAuthorizationReply rep; + Xauth *auth_return; + unsigned long values[3]; + unsigned long *value = values; + unsigned int nvalues; + + *auth_id_return = 0; /* in case we fail */ + + /* make sure extension is available */ + + SecurityCheckExtension (dpy, info, (Xauth *)NULL); + + LockDisplay(dpy); + SecurityGetReq(SecurityGenerateAuthorization, req, info); + + req->nbytesAuthProto = auth_in->name_length; + req->nbytesAuthData = auth_in->data_length; + + /* adjust length to account for auth name and data */ + req->length += (auth_in->name_length + (unsigned)3) >> 2; + req->length += (auth_in->data_length + (unsigned)3) >> 2; + + /* adjust length to account for list of values */ + req->valueMask = valuemask & XSecurityAllAuthorizationAttributes; + nvalues = Ones(req->valueMask); + req->length += nvalues; + + /* send auth name and data */ + Data(dpy, auth_in->name, auth_in->name_length); + Data(dpy, auth_in->data, auth_in->data_length); + + /* send values */ + if (valuemask & XSecurityTimeout) *value++ = attributes->timeout; + if (valuemask & XSecurityTrustLevel) *value++ = attributes->trust_level; + if (valuemask & XSecurityGroup) *value++ = attributes->group; + if (valuemask & XSecurityEventMask) *value++ = attributes->event_mask; + + nvalues <<= 2; + Data32(dpy, (long *)values, (long)nvalues); + + if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay (dpy); + SyncHandle (); + return (Xauth *)NULL; + } + + *auth_id_return = rep.authId; + + /* Allocate space for the Xauth struct and the auth name and data all + * in one hunk. This lets XSecurityFreeXauth not have to care + * about whether the auth was allocated here or in + * XSecurityAllocXauth; in both cases, you just free one pointer. + */ + + if ((auth_return = (Xauth *)Xcalloc(1, + (sizeof(Xauth) + auth_in->name_length + rep.dataLength)))) + { + auth_return->data_length = rep.dataLength; + auth_return->data = (char *)&auth_return[1]; + _XReadPad(dpy, auth_return->data, (long)rep.dataLength); + + auth_return->name_length = auth_in->name_length; + auth_return->name = auth_return->data + auth_return->data_length; + memcpy(auth_return->name, auth_in->name, auth_return->name_length); + } + else + { + _XEatData(dpy, (unsigned long) (rep.dataLength + 3) & ~3); + } + + UnlockDisplay (dpy); + SyncHandle (); + return auth_return; + +} /* XSecurityGenerateAuthorization */ + +Status +XSecurityRevokeAuthorization( + Display *dpy, + XSecurityAuthorization auth_id) +{ + XExtDisplayInfo *info = find_display (dpy); + xSecurityRevokeAuthorizationReq *req; + + SecurityCheckExtension (dpy, info, 0); + LockDisplay(dpy); + SecurityGetReq(SecurityRevokeAuthorization, req, info); + req->authId = auth_id; + UnlockDisplay (dpy); + SyncHandle (); + return 1; +} /* XSecurityRevokeAuthorization */ diff --git a/libXext/src/XShape.c b/libXext/src/XShape.c index 1e3a77f23..6e8fbae9f 100644 --- a/libXext/src/XShape.c +++ b/libXext/src/XShape.c @@ -38,7 +38,7 @@ in this Software without prior written authorization from The Open Group. static XExtensionInfo _shape_info_data; static XExtensionInfo *shape_info = &_shape_info_data; -static /* const */ char *shape_extension_name = SHAPENAME; +static const char *shape_extension_name = SHAPENAME; #define ShapeCheckExtension(dpy,i,val) \ XextCheckExtension (dpy, i, shape_extension_name, val) diff --git a/libXext/src/XShm.c b/libXext/src/XShm.c index e3f8fa09b..f82455c6e 100644 --- a/libXext/src/XShm.c +++ b/libXext/src/XShm.c @@ -40,7 +40,7 @@ in this Software without prior written authorization from The Open Group. static XExtensionInfo _shm_info_data; static XExtensionInfo *shm_info = &_shm_info_data; -static /* const */ char *shm_extension_name = SHMNAME; +static const char *shm_extension_name = SHMNAME; #define ShmCheckExtension(dpy,i,val) \ XextCheckExtension (dpy, i, shm_extension_name, val) @@ -70,7 +70,7 @@ static /* const */ XExtensionHooks shm_extension_hooks = { error_string, /* error_string */ }; -static /* const */ char *shm_error_list[] = { +static const char *shm_error_list[] = { "BadShmSeg", /* BadShmSeg */ }; diff --git a/libXext/src/XSync.c b/libXext/src/XSync.c index 0e19922dd..df7c43542 100644 --- a/libXext/src/XSync.c +++ b/libXext/src/XSync.c @@ -62,7 +62,7 @@ PERFORMANCE OF THIS SOFTWARE. static XExtensionInfo _sync_info_data; static XExtensionInfo *sync_info = &_sync_info_data; -static char *sync_extension_name = SYNC_NAME; +static const char *sync_extension_name = SYNC_NAME; #define SyncCheckExtension(dpy,i,val) \ XextCheckExtension(dpy, i, sync_extension_name, val) @@ -89,7 +89,7 @@ static XExtensionHooks sync_extension_hooks = { error_string, /* error_string */ }; -static char *sync_error_list[] = { +static const char *sync_error_list[] = { "BadCounter", "BadAlarm", "BadFence", diff --git a/libXext/src/Xcup.c b/libXext/src/Xcup.c index ad78699be..bb9e90f7e 100644 --- a/libXext/src/Xcup.c +++ b/libXext/src/Xcup.c @@ -39,7 +39,7 @@ in this Software without prior written authorization from The Open Group. static XExtensionInfo _xcup_info_data; static XExtensionInfo *xcup_info = &_xcup_info_data; -static char *xcup_extension_name = XCUPNAME; +static const char *xcup_extension_name = XCUPNAME; /***************************************************************************** * * diff --git a/libXext/src/Xdbe.c b/libXext/src/Xdbe.c index 1b9e2da52..4b5fa186c 100644 --- a/libXext/src/Xdbe.c +++ b/libXext/src/Xdbe.c @@ -42,7 +42,7 @@ static XExtensionInfo _dbe_info_data; static XExtensionInfo *dbe_info = &_dbe_info_data; -static char *dbe_extension_name = DBE_PROTOCOL_NAME; +static const char *dbe_extension_name = DBE_PROTOCOL_NAME; #define DbeCheckExtension(dpy,i,val) \ XextCheckExtension (dpy, i, dbe_extension_name, val) @@ -86,7 +86,7 @@ static XExtensionHooks dbe_extension_hooks = { error_string, /* error_string */ }; -static char *dbe_error_list[] = { +static const char *dbe_error_list[] = { "BadBuffer", /* DbeBadBuffer */ }; diff --git a/libXext/src/Xge.c b/libXext/src/Xge.c index d28a4f052..74e48020a 100644 --- a/libXext/src/Xge.c +++ b/libXext/src/Xge.c @@ -76,7 +76,7 @@ static Bool _xgeCheckExtension(Display* dpy, XExtDisplayInfo* info); /* main extension information data */ static XExtensionInfo *xge_info; -static char xge_extension_name[] = GE_NAME; +static const char xge_extension_name[] = GE_NAME; static XExtensionHooks xge_extension_hooks = { NULL, /* create_gc */ NULL, /* copy_gc */ diff --git a/libXext/src/extutil.c b/libXext/src/extutil.c index 361a3274d..93cab7397 100644 --- a/libXext/src/extutil.c +++ b/libXext/src/extutil.c @@ -96,7 +96,7 @@ void XextDestroyExtension (XExtensionInfo *info) XExtDisplayInfo *XextAddDisplay ( XExtensionInfo *extinfo, Display *dpy, - char *ext_name, + _Xconst char *ext_name, XExtensionHooks *hooks, int nevents, XPointer data) diff --git a/libXinerama/src/Xinerama.c b/libXinerama/src/Xinerama.c index 93b1a9f21..7d7e4d856 100644 --- a/libXinerama/src/Xinerama.c +++ b/libXinerama/src/Xinerama.c @@ -34,7 +34,7 @@ Equipment Corporation. static XExtensionInfo _panoramiX_ext_info_data; static XExtensionInfo *panoramiX_ext_info = &_panoramiX_ext_info_data; -static /* const */ char *panoramiX_extension_name = PANORAMIX_PROTOCOL_NAME; +static const char *panoramiX_extension_name = PANORAMIX_PROTOCOL_NAME; #define PanoramiXCheckExtension(dpy,i,val) \ XextCheckExtension (dpy, i, panoramiX_extension_name, val) diff --git a/libXmu/include/X11/Xmu/EditresP.h b/libXmu/include/X11/Xmu/EditresP.h index 61ec51dbe..ed9dd41ea 100644 --- a/libXmu/include/X11/Xmu/EditresP.h +++ b/libXmu/include/X11/Xmu/EditresP.h @@ -335,7 +335,7 @@ _XFUNCPROTOBEGIN void _XEditResPutString8 ( ProtocolStream *stream, - char *str + _Xconst char *str ); void _XEditResPut8 diff --git a/libXmu/src/Atoms.c b/libXmu/src/Atoms.c index 412f399e7..6f0ca64a0 100644 --- a/libXmu/src/Atoms.c +++ b/libXmu/src/Atoms.c @@ -50,7 +50,7 @@ typedef struct _DisplayRec { } DisplayRec; struct _AtomRec { - char *name; + _Xconst char *name; DisplayRec* head; }; @@ -60,15 +60,9 @@ struct _AtomRec { #define STATIC static #endif -#if !defined(UNIXCPP) || defined(ANSICPP) #define DeclareAtom(atom,text) \ STATIC struct _AtomRec __##atom = { text, NULL }; \ AtomPtr _##atom = &__##atom; -#else -#define DeclareAtom(atom,text) \ -STATIC struct _AtomRec __/**/atom = { text, NULL }; \ -AtomPtr _/**/atom = &__/**/atom; -#endif DeclareAtom(XA_ATOM_PAIR, "ATOM_PAIR" ) DeclareAtom(XA_CHARACTER_POSITION, "CHARACTER_POSITION" ) @@ -105,7 +99,7 @@ AtomPtr XmuMakeAtom(_Xconst char *name) { AtomPtr ptr = XtNew(struct _AtomRec); - ptr->name = (char *) name; + ptr->name = name; ptr->head = NULL; return ptr; } @@ -113,7 +107,7 @@ XmuMakeAtom(_Xconst char *name) char * XmuNameOfAtom(AtomPtr atom_ptr) { - return atom_ptr->name; + return (char *) atom_ptr->name; } diff --git a/libXmu/src/DefErrMsg.c b/libXmu/src/DefErrMsg.c index 091d2c4aa..3cb914a9d 100644 --- a/libXmu/src/DefErrMsg.c +++ b/libXmu/src/DefErrMsg.c @@ -43,7 +43,7 @@ XmuPrintDefaultErrorMessage(Display *dpy, XErrorEvent *event, FILE *fp) char buffer[BUFSIZ]; char mesg[BUFSIZ]; char number[32]; - char *mtype = "XlibMessage"; + _Xconst char *mtype = "XlibMessage"; register _XExtension *ext = (_XExtension *)NULL; _XExtension *bext = (_XExtension *)NULL; XGetErrorText(dpy, event->error_code, buffer, BUFSIZ); diff --git a/libXmu/src/EditresCom.c b/libXmu/src/EditresCom.c index b4554e142..716a2b3c6 100644 --- a/libXmu/src/EditresCom.c +++ b/libXmu/src/EditresCom.c @@ -142,13 +142,13 @@ static Boolean CvtStringToBlock(Display*, XrmValue*, Cardinal*, XrmValue*, XrmValue*, XtPointer*); static EditresEvent *BuildEvent(Widget, Atom, XtPointer, ResIdent, unsigned long); -static char *DoFindChild(Widget, EditresEvent*, ProtocolStream*); -static char *DoGetGeometry(Widget, EditresEvent*, ProtocolStream*); -static char *DoGetResources(Widget, EditresEvent*, ProtocolStream*); -static char *DoSetValues(Widget, EditresEvent*, ProtocolStream*); +static _Xconst char *DoFindChild(Widget, EditresEvent*, ProtocolStream*); +static _Xconst char *DoGetGeometry(Widget, EditresEvent*, ProtocolStream*); +static _Xconst char *DoGetResources(Widget, EditresEvent*, ProtocolStream*); +static _Xconst char *DoSetValues(Widget, EditresEvent*, ProtocolStream*); static void DumpChildren(Widget, ProtocolStream*, unsigned short*); -static char *DumpValues(Widget, EditresEvent*, ProtocolStream*); -static char *DumpWidgets(Widget, EditresEvent*, ProtocolStream*); +static _Xconst char *DumpValues(Widget, EditresEvent*, ProtocolStream*); +static _Xconst char *DumpWidgets(Widget, EditresEvent*, ProtocolStream*); static void ExecuteCommand(Widget, Atom, ResIdent, EditresEvent*); static void ExecuteGetGeometry(Widget, ProtocolStream*); static void ExecuteGetResources(Widget w, ProtocolStream *stream); @@ -167,8 +167,8 @@ static Bool PositionInChild(Widget, int, int); static int qcmp_widget_list(register _Xconst void*, register _Xconst void*); static void SendCommand(Widget, Atom, ResIdent, EditResError, ProtocolStream*); -static void SendFailure(Widget, Atom, ResIdent, char*); -static char *VerifyWidget(Widget, WidgetInfo*); +static void SendFailure(Widget, Atom, ResIdent, _Xconst char*); +static _Xconst char *VerifyWidget(Widget, WidgetInfo*); /* * External @@ -215,13 +215,13 @@ _XEditResCheckMessages(Widget w, XtPointer data, XEvent *event, Boolean *cont) if (!first_time) { Atom atoms[4]; - static char *names[] = { + static _Xconst char *names[] = { EDITRES_NAME, EDITRES_COMMAND_ATOM, EDITRES_PROTOCOL_ATOM, EDITRES_CLIENT_VALUE }; first_time = True; - XInternAtoms(dpy, names, 4, False, atoms); + XInternAtoms(dpy, (char **) names, 4, False, atoms); res_editor = atoms[0]; res_editor_command = atoms[1]; res_editor_protocol = atoms[2]; @@ -479,8 +479,8 @@ GetCommand(Widget w, XtPointer data, Atom *selection, Atom *type, static void ExecuteCommand(Widget w, Atom sel, ResIdent ident, EditresEvent *event) { - char *(*func)(Widget, EditresEvent*, ProtocolStream*); - char *str; + _Xconst char *(*func)(Widget, EditresEvent*, ProtocolStream*); + _Xconst char *str; if (globals.block == BlockAll) { @@ -609,7 +609,7 @@ CommandDone(Widget widget, Atom *selection, Atom *target) * Sends a failure message */ static void -SendFailure(Widget w, Atom sel, ResIdent ident, char *str) +SendFailure(Widget w, Atom sel, ResIdent ident, _Xconst char *str) { _XEditResResetStream(&globals.stream); _XEditResPutString8(&globals.stream, str); @@ -889,7 +889,7 @@ IsChild(Widget top, Widget parent, Widget child) * Description: * Makes sure all the widgets still exist */ -static char * +static _Xconst char * VerifyWidget(Widget w, WidgetInfo *info) { Widget top; @@ -938,10 +938,10 @@ VerifyWidget(Widget w, WidgetInfo *info) * Returns: * NULL */ -static char * +static _Xconst char * DoSetValues(Widget w, EditresEvent *event, ProtocolStream *stream) { - char *str; + _Xconst char *str; register unsigned i; unsigned short count = 0; SetValuesEvent *sv_event = (SetValuesEvent *)event; @@ -1078,7 +1078,7 @@ ExecuteSetValues(Widget w, SetValuesEvent *sv_event, WidgetInfo *entry, */ #define TOOLKIT_TYPE ("Xt") /*ARGSUSED*/ -static char * +static _Xconst char * DumpWidgets(Widget w, EditresEvent *event, ProtocolStream *stream) { unsigned short count = 0; @@ -1201,11 +1201,11 @@ DumpChildren(Widget w, ProtocolStream *stream, unsigned short *count) * Returns: * NULL */ -static char * +static _Xconst char * DoGetGeometry(Widget w, EditresEvent *event, ProtocolStream *stream) { unsigned i; - char *str; + _Xconst char *str; GetGeomEvent *geom_event = (GetGeomEvent *)event; _XEditResPut16(stream, geom_event->num_entries); @@ -1414,10 +1414,10 @@ _FindChild(Widget parent, int x, int y) * An allocated error message if something went horribly wrong and * no set values were performed, else NULL. */ -static char * +static _Xconst char * DoFindChild(Widget w, EditresEvent *event, ProtocolStream *stream) { - char *str; + _Xconst char *str; Widget parent, child; Position parent_x, parent_y; FindChildEvent *find_event = (FindChildEvent *)event; @@ -1456,11 +1456,11 @@ DoFindChild(Widget w, EditresEvent *event, ProtocolStream *stream) * Returns: * NULL */ -static char * +static _Xconst char * DoGetResources(Widget w, EditresEvent *event, ProtocolStream *stream) { unsigned int i; - char *str; + _Xconst char *str; GetResEvent *res_event = (GetResEvent *)event; _XEditResPut16(stream, res_event->num_entries); /* number of replys */ @@ -1558,12 +1558,12 @@ ExecuteGetResources(Widget w, ProtocolStream *stream) * NULL */ /*ARGSUSED*/ -static char * +static _Xconst char * DumpValues(Widget w, EditresEvent* event, ProtocolStream* stream) { - char *str; + _Xconst char *str; Arg warg[1]; - String res_value = NULL; + _Xconst _XtString res_value = NULL; GetValuesEvent *gv_event = (GetValuesEvent *)event; /* put the count in the stream */ @@ -1645,7 +1645,7 @@ InsertWidget(ProtocolStream *stream, Widget w) * Inserts a string into the protocol stream. */ void -_XEditResPutString8(ProtocolStream *stream, char *str) +_XEditResPutString8(ProtocolStream *stream, _Xconst char *str) { int i, len = strlen(str); diff --git a/libXmu/src/StrToGrav.c b/libXmu/src/StrToGrav.c index 44cc13bb0..ca8bb5322 100644 --- a/libXmu/src/StrToGrav.c +++ b/libXmu/src/StrToGrav.c @@ -39,7 +39,7 @@ in this Software without prior written authorization from The Open Group. */ static struct _namepair { XrmQuark quark; - char *name; + _Xconst char *name; XtGravity gravity; } names[] = { { NULLQUARK, XtEForget, ForgetGravity }, diff --git a/libXmu/src/sharedlib.c b/libXmu/src/sharedlib.c index 4bb8c3b5f..b47213df5 100644 --- a/libXmu/src/sharedlib.c +++ b/libXmu/src/sharedlib.c @@ -36,15 +36,9 @@ struct _AtomRec { struct _DisplayRec* head; }; -#if !defined(UNIXCPP) || defined(ANSICPP) #define DeclareAtom(atom) \ extern struct _AtomRec __##atom; \ AtomPtr _##atom = &__##atom; -#else -#define DeclareAtom(atom) \ -extern struct _AtomRec __/**/atom; \ -AtomPtr _/**/atom = &__/**/atom; -#endif DeclareAtom(XA_ATOM_PAIR) DeclareAtom(XA_CHARACTER_POSITION) diff --git a/libfontenc/src/encparse.c b/libfontenc/src/encparse.c index 03b2afa63..cbcac8023 100644 --- a/libfontenc/src/encparse.c +++ b/libfontenc/src/encparse.c @@ -28,11 +28,8 @@ THE SOFTWARE. to be pure ASCII. Bloody ``Code Set Independence''. */ #include -#include - -#if defined(__SCO__) || defined(__UNIXWARE__) #include -#endif +#include #include diff --git a/libfontenc/src/fontenc.c b/libfontenc/src/fontenc.c index 837c92558..fb56ff173 100644 --- a/libfontenc/src/fontenc.c +++ b/libfontenc/src/fontenc.c @@ -23,11 +23,7 @@ THE SOFTWARE. /* Backend-independent encoding code */ #include - -#if defined(__SCO__) || defined(__UNIXWARE__) #include -#endif - #include #define FALSE 0 diff --git a/libxcb/xcb-proto/xcb-proto.pc.in b/libxcb/xcb-proto/xcb-proto.pc.in index 6cbcf2779..d312e6e5d 100644 --- a/libxcb/xcb-proto/xcb-proto.pc.in +++ b/libxcb/xcb-proto/xcb-proto.pc.in @@ -1,6 +1,8 @@ prefix=@prefix@ +exec_prefix=@exec_prefix@ datarootdir=@datarootdir@ datadir=@datadir@ +libdir=@libdir@ xcbincludedir=@xcbincludedir@ pythondir=@pythondir@ diff --git a/mesalib/bin/mklib b/mesalib/bin/mklib index fd87aad42..70bd1a27a 100644 --- a/mesalib/bin/mklib +++ b/mesalib/bin/mklib @@ -260,7 +260,7 @@ if [ $STATIC = 1 ]; then NEWOBJECTS="" for OBJ in $OBJECTS ; do case $OBJ in - -Wl,*) + -Wl,*|-L*|-l*) echo "mklib: warning: ignoring $OBJ for static library" ;; *) diff --git a/mesalib/docs/viewperf.html b/mesalib/docs/viewperf.html index cef584fd8..bb3852734 100644 --- a/mesalib/docs/viewperf.html +++ b/mesalib/docs/viewperf.html @@ -34,6 +34,19 @@ they'll be fixed in the future. +

Catia-03 test 2

+ +

+This test creates over 38000 vertex buffer objects. On some systems +this can exceed the maximum number of buffer allocations. Mesa +generates GL_OUT_OF_MEMORY errors in this situation, but Viewperf +does no error checking and continues. When this happens, some drawing +commands become no-ops. This can also eventually lead to a segfault +either in Viewperf or the Mesa driver. +

+ + +

Catia-03 tests 3, 4, 8

diff --git a/mesalib/src/gallium/auxiliary/util/u_blit.c b/mesalib/src/gallium/auxiliary/util/u_blit.c index 6a4324bc2..3a0d7d424 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blit.c +++ b/mesalib/src/gallium/auxiliary/util/u_blit.c @@ -286,8 +286,10 @@ setup_vertex_data_tex(struct blit_state *ctx, offset = get_next_slot( ctx ); - pipe_buffer_write_nooverlap(ctx->pipe, ctx->vbuf, - offset, sizeof(ctx->vertices), ctx->vertices); + if (ctx->vbuf) { + pipe_buffer_write_nooverlap(ctx->pipe, ctx->vbuf, + offset, sizeof(ctx->vertices), ctx->vertices); + } return offset; } @@ -599,10 +601,12 @@ util_blit_pixels_writemask(struct blit_state *ctx, s1, t1, z); - util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, offset, - PIPE_PRIM_TRIANGLE_FAN, - 4, /* verts */ - 2); /* attribs/vert */ + if (ctx->vbuf) { + util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, offset, + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + 2); /* attribs/vert */ + } /* restore state we changed */ cso_restore_blend(ctx->cso); diff --git a/mesalib/src/gallium/auxiliary/util/u_format_pack.py b/mesalib/src/gallium/auxiliary/util/u_format_pack.py index 5cfbe323d..14a504944 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format_pack.py +++ b/mesalib/src/gallium/auxiliary/util/u_format_pack.py @@ -150,6 +150,11 @@ def is_format_pure_signed(format): def native_type(format): '''Get the native appropriate for a format.''' + if format.name == 'PIPE_FORMAT_R11G11B10_FLOAT': + return 'uint32_t' + if format.name == 'PIPE_FORMAT_R9G9B9E5_FLOAT': + return 'uint32_t' + if format.layout == PLAIN: if not format.is_array(): # For arithmetic pixel formats return the integer type that matches the whole pixel diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources index b4bfff09c..c65bfe4ff 100644 --- a/mesalib/src/glsl/Makefile.sources +++ b/mesalib/src/glsl/Makefile.sources @@ -20,6 +20,7 @@ LIBGLSL_CXX_SOURCES := \ ast_function.cpp \ ast_to_hir.cpp \ ast_type.cpp \ + builtin_variables.cpp \ glsl_parser_extras.cpp \ glsl_types.cpp \ glsl_symbol_table.cpp \ @@ -40,7 +41,6 @@ LIBGLSL_CXX_SOURCES := \ ir_rvalue_visitor.cpp \ ir_set_program_inouts.cpp \ ir_validate.cpp \ - ir_variable.cpp \ ir_variable_refcount.cpp \ linker.cpp \ link_functions.cpp \ diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp new file mode 100644 index 000000000..ed6b922ca --- /dev/null +++ b/mesalib/src/glsl/builtin_variables.cpp @@ -0,0 +1,1001 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "ir.h" +#include "glsl_parser_extras.h" +#include "glsl_symbol_table.h" +#include "main/core.h" +#include "main/uniforms.h" +#include "program/prog_parameter.h" +#include "program/prog_statevars.h" +#include "program/prog_instruction.h" + +static void generate_ARB_draw_buffers_variables(exec_list *, + struct _mesa_glsl_parse_state *, + bool, _mesa_glsl_parser_targets); + +static void +generate_ARB_draw_instanced_variables(exec_list *, + struct _mesa_glsl_parse_state *, + bool, _mesa_glsl_parser_targets); + +struct builtin_variable { + enum ir_variable_mode mode; + int slot; + const char *type; + const char *name; +}; + +static const builtin_variable builtin_core_vs_variables[] = { + { ir_var_out, VERT_RESULT_HPOS, "vec4", "gl_Position" }, + { ir_var_out, VERT_RESULT_PSIZ, "float", "gl_PointSize" }, +}; + +static const builtin_variable builtin_core_fs_variables[] = { + { ir_var_in, FRAG_ATTRIB_WPOS, "vec4", "gl_FragCoord" }, + { ir_var_in, FRAG_ATTRIB_FACE, "bool", "gl_FrontFacing" }, + { ir_var_out, FRAG_RESULT_COLOR, "vec4", "gl_FragColor" }, +}; + +static const builtin_variable builtin_100ES_fs_variables[] = { + { ir_var_in, FRAG_ATTRIB_PNTC, "vec2", "gl_PointCoord" }, +}; + +static const builtin_variable builtin_110_fs_variables[] = { + { ir_var_out, FRAG_RESULT_DEPTH, "float", "gl_FragDepth" }, +}; + +static const builtin_variable builtin_110_deprecated_fs_variables[] = { + { ir_var_in, FRAG_ATTRIB_COL0, "vec4", "gl_Color" }, + { ir_var_in, FRAG_ATTRIB_COL1, "vec4", "gl_SecondaryColor" }, + { ir_var_in, FRAG_ATTRIB_FOGC, "float", "gl_FogFragCoord" }, +}; + +static const builtin_variable builtin_110_deprecated_vs_variables[] = { + { ir_var_in, VERT_ATTRIB_POS, "vec4", "gl_Vertex" }, + { ir_var_in, VERT_ATTRIB_NORMAL, "vec3", "gl_Normal" }, + { ir_var_in, VERT_ATTRIB_COLOR0, "vec4", "gl_Color" }, + { ir_var_in, VERT_ATTRIB_COLOR1, "vec4", "gl_SecondaryColor" }, + { ir_var_in, VERT_ATTRIB_TEX0, "vec4", "gl_MultiTexCoord0" }, + { ir_var_in, VERT_ATTRIB_TEX1, "vec4", "gl_MultiTexCoord1" }, + { ir_var_in, VERT_ATTRIB_TEX2, "vec4", "gl_MultiTexCoord2" }, + { ir_var_in, VERT_ATTRIB_TEX3, "vec4", "gl_MultiTexCoord3" }, + { ir_var_in, VERT_ATTRIB_TEX4, "vec4", "gl_MultiTexCoord4" }, + { ir_var_in, VERT_ATTRIB_TEX5, "vec4", "gl_MultiTexCoord5" }, + { ir_var_in, VERT_ATTRIB_TEX6, "vec4", "gl_MultiTexCoord6" }, + { ir_var_in, VERT_ATTRIB_TEX7, "vec4", "gl_MultiTexCoord7" }, + { ir_var_in, VERT_ATTRIB_FOG, "float", "gl_FogCoord" }, + { ir_var_out, VERT_RESULT_CLIP_VERTEX, "vec4", "gl_ClipVertex" }, + { ir_var_out, VERT_RESULT_COL0, "vec4", "gl_FrontColor" }, + { ir_var_out, VERT_RESULT_BFC0, "vec4", "gl_BackColor" }, + { ir_var_out, VERT_RESULT_COL1, "vec4", "gl_FrontSecondaryColor" }, + { ir_var_out, VERT_RESULT_BFC1, "vec4", "gl_BackSecondaryColor" }, + { ir_var_out, VERT_RESULT_FOGC, "float", "gl_FogFragCoord" }, +}; + +static const builtin_variable builtin_120_fs_variables[] = { + { ir_var_in, FRAG_ATTRIB_PNTC, "vec2", "gl_PointCoord" }, +}; + +static const builtin_variable builtin_130_vs_variables[] = { + { ir_var_system_value, SYSTEM_VALUE_VERTEX_ID, "int", "gl_VertexID" }, +}; + +static const builtin_variable builtin_110_deprecated_uniforms[] = { + { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrix" }, + { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrix" }, + { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrix" }, + { ir_var_uniform, -1, "mat3", "gl_NormalMatrix" }, + { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixInverse" }, + { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixInverse" }, + { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverse" }, + { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixTranspose" }, + { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixTranspose" }, + { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixTranspose" }, + { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixInverseTranspose" }, + { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixInverseTranspose" }, + { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverseTranspose" }, + { ir_var_uniform, -1, "float", "gl_NormalScale" }, + { ir_var_uniform, -1, "gl_LightModelParameters", "gl_LightModel"}, + + /* Mesa-internal ATI_envmap_bumpmap state. */ + { ir_var_uniform, -1, "vec2", "gl_BumpRotMatrix0MESA"}, + { ir_var_uniform, -1, "vec2", "gl_BumpRotMatrix1MESA"}, + { ir_var_uniform, -1, "vec4", "gl_FogParamsOptimizedMESA"}, +}; + +static struct gl_builtin_uniform_element gl_DepthRange_elements[] = { + {"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX}, + {"far", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY}, + {"diff", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ}, +}; + +static struct gl_builtin_uniform_element gl_ClipPlane_elements[] = { + {NULL, {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW} +}; + +static struct gl_builtin_uniform_element gl_Point_elements[] = { + {"size", {STATE_POINT_SIZE}, SWIZZLE_XXXX}, + {"sizeMin", {STATE_POINT_SIZE}, SWIZZLE_YYYY}, + {"sizeMax", {STATE_POINT_SIZE}, SWIZZLE_ZZZZ}, + {"fadeThresholdSize", {STATE_POINT_SIZE}, SWIZZLE_WWWW}, + {"distanceConstantAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX}, + {"distanceLinearAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY}, + {"distanceQuadraticAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ}, +}; + +static struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = { + {"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW}, + {"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW}, + {"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW}, + {"specular", {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW}, + {"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX}, +}; + +static struct gl_builtin_uniform_element gl_BackMaterial_elements[] = { + {"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW}, + {"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW}, + {"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW}, + {"specular", {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW}, + {"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX}, +}; + +static struct gl_builtin_uniform_element gl_LightSource_elements[] = { + {"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW}, + {"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW}, + {"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW}, + {"position", {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW}, + {"halfVector", {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW}, + {"spotDirection", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, + MAKE_SWIZZLE4(SWIZZLE_X, + SWIZZLE_Y, + SWIZZLE_Z, + SWIZZLE_Z)}, + {"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW}, + {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX}, + {"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW}, + {"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX}, + {"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY}, + {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ}, +}; + +static struct gl_builtin_uniform_element gl_LightModel_elements[] = { + {"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = { + {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_BackLightModelProduct_elements[] = { + {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = { + {"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW}, + {"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW}, + {"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = { + {"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW}, + {"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW}, + {"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = { + {NULL, {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_EyePlaneS_elements[] = { + {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_EyePlaneT_elements[] = { + {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_EyePlaneR_elements[] = { + {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_EyePlaneQ_elements[] = { + {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_ObjectPlaneS_elements[] = { + {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_ObjectPlaneT_elements[] = { + {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_ObjectPlaneR_elements[] = { + {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_ObjectPlaneQ_elements[] = { + {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_Fog_elements[] = { + {"color", {STATE_FOG_COLOR}, SWIZZLE_XYZW}, + {"density", {STATE_FOG_PARAMS}, SWIZZLE_XXXX}, + {"start", {STATE_FOG_PARAMS}, SWIZZLE_YYYY}, + {"end", {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ}, + {"scale", {STATE_FOG_PARAMS}, SWIZZLE_WWWW}, +}; + +static struct gl_builtin_uniform_element gl_NormalScale_elements[] = { + {NULL, {STATE_NORMAL_SCALE}, SWIZZLE_XXXX}, +}; + +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_BumpRotMatrix1MESA_elements[] = { + {NULL, {STATE_INTERNAL, STATE_ROT_MATRIX_1}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_FogParamsOptimizedMESA_elements[] = { + {NULL, {STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_CurrentAttribVertMESA_elements[] = { + {NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB, 0}, SWIZZLE_XYZW}, +}; + +static struct gl_builtin_uniform_element gl_CurrentAttribFragMESA_elements[] = { + {NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, 0}, SWIZZLE_XYZW}, +}; + +#define MATRIX(name, statevar, modifier) \ + static struct gl_builtin_uniform_element name ## _elements[] = { \ + { NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW }, \ + { NULL, { statevar, 0, 1, 1, modifier}, SWIZZLE_XYZW }, \ + { NULL, { statevar, 0, 2, 2, modifier}, SWIZZLE_XYZW }, \ + { NULL, { statevar, 0, 3, 3, modifier}, SWIZZLE_XYZW }, \ + } + +MATRIX(gl_ModelViewMatrix, + STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE); +MATRIX(gl_ModelViewMatrixInverse, + STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS); +MATRIX(gl_ModelViewMatrixTranspose, + STATE_MODELVIEW_MATRIX, 0); +MATRIX(gl_ModelViewMatrixInverseTranspose, + STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE); + +MATRIX(gl_ProjectionMatrix, + STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE); +MATRIX(gl_ProjectionMatrixInverse, + STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS); +MATRIX(gl_ProjectionMatrixTranspose, + STATE_PROJECTION_MATRIX, 0); +MATRIX(gl_ProjectionMatrixInverseTranspose, + STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE); + +MATRIX(gl_ModelViewProjectionMatrix, + STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE); +MATRIX(gl_ModelViewProjectionMatrixInverse, + STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS); +MATRIX(gl_ModelViewProjectionMatrixTranspose, + STATE_MVP_MATRIX, 0); +MATRIX(gl_ModelViewProjectionMatrixInverseTranspose, + STATE_MVP_MATRIX, STATE_MATRIX_INVERSE); + +MATRIX(gl_TextureMatrix, + STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE); +MATRIX(gl_TextureMatrixInverse, + STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS); +MATRIX(gl_TextureMatrixTranspose, + STATE_TEXTURE_MATRIX, 0); +MATRIX(gl_TextureMatrixInverseTranspose, + STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE); + +static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = { + { NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE}, + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) }, + { NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE}, + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) }, + { NULL, { STATE_MODELVIEW_MATRIX, 0, 2, 2, STATE_MATRIX_INVERSE}, + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) }, +}; + +#undef MATRIX + +#define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)} + +const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = { + STATEVAR(gl_DepthRange), + STATEVAR(gl_ClipPlane), + STATEVAR(gl_Point), + STATEVAR(gl_FrontMaterial), + STATEVAR(gl_BackMaterial), + STATEVAR(gl_LightSource), + STATEVAR(gl_LightModel), + STATEVAR(gl_FrontLightModelProduct), + STATEVAR(gl_BackLightModelProduct), + STATEVAR(gl_FrontLightProduct), + STATEVAR(gl_BackLightProduct), + STATEVAR(gl_TextureEnvColor), + STATEVAR(gl_EyePlaneS), + STATEVAR(gl_EyePlaneT), + STATEVAR(gl_EyePlaneR), + STATEVAR(gl_EyePlaneQ), + STATEVAR(gl_ObjectPlaneS), + STATEVAR(gl_ObjectPlaneT), + STATEVAR(gl_ObjectPlaneR), + STATEVAR(gl_ObjectPlaneQ), + STATEVAR(gl_Fog), + + STATEVAR(gl_ModelViewMatrix), + STATEVAR(gl_ModelViewMatrixInverse), + STATEVAR(gl_ModelViewMatrixTranspose), + STATEVAR(gl_ModelViewMatrixInverseTranspose), + + STATEVAR(gl_ProjectionMatrix), + STATEVAR(gl_ProjectionMatrixInverse), + STATEVAR(gl_ProjectionMatrixTranspose), + STATEVAR(gl_ProjectionMatrixInverseTranspose), + + STATEVAR(gl_ModelViewProjectionMatrix), + STATEVAR(gl_ModelViewProjectionMatrixInverse), + STATEVAR(gl_ModelViewProjectionMatrixTranspose), + STATEVAR(gl_ModelViewProjectionMatrixInverseTranspose), + + STATEVAR(gl_TextureMatrix), + STATEVAR(gl_TextureMatrixInverse), + STATEVAR(gl_TextureMatrixTranspose), + STATEVAR(gl_TextureMatrixInverseTranspose), + + STATEVAR(gl_NormalMatrix), + STATEVAR(gl_NormalScale), + + STATEVAR(gl_BumpRotMatrix0MESA), + STATEVAR(gl_BumpRotMatrix1MESA), + STATEVAR(gl_FogParamsOptimizedMESA), + STATEVAR(gl_CurrentAttribVertMESA), + STATEVAR(gl_CurrentAttribFragMESA), + + {NULL, NULL, 0} +}; + +static ir_variable * +add_variable(exec_list *instructions, glsl_symbol_table *symtab, + const char *name, const glsl_type *type, + enum ir_variable_mode mode, int slot) +{ + ir_variable *var = new(symtab) ir_variable(type, name, mode); + + switch (var->mode) { + case ir_var_auto: + case ir_var_in: + case ir_var_const_in: + case ir_var_uniform: + case ir_var_system_value: + var->read_only = true; + break; + case ir_var_inout: + case ir_var_out: + break; + default: + assert(0); + break; + } + + var->location = slot; + var->explicit_location = (slot >= 0); + + /* Once the variable is created an initialized, add it to the symbol table + * and add the declaration to the IR stream. + */ + instructions->push_tail(var); + + symtab->add_variable(var); + return var; +} + +static ir_variable * +add_uniform(exec_list *instructions, glsl_symbol_table *symtab, + const char *name, const glsl_type *type) +{ + ir_variable *const uni = + add_variable(instructions, symtab, name, type, ir_var_uniform, -1); + + unsigned i; + for (i = 0; _mesa_builtin_uniform_desc[i].name != NULL; i++) { + if (strcmp(_mesa_builtin_uniform_desc[i].name, name) == 0) { + break; + } + } + + assert(_mesa_builtin_uniform_desc[i].name != NULL); + const struct gl_builtin_uniform_desc* const statevar = + &_mesa_builtin_uniform_desc[i]; + + const unsigned array_count = type->is_array() ? type->length : 1; + uni->num_state_slots = array_count * statevar->num_elements; + + ir_state_slot *slots = + ralloc_array(uni, ir_state_slot, uni->num_state_slots); + + uni->state_slots = slots; + + for (unsigned a = 0; a < array_count; a++) { + for (unsigned j = 0; j < statevar->num_elements; j++) { + struct gl_builtin_uniform_element *element = &statevar->elements[j]; + + memcpy(slots->tokens, element->tokens, sizeof(element->tokens)); + if (type->is_array()) { + if (strcmp(name, "gl_CurrentAttribVertMESA") == 0 || + strcmp(name, "gl_CurrentAttribFragMESA") == 0) { + slots->tokens[2] = a; + } else { + slots->tokens[1] = a; + } + } + + slots->swizzle = element->swizzle; + slots++; + } + } + + return uni; +} + +static void +add_builtin_variable(exec_list *instructions, glsl_symbol_table *symtab, + const builtin_variable *proto) +{ + /* Create a new variable declaration from the description supplied by + * the caller. + */ + const glsl_type *const type = symtab->get_type(proto->type); + + assert(type != NULL); + + if (proto->mode == ir_var_uniform) { + add_uniform(instructions, symtab, proto->name, type); + } else { + add_variable(instructions, symtab, proto->name, type, proto->mode, + proto->slot); + } +} + +static ir_variable * +add_builtin_constant(exec_list *instructions, glsl_symbol_table *symtab, + const char *name, int value) +{ + ir_variable *const var = add_variable(instructions, symtab, + name, glsl_type::int_type, + ir_var_auto, -1); + var->constant_value = new(var) ir_constant(value); + var->constant_initializer = new(var) ir_constant(value); + var->has_initializer = true; + return var; +} + +/* Several constants in GLSL ES have different names than normal desktop GLSL. + * Therefore, this function should only be called on the ES path. + */ +static void +generate_100ES_uniforms(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + glsl_symbol_table *const symtab = state->symbols; + + add_builtin_constant(instructions, symtab, "gl_MaxVertexAttribs", + state->Const.MaxVertexAttribs); + add_builtin_constant(instructions, symtab, "gl_MaxVertexUniformVectors", + state->Const.MaxVertexUniformComponents); + add_builtin_constant(instructions, symtab, "gl_MaxVaryingVectors", + state->Const.MaxVaryingFloats / 4); + add_builtin_constant(instructions, symtab, "gl_MaxVertexTextureImageUnits", + state->Const.MaxVertexTextureImageUnits); + add_builtin_constant(instructions, symtab, "gl_MaxCombinedTextureImageUnits", + state->Const.MaxCombinedTextureImageUnits); + add_builtin_constant(instructions, symtab, "gl_MaxTextureImageUnits", + state->Const.MaxTextureImageUnits); + add_builtin_constant(instructions, symtab, "gl_MaxFragmentUniformVectors", + state->Const.MaxFragmentUniformComponents); + + add_uniform(instructions, symtab, "gl_DepthRange", + state->symbols->get_type("gl_DepthRangeParameters")); +} + +static void +generate_110_uniforms(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + glsl_symbol_table *const symtab = state->symbols; + + for (unsigned i = 0 + ; i < Elements(builtin_110_deprecated_uniforms) + ; i++) { + add_builtin_variable(instructions, symtab, + & builtin_110_deprecated_uniforms[i]); + } + + add_builtin_constant(instructions, symtab, "gl_MaxLights", + state->Const.MaxLights); + add_builtin_constant(instructions, symtab, "gl_MaxClipPlanes", + state->Const.MaxClipPlanes); + add_builtin_constant(instructions, symtab, "gl_MaxTextureUnits", + state->Const.MaxTextureUnits); + add_builtin_constant(instructions, symtab, "gl_MaxTextureCoords", + state->Const.MaxTextureCoords); + add_builtin_constant(instructions, symtab, "gl_MaxVertexAttribs", + state->Const.MaxVertexAttribs); + add_builtin_constant(instructions, symtab, "gl_MaxVertexUniformComponents", + state->Const.MaxVertexUniformComponents); + add_builtin_constant(instructions, symtab, "gl_MaxVaryingFloats", + state->Const.MaxVaryingFloats); + add_builtin_constant(instructions, symtab, "gl_MaxVertexTextureImageUnits", + state->Const.MaxVertexTextureImageUnits); + add_builtin_constant(instructions, symtab, "gl_MaxCombinedTextureImageUnits", + state->Const.MaxCombinedTextureImageUnits); + add_builtin_constant(instructions, symtab, "gl_MaxTextureImageUnits", + state->Const.MaxTextureImageUnits); + add_builtin_constant(instructions, symtab, "gl_MaxFragmentUniformComponents", + state->Const.MaxFragmentUniformComponents); + + const glsl_type *const mat4_array_type = + glsl_type::get_array_instance(glsl_type::mat4_type, + state->Const.MaxTextureCoords); + + add_uniform(instructions, symtab, "gl_TextureMatrix", mat4_array_type); + add_uniform(instructions, symtab, "gl_TextureMatrixInverse", mat4_array_type); + add_uniform(instructions, symtab, "gl_TextureMatrixTranspose", mat4_array_type); + add_uniform(instructions, symtab, "gl_TextureMatrixInverseTranspose", mat4_array_type); + + add_uniform(instructions, symtab, "gl_DepthRange", + symtab->get_type("gl_DepthRangeParameters")); + + add_uniform(instructions, symtab, "gl_ClipPlane", + glsl_type::get_array_instance(glsl_type::vec4_type, + state->Const.MaxClipPlanes)); + add_uniform(instructions, symtab, "gl_Point", + symtab->get_type("gl_PointParameters")); + + const glsl_type *const material_parameters_type = + symtab->get_type("gl_MaterialParameters"); + add_uniform(instructions, symtab, "gl_FrontMaterial", material_parameters_type); + add_uniform(instructions, symtab, "gl_BackMaterial", material_parameters_type); + + const glsl_type *const light_source_array_type = + glsl_type::get_array_instance(symtab->get_type("gl_LightSourceParameters"), state->Const.MaxLights); + + add_uniform(instructions, symtab, "gl_LightSource", light_source_array_type); + + const glsl_type *const light_model_products_type = + symtab->get_type("gl_LightModelProducts"); + add_uniform(instructions, symtab, "gl_FrontLightModelProduct", + light_model_products_type); + add_uniform(instructions, symtab, "gl_BackLightModelProduct", + light_model_products_type); + + const glsl_type *const light_products_type = + glsl_type::get_array_instance(symtab->get_type("gl_LightProducts"), + state->Const.MaxLights); + add_uniform(instructions, symtab, "gl_FrontLightProduct", light_products_type); + add_uniform(instructions, symtab, "gl_BackLightProduct", light_products_type); + + add_uniform(instructions, symtab, "gl_TextureEnvColor", + glsl_type::get_array_instance(glsl_type::vec4_type, + state->Const.MaxTextureUnits)); + + const glsl_type *const texcoords_vec4 = + glsl_type::get_array_instance(glsl_type::vec4_type, + state->Const.MaxTextureCoords); + add_uniform(instructions, symtab, "gl_EyePlaneS", texcoords_vec4); + add_uniform(instructions, symtab, "gl_EyePlaneT", texcoords_vec4); + add_uniform(instructions, symtab, "gl_EyePlaneR", texcoords_vec4); + add_uniform(instructions, symtab, "gl_EyePlaneQ", texcoords_vec4); + add_uniform(instructions, symtab, "gl_ObjectPlaneS", texcoords_vec4); + add_uniform(instructions, symtab, "gl_ObjectPlaneT", texcoords_vec4); + add_uniform(instructions, symtab, "gl_ObjectPlaneR", texcoords_vec4); + add_uniform(instructions, symtab, "gl_ObjectPlaneQ", texcoords_vec4); + + add_uniform(instructions, symtab, "gl_Fog", + symtab->get_type("gl_FogParameters")); + + /* Mesa-internal current attrib state */ + const glsl_type *const vert_attribs = + glsl_type::get_array_instance(glsl_type::vec4_type, VERT_ATTRIB_MAX); + add_uniform(instructions, symtab, "gl_CurrentAttribVertMESA", vert_attribs); + const glsl_type *const frag_attribs = + glsl_type::get_array_instance(glsl_type::vec4_type, FRAG_ATTRIB_MAX); + add_uniform(instructions, symtab, "gl_CurrentAttribFragMESA", frag_attribs); +} + +/* This function should only be called for ES, not desktop GL. */ +static void +generate_100ES_vs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_core_vs_variables[i]); + } + + generate_100ES_uniforms(instructions, state); + + generate_ARB_draw_buffers_variables(instructions, state, false, + vertex_shader); +} + + +static void +generate_110_vs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_core_vs_variables[i]); + } + + for (unsigned i = 0 + ; i < Elements(builtin_110_deprecated_vs_variables) + ; i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_110_deprecated_vs_variables[i]); + } + generate_110_uniforms(instructions, state); + + /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: + * + * "As with all arrays, indices used to subscript gl_TexCoord must + * either be an integral constant expressions, or this array must be + * re-declared by the shader with a size. The size can be at most + * gl_MaxTextureCoords. Using indexes close to 0 may aid the + * implementation in preserving varying resources." + */ + const glsl_type *const vec4_array_type = + glsl_type::get_array_instance(glsl_type::vec4_type, 0); + + add_variable(instructions, state->symbols, + "gl_TexCoord", vec4_array_type, ir_var_out, VERT_RESULT_TEX0); + + generate_ARB_draw_buffers_variables(instructions, state, false, + vertex_shader); +} + + +static void +generate_120_vs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + /* GLSL version 1.20 did not add any built-in variables in the vertex + * shader. + */ + generate_110_vs_variables(instructions, state); +} + + +static void +generate_130_uniforms(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + glsl_symbol_table *const symtab = state->symbols; + + add_builtin_constant(instructions, symtab, "gl_MaxClipDistances", + state->Const.MaxClipPlanes); + add_builtin_constant(instructions, symtab, "gl_MaxVaryingComponents", + state->Const.MaxVaryingFloats); +} + + +static void +generate_130_vs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + generate_120_vs_variables(instructions, state); + + for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_130_vs_variables[i]); + } + + generate_130_uniforms(instructions, state); + + /* From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special + * Variables): + * + * The gl_ClipDistance array is predeclared as unsized and must + * be sized by the shader either redeclaring it with a size or + * indexing it only with integral constant expressions. + * + * We represent this in Mesa by initially declaring the array as + * size 0. + */ + const glsl_type *const clip_distance_array_type = + glsl_type::get_array_instance(glsl_type::float_type, 0); + + add_variable(instructions, state->symbols, + "gl_ClipDistance", clip_distance_array_type, ir_var_out, + VERT_RESULT_CLIP_DIST0); + +} + + +static void +initialize_vs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + + switch (state->language_version) { + case 100: + generate_100ES_vs_variables(instructions, state); + break; + case 110: + generate_110_vs_variables(instructions, state); + break; + case 120: + generate_120_vs_variables(instructions, state); + break; + case 130: + generate_130_vs_variables(instructions, state); + break; + } + + if (state->ARB_draw_instanced_enable) + generate_ARB_draw_instanced_variables(instructions, state, false, + vertex_shader); +} + + +/* This function should only be called for ES, not desktop GL. */ +static void +generate_100ES_fs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_core_fs_variables[i]); + } + + for (unsigned i = 0; i < Elements(builtin_100ES_fs_variables); i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_100ES_fs_variables[i]); + } + + generate_100ES_uniforms(instructions, state); + + generate_ARB_draw_buffers_variables(instructions, state, false, + fragment_shader); +} + +static void +generate_110_fs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_core_fs_variables[i]); + } + + for (unsigned i = 0; i < Elements(builtin_110_fs_variables); i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_110_fs_variables[i]); + } + + for (unsigned i = 0 + ; i < Elements(builtin_110_deprecated_fs_variables) + ; i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_110_deprecated_fs_variables[i]); + } + generate_110_uniforms(instructions, state); + + /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: + * + * "As with all arrays, indices used to subscript gl_TexCoord must + * either be an integral constant expressions, or this array must be + * re-declared by the shader with a size. The size can be at most + * gl_MaxTextureCoords. Using indexes close to 0 may aid the + * implementation in preserving varying resources." + */ + const glsl_type *const vec4_array_type = + glsl_type::get_array_instance(glsl_type::vec4_type, 0); + + add_variable(instructions, state->symbols, + "gl_TexCoord", vec4_array_type, ir_var_in, FRAG_ATTRIB_TEX0); + + generate_ARB_draw_buffers_variables(instructions, state, false, + fragment_shader); +} + + +static void +generate_ARB_draw_buffers_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state, + bool warn, _mesa_glsl_parser_targets target) +{ + /* gl_MaxDrawBuffers is available in all shader stages. + */ + ir_variable *const mdb = + add_builtin_constant(instructions, state->symbols, "gl_MaxDrawBuffers", + state->Const.MaxDrawBuffers); + + if (warn) + mdb->warn_extension = "GL_ARB_draw_buffers"; + + /* gl_FragData is only available in the fragment shader. + */ + if (target == fragment_shader) { + const glsl_type *const vec4_array_type = + glsl_type::get_array_instance(glsl_type::vec4_type, + state->Const.MaxDrawBuffers); + + ir_variable *const fd = + add_variable(instructions, state->symbols, + "gl_FragData", vec4_array_type, + ir_var_out, FRAG_RESULT_DATA0); + + if (warn) + fd->warn_extension = "GL_ARB_draw_buffers"; + } +} + + +static void +generate_ARB_draw_instanced_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state, + bool warn, + _mesa_glsl_parser_targets target) +{ + /* gl_InstanceIDARB is only available in the vertex shader. + */ + if (target == vertex_shader) { + ir_variable *const inst = + add_variable(instructions, state->symbols, + "gl_InstanceIDARB", glsl_type::int_type, + ir_var_system_value, SYSTEM_VALUE_INSTANCE_ID); + + if (warn) + inst->warn_extension = "GL_ARB_draw_instanced"; + } +} + + +static void +generate_ARB_shader_stencil_export_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state, + bool warn) +{ + /* gl_FragStencilRefARB is only available in the fragment shader. + */ + ir_variable *const fd = + add_variable(instructions, state->symbols, + "gl_FragStencilRefARB", glsl_type::int_type, + ir_var_out, FRAG_RESULT_STENCIL); + + if (warn) + fd->warn_extension = "GL_ARB_shader_stencil_export"; +} + +static void +generate_AMD_shader_stencil_export_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state, + bool warn) +{ + /* gl_FragStencilRefAMD is only available in the fragment shader. + */ + ir_variable *const fd = + add_variable(instructions, state->symbols, + "gl_FragStencilRefAMD", glsl_type::int_type, + ir_var_out, FRAG_RESULT_STENCIL); + + if (warn) + fd->warn_extension = "GL_AMD_shader_stencil_export"; +} + +static void +generate_120_fs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + generate_110_fs_variables(instructions, state); + + for (unsigned i = 0 + ; i < Elements(builtin_120_fs_variables) + ; i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_120_fs_variables[i]); + } +} + +static void +generate_130_fs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + generate_120_fs_variables(instructions, state); + + generate_130_uniforms(instructions, state); + + /* From the GLSL 1.30 spec, section 7.2 (Fragment Shader Special + * Variables): + * + * The built-in input variable gl_ClipDistance array contains linearly + * interpolated values for the vertex values written by the vertex shader + * to the gl_ClipDistance vertex output variable. This array must be + * sized in the fragment shader either implicitly or explicitly to be the + * same size as it was sized in the vertex shader. + * + * In other words, the array must be pre-declared as implicitly sized. We + * represent this in Mesa by initially declaring the array as size 0. + */ + const glsl_type *const clip_distance_array_type = + glsl_type::get_array_instance(glsl_type::float_type, 0); + + add_variable(instructions, state->symbols, + "gl_ClipDistance", clip_distance_array_type, ir_var_in, + FRAG_ATTRIB_CLIP_DIST0); +} + +static void +initialize_fs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + + switch (state->language_version) { + case 100: + generate_100ES_fs_variables(instructions, state); + break; + case 110: + generate_110_fs_variables(instructions, state); + break; + case 120: + generate_120_fs_variables(instructions, state); + break; + case 130: + generate_130_fs_variables(instructions, state); + break; + } + + if (state->ARB_shader_stencil_export_enable) + generate_ARB_shader_stencil_export_variables(instructions, state, + state->ARB_shader_stencil_export_warn); + + if (state->AMD_shader_stencil_export_enable) + generate_AMD_shader_stencil_export_variables(instructions, state, + state->AMD_shader_stencil_export_warn); +} + +void +_mesa_glsl_initialize_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + switch (state->target) { + case vertex_shader: + initialize_vs_variables(instructions, state); + break; + case geometry_shader: + break; + case fragment_shader: + initialize_fs_variables(instructions, state); + break; + } +} diff --git a/mesalib/src/glsl/builtin_variables.h b/mesalib/src/glsl/builtin_variables.h deleted file mode 100644 index 237b361d8..000000000 --- a/mesalib/src/glsl/builtin_variables.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "main/core.h" /* for slot numbers */ - -struct builtin_variable { - enum ir_variable_mode mode; - int slot; - const char *type; - const char *name; -}; - -static const builtin_variable builtin_core_vs_variables[] = { - { ir_var_out, VERT_RESULT_HPOS, "vec4", "gl_Position" }, - { ir_var_out, VERT_RESULT_PSIZ, "float", "gl_PointSize" }, -}; - -static const builtin_variable builtin_core_fs_variables[] = { - { ir_var_in, FRAG_ATTRIB_WPOS, "vec4", "gl_FragCoord" }, - { ir_var_in, FRAG_ATTRIB_FACE, "bool", "gl_FrontFacing" }, - { ir_var_out, FRAG_RESULT_COLOR, "vec4", "gl_FragColor" }, -}; - -static const builtin_variable builtin_100ES_fs_variables[] = { - { ir_var_in, FRAG_ATTRIB_PNTC, "vec2", "gl_PointCoord" }, -}; - -static const builtin_variable builtin_110_fs_variables[] = { - { ir_var_out, FRAG_RESULT_DEPTH, "float", "gl_FragDepth" }, -}; - -static const builtin_variable builtin_110_deprecated_fs_variables[] = { - { ir_var_in, FRAG_ATTRIB_COL0, "vec4", "gl_Color" }, - { ir_var_in, FRAG_ATTRIB_COL1, "vec4", "gl_SecondaryColor" }, - { ir_var_in, FRAG_ATTRIB_FOGC, "float", "gl_FogFragCoord" }, -}; - -static const builtin_variable builtin_110_deprecated_vs_variables[] = { - { ir_var_in, VERT_ATTRIB_POS, "vec4", "gl_Vertex" }, - { ir_var_in, VERT_ATTRIB_NORMAL, "vec3", "gl_Normal" }, - { ir_var_in, VERT_ATTRIB_COLOR0, "vec4", "gl_Color" }, - { ir_var_in, VERT_ATTRIB_COLOR1, "vec4", "gl_SecondaryColor" }, - { ir_var_in, VERT_ATTRIB_TEX0, "vec4", "gl_MultiTexCoord0" }, - { ir_var_in, VERT_ATTRIB_TEX1, "vec4", "gl_MultiTexCoord1" }, - { ir_var_in, VERT_ATTRIB_TEX2, "vec4", "gl_MultiTexCoord2" }, - { ir_var_in, VERT_ATTRIB_TEX3, "vec4", "gl_MultiTexCoord3" }, - { ir_var_in, VERT_ATTRIB_TEX4, "vec4", "gl_MultiTexCoord4" }, - { ir_var_in, VERT_ATTRIB_TEX5, "vec4", "gl_MultiTexCoord5" }, - { ir_var_in, VERT_ATTRIB_TEX6, "vec4", "gl_MultiTexCoord6" }, - { ir_var_in, VERT_ATTRIB_TEX7, "vec4", "gl_MultiTexCoord7" }, - { ir_var_in, VERT_ATTRIB_FOG, "float", "gl_FogCoord" }, - { ir_var_out, VERT_RESULT_CLIP_VERTEX, "vec4", "gl_ClipVertex" }, - { ir_var_out, VERT_RESULT_COL0, "vec4", "gl_FrontColor" }, - { ir_var_out, VERT_RESULT_BFC0, "vec4", "gl_BackColor" }, - { ir_var_out, VERT_RESULT_COL1, "vec4", "gl_FrontSecondaryColor" }, - { ir_var_out, VERT_RESULT_BFC1, "vec4", "gl_BackSecondaryColor" }, - { ir_var_out, VERT_RESULT_FOGC, "float", "gl_FogFragCoord" }, -}; - -static const builtin_variable builtin_120_fs_variables[] = { - { ir_var_in, FRAG_ATTRIB_PNTC, "vec2", "gl_PointCoord" }, -}; - -static const builtin_variable builtin_130_vs_variables[] = { - { ir_var_in, -1, "int", "gl_VertexID" }, -}; - -static const builtin_variable builtin_110_deprecated_uniforms[] = { - { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrix" }, - { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrix" }, - { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrix" }, - { ir_var_uniform, -1, "mat3", "gl_NormalMatrix" }, - { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixInverse" }, - { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixInverse" }, - { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverse" }, - { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixTranspose" }, - { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixTranspose" }, - { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixTranspose" }, - { ir_var_uniform, -1, "mat4", "gl_ModelViewMatrixInverseTranspose" }, - { ir_var_uniform, -1, "mat4", "gl_ProjectionMatrixInverseTranspose" }, - { ir_var_uniform, -1, "mat4", "gl_ModelViewProjectionMatrixInverseTranspose" }, - { ir_var_uniform, -1, "float", "gl_NormalScale" }, - { ir_var_uniform, -1, "gl_LightModelParameters", "gl_LightModel"}, - - /* Mesa-internal ATI_envmap_bumpmap state. */ - { 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/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index 1b17ff43a..c0457b057 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -1132,6 +1132,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) if (extensions->ARB_shader_texture_lod) add_builtin_define(parser, "GL_ARB_shader_texture_lod", 1); + if (extensions->ARB_draw_instanced) + add_builtin_define(parser, "GL_ARB_draw_instanced", 1); + if (extensions->AMD_conservative_depth) { add_builtin_define(parser, "GL_AMD_conservative_depth", 1); add_builtin_define(parser, "GL_ARB_conservative_depth", 1); diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp index 492be325f..adca62e8d 100644 --- a/mesalib/src/glsl/ir_constant_expression.cpp +++ b/mesalib/src/glsl/ir_constant_expression.cpp @@ -713,6 +713,9 @@ ir_expression::constant_expression_value() case GLSL_TYPE_FLOAT: data.b[c] = op[0]->value.f[c] == op[1]->value.f[c]; break; + case GLSL_TYPE_BOOL: + data.b[c] = op[0]->value.b[c] == op[1]->value.b[c]; + break; default: assert(0); } @@ -731,6 +734,9 @@ ir_expression::constant_expression_value() case GLSL_TYPE_FLOAT: data.b[c] = op[0]->value.f[c] != op[1]->value.f[c]; break; + case GLSL_TYPE_BOOL: + data.b[c] = op[0]->value.b[c] != op[1]->value.b[c]; + break; default: assert(0); } diff --git a/mesalib/src/glsl/ir_variable.cpp b/mesalib/src/glsl/ir_variable.cpp deleted file mode 100644 index 3092507bc..000000000 --- a/mesalib/src/glsl/ir_variable.cpp +++ /dev/null @@ -1,916 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "ir.h" -#include "glsl_parser_extras.h" -#include "glsl_symbol_table.h" -#include "builtin_variables.h" -#include "main/uniforms.h" -#include "program/prog_parameter.h" -#include "program/prog_statevars.h" -#include "program/prog_instruction.h" - -static void generate_ARB_draw_buffers_variables(exec_list *, - struct _mesa_glsl_parse_state *, - bool, _mesa_glsl_parser_targets); - -static void -generate_ARB_draw_instanced_variables(exec_list *, - struct _mesa_glsl_parse_state *, - bool, _mesa_glsl_parser_targets); - -static struct gl_builtin_uniform_element gl_DepthRange_elements[] = { - {"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX}, - {"far", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY}, - {"diff", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ}, -}; - -static struct gl_builtin_uniform_element gl_ClipPlane_elements[] = { - {NULL, {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW} -}; - -static struct gl_builtin_uniform_element gl_Point_elements[] = { - {"size", {STATE_POINT_SIZE}, SWIZZLE_XXXX}, - {"sizeMin", {STATE_POINT_SIZE}, SWIZZLE_YYYY}, - {"sizeMax", {STATE_POINT_SIZE}, SWIZZLE_ZZZZ}, - {"fadeThresholdSize", {STATE_POINT_SIZE}, SWIZZLE_WWWW}, - {"distanceConstantAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX}, - {"distanceLinearAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY}, - {"distanceQuadraticAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ}, -}; - -static struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = { - {"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW}, - {"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW}, - {"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW}, - {"specular", {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW}, - {"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX}, -}; - -static struct gl_builtin_uniform_element gl_BackMaterial_elements[] = { - {"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW}, - {"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW}, - {"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW}, - {"specular", {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW}, - {"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX}, -}; - -static struct gl_builtin_uniform_element gl_LightSource_elements[] = { - {"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW}, - {"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW}, - {"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW}, - {"position", {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW}, - {"halfVector", {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW}, - {"spotDirection", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, - MAKE_SWIZZLE4(SWIZZLE_X, - SWIZZLE_Y, - SWIZZLE_Z, - SWIZZLE_Z)}, - {"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW}, - {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX}, - {"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW}, - {"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX}, - {"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY}, - {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ}, -}; - -static struct gl_builtin_uniform_element gl_LightModel_elements[] = { - {"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = { - {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_BackLightModelProduct_elements[] = { - {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = { - {"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW}, - {"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW}, - {"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = { - {"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW}, - {"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW}, - {"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = { - {NULL, {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_EyePlaneS_elements[] = { - {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_EyePlaneT_elements[] = { - {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_EyePlaneR_elements[] = { - {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_EyePlaneQ_elements[] = { - {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_ObjectPlaneS_elements[] = { - {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_ObjectPlaneT_elements[] = { - {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_ObjectPlaneR_elements[] = { - {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_ObjectPlaneQ_elements[] = { - {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_Fog_elements[] = { - {"color", {STATE_FOG_COLOR}, SWIZZLE_XYZW}, - {"density", {STATE_FOG_PARAMS}, SWIZZLE_XXXX}, - {"start", {STATE_FOG_PARAMS}, SWIZZLE_YYYY}, - {"end", {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ}, - {"scale", {STATE_FOG_PARAMS}, SWIZZLE_WWWW}, -}; - -static struct gl_builtin_uniform_element gl_NormalScale_elements[] = { - {NULL, {STATE_NORMAL_SCALE}, SWIZZLE_XXXX}, -}; - -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_BumpRotMatrix1MESA_elements[] = { - {NULL, {STATE_INTERNAL, STATE_ROT_MATRIX_1}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_FogParamsOptimizedMESA_elements[] = { - {NULL, {STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_CurrentAttribVertMESA_elements[] = { - {NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB, 0}, SWIZZLE_XYZW}, -}; - -static struct gl_builtin_uniform_element gl_CurrentAttribFragMESA_elements[] = { - {NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, 0}, SWIZZLE_XYZW}, -}; - -#define MATRIX(name, statevar, modifier) \ - static struct gl_builtin_uniform_element name ## _elements[] = { \ - { NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW }, \ - { NULL, { statevar, 0, 1, 1, modifier}, SWIZZLE_XYZW }, \ - { NULL, { statevar, 0, 2, 2, modifier}, SWIZZLE_XYZW }, \ - { NULL, { statevar, 0, 3, 3, modifier}, SWIZZLE_XYZW }, \ - } - -MATRIX(gl_ModelViewMatrix, - STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE); -MATRIX(gl_ModelViewMatrixInverse, - STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS); -MATRIX(gl_ModelViewMatrixTranspose, - STATE_MODELVIEW_MATRIX, 0); -MATRIX(gl_ModelViewMatrixInverseTranspose, - STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE); - -MATRIX(gl_ProjectionMatrix, - STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE); -MATRIX(gl_ProjectionMatrixInverse, - STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS); -MATRIX(gl_ProjectionMatrixTranspose, - STATE_PROJECTION_MATRIX, 0); -MATRIX(gl_ProjectionMatrixInverseTranspose, - STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE); - -MATRIX(gl_ModelViewProjectionMatrix, - STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE); -MATRIX(gl_ModelViewProjectionMatrixInverse, - STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS); -MATRIX(gl_ModelViewProjectionMatrixTranspose, - STATE_MVP_MATRIX, 0); -MATRIX(gl_ModelViewProjectionMatrixInverseTranspose, - STATE_MVP_MATRIX, STATE_MATRIX_INVERSE); - -MATRIX(gl_TextureMatrix, - STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE); -MATRIX(gl_TextureMatrixInverse, - STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS); -MATRIX(gl_TextureMatrixTranspose, - STATE_TEXTURE_MATRIX, 0); -MATRIX(gl_TextureMatrixInverseTranspose, - STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE); - -static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = { - { NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE}, - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) }, - { NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE}, - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) }, - { NULL, { STATE_MODELVIEW_MATRIX, 0, 2, 2, STATE_MATRIX_INVERSE}, - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) }, -}; - -#undef MATRIX - -#define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)} - -const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = { - STATEVAR(gl_DepthRange), - STATEVAR(gl_ClipPlane), - STATEVAR(gl_Point), - STATEVAR(gl_FrontMaterial), - STATEVAR(gl_BackMaterial), - STATEVAR(gl_LightSource), - STATEVAR(gl_LightModel), - STATEVAR(gl_FrontLightModelProduct), - STATEVAR(gl_BackLightModelProduct), - STATEVAR(gl_FrontLightProduct), - STATEVAR(gl_BackLightProduct), - STATEVAR(gl_TextureEnvColor), - STATEVAR(gl_EyePlaneS), - STATEVAR(gl_EyePlaneT), - STATEVAR(gl_EyePlaneR), - STATEVAR(gl_EyePlaneQ), - STATEVAR(gl_ObjectPlaneS), - STATEVAR(gl_ObjectPlaneT), - STATEVAR(gl_ObjectPlaneR), - STATEVAR(gl_ObjectPlaneQ), - STATEVAR(gl_Fog), - - STATEVAR(gl_ModelViewMatrix), - STATEVAR(gl_ModelViewMatrixInverse), - STATEVAR(gl_ModelViewMatrixTranspose), - STATEVAR(gl_ModelViewMatrixInverseTranspose), - - STATEVAR(gl_ProjectionMatrix), - STATEVAR(gl_ProjectionMatrixInverse), - STATEVAR(gl_ProjectionMatrixTranspose), - STATEVAR(gl_ProjectionMatrixInverseTranspose), - - STATEVAR(gl_ModelViewProjectionMatrix), - STATEVAR(gl_ModelViewProjectionMatrixInverse), - STATEVAR(gl_ModelViewProjectionMatrixTranspose), - STATEVAR(gl_ModelViewProjectionMatrixInverseTranspose), - - STATEVAR(gl_TextureMatrix), - STATEVAR(gl_TextureMatrixInverse), - STATEVAR(gl_TextureMatrixTranspose), - STATEVAR(gl_TextureMatrixInverseTranspose), - - STATEVAR(gl_NormalMatrix), - STATEVAR(gl_NormalScale), - - STATEVAR(gl_BumpRotMatrix0MESA), - STATEVAR(gl_BumpRotMatrix1MESA), - STATEVAR(gl_FogParamsOptimizedMESA), - STATEVAR(gl_CurrentAttribVertMESA), - STATEVAR(gl_CurrentAttribFragMESA), - - {NULL, NULL, 0} -}; - -static ir_variable * -add_variable(exec_list *instructions, glsl_symbol_table *symtab, - const char *name, const glsl_type *type, - enum ir_variable_mode mode, int slot) -{ - ir_variable *var = new(symtab) ir_variable(type, name, mode); - - switch (var->mode) { - case ir_var_auto: - case ir_var_in: - case ir_var_const_in: - case ir_var_uniform: - case ir_var_system_value: - var->read_only = true; - break; - case ir_var_inout: - case ir_var_out: - break; - default: - assert(0); - break; - } - - var->location = slot; - var->explicit_location = (slot >= 0); - - /* Once the variable is created an initialized, add it to the symbol table - * and add the declaration to the IR stream. - */ - instructions->push_tail(var); - - symtab->add_variable(var); - return var; -} - -static ir_variable * -add_uniform(exec_list *instructions, glsl_symbol_table *symtab, - const char *name, const glsl_type *type) -{ - ir_variable *const uni = - add_variable(instructions, symtab, name, type, ir_var_uniform, -1); - - unsigned i; - for (i = 0; _mesa_builtin_uniform_desc[i].name != NULL; i++) { - if (strcmp(_mesa_builtin_uniform_desc[i].name, name) == 0) { - break; - } - } - - assert(_mesa_builtin_uniform_desc[i].name != NULL); - const struct gl_builtin_uniform_desc* const statevar = - &_mesa_builtin_uniform_desc[i]; - - const unsigned array_count = type->is_array() ? type->length : 1; - uni->num_state_slots = array_count * statevar->num_elements; - - ir_state_slot *slots = - ralloc_array(uni, ir_state_slot, uni->num_state_slots); - - uni->state_slots = slots; - - for (unsigned a = 0; a < array_count; a++) { - for (unsigned j = 0; j < statevar->num_elements; j++) { - struct gl_builtin_uniform_element *element = &statevar->elements[j]; - - memcpy(slots->tokens, element->tokens, sizeof(element->tokens)); - if (type->is_array()) { - if (strcmp(name, "gl_CurrentAttribVertMESA") == 0 || - strcmp(name, "gl_CurrentAttribFragMESA") == 0) { - slots->tokens[2] = a; - } else { - slots->tokens[1] = a; - } - } - - slots->swizzle = element->swizzle; - slots++; - } - } - - return uni; -} - -static void -add_builtin_variable(exec_list *instructions, glsl_symbol_table *symtab, - const builtin_variable *proto) -{ - /* Create a new variable declaration from the description supplied by - * the caller. - */ - const glsl_type *const type = symtab->get_type(proto->type); - - assert(type != NULL); - - if (proto->mode == ir_var_uniform) { - add_uniform(instructions, symtab, proto->name, type); - } else { - add_variable(instructions, symtab, proto->name, type, proto->mode, - proto->slot); - } -} - -static ir_variable * -add_builtin_constant(exec_list *instructions, glsl_symbol_table *symtab, - const char *name, int value) -{ - ir_variable *const var = add_variable(instructions, symtab, - name, glsl_type::int_type, - ir_var_auto, -1); - var->constant_value = new(var) ir_constant(value); - var->constant_initializer = new(var) ir_constant(value); - var->has_initializer = true; - return var; -} - -/* Several constants in GLSL ES have different names than normal desktop GLSL. - * Therefore, this function should only be called on the ES path. - */ -static void -generate_100ES_uniforms(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - glsl_symbol_table *const symtab = state->symbols; - - add_builtin_constant(instructions, symtab, "gl_MaxVertexAttribs", - state->Const.MaxVertexAttribs); - add_builtin_constant(instructions, symtab, "gl_MaxVertexUniformVectors", - state->Const.MaxVertexUniformComponents); - add_builtin_constant(instructions, symtab, "gl_MaxVaryingVectors", - state->Const.MaxVaryingFloats / 4); - add_builtin_constant(instructions, symtab, "gl_MaxVertexTextureImageUnits", - state->Const.MaxVertexTextureImageUnits); - add_builtin_constant(instructions, symtab, "gl_MaxCombinedTextureImageUnits", - state->Const.MaxCombinedTextureImageUnits); - add_builtin_constant(instructions, symtab, "gl_MaxTextureImageUnits", - state->Const.MaxTextureImageUnits); - add_builtin_constant(instructions, symtab, "gl_MaxFragmentUniformVectors", - state->Const.MaxFragmentUniformComponents); - - add_uniform(instructions, symtab, "gl_DepthRange", - state->symbols->get_type("gl_DepthRangeParameters")); -} - -static void -generate_110_uniforms(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - glsl_symbol_table *const symtab = state->symbols; - - for (unsigned i = 0 - ; i < Elements(builtin_110_deprecated_uniforms) - ; i++) { - add_builtin_variable(instructions, symtab, - & builtin_110_deprecated_uniforms[i]); - } - - add_builtin_constant(instructions, symtab, "gl_MaxLights", - state->Const.MaxLights); - add_builtin_constant(instructions, symtab, "gl_MaxClipPlanes", - state->Const.MaxClipPlanes); - add_builtin_constant(instructions, symtab, "gl_MaxTextureUnits", - state->Const.MaxTextureUnits); - add_builtin_constant(instructions, symtab, "gl_MaxTextureCoords", - state->Const.MaxTextureCoords); - add_builtin_constant(instructions, symtab, "gl_MaxVertexAttribs", - state->Const.MaxVertexAttribs); - add_builtin_constant(instructions, symtab, "gl_MaxVertexUniformComponents", - state->Const.MaxVertexUniformComponents); - add_builtin_constant(instructions, symtab, "gl_MaxVaryingFloats", - state->Const.MaxVaryingFloats); - add_builtin_constant(instructions, symtab, "gl_MaxVertexTextureImageUnits", - state->Const.MaxVertexTextureImageUnits); - add_builtin_constant(instructions, symtab, "gl_MaxCombinedTextureImageUnits", - state->Const.MaxCombinedTextureImageUnits); - add_builtin_constant(instructions, symtab, "gl_MaxTextureImageUnits", - state->Const.MaxTextureImageUnits); - add_builtin_constant(instructions, symtab, "gl_MaxFragmentUniformComponents", - state->Const.MaxFragmentUniformComponents); - - const glsl_type *const mat4_array_type = - glsl_type::get_array_instance(glsl_type::mat4_type, - state->Const.MaxTextureCoords); - - add_uniform(instructions, symtab, "gl_TextureMatrix", mat4_array_type); - add_uniform(instructions, symtab, "gl_TextureMatrixInverse", mat4_array_type); - add_uniform(instructions, symtab, "gl_TextureMatrixTranspose", mat4_array_type); - add_uniform(instructions, symtab, "gl_TextureMatrixInverseTranspose", mat4_array_type); - - add_uniform(instructions, symtab, "gl_DepthRange", - symtab->get_type("gl_DepthRangeParameters")); - - add_uniform(instructions, symtab, "gl_ClipPlane", - glsl_type::get_array_instance(glsl_type::vec4_type, - state->Const.MaxClipPlanes)); - add_uniform(instructions, symtab, "gl_Point", - symtab->get_type("gl_PointParameters")); - - const glsl_type *const material_parameters_type = - symtab->get_type("gl_MaterialParameters"); - add_uniform(instructions, symtab, "gl_FrontMaterial", material_parameters_type); - add_uniform(instructions, symtab, "gl_BackMaterial", material_parameters_type); - - const glsl_type *const light_source_array_type = - glsl_type::get_array_instance(symtab->get_type("gl_LightSourceParameters"), state->Const.MaxLights); - - add_uniform(instructions, symtab, "gl_LightSource", light_source_array_type); - - const glsl_type *const light_model_products_type = - symtab->get_type("gl_LightModelProducts"); - add_uniform(instructions, symtab, "gl_FrontLightModelProduct", - light_model_products_type); - add_uniform(instructions, symtab, "gl_BackLightModelProduct", - light_model_products_type); - - const glsl_type *const light_products_type = - glsl_type::get_array_instance(symtab->get_type("gl_LightProducts"), - state->Const.MaxLights); - add_uniform(instructions, symtab, "gl_FrontLightProduct", light_products_type); - add_uniform(instructions, symtab, "gl_BackLightProduct", light_products_type); - - add_uniform(instructions, symtab, "gl_TextureEnvColor", - glsl_type::get_array_instance(glsl_type::vec4_type, - state->Const.MaxTextureUnits)); - - const glsl_type *const texcoords_vec4 = - glsl_type::get_array_instance(glsl_type::vec4_type, - state->Const.MaxTextureCoords); - add_uniform(instructions, symtab, "gl_EyePlaneS", texcoords_vec4); - add_uniform(instructions, symtab, "gl_EyePlaneT", texcoords_vec4); - add_uniform(instructions, symtab, "gl_EyePlaneR", texcoords_vec4); - add_uniform(instructions, symtab, "gl_EyePlaneQ", texcoords_vec4); - add_uniform(instructions, symtab, "gl_ObjectPlaneS", texcoords_vec4); - add_uniform(instructions, symtab, "gl_ObjectPlaneT", texcoords_vec4); - add_uniform(instructions, symtab, "gl_ObjectPlaneR", texcoords_vec4); - add_uniform(instructions, symtab, "gl_ObjectPlaneQ", texcoords_vec4); - - add_uniform(instructions, symtab, "gl_Fog", - symtab->get_type("gl_FogParameters")); - - /* Mesa-internal current attrib state */ - const glsl_type *const vert_attribs = - glsl_type::get_array_instance(glsl_type::vec4_type, VERT_ATTRIB_MAX); - add_uniform(instructions, symtab, "gl_CurrentAttribVertMESA", vert_attribs); - const glsl_type *const frag_attribs = - glsl_type::get_array_instance(glsl_type::vec4_type, FRAG_ATTRIB_MAX); - add_uniform(instructions, symtab, "gl_CurrentAttribFragMESA", frag_attribs); -} - -/* This function should only be called for ES, not desktop GL. */ -static void -generate_100ES_vs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) { - add_builtin_variable(instructions, state->symbols, - & builtin_core_vs_variables[i]); - } - - generate_100ES_uniforms(instructions, state); - - generate_ARB_draw_buffers_variables(instructions, state, false, - vertex_shader); -} - - -static void -generate_110_vs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) { - add_builtin_variable(instructions, state->symbols, - & builtin_core_vs_variables[i]); - } - - for (unsigned i = 0 - ; i < Elements(builtin_110_deprecated_vs_variables) - ; i++) { - add_builtin_variable(instructions, state->symbols, - & builtin_110_deprecated_vs_variables[i]); - } - generate_110_uniforms(instructions, state); - - /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: - * - * "As with all arrays, indices used to subscript gl_TexCoord must - * either be an integral constant expressions, or this array must be - * re-declared by the shader with a size. The size can be at most - * gl_MaxTextureCoords. Using indexes close to 0 may aid the - * implementation in preserving varying resources." - */ - const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(glsl_type::vec4_type, 0); - - add_variable(instructions, state->symbols, - "gl_TexCoord", vec4_array_type, ir_var_out, VERT_RESULT_TEX0); - - generate_ARB_draw_buffers_variables(instructions, state, false, - vertex_shader); -} - - -static void -generate_120_vs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - /* GLSL version 1.20 did not add any built-in variables in the vertex - * shader. - */ - generate_110_vs_variables(instructions, state); -} - - -static void -generate_130_uniforms(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - glsl_symbol_table *const symtab = state->symbols; - - add_builtin_constant(instructions, symtab, "gl_MaxClipDistances", - state->Const.MaxClipPlanes); - add_builtin_constant(instructions, symtab, "gl_MaxVaryingComponents", - state->Const.MaxVaryingFloats); -} - - -static void -generate_130_vs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - generate_120_vs_variables(instructions, state); - - for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) { - add_builtin_variable(instructions, state->symbols, - & builtin_130_vs_variables[i]); - } - - generate_130_uniforms(instructions, state); - - /* From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special - * Variables): - * - * The gl_ClipDistance array is predeclared as unsized and must - * be sized by the shader either redeclaring it with a size or - * indexing it only with integral constant expressions. - * - * We represent this in Mesa by initially declaring the array as - * size 0. - */ - const glsl_type *const clip_distance_array_type = - glsl_type::get_array_instance(glsl_type::float_type, 0); - - add_variable(instructions, state->symbols, - "gl_ClipDistance", clip_distance_array_type, ir_var_out, - VERT_RESULT_CLIP_DIST0); - -} - - -static void -initialize_vs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - - switch (state->language_version) { - case 100: - generate_100ES_vs_variables(instructions, state); - break; - case 110: - generate_110_vs_variables(instructions, state); - break; - case 120: - generate_120_vs_variables(instructions, state); - break; - case 130: - generate_130_vs_variables(instructions, state); - break; - } - - if (state->ARB_draw_instanced_enable) - generate_ARB_draw_instanced_variables(instructions, state, false, - vertex_shader); -} - - -/* This function should only be called for ES, not desktop GL. */ -static void -generate_100ES_fs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) { - add_builtin_variable(instructions, state->symbols, - & builtin_core_fs_variables[i]); - } - - for (unsigned i = 0; i < Elements(builtin_100ES_fs_variables); i++) { - add_builtin_variable(instructions, state->symbols, - & builtin_100ES_fs_variables[i]); - } - - generate_100ES_uniforms(instructions, state); - - generate_ARB_draw_buffers_variables(instructions, state, false, - fragment_shader); -} - -static void -generate_110_fs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) { - add_builtin_variable(instructions, state->symbols, - & builtin_core_fs_variables[i]); - } - - for (unsigned i = 0; i < Elements(builtin_110_fs_variables); i++) { - add_builtin_variable(instructions, state->symbols, - & builtin_110_fs_variables[i]); - } - - for (unsigned i = 0 - ; i < Elements(builtin_110_deprecated_fs_variables) - ; i++) { - add_builtin_variable(instructions, state->symbols, - & builtin_110_deprecated_fs_variables[i]); - } - generate_110_uniforms(instructions, state); - - /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: - * - * "As with all arrays, indices used to subscript gl_TexCoord must - * either be an integral constant expressions, or this array must be - * re-declared by the shader with a size. The size can be at most - * gl_MaxTextureCoords. Using indexes close to 0 may aid the - * implementation in preserving varying resources." - */ - const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(glsl_type::vec4_type, 0); - - add_variable(instructions, state->symbols, - "gl_TexCoord", vec4_array_type, ir_var_in, FRAG_ATTRIB_TEX0); - - generate_ARB_draw_buffers_variables(instructions, state, false, - fragment_shader); -} - - -static void -generate_ARB_draw_buffers_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state, - bool warn, _mesa_glsl_parser_targets target) -{ - /* gl_MaxDrawBuffers is available in all shader stages. - */ - ir_variable *const mdb = - add_builtin_constant(instructions, state->symbols, "gl_MaxDrawBuffers", - state->Const.MaxDrawBuffers); - - if (warn) - mdb->warn_extension = "GL_ARB_draw_buffers"; - - /* gl_FragData is only available in the fragment shader. - */ - if (target == fragment_shader) { - const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(glsl_type::vec4_type, - state->Const.MaxDrawBuffers); - - ir_variable *const fd = - add_variable(instructions, state->symbols, - "gl_FragData", vec4_array_type, - ir_var_out, FRAG_RESULT_DATA0); - - if (warn) - fd->warn_extension = "GL_ARB_draw_buffers"; - } -} - - -static void -generate_ARB_draw_instanced_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state, - bool warn, - _mesa_glsl_parser_targets target) -{ - /* gl_InstanceIDARB is only available in the vertex shader. - */ - if (target == vertex_shader) { - ir_variable *const inst = - add_variable(instructions, state->symbols, - "gl_InstanceIDARB", glsl_type::int_type, - ir_var_system_value, SYSTEM_VALUE_INSTANCE_ID); - - if (warn) - inst->warn_extension = "GL_ARB_draw_instanced"; - } -} - - -static void -generate_ARB_shader_stencil_export_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state, - bool warn) -{ - /* gl_FragStencilRefARB is only available in the fragment shader. - */ - ir_variable *const fd = - add_variable(instructions, state->symbols, - "gl_FragStencilRefARB", glsl_type::int_type, - ir_var_out, FRAG_RESULT_STENCIL); - - if (warn) - fd->warn_extension = "GL_ARB_shader_stencil_export"; -} - -static void -generate_AMD_shader_stencil_export_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state, - bool warn) -{ - /* gl_FragStencilRefAMD is only available in the fragment shader. - */ - ir_variable *const fd = - add_variable(instructions, state->symbols, - "gl_FragStencilRefAMD", glsl_type::int_type, - ir_var_out, FRAG_RESULT_STENCIL); - - if (warn) - fd->warn_extension = "GL_AMD_shader_stencil_export"; -} - -static void -generate_120_fs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - generate_110_fs_variables(instructions, state); - - for (unsigned i = 0 - ; i < Elements(builtin_120_fs_variables) - ; i++) { - add_builtin_variable(instructions, state->symbols, - & builtin_120_fs_variables[i]); - } -} - -static void -generate_130_fs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - generate_120_fs_variables(instructions, state); - - generate_130_uniforms(instructions, state); - - /* From the GLSL 1.30 spec, section 7.2 (Fragment Shader Special - * Variables): - * - * The built-in input variable gl_ClipDistance array contains linearly - * interpolated values for the vertex values written by the vertex shader - * to the gl_ClipDistance vertex output variable. This array must be - * sized in the fragment shader either implicitly or explicitly to be the - * same size as it was sized in the vertex shader. - * - * In other words, the array must be pre-declared as implicitly sized. We - * represent this in Mesa by initially declaring the array as size 0. - */ - const glsl_type *const clip_distance_array_type = - glsl_type::get_array_instance(glsl_type::float_type, 0); - - add_variable(instructions, state->symbols, - "gl_ClipDistance", clip_distance_array_type, ir_var_in, - FRAG_ATTRIB_CLIP_DIST0); -} - -static void -initialize_fs_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - - switch (state->language_version) { - case 100: - generate_100ES_fs_variables(instructions, state); - break; - case 110: - generate_110_fs_variables(instructions, state); - break; - case 120: - generate_120_fs_variables(instructions, state); - break; - case 130: - generate_130_fs_variables(instructions, state); - break; - } - - if (state->ARB_shader_stencil_export_enable) - generate_ARB_shader_stencil_export_variables(instructions, state, - state->ARB_shader_stencil_export_warn); - - if (state->AMD_shader_stencil_export_enable) - generate_AMD_shader_stencil_export_variables(instructions, state, - state->AMD_shader_stencil_export_warn); -} - -void -_mesa_glsl_initialize_variables(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - switch (state->target) { - case vertex_shader: - initialize_vs_variables(instructions, state); - break; - case geometry_shader: - break; - case fragment_shader: - initialize_fs_variables(instructions, state); - break; - } -} diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript index 8f978097c..3e42bfd8b 100644 --- a/mesalib/src/mesa/SConscript +++ b/mesalib/src/mesa/SConscript @@ -40,7 +40,6 @@ main_sources = [ 'main/api_arrayelt.c', 'main/api_exec.c', 'main/api_loopback.c', - 'main/api_noop.c', 'main/api_validate.c', 'main/accum.c', 'main/arbprogram.c', @@ -214,6 +213,7 @@ vbo_sources = [ 'vbo/vbo_exec_array.c', 'vbo/vbo_exec_draw.c', 'vbo/vbo_exec_eval.c', + 'vbo/vbo_noop.c', 'vbo/vbo_rebase.c', 'vbo/vbo_split.c', 'vbo/vbo_split_copy.c', diff --git a/mesalib/src/mesa/main/api_noop.c b/mesalib/src/mesa/main/api_noop.c deleted file mode 100644 index c4ac95c98..000000000 --- a/mesalib/src/mesa/main/api_noop.c +++ /dev/null @@ -1,1089 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.1 - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -#include "glheader.h" -#include "api_noop.h" -#include "api_validate.h" -#include "api_arrayelt.h" -#include "context.h" -#include "light.h" -#include "macros.h" -#include "mfeatures.h" -#include "dlist.h" -#include "eval.h" -#include "main/dispatch.h" - - -/** - * \file - * Just update the ctx->Current vertex attributes. - * These functions are used when outside glBegin/glEnd or outside display - * lists. - */ - - -#if FEATURE_beginend - - -static void GLAPIENTRY _mesa_noop_EdgeFlag( GLboolean b ) -{ - GET_CURRENT_CONTEXT(ctx); - ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] = (GLfloat)b; -} - -static void GLAPIENTRY _mesa_noop_Indexf( GLfloat f ) -{ - GET_CURRENT_CONTEXT(ctx); - ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0] = f; -} - -static void GLAPIENTRY _mesa_noop_Indexfv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0] = *v; -} - -static void GLAPIENTRY _mesa_noop_FogCoordfEXT( GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_FOG]; - dest[0] = a; - dest[1] = 0.0; - dest[2] = 0.0; - dest[3] = 1.0; -} - -static void GLAPIENTRY _mesa_noop_FogCoordfvEXT( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_FOG]; - dest[0] = v[0]; - dest[1] = 0.0; - dest[2] = 0.0; - dest[3] = 1.0; -} - -static void GLAPIENTRY _mesa_noop_Normal3f( GLfloat a, GLfloat b, GLfloat c ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; - dest[0] = a; - dest[1] = b; - dest[2] = c; - dest[3] = 1.0; -} - -static void GLAPIENTRY _mesa_noop_Normal3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - -static void GLAPIENTRY _mesa_noop_Color4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - color[0] = a; - color[1] = b; - color[2] = c; - color[3] = d; -} - -static void GLAPIENTRY _mesa_noop_Color4fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - color[0] = v[0]; - color[1] = v[1]; - color[2] = v[2]; - color[3] = v[3]; -} - -static void GLAPIENTRY _mesa_noop_Color3f( GLfloat a, GLfloat b, GLfloat c ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - color[0] = a; - color[1] = b; - color[2] = c; - color[3] = 1.0; -} - -static void GLAPIENTRY _mesa_noop_Color3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - color[0] = v[0]; - color[1] = v[1]; - color[2] = v[2]; - color[3] = 1.0; -} - -static void GLAPIENTRY _mesa_noop_MultiTexCoord1fARB( GLenum target, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint unit = target - GL_TEXTURE0_ARB; - - /* unit is unsigned -- cannot be less than zero. - */ - if (unit < MAX_TEXTURE_COORD_UNITS) - { - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit]; - dest[0] = a; - dest[1] = 0; - dest[2] = 0; - dest[3] = 1; - } -} - -static void GLAPIENTRY _mesa_noop_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint unit = target - GL_TEXTURE0_ARB; - - /* unit is unsigned -- cannot be less than zero. - */ - if (unit < MAX_TEXTURE_COORD_UNITS) - { - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit]; - dest[0] = v[0]; - dest[1] = 0; - dest[2] = 0; - dest[3] = 1; - } -} - -static void GLAPIENTRY _mesa_noop_MultiTexCoord2fARB( GLenum target, GLfloat a, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint unit = target - GL_TEXTURE0_ARB; - - /* unit is unsigned -- cannot be less than zero. - */ - if (unit < MAX_TEXTURE_COORD_UNITS) - { - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit]; - dest[0] = a; - dest[1] = b; - dest[2] = 0; - dest[3] = 1; - } -} - -static void GLAPIENTRY _mesa_noop_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint unit = target - GL_TEXTURE0_ARB; - - /* unit is unsigned -- cannot be less than zero. - */ - if (unit < MAX_TEXTURE_COORD_UNITS) - { - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit]; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = 0; - dest[3] = 1; - } -} - -static void GLAPIENTRY _mesa_noop_MultiTexCoord3fARB( GLenum target, GLfloat a, GLfloat b, GLfloat c) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint unit = target - GL_TEXTURE0_ARB; - - /* unit is unsigned -- cannot be less than zero. - */ - if (unit < MAX_TEXTURE_COORD_UNITS) - { - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit]; - dest[0] = a; - dest[1] = b; - dest[2] = c; - dest[3] = 1; - } -} - -static void GLAPIENTRY _mesa_noop_MultiTexCoord3fvARB( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint unit = target - GL_TEXTURE0_ARB; - - /* unit is unsigned -- cannot be less than zero. - */ - if (unit < MAX_TEXTURE_COORD_UNITS) - { - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit]; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1; - } -} - -static void GLAPIENTRY _mesa_noop_MultiTexCoord4fARB( GLenum target, GLfloat a, GLfloat b, - GLfloat c, GLfloat d ) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint unit = target - GL_TEXTURE0_ARB; - - /* unit is unsigned -- cannot be less than zero. - */ - if (unit < MAX_TEXTURE_COORD_UNITS) - { - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit]; - dest[0] = a; - dest[1] = b; - dest[2] = c; - dest[3] = d; - } -} - -static void GLAPIENTRY _mesa_noop_MultiTexCoord4fvARB( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint unit = target - GL_TEXTURE0_ARB; - - /* unit is unsigned -- cannot be less than zero. - */ - if (unit < MAX_TEXTURE_COORD_UNITS) - { - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit]; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = v[3]; - } -} - -static void GLAPIENTRY _mesa_noop_SecondaryColor3fEXT( GLfloat a, GLfloat b, GLfloat c ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; - color[0] = a; - color[1] = b; - color[2] = c; - color[3] = 1.0; -} - -static void GLAPIENTRY _mesa_noop_SecondaryColor3fvEXT( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; - color[0] = v[0]; - color[1] = v[1]; - color[2] = v[2]; - color[3] = 1.0; -} - -static void GLAPIENTRY _mesa_noop_TexCoord1f( GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - dest[0] = a; - dest[1] = 0; - dest[2] = 0; - dest[3] = 1; -} - -static void GLAPIENTRY _mesa_noop_TexCoord1fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - dest[0] = v[0]; - dest[1] = 0; - dest[2] = 0; - dest[3] = 1; -} - -static void GLAPIENTRY _mesa_noop_TexCoord2f( GLfloat a, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - dest[0] = a; - dest[1] = b; - dest[2] = 0; - dest[3] = 1; -} - -static void GLAPIENTRY _mesa_noop_TexCoord2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = 0; - dest[3] = 1; -} - -static void GLAPIENTRY _mesa_noop_TexCoord3f( GLfloat a, GLfloat b, GLfloat c ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - dest[0] = a; - dest[1] = b; - dest[2] = c; - dest[3] = 1; -} - -static void GLAPIENTRY _mesa_noop_TexCoord3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1; -} - -static void GLAPIENTRY _mesa_noop_TexCoord4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - dest[0] = a; - dest[1] = b; - dest[2] = c; - dest[3] = d; -} - -static void GLAPIENTRY _mesa_noop_TexCoord4fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = v[3]; -} - - -/** - * GL_NV_vertex_program attributes. - * Note that these attributes alias the conventional vertex attributes. - */ - -static void GLAPIENTRY _mesa_noop_VertexAttrib1fNV( GLuint index, GLfloat x ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) { - ASSIGN_4V(ctx->Current.Attrib[index], x, 0, 0, 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib1fNV(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib1fvNV( GLuint index, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) { - ASSIGN_4V(ctx->Current.Attrib[index], v[0], 0, 0, 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib1fvNV(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) { - ASSIGN_4V(ctx->Current.Attrib[index], x, y, 0, 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib2fNV(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib2fvNV( GLuint index, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) { - ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], 0, 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib2fvNV(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib3fNV( GLuint index, GLfloat x, - GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) { - ASSIGN_4V(ctx->Current.Attrib[index], x, y, z, 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib3fNV(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib3fvNV( GLuint index, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) { - ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], v[2], 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib3fvNV(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib4fNV( GLuint index, GLfloat x, - GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) { - ASSIGN_4V(ctx->Current.Attrib[index], x, y, z, w); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib4fNV(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib4fvNV( GLuint index, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) { - ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], v[2], v[3]); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib4fvNV(index)" ); -} - - - -/** - * GL_ARB_vertex_program attributes. - * Note that these attributes DO NOT alias the conventional vertex attributes. - */ - -static void GLAPIENTRY _mesa_noop_VertexAttrib1fARB( GLuint index, GLfloat x ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_VERTEX_GENERIC_ATTRIBS) { - ASSIGN_4V(ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index], x, 0, 0, 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib1fARB(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib1fvARB( GLuint index, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_VERTEX_GENERIC_ATTRIBS) { - ASSIGN_4V(ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index], v[0], 0, 0, 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib1fvARB(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib2fARB( GLuint index, GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_VERTEX_GENERIC_ATTRIBS) { - ASSIGN_4V(ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index], x, y, 0, 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib2fARB(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib2fvARB( GLuint index, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_VERTEX_GENERIC_ATTRIBS) { - ASSIGN_4V(ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index], v[0], v[1], 0, 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib2fvARB(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib3fARB( GLuint index, GLfloat x, - GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_VERTEX_GENERIC_ATTRIBS) { - ASSIGN_4V(ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index], x, y, z, 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib3fARB(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib3fvARB( GLuint index, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_VERTEX_GENERIC_ATTRIBS) { - ASSIGN_4V(ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index], v[0], v[1], v[2], 1); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib3fvARB(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib4fARB( GLuint index, GLfloat x, - GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_VERTEX_GENERIC_ATTRIBS) { - ASSIGN_4V(ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index], x, y, z, w); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib4fARB(index)" ); -} - -static void GLAPIENTRY _mesa_noop_VertexAttrib4fvARB( GLuint index, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - if (index < MAX_VERTEX_GENERIC_ATTRIBS) { - ASSIGN_4V(ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index], v[0], v[1], v[2], v[3]); - } - else - _mesa_error( ctx, GL_INVALID_VALUE, "glVertexAttrib4fvARB(index)" ); -} - - - -/** - * Called by glMaterial*() - */ -void GLAPIENTRY -_mesa_noop_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i, nr; - struct gl_material *mat = &ctx->Light.Material; - GLuint bitmask = _mesa_material_bitmask( ctx, face, pname, ~0, - "_mesa_noop_Materialfv" ); - - if (ctx->Light.ColorMaterialEnabled) - bitmask &= ~ctx->Light.ColorMaterialBitmask; - - if (bitmask == 0) - return; - - switch (pname) { - case GL_SHININESS: nr = 1; break; - case GL_COLOR_INDEXES: nr = 3; break; - default: nr = 4 ; break; - } - - for (i = 0 ; i < MAT_ATTRIB_MAX ; i++) - if (bitmask & (1<Attrib[i], nr, params ); - - _mesa_update_material( ctx, bitmask ); -} - - -/** - * These really are noops outside begin/end: - */ -static void GLAPIENTRY _mesa_noop_Vertex2fv( const GLfloat *v ) -{ - (void) v; -} - -static void GLAPIENTRY _mesa_noop_Vertex3fv( const GLfloat *v ) -{ - (void) v; -} - -static void GLAPIENTRY _mesa_noop_Vertex4fv( const GLfloat *v ) -{ - (void) v; -} - -static void GLAPIENTRY _mesa_noop_Vertex2f( GLfloat a, GLfloat b ) -{ - (void) a; (void) b; -} - -static void GLAPIENTRY _mesa_noop_Vertex3f( GLfloat a, GLfloat b, GLfloat c ) -{ - (void) a; (void) b; (void) c; -} - -static void GLAPIENTRY _mesa_noop_Vertex4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d ) -{ - (void) a; (void) b; (void) c; (void) d; -} - - -#if FEATURE_evaluators -/* Similarly, these have no effect outside begin/end: - */ -static void GLAPIENTRY _mesa_noop_EvalCoord1f( GLfloat a ) -{ - (void) a; -} - -static void GLAPIENTRY _mesa_noop_EvalCoord1fv( const GLfloat *v ) -{ - (void) v; -} - -static void GLAPIENTRY _mesa_noop_EvalCoord2f( GLfloat a, GLfloat b ) -{ - (void) a; (void) b; -} - -static void GLAPIENTRY _mesa_noop_EvalCoord2fv( const GLfloat *v ) -{ - (void) v; -} - -static void GLAPIENTRY _mesa_noop_EvalPoint1( GLint a ) -{ - (void) a; -} - -static void GLAPIENTRY _mesa_noop_EvalPoint2( GLint a, GLint b ) -{ - (void) a; (void) b; -} -#endif /* FEATURE_evaluators */ - - -/* Begin -- call into driver, should result in the vtxfmt being - * swapped out: - */ -static void GLAPIENTRY _mesa_noop_Begin( GLenum mode ) -{ - (void) mode; -} - - -/* End -- just raise an error - */ -static void GLAPIENTRY _mesa_noop_End( void ) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd(no glBegin)" ); -} - - -/*** - * PrimitiveRestart called outside glBegin()/End(): raise an error - */ -static void GLAPIENTRY _mesa_noop_PrimitiveRestartNV( void ) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartNV(no glBegin)"); -} - - -/** - * Execute a glRectf() function. This is not suitable for GL_COMPILE - * modes (as the test for outside begin/end is not compiled), - * but may be useful for drivers in circumstances which exclude - * display list interactions. - * - * (None of the functions in this file are suitable for GL_COMPILE - * modes). - */ -void GLAPIENTRY -_mesa_noop_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - { - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - } - - CALL_Begin(GET_DISPATCH(), (GL_QUADS)); - CALL_Vertex2f(GET_DISPATCH(), (x1, y1)); - CALL_Vertex2f(GET_DISPATCH(), (x2, y1)); - CALL_Vertex2f(GET_DISPATCH(), (x2, y2)); - CALL_Vertex2f(GET_DISPATCH(), (x1, y2)); - CALL_End(GET_DISPATCH(), ()); -} - - -/** - * Some very basic support for arrays. Drivers without explicit array - * support can hook these in, but still need to supply an array-elt - * implementation. - */ -static void GLAPIENTRY -_mesa_noop_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - CALL_Begin(GET_DISPATCH(), (mode)); - for (i = 0; i < count; i++) - CALL_ArrayElement(GET_DISPATCH(), (start + i)); - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY -_mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 )) - return; - - CALL_Begin(GET_DISPATCH(), (mode)); - - switch (type) { - case GL_UNSIGNED_BYTE: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); - break; - case GL_UNSIGNED_SHORT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); - break; - case GL_UNSIGNED_INT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); - break; - } - - CALL_End(GET_DISPATCH(), ()); -} - -static void GLAPIENTRY -_mesa_noop_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, - basevertex )) - return; - - CALL_Begin(GET_DISPATCH(), (mode)); - - switch (type) { - case GL_UNSIGNED_BYTE: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] + - basevertex)); - break; - case GL_UNSIGNED_SHORT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] + - basevertex )); - break; - case GL_UNSIGNED_INT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] + - basevertex )); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElementsBaseVertex(type)" ); - break; - } - - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY -_mesa_noop_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - - if (_mesa_validate_DrawRangeElements( ctx, mode, - start, end, - count, type, indices, 0 )) - CALL_DrawElements(GET_DISPATCH(), (mode, count, type, indices)); -} - -/* GL_EXT_multi_draw_arrays */ -void GLAPIENTRY -_mesa_noop_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, - const GLvoid **indices, GLsizei primcount) -{ - GLsizei i; - - for (i = 0; i < primcount; i++) { - if (count[i] > 0) { - CALL_DrawElements(GET_DISPATCH(), (mode, count[i], type, indices[i])); - } - } -} - -static void GLAPIENTRY -_mesa_noop_DrawRangeElementsBaseVertex(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex) -{ - GET_CURRENT_CONTEXT(ctx); - - if (_mesa_validate_DrawRangeElements( ctx, mode, - start, end, - count, type, indices, basevertex )) - CALL_DrawElementsBaseVertex(GET_DISPATCH(), (mode, count, type, indices, - basevertex)); -} - -/* GL_EXT_multi_draw_arrays */ -void GLAPIENTRY -_mesa_noop_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, - GLenum type, - const GLvoid **indices, - GLsizei primcount, - const GLint *basevertex) -{ - GLsizei i; - - for (i = 0; i < primcount; i++) { - if (count[i] > 0) { - CALL_DrawElementsBaseVertex(GET_DISPATCH(), (mode, count[i], type, - indices[i], - basevertex[i])); - } - } -} - -/* - * Eval Mesh - */ - -/** - * KW: - * If are compiling, we don't know whether eval will produce a - * vertex when it is run in the future. If this is pure immediate - * mode, eval is a noop if neither vertex map is enabled. - * - * Thus we need to have a check in the display list code or elsewhere - * for eval(1,2) vertices in the case where map(1,2)_vertex is - * disabled, and to purge those vertices from the vb. - */ -void GLAPIENTRY -_mesa_noop_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - GLfloat u, du; - GLenum prim; - - ASSERT_OUTSIDE_BEGIN_END(ctx); - - switch (mode) { - case GL_POINT: - prim = GL_POINTS; - break; - case GL_LINE: - prim = GL_LINE_STRIP; - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" ); - return; - } - - /* No effect if vertex maps disabled. - */ - if (!ctx->Eval.Map1Vertex4 && - !ctx->Eval.Map1Vertex3 && - !(ctx->VertexProgram._Enabled && ctx->Eval.Map1Attrib[VERT_ATTRIB_POS])) - return; - - du = ctx->Eval.MapGrid1du; - u = ctx->Eval.MapGrid1u1 + i1 * du; - - CALL_Begin(GET_DISPATCH(), (prim)); - for (i=i1;i<=i2;i++,u+=du) { - CALL_EvalCoord1f(GET_DISPATCH(), (u)); - } - CALL_End(GET_DISPATCH(), ()); -} - - - -void GLAPIENTRY -_mesa_noop_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat u, du, v, dv, v1, u1; - GLint i, j; - - ASSERT_OUTSIDE_BEGIN_END(ctx); - - switch (mode) { - case GL_POINT: - case GL_LINE: - case GL_FILL: - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" ); - return; - } - - /* No effect if vertex maps disabled. - */ - if (!ctx->Eval.Map2Vertex4 && - !ctx->Eval.Map2Vertex3 && - !(ctx->VertexProgram._Enabled && ctx->Eval.Map2Attrib[VERT_ATTRIB_POS])) - return; - - du = ctx->Eval.MapGrid2du; - dv = ctx->Eval.MapGrid2dv; - v1 = ctx->Eval.MapGrid2v1 + j1 * dv; - u1 = ctx->Eval.MapGrid2u1 + i1 * du; - - switch (mode) { - case GL_POINT: - CALL_Begin(GET_DISPATCH(), (GL_POINTS)); - for (v=v1,j=j1;j<=j2;j++,v+=dv) { - for (u=u1,i=i1;i<=i2;i++,u+=du) { - CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); - } - } - CALL_End(GET_DISPATCH(), ()); - break; - case GL_LINE: - for (v=v1,j=j1;j<=j2;j++,v+=dv) { - CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); - for (u=u1,i=i1;i<=i2;i++,u+=du) { - CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); - } - CALL_End(GET_DISPATCH(), ()); - } - for (u=u1,i=i1;i<=i2;i++,u+=du) { - CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); - for (v=v1,j=j1;j<=j2;j++,v+=dv) { - CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); - } - CALL_End(GET_DISPATCH(), ()); - } - break; - case GL_FILL: - for (v=v1,j=j1;jBegin = _mesa_noop_Begin; - - _MESA_INIT_DLIST_VTXFMT(vfmt, _mesa_); - - vfmt->Color3f = _mesa_noop_Color3f; - vfmt->Color3fv = _mesa_noop_Color3fv; - vfmt->Color4f = _mesa_noop_Color4f; - vfmt->Color4fv = _mesa_noop_Color4fv; - vfmt->EdgeFlag = _mesa_noop_EdgeFlag; - vfmt->End = _mesa_noop_End; - - vfmt->PrimitiveRestartNV = _mesa_noop_PrimitiveRestartNV; - - _MESA_INIT_EVAL_VTXFMT(vfmt, _mesa_noop_); - - vfmt->FogCoordfEXT = _mesa_noop_FogCoordfEXT; - vfmt->FogCoordfvEXT = _mesa_noop_FogCoordfvEXT; - vfmt->Indexf = _mesa_noop_Indexf; - vfmt->Indexfv = _mesa_noop_Indexfv; - vfmt->Materialfv = _mesa_noop_Materialfv; - vfmt->MultiTexCoord1fARB = _mesa_noop_MultiTexCoord1fARB; - vfmt->MultiTexCoord1fvARB = _mesa_noop_MultiTexCoord1fvARB; - vfmt->MultiTexCoord2fARB = _mesa_noop_MultiTexCoord2fARB; - vfmt->MultiTexCoord2fvARB = _mesa_noop_MultiTexCoord2fvARB; - vfmt->MultiTexCoord3fARB = _mesa_noop_MultiTexCoord3fARB; - vfmt->MultiTexCoord3fvARB = _mesa_noop_MultiTexCoord3fvARB; - vfmt->MultiTexCoord4fARB = _mesa_noop_MultiTexCoord4fARB; - vfmt->MultiTexCoord4fvARB = _mesa_noop_MultiTexCoord4fvARB; - vfmt->Normal3f = _mesa_noop_Normal3f; - vfmt->Normal3fv = _mesa_noop_Normal3fv; - vfmt->SecondaryColor3fEXT = _mesa_noop_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = _mesa_noop_SecondaryColor3fvEXT; - vfmt->TexCoord1f = _mesa_noop_TexCoord1f; - vfmt->TexCoord1fv = _mesa_noop_TexCoord1fv; - vfmt->TexCoord2f = _mesa_noop_TexCoord2f; - vfmt->TexCoord2fv = _mesa_noop_TexCoord2fv; - vfmt->TexCoord3f = _mesa_noop_TexCoord3f; - vfmt->TexCoord3fv = _mesa_noop_TexCoord3fv; - vfmt->TexCoord4f = _mesa_noop_TexCoord4f; - vfmt->TexCoord4fv = _mesa_noop_TexCoord4fv; - vfmt->Vertex2f = _mesa_noop_Vertex2f; - vfmt->Vertex2fv = _mesa_noop_Vertex2fv; - vfmt->Vertex3f = _mesa_noop_Vertex3f; - vfmt->Vertex3fv = _mesa_noop_Vertex3fv; - vfmt->Vertex4f = _mesa_noop_Vertex4f; - vfmt->Vertex4fv = _mesa_noop_Vertex4fv; - vfmt->VertexAttrib1fNV = _mesa_noop_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = _mesa_noop_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = _mesa_noop_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = _mesa_noop_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = _mesa_noop_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = _mesa_noop_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = _mesa_noop_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = _mesa_noop_VertexAttrib4fvNV; - vfmt->VertexAttrib1fARB = _mesa_noop_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = _mesa_noop_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = _mesa_noop_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = _mesa_noop_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = _mesa_noop_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = _mesa_noop_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = _mesa_noop_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = _mesa_noop_VertexAttrib4fvARB; - - vfmt->Rectf = _mesa_noop_Rectf; - - vfmt->DrawArrays = _mesa_noop_DrawArrays; - vfmt->DrawElements = _mesa_noop_DrawElements; - vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements; - vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements; - vfmt->DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex; - vfmt->DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex; - vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex; -} - - -#endif /* FEATURE_beginend */ diff --git a/mesalib/src/mesa/main/api_noop.h b/mesalib/src/mesa/main/api_noop.h deleted file mode 100644 index 4af2cde6b..000000000 --- a/mesalib/src/mesa/main/api_noop.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.1 - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _API_NOOP_H -#define _API_NOOP_H - -#include "main/mfeatures.h" -#include "main/mtypes.h" - -#if FEATURE_beginend - -extern void GLAPIENTRY -_mesa_noop_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); - -extern void GLAPIENTRY -_mesa_noop_EvalMesh1(GLenum mode, GLint i1, GLint i2); - -extern void GLAPIENTRY -_mesa_noop_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); - -extern void GLAPIENTRY -_mesa_noop_Materialfv(GLenum face, GLenum pname, const GLfloat *param); - -extern void GLAPIENTRY -_mesa_noop_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, - const GLvoid **indices, GLsizei primcount); - -extern void GLAPIENTRY -_mesa_noop_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, - GLenum type, - const GLvoid **indices, - GLsizei primcount, - const GLint *basevertex); - -extern void -_mesa_noop_vtxfmt_init(GLvertexformat *vfmt); - -#endif /* FEATURE_beginend */ - -#endif /* _API_NOOP_H */ diff --git a/mesalib/src/mesa/main/eval.h b/mesalib/src/mesa/main/eval.h index 5a4203138..c07d4d532 100644 --- a/mesalib/src/mesa/main/eval.h +++ b/mesalib/src/mesa/main/eval.h @@ -58,10 +58,6 @@ extern GLuint _mesa_evaluator_components( GLenum target ); -extern void gl_free_control_points( struct gl_context *ctx, - GLenum target, GLfloat *data ); - - extern GLfloat *_mesa_copy_map_points1f( GLenum target, GLint ustride, GLint uorder, const GLfloat *points ); diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index bcebf1240..f8b148cee 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -1939,7 +1939,29 @@ _mesa_CheckFramebufferStatusEXT(GLenum target) return buffer->_Status; } - +/** + * Replicate the src attachment point. Used by framebuffer_texture() when + * the same texture is attached at GL_DEPTH_ATTACHMENT and + * GL_STENCIL_ATTACHMENT. + */ +static void +reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb, + gl_buffer_index dst, + gl_buffer_index src) +{ + struct gl_renderbuffer_attachment *dst_att = &fb->Attachment[dst]; + struct gl_renderbuffer_attachment *src_att = &fb->Attachment[src]; + + assert(src_att->Texture != NULL); + assert (src_att->Renderbuffer != NULL); + + _mesa_reference_texobj(&dst_att->Texture, src_att->Texture); + _mesa_reference_renderbuffer(&dst_att->Renderbuffer, src_att->Renderbuffer); + dst_att->Type = src_att->Type; + dst_att->Complete = src_att->Complete; + dst_att->TextureLevel = src_att->TextureLevel; + dst_att->Zoffset = src_att->Zoffset; +} /** * Common code called by glFramebufferTexture1D/2D/3DEXT(). @@ -2041,8 +2063,34 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, _glthread_LOCK_MUTEX(fb->Mutex); if (texObj) { - _mesa_set_texture_attachment(ctx, fb, att, texObj, textarget, - level, zoffset); + if (attachment == GL_DEPTH_ATTACHMENT && + texObj == fb->Attachment[BUFFER_STENCIL].Texture) { + /* The texture object is already attached to the stencil attachment + * point. Don't create a new renderbuffer; just reuse the stencil + * attachment's. This is required to prevent a GL error in + * glGetFramebufferAttachmentParameteriv(GL_DEPTH_STENCIL). + */ + reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH, + BUFFER_STENCIL); + } else if (attachment == GL_STENCIL_ATTACHMENT && + texObj== fb->Attachment[BUFFER_DEPTH].Texture) { + /* As above, but with depth and stencil juxtasposed. */ + reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL, + BUFFER_DEPTH); + } else { + _mesa_set_texture_attachment(ctx, fb, att, texObj, textarget, + level, zoffset); + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { + /* Above we created a new renderbuffer and attached it to the + * depth attachment point. Now attach it to the stencil attachment + * point too. + */ + assert(att == &fb->Attachment[BUFFER_DEPTH]); + reuse_framebuffer_texture_attachment(fb,BUFFER_STENCIL, + BUFFER_DEPTH); + } + } + /* Set the render-to-texture flag. We'll check this flag in * glTexImage() and friends to determine if we need to revalidate * any FBOs that might be rendering into this texture. @@ -2055,6 +2103,10 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, } else { _mesa_remove_attachment(ctx, att); + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { + assert(att == &fb->Attachment[BUFFER_DEPTH]); + _mesa_remove_attachment(ctx, &fb->Attachment[BUFFER_STENCIL]); + } } invalidate_framebuffer(fb); diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index adcbaeb19..deab97d3e 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1798,6 +1798,7 @@ typedef enum typedef enum { SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */ + SYSTEM_VALUE_VERTEX_ID, /**< Vertex shader only */ SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */ SYSTEM_VALUE_MAX /**< Number of values */ } gl_system_value; diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 39aa5570e..5371d6a17 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -894,7 +894,7 @@ _mesa_get_uniform_location(struct gl_context *ctx, array_lookup = false; } - unsigned location; + unsigned location = 0; const bool found = shProg->UniformHash->get(location, name_copy); assert(!found diff --git a/mesalib/src/mesa/sources.mak b/mesalib/src/mesa/sources.mak index b804a95cc..102562ace 100644 --- a/mesalib/src/mesa/sources.mak +++ b/mesalib/src/mesa/sources.mak @@ -9,7 +9,6 @@ MAIN_SOURCES = \ main/api_arrayelt.c \ main/api_exec.c \ main/api_loopback.c \ - main/api_noop.c \ main/api_validate.c \ main/accum.c \ main/arbprogram.c \ @@ -183,6 +182,7 @@ VBO_SOURCES = \ vbo/vbo_exec_array.c \ vbo/vbo_exec_draw.c \ vbo/vbo_exec_eval.c \ + vbo/vbo_noop.c \ vbo/vbo_rebase.c \ vbo/vbo_split.c \ vbo/vbo_split_copy.c \ diff --git a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c index 1a8854b9b..fa37be0b6 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c @@ -376,6 +376,10 @@ setup_bitmap_vertex_data(struct st_context *st, bool normalized, PIPE_USAGE_STREAM, max_slots * sizeof(st->bitmap.vertices)); + if (!st->bitmap.vbuf) { + /* out of memory */ + return 0; + } } /* Positions are in clip coords since we need to do clipping in case @@ -547,11 +551,12 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, sv->texture->target != PIPE_TEXTURE_RECT, x, y, width, height, z, color); - util_draw_vertex_buffer(pipe, st->cso_context, st->bitmap.vbuf, offset, - PIPE_PRIM_TRIANGLE_FAN, - 4, /* verts */ - 3); /* attribs/vert */ - + if (st->bitmap.vbuf) { + util_draw_vertex_buffer(pipe, st->cso_context, st->bitmap.vbuf, offset, + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + 3); /* attribs/vert */ + } /* restore state */ cso_restore_rasterizer(cso); diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c index eff195068..332b0d1b6 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c @@ -114,7 +114,6 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, uint semantic_names[2 + MAX_TEXTURE_UNITS]; uint semantic_indexes[2 + MAX_TEXTURE_UNITS]; struct pipe_vertex_element velements[2 + MAX_TEXTURE_UNITS]; - GLbitfield inputs = VERT_BIT_POS; st_validate_state(st); @@ -128,7 +127,6 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, numTexCoords = 0; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_2D_BIT) { - inputs |= VERT_BIT_TEX(i); numTexCoords++; } } diff --git a/mesalib/src/mesa/swrast/s_readpix.c b/mesalib/src/mesa/swrast/s_readpix.c index 54f42db02..3cef7304a 100644 --- a/mesalib/src/mesa/swrast/s_readpix.c +++ b/mesalib/src/mesa/swrast/s_readpix.c @@ -236,6 +236,7 @@ slow_read_rgba_pixels( struct gl_context *ctx, GLbitfield transferOps ) { struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; + const gl_format rbFormat = _mesa_get_srgb_format_linear(rb->Format); union { float f[MAX_WIDTH][4]; unsigned int i[MAX_WIDTH][4]; @@ -252,11 +253,10 @@ slow_read_rgba_pixels( struct gl_context *ctx, for (j = 0; j < height; j++) { if (_mesa_is_integer_format(format)) { - _mesa_unpack_int_rgba_row(rb->Format, width, map, rgba.i); + _mesa_unpack_int_rgba_row(rbFormat, width, map, rgba.i); _mesa_pack_rgba_span_int(ctx, width, rgba.i, format, type, dst); } else { - _mesa_unpack_rgba_row(_mesa_get_srgb_format_linear(rb->Format), - width, map, rgba.f); + _mesa_unpack_rgba_row(rbFormat, width, map, rgba.f); _mesa_pack_rgba_span_float(ctx, width, rgba.f, format, type, dst, packing, transferOps); } diff --git a/mesalib/src/mesa/swrast/s_texture.c b/mesalib/src/mesa/swrast/s_texture.c index ba67c6fa4..76a31eeae 100644 --- a/mesalib/src/mesa/swrast/s_texture.c +++ b/mesalib/src/mesa/swrast/s_texture.c @@ -241,7 +241,6 @@ _swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj) /* XXX we'll eventually call _swrast_map_teximage() here */ swImage->Data = swImage->Buffer; - assert(swImage->Buffer); } } } diff --git a/mesalib/src/mesa/vbo/vbo_exec.h b/mesalib/src/mesa/vbo/vbo_exec.h index 0b72579a8..8d6b8f95a 100644 --- a/mesalib/src/mesa/vbo/vbo_exec.h +++ b/mesalib/src/mesa/vbo/vbo_exec.h @@ -82,6 +82,7 @@ struct vbo_exec_context { struct gl_context *ctx; GLvertexformat vtxfmt; + GLvertexformat vtxfmt_noop; struct { struct gl_buffer_object *bufferobj; diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c index 5f3ed9d5d..62e7d03f3 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_api.c +++ b/mesalib/src/mesa/vbo/vbo_exec_api.c @@ -41,11 +41,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/state.h" #include "main/light.h" #include "main/api_arrayelt.h" -#include "main/api_noop.h" #include "main/api_validate.h" #include "main/dispatch.h" #include "vbo_context.h" +#include "vbo_noop.h" + #ifdef ERROR #undef ERROR @@ -546,13 +547,146 @@ static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j ) vbo_exec_EvalCoord2f( u, v ); } -/* use noop eval mesh */ -#define vbo_exec_EvalMesh1 _mesa_noop_EvalMesh1 -#define vbo_exec_EvalMesh2 _mesa_noop_EvalMesh2 + +static void GLAPIENTRY +vbo_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + GLfloat u, du; + GLenum prim; + + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (mode) { + case GL_POINT: + prim = GL_POINTS; + break; + case GL_LINE: + prim = GL_LINE_STRIP; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" ); + return; + } + + /* No effect if vertex maps disabled. + */ + if (!ctx->Eval.Map1Vertex4 && + !ctx->Eval.Map1Vertex3 && + !(ctx->VertexProgram._Enabled && ctx->Eval.Map1Attrib[VERT_ATTRIB_POS])) + return; + + du = ctx->Eval.MapGrid1du; + u = ctx->Eval.MapGrid1u1 + i1 * du; + + CALL_Begin(GET_DISPATCH(), (prim)); + for (i=i1;i<=i2;i++,u+=du) { + CALL_EvalCoord1f(GET_DISPATCH(), (u)); + } + CALL_End(GET_DISPATCH(), ()); +} + + +static void GLAPIENTRY +vbo_exec_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat u, du, v, dv, v1, u1; + GLint i, j; + + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (mode) { + case GL_POINT: + case GL_LINE: + case GL_FILL: + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" ); + return; + } + + /* No effect if vertex maps disabled. + */ + if (!ctx->Eval.Map2Vertex4 && + !ctx->Eval.Map2Vertex3 && + !(ctx->VertexProgram._Enabled && ctx->Eval.Map2Attrib[VERT_ATTRIB_POS])) + return; + + du = ctx->Eval.MapGrid2du; + dv = ctx->Eval.MapGrid2dv; + v1 = ctx->Eval.MapGrid2v1 + j1 * dv; + u1 = ctx->Eval.MapGrid2u1 + i1 * du; + + switch (mode) { + case GL_POINT: + CALL_Begin(GET_DISPATCH(), (GL_POINTS)); + for (v=v1,j=j1;j<=j2;j++,v+=dv) { + for (u=u1,i=i1;i<=i2;i++,u+=du) { + CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); + } + } + CALL_End(GET_DISPATCH(), ()); + break; + case GL_LINE: + for (v=v1,j=j1;j<=j2;j++,v+=dv) { + CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); + for (u=u1,i=i1;i<=i2;i++,u+=du) { + CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); + } + CALL_End(GET_DISPATCH(), ()); + } + for (u=u1,i=i1;i<=i2;i++,u+=du) { + CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); + for (v=v1,j=j1;j<=j2;j++,v+=dv) { + CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); + } + CALL_End(GET_DISPATCH(), ()); + } + break; + case GL_FILL: + for (v=v1,j=j1;jRectf = _mesa_noop_Rectf; + vfmt->Rectf = vbo_exec_Rectf; /* from attrib_tmp.h: */ @@ -896,7 +1030,9 @@ void vbo_use_buffer_objects(struct gl_context *ctx) /* Allocate a real buffer object now */ _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL); exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target); - ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj); + if (!ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "VBO allocation"); + } } @@ -933,6 +1069,7 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec ) exec->vtx.buffer_ptr = exec->vtx.buffer_map; vbo_exec_vtxfmt_init( exec ); + _mesa_noop_vtxfmt_init(&exec->vtxfmt_noop); /* Hook our functions into the dispatch table. */ diff --git a/mesalib/src/mesa/vbo/vbo_exec_draw.c b/mesalib/src/mesa/vbo/vbo_exec_draw.c index 8ffaaaa48..efb6dd10a 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_draw.c +++ b/mesalib/src/mesa/vbo/vbo_exec_draw.c @@ -28,11 +28,14 @@ #include "main/glheader.h" #include "main/bufferobj.h" #include "main/compiler.h" +#include "main/context.h" #include "main/enums.h" #include "main/mfeatures.h" #include "main/state.h" +#include "main/vtxfmt.h" #include "vbo_context.h" +#include "vbo_noop.h" #if FEATURE_beginend @@ -308,32 +311,55 @@ vbo_exec_vtx_map( struct vbo_exec_context *exec ) if (VBO_VERT_BUFFER_SIZE > exec->vtx.buffer_used + 1024) { /* The VBO exists and there's room for more */ - exec->vtx.buffer_map = - (GLfloat *)ctx->Driver.MapBufferRange(ctx, - exec->vtx.buffer_used, - (VBO_VERT_BUFFER_SIZE - - exec->vtx.buffer_used), - accessRange, - exec->vtx.bufferobj); - exec->vtx.buffer_ptr = exec->vtx.buffer_map; + if (exec->vtx.bufferobj->Size > 0) { + exec->vtx.buffer_map = + (GLfloat *)ctx->Driver.MapBufferRange(ctx, + exec->vtx.buffer_used, + (VBO_VERT_BUFFER_SIZE - + exec->vtx.buffer_used), + accessRange, + exec->vtx.bufferobj); + exec->vtx.buffer_ptr = exec->vtx.buffer_map; + } + else { + exec->vtx.buffer_ptr = exec->vtx.buffer_map = NULL; + } } if (!exec->vtx.buffer_map) { /* Need to allocate a new VBO */ exec->vtx.buffer_used = 0; - ctx->Driver.BufferData(ctx, GL_ARRAY_BUFFER_ARB, - VBO_VERT_BUFFER_SIZE, - NULL, usage, exec->vtx.bufferobj); + if (ctx->Driver.BufferData(ctx, GL_ARRAY_BUFFER_ARB, + VBO_VERT_BUFFER_SIZE, + NULL, usage, exec->vtx.bufferobj)) { + /* buffer allocation worked, now map the buffer */ + exec->vtx.buffer_map = + (GLfloat *)ctx->Driver.MapBufferRange(ctx, + 0, VBO_VERT_BUFFER_SIZE, + accessRange, + exec->vtx.bufferobj); + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "VBO allocation"); + exec->vtx.buffer_map = NULL; + } + } + exec->vtx.buffer_ptr = exec->vtx.buffer_map; - exec->vtx.buffer_map = - (GLfloat *)ctx->Driver.MapBufferRange(ctx, - 0, VBO_VERT_BUFFER_SIZE, - accessRange, - exec->vtx.bufferobj); - assert(exec->vtx.buffer_map); - exec->vtx.buffer_ptr = exec->vtx.buffer_map; + if (!exec->vtx.buffer_map) { + /* out of memory */ + _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt_noop ); + } + else { + if (_mesa_using_noop_vtxfmt(ctx->Exec)) { + /* The no-op functions are installed so switch back to regular + * functions. We do this test just to avoid frequent and needless + * calls to _mesa_install_exec_vtxfmt(). + */ + _mesa_install_exec_vtxfmt(ctx, &exec->vtxfmt); + } } if (0) diff --git a/mesalib/src/mesa/vbo/vbo_noop.c b/mesalib/src/mesa/vbo/vbo_noop.c new file mode 100644 index 000000000..430011207 --- /dev/null +++ b/mesalib/src/mesa/vbo/vbo_noop.c @@ -0,0 +1,519 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2011 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * GLvertexformat no-op functions. Used in out-of-memory situations. + */ + + +#include "main/glheader.h" +#include "main/api_arrayelt.h" +#include "main/context.h" +#include "main/dispatch.h" +#include "main/dlist.h" +#include "main/eval.h" +#include "main/mfeatures.h" +#include "vbo/vbo_noop.h" + +#if FEATURE_beginend + + +static void GLAPIENTRY +_mesa_noop_EdgeFlag(GLboolean b) +{ +} + +static void GLAPIENTRY +_mesa_noop_Indexf(GLfloat f) +{ +} + +static void GLAPIENTRY +_mesa_noop_Indexfv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_FogCoordfEXT(GLfloat a) +{ +} + +static void GLAPIENTRY +_mesa_noop_FogCoordfvEXT(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_Normal3f(GLfloat a, GLfloat b, GLfloat c) +{ +} + +static void GLAPIENTRY +_mesa_noop_Normal3fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_Color4f(GLfloat a, GLfloat b, GLfloat c, GLfloat d) +{ +} + +static void GLAPIENTRY +_mesa_noop_Color4fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_Color3f(GLfloat a, GLfloat b, GLfloat c) +{ +} + +static void GLAPIENTRY +_mesa_noop_Color3fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_MultiTexCoord1fARB(GLenum target, GLfloat a) +{ +} + +static void GLAPIENTRY +_mesa_noop_MultiTexCoord1fvARB(GLenum target, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_MultiTexCoord2fARB(GLenum target, GLfloat a, GLfloat b) +{ +} + +static void GLAPIENTRY +_mesa_noop_MultiTexCoord2fvARB(GLenum target, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_MultiTexCoord3fARB(GLenum target, GLfloat a, GLfloat b, GLfloat c) +{ +} + +static void GLAPIENTRY +_mesa_noop_MultiTexCoord3fvARB(GLenum target, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_MultiTexCoord4fARB(GLenum target, GLfloat a, GLfloat b, + GLfloat c, GLfloat d) +{ +} + +static void GLAPIENTRY +_mesa_noop_MultiTexCoord4fvARB(GLenum target, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_SecondaryColor3fEXT(GLfloat a, GLfloat b, GLfloat c) +{ +} + +static void GLAPIENTRY +_mesa_noop_SecondaryColor3fvEXT(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_TexCoord1f(GLfloat a) +{ +} + +static void GLAPIENTRY +_mesa_noop_TexCoord1fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_TexCoord2f(GLfloat a, GLfloat b) +{ +} + +static void GLAPIENTRY +_mesa_noop_TexCoord2fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_TexCoord3f(GLfloat a, GLfloat b, GLfloat c) +{ +} + +static void GLAPIENTRY +_mesa_noop_TexCoord3fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_TexCoord4f(GLfloat a, GLfloat b, GLfloat c, GLfloat d) +{ +} + +static void GLAPIENTRY +_mesa_noop_TexCoord4fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib1fNV(GLuint index, GLfloat x) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib1fvNV(GLuint index, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib2fvNV(GLuint index, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib3fvNV(GLuint index, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib4fNV(GLuint index, GLfloat x, + GLfloat y, GLfloat z, GLfloat w) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib4fvNV(GLuint index, const GLfloat * v) +{ +} + + +static void GLAPIENTRY +_mesa_noop_VertexAttrib1fARB(GLuint index, GLfloat x) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib1fvARB(GLuint index, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib2fvARB(GLuint index, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib3fvARB(GLuint index, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib4fARB(GLuint index, GLfloat x, + GLfloat y, GLfloat z, GLfloat w) +{ +} + +static void GLAPIENTRY +_mesa_noop_VertexAttrib4fvARB(GLuint index, const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_Materialfv(GLenum face, GLenum pname, const GLfloat * params) +{ +} + +static void GLAPIENTRY +_mesa_noop_Vertex2fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_Vertex3fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_Vertex4fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_Vertex2f(GLfloat a, GLfloat b) +{ +} + +static void GLAPIENTRY +_mesa_noop_Vertex3f(GLfloat a, GLfloat b, GLfloat c) +{ +} + +static void GLAPIENTRY +_mesa_noop_Vertex4f(GLfloat a, GLfloat b, GLfloat c, GLfloat d) +{ +} + + +#if FEATURE_evaluators +static void GLAPIENTRY +_mesa_noop_EvalCoord1f(GLfloat a) +{ +} + +static void GLAPIENTRY +_mesa_noop_EvalCoord1fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_EvalCoord2f(GLfloat a, GLfloat b) +{ +} + +static void GLAPIENTRY +_mesa_noop_EvalCoord2fv(const GLfloat * v) +{ +} + +static void GLAPIENTRY +_mesa_noop_EvalPoint1(GLint a) +{ +} + +static void GLAPIENTRY +_mesa_noop_EvalPoint2(GLint a, GLint b) +{ +} +#endif /* FEATURE_evaluators */ + + +static void GLAPIENTRY +_mesa_noop_Begin(GLenum mode) +{ +} + +static void GLAPIENTRY +_mesa_noop_End(void) +{ +} + +static void GLAPIENTRY +_mesa_noop_PrimitiveRestartNV(void) +{ +} + + +static void GLAPIENTRY +_mesa_noop_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) +{ +} + + +static void GLAPIENTRY +_mesa_noop_DrawArrays(GLenum mode, GLint start, GLsizei count) +{ +} + +static void GLAPIENTRY +_mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid * indices) +{ +} + +static void GLAPIENTRY +_mesa_noop_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, + const GLvoid * indices, GLint basevertex) +{ +} + + +static void GLAPIENTRY +_mesa_noop_DrawRangeElements(GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid * indices) +{ +} + +static void GLAPIENTRY +_mesa_noop_MultiDrawElements(GLenum mode, const GLsizei * count, GLenum type, + const GLvoid ** indices, GLsizei primcount) +{ +} + +static void GLAPIENTRY +_mesa_noop_DrawRangeElementsBaseVertex(GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid * indices, + GLint basevertex) +{ +} + +static void GLAPIENTRY +_mesa_noop_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei * count, + GLenum type, + const GLvoid ** indices, + GLsizei primcount, + const GLint * basevertex) +{ +} + +static void GLAPIENTRY +_mesa_noop_EvalMesh1(GLenum mode, GLint i1, GLint i2) +{ +} + +static void GLAPIENTRY +_mesa_noop_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) +{ +} + + +/** + * Build a vertexformat of functions that are no-ops. + * These are used in out-of-memory situations when we have no VBO + * to put the vertex data into. + */ +void +_mesa_noop_vtxfmt_init(GLvertexformat * vfmt) +{ + _MESA_INIT_ARRAYELT_VTXFMT(vfmt, _ae_); + + vfmt->Begin = _mesa_noop_Begin; + + _MESA_INIT_DLIST_VTXFMT(vfmt, _mesa_); + + vfmt->Color3f = _mesa_noop_Color3f; + vfmt->Color3fv = _mesa_noop_Color3fv; + vfmt->Color4f = _mesa_noop_Color4f; + vfmt->Color4fv = _mesa_noop_Color4fv; + vfmt->EdgeFlag = _mesa_noop_EdgeFlag; + vfmt->End = _mesa_noop_End; + + vfmt->PrimitiveRestartNV = _mesa_noop_PrimitiveRestartNV; + + _MESA_INIT_EVAL_VTXFMT(vfmt, _mesa_noop_); + + vfmt->FogCoordfEXT = _mesa_noop_FogCoordfEXT; + vfmt->FogCoordfvEXT = _mesa_noop_FogCoordfvEXT; + vfmt->Indexf = _mesa_noop_Indexf; + vfmt->Indexfv = _mesa_noop_Indexfv; + vfmt->Materialfv = _mesa_noop_Materialfv; + vfmt->MultiTexCoord1fARB = _mesa_noop_MultiTexCoord1fARB; + vfmt->MultiTexCoord1fvARB = _mesa_noop_MultiTexCoord1fvARB; + vfmt->MultiTexCoord2fARB = _mesa_noop_MultiTexCoord2fARB; + vfmt->MultiTexCoord2fvARB = _mesa_noop_MultiTexCoord2fvARB; + vfmt->MultiTexCoord3fARB = _mesa_noop_MultiTexCoord3fARB; + vfmt->MultiTexCoord3fvARB = _mesa_noop_MultiTexCoord3fvARB; + vfmt->MultiTexCoord4fARB = _mesa_noop_MultiTexCoord4fARB; + vfmt->MultiTexCoord4fvARB = _mesa_noop_MultiTexCoord4fvARB; + vfmt->Normal3f = _mesa_noop_Normal3f; + vfmt->Normal3fv = _mesa_noop_Normal3fv; + vfmt->SecondaryColor3fEXT = _mesa_noop_SecondaryColor3fEXT; + vfmt->SecondaryColor3fvEXT = _mesa_noop_SecondaryColor3fvEXT; + vfmt->TexCoord1f = _mesa_noop_TexCoord1f; + vfmt->TexCoord1fv = _mesa_noop_TexCoord1fv; + vfmt->TexCoord2f = _mesa_noop_TexCoord2f; + vfmt->TexCoord2fv = _mesa_noop_TexCoord2fv; + vfmt->TexCoord3f = _mesa_noop_TexCoord3f; + vfmt->TexCoord3fv = _mesa_noop_TexCoord3fv; + vfmt->TexCoord4f = _mesa_noop_TexCoord4f; + vfmt->TexCoord4fv = _mesa_noop_TexCoord4fv; + vfmt->Vertex2f = _mesa_noop_Vertex2f; + vfmt->Vertex2fv = _mesa_noop_Vertex2fv; + vfmt->Vertex3f = _mesa_noop_Vertex3f; + vfmt->Vertex3fv = _mesa_noop_Vertex3fv; + vfmt->Vertex4f = _mesa_noop_Vertex4f; + vfmt->Vertex4fv = _mesa_noop_Vertex4fv; + vfmt->VertexAttrib1fNV = _mesa_noop_VertexAttrib1fNV; + vfmt->VertexAttrib1fvNV = _mesa_noop_VertexAttrib1fvNV; + vfmt->VertexAttrib2fNV = _mesa_noop_VertexAttrib2fNV; + vfmt->VertexAttrib2fvNV = _mesa_noop_VertexAttrib2fvNV; + vfmt->VertexAttrib3fNV = _mesa_noop_VertexAttrib3fNV; + vfmt->VertexAttrib3fvNV = _mesa_noop_VertexAttrib3fvNV; + vfmt->VertexAttrib4fNV = _mesa_noop_VertexAttrib4fNV; + vfmt->VertexAttrib4fvNV = _mesa_noop_VertexAttrib4fvNV; + vfmt->VertexAttrib1fARB = _mesa_noop_VertexAttrib1fARB; + vfmt->VertexAttrib1fvARB = _mesa_noop_VertexAttrib1fvARB; + vfmt->VertexAttrib2fARB = _mesa_noop_VertexAttrib2fARB; + vfmt->VertexAttrib2fvARB = _mesa_noop_VertexAttrib2fvARB; + vfmt->VertexAttrib3fARB = _mesa_noop_VertexAttrib3fARB; + vfmt->VertexAttrib3fvARB = _mesa_noop_VertexAttrib3fvARB; + vfmt->VertexAttrib4fARB = _mesa_noop_VertexAttrib4fARB; + vfmt->VertexAttrib4fvARB = _mesa_noop_VertexAttrib4fvARB; + + vfmt->Rectf = _mesa_noop_Rectf; + + vfmt->DrawArrays = _mesa_noop_DrawArrays; + vfmt->DrawElements = _mesa_noop_DrawElements; + vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements; + vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements; + vfmt->DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex; + vfmt->DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex; + vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex; +} + + +/** + * Is the given dispatch table using the no-op functions? + */ +GLboolean +_mesa_using_noop_vtxfmt(const struct _glapi_table *dispatch) +{ + return GET_Begin((struct _glapi_table *) dispatch) == _mesa_noop_Begin; +} + + +#endif /* FEATURE_beginend */ diff --git a/mesalib/src/mesa/vbo/vbo_noop.h b/mesalib/src/mesa/vbo/vbo_noop.h new file mode 100644 index 000000000..f9180374f --- /dev/null +++ b/mesalib/src/mesa/vbo/vbo_noop.h @@ -0,0 +1,45 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2011 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _API_NOOP_H +#define _API_NOOP_H + + +#include "main/mfeatures.h" +#include "main/mtypes.h" + + +#if FEATURE_beginend + +extern void +_mesa_noop_vtxfmt_init(GLvertexformat *vfmt); + +extern GLboolean +_mesa_using_noop_vtxfmt(const struct _glapi_table *dispatch); + + +#endif /* FEATURE_beginend */ + + +#endif /* _API_NOOP_H */ diff --git a/mesalib/src/mesa/vbo/vbo_save.h b/mesalib/src/mesa/vbo/vbo_save.h index a85a7cbf6..4d4a5bf17 100644 --- a/mesalib/src/mesa/vbo/vbo_save.h +++ b/mesalib/src/mesa/vbo/vbo_save.h @@ -122,6 +122,7 @@ struct vbo_save_primitive_store { struct vbo_save_context { struct gl_context *ctx; GLvertexformat vtxfmt; + GLvertexformat vtxfmt_noop; /**< Used if out_of_memory is true */ struct gl_client_array arrays[VBO_ATTRIB_MAX]; const struct gl_client_array *inputs[VBO_ATTRIB_MAX]; @@ -129,6 +130,8 @@ struct vbo_save_context { GLubyte active_sz[VBO_ATTRIB_MAX]; GLuint vertex_size; + GLboolean out_of_memory; /**< True if last VBO allocation failed */ + GLfloat *buffer; GLuint count; GLuint wrap_count; diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c index 87a52e81f..64da7ac49 100644 --- a/mesalib/src/mesa/vbo/vbo_save_api.c +++ b/mesalib/src/mesa/vbo/vbo_save_api.c @@ -75,13 +75,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/eval.h" #include "main/macros.h" #include "main/mfeatures.h" -#include "main/api_noop.h" #include "main/api_validate.h" #include "main/api_arrayelt.h" #include "main/vtxfmt.h" #include "main/dispatch.h" #include "vbo_context.h" +#include "vbo_noop.h" #if FEATURE_dlist @@ -185,6 +185,7 @@ _save_copy_vertices(struct gl_context *ctx, static struct vbo_save_vertex_store * alloc_vertex_store(struct gl_context *ctx) { + struct vbo_save_context *save = &vbo_context(ctx)->save; struct vbo_save_vertex_store *vertex_store = CALLOC_STRUCT(vbo_save_vertex_store); @@ -197,11 +198,22 @@ alloc_vertex_store(struct gl_context *ctx) vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx, VBO_BUF_ID, GL_ARRAY_BUFFER_ARB); + if (vertex_store->bufferobj) { + save->out_of_memory = + !ctx->Driver.BufferData(ctx, + GL_ARRAY_BUFFER_ARB, + VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat), + NULL, GL_STATIC_DRAW_ARB, + vertex_store->bufferobj); + } + else { + save->out_of_memory = GL_TRUE; + } - ctx->Driver.BufferData(ctx, - GL_ARRAY_BUFFER_ARB, - VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat), - NULL, GL_STATIC_DRAW_ARB, vertex_store->bufferobj); + if (save->out_of_memory) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "internal VBO allocation"); + _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop); + } vertex_store->buffer = NULL; vertex_store->used = 0; @@ -231,14 +243,19 @@ map_vertex_store(struct gl_context *ctx, { assert(vertex_store->bufferobj); assert(!vertex_store->buffer); - vertex_store->buffer = - (GLfloat *) ctx->Driver.MapBufferRange(ctx, 0, - vertex_store->bufferobj->Size, - GL_MAP_WRITE_BIT, /* not used */ - vertex_store->bufferobj); - - assert(vertex_store->buffer); - return vertex_store->buffer + vertex_store->used; + if (vertex_store->bufferobj->Size > 0) { + vertex_store->buffer = + (GLfloat *) ctx->Driver.MapBufferRange(ctx, 0, + vertex_store->bufferobj->Size, + GL_MAP_WRITE_BIT, /* not used */ + vertex_store->bufferobj); + assert(vertex_store->buffer); + return vertex_store->buffer + vertex_store->used; + } + else { + /* probably ran out of memory for buffers */ + return NULL; + } } @@ -246,7 +263,9 @@ static void unmap_vertex_store(struct gl_context *ctx, struct vbo_save_vertex_store *vertex_store) { - ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj); + if (vertex_store->bufferobj->Size > 0) { + ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj); + } vertex_store->buffer = NULL; } @@ -400,6 +419,7 @@ _save_compile_vertex_list(struct gl_context *ctx) */ save->vertex_store = alloc_vertex_store(ctx); save->buffer_ptr = map_vertex_store(ctx, save->vertex_store); + save->out_of_memory = save->buffer_ptr == NULL; } if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) { @@ -733,7 +753,12 @@ dlist_fallback(struct gl_context *ctx) _save_copy_to_current(ctx); _save_reset_vertex(ctx); _save_reset_counters(ctx); - _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); + if (save->out_of_memory) { + _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop); + } + else { + _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); + } ctx->Driver.SaveNeedFlush = 0; } @@ -826,7 +851,12 @@ vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode) save->prim[i].count = 0; save->prim[i].num_instances = 1; - _mesa_install_save_vtxfmt(ctx, &save->vtxfmt); + if (save->out_of_memory) { + _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop); + } + else { + _mesa_install_save_vtxfmt(ctx, &save->vtxfmt); + } ctx->Driver.SaveNeedFlush = 1; return GL_TRUE; } @@ -852,7 +882,12 @@ _save_End(void) * etc. received between here and the next begin will be compiled * as opcodes. */ - _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); + if (save->out_of_memory) { + _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop); + } + else { + _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); + } } @@ -932,6 +967,37 @@ _save_DrawArrays(GLenum mode, GLint start, GLsizei count) } +static void GLAPIENTRY +_save_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, + const GLvoid **indices, GLsizei primcount) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; + (void) count; + (void) type; + (void) indices; + (void) primcount; + _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glMultiDrawElements"); +} + + +static void GLAPIENTRY +_save_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, + GLenum type, const GLvoid **indices, + GLsizei primcount, const GLint *basevertex) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; + (void) count; + (void) type; + (void) indices; + (void) primcount; + (void) basevertex; + _mesa_compile_error(ctx, GL_INVALID_OPERATION, + "glMultiDrawElementsBaseVertex"); +} + + static void GLAPIENTRY _save_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { @@ -993,6 +1059,7 @@ _save_PrimitiveRestartNV(void) /* Unlike the functions above, these are to be hooked into the vtxfmt * maintained in ctx->ListState, active when the list is known or * suspected to be outside any begin/end primitive. + * Note: OBE = Outside Begin/End */ static void GLAPIENTRY _save_OBE_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) @@ -1011,11 +1078,15 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count) { GET_CURRENT_CONTEXT(ctx); + struct vbo_save_context *save = &vbo_context(ctx)->save; GLint i; if (!_mesa_validate_DrawArrays(ctx, mode, start, count)) return; + if (save->out_of_memory) + return; + _ae_map_vbos(ctx); vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK @@ -1037,11 +1108,15 @@ _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { GET_CURRENT_CONTEXT(ctx); + struct vbo_save_context *save = &vbo_context(ctx)->save; GLint i; if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices, 0)) return; + if (save->out_of_memory) + return; + _ae_map_vbos(ctx); if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) @@ -1081,9 +1156,48 @@ _save_OBE_DrawRangeElements(GLenum mode, GLuint start, GLuint end, const GLvoid * indices) { GET_CURRENT_CONTEXT(ctx); - if (_mesa_validate_DrawRangeElements(ctx, mode, - start, end, count, type, indices, 0)) { - _save_OBE_DrawElements(mode, count, type, indices); + struct vbo_save_context *save = &vbo_context(ctx)->save; + + if (!_mesa_validate_DrawRangeElements(ctx, mode, + start, end, count, type, indices, 0)) + return; + + if (save->out_of_memory) + return; + + _save_OBE_DrawElements(mode, count, type, indices); +} + + +static void GLAPIENTRY +_save_OBE_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, + const GLvoid **indices, GLsizei primcount) +{ + GLsizei i; + + for (i = 0; i < primcount; i++) { + if (count[i] > 0) { + CALL_DrawElements(GET_DISPATCH(), (mode, count[i], type, indices[i])); + } + } +} + + +static void GLAPIENTRY +_save_OBE_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, + GLenum type, + const GLvoid **indices, + GLsizei primcount, + const GLint *basevertex) +{ + GLsizei i; + + for (i = 0; i < primcount; i++) { + if (count[i] > 0) { + CALL_DrawElementsBaseVertex(GET_DISPATCH(), (mode, count[i], type, + indices[i], + basevertex[i])); + } } } @@ -1223,8 +1337,8 @@ _save_vtxfmt_init(struct gl_context *ctx) _MESA_INIT_EVAL_VTXFMT(vfmt, _save_); - /* These are all errors as we at least know we are in some sort of - * begin/end pair: + /* These calls all generate GL_INVALID_OPERATION since this vtxfmt is + * only used when we're inside a glBegin/End pair. */ vfmt->Begin = _save_Begin; vfmt->Rectf = _save_Rectf; @@ -1233,9 +1347,8 @@ _save_vtxfmt_init(struct gl_context *ctx) vfmt->DrawRangeElements = _save_DrawRangeElements; vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex; vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex; - /* Loops back into vfmt->DrawElements */ - vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements; - vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex; + vfmt->MultiDrawElementsEXT = _save_MultiDrawElements; + vfmt->MultiDrawElementsBaseVertex = _save_MultiDrawElementsBaseVertex; } @@ -1424,6 +1537,7 @@ vbo_save_api_init(struct vbo_save_context *save) _save_vtxfmt_init(ctx); _save_current_init(ctx); + _mesa_noop_vtxfmt_init(&save->vtxfmt_noop); /* These will actually get set again when binding/drawing */ for (i = 0; i < VBO_ATTRIB_MAX; i++) @@ -1436,11 +1550,8 @@ vbo_save_api_init(struct vbo_save_context *save) ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; - /* loops back into _save_OBE_DrawElements */ - ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = - _mesa_noop_MultiDrawElements; - ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = - _mesa_noop_MultiDrawElementsBaseVertex; + ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = _save_OBE_MultiDrawElements; + ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = _save_OBE_MultiDrawElementsBaseVertex; _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); } diff --git a/pixman/test/Makefile.win32 b/pixman/test/Makefile.win32 index 307ba0c23..c88d0872a 100644 --- a/pixman/test/Makefile.win32 +++ b/pixman/test/Makefile.win32 @@ -19,7 +19,26 @@ BENCHS = $(patsubst %, $(CFG_VAR)/%.exe, $(BENCHMARKS)) all: inform $(TESTS) $(BENCHS) check: inform $(TESTS) - @for test in $(TESTS) ; do ./$$test && echo "PASS: $$test" || echo "FAIL: $$test" ; done + @failures=0 ; \ + total=0 ; \ + for test in $(TESTS) ; \ + do \ + total=`expr $$total + 1` ; \ + if ./$$test ; \ + then echo "PASS: $$test" ; \ + else echo "FAIL: $$test" ; \ + failures=`expr $$failures + 1` ; \ + fi ; \ + done ; \ + if test $$failures -eq 0 ; \ + then banner="All $$total tests passed" ; \ + else banner="$$failures of $$total tests failed" ; \ + fi ; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes" ; \ + echo "$$banner" ; \ + echo "$$dashes" ; \ + test $$failures -eq 0 $(CFG_VAR)/libutils.lib: $(libutils_OBJECTS) @$(AR) $(PIXMAN_ARFLAGS) -OUT:$@ $^ diff --git a/xkbcomp/alias.c b/xkbcomp/alias.c index ba55d3d32..f28c2d286 100644 --- a/xkbcomp/alias.c +++ b/xkbcomp/alias.c @@ -215,10 +215,10 @@ ApplyAliases(XkbDescPtr xkb, Bool toGeom, AliasInfo ** info_in) { if (strncmp(a->alias, info->alias, XkbKeyNameLength) == 0) { - AliasInfo old; - InitAliasInfo(&old, MergeAugment, 0, a->alias, a->real); - HandleCollision(&old, info); - memcpy(old.real, a->real, XkbKeyNameLength); + AliasInfo oldai; + InitAliasInfo(&oldai, MergeAugment, 0, a->alias, a->real); + HandleCollision(&oldai, info); + memcpy(oldai.real, a->real, XkbKeyNameLength); info->alias[0] = '\0'; nNew--; break; @@ -278,7 +278,7 @@ ApplyAliases(XkbDescPtr xkb, Bool toGeom, AliasInfo ** info_in) if ((a - old) != (nOld + nNew)) { WSGO2("Expected %d aliases total but created %d\n", nOld + nNew, - a - old); + (int)(a - old)); } #endif if (toGeom) diff --git a/xkbcomp/configure.ac b/xkbcomp/configure.ac index 9c400b650..383ccf0cb 100644 --- a/xkbcomp/configure.ac +++ b/xkbcomp/configure.ac @@ -45,7 +45,7 @@ fi AC_CHECK_FUNCS([strdup strcasecmp]) -REQUIRED_MODULES="x11 xkbfile" +REQUIRED_MODULES="x11 xkbfile xproto >= 7.0.17" # Checks for pkg-config packages PKG_CHECK_MODULES(XKBCOMP, [$REQUIRED_MODULES]) diff --git a/xkbcomp/geometry.c b/xkbcomp/geometry.c index 6d2ca7f90..7f65c3af4 100644 --- a/xkbcomp/geometry.c +++ b/xkbcomp/geometry.c @@ -366,7 +366,7 @@ InitRowInfo(RowInfo * row, SectionInfo * section, GeometryInfo * info) } else { - bzero(row, sizeof(RowInfo *)); + bzero(row, sizeof(*row)); row->defs.defined = _GR_Default; row->defs.fileID = info->fileID; row->defs.merge = info->merge; @@ -3611,11 +3611,11 @@ CopySectionDef(XkbGeometryPtr geom, SectionInfo * si, GeometryInfo * info) key->shape_ndx = 0; else { - ShapeInfo *si; - si = FindShape(info, ki->shape, "key", keyText(ki)); - if (!si) + ShapeInfo *sinfo; + sinfo = FindShape(info, ki->shape, "key", keyText(ki)); + if (!sinfo) return False; - key->shape_ndx = si->index; + key->shape_ndx = sinfo->index; } if (ki->color != None) color = diff --git a/xkbcomp/parseutils.c b/xkbcomp/parseutils.c index ca665e25a..253cd9dae 100644 --- a/xkbcomp/parseutils.c +++ b/xkbcomp/parseutils.c @@ -748,12 +748,12 @@ IncludeCreate(char *str, unsigned merge) void PrintStmtAddrs(ParseCommon * stmt) { - fprintf(stderr, "0x%x", stmt); + fprintf(stderr, "%p", stmt); if (stmt) { do { - fprintf(stderr, "->0x%x", stmt->next); + fprintf(stderr, "->%p", stmt->next); stmt = stmt->next; } while (stmt); diff --git a/xkbcomp/symbols.c b/xkbcomp/symbols.c index 4463a4b5f..625fe9676 100644 --- a/xkbcomp/symbols.c +++ b/xkbcomp/symbols.c @@ -1,2306 +1,2306 @@ -/************************************************************ - Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - - Permission to use, copy, modify, and distribute this - software and its documentation for any purpose and without - fee is hereby granted, provided that the above copyright - notice appear in all copies and that both that copyright - notice and this permission notice appear in supporting - documentation, and that the name of Silicon Graphics not be - used in advertising or publicity pertaining to distribution - of the software without specific prior written permission. - Silicon Graphics makes no representation about the suitability - of this software for any purpose. It is provided "as is" - without any express or implied warranty. - - SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ********************************************************/ - -#include "xkbcomp.h" -#include "tokens.h" -#include "expr.h" -#include "parseutils.h" - -#include -#include -#include - -#include "expr.h" -#include "vmod.h" -#include "action.h" -#include "keycodes.h" -#include "misc.h" -#include "alias.h" - -extern Atom tok_ONE_LEVEL; -extern Atom tok_TWO_LEVEL; -extern Atom tok_KEYPAD; - -/***====================================================================***/ - -#define RepeatYes 1 -#define RepeatNo 0 -#define RepeatUndefined ~((unsigned)0) - -#define _Key_Syms (1<<0) -#define _Key_Acts (1<<1) -#define _Key_Repeat (1<<2) -#define _Key_Behavior (1<<3) -#define _Key_Type_Dflt (1<<4) -#define _Key_Types (1<<5) -#define _Key_GroupInfo (1<<6) -#define _Key_VModMap (1<<7) - -typedef struct _KeyInfo -{ - CommonInfo defs; - unsigned long name; /* the 4 chars of the key name, as long */ - unsigned char groupInfo; - unsigned char typesDefined; - unsigned char symsDefined; - unsigned char actsDefined; - short numLevels[XkbNumKbdGroups]; - KeySym *syms[XkbNumKbdGroups]; - XkbAction *acts[XkbNumKbdGroups]; - Atom types[XkbNumKbdGroups]; - unsigned repeat; - XkbBehavior behavior; - unsigned short vmodmap; - unsigned long nameForOverlayKey; - unsigned long allowNone; - Atom dfltType; -} KeyInfo; - -/** - * Init the given key info to sane values. - */ -static void -InitKeyInfo(KeyInfo * info) -{ - register int i; - static char dflt[4] = "*"; - - info->defs.defined = 0; - info->defs.fileID = 0; - info->defs.merge = MergeOverride; - info->defs.next = NULL; - info->name = KeyNameToLong(dflt); - info->groupInfo = 0; - info->typesDefined = info->symsDefined = info->actsDefined = 0; - for (i = 0; i < XkbNumKbdGroups; i++) - { - info->numLevels[i] = 0; - info->types[i] = None; - info->syms[i] = NULL; - info->acts[i] = NULL; - } - info->dfltType = None; - info->behavior.type = XkbKB_Default; - info->behavior.data = 0; - info->vmodmap = 0; - info->nameForOverlayKey = 0; - info->repeat = RepeatUndefined; - info->allowNone = 0; - return; -} - -/** - * Free memory associated with this key info and reset to sane values. - */ -static void -FreeKeyInfo(KeyInfo * info) -{ - register int i; - - info->defs.defined = 0; - info->defs.fileID = 0; - info->defs.merge = MergeOverride; - info->defs.next = NULL; - info->groupInfo = 0; - info->typesDefined = info->symsDefined = info->actsDefined = 0; - for (i = 0; i < XkbNumKbdGroups; i++) - { - info->numLevels[i] = 0; - info->types[i] = None; - if (info->syms[i] != NULL) - uFree(info->syms[i]); - info->syms[i] = NULL; - if (info->acts[i] != NULL) - uFree(info->acts[i]); - info->acts[i] = NULL; - } - info->dfltType = None; - info->behavior.type = XkbKB_Default; - info->behavior.data = 0; - info->vmodmap = 0; - info->nameForOverlayKey = 0; - info->repeat = RepeatUndefined; - info->allowNone = 0; - return; -} - -/** - * Copy old into new, optionally reset old to 0. - * If old is reset, new simply re-uses old's memory. Otherwise, the memory is - * newly allocated and new points to the new memory areas. - */ -static Bool -CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld) -{ - register int i; - - *new = *old; - new->defs.next = NULL; - if (clearOld) - { - for (i = 0; i < XkbNumKbdGroups; i++) - { - old->numLevels[i] = 0; - old->syms[i] = NULL; - old->acts[i] = NULL; - } - } - else - { - int width; - for (i = 0; i < XkbNumKbdGroups; i++) - { - width = new->numLevels[i]; - if (old->syms[i] != NULL) - { - new->syms[i] = uTypedCalloc(width, KeySym); - if (!new->syms[i]) - { - new->syms[i] = NULL; - new->numLevels[i] = 0; - return False; - } - memcpy((char *) new->syms[i], (char *) old->syms[i], - width * sizeof(KeySym)); - } - if (old->acts[i] != NULL) - { - new->acts[i] = uTypedCalloc(width, XkbAction); - if (!new->acts[i]) - { - new->acts[i] = NULL; - return False; - } - memcpy((char *) new->acts[i], (char *) old->acts[i], - width * sizeof(XkbAction)); - } - } - } - return True; -} - -/***====================================================================***/ - -typedef struct _ModMapEntry -{ - CommonInfo defs; - Bool haveSymbol; - int modifier; - union - { - unsigned long keyName; - KeySym keySym; - } u; -} ModMapEntry; - -#define SYMBOLS_INIT_SIZE 110 -#define SYMBOLS_CHUNK 20 -typedef struct _SymbolsInfo -{ - char *name; /* e.g. pc+us+inet(evdev) */ - int errorCount; - unsigned fileID; - unsigned merge; - unsigned explicit_group; - unsigned groupInfo; - unsigned szKeys; - unsigned nKeys; - KeyInfo *keys; - KeyInfo dflt; - VModInfo vmods; - ActionInfo *action; - Atom groupNames[XkbNumKbdGroups]; - - ModMapEntry *modMap; - AliasInfo *aliases; -} SymbolsInfo; - -static void -InitSymbolsInfo(SymbolsInfo * info, XkbDescPtr xkb) -{ - register int i; - - tok_ONE_LEVEL = XkbInternAtom(NULL, "ONE_LEVEL", False); - tok_TWO_LEVEL = XkbInternAtom(NULL, "TWO_LEVEL", False); - tok_KEYPAD = XkbInternAtom(NULL, "KEYPAD", False); - info->name = NULL; - info->explicit_group = 0; - info->errorCount = 0; - info->fileID = 0; - info->merge = MergeOverride; - info->groupInfo = 0; - info->szKeys = SYMBOLS_INIT_SIZE; - info->nKeys = 0; - info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo); - info->modMap = NULL; - for (i = 0; i < XkbNumKbdGroups; i++) - info->groupNames[i] = None; - InitKeyInfo(&info->dflt); - InitVModInfo(&info->vmods, xkb); - info->action = NULL; - info->aliases = NULL; - return; -} - -static void -FreeSymbolsInfo(SymbolsInfo * info) -{ - register int i; - - if (info->name) - uFree(info->name); - info->name = NULL; - if (info->keys) - { - for (i = 0; i < info->nKeys; i++) - { - FreeKeyInfo(&info->keys[i]); - } - uFree(info->keys); - info->keys = NULL; - } - if (info->modMap) - { - ClearCommonInfo(&info->modMap->defs); - info->modMap = NULL; - } - if (info->aliases) - { - ClearAliases(&info->aliases); - info->aliases = NULL; - } - bzero((char *) info, sizeof(SymbolsInfo)); - return; -} - -static Bool -ResizeKeyGroup(KeyInfo * key, - unsigned group, unsigned atLeastSize, Bool forceActions) -{ - Bool tooSmall; - unsigned newWidth; - - tooSmall = (key->numLevels[group] < atLeastSize); - if (tooSmall) - newWidth = atLeastSize; - else - newWidth = key->numLevels[group]; - - if ((key->syms[group] == NULL) || tooSmall) - { - key->syms[group] = uTypedRecalloc(key->syms[group], - key->numLevels[group], newWidth, - KeySym); - if (!key->syms[group]) - return False; - } - if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) || - (tooSmall && (key->acts[group] != NULL))) - { - key->acts[group] = uTypedRecalloc(key->acts[group], - key->numLevels[group], newWidth, - XkbAction); - if (!key->acts[group]) - return False; - } - key->numLevels[group] = newWidth; - return True; -} - -static Bool -MergeKeyGroups(SymbolsInfo * info, - KeyInfo * into, KeyInfo * from, unsigned group) -{ - KeySym *resultSyms; - XkbAction *resultActs; - int resultWidth; - register int i; - Bool report, clobber; - - clobber = (from->defs.merge != MergeAugment); - report = (warningLevel > 9) || - ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0)); - if (into->numLevels[group] >= from->numLevels[group]) - { - resultSyms = into->syms[group]; - resultActs = into->acts[group]; - resultWidth = into->numLevels[group]; - } - else - { - resultSyms = from->syms[group]; - resultActs = from->acts[group]; - resultWidth = from->numLevels[group]; - } - if (resultSyms == NULL) - { - resultSyms = uTypedCalloc(resultWidth, KeySym); - if (!resultSyms) - { - WSGO("Could not allocate symbols for group merge\n"); - ACTION2("Group %d of key %s not merged\n", group, - longText(into->name, XkbMessage)); - return False; - } - } - if ((resultActs == NULL) && (into->acts[group] || from->acts[group])) - { - resultActs = uTypedCalloc(resultWidth, XkbAction); - if (!resultActs) - { - WSGO("Could not allocate actions for group merge\n"); - ACTION2("Group %d of key %s not merged\n", group, - longText(into->name, XkbMessage)); - return False; - } - } - for (i = 0; i < resultWidth; i++) - { - KeySym fromSym, toSym; - if (from->syms[group] && (i < from->numLevels[group])) - fromSym = from->syms[group][i]; - else - fromSym = NoSymbol; - if (into->syms[group] && (i < into->numLevels[group])) - toSym = into->syms[group][i]; - else - toSym = NoSymbol; - if ((fromSym == NoSymbol) || (fromSym == toSym)) - resultSyms[i] = toSym; - else if (toSym == NoSymbol) - resultSyms[i] = fromSym; - else - { - KeySym use, ignore; - if (clobber) - { - use = fromSym; - ignore = toSym; - } - else - { - use = toSym; - ignore = fromSym; - } - if (report) - { - WARN3 - ("Multiple symbols for level %d/group %d on key %s\n", - i + 1, group + 1, longText(into->name, XkbMessage)); - ACTION2("Using %s, ignoring %s\n", - XkbKeysymText(use, XkbMessage), - XkbKeysymText(ignore, XkbMessage)); - } - resultSyms[i] = use; - } - if (resultActs != NULL) - { - XkbAction *fromAct, *toAct; - fromAct = (from->acts[group] ? &from->acts[group][i] : NULL); - toAct = (into->acts[group] ? &into->acts[group][i] : NULL); - if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction)) - && (toAct != NULL)) - { - resultActs[i] = *toAct; - } - else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction)) - && (fromAct != NULL)) - { - resultActs[i] = *fromAct; - } - else - { - XkbAction *use, *ignore; - if (clobber) - { - use = fromAct; - ignore = toAct; - } - else - { - use = toAct; - ignore = fromAct; - } - if (report) - { - WARN3 - ("Multiple actions for level %d/group %d on key %s\n", - i + 1, group + 1, longText(into->name, XkbMessage)); - ACTION2("Using %s, ignoring %s\n", - XkbActionTypeText(use->type, XkbMessage), - XkbActionTypeText(ignore->type, XkbMessage)); - } - resultActs[i] = *use; - } - } - } - if ((into->syms[group] != NULL) && (resultSyms != into->syms[group])) - uFree(into->syms[group]); - if ((from->syms[group] != NULL) && (resultSyms != from->syms[group])) - uFree(from->syms[group]); - if ((into->acts[group] != NULL) && (resultActs != into->acts[group])) - uFree(into->acts[group]); - if ((from->acts[group] != NULL) && (resultActs != from->acts[group])) - uFree(from->acts[group]); - into->numLevels[group] = resultWidth; - into->syms[group] = resultSyms; - from->syms[group] = NULL; - into->acts[group] = resultActs; - from->acts[group] = NULL; - into->symsDefined |= (1 << group); - from->symsDefined &= ~(1 << group); - into->actsDefined |= (1 << group); - from->actsDefined &= ~(1 << group); - return True; -} - -static Bool -MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) -{ - register int i; - unsigned collide = 0; - Bool report; - - if (from->defs.merge == MergeReplace) - { - for (i = 0; i < XkbNumKbdGroups; i++) - { - if (into->numLevels[i] != 0) - { - if (into->syms[i]) - uFree(into->syms[i]); - if (into->acts[i]) - uFree(into->acts[i]); - } - } - *into = *from; - bzero(from, sizeof(KeyInfo)); - return True; - } - report = ((warningLevel > 9) || - ((into->defs.fileID == from->defs.fileID) - && (warningLevel > 0))); - for (i = 0; i < XkbNumKbdGroups; i++) - { - if (from->numLevels[i] > 0) - { - if (into->numLevels[i] == 0) - { - into->numLevels[i] = from->numLevels[i]; - into->syms[i] = from->syms[i]; - into->acts[i] = from->acts[i]; - into->symsDefined |= (1 << i); - from->syms[i] = NULL; - from->acts[i] = NULL; - from->numLevels[i] = 0; - from->symsDefined &= ~(1 << i); - if (into->syms[i]) - into->defs.defined |= _Key_Syms; - if (into->acts[i]) - into->defs.defined |= _Key_Acts; - } - else - { - if (report) - { - if (into->syms[i]) - collide |= _Key_Syms; - if (into->acts[i]) - collide |= _Key_Acts; - } - MergeKeyGroups(info, into, from, (unsigned) i); - } - } - if (from->types[i] != None) - { - if ((into->types[i] != None) && (report) && - (into->types[i] != from->types[i])) - { - Atom use, ignore; - collide |= _Key_Types; - if (from->defs.merge != MergeAugment) - { - use = from->types[i]; - ignore = into->types[i]; - } - else - { - use = into->types[i]; - ignore = from->types[i]; - } - WARN2 - ("Multiple definitions for group %d type of key %s\n", - i, longText(into->name, XkbMessage)); - ACTION2("Using %s, ignoring %s\n", - XkbAtomText(NULL, use, XkbMessage), - XkbAtomText(NULL, ignore, XkbMessage)); - } - if ((from->defs.merge != MergeAugment) - || (into->types[i] == None)) - { - into->types[i] = from->types[i]; - } - } - } - if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide)) - { - into->behavior = from->behavior; - into->nameForOverlayKey = from->nameForOverlayKey; - into->defs.defined |= _Key_Behavior; - } - if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide)) - { - into->vmodmap = from->vmodmap; - into->defs.defined |= _Key_VModMap; - } - if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide)) - { - into->repeat = from->repeat; - into->defs.defined |= _Key_Repeat; - } - if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide)) - { - into->dfltType = from->dfltType; - into->defs.defined |= _Key_Type_Dflt; - } - if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide)) - { - into->groupInfo = from->groupInfo; - into->defs.defined |= _Key_GroupInfo; - } - if (collide) - { - WARN1("Symbol map for key %s redefined\n", - longText(into->name, XkbMessage)); - ACTION1("Using %s definition for conflicting fields\n", - (from->defs.merge == MergeAugment ? "first" : "last")); - } - return True; -} - -static Bool -AddKeySymbols(SymbolsInfo * info, KeyInfo * key, XkbDescPtr xkb) -{ - register int i; - unsigned long real_name; - - for (i = 0; i < info->nKeys; i++) - { - if (info->keys[i].name == key->name) - return MergeKeys(info, &info->keys[i], key); - } - if (FindKeyNameForAlias(xkb, key->name, &real_name)) - { - for (i = 0; i < info->nKeys; i++) - { - if (info->keys[i].name == real_name) - return MergeKeys(info, &info->keys[i], key); - } - } - if (info->nKeys >= info->szKeys) - { - info->szKeys += SYMBOLS_CHUNK; - info->keys = - uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo); - if (!info->keys) - { - WSGO("Could not allocate key symbols descriptions\n"); - ACTION("Some key symbols definitions may be lost\n"); - return False; - } - } - return CopyKeyInfo(key, &info->keys[info->nKeys++], True); -} - -static Bool -AddModMapEntry(SymbolsInfo * info, ModMapEntry * new) -{ - ModMapEntry *mm; - Bool clobber; - - clobber = (new->defs.merge != MergeAugment); - for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next) - { - if (new->haveSymbol && mm->haveSymbol - && (new->u.keySym == mm->u.keySym)) - { - unsigned use, ignore; - if (mm->modifier != new->modifier) - { - if (clobber) - { - use = new->modifier; - ignore = mm->modifier; - } - else - { - use = mm->modifier; - ignore = new->modifier; - } - ERROR1 - ("%s added to symbol map for multiple modifiers\n", - XkbKeysymText(new->u.keySym, XkbMessage)); - ACTION2("Using %s, ignoring %s.\n", - XkbModIndexText(use, XkbMessage), - XkbModIndexText(ignore, XkbMessage)); - mm->modifier = use; - } - return True; - } - if ((!new->haveSymbol) && (!mm->haveSymbol) && - (new->u.keyName == mm->u.keyName)) - { - unsigned use, ignore; - if (mm->modifier != new->modifier) - { - if (clobber) - { - use = new->modifier; - ignore = mm->modifier; - } - else - { - use = mm->modifier; - ignore = new->modifier; - } - ERROR1("Key %s added to map for multiple modifiers\n", - longText(new->u.keyName, XkbMessage)); - ACTION2("Using %s, ignoring %s.\n", - XkbModIndexText(use, XkbMessage), - XkbModIndexText(ignore, XkbMessage)); - mm->modifier = use; - } - return True; - } - } - mm = uTypedAlloc(ModMapEntry); - if (mm == NULL) - { - WSGO("Could not allocate modifier map entry\n"); - ACTION1("Modifier map for %s will be incomplete\n", - XkbModIndexText(new->modifier, XkbMessage)); - return False; - } - *mm = *new; - mm->defs.next = &info->modMap->defs; - info->modMap = mm; - return True; -} - -/***====================================================================***/ - -static void -MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from, - unsigned merge, XkbDescPtr xkb) -{ - register int i; - KeyInfo *key; - - if (from->errorCount > 0) - { - into->errorCount += from->errorCount; - return; - } - if (into->name == NULL) - { - into->name = from->name; - from->name = NULL; - } - for (i = 0; i < XkbNumKbdGroups; i++) - { - if (from->groupNames[i] != None) - { - if ((merge != MergeAugment) || (into->groupNames[i] == None)) - into->groupNames[i] = from->groupNames[i]; - } - } - for (i = 0, key = from->keys; i < from->nKeys; i++, key++) - { - if (merge != MergeDefault) - key->defs.merge = merge; - if (!AddKeySymbols(into, key, xkb)) - into->errorCount++; - } - if (from->modMap != NULL) - { - ModMapEntry *mm, *next; - for (mm = from->modMap; mm != NULL; mm = next) - { - if (merge != MergeDefault) - mm->defs.merge = merge; - if (!AddModMapEntry(into, mm)) - into->errorCount++; - next = (ModMapEntry *) mm->defs.next; - uFree(mm); - } - from->modMap = NULL; - } - if (!MergeAliases(&into->aliases, &from->aliases, merge)) - into->errorCount++; - return; -} - -typedef void (*FileHandler) (XkbFile * /* rtrn */ , - XkbDescPtr /* xkb */ , - unsigned /* merge */ , - SymbolsInfo * /* included */ - ); - -static Bool -HandleIncludeSymbols(IncludeStmt * stmt, - XkbDescPtr xkb, SymbolsInfo * info, FileHandler hndlr) -{ - unsigned newMerge; - XkbFile *rtrn; - SymbolsInfo included; - Bool haveSelf; - - haveSelf = False; - if ((stmt->file == NULL) && (stmt->map == NULL)) - { - haveSelf = True; - included = *info; - bzero(info, sizeof(SymbolsInfo)); - } - else if (ProcessIncludeFile(stmt, XkmSymbolsIndex, &rtrn, &newMerge)) - { - InitSymbolsInfo(&included, xkb); - included.fileID = included.dflt.defs.fileID = rtrn->id; - included.merge = included.dflt.defs.merge = MergeOverride; - if (stmt->modifier) - { - included.explicit_group = atoi(stmt->modifier) - 1; - } - else - { - included.explicit_group = info->explicit_group; - } - (*hndlr) (rtrn, xkb, MergeOverride, &included); - if (stmt->stmt != NULL) - { - if (included.name != NULL) - uFree(included.name); - included.name = stmt->stmt; - stmt->stmt = NULL; - } - } - else - { - info->errorCount += 10; - return False; - } - if ((stmt->next != NULL) && (included.errorCount < 1)) - { - IncludeStmt *next; - unsigned op; - SymbolsInfo next_incl; - - for (next = stmt->next; next != NULL; next = next->next) - { - if ((next->file == NULL) && (next->map == NULL)) - { - haveSelf = True; - MergeIncludedSymbols(&included, info, next->merge, xkb); - FreeSymbolsInfo(info); - } - else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op)) - { - InitSymbolsInfo(&next_incl, xkb); - next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id; - next_incl.merge = next_incl.dflt.defs.merge = MergeOverride; - if (next->modifier) - { - next_incl.explicit_group = atoi(next->modifier) - 1; - } - else - { - next_incl.explicit_group = info->explicit_group; - } - (*hndlr) (rtrn, xkb, MergeOverride, &next_incl); - MergeIncludedSymbols(&included, &next_incl, op, xkb); - FreeSymbolsInfo(&next_incl); - } - else - { - info->errorCount += 10; - return False; - } - } - } - if (haveSelf) - *info = included; - else - { - MergeIncludedSymbols(info, &included, newMerge, xkb); - FreeSymbolsInfo(&included); - } - return (info->errorCount == 0); -} - -static LookupEntry groupNames[] = { - {"group1", 1}, - {"group2", 2}, - {"group3", 3}, - {"group4", 4}, - {"group5", 5}, - {"group6", 6}, - {"group7", 7}, - {"group8", 8}, - {NULL, 0} -}; - - -#define SYMBOLS 1 -#define ACTIONS 2 - -static Bool -GetGroupIndex(KeyInfo * key, - ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn) -{ - const char *name; - ExprResult tmp; - - if (what == SYMBOLS) - name = "symbols"; - else - name = "actions"; - - if (arrayNdx == NULL) - { - register int i; - unsigned defined; - if (what == SYMBOLS) - defined = key->symsDefined; - else - defined = key->actsDefined; - - for (i = 0; i < XkbNumKbdGroups; i++) - { - if ((defined & (1 << i)) == 0) - { - *ndx_rtrn = i; - return True; - } - } - ERROR3("Too many groups of %s for key %s (max %d)\n", name, - longText(key->name, XkbMessage), XkbNumKbdGroups + 1); - ACTION1("Ignoring %s defined for extra groups\n", name); - return False; - } - if (!ExprResolveInteger - (arrayNdx, &tmp, SimpleLookup, (XPointer) groupNames)) - { - ERROR2("Illegal group index for %s of key %s\n", name, - longText(key->name, XkbMessage)); - ACTION("Definition with non-integer array index ignored\n"); - return False; - } - if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) - { - ERROR3("Group index for %s of key %s is out of range (1..%d)\n", - name, longText(key->name, XkbMessage), XkbNumKbdGroups + 1); - ACTION2("Ignoring %s for group %d\n", name, tmp.uval); - return False; - } - *ndx_rtrn = tmp.uval - 1; - return True; -} - -static Bool -AddSymbolsToKey(KeyInfo * key, - XkbDescPtr xkb, - char *field, - ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info) -{ - unsigned ndx, nSyms; - int i; - - if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx)) - return False; - if (value == NULL) - { - key->symsDefined |= (1 << ndx); - return True; - } - if (value->op != ExprKeysymList) - { - ERROR1("Expected a list of symbols, found %s\n", - exprOpText(value->op)); - ACTION2("Ignoring symbols for group %d of %s\n", ndx, - longText(key->name, XkbMessage)); - return False; - } - if (key->syms[ndx] != NULL) - { - WSGO2("Symbols for key %s, group %d already defined\n", - longText(key->name, XkbMessage), ndx); - return False; - } - nSyms = value->value.list.nSyms; - if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) && - (!ResizeKeyGroup(key, ndx, nSyms, False))) - { - WSGO2("Could not resize group %d of key %s\n", ndx, - longText(key->name, XkbMessage)); - ACTION("Symbols lost\n"); - return False; - } - key->symsDefined |= (1 << ndx); - for (i = 0; i < nSyms; i++) { - if (!LookupKeysym(value->value.list.syms[i], &key->syms[ndx][i])) { - WSGO1("Could not resolve keysym %s\n", value->value.list.syms[i]); - key->syms[ndx][i] = NoSymbol; - } - } - for (i = key->numLevels[ndx] - 1; - (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--) - { - key->numLevels[ndx]--; - } - return True; -} - -static Bool -AddActionsToKey(KeyInfo * key, - XkbDescPtr xkb, - char *field, - ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info) -{ - register int i; - unsigned ndx, nActs; - ExprDef *act; - XkbAnyAction *toAct; - - if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx)) - return False; - - if (value == NULL) - { - key->actsDefined |= (1 << ndx); - return True; - } - if (value->op != ExprActionList) - { - WSGO1("Bad expression type (%d) for action list value\n", value->op); - ACTION2("Ignoring actions for group %d of %s\n", ndx, - longText(key->name, XkbMessage)); - return False; - } - if (key->acts[ndx] != NULL) - { - WSGO2("Actions for key %s, group %d already defined\n", - longText(key->name, XkbMessage), ndx); - return False; - } - for (nActs = 0, act = value->value.child; act != NULL; nActs++) - { - act = (ExprDef *) act->common.next; - } - if (nActs < 1) - { - WSGO("Action list but not actions in AddActionsToKey\n"); - return False; - } - if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) && - (!ResizeKeyGroup(key, ndx, nActs, True))) - { - WSGO2("Could not resize group %d of key %s\n", ndx, - longText(key->name, XkbMessage)); - ACTION("Actions lost\n"); - return False; - } - key->actsDefined |= (1 << ndx); - - toAct = (XkbAnyAction *) key->acts[ndx]; - act = value->value.child; - for (i = 0; i < nActs; i++, toAct++) - { - if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action)) - { - ERROR1("Illegal action definition for %s\n", - longText(key->name, XkbMessage)); - ACTION2("Action for group %d/level %d ignored\n", ndx + 1, i + 1); - } - act = (ExprDef *) act->common.next; - } - return True; -} - -static int -SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value) -{ - ExprResult tmp; - unsigned radio_groups = 0; - - if (arrayNdx == NULL) - { - radio_groups = XkbAllRadioGroupsMask; - } - else - { - if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL)) - { - ERROR("Illegal index in group name definition\n"); - ACTION("Definition with non-integer array index ignored\n"); - return False; - } - if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups)) - { - ERROR1("Illegal radio group specified (must be 1..%d)\n", - XkbMaxRadioGroups + 1); - ACTION1("Value of \"allow none\" for group %d ignored\n", - tmp.uval); - return False; - } - radio_groups |= (1 << (tmp.uval - 1)); - } - if (!ExprResolveBoolean(value, &tmp, NULL, NULL)) - { - ERROR1("Illegal \"allow none\" value for %s\n", - longText(key->name, XkbMessage)); - ACTION("Non-boolean value ignored\n"); - return False; - } - if (tmp.uval) - key->allowNone |= radio_groups; - else - key->allowNone &= ~radio_groups; - return True; -} - - -static LookupEntry lockingEntries[] = { - {"true", XkbKB_Lock}, - {"yes", XkbKB_Lock}, - {"on", XkbKB_Lock}, - {"false", XkbKB_Default}, - {"no", XkbKB_Default}, - {"off", XkbKB_Default}, - {"permanent", XkbKB_Lock | XkbKB_Permanent}, - {NULL, 0} -}; - -static LookupEntry repeatEntries[] = { - {"true", RepeatYes}, - {"yes", RepeatYes}, - {"on", RepeatYes}, - {"false", RepeatNo}, - {"no", RepeatNo}, - {"off", RepeatNo}, - {"default", RepeatUndefined}, - {NULL, 0} -}; - -static LookupEntry rgEntries[] = { - {"none", 0}, - {NULL, 0} -}; - -static Bool -SetSymbolsField(KeyInfo * key, - XkbDescPtr xkb, - char *field, - ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info) -{ - Bool ok = True; - ExprResult tmp; - - if (uStrCaseCmp(field, "type") == 0) - { - ExprResult ndx; - if ((!ExprResolveString(value, &tmp, NULL, NULL)) - && (warningLevel > 0)) - { - WARN("The type field of a key symbol map must be a string\n"); - ACTION("Ignoring illegal type definition\n"); - } - if (arrayNdx == NULL) - { - key->dfltType = XkbInternAtom(NULL, tmp.str, False); - key->defs.defined |= _Key_Type_Dflt; - } - else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup, - (XPointer) groupNames)) - { - ERROR1("Illegal group index for type of key %s\n", - longText(key->name, XkbMessage)); - ACTION("Definition with non-integer array index ignored\n"); - return False; - } - else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups)) - { - ERROR2 - ("Group index for type of key %s is out of range (1..%d)\n", - longText(key->name, XkbMessage), XkbNumKbdGroups + 1); - ACTION1("Ignoring type for group %d\n", ndx.uval); - return False; - } - else - { - key->types[ndx.uval - 1] = XkbInternAtom(NULL, tmp.str, False); - key->typesDefined |= (1 << (ndx.uval - 1)); - } - } - else if (uStrCaseCmp(field, "symbols") == 0) - return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info); - else if (uStrCaseCmp(field, "actions") == 0) - return AddActionsToKey(key, xkb, field, arrayNdx, value, info); - else if ((uStrCaseCmp(field, "vmods") == 0) || - (uStrCaseCmp(field, "virtualmods") == 0) || - (uStrCaseCmp(field, "virtualmodifiers") == 0)) - { - ok = ExprResolveModMask(value, &tmp, LookupVModMask, (XPointer) xkb); - if (ok) - { - key->vmodmap = (tmp.uval >> 8); - key->defs.defined |= _Key_VModMap; - } - else - { - ERROR1("Expected a virtual modifier mask, found %s\n", - exprOpText(value->op)); - ACTION1("Ignoring virtual modifiers definition for key %s\n", - longText(key->name, XkbMessage)); - } - } - else if ((uStrCaseCmp(field, "locking") == 0) - || (uStrCaseCmp(field, "lock") == 0) - || (uStrCaseCmp(field, "locks") == 0)) - { - ok = ExprResolveEnum(value, &tmp, lockingEntries); - if (ok) - key->behavior.type = tmp.uval; - key->defs.defined |= _Key_Behavior; - } - else if ((uStrCaseCmp(field, "radiogroup") == 0) || - (uStrCaseCmp(field, "permanentradiogroup") == 0)) - { - Bool permanent = False; - if (uStrCaseCmp(field, "permanentradiogroup") == 0) - permanent = True; - ok = ExprResolveInteger(value, &tmp, SimpleLookup, - (XPointer) rgEntries); - if (!ok) - { - ERROR1("Illegal radio group specification for %s\n", - longText(key->name, XkbMessage)); - ACTION("Non-integer radio group ignored\n"); - return False; - } - if (tmp.uval == 0) - { - key->behavior.type = XkbKB_Default; - key->behavior.data = 0; - return ok; - } - if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups)) - { - ERROR1 - ("Radio group specification for %s out of range (1..32)\n", - longText(key->name, XkbMessage)); - ACTION1("Illegal radio group %d ignored\n", tmp.uval); - return False; - } - key->behavior.type = - XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0); - key->behavior.data = tmp.uval - 1; - if (key->allowNone & (1 << (tmp.uval - 1))) - key->behavior.data |= XkbKB_RGAllowNone; - key->defs.defined |= _Key_Behavior; - } - else if (uStrCaseEqual(field, "allownone")) - { - ok = SetAllowNone(key, arrayNdx, value); - } - else if (uStrCasePrefix("overlay", field) || - uStrCasePrefix("permanentoverlay", field)) - { - Bool permanent = False; - char *which; - int overlayNdx; - if (uStrCasePrefix("permanent", field)) - { - permanent = True; - which = &field[sizeof("permanentoverlay") - 1]; - } - else - { - which = &field[sizeof("overlay") - 1]; - } - if (sscanf(which, "%d", &overlayNdx) == 1) - { - if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0)) - { - ERROR2("Illegal overlay %d specified for %s\n", - overlayNdx, longText(key->name, XkbMessage)); - ACTION("Ignored\n"); - return False; - } - } - else if (*which == '\0') - overlayNdx = 1; - else if (warningLevel > 0) - { - ERROR2("Illegal overlay \"%s\" specified for %s\n", - which, longText(key->name, XkbMessage)); - ACTION("Ignored\n"); - return False; - } - ok = ExprResolveKeyName(value, &tmp, NULL, NULL); - if (!ok) - { - ERROR1("Illegal overlay key specification for %s\n", - longText(key->name, XkbMessage)); - ACTION("Overlay key must be specified by name\n"); - return False; - } - if (overlayNdx == 1) - key->behavior.type = XkbKB_Overlay1; - else - key->behavior.type = XkbKB_Overlay2; - if (permanent) - key->behavior.type |= XkbKB_Permanent; - - key->behavior.data = 0; - key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name); - key->defs.defined |= _Key_Behavior; - } - else if ((uStrCaseCmp(field, "repeating") == 0) || - (uStrCaseCmp(field, "repeats") == 0) || - (uStrCaseCmp(field, "repeat") == 0)) - { - ok = ExprResolveEnum(value, &tmp, repeatEntries); - if (!ok) - { - ERROR1("Illegal repeat setting for %s\n", - longText(key->name, XkbMessage)); - ACTION("Non-boolean repeat setting ignored\n"); - return False; - } - key->repeat = tmp.uval; - key->defs.defined |= _Key_Repeat; - } - else if ((uStrCaseCmp(field, "groupswrap") == 0) || - (uStrCaseCmp(field, "wrapgroups") == 0)) - { - ok = ExprResolveBoolean(value, &tmp, NULL, NULL); - if (!ok) - { - ERROR1("Illegal groupsWrap setting for %s\n", - longText(key->name, XkbMessage)); - ACTION("Non-boolean value ignored\n"); - return False; - } - if (tmp.uval) - key->groupInfo = XkbWrapIntoRange; - else - key->groupInfo = XkbClampIntoRange; - key->defs.defined |= _Key_GroupInfo; - } - else if ((uStrCaseCmp(field, "groupsclamp") == 0) || - (uStrCaseCmp(field, "clampgroups") == 0)) - { - ok = ExprResolveBoolean(value, &tmp, NULL, NULL); - if (!ok) - { - ERROR1("Illegal groupsClamp setting for %s\n", - longText(key->name, XkbMessage)); - ACTION("Non-boolean value ignored\n"); - return False; - } - if (tmp.uval) - key->groupInfo = XkbClampIntoRange; - else - key->groupInfo = XkbWrapIntoRange; - key->defs.defined |= _Key_GroupInfo; - } - else if ((uStrCaseCmp(field, "groupsredirect") == 0) || - (uStrCaseCmp(field, "redirectgroups") == 0)) - { - if (!ExprResolveInteger - (value, &tmp, SimpleLookup, (XPointer) groupNames)) - { - ERROR1("Illegal group index for redirect of key %s\n", - longText(key->name, XkbMessage)); - ACTION("Definition with non-integer group ignored\n"); - return False; - } - if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) - { - ERROR2("Out-of-range (1..%d) group for redirect of key %s\n", - XkbNumKbdGroups, longText(key->name, XkbMessage)); - ERROR1("Ignoring illegal group %d\n", tmp.uval); - return False; - } - key->groupInfo = - XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1); - key->defs.defined |= _Key_GroupInfo; - } - else - { - ERROR1("Unknown field %s in a symbol interpretation\n", field); - ACTION("Definition ignored\n"); - ok = False; - } - return ok; -} - -static int -SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value) -{ - ExprResult tmp, name; - - if ((arrayNdx == NULL) && (warningLevel > 0)) - { - WARN("You must specify an index when specifying a group name\n"); - ACTION("Group name definition without array subscript ignored\n"); - return False; - } - if (!ExprResolveInteger - (arrayNdx, &tmp, SimpleLookup, (XPointer) groupNames)) - { - ERROR("Illegal index in group name definition\n"); - ACTION("Definition with non-integer array index ignored\n"); - return False; - } - if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) - { - ERROR1 - ("Attempt to specify name for illegal group (must be 1..%d)\n", - XkbNumKbdGroups + 1); - ACTION1("Name for group %d ignored\n", tmp.uval); - return False; - } - if (!ExprResolveString(value, &name, NULL, NULL)) - { - ERROR("Group name must be a string\n"); - ACTION1("Illegal name for group %d ignored\n", tmp.uval); - return False; - } - info->groupNames[tmp.uval - 1 + info->explicit_group] = - XkbInternAtom(NULL, name.str, False); - - return True; -} - -static int -HandleSymbolsVar(VarDef * stmt, XkbDescPtr xkb, SymbolsInfo * info) -{ - ExprResult elem, field, tmp; - ExprDef *arrayNdx; - - if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0) - return 0; /* internal error, already reported */ - if (elem.str && (uStrCaseCmp(elem.str, "key") == 0)) - { - return SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx, - stmt->value, info); - } - else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) || - (uStrCaseCmp(field.str, "groupname") == - 0))) - { - return SetGroupName(info, arrayNdx, stmt->value); - } - else if ((elem.str == NULL) - && ((uStrCaseCmp(field.str, "groupswrap") == 0) - || (uStrCaseCmp(field.str, "wrapgroups") == 0))) - { - if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL)) - { - ERROR("Illegal setting for global groupsWrap\n"); - ACTION("Non-boolean value ignored\n"); - return False; - } - if (tmp.uval) - info->groupInfo = XkbWrapIntoRange; - else - info->groupInfo = XkbClampIntoRange; - return True; - } - else if ((elem.str == NULL) - && ((uStrCaseCmp(field.str, "groupsclamp") == 0) - || (uStrCaseCmp(field.str, "clampgroups") == 0))) - { - if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL)) - { - ERROR("Illegal setting for global groupsClamp\n"); - ACTION("Non-boolean value ignored\n"); - return False; - } - if (tmp.uval) - info->groupInfo = XkbClampIntoRange; - else - info->groupInfo = XkbWrapIntoRange; - return True; - } - else if ((elem.str == NULL) - && ((uStrCaseCmp(field.str, "groupsredirect") == 0) - || (uStrCaseCmp(field.str, "redirectgroups") == 0))) - { - if (!ExprResolveInteger(stmt->value, &tmp, - SimpleLookup, (XPointer) groupNames)) - { - ERROR("Illegal group index for global groupsRedirect\n"); - ACTION("Definition with non-integer group ignored\n"); - return False; - } - if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) - { - ERROR1 - ("Out-of-range (1..%d) group for global groupsRedirect\n", - XkbNumKbdGroups); - ACTION1("Ignoring illegal group %d\n", tmp.uval); - return False; - } - info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval); - return True; - } - else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0)) - { - return SetAllowNone(&info->dflt, arrayNdx, stmt->value); - } - return SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value, - &info->action); -} - -static Bool -HandleSymbolsBody(VarDef * def, - XkbDescPtr xkb, KeyInfo * key, SymbolsInfo * info) -{ - Bool ok = True; - ExprResult tmp, field; - ExprDef *arrayNdx; - - for (; def != NULL; def = (VarDef *) def->common.next) - { - if ((def->name) && (def->name->type == ExprFieldRef)) - { - ok = HandleSymbolsVar(def, xkb, info); - continue; - } - else - { - if (def->name == NULL) - { - if ((def->value == NULL) - || (def->value->op == ExprKeysymList)) - field.str = "symbols"; - else - field.str = "actions"; - arrayNdx = NULL; - } - else - { - ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx); - } - if (ok) - ok = SetSymbolsField(key, xkb, field.str, arrayNdx, - def->value, info); - } - } - return ok; -} - -static Bool -SetExplicitGroup(SymbolsInfo * info, KeyInfo * key) -{ - unsigned group = info->explicit_group; - - if (group == 0) - return True; - - if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1) - { - int i; - WARN1("For the map %s an explicit group specified\n", info->name); - WARN1("but key %s has more than one group defined\n", - longText(key->name, XkbMessage)); - ACTION("All groups except first one will be ignored\n"); - for (i = 1; i < XkbNumKbdGroups; i++) - { - key->numLevels[i] = 0; - if (key->syms[i] != NULL) - uFree(key->syms[i]); - key->syms[i] = (KeySym *) NULL; - if (key->acts[i] != NULL) - uFree(key->acts[i]); - key->acts[i] = (XkbAction *) NULL; - key->types[i] = (Atom) 0; - } - } - key->typesDefined = key->symsDefined = key->actsDefined = 1 << group; - - key->numLevels[group] = key->numLevels[0]; - key->numLevels[0] = 0; - key->syms[group] = key->syms[0]; - key->syms[0] = (KeySym *) NULL; - key->acts[group] = key->acts[0]; - key->acts[0] = (XkbAction *) NULL; - key->types[group] = key->types[0]; - key->types[0] = (Atom) 0; - return True; -} - -static int -HandleSymbolsDef(SymbolsDef * stmt, - XkbDescPtr xkb, unsigned merge, SymbolsInfo * info) -{ - KeyInfo key; - - InitKeyInfo(&key); - CopyKeyInfo(&info->dflt, &key, False); - key.defs.merge = stmt->merge; - key.name = KeyNameToLong(stmt->keyName); - if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info)) - { - info->errorCount++; - return False; - } - - if (!SetExplicitGroup(info, &key)) - { - info->errorCount++; - return False; - } - - if (!AddKeySymbols(info, &key, xkb)) - { - info->errorCount++; - return False; - } - return True; -} - -static Bool -HandleModMapDef(ModMapDef * def, - XkbDescPtr xkb, unsigned merge, SymbolsInfo * info) -{ - ExprDef *key; - ModMapEntry tmp; - ExprResult rtrn; - Bool ok; - - if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn)) - { - ERROR("Illegal modifier map definition\n"); - ACTION1("Ignoring map for non-modifier \"%s\"\n", - XkbAtomText(NULL, def->modifier, XkbMessage)); - return False; - } - ok = True; - tmp.modifier = rtrn.uval; - for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) - { - if ((key->op == ExprValue) && (key->type == TypeKeyName)) - { - tmp.haveSymbol = False; - tmp.u.keyName = KeyNameToLong(key->value.keyName); - } - else if (ExprResolveKeySym(key, &rtrn, NULL, NULL)) - { - tmp.haveSymbol = True; - tmp.u.keySym = rtrn.uval; - } - else - { - ERROR("Modmap entries may contain only key names or keysyms\n"); - ACTION1("Illegal definition for %s modifier ignored\n", - XkbModIndexText(tmp.modifier, XkbMessage)); - continue; - } - - ok = AddModMapEntry(info, &tmp) && ok; - } - return ok; -} - -static void -HandleSymbolsFile(XkbFile * file, - XkbDescPtr xkb, unsigned merge, SymbolsInfo * info) -{ - ParseCommon *stmt; - - info->name = uStringDup(file->name); - stmt = file->defs; - while (stmt) - { - switch (stmt->stmtType) - { - case StmtInclude: - if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info, - HandleSymbolsFile)) - info->errorCount++; - break; - case StmtSymbolsDef: - if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info)) - info->errorCount++; - break; - case StmtVarDef: - if (!HandleSymbolsVar((VarDef *) stmt, xkb, info)) - info->errorCount++; - break; - case StmtVModDef: - if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods)) - info->errorCount++; - break; - case StmtInterpDef: - ERROR("Interpretation files may not include other types\n"); - ACTION("Ignoring definition of symbol interpretation\n"); - info->errorCount++; - break; - case StmtKeycodeDef: - ERROR("Interpretation files may not include other types\n"); - ACTION("Ignoring definition of key name\n"); - info->errorCount++; - break; - case StmtModMapDef: - if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info)) - info->errorCount++; - break; - default: - WSGO1("Unexpected statement type %d in HandleSymbolsFile\n", - stmt->stmtType); - break; - } - stmt = stmt->next; - if (info->errorCount > 10) - { -#ifdef NOISY - ERROR("Too many errors\n"); -#endif - ACTION1("Abandoning symbols file \"%s\"\n", file->topName); - break; - } - } - return; -} - -static Bool -FindKeyForSymbol(XkbDescPtr xkb, KeySym sym, unsigned int *kc_rtrn) -{ - register int i, j; - register Bool gotOne; - - j = 0; - do - { - gotOne = False; - for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) - { - if (j < (int) XkbKeyNumSyms(xkb, i)) - { - gotOne = True; - if ((XkbKeySym(xkb, i, j) == sym)) - { - *kc_rtrn = i; - return True; - } - } - } - j++; - } - while (gotOne); - return False; -} - -/** - * Find the given name in the xkb->map->types and return its index. - * - * @param name The atom to search for. - * @param type_rtrn Set to the index of the name if found. - * - * @return True if found, False otherwise. - */ -static Bool -FindNamedType(XkbDescPtr xkb, Atom name, unsigned *type_rtrn) -{ - register unsigned n; - - if (xkb && xkb->map && xkb->map->types) - { - for (n = 0; n < xkb->map->num_types; n++) - { - if (xkb->map->types[n].name == (Atom) name) - { - *type_rtrn = n; - return True; - } - } - } - return False; -} - -static Bool -KSIsLower(KeySym ks) -{ - KeySym lower, upper; - XConvertCase(ks, &lower, &upper); - - if (lower == upper) - return False; - return (ks == lower ? True : False); -} - -static Bool -KSIsUpper(KeySym ks) -{ - KeySym lower, upper; - XConvertCase(ks, &lower, &upper); - - if (lower == upper) - return False; - return (ks == upper ? True : False); -} - -/** - * Assign a type to the given sym and return the Atom for the type assigned. - * - * Simple recipe: - * - ONE_LEVEL for width 0/1 - * - ALPHABETIC for 2 shift levels, with lower/upercase - * - KEYPAD for keypad keys. - * - TWO_LEVEL for other 2 shift level keys. - * and the same for four level keys. - * - * @param width Number of sysms in syms. - * @param syms The keysyms for the given key (must be size width). - * @param typeNameRtrn Set to the Atom of the type name. - * - * @returns True if a type could be found, False otherwise. - */ -static Bool -FindAutomaticType(int width, KeySym * syms, Atom * typeNameRtrn, - Bool * autoType) -{ - *autoType = False; - if ((width == 1) || (width == 0)) - { - *typeNameRtrn = XkbInternAtom(NULL, "ONE_LEVEL", False); - *autoType = True; - } - else if (width == 2) - { - if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1])) - { - *typeNameRtrn = XkbInternAtom(NULL, "ALPHABETIC", False); - } - else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1]))) - { - *typeNameRtrn = XkbInternAtom(NULL, "KEYPAD", False); - *autoType = True; - } - else - { - *typeNameRtrn = XkbInternAtom(NULL, "TWO_LEVEL", False); - *autoType = True; - } - } - else if (width <= 4) - { - if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1])) - if (KSIsLower(syms[2]) && KSIsUpper(syms[3])) - *typeNameRtrn = - XkbInternAtom(NULL, "FOUR_LEVEL_ALPHABETIC", False); - else - *typeNameRtrn = XkbInternAtom(NULL, - "FOUR_LEVEL_SEMIALPHABETIC", - False); - - else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1]))) - *typeNameRtrn = XkbInternAtom(NULL, "FOUR_LEVEL_KEYPAD", False); - else - *typeNameRtrn = XkbInternAtom(NULL, "FOUR_LEVEL", False); - /* XXX: why not set autoType here? */ - } - return ((width >= 0) && (width <= 4)); -} - -/** - * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the - * groups, and reduce to one group if all groups are identical anyway. - */ -static void -PrepareKeyDef(KeyInfo * key) -{ - int i, j, width, defined, lastGroup; - Bool identical; - - defined = key->symsDefined | key->actsDefined | key->typesDefined; - /* get highest group number */ - for (i = XkbNumKbdGroups - 1; i >= 0; i--) - { - if (defined & (1 << i)) - break; - } - lastGroup = i; - - if (lastGroup == 0) - return; - - /* If there are empty groups between non-empty ones fill them with data */ - /* from the first group. */ - /* We can make a wrong assumption here. But leaving gaps is worse. */ - for (i = lastGroup; i > 0; i--) - { - if (defined & (1 << i)) - continue; - width = key->numLevels[0]; - if (key->typesDefined & 1) - { - for (j = 0; j < width; j++) - { - key->types[i] = key->types[0]; - } - key->typesDefined |= 1 << i; - } - if ((key->actsDefined & 1) && key->acts[0]) - { - key->acts[i] = uTypedCalloc(width, XkbAction); - if (key->acts[i] == NULL) - continue; - memcpy((void *) key->acts[i], (void *) key->acts[0], - width * sizeof(XkbAction)); - key->actsDefined |= 1 << i; - } - if ((key->symsDefined & 1) && key->syms[0]) - { - key->syms[i] = uTypedCalloc(width, KeySym); - if (key->syms[i] == NULL) - continue; - memcpy((void *) key->syms[i], (void *) key->syms[0], - width * sizeof(KeySym)); - key->symsDefined |= 1 << i; - } - if (defined & 1) - { - key->numLevels[i] = key->numLevels[0]; - } - } - /* If all groups are completely identical remove them all */ - /* exept the first one. */ - identical = True; - for (i = lastGroup; i > 0; i--) - { - if ((key->numLevels[i] != key->numLevels[0]) || - (key->types[i] != key->types[0])) - { - identical = False; - break; - } - if ((key->syms[i] != key->syms[0]) && - (key->syms[i] == NULL || key->syms[0] == NULL || - memcmp((void *) key->syms[i], (void *) key->syms[0], - sizeof(KeySym) * key->numLevels[0]))) - { - identical = False; - break; - } - if ((key->acts[i] != key->acts[0]) && - (key->acts[i] == NULL || key->acts[0] == NULL || - memcmp((void *) key->acts[i], (void *) key->acts[0], - sizeof(XkbAction) * key->numLevels[0]))) - { - identical = False; - break; - } - } - if (identical) - { - for (i = lastGroup; i > 0; i--) - { - key->numLevels[i] = 0; - if (key->syms[i] != NULL) - uFree(key->syms[i]); - key->syms[i] = (KeySym *) NULL; - if (key->acts[i] != NULL) - uFree(key->acts[i]); - key->acts[i] = (XkbAction *) NULL; - key->types[i] = (Atom) 0; - } - key->symsDefined &= 1; - key->actsDefined &= 1; - key->typesDefined &= 1; - } - return; -} - -/** - * Copy the KeyInfo into result. - * - * This function recurses. - */ -static Bool -CopySymbolsDef(XkbFileInfo * result, KeyInfo * key, int start_from) -{ - register int i; - unsigned okc, kc, width, tmp, nGroups; - XkbKeyTypePtr type; - Bool haveActions, autoType, useAlias; - KeySym *outSyms; - XkbAction *outActs; - XkbDescPtr xkb; - unsigned types[XkbNumKbdGroups]; - - xkb = result->xkb; - useAlias = (start_from == 0); - - /* get the keycode for the key. */ - if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb), - start_from)) - { - if ((start_from == 0) && (warningLevel >= 5)) - { - WARN2("Key %s not found in %s keycodes\n", - longText(key->name, XkbMessage), - XkbAtomText(NULL, xkb->names->keycodes, XkbMessage)); - ACTION("Symbols ignored\n"); - } - return False; - } - - haveActions = False; - for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++) - { - if (((i + 1) > nGroups) - && (((key->symsDefined | key->actsDefined) & (1 << i)) - || (key->typesDefined) & (1 << i))) - nGroups = i + 1; - if (key->acts[i]) - haveActions = True; - autoType = False; - /* Assign the type to the key, if it is missing. */ - if (key->types[i] == None) - { - if (key->dfltType != None) - key->types[i] = key->dfltType; - else if (FindAutomaticType(key->numLevels[i], key->syms[i], - &key->types[i], &autoType)) - { - } - else - { - if (warningLevel >= 5) - { - WARN1("No automatic type for %d symbols\n", - (unsigned int) key->numLevels[i]); - ACTION3("Using %s for the %s key (keycode %d)\n", - XkbAtomText(NULL, key->types[i], - XkbMessage), - longText(key->name, XkbMessage), kc); - } - } - } - if (FindNamedType(xkb, key->types[i], &types[i])) - { - if (!autoType || key->numLevels[i] > 2) - xkb->server->explicit[kc] |= (1 << i); - } - else - { - if (warningLevel >= 3) - { - WARN1("Type \"%s\" is not defined\n", - XkbAtomText(NULL, key->types[i], XkbMessage)); - ACTION2("Using TWO_LEVEL for the %s key (keycode %d)\n", - longText(key->name, XkbMessage), kc); - } - types[i] = XkbTwoLevelIndex; - } - /* if the type specifies less syms than the key has, shrink the key */ - type = &xkb->map->types[types[i]]; - if (type->num_levels < key->numLevels[i]) - { - if (warningLevel > 0) - { - WARN4 - ("Type \"%s\" has %d levels, but %s has %d symbols\n", - XkbAtomText(NULL, type->name, XkbMessage), - (unsigned int) type->num_levels, - longText(key->name, XkbMessage), - (unsigned int) key->numLevels[i]); - ACTION("Ignoring extra symbols\n"); - } - key->numLevels[i] = type->num_levels; - } - if (key->numLevels[i] > width) - width = key->numLevels[i]; - if (type->num_levels > width) - width = type->num_levels; - } - - /* width is now the largest width found */ - - i = width * nGroups; - outSyms = XkbResizeKeySyms(xkb, kc, i); - if (outSyms == NULL) - { - WSGO2("Could not enlarge symbols for %s (keycode %d)\n", - longText(key->name, XkbMessage), kc); - return False; - } - if (haveActions) - { - outActs = XkbResizeKeyActions(xkb, kc, i); - if (outActs == NULL) - { - WSGO2("Could not enlarge actions for %s (key %d)\n", - longText(key->name, XkbMessage), kc); - return False; - } - xkb->server->explicit[kc] |= XkbExplicitInterpretMask; - } - else - outActs = NULL; - if (key->defs.defined & _Key_GroupInfo) - i = key->groupInfo; - else - i = xkb->map->key_sym_map[kc].group_info; - - xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups); - xkb->map->key_sym_map[kc].width = width; - for (i = 0; i < nGroups; i++) - { - /* assign kt_index[i] to the index of the type in map->types. - * kt_index[i] may have been set by a previous run (if we have two - * layouts specified). Let's not overwrite it with the ONE_LEVEL - * default group if we dont even have keys for this group anyway. - * - * FIXME: There should be a better fix for this. - */ - if (key->numLevels[i]) - xkb->map->key_sym_map[kc].kt_index[i] = types[i]; - if (key->syms[i] != NULL) - { - /* fill key to "width" symbols*/ - for (tmp = 0; tmp < width; tmp++) - { - if (tmp < key->numLevels[i]) - outSyms[tmp] = key->syms[i][tmp]; - else - outSyms[tmp] = NoSymbol; - if ((outActs != NULL) && (key->acts[i] != NULL)) - { - if (tmp < key->numLevels[i]) - outActs[tmp] = key->acts[i][tmp]; - else - outActs[tmp].type = XkbSA_NoAction; - } - } - } - outSyms += width; - if (outActs) - outActs += width; - } - switch (key->behavior.type & XkbKB_OpMask) - { - case XkbKB_Default: - break; - case XkbKB_Overlay1: - case XkbKB_Overlay2: - /* find key by name! */ - if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True, - CreateKeyNames(xkb), 0)) - { - if (warningLevel >= 1) - { - WARN2("Key %s not found in %s keycodes\n", - longText(key->nameForOverlayKey, XkbMessage), - XkbAtomText(NULL, xkb->names->keycodes, XkbMessage)); - ACTION1("Not treating %s as an overlay key \n", - longText(key->name, XkbMessage)); - } - break; - } - key->behavior.data = okc; - default: - xkb->server->behaviors[kc] = key->behavior; - xkb->server->explicit[kc] |= XkbExplicitBehaviorMask; - break; - } - if (key->defs.defined & _Key_VModMap) - { - xkb->server->vmodmap[kc] = key->vmodmap; - xkb->server->explicit[kc] |= XkbExplicitVModMapMask; - } - if (key->repeat != RepeatUndefined) - { - if (key->repeat == RepeatYes) - xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8)); - else - xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8)); - xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask; - } - - /* do the same thing for the next key */ - CopySymbolsDef(result, key, kc + 1); - return True; -} - -static Bool -CopyModMapDef(XkbFileInfo * result, ModMapEntry * entry) -{ - unsigned kc; - XkbDescPtr xkb; - - xkb = result->xkb; - if ((!entry->haveSymbol) - && - (!FindNamedKey - (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0))) - { - if (warningLevel >= 5) - { - WARN2("Key %s not found in %s keycodes\n", - longText(entry->u.keyName, XkbMessage), - XkbAtomText(NULL, xkb->names->keycodes, XkbMessage)); - ACTION1("Modifier map entry for %s not updated\n", - XkbModIndexText(entry->modifier, XkbMessage)); - } - return False; - } - else if (entry->haveSymbol - && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc))) - { - if (warningLevel > 5) - { - WARN2("Key \"%s\" not found in %s symbol map\n", - XkbKeysymText(entry->u.keySym, XkbMessage), - XkbAtomText(NULL, xkb->names->symbols, XkbMessage)); - ACTION1("Modifier map entry for %s not updated\n", - XkbModIndexText(entry->modifier, XkbMessage)); - } - return False; - } - xkb->map->modmap[kc] |= (1 << entry->modifier); - return True; -} - -/** - * Handle the xkb_symbols section of an xkb file. - * - * @param file The parsed xkb_symbols section of the xkb file. - * @param result Handle to the data to store the result in. - * @param merge Merge strategy (e.g. MergeOverride). - */ -Bool -CompileSymbols(XkbFile * file, XkbFileInfo * result, unsigned merge) -{ - register int i; - SymbolsInfo info; - XkbDescPtr xkb; - - xkb = result->xkb; - InitSymbolsInfo(&info, xkb); - info.dflt.defs.fileID = file->id; - info.dflt.defs.merge = merge; - HandleSymbolsFile(file, xkb, merge, &info); - - if (info.nKeys == 0) - return True; - if (info.errorCount == 0) - { - KeyInfo *key; - - /* alloc memory in the xkb struct */ - if (XkbAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0) - != Success) - { - WSGO("Can not allocate names in CompileSymbols\n"); - ACTION("Symbols not added\n"); - return False; - } - if (XkbAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0) - != Success) - { - WSGO("Could not allocate client map in CompileSymbols\n"); - ACTION("Symbols not added\n"); - return False; - } - if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success) - { - WSGO("Could not allocate server map in CompileSymbols\n"); - ACTION("Symbols not added\n"); - return False; - } - if (XkbAllocControls(xkb, XkbPerKeyRepeatMask) != Success) - { - WSGO("Could not allocate controls in CompileSymbols\n"); - ACTION("Symbols not added\n"); - return False; - } - - /* now copy info into xkb. */ - xkb->names->symbols = XkbInternAtom(xkb->dpy, info.name, False); - if (info.aliases) - ApplyAliases(xkb, False, &info.aliases); - for (i = 0; i < XkbNumKbdGroups; i++) - { - if (info.groupNames[i] != None) - xkb->names->groups[i] = info.groupNames[i]; - } - /* sanitize keys */ - for (key = info.keys, i = 0; i < info.nKeys; i++, key++) - { - PrepareKeyDef(key); - } - /* copy! */ - for (key = info.keys, i = 0; i < info.nKeys; i++, key++) - { - if (!CopySymbolsDef(result, key, 0)) - info.errorCount++; - } - if (warningLevel > 3) - { - for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) - { - if (xkb->names->keys[i].name[0] == '\0') - continue; - if (XkbKeyNumGroups(xkb, i) < 1) - { - char buf[5]; - memcpy(buf, xkb->names->keys[i].name, 4); - buf[4] = '\0'; - WARN2 - ("No symbols defined for <%s> (keycode %d)\n", - buf, i); - } - } - } - if (info.modMap) - { - ModMapEntry *mm, *next; - for (mm = info.modMap; mm != NULL; mm = next) - { - if (!CopyModMapDef(result, mm)) - info.errorCount++; - next = (ModMapEntry *) mm->defs.next; - } - } - return True; - } - return False; -} +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH + THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ********************************************************/ + +#include "xkbcomp.h" +#include "tokens.h" +#include "expr.h" +#include "parseutils.h" + +#include +#include +#include + +#include "expr.h" +#include "vmod.h" +#include "action.h" +#include "keycodes.h" +#include "misc.h" +#include "alias.h" + +extern Atom tok_ONE_LEVEL; +extern Atom tok_TWO_LEVEL; +extern Atom tok_KEYPAD; + +/***====================================================================***/ + +#define RepeatYes 1 +#define RepeatNo 0 +#define RepeatUndefined ~((unsigned)0) + +#define _Key_Syms (1<<0) +#define _Key_Acts (1<<1) +#define _Key_Repeat (1<<2) +#define _Key_Behavior (1<<3) +#define _Key_Type_Dflt (1<<4) +#define _Key_Types (1<<5) +#define _Key_GroupInfo (1<<6) +#define _Key_VModMap (1<<7) + +typedef struct _KeyInfo +{ + CommonInfo defs; + unsigned long name; /* the 4 chars of the key name, as long */ + unsigned char groupInfo; + unsigned char typesDefined; + unsigned char symsDefined; + unsigned char actsDefined; + short numLevels[XkbNumKbdGroups]; + KeySym *syms[XkbNumKbdGroups]; + XkbAction *acts[XkbNumKbdGroups]; + Atom types[XkbNumKbdGroups]; + unsigned repeat; + XkbBehavior behavior; + unsigned short vmodmap; + unsigned long nameForOverlayKey; + unsigned long allowNone; + Atom dfltType; +} KeyInfo; + +/** + * Init the given key info to sane values. + */ +static void +InitKeyInfo(KeyInfo * info) +{ + register int i; + static char dflt[4] = "*"; + + info->defs.defined = 0; + info->defs.fileID = 0; + info->defs.merge = MergeOverride; + info->defs.next = NULL; + info->name = KeyNameToLong(dflt); + info->groupInfo = 0; + info->typesDefined = info->symsDefined = info->actsDefined = 0; + for (i = 0; i < XkbNumKbdGroups; i++) + { + info->numLevels[i] = 0; + info->types[i] = None; + info->syms[i] = NULL; + info->acts[i] = NULL; + } + info->dfltType = None; + info->behavior.type = XkbKB_Default; + info->behavior.data = 0; + info->vmodmap = 0; + info->nameForOverlayKey = 0; + info->repeat = RepeatUndefined; + info->allowNone = 0; + return; +} + +/** + * Free memory associated with this key info and reset to sane values. + */ +static void +FreeKeyInfo(KeyInfo * info) +{ + register int i; + + info->defs.defined = 0; + info->defs.fileID = 0; + info->defs.merge = MergeOverride; + info->defs.next = NULL; + info->groupInfo = 0; + info->typesDefined = info->symsDefined = info->actsDefined = 0; + for (i = 0; i < XkbNumKbdGroups; i++) + { + info->numLevels[i] = 0; + info->types[i] = None; + if (info->syms[i] != NULL) + uFree(info->syms[i]); + info->syms[i] = NULL; + if (info->acts[i] != NULL) + uFree(info->acts[i]); + info->acts[i] = NULL; + } + info->dfltType = None; + info->behavior.type = XkbKB_Default; + info->behavior.data = 0; + info->vmodmap = 0; + info->nameForOverlayKey = 0; + info->repeat = RepeatUndefined; + info->allowNone = 0; + return; +} + +/** + * Copy old into new, optionally reset old to 0. + * If old is reset, new simply re-uses old's memory. Otherwise, the memory is + * newly allocated and new points to the new memory areas. + */ +static Bool +CopyKeyInfo(KeyInfo * old, KeyInfo * new, Bool clearOld) +{ + register int i; + + *new = *old; + new->defs.next = NULL; + if (clearOld) + { + for (i = 0; i < XkbNumKbdGroups; i++) + { + old->numLevels[i] = 0; + old->syms[i] = NULL; + old->acts[i] = NULL; + } + } + else + { + int width; + for (i = 0; i < XkbNumKbdGroups; i++) + { + width = new->numLevels[i]; + if (old->syms[i] != NULL) + { + new->syms[i] = uTypedCalloc(width, KeySym); + if (!new->syms[i]) + { + new->syms[i] = NULL; + new->numLevels[i] = 0; + return False; + } + memcpy((char *) new->syms[i], (char *) old->syms[i], + width * sizeof(KeySym)); + } + if (old->acts[i] != NULL) + { + new->acts[i] = uTypedCalloc(width, XkbAction); + if (!new->acts[i]) + { + new->acts[i] = NULL; + return False; + } + memcpy((char *) new->acts[i], (char *) old->acts[i], + width * sizeof(XkbAction)); + } + } + } + return True; +} + +/***====================================================================***/ + +typedef struct _ModMapEntry +{ + CommonInfo defs; + Bool haveSymbol; + int modifier; + union + { + unsigned long keyName; + KeySym keySym; + } u; +} ModMapEntry; + +#define SYMBOLS_INIT_SIZE 110 +#define SYMBOLS_CHUNK 20 +typedef struct _SymbolsInfo +{ + char *name; /* e.g. pc+us+inet(evdev) */ + int errorCount; + unsigned fileID; + unsigned merge; + unsigned explicit_group; + unsigned groupInfo; + unsigned szKeys; + unsigned nKeys; + KeyInfo *keys; + KeyInfo dflt; + VModInfo vmods; + ActionInfo *action; + Atom groupNames[XkbNumKbdGroups]; + + ModMapEntry *modMap; + AliasInfo *aliases; +} SymbolsInfo; + +static void +InitSymbolsInfo(SymbolsInfo * info, XkbDescPtr xkb) +{ + register int i; + + tok_ONE_LEVEL = XkbInternAtom(NULL, "ONE_LEVEL", False); + tok_TWO_LEVEL = XkbInternAtom(NULL, "TWO_LEVEL", False); + tok_KEYPAD = XkbInternAtom(NULL, "KEYPAD", False); + info->name = NULL; + info->explicit_group = 0; + info->errorCount = 0; + info->fileID = 0; + info->merge = MergeOverride; + info->groupInfo = 0; + info->szKeys = SYMBOLS_INIT_SIZE; + info->nKeys = 0; + info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo); + info->modMap = NULL; + for (i = 0; i < XkbNumKbdGroups; i++) + info->groupNames[i] = None; + InitKeyInfo(&info->dflt); + InitVModInfo(&info->vmods, xkb); + info->action = NULL; + info->aliases = NULL; + return; +} + +static void +FreeSymbolsInfo(SymbolsInfo * info) +{ + register int i; + + if (info->name) + uFree(info->name); + info->name = NULL; + if (info->keys) + { + for (i = 0; i < info->nKeys; i++) + { + FreeKeyInfo(&info->keys[i]); + } + uFree(info->keys); + info->keys = NULL; + } + if (info->modMap) + { + ClearCommonInfo(&info->modMap->defs); + info->modMap = NULL; + } + if (info->aliases) + { + ClearAliases(&info->aliases); + info->aliases = NULL; + } + bzero((char *) info, sizeof(SymbolsInfo)); + return; +} + +static Bool +ResizeKeyGroup(KeyInfo * key, + unsigned group, unsigned atLeastSize, Bool forceActions) +{ + Bool tooSmall; + unsigned newWidth; + + tooSmall = (key->numLevels[group] < atLeastSize); + if (tooSmall) + newWidth = atLeastSize; + else + newWidth = key->numLevels[group]; + + if ((key->syms[group] == NULL) || tooSmall) + { + key->syms[group] = uTypedRecalloc(key->syms[group], + key->numLevels[group], newWidth, + KeySym); + if (!key->syms[group]) + return False; + } + if (((forceActions) && (tooSmall || (key->acts[group] == NULL))) || + (tooSmall && (key->acts[group] != NULL))) + { + key->acts[group] = uTypedRecalloc(key->acts[group], + key->numLevels[group], newWidth, + XkbAction); + if (!key->acts[group]) + return False; + } + key->numLevels[group] = newWidth; + return True; +} + +static Bool +MergeKeyGroups(SymbolsInfo * info, + KeyInfo * into, KeyInfo * from, unsigned group) +{ + KeySym *resultSyms; + XkbAction *resultActs; + int resultWidth; + register int i; + Bool report, clobber; + + clobber = (from->defs.merge != MergeAugment); + report = (warningLevel > 9) || + ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0)); + if (into->numLevels[group] >= from->numLevels[group]) + { + resultSyms = into->syms[group]; + resultActs = into->acts[group]; + resultWidth = into->numLevels[group]; + } + else + { + resultSyms = from->syms[group]; + resultActs = from->acts[group]; + resultWidth = from->numLevels[group]; + } + if (resultSyms == NULL) + { + resultSyms = uTypedCalloc(resultWidth, KeySym); + if (!resultSyms) + { + WSGO("Could not allocate symbols for group merge\n"); + ACTION2("Group %d of key %s not merged\n", group, + longText(into->name, XkbMessage)); + return False; + } + } + if ((resultActs == NULL) && (into->acts[group] || from->acts[group])) + { + resultActs = uTypedCalloc(resultWidth, XkbAction); + if (!resultActs) + { + WSGO("Could not allocate actions for group merge\n"); + ACTION2("Group %d of key %s not merged\n", group, + longText(into->name, XkbMessage)); + return False; + } + } + for (i = 0; i < resultWidth; i++) + { + KeySym fromSym, toSym; + if (from->syms[group] && (i < from->numLevels[group])) + fromSym = from->syms[group][i]; + else + fromSym = NoSymbol; + if (into->syms[group] && (i < into->numLevels[group])) + toSym = into->syms[group][i]; + else + toSym = NoSymbol; + if ((fromSym == NoSymbol) || (fromSym == toSym)) + resultSyms[i] = toSym; + else if (toSym == NoSymbol) + resultSyms[i] = fromSym; + else + { + KeySym use, ignore; + if (clobber) + { + use = fromSym; + ignore = toSym; + } + else + { + use = toSym; + ignore = fromSym; + } + if (report) + { + WARN3 + ("Multiple symbols for level %d/group %d on key %s\n", + i + 1, group + 1, longText(into->name, XkbMessage)); + ACTION2("Using %s, ignoring %s\n", + XkbKeysymText(use, XkbMessage), + XkbKeysymText(ignore, XkbMessage)); + } + resultSyms[i] = use; + } + if (resultActs != NULL) + { + XkbAction *fromAct, *toAct; + fromAct = (from->acts[group] ? &from->acts[group][i] : NULL); + toAct = (into->acts[group] ? &into->acts[group][i] : NULL); + if (((fromAct == NULL) || (fromAct->type == XkbSA_NoAction)) + && (toAct != NULL)) + { + resultActs[i] = *toAct; + } + else if (((toAct == NULL) || (toAct->type == XkbSA_NoAction)) + && (fromAct != NULL)) + { + resultActs[i] = *fromAct; + } + else + { + XkbAction *use, *ignore; + if (clobber) + { + use = fromAct; + ignore = toAct; + } + else + { + use = toAct; + ignore = fromAct; + } + if (report) + { + WARN3 + ("Multiple actions for level %d/group %d on key %s\n", + i + 1, group + 1, longText(into->name, XkbMessage)); + ACTION2("Using %s, ignoring %s\n", + XkbActionTypeText(use->type, XkbMessage), + XkbActionTypeText(ignore->type, XkbMessage)); + } + resultActs[i] = *use; + } + } + } + if ((into->syms[group] != NULL) && (resultSyms != into->syms[group])) + uFree(into->syms[group]); + if ((from->syms[group] != NULL) && (resultSyms != from->syms[group])) + uFree(from->syms[group]); + if ((into->acts[group] != NULL) && (resultActs != into->acts[group])) + uFree(into->acts[group]); + if ((from->acts[group] != NULL) && (resultActs != from->acts[group])) + uFree(from->acts[group]); + into->numLevels[group] = resultWidth; + into->syms[group] = resultSyms; + from->syms[group] = NULL; + into->acts[group] = resultActs; + from->acts[group] = NULL; + into->symsDefined |= (1 << group); + from->symsDefined &= ~(1 << group); + into->actsDefined |= (1 << group); + from->actsDefined &= ~(1 << group); + return True; +} + +static Bool +MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from) +{ + register int i; + unsigned collide = 0; + Bool report; + + if (from->defs.merge == MergeReplace) + { + for (i = 0; i < XkbNumKbdGroups; i++) + { + if (into->numLevels[i] != 0) + { + if (into->syms[i]) + uFree(into->syms[i]); + if (into->acts[i]) + uFree(into->acts[i]); + } + } + *into = *from; + bzero(from, sizeof(KeyInfo)); + return True; + } + report = ((warningLevel > 9) || + ((into->defs.fileID == from->defs.fileID) + && (warningLevel > 0))); + for (i = 0; i < XkbNumKbdGroups; i++) + { + if (from->numLevels[i] > 0) + { + if (into->numLevels[i] == 0) + { + into->numLevels[i] = from->numLevels[i]; + into->syms[i] = from->syms[i]; + into->acts[i] = from->acts[i]; + into->symsDefined |= (1 << i); + from->syms[i] = NULL; + from->acts[i] = NULL; + from->numLevels[i] = 0; + from->symsDefined &= ~(1 << i); + if (into->syms[i]) + into->defs.defined |= _Key_Syms; + if (into->acts[i]) + into->defs.defined |= _Key_Acts; + } + else + { + if (report) + { + if (into->syms[i]) + collide |= _Key_Syms; + if (into->acts[i]) + collide |= _Key_Acts; + } + MergeKeyGroups(info, into, from, (unsigned) i); + } + } + if (from->types[i] != None) + { + if ((into->types[i] != None) && (report) && + (into->types[i] != from->types[i])) + { + Atom use, ignore; + collide |= _Key_Types; + if (from->defs.merge != MergeAugment) + { + use = from->types[i]; + ignore = into->types[i]; + } + else + { + use = into->types[i]; + ignore = from->types[i]; + } + WARN2 + ("Multiple definitions for group %d type of key %s\n", + i, longText(into->name, XkbMessage)); + ACTION2("Using %s, ignoring %s\n", + XkbAtomText(NULL, use, XkbMessage), + XkbAtomText(NULL, ignore, XkbMessage)); + } + if ((from->defs.merge != MergeAugment) + || (into->types[i] == None)) + { + into->types[i] = from->types[i]; + } + } + } + if (UseNewField(_Key_Behavior, &into->defs, &from->defs, &collide)) + { + into->behavior = from->behavior; + into->nameForOverlayKey = from->nameForOverlayKey; + into->defs.defined |= _Key_Behavior; + } + if (UseNewField(_Key_VModMap, &into->defs, &from->defs, &collide)) + { + into->vmodmap = from->vmodmap; + into->defs.defined |= _Key_VModMap; + } + if (UseNewField(_Key_Repeat, &into->defs, &from->defs, &collide)) + { + into->repeat = from->repeat; + into->defs.defined |= _Key_Repeat; + } + if (UseNewField(_Key_Type_Dflt, &into->defs, &from->defs, &collide)) + { + into->dfltType = from->dfltType; + into->defs.defined |= _Key_Type_Dflt; + } + if (UseNewField(_Key_GroupInfo, &into->defs, &from->defs, &collide)) + { + into->groupInfo = from->groupInfo; + into->defs.defined |= _Key_GroupInfo; + } + if (collide) + { + WARN1("Symbol map for key %s redefined\n", + longText(into->name, XkbMessage)); + ACTION1("Using %s definition for conflicting fields\n", + (from->defs.merge == MergeAugment ? "first" : "last")); + } + return True; +} + +static Bool +AddKeySymbols(SymbolsInfo * info, KeyInfo * key, XkbDescPtr xkb) +{ + register int i; + unsigned long real_name; + + for (i = 0; i < info->nKeys; i++) + { + if (info->keys[i].name == key->name) + return MergeKeys(info, &info->keys[i], key); + } + if (FindKeyNameForAlias(xkb, key->name, &real_name)) + { + for (i = 0; i < info->nKeys; i++) + { + if (info->keys[i].name == real_name) + return MergeKeys(info, &info->keys[i], key); + } + } + if (info->nKeys >= info->szKeys) + { + info->szKeys += SYMBOLS_CHUNK; + info->keys = + uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo); + if (!info->keys) + { + WSGO("Could not allocate key symbols descriptions\n"); + ACTION("Some key symbols definitions may be lost\n"); + return False; + } + } + return CopyKeyInfo(key, &info->keys[info->nKeys++], True); +} + +static Bool +AddModMapEntry(SymbolsInfo * info, ModMapEntry * new) +{ + ModMapEntry *mm; + Bool clobber; + + clobber = (new->defs.merge != MergeAugment); + for (mm = info->modMap; mm != NULL; mm = (ModMapEntry *) mm->defs.next) + { + if (new->haveSymbol && mm->haveSymbol + && (new->u.keySym == mm->u.keySym)) + { + unsigned use, ignore; + if (mm->modifier != new->modifier) + { + if (clobber) + { + use = new->modifier; + ignore = mm->modifier; + } + else + { + use = mm->modifier; + ignore = new->modifier; + } + ERROR1 + ("%s added to symbol map for multiple modifiers\n", + XkbKeysymText(new->u.keySym, XkbMessage)); + ACTION2("Using %s, ignoring %s.\n", + XkbModIndexText(use, XkbMessage), + XkbModIndexText(ignore, XkbMessage)); + mm->modifier = use; + } + return True; + } + if ((!new->haveSymbol) && (!mm->haveSymbol) && + (new->u.keyName == mm->u.keyName)) + { + unsigned use, ignore; + if (mm->modifier != new->modifier) + { + if (clobber) + { + use = new->modifier; + ignore = mm->modifier; + } + else + { + use = mm->modifier; + ignore = new->modifier; + } + ERROR1("Key %s added to map for multiple modifiers\n", + longText(new->u.keyName, XkbMessage)); + ACTION2("Using %s, ignoring %s.\n", + XkbModIndexText(use, XkbMessage), + XkbModIndexText(ignore, XkbMessage)); + mm->modifier = use; + } + return True; + } + } + mm = uTypedAlloc(ModMapEntry); + if (mm == NULL) + { + WSGO("Could not allocate modifier map entry\n"); + ACTION1("Modifier map for %s will be incomplete\n", + XkbModIndexText(new->modifier, XkbMessage)); + return False; + } + *mm = *new; + mm->defs.next = &info->modMap->defs; + info->modMap = mm; + return True; +} + +/***====================================================================***/ + +static void +MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from, + unsigned merge, XkbDescPtr xkb) +{ + register int i; + KeyInfo *key; + + if (from->errorCount > 0) + { + into->errorCount += from->errorCount; + return; + } + if (into->name == NULL) + { + into->name = from->name; + from->name = NULL; + } + for (i = 0; i < XkbNumKbdGroups; i++) + { + if (from->groupNames[i] != None) + { + if ((merge != MergeAugment) || (into->groupNames[i] == None)) + into->groupNames[i] = from->groupNames[i]; + } + } + for (i = 0, key = from->keys; i < from->nKeys; i++, key++) + { + if (merge != MergeDefault) + key->defs.merge = merge; + if (!AddKeySymbols(into, key, xkb)) + into->errorCount++; + } + if (from->modMap != NULL) + { + ModMapEntry *mm, *next; + for (mm = from->modMap; mm != NULL; mm = next) + { + if (merge != MergeDefault) + mm->defs.merge = merge; + if (!AddModMapEntry(into, mm)) + into->errorCount++; + next = (ModMapEntry *) mm->defs.next; + uFree(mm); + } + from->modMap = NULL; + } + if (!MergeAliases(&into->aliases, &from->aliases, merge)) + into->errorCount++; + return; +} + +typedef void (*FileHandler) (XkbFile * /* rtrn */ , + XkbDescPtr /* xkb */ , + unsigned /* merge */ , + SymbolsInfo * /* included */ + ); + +static Bool +HandleIncludeSymbols(IncludeStmt * stmt, + XkbDescPtr xkb, SymbolsInfo * info, FileHandler hndlr) +{ + unsigned newMerge; + XkbFile *rtrn; + SymbolsInfo included; + Bool haveSelf; + + haveSelf = False; + if ((stmt->file == NULL) && (stmt->map == NULL)) + { + haveSelf = True; + included = *info; + bzero(info, sizeof(SymbolsInfo)); + } + else if (ProcessIncludeFile(stmt, XkmSymbolsIndex, &rtrn, &newMerge)) + { + InitSymbolsInfo(&included, xkb); + included.fileID = included.dflt.defs.fileID = rtrn->id; + included.merge = included.dflt.defs.merge = MergeOverride; + if (stmt->modifier) + { + included.explicit_group = atoi(stmt->modifier) - 1; + } + else + { + included.explicit_group = info->explicit_group; + } + (*hndlr) (rtrn, xkb, MergeOverride, &included); + if (stmt->stmt != NULL) + { + if (included.name != NULL) + uFree(included.name); + included.name = stmt->stmt; + stmt->stmt = NULL; + } + } + else + { + info->errorCount += 10; + return False; + } + if ((stmt->next != NULL) && (included.errorCount < 1)) + { + IncludeStmt *next; + unsigned op; + SymbolsInfo next_incl; + + for (next = stmt->next; next != NULL; next = next->next) + { + if ((next->file == NULL) && (next->map == NULL)) + { + haveSelf = True; + MergeIncludedSymbols(&included, info, next->merge, xkb); + FreeSymbolsInfo(info); + } + else if (ProcessIncludeFile(next, XkmSymbolsIndex, &rtrn, &op)) + { + InitSymbolsInfo(&next_incl, xkb); + next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id; + next_incl.merge = next_incl.dflt.defs.merge = MergeOverride; + if (next->modifier) + { + next_incl.explicit_group = atoi(next->modifier) - 1; + } + else + { + next_incl.explicit_group = info->explicit_group; + } + (*hndlr) (rtrn, xkb, MergeOverride, &next_incl); + MergeIncludedSymbols(&included, &next_incl, op, xkb); + FreeSymbolsInfo(&next_incl); + } + else + { + info->errorCount += 10; + return False; + } + } + } + if (haveSelf) + *info = included; + else + { + MergeIncludedSymbols(info, &included, newMerge, xkb); + FreeSymbolsInfo(&included); + } + return (info->errorCount == 0); +} + +static LookupEntry groupNames[] = { + {"group1", 1}, + {"group2", 2}, + {"group3", 3}, + {"group4", 4}, + {"group5", 5}, + {"group6", 6}, + {"group7", 7}, + {"group8", 8}, + {NULL, 0} +}; + + +#define SYMBOLS 1 +#define ACTIONS 2 + +static Bool +GetGroupIndex(KeyInfo * key, + ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn) +{ + const char *name; + ExprResult tmp; + + if (what == SYMBOLS) + name = "symbols"; + else + name = "actions"; + + if (arrayNdx == NULL) + { + register int i; + unsigned defined; + if (what == SYMBOLS) + defined = key->symsDefined; + else + defined = key->actsDefined; + + for (i = 0; i < XkbNumKbdGroups; i++) + { + if ((defined & (1 << i)) == 0) + { + *ndx_rtrn = i; + return True; + } + } + ERROR3("Too many groups of %s for key %s (max %d)\n", name, + longText(key->name, XkbMessage), XkbNumKbdGroups + 1); + ACTION1("Ignoring %s defined for extra groups\n", name); + return False; + } + if (!ExprResolveInteger + (arrayNdx, &tmp, SimpleLookup, (XPointer) groupNames)) + { + ERROR2("Illegal group index for %s of key %s\n", name, + longText(key->name, XkbMessage)); + ACTION("Definition with non-integer array index ignored\n"); + return False; + } + if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) + { + ERROR3("Group index for %s of key %s is out of range (1..%d)\n", + name, longText(key->name, XkbMessage), XkbNumKbdGroups + 1); + ACTION2("Ignoring %s for group %d\n", name, tmp.uval); + return False; + } + *ndx_rtrn = tmp.uval - 1; + return True; +} + +static Bool +AddSymbolsToKey(KeyInfo * key, + XkbDescPtr xkb, + char *field, + ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info) +{ + unsigned ndx, nSyms; + int i; + + if (!GetGroupIndex(key, arrayNdx, SYMBOLS, &ndx)) + return False; + if (value == NULL) + { + key->symsDefined |= (1 << ndx); + return True; + } + if (value->op != ExprKeysymList) + { + ERROR1("Expected a list of symbols, found %s\n", + exprOpText(value->op)); + ACTION2("Ignoring symbols for group %d of %s\n", ndx, + longText(key->name, XkbMessage)); + return False; + } + if (key->syms[ndx] != NULL) + { + WSGO2("Symbols for key %s, group %d already defined\n", + longText(key->name, XkbMessage), ndx); + return False; + } + nSyms = value->value.list.nSyms; + if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL)) && + (!ResizeKeyGroup(key, ndx, nSyms, False))) + { + WSGO2("Could not resize group %d of key %s\n", ndx, + longText(key->name, XkbMessage)); + ACTION("Symbols lost\n"); + return False; + } + key->symsDefined |= (1 << ndx); + for (i = 0; i < nSyms; i++) { + if (!LookupKeysym(value->value.list.syms[i], &key->syms[ndx][i])) { + WSGO1("Could not resolve keysym %s\n", value->value.list.syms[i]); + key->syms[ndx][i] = NoSymbol; + } + } + for (i = key->numLevels[ndx] - 1; + (i >= 0) && (key->syms[ndx][i] == NoSymbol); i--) + { + key->numLevels[ndx]--; + } + return True; +} + +static Bool +AddActionsToKey(KeyInfo * key, + XkbDescPtr xkb, + char *field, + ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info) +{ + register int i; + unsigned ndx, nActs; + ExprDef *act; + XkbAnyAction *toAct; + + if (!GetGroupIndex(key, arrayNdx, ACTIONS, &ndx)) + return False; + + if (value == NULL) + { + key->actsDefined |= (1 << ndx); + return True; + } + if (value->op != ExprActionList) + { + WSGO1("Bad expression type (%d) for action list value\n", value->op); + ACTION2("Ignoring actions for group %d of %s\n", ndx, + longText(key->name, XkbMessage)); + return False; + } + if (key->acts[ndx] != NULL) + { + WSGO2("Actions for key %s, group %d already defined\n", + longText(key->name, XkbMessage), ndx); + return False; + } + for (nActs = 0, act = value->value.child; act != NULL; nActs++) + { + act = (ExprDef *) act->common.next; + } + if (nActs < 1) + { + WSGO("Action list but not actions in AddActionsToKey\n"); + return False; + } + if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL)) && + (!ResizeKeyGroup(key, ndx, nActs, True))) + { + WSGO2("Could not resize group %d of key %s\n", ndx, + longText(key->name, XkbMessage)); + ACTION("Actions lost\n"); + return False; + } + key->actsDefined |= (1 << ndx); + + toAct = (XkbAnyAction *) key->acts[ndx]; + act = value->value.child; + for (i = 0; i < nActs; i++, toAct++) + { + if (!HandleActionDef(act, xkb, toAct, MergeOverride, info->action)) + { + ERROR1("Illegal action definition for %s\n", + longText(key->name, XkbMessage)); + ACTION2("Action for group %d/level %d ignored\n", ndx + 1, i + 1); + } + act = (ExprDef *) act->common.next; + } + return True; +} + +static int +SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value) +{ + ExprResult tmp; + unsigned radio_groups = 0; + + if (arrayNdx == NULL) + { + radio_groups = XkbAllRadioGroupsMask; + } + else + { + if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL)) + { + ERROR("Illegal index in group name definition\n"); + ACTION("Definition with non-integer array index ignored\n"); + return False; + } + if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups)) + { + ERROR1("Illegal radio group specified (must be 1..%d)\n", + XkbMaxRadioGroups + 1); + ACTION1("Value of \"allow none\" for group %d ignored\n", + tmp.uval); + return False; + } + radio_groups |= (1 << (tmp.uval - 1)); + } + if (!ExprResolveBoolean(value, &tmp, NULL, NULL)) + { + ERROR1("Illegal \"allow none\" value for %s\n", + longText(key->name, XkbMessage)); + ACTION("Non-boolean value ignored\n"); + return False; + } + if (tmp.uval) + key->allowNone |= radio_groups; + else + key->allowNone &= ~radio_groups; + return True; +} + + +static LookupEntry lockingEntries[] = { + {"true", XkbKB_Lock}, + {"yes", XkbKB_Lock}, + {"on", XkbKB_Lock}, + {"false", XkbKB_Default}, + {"no", XkbKB_Default}, + {"off", XkbKB_Default}, + {"permanent", XkbKB_Lock | XkbKB_Permanent}, + {NULL, 0} +}; + +static LookupEntry repeatEntries[] = { + {"true", RepeatYes}, + {"yes", RepeatYes}, + {"on", RepeatYes}, + {"false", RepeatNo}, + {"no", RepeatNo}, + {"off", RepeatNo}, + {"default", RepeatUndefined}, + {NULL, 0} +}; + +static LookupEntry rgEntries[] = { + {"none", 0}, + {NULL, 0} +}; + +static Bool +SetSymbolsField(KeyInfo * key, + XkbDescPtr xkb, + char *field, + ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info) +{ + Bool ok = True; + ExprResult tmp; + + if (uStrCaseCmp(field, "type") == 0) + { + ExprResult ndx; + if ((!ExprResolveString(value, &tmp, NULL, NULL)) + && (warningLevel > 0)) + { + WARN("The type field of a key symbol map must be a string\n"); + ACTION("Ignoring illegal type definition\n"); + } + if (arrayNdx == NULL) + { + key->dfltType = XkbInternAtom(NULL, tmp.str, False); + key->defs.defined |= _Key_Type_Dflt; + } + else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup, + (XPointer) groupNames)) + { + ERROR1("Illegal group index for type of key %s\n", + longText(key->name, XkbMessage)); + ACTION("Definition with non-integer array index ignored\n"); + return False; + } + else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups)) + { + ERROR2 + ("Group index for type of key %s is out of range (1..%d)\n", + longText(key->name, XkbMessage), XkbNumKbdGroups + 1); + ACTION1("Ignoring type for group %d\n", ndx.uval); + return False; + } + else + { + key->types[ndx.uval - 1] = XkbInternAtom(NULL, tmp.str, False); + key->typesDefined |= (1 << (ndx.uval - 1)); + } + } + else if (uStrCaseCmp(field, "symbols") == 0) + return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info); + else if (uStrCaseCmp(field, "actions") == 0) + return AddActionsToKey(key, xkb, field, arrayNdx, value, info); + else if ((uStrCaseCmp(field, "vmods") == 0) || + (uStrCaseCmp(field, "virtualmods") == 0) || + (uStrCaseCmp(field, "virtualmodifiers") == 0)) + { + ok = ExprResolveModMask(value, &tmp, LookupVModMask, (XPointer) xkb); + if (ok) + { + key->vmodmap = (tmp.uval >> 8); + key->defs.defined |= _Key_VModMap; + } + else + { + ERROR1("Expected a virtual modifier mask, found %s\n", + exprOpText(value->op)); + ACTION1("Ignoring virtual modifiers definition for key %s\n", + longText(key->name, XkbMessage)); + } + } + else if ((uStrCaseCmp(field, "locking") == 0) + || (uStrCaseCmp(field, "lock") == 0) + || (uStrCaseCmp(field, "locks") == 0)) + { + ok = ExprResolveEnum(value, &tmp, lockingEntries); + if (ok) + key->behavior.type = tmp.uval; + key->defs.defined |= _Key_Behavior; + } + else if ((uStrCaseCmp(field, "radiogroup") == 0) || + (uStrCaseCmp(field, "permanentradiogroup") == 0)) + { + Bool permanent = False; + if (uStrCaseCmp(field, "permanentradiogroup") == 0) + permanent = True; + ok = ExprResolveInteger(value, &tmp, SimpleLookup, + (XPointer) rgEntries); + if (!ok) + { + ERROR1("Illegal radio group specification for %s\n", + longText(key->name, XkbMessage)); + ACTION("Non-integer radio group ignored\n"); + return False; + } + if (tmp.uval == 0) + { + key->behavior.type = XkbKB_Default; + key->behavior.data = 0; + return ok; + } + if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups)) + { + ERROR1 + ("Radio group specification for %s out of range (1..32)\n", + longText(key->name, XkbMessage)); + ACTION1("Illegal radio group %d ignored\n", tmp.uval); + return False; + } + key->behavior.type = + XkbKB_RadioGroup | (permanent ? XkbKB_Permanent : 0); + key->behavior.data = tmp.uval - 1; + if (key->allowNone & (1 << (tmp.uval - 1))) + key->behavior.data |= XkbKB_RGAllowNone; + key->defs.defined |= _Key_Behavior; + } + else if (uStrCaseEqual(field, "allownone")) + { + ok = SetAllowNone(key, arrayNdx, value); + } + else if (uStrCasePrefix("overlay", field) || + uStrCasePrefix("permanentoverlay", field)) + { + Bool permanent = False; + char *which; + int overlayNdx; + if (uStrCasePrefix("permanent", field)) + { + permanent = True; + which = &field[sizeof("permanentoverlay") - 1]; + } + else + { + which = &field[sizeof("overlay") - 1]; + } + if (sscanf(which, "%d", &overlayNdx) == 1) + { + if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0)) + { + ERROR2("Illegal overlay %d specified for %s\n", + overlayNdx, longText(key->name, XkbMessage)); + ACTION("Ignored\n"); + return False; + } + } + else if (*which == '\0') + overlayNdx = 1; + else if (warningLevel > 0) + { + ERROR2("Illegal overlay \"%s\" specified for %s\n", + which, longText(key->name, XkbMessage)); + ACTION("Ignored\n"); + return False; + } + ok = ExprResolveKeyName(value, &tmp, NULL, NULL); + if (!ok) + { + ERROR1("Illegal overlay key specification for %s\n", + longText(key->name, XkbMessage)); + ACTION("Overlay key must be specified by name\n"); + return False; + } + if (overlayNdx == 1) + key->behavior.type = XkbKB_Overlay1; + else + key->behavior.type = XkbKB_Overlay2; + if (permanent) + key->behavior.type |= XkbKB_Permanent; + + key->behavior.data = 0; + key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name); + key->defs.defined |= _Key_Behavior; + } + else if ((uStrCaseCmp(field, "repeating") == 0) || + (uStrCaseCmp(field, "repeats") == 0) || + (uStrCaseCmp(field, "repeat") == 0)) + { + ok = ExprResolveEnum(value, &tmp, repeatEntries); + if (!ok) + { + ERROR1("Illegal repeat setting for %s\n", + longText(key->name, XkbMessage)); + ACTION("Non-boolean repeat setting ignored\n"); + return False; + } + key->repeat = tmp.uval; + key->defs.defined |= _Key_Repeat; + } + else if ((uStrCaseCmp(field, "groupswrap") == 0) || + (uStrCaseCmp(field, "wrapgroups") == 0)) + { + ok = ExprResolveBoolean(value, &tmp, NULL, NULL); + if (!ok) + { + ERROR1("Illegal groupsWrap setting for %s\n", + longText(key->name, XkbMessage)); + ACTION("Non-boolean value ignored\n"); + return False; + } + if (tmp.uval) + key->groupInfo = XkbWrapIntoRange; + else + key->groupInfo = XkbClampIntoRange; + key->defs.defined |= _Key_GroupInfo; + } + else if ((uStrCaseCmp(field, "groupsclamp") == 0) || + (uStrCaseCmp(field, "clampgroups") == 0)) + { + ok = ExprResolveBoolean(value, &tmp, NULL, NULL); + if (!ok) + { + ERROR1("Illegal groupsClamp setting for %s\n", + longText(key->name, XkbMessage)); + ACTION("Non-boolean value ignored\n"); + return False; + } + if (tmp.uval) + key->groupInfo = XkbClampIntoRange; + else + key->groupInfo = XkbWrapIntoRange; + key->defs.defined |= _Key_GroupInfo; + } + else if ((uStrCaseCmp(field, "groupsredirect") == 0) || + (uStrCaseCmp(field, "redirectgroups") == 0)) + { + if (!ExprResolveInteger + (value, &tmp, SimpleLookup, (XPointer) groupNames)) + { + ERROR1("Illegal group index for redirect of key %s\n", + longText(key->name, XkbMessage)); + ACTION("Definition with non-integer group ignored\n"); + return False; + } + if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) + { + ERROR2("Out-of-range (1..%d) group for redirect of key %s\n", + XkbNumKbdGroups, longText(key->name, XkbMessage)); + ERROR1("Ignoring illegal group %d\n", tmp.uval); + return False; + } + key->groupInfo = + XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1); + key->defs.defined |= _Key_GroupInfo; + } + else + { + ERROR1("Unknown field %s in a symbol interpretation\n", field); + ACTION("Definition ignored\n"); + ok = False; + } + return ok; +} + +static int +SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value) +{ + ExprResult tmp, name; + + if ((arrayNdx == NULL) && (warningLevel > 0)) + { + WARN("You must specify an index when specifying a group name\n"); + ACTION("Group name definition without array subscript ignored\n"); + return False; + } + if (!ExprResolveInteger + (arrayNdx, &tmp, SimpleLookup, (XPointer) groupNames)) + { + ERROR("Illegal index in group name definition\n"); + ACTION("Definition with non-integer array index ignored\n"); + return False; + } + if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) + { + ERROR1 + ("Attempt to specify name for illegal group (must be 1..%d)\n", + XkbNumKbdGroups + 1); + ACTION1("Name for group %d ignored\n", tmp.uval); + return False; + } + if (!ExprResolveString(value, &name, NULL, NULL)) + { + ERROR("Group name must be a string\n"); + ACTION1("Illegal name for group %d ignored\n", tmp.uval); + return False; + } + info->groupNames[tmp.uval - 1 + info->explicit_group] = + XkbInternAtom(NULL, name.str, False); + + return True; +} + +static int +HandleSymbolsVar(VarDef * stmt, XkbDescPtr xkb, SymbolsInfo * info) +{ + ExprResult elem, field, tmp; + ExprDef *arrayNdx; + + if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0) + return 0; /* internal error, already reported */ + if (elem.str && (uStrCaseCmp(elem.str, "key") == 0)) + { + return SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx, + stmt->value, info); + } + else if ((elem.str == NULL) && ((uStrCaseCmp(field.str, "name") == 0) || + (uStrCaseCmp(field.str, "groupname") == + 0))) + { + return SetGroupName(info, arrayNdx, stmt->value); + } + else if ((elem.str == NULL) + && ((uStrCaseCmp(field.str, "groupswrap") == 0) + || (uStrCaseCmp(field.str, "wrapgroups") == 0))) + { + if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL)) + { + ERROR("Illegal setting for global groupsWrap\n"); + ACTION("Non-boolean value ignored\n"); + return False; + } + if (tmp.uval) + info->groupInfo = XkbWrapIntoRange; + else + info->groupInfo = XkbClampIntoRange; + return True; + } + else if ((elem.str == NULL) + && ((uStrCaseCmp(field.str, "groupsclamp") == 0) + || (uStrCaseCmp(field.str, "clampgroups") == 0))) + { + if (!ExprResolveBoolean(stmt->value, &tmp, NULL, NULL)) + { + ERROR("Illegal setting for global groupsClamp\n"); + ACTION("Non-boolean value ignored\n"); + return False; + } + if (tmp.uval) + info->groupInfo = XkbClampIntoRange; + else + info->groupInfo = XkbWrapIntoRange; + return True; + } + else if ((elem.str == NULL) + && ((uStrCaseCmp(field.str, "groupsredirect") == 0) + || (uStrCaseCmp(field.str, "redirectgroups") == 0))) + { + if (!ExprResolveInteger(stmt->value, &tmp, + SimpleLookup, (XPointer) groupNames)) + { + ERROR("Illegal group index for global groupsRedirect\n"); + ACTION("Definition with non-integer group ignored\n"); + return False; + } + if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups)) + { + ERROR1 + ("Out-of-range (1..%d) group for global groupsRedirect\n", + XkbNumKbdGroups); + ACTION1("Ignoring illegal group %d\n", tmp.uval); + return False; + } + info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval); + return True; + } + else if ((elem.str == NULL) && (uStrCaseCmp(field.str, "allownone") == 0)) + { + return SetAllowNone(&info->dflt, arrayNdx, stmt->value); + } + return SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value, + &info->action); +} + +static Bool +HandleSymbolsBody(VarDef * def, + XkbDescPtr xkb, KeyInfo * key, SymbolsInfo * info) +{ + Bool ok = True; + ExprResult tmp, field; + ExprDef *arrayNdx; + + for (; def != NULL; def = (VarDef *) def->common.next) + { + if ((def->name) && (def->name->type == ExprFieldRef)) + { + ok = HandleSymbolsVar(def, xkb, info); + continue; + } + else + { + if (def->name == NULL) + { + if ((def->value == NULL) + || (def->value->op == ExprKeysymList)) + field.str = "symbols"; + else + field.str = "actions"; + arrayNdx = NULL; + } + else + { + ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx); + } + if (ok) + ok = SetSymbolsField(key, xkb, field.str, arrayNdx, + def->value, info); + } + } + return ok; +} + +static Bool +SetExplicitGroup(SymbolsInfo * info, KeyInfo * key) +{ + unsigned group = info->explicit_group; + + if (group == 0) + return True; + + if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1) + { + int i; + WARN1("For the map %s an explicit group specified\n", info->name); + WARN1("but key %s has more than one group defined\n", + longText(key->name, XkbMessage)); + ACTION("All groups except first one will be ignored\n"); + for (i = 1; i < XkbNumKbdGroups; i++) + { + key->numLevels[i] = 0; + if (key->syms[i] != NULL) + uFree(key->syms[i]); + key->syms[i] = (KeySym *) NULL; + if (key->acts[i] != NULL) + uFree(key->acts[i]); + key->acts[i] = (XkbAction *) NULL; + key->types[i] = (Atom) 0; + } + } + key->typesDefined = key->symsDefined = key->actsDefined = 1 << group; + + key->numLevels[group] = key->numLevels[0]; + key->numLevels[0] = 0; + key->syms[group] = key->syms[0]; + key->syms[0] = (KeySym *) NULL; + key->acts[group] = key->acts[0]; + key->acts[0] = (XkbAction *) NULL; + key->types[group] = key->types[0]; + key->types[0] = (Atom) 0; + return True; +} + +static int +HandleSymbolsDef(SymbolsDef * stmt, + XkbDescPtr xkb, unsigned merge, SymbolsInfo * info) +{ + KeyInfo key; + + InitKeyInfo(&key); + CopyKeyInfo(&info->dflt, &key, False); + key.defs.merge = stmt->merge; + key.name = KeyNameToLong(stmt->keyName); + if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info)) + { + info->errorCount++; + return False; + } + + if (!SetExplicitGroup(info, &key)) + { + info->errorCount++; + return False; + } + + if (!AddKeySymbols(info, &key, xkb)) + { + info->errorCount++; + return False; + } + return True; +} + +static Bool +HandleModMapDef(ModMapDef * def, + XkbDescPtr xkb, unsigned merge, SymbolsInfo * info) +{ + ExprDef *key; + ModMapEntry tmp; + ExprResult rtrn; + Bool ok; + + if (!LookupModIndex(NULL, None, def->modifier, TypeInt, &rtrn)) + { + ERROR("Illegal modifier map definition\n"); + ACTION1("Ignoring map for non-modifier \"%s\"\n", + XkbAtomText(NULL, def->modifier, XkbMessage)); + return False; + } + ok = True; + tmp.modifier = rtrn.uval; + for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) + { + if ((key->op == ExprValue) && (key->type == TypeKeyName)) + { + tmp.haveSymbol = False; + tmp.u.keyName = KeyNameToLong(key->value.keyName); + } + else if (ExprResolveKeySym(key, &rtrn, NULL, NULL)) + { + tmp.haveSymbol = True; + tmp.u.keySym = rtrn.uval; + } + else + { + ERROR("Modmap entries may contain only key names or keysyms\n"); + ACTION1("Illegal definition for %s modifier ignored\n", + XkbModIndexText(tmp.modifier, XkbMessage)); + continue; + } + + ok = AddModMapEntry(info, &tmp) && ok; + } + return ok; +} + +static void +HandleSymbolsFile(XkbFile * file, + XkbDescPtr xkb, unsigned merge, SymbolsInfo * info) +{ + ParseCommon *stmt; + + info->name = uStringDup(file->name); + stmt = file->defs; + while (stmt) + { + switch (stmt->stmtType) + { + case StmtInclude: + if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info, + HandleSymbolsFile)) + info->errorCount++; + break; + case StmtSymbolsDef: + if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info)) + info->errorCount++; + break; + case StmtVarDef: + if (!HandleSymbolsVar((VarDef *) stmt, xkb, info)) + info->errorCount++; + break; + case StmtVModDef: + if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods)) + info->errorCount++; + break; + case StmtInterpDef: + ERROR("Interpretation files may not include other types\n"); + ACTION("Ignoring definition of symbol interpretation\n"); + info->errorCount++; + break; + case StmtKeycodeDef: + ERROR("Interpretation files may not include other types\n"); + ACTION("Ignoring definition of key name\n"); + info->errorCount++; + break; + case StmtModMapDef: + if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info)) + info->errorCount++; + break; + default: + WSGO1("Unexpected statement type %d in HandleSymbolsFile\n", + stmt->stmtType); + break; + } + stmt = stmt->next; + if (info->errorCount > 10) + { +#ifdef NOISY + ERROR("Too many errors\n"); +#endif + ACTION1("Abandoning symbols file \"%s\"\n", file->topName); + break; + } + } + return; +} + +static Bool +FindKeyForSymbol(XkbDescPtr xkb, KeySym sym, unsigned int *kc_rtrn) +{ + register int i, j; + register Bool gotOne; + + j = 0; + do + { + gotOne = False; + for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) + { + if (j < (int) XkbKeyNumSyms(xkb, i)) + { + gotOne = True; + if (XkbKeySym(xkb, i, j) == sym) + { + *kc_rtrn = i; + return True; + } + } + } + j++; + } + while (gotOne); + return False; +} + +/** + * Find the given name in the xkb->map->types and return its index. + * + * @param name The atom to search for. + * @param type_rtrn Set to the index of the name if found. + * + * @return True if found, False otherwise. + */ +static Bool +FindNamedType(XkbDescPtr xkb, Atom name, unsigned *type_rtrn) +{ + register unsigned n; + + if (xkb && xkb->map && xkb->map->types) + { + for (n = 0; n < xkb->map->num_types; n++) + { + if (xkb->map->types[n].name == (Atom) name) + { + *type_rtrn = n; + return True; + } + } + } + return False; +} + +static Bool +KSIsLower(KeySym ks) +{ + KeySym lower, upper; + XConvertCase(ks, &lower, &upper); + + if (lower == upper) + return False; + return (ks == lower ? True : False); +} + +static Bool +KSIsUpper(KeySym ks) +{ + KeySym lower, upper; + XConvertCase(ks, &lower, &upper); + + if (lower == upper) + return False; + return (ks == upper ? True : False); +} + +/** + * Assign a type to the given sym and return the Atom for the type assigned. + * + * Simple recipe: + * - ONE_LEVEL for width 0/1 + * - ALPHABETIC for 2 shift levels, with lower/upercase + * - KEYPAD for keypad keys. + * - TWO_LEVEL for other 2 shift level keys. + * and the same for four level keys. + * + * @param width Number of sysms in syms. + * @param syms The keysyms for the given key (must be size width). + * @param typeNameRtrn Set to the Atom of the type name. + * + * @returns True if a type could be found, False otherwise. + */ +static Bool +FindAutomaticType(int width, KeySym * syms, Atom * typeNameRtrn, + Bool * autoType) +{ + *autoType = False; + if ((width == 1) || (width == 0)) + { + *typeNameRtrn = XkbInternAtom(NULL, "ONE_LEVEL", False); + *autoType = True; + } + else if (width == 2) + { + if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1])) + { + *typeNameRtrn = XkbInternAtom(NULL, "ALPHABETIC", False); + } + else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1]))) + { + *typeNameRtrn = XkbInternAtom(NULL, "KEYPAD", False); + *autoType = True; + } + else + { + *typeNameRtrn = XkbInternAtom(NULL, "TWO_LEVEL", False); + *autoType = True; + } + } + else if (width <= 4) + { + if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1])) + if (KSIsLower(syms[2]) && KSIsUpper(syms[3])) + *typeNameRtrn = + XkbInternAtom(NULL, "FOUR_LEVEL_ALPHABETIC", False); + else + *typeNameRtrn = XkbInternAtom(NULL, + "FOUR_LEVEL_SEMIALPHABETIC", + False); + + else if (syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1]))) + *typeNameRtrn = XkbInternAtom(NULL, "FOUR_LEVEL_KEYPAD", False); + else + *typeNameRtrn = XkbInternAtom(NULL, "FOUR_LEVEL", False); + /* XXX: why not set autoType here? */ + } + return ((width >= 0) && (width <= 4)); +} + +/** + * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the + * groups, and reduce to one group if all groups are identical anyway. + */ +static void +PrepareKeyDef(KeyInfo * key) +{ + int i, j, width, defined, lastGroup; + Bool identical; + + defined = key->symsDefined | key->actsDefined | key->typesDefined; + /* get highest group number */ + for (i = XkbNumKbdGroups - 1; i >= 0; i--) + { + if (defined & (1 << i)) + break; + } + lastGroup = i; + + if (lastGroup == 0) + return; + + /* If there are empty groups between non-empty ones fill them with data */ + /* from the first group. */ + /* We can make a wrong assumption here. But leaving gaps is worse. */ + for (i = lastGroup; i > 0; i--) + { + if (defined & (1 << i)) + continue; + width = key->numLevels[0]; + if (key->typesDefined & 1) + { + for (j = 0; j < width; j++) + { + key->types[i] = key->types[0]; + } + key->typesDefined |= 1 << i; + } + if ((key->actsDefined & 1) && key->acts[0]) + { + key->acts[i] = uTypedCalloc(width, XkbAction); + if (key->acts[i] == NULL) + continue; + memcpy((void *) key->acts[i], (void *) key->acts[0], + width * sizeof(XkbAction)); + key->actsDefined |= 1 << i; + } + if ((key->symsDefined & 1) && key->syms[0]) + { + key->syms[i] = uTypedCalloc(width, KeySym); + if (key->syms[i] == NULL) + continue; + memcpy((void *) key->syms[i], (void *) key->syms[0], + width * sizeof(KeySym)); + key->symsDefined |= 1 << i; + } + if (defined & 1) + { + key->numLevels[i] = key->numLevels[0]; + } + } + /* If all groups are completely identical remove them all */ + /* exept the first one. */ + identical = True; + for (i = lastGroup; i > 0; i--) + { + if ((key->numLevels[i] != key->numLevels[0]) || + (key->types[i] != key->types[0])) + { + identical = False; + break; + } + if ((key->syms[i] != key->syms[0]) && + (key->syms[i] == NULL || key->syms[0] == NULL || + memcmp((void *) key->syms[i], (void *) key->syms[0], + sizeof(KeySym) * key->numLevels[0]))) + { + identical = False; + break; + } + if ((key->acts[i] != key->acts[0]) && + (key->acts[i] == NULL || key->acts[0] == NULL || + memcmp((void *) key->acts[i], (void *) key->acts[0], + sizeof(XkbAction) * key->numLevels[0]))) + { + identical = False; + break; + } + } + if (identical) + { + for (i = lastGroup; i > 0; i--) + { + key->numLevels[i] = 0; + if (key->syms[i] != NULL) + uFree(key->syms[i]); + key->syms[i] = (KeySym *) NULL; + if (key->acts[i] != NULL) + uFree(key->acts[i]); + key->acts[i] = (XkbAction *) NULL; + key->types[i] = (Atom) 0; + } + key->symsDefined &= 1; + key->actsDefined &= 1; + key->typesDefined &= 1; + } + return; +} + +/** + * Copy the KeyInfo into result. + * + * This function recurses. + */ +static Bool +CopySymbolsDef(XkbFileInfo * result, KeyInfo * key, int start_from) +{ + register int i; + unsigned okc, kc, width, tmp, nGroups; + XkbKeyTypePtr type; + Bool haveActions, autoType, useAlias; + KeySym *outSyms; + XkbAction *outActs; + XkbDescPtr xkb; + unsigned types[XkbNumKbdGroups]; + + xkb = result->xkb; + useAlias = (start_from == 0); + + /* get the keycode for the key. */ + if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb), + start_from)) + { + if ((start_from == 0) && (warningLevel >= 5)) + { + WARN2("Key %s not found in %s keycodes\n", + longText(key->name, XkbMessage), + XkbAtomText(NULL, xkb->names->keycodes, XkbMessage)); + ACTION("Symbols ignored\n"); + } + return False; + } + + haveActions = False; + for (i = width = nGroups = 0; i < XkbNumKbdGroups; i++) + { + if (((i + 1) > nGroups) + && (((key->symsDefined | key->actsDefined) & (1 << i)) + || (key->typesDefined) & (1 << i))) + nGroups = i + 1; + if (key->acts[i]) + haveActions = True; + autoType = False; + /* Assign the type to the key, if it is missing. */ + if (key->types[i] == None) + { + if (key->dfltType != None) + key->types[i] = key->dfltType; + else if (FindAutomaticType(key->numLevels[i], key->syms[i], + &key->types[i], &autoType)) + { + } + else + { + if (warningLevel >= 5) + { + WARN1("No automatic type for %d symbols\n", + (unsigned int) key->numLevels[i]); + ACTION3("Using %s for the %s key (keycode %d)\n", + XkbAtomText(NULL, key->types[i], + XkbMessage), + longText(key->name, XkbMessage), kc); + } + } + } + if (FindNamedType(xkb, key->types[i], &types[i])) + { + if (!autoType || key->numLevels[i] > 2) + xkb->server->explicit[kc] |= (1 << i); + } + else + { + if (warningLevel >= 3) + { + WARN1("Type \"%s\" is not defined\n", + XkbAtomText(NULL, key->types[i], XkbMessage)); + ACTION2("Using TWO_LEVEL for the %s key (keycode %d)\n", + longText(key->name, XkbMessage), kc); + } + types[i] = XkbTwoLevelIndex; + } + /* if the type specifies less syms than the key has, shrink the key */ + type = &xkb->map->types[types[i]]; + if (type->num_levels < key->numLevels[i]) + { + if (warningLevel > 0) + { + WARN4 + ("Type \"%s\" has %d levels, but %s has %d symbols\n", + XkbAtomText(NULL, type->name, XkbMessage), + (unsigned int) type->num_levels, + longText(key->name, XkbMessage), + (unsigned int) key->numLevels[i]); + ACTION("Ignoring extra symbols\n"); + } + key->numLevels[i] = type->num_levels; + } + if (key->numLevels[i] > width) + width = key->numLevels[i]; + if (type->num_levels > width) + width = type->num_levels; + } + + /* width is now the largest width found */ + + i = width * nGroups; + outSyms = XkbResizeKeySyms(xkb, kc, i); + if (outSyms == NULL) + { + WSGO2("Could not enlarge symbols for %s (keycode %d)\n", + longText(key->name, XkbMessage), kc); + return False; + } + if (haveActions) + { + outActs = XkbResizeKeyActions(xkb, kc, i); + if (outActs == NULL) + { + WSGO2("Could not enlarge actions for %s (key %d)\n", + longText(key->name, XkbMessage), kc); + return False; + } + xkb->server->explicit[kc] |= XkbExplicitInterpretMask; + } + else + outActs = NULL; + if (key->defs.defined & _Key_GroupInfo) + i = key->groupInfo; + else + i = xkb->map->key_sym_map[kc].group_info; + + xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups); + xkb->map->key_sym_map[kc].width = width; + for (i = 0; i < nGroups; i++) + { + /* assign kt_index[i] to the index of the type in map->types. + * kt_index[i] may have been set by a previous run (if we have two + * layouts specified). Let's not overwrite it with the ONE_LEVEL + * default group if we dont even have keys for this group anyway. + * + * FIXME: There should be a better fix for this. + */ + if (key->numLevels[i]) + xkb->map->key_sym_map[kc].kt_index[i] = types[i]; + if (key->syms[i] != NULL) + { + /* fill key to "width" symbols*/ + for (tmp = 0; tmp < width; tmp++) + { + if (tmp < key->numLevels[i]) + outSyms[tmp] = key->syms[i][tmp]; + else + outSyms[tmp] = NoSymbol; + if ((outActs != NULL) && (key->acts[i] != NULL)) + { + if (tmp < key->numLevels[i]) + outActs[tmp] = key->acts[i][tmp]; + else + outActs[tmp].type = XkbSA_NoAction; + } + } + } + outSyms += width; + if (outActs) + outActs += width; + } + switch (key->behavior.type & XkbKB_OpMask) + { + case XkbKB_Default: + break; + case XkbKB_Overlay1: + case XkbKB_Overlay2: + /* find key by name! */ + if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True, + CreateKeyNames(xkb), 0)) + { + if (warningLevel >= 1) + { + WARN2("Key %s not found in %s keycodes\n", + longText(key->nameForOverlayKey, XkbMessage), + XkbAtomText(NULL, xkb->names->keycodes, XkbMessage)); + ACTION1("Not treating %s as an overlay key \n", + longText(key->name, XkbMessage)); + } + break; + } + key->behavior.data = okc; + default: + xkb->server->behaviors[kc] = key->behavior; + xkb->server->explicit[kc] |= XkbExplicitBehaviorMask; + break; + } + if (key->defs.defined & _Key_VModMap) + { + xkb->server->vmodmap[kc] = key->vmodmap; + xkb->server->explicit[kc] |= XkbExplicitVModMapMask; + } + if (key->repeat != RepeatUndefined) + { + if (key->repeat == RepeatYes) + xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8)); + else + xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8)); + xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask; + } + + /* do the same thing for the next key */ + CopySymbolsDef(result, key, kc + 1); + return True; +} + +static Bool +CopyModMapDef(XkbFileInfo * result, ModMapEntry * entry) +{ + unsigned kc; + XkbDescPtr xkb; + + xkb = result->xkb; + if ((!entry->haveSymbol) + && + (!FindNamedKey + (xkb, entry->u.keyName, &kc, True, CreateKeyNames(xkb), 0))) + { + if (warningLevel >= 5) + { + WARN2("Key %s not found in %s keycodes\n", + longText(entry->u.keyName, XkbMessage), + XkbAtomText(NULL, xkb->names->keycodes, XkbMessage)); + ACTION1("Modifier map entry for %s not updated\n", + XkbModIndexText(entry->modifier, XkbMessage)); + } + return False; + } + else if (entry->haveSymbol + && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc))) + { + if (warningLevel > 5) + { + WARN2("Key \"%s\" not found in %s symbol map\n", + XkbKeysymText(entry->u.keySym, XkbMessage), + XkbAtomText(NULL, xkb->names->symbols, XkbMessage)); + ACTION1("Modifier map entry for %s not updated\n", + XkbModIndexText(entry->modifier, XkbMessage)); + } + return False; + } + xkb->map->modmap[kc] |= (1 << entry->modifier); + return True; +} + +/** + * Handle the xkb_symbols section of an xkb file. + * + * @param file The parsed xkb_symbols section of the xkb file. + * @param result Handle to the data to store the result in. + * @param merge Merge strategy (e.g. MergeOverride). + */ +Bool +CompileSymbols(XkbFile * file, XkbFileInfo * result, unsigned merge) +{ + register int i; + SymbolsInfo info; + XkbDescPtr xkb; + + xkb = result->xkb; + InitSymbolsInfo(&info, xkb); + info.dflt.defs.fileID = file->id; + info.dflt.defs.merge = merge; + HandleSymbolsFile(file, xkb, merge, &info); + + if (info.nKeys == 0) + return True; + if (info.errorCount == 0) + { + KeyInfo *key; + + /* alloc memory in the xkb struct */ + if (XkbAllocNames(xkb, XkbSymbolsNameMask | XkbGroupNamesMask, 0, 0) + != Success) + { + WSGO("Can not allocate names in CompileSymbols\n"); + ACTION("Symbols not added\n"); + return False; + } + if (XkbAllocClientMap(xkb, XkbKeySymsMask | XkbModifierMapMask, 0) + != Success) + { + WSGO("Could not allocate client map in CompileSymbols\n"); + ACTION("Symbols not added\n"); + return False; + } + if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, 32) != Success) + { + WSGO("Could not allocate server map in CompileSymbols\n"); + ACTION("Symbols not added\n"); + return False; + } + if (XkbAllocControls(xkb, XkbPerKeyRepeatMask) != Success) + { + WSGO("Could not allocate controls in CompileSymbols\n"); + ACTION("Symbols not added\n"); + return False; + } + + /* now copy info into xkb. */ + xkb->names->symbols = XkbInternAtom(xkb->dpy, info.name, False); + if (info.aliases) + ApplyAliases(xkb, False, &info.aliases); + for (i = 0; i < XkbNumKbdGroups; i++) + { + if (info.groupNames[i] != None) + xkb->names->groups[i] = info.groupNames[i]; + } + /* sanitize keys */ + for (key = info.keys, i = 0; i < info.nKeys; i++, key++) + { + PrepareKeyDef(key); + } + /* copy! */ + for (key = info.keys, i = 0; i < info.nKeys; i++, key++) + { + if (!CopySymbolsDef(result, key, 0)) + info.errorCount++; + } + if (warningLevel > 3) + { + for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) + { + if (xkb->names->keys[i].name[0] == '\0') + continue; + if (XkbKeyNumGroups(xkb, i) < 1) + { + char buf[5]; + memcpy(buf, xkb->names->keys[i].name, 4); + buf[4] = '\0'; + WARN2 + ("No symbols defined for <%s> (keycode %d)\n", + buf, i); + } + } + } + if (info.modMap) + { + ModMapEntry *mm, *next; + for (mm = info.modMap; mm != NULL; mm = next) + { + if (!CopyModMapDef(result, mm)) + info.errorCount++; + next = (ModMapEntry *) mm->defs.next; + } + } + return True; + } + return False; +} diff --git a/xkbcomp/utils.h b/xkbcomp/utils.h index 61a598734..63eda3632 100644 --- a/xkbcomp/utils.h +++ b/xkbcomp/utils.h @@ -159,7 +159,7 @@ uInformation(const char * /* s */ , ... #define FATAL uFatalError extern void uFatalError(const char * /* s */ , ... - ) _X_ATTRIBUTE_PRINTF(1, 2); + ) _X_ATTRIBUTE_PRINTF(1, 2) _X_NORETURN; /* WSGO stands for "Weird Stuff Going On" */ #define WSGO6 uInternalError @@ -196,6 +196,7 @@ uInformation(const char * /* s */ , ... (s1)!=(s2):strcmp(s1,s2)) #define uStrCaseEqual(s1,s2) (uStrCaseCmp(s1,s2)==0) #ifdef HAVE_STRCASECMP +#include #define uStrCaseCmp(s1,s2) (strcasecmp(s1,s2)) #define uStrCasePrefix(p,s) (strncasecmp(p,s,strlen(p))==0) #else @@ -207,6 +208,7 @@ uInformation(const char * /* s */ , ... ); #endif #ifdef HAVE_STRDUP +#include #define uStringDup(s1) ((s1) ? strdup(s1) : NULL) #else extern char *uStringDup(const char * /* s1 */ diff --git a/xkbcomp/xkbcomp.c b/xkbcomp/xkbcomp.c index 2a3e8f48a..063ae8741 100644 --- a/xkbcomp/xkbcomp.c +++ b/xkbcomp/xkbcomp.c @@ -653,25 +653,25 @@ parseArgs(int argc, char *argv[]) len = strlen(inputFile); if (inputFile[len - 1] == ')') { - char *tmp; - if ((tmp = strchr(inputFile, '(')) != NULL) + char *tmpstr; + if ((tmpstr = strchr(inputFile, '(')) != NULL) { - *tmp = '\0'; + *tmpstr = '\0'; inputFile[len - 1] = '\0'; - tmp++; - if (*tmp == '\0') + tmpstr++; + if (*tmpstr == '\0') { WARN("Empty map in filename\n"); ACTION("Ignored\n"); } else if (inputMap == NULL) { - inputMap = uStringDup(tmp); + inputMap = uStringDup(tmpstr); } else { WARN("Map specified in filename and with -m flag\n"); - ACTION1("map from name (\"%s\") ignored\n", tmp); + ACTION1("map from name (\"%s\") ignored\n", tmpstr); } } else -- cgit v1.2.3