aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libxcb/configure.ac533
-rw-r--r--mesalib/include/EGL/eglext.h796
-rw-r--r--mesalib/src/glsl/SConscript346
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp6960
-rw-r--r--mesalib/src/glsl/glcpp/glcpp-lex.l644
-rw-r--r--mesalib/src/glsl/glcpp/glcpp.c252
-rw-r--r--mesalib/src/glsl/glsl_lexer.ll4
-rw-r--r--mesalib/src/mesa/sources.mak741
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c3869
-rw-r--r--xorg-server/xkeyboard-config/rules/base.xml.in12350
-rw-r--r--xorg-server/xkeyboard-config/symbols/Makefile.am82
-rw-r--r--xorg-server/xkeyboard-config/symbols/tw73
12 files changed, 13414 insertions, 13236 deletions
diff --git a/libxcb/configure.ac b/libxcb/configure.ac
index a8e171b07..fc9f17ef6 100644
--- a/libxcb/configure.ac
+++ b/libxcb/configure.ac
@@ -1,259 +1,274 @@
-# -*- Autoconf -*-
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ(2.57)
-AC_INIT([libxcb],
- 1.7,
- [xcb@lists.freedesktop.org])
-AC_CONFIG_SRCDIR([xcb.pc.in])
-AM_INIT_AUTOMAKE([foreign dist-bzip2])
-
-AM_PATH_PYTHON([2.5])
-
-PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=yes], [HAVE_CHECK=no])
-AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes)
-
-AC_CONFIG_HEADERS([src/config.h])
-
-AC_LIBTOOL_WIN32_DLL
-AC_PROG_LIBTOOL
-AC_PROG_CC
-
-AC_PATH_PROG(XSLTPROC, xsltproc, no)
-if test "$XSLTPROC" = "no"; then
- AC_MSG_ERROR([XCB requires xsltproc.])
-fi
-
-HTML_CHECK_RESULT=false
-if test x"$HAVE_CHECK" = xyes; then
- if test x"$XSLTPROC" != xno; then
- HTML_CHECK_RESULT=true
- fi
-fi
-AC_SUBST(HTML_CHECK_RESULT)
-
-# Checks for pkg-config packages
-PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.6)
-NEEDED="pthread-stubs xau >= 0.99.2"
-PKG_CHECK_MODULES(NEEDED, $NEEDED)
-
-have_xdmcp="no"
-PKG_CHECK_MODULES(XDMCP, xdmcp,
- AC_CHECK_LIB(Xdmcp, XdmcpWrap,
- [
- AC_DEFINE(HASXDMAUTH,1,[Has Wraphelp.c needed for XDM AUTH protocols])
- NEEDED="$NEEDED xdmcp"
- have_xdmcp="yes"
- ],
- [
- XDMCP_CFLAGS=
- XDMCP_LIBS=
- ], [$XDMCP_LIBS]),
- [AC_MSG_RESULT(no)])
-
-AC_SUBST(NEEDED)
-
-# Find the xcb-proto protocol descriptions
-AC_MSG_CHECKING(XCBPROTO_XCBINCLUDEDIR)
-XCBPROTO_XCBINCLUDEDIR=`$PKG_CONFIG --variable=xcbincludedir xcb-proto`
-AC_MSG_RESULT($XCBPROTO_XCBINCLUDEDIR)
-AC_SUBST(XCBPROTO_XCBINCLUDEDIR)
-
-# Find the xcb-proto version
-XCBPROTO_VERSION=`$PKG_CONFIG --modversion xcb-proto`
-AC_SUBST(XCBPROTO_VERSION)
-
-# Find the xcbgen Python package
-AC_MSG_CHECKING(XCBPROTO_XCBPYTHONDIR)
-XCBPROTO_XCBPYTHONDIR=`$PKG_CONFIG --variable=pythondir xcb-proto`
-AC_MSG_RESULT($XCBPROTO_XCBPYTHONDIR)
-AC_SUBST(XCBPROTO_XCBPYTHONDIR)
-
-AC_HEADER_STDC
-AC_SEARCH_LIBS(getaddrinfo, socket)
-AC_SEARCH_LIBS(connect, socket)
-
-have_win32="no"
-lt_enable_auto_import=""
-case $host_os in
-mingw*)
- have_win32="yes"
- lt_enable_auto_import="-Wl,--enable-auto-import"
- ;;
-linux*)
- AC_DEFINE([HAVE_ABSTRACT_SOCKETS], 1, [Define if your platform supports abstract sockets])
- ;;
-esac
-
-AC_SUBST(lt_enable_auto_import)
-AM_CONDITIONAL([XCB_HAVE_WIN32], [test "x${have_win32}" = "xyes"])
-
-dnl define buffer queue size
-AC_ARG_WITH([queue-size],
- AC_HELP_STRING([--with-queue-size=SIZE],
- [Set the XCB buffer queue size (default is 16384)]),
- [xcb_queue_buffer_size="$withval"],
- [xcb_queue_buffer_size=16384])
-AC_DEFINE_UNQUOTED(XCB_QUEUE_BUFFER_SIZE, [$xcb_queue_buffer_size],
- [XCB buffer queue size])
-
-dnl check for the sockaddr_un.sun_len member
-AC_CHECK_MEMBER([struct sockaddr_un.sun_len],
- [AC_DEFINE(HAVE_SOCKADDR_SUN_LEN,1,[Have the sockaddr_un.sun_len member.])],
- [],
- [ #include <sys/types.h>
- #include <sys/un.h>
- ])
-
-xcbincludedir='${includedir}/xcb'
-AC_SUBST(xcbincludedir)
-
-if test "x$GCC" = xyes ; then
- CWARNFLAGS="-Wall -pedantic -Wpointer-arith \
- -Wstrict-prototypes -Wmissing-declarations -Wnested-externs"
-else
- AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
- if test "x$SUNCC" = "xyes"; then
- CWARNFLAGS="-v"
- fi
-fi
-AC_SUBST(CWARNFLAGS)
-
-XCB_CHECK_VISIBILITY()
-
-# htmldir is not defined prior to autoconf 2.59c, so on earlier versions
-# set an equivalent value.
-AC_PREREQ([2.59c], [], [AC_SUBST([htmldir], [m4_ifset([AC_PACKAGE_TARNAME],
- ['${datadir}/doc/${PACKAGE_TARNAME}'],
- ['${datadir}/doc/${PACKAGE}'])
-])])
-
-XCB_CHECK_DOXYGEN()
-
-case $host_os in
- # darwin has poll() but can't be used to poll character devices (atleast through SnowLeopard)
- darwin*) ;;
- *)
- AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], )
- ;;
-esac
-
-XCB_EXTENSION(Composite, "yes")
-XCB_EXTENSION(Damage, "yes")
-XCB_EXTENSION(DPMS, "yes")
-XCB_EXTENSION(DRI2, "yes")
-XCB_EXTENSION(GLX, "yes")
-XCB_EXTENSION(RandR, "yes")
-XCB_EXTENSION(Record, "yes")
-XCB_EXTENSION(Render, "yes")
-XCB_EXTENSION(Resource, "yes")
-XCB_EXTENSION(Screensaver, "yes")
-XCB_EXTENSION(Shape, "yes")
-XCB_EXTENSION(Shm, "yes")
-XCB_EXTENSION(Sync, "yes")
-XCB_EXTENSION(Xevie, "yes")
-XCB_EXTENSION(XFixes, "yes")
-XCB_EXTENSION(XFree86-DRI, "yes")
-XCB_EXTENSION(Xinerama, "yes")
-XCB_EXTENSION(XInput, "no")
-XCB_EXTENSION(XKB, "no")
-XCB_EXTENSION(Xprint, "yes")
-XCB_EXTENSION(SELinux, "no")
-XCB_EXTENSION(XTest, "yes")
-XCB_EXTENSION(Xv, "yes")
-XCB_EXTENSION(XvMC, "yes")
-
-AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto])
-if test "x$LAUNCHD" = xauto; then
- unset LAUNCHD
- AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin])
-fi
-
-if test "x$LAUNCHD" = xyes ; then
- AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available])
-fi
-
-AC_CONFIG_FILES([
-Makefile
-doc/Makefile
-src/Makefile
-tests/Makefile
-])
-
-AC_CONFIG_FILES([
-xcb.pc
-xcb-composite.pc
-xcb-damage.pc
-xcb-dpms.pc
-xcb-dri2.pc
-xcb-glx.pc
-xcb-randr.pc
-xcb-record.pc
-xcb-render.pc
-xcb-res.pc
-xcb-screensaver.pc
-xcb-shape.pc
-xcb-shm.pc
-xcb-sync.pc
-xcb-xevie.pc
-xcb-xf86dri.pc
-xcb-xfixes.pc
-xcb-xinerama.pc
-xcb-xinput.pc
-xcb-xkb.pc
-xcb-xprint.pc
-xcb-xselinux.pc
-xcb-xtest.pc
-xcb-xv.pc
-xcb-xvmc.pc
-])
-
-AC_CONFIG_FILES([
-doc/xcb.doxygen
-])
-
-AC_OUTPUT
-
-dnl Configuration output
-
-echo ""
-echo " Package: ${PACKAGE_NAME} ${PACKAGE_VERSION}"
-echo ""
-echo " Configuration"
-echo " XDM support.........: ${have_xdmcp}"
-echo " Build unit tests....: ${HAVE_CHECK}"
-echo " XCB buffer size.....: ${xcb_queue_buffer_size}"
-echo ""
-echo " X11 extensions"
-echo " Composite...........: ${BUILD_COMPOSITE}"
-echo " Damage..............: ${BUILD_DAMAGE}"
-echo " Dpms................: ${BUILD_DPMS}"
-echo " Dri2................: ${BUILD_DRI2}"
-echo " Glx.................: ${BUILD_GLX}"
-echo " Randr...............: ${BUILD_RANDR}"
-echo " Record..............: ${BUILD_RECORD}"
-echo " Render..............: ${BUILD_RENDER}"
-echo " Resource............: ${BUILD_RESOURCE}"
-echo " Screensaver.........: ${BUILD_SCREENSAVER}"
-echo " selinux.............: ${BUILD_SELINUX}"
-echo " Shape...............: ${BUILD_SHAPE}"
-echo " Shm.................: ${BUILD_SHM}"
-echo " Sync................: ${BUILD_SYNC}"
-echo " Xevie...............: ${BUILD_XEVIE}"
-echo " Xfixes..............: ${BUILD_XFIXES}"
-echo " Xfree86-dri.........: ${BUILD_XFREE86_DRI}"
-echo " xinerama............: ${BUILD_XINERAMA}"
-echo " xinput..............: ${BUILD_XINPUT}"
-echo " xprint..............: ${BUILD_XPRINT}"
-echo " xtest...............: ${BUILD_XTEST}"
-echo " xv..................: ${BUILD_XV}"
-echo " xvmc................: ${BUILD_XVMC}"
-echo ""
-echo " Used CFLAGS:"
-echo " CPPFLAGS............: ${CPPFLAGS}"
-echo " CFLAGS..............: ${CFLAGS}"
-echo " Warning CFLAGS......: ${CWARNFLAGS}"
-echo ""
-echo " Installation:"
-echo " Prefix..............: ${prefix}"
-echo ""
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.57)
+AC_INIT([libxcb],
+ 1.7,
+ [xcb@lists.freedesktop.org])
+AC_CONFIG_SRCDIR([xcb.pc.in])
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+
+AM_PATH_PYTHON([2.5])
+
+PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=yes], [HAVE_CHECK=no])
+AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes)
+
+AC_CONFIG_HEADERS([src/config.h])
+
+AC_LIBTOOL_WIN32_DLL
+AC_PROG_LIBTOOL
+AC_PROG_CC
+
+AC_PATH_PROG(XSLTPROC, xsltproc, no)
+if test "$XSLTPROC" = "no"; then
+ AC_MSG_ERROR([XCB requires xsltproc.])
+fi
+
+HTML_CHECK_RESULT=false
+if test x"$HAVE_CHECK" = xyes; then
+ if test x"$XSLTPROC" != xno; then
+ HTML_CHECK_RESULT=true
+ fi
+fi
+AC_SUBST(HTML_CHECK_RESULT)
+
+# Checks for pkg-config packages
+PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.6)
+NEEDED="pthread-stubs xau >= 0.99.2"
+PKG_CHECK_MODULES(NEEDED, $NEEDED)
+
+have_xdmcp="no"
+PKG_CHECK_MODULES(XDMCP, xdmcp,
+ AC_CHECK_LIB(Xdmcp, XdmcpWrap,
+ [
+ AC_DEFINE(HASXDMAUTH,1,[Has Wraphelp.c needed for XDM AUTH protocols])
+ NEEDED="$NEEDED xdmcp"
+ have_xdmcp="yes"
+ ],
+ [
+ XDMCP_CFLAGS=
+ XDMCP_LIBS=
+ ], [$XDMCP_LIBS]),
+ [AC_MSG_RESULT(no)])
+
+AC_SUBST(NEEDED)
+
+# Find the xcb-proto protocol descriptions
+AC_MSG_CHECKING(XCBPROTO_XCBINCLUDEDIR)
+XCBPROTO_XCBINCLUDEDIR=`$PKG_CONFIG --variable=xcbincludedir xcb-proto`
+AC_MSG_RESULT($XCBPROTO_XCBINCLUDEDIR)
+AC_SUBST(XCBPROTO_XCBINCLUDEDIR)
+
+# Find the xcb-proto version
+XCBPROTO_VERSION=`$PKG_CONFIG --modversion xcb-proto`
+AC_SUBST(XCBPROTO_VERSION)
+
+# Find the xcbgen Python package
+AC_MSG_CHECKING(XCBPROTO_XCBPYTHONDIR)
+XCBPROTO_XCBPYTHONDIR=`$PKG_CONFIG --variable=pythondir xcb-proto`
+AC_MSG_RESULT($XCBPROTO_XCBPYTHONDIR)
+AC_SUBST(XCBPROTO_XCBPYTHONDIR)
+
+AC_HEADER_STDC
+AC_SEARCH_LIBS(getaddrinfo, socket)
+AC_SEARCH_LIBS(connect, socket)
+
+have_win32="no"
+lt_enable_auto_import=""
+case $host_os in
+mingw*)
+ have_win32="yes"
+ lt_enable_auto_import="-Wl,--enable-auto-import"
+ ;;
+linux*)
+ AC_DEFINE([HAVE_ABSTRACT_SOCKETS], 1, [Define if your platform supports abstract sockets])
+ ;;
+esac
+
+AC_SUBST(lt_enable_auto_import)
+AM_CONDITIONAL([XCB_HAVE_WIN32], [test "x${have_win32}" = "xyes"])
+
+dnl define buffer queue size
+AC_ARG_WITH([queue-size],
+ AC_HELP_STRING([--with-queue-size=SIZE],
+ [Set the XCB buffer queue size (default is 16384)]),
+ [xcb_queue_buffer_size="$withval"],
+ [xcb_queue_buffer_size=16384])
+AC_DEFINE_UNQUOTED(XCB_QUEUE_BUFFER_SIZE, [$xcb_queue_buffer_size],
+ [XCB buffer queue size])
+
+dnl check for the sockaddr_un.sun_len member
+AC_CHECK_MEMBER([struct sockaddr_un.sun_len],
+ [AC_DEFINE(HAVE_SOCKADDR_SUN_LEN,1,[Have the sockaddr_un.sun_len member.])],
+ [],
+ [ #include <sys/types.h>
+ #include <sys/un.h>
+ ])
+
+xcbincludedir='${includedir}/xcb'
+AC_SUBST(xcbincludedir)
+
+if test "x$GCC" = xyes ; then
+ CWARNFLAGS="-Wall -pedantic -Wpointer-arith \
+ -Wstrict-prototypes -Wmissing-declarations -Wnested-externs"
+else
+ AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
+ if test "x$SUNCC" = "xyes"; then
+ CWARNFLAGS="-v"
+ fi
+fi
+AC_SUBST(CWARNFLAGS)
+
+XCB_CHECK_VISIBILITY()
+
+# htmldir is not defined prior to autoconf 2.59c, so on earlier versions
+# set an equivalent value.
+AC_PREREQ([2.59c], [], [AC_SUBST([htmldir], [m4_ifset([AC_PACKAGE_TARNAME],
+ ['${datadir}/doc/${PACKAGE_TARNAME}'],
+ ['${datadir}/doc/${PACKAGE}'])
+])])
+
+XCB_CHECK_DOXYGEN()
+
+case $host_os in
+ # darwin through Snow Leopard has poll() but can't be used to poll character devices.
+ darwin@<:@789@:>@*|darwin10*) ;;
+ darwin*)
+ _ac_xorg_macosx_version_min=""
+ if echo $CPPFLAGS $CFLAGS | grep -q mmacosx-version-min ; then
+ _ac_xorg_macosx_version_min=`echo $CPPFLAGS $CFLAGS | sed 's/^.*-mmacosx-version-min=\(@<:@^ @:>@*\).*$/\1/'`
+ else
+ _ac_xorg_macosx_version_min=$MACOSX_DEPLOYMENT_TARGET
+ fi
+ case $_ac_xorg_macosx_version_min in
+ 10.@<:@0123456@:>@|10.@<:@0123456@:>@.*) ;;
+ *)
+ AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], )
+ ;;
+ esac
+ unset _ac_xorg_macosx_version_min
+ ;;
+ *)
+ AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], )
+ ;;
+esac
+
+XCB_EXTENSION(Composite, "yes")
+XCB_EXTENSION(Damage, "yes")
+XCB_EXTENSION(DPMS, "yes")
+XCB_EXTENSION(DRI2, "yes")
+XCB_EXTENSION(GLX, "yes")
+XCB_EXTENSION(RandR, "yes")
+XCB_EXTENSION(Record, "yes")
+XCB_EXTENSION(Render, "yes")
+XCB_EXTENSION(Resource, "yes")
+XCB_EXTENSION(Screensaver, "yes")
+XCB_EXTENSION(Shape, "yes")
+XCB_EXTENSION(Shm, "yes")
+XCB_EXTENSION(Sync, "yes")
+XCB_EXTENSION(Xevie, "yes")
+XCB_EXTENSION(XFixes, "yes")
+XCB_EXTENSION(XFree86-DRI, "yes")
+XCB_EXTENSION(Xinerama, "yes")
+XCB_EXTENSION(XInput, "no")
+XCB_EXTENSION(XKB, "no")
+XCB_EXTENSION(Xprint, "yes")
+XCB_EXTENSION(SELinux, "no")
+XCB_EXTENSION(XTest, "yes")
+XCB_EXTENSION(Xv, "yes")
+XCB_EXTENSION(XvMC, "yes")
+
+AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto])
+if test "x$LAUNCHD" = xauto; then
+ unset LAUNCHD
+ AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin])
+fi
+
+if test "x$LAUNCHD" = xyes ; then
+ AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available])
+fi
+
+AC_CONFIG_FILES([
+Makefile
+doc/Makefile
+src/Makefile
+tests/Makefile
+])
+
+AC_CONFIG_FILES([
+xcb.pc
+xcb-composite.pc
+xcb-damage.pc
+xcb-dpms.pc
+xcb-dri2.pc
+xcb-glx.pc
+xcb-randr.pc
+xcb-record.pc
+xcb-render.pc
+xcb-res.pc
+xcb-screensaver.pc
+xcb-shape.pc
+xcb-shm.pc
+xcb-sync.pc
+xcb-xevie.pc
+xcb-xf86dri.pc
+xcb-xfixes.pc
+xcb-xinerama.pc
+xcb-xinput.pc
+xcb-xkb.pc
+xcb-xprint.pc
+xcb-xselinux.pc
+xcb-xtest.pc
+xcb-xv.pc
+xcb-xvmc.pc
+])
+
+AC_CONFIG_FILES([
+doc/xcb.doxygen
+])
+
+AC_OUTPUT
+
+dnl Configuration output
+
+echo ""
+echo " Package: ${PACKAGE_NAME} ${PACKAGE_VERSION}"
+echo ""
+echo " Configuration"
+echo " XDM support.........: ${have_xdmcp}"
+echo " Build unit tests....: ${HAVE_CHECK}"
+echo " XCB buffer size.....: ${xcb_queue_buffer_size}"
+echo ""
+echo " X11 extensions"
+echo " Composite...........: ${BUILD_COMPOSITE}"
+echo " Damage..............: ${BUILD_DAMAGE}"
+echo " Dpms................: ${BUILD_DPMS}"
+echo " Dri2................: ${BUILD_DRI2}"
+echo " Glx.................: ${BUILD_GLX}"
+echo " Randr...............: ${BUILD_RANDR}"
+echo " Record..............: ${BUILD_RECORD}"
+echo " Render..............: ${BUILD_RENDER}"
+echo " Resource............: ${BUILD_RESOURCE}"
+echo " Screensaver.........: ${BUILD_SCREENSAVER}"
+echo " selinux.............: ${BUILD_SELINUX}"
+echo " Shape...............: ${BUILD_SHAPE}"
+echo " Shm.................: ${BUILD_SHM}"
+echo " Sync................: ${BUILD_SYNC}"
+echo " Xevie...............: ${BUILD_XEVIE}"
+echo " Xfixes..............: ${BUILD_XFIXES}"
+echo " Xfree86-dri.........: ${BUILD_XFREE86_DRI}"
+echo " xinerama............: ${BUILD_XINERAMA}"
+echo " xinput..............: ${BUILD_XINPUT}"
+echo " xprint..............: ${BUILD_XPRINT}"
+echo " xtest...............: ${BUILD_XTEST}"
+echo " xv..................: ${BUILD_XV}"
+echo " xvmc................: ${BUILD_XVMC}"
+echo ""
+echo " Used CFLAGS:"
+echo " CPPFLAGS............: ${CPPFLAGS}"
+echo " CFLAGS..............: ${CFLAGS}"
+echo " Warning CFLAGS......: ${CWARNFLAGS}"
+echo ""
+echo " Installation:"
+echo " Prefix..............: ${prefix}"
+echo ""
diff --git a/mesalib/include/EGL/eglext.h b/mesalib/include/EGL/eglext.h
index bae966f1e..4a789c607 100644
--- a/mesalib/include/EGL/eglext.h
+++ b/mesalib/include/EGL/eglext.h
@@ -1,398 +1,398 @@
-#ifndef __eglext_h_
-#define __eglext_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
-** Copyright (c) 2007-2010 The Khronos Group Inc.
-**
-** Permission is hereby granted, free of charge, to any person obtaining a
-** copy of this software and/or associated documentation files (the
-** "Materials"), to deal in the Materials without restriction, including
-** without limitation the rights to use, copy, modify, merge, publish,
-** distribute, sublicense, and/or sell copies of the Materials, and to
-** permit persons to whom the Materials are 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 Materials.
-**
-** THE MATERIALS ARE 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
-** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
-*/
-
-#include <EGL/eglplatform.h>
-
-/*************************************************************/
-
-/* Header file version number */
-/* Current version at http://www.khronos.org/registry/egl/ */
-/* $Revision$ on $Date: 2010-07-27 20:12:35 -0700 (Tue, 27 Jul 2010) $ */
-#define EGL_EGLEXT_VERSION 7
-
-#ifndef EGL_KHR_config_attribs
-#define EGL_KHR_config_attribs 1
-#define EGL_CONFORMANT_KHR 0x3042 /* EGLConfig attribute */
-#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 /* EGL_SURFACE_TYPE bitfield */
-#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 /* EGL_SURFACE_TYPE bitfield */
-#endif
-
-#ifndef EGL_KHR_lock_surface
-#define EGL_KHR_lock_surface 1
-#define EGL_READ_SURFACE_BIT_KHR 0x0001 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
-#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
-#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 /* EGL_SURFACE_TYPE bitfield */
-#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 /* EGL_SURFACE_TYPE bitfield */
-#define EGL_MATCH_FORMAT_KHR 0x3043 /* EGLConfig attribute */
-#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 /* EGL_MATCH_FORMAT_KHR value */
-#define EGL_FORMAT_RGB_565_KHR 0x30C1 /* EGL_MATCH_FORMAT_KHR value */
-#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 /* EGL_MATCH_FORMAT_KHR value */
-#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 /* EGL_MATCH_FORMAT_KHR value */
-#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 /* eglLockSurfaceKHR attribute */
-#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 /* eglLockSurfaceKHR attribute */
-#define EGL_BITMAP_POINTER_KHR 0x30C6 /* eglQuerySurface attribute */
-#define EGL_BITMAP_PITCH_KHR 0x30C7 /* eglQuerySurface attribute */
-#define EGL_BITMAP_ORIGIN_KHR 0x30C8 /* eglQuerySurface attribute */
-#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 /* eglQuerySurface attribute */
-#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA /* eglQuerySurface attribute */
-#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB /* eglQuerySurface attribute */
-#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC /* eglQuerySurface attribute */
-#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD /* eglQuerySurface attribute */
-#define EGL_LOWER_LEFT_KHR 0x30CE /* EGL_BITMAP_ORIGIN_KHR value */
-#define EGL_UPPER_LEFT_KHR 0x30CF /* EGL_BITMAP_ORIGIN_KHR value */
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface);
-#endif
-
-#ifndef EGL_KHR_image
-#define EGL_KHR_image 1
-#define EGL_NATIVE_PIXMAP_KHR 0x30B0 /* eglCreateImageKHR target */
-typedef void *EGLImageKHR;
-#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
-#endif
-
-#ifndef EGL_KHR_vg_parent_image
-#define EGL_KHR_vg_parent_image 1
-#define EGL_VG_PARENT_IMAGE_KHR 0x30BA /* eglCreateImageKHR target */
-#endif
-
-#ifndef EGL_KHR_gl_texture_2D_image
-#define EGL_KHR_gl_texture_2D_image 1
-#define EGL_GL_TEXTURE_2D_KHR 0x30B1 /* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC /* eglCreateImageKHR attribute */
-#endif
-
-#ifndef EGL_KHR_gl_texture_cubemap_image
-#define EGL_KHR_gl_texture_cubemap_image 1
-#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 /* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 /* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 /* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 /* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 /* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 /* eglCreateImageKHR target */
-#endif
-
-#ifndef EGL_KHR_gl_texture_3D_image
-#define EGL_KHR_gl_texture_3D_image 1
-#define EGL_GL_TEXTURE_3D_KHR 0x30B2 /* eglCreateImageKHR target */
-#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD /* eglCreateImageKHR attribute */
-#endif
-
-#ifndef EGL_KHR_gl_renderbuffer_image
-#define EGL_KHR_gl_renderbuffer_image 1
-#define EGL_GL_RENDERBUFFER_KHR 0x30B9 /* eglCreateImageKHR target */
-#endif
-
-#ifndef EGL_MESA_drm_image
-#define EGL_MESA_drm_image 1
-#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 /* eglCreateImageKHR attribute */
-#define EGL_DRM_BUFFER_USE_MESA 0x31D1
-
-/* EGL_DRM_BUFFER_FORMAT_MESA tokens */
-#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
-
-/* EGL_DRM_BUFFER_USE_MESA bits */
-#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x0001
-#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x0002
-
-#define EGL_DRM_BUFFER_MESA 0x31D3 /* eglCreateImageKHR target */
-#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 /* eglCreateImageKHR attribute */
-
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
-#endif
-typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESA) (EGLDisplay dpy, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESA) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
-#endif
-
-#ifndef EGL_WL_bind_wayland_display
-#define EGL_WL_bind_wayland_display 1
-
-#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */
-struct wl_display;
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
-EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
-#else
-typedef EGLBoolean (EGLAPIENTRY PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
-typedef EGLBoolean (EGLAPIENTRY PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
-#endif
-#endif
-
-#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
-#ifndef EGL_KHR_reusable_sync
-#define EGL_KHR_reusable_sync 1
-
-typedef void* EGLSyncKHR;
-typedef khronos_utime_nanoseconds_t EGLTimeKHR;
-
-#define EGL_SYNC_STATUS_KHR 0x30F1
-#define EGL_SIGNALED_KHR 0x30F2
-#define EGL_UNSIGNALED_KHR 0x30F3
-#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
-#define EGL_CONDITION_SATISFIED_KHR 0x30F6
-#define EGL_SYNC_TYPE_KHR 0x30F7
-#define EGL_SYNC_REUSABLE_KHR 0x30FA
-#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 /* eglClientWaitSyncKHR <flags> bitfield */
-#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
-#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
-EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
-EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
-typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
-#endif
-#endif
-
-/* EGL_MESA_screen extension >>> PRELIMINARY <<< */
-#ifndef EGL_MESA_screen_surface
-#define EGL_MESA_screen_surface 1
-
-#define EGL_BAD_SCREEN_MESA 0x4000
-#define EGL_BAD_MODE_MESA 0x4001
-#define EGL_SCREEN_COUNT_MESA 0x4002
-#define EGL_SCREEN_POSITION_MESA 0x4003
-#define EGL_SCREEN_POSITION_GRANULARITY_MESA 0x4004
-#define EGL_MODE_ID_MESA 0x4005
-#define EGL_REFRESH_RATE_MESA 0x4006
-#define EGL_OPTIMAL_MESA 0x4007
-#define EGL_INTERLACED_MESA 0x4008
-#define EGL_SCREEN_BIT_MESA 0x08
-
-typedef khronos_uint32_t EGLScreenMESA;
-typedef khronos_uint32_t EGLModeMESA;
-
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
-EGLAPI EGLBoolean EGLAPIENTRY eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-EGLAPI EGLSurface EGLAPIENTRY eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-EGLAPI EGLBoolean EGLAPIENTRY eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
-EGLAPI EGLBoolean EGLAPIENTRY eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
-EGLAPI const char * EGLAPIENTRY eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSEMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMODESMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGetModeATTRIBMESA) (EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSCRREENSMESA) (EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESCREENSURFACEMESA) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSHOWSCREENSURFACEMESA) (EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSCREENPOSIITONMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENSURFACEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
-typedef const char * (EGLAPIENTRYP PFNEGLQUERYMODESTRINGMESA) (EGLDisplay dpy, EGLModeMESA mode);
-
-#endif /* EGL_MESA_screen_surface */
-
-
-#ifndef EGL_MESA_copy_context
-#define EGL_MESA_copy_context 1
-
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
-
-#endif /* EGL_MESA_copy_context */
-
-#ifndef EGL_MESA_drm_display
-#define EGL_MESA_drm_display 1
-
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLDisplay EGLAPIENTRY eglGetDRMDisplayMESA(int fd);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-
-typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDRMDISPLAYMESA) (int fd);
-
-#endif /* EGL_MESA_drm_display */
-
-#ifndef EGL_KHR_image_base
-#define EGL_KHR_image_base 1
-/* Most interfaces defined by EGL_KHR_image_pixmap above */
-#define EGL_IMAGE_PRESERVED_KHR 0x30D2 /* eglCreateImageKHR attribute */
-#endif
-
-#ifndef EGL_KHR_image_pixmap
-#define EGL_KHR_image_pixmap 1
-/* Interfaces defined by EGL_KHR_image above */
-#endif
-
-#ifndef EGL_IMG_context_priority
-#define EGL_IMG_context_priority 1
-#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
-#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
-#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
-#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
-#endif
-
-#ifndef EGL_KHR_lock_surface2
-#define EGL_KHR_lock_surface2 1
-#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
-#endif
-
-#ifndef EGL_NV_coverage_sample
-#define EGL_NV_coverage_sample 1
-#define EGL_COVERAGE_BUFFERS_NV 0x30E0
-#define EGL_COVERAGE_SAMPLES_NV 0x30E1
-#endif
-
-#ifndef EGL_NV_depth_nonlinear
-#define EGL_NV_depth_nonlinear 1
-#define EGL_DEPTH_ENCODING_NV 0x30E2
-#define EGL_DEPTH_ENCODING_NONE_NV 0
-#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
-#endif
-
-#if KHRONOS_SUPPORT_INT64 /* EGLTimeNV requires 64-bit uint support */
-#ifndef EGL_NV_sync
-#define EGL_NV_sync 1
-#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
-#define EGL_SYNC_STATUS_NV 0x30E7
-#define EGL_SIGNALED_NV 0x30E8
-#define EGL_UNSIGNALED_NV 0x30E9
-#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
-#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
-#define EGL_ALREADY_SIGNALED_NV 0x30EA
-#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
-#define EGL_CONDITION_SATISFIED_NV 0x30EC
-#define EGL_SYNC_TYPE_NV 0x30ED
-#define EGL_SYNC_CONDITION_NV 0x30EE
-#define EGL_SYNC_FENCE_NV 0x30EF
-#define EGL_NO_SYNC_NV ((EGLSyncNV)0)
-typedef void* EGLSyncNV;
-typedef khronos_utime_nanoseconds_t EGLTimeNV;
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLSyncNV eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
-EGLBoolean eglDestroySyncNV (EGLSyncNV sync);
-EGLBoolean eglFenceNV (EGLSyncNV sync);
-EGLint eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
-EGLBoolean eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
-EGLBoolean eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
-typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
-#endif
-#endif
-
-#if KHRONOS_SUPPORT_INT64 /* Dependent on EGL_KHR_reusable_sync which requires 64-bit uint support */
-#ifndef EGL_KHR_fence_sync
-#define EGL_KHR_fence_sync 1
-/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */
-#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
-#define EGL_SYNC_CONDITION_KHR 0x30F8
-#define EGL_SYNC_FENCE_KHR 0x30F9
-#endif
-#endif
-
-#ifndef EGL_HI_clientpixmap
-#define EGL_HI_clientpixmap 1
-
-/* Surface Attribute */
-#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
-/*
- * Structure representing a client pixmap
- * (pixmap's data is in client-space memory).
- */
-struct EGLClientPixmapHI
-{
- void* pData;
- EGLint iWidth;
- EGLint iHeight;
- EGLint iStride;
-};
-
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
-#endif /* EGL_EGLEXT_PROTOTYPES */
-typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
-#endif /* EGL_HI_clientpixmap */
-
-#ifndef EGL_HI_colorformats
-#define EGL_HI_colorformats 1
-/* Config Attribute */
-#define EGL_COLOR_FORMAT_HI 0x8F70
-/* Color Formats */
-#define EGL_COLOR_RGB_HI 0x8F71
-#define EGL_COLOR_RGBA_HI 0x8F72
-#define EGL_COLOR_ARGB_HI 0x8F73
-#endif /* EGL_HI_colorformats */
-
-#ifndef EGL_NOK_swap_region
-#define EGL_NOK_swap_region 1
-
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
-#endif
-
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
-#endif
-
-
-#ifndef EGL_NOK_texture_from_pixmap
-#define EGL_NOK_texture_from_pixmap 1
-
-#define EGL_Y_INVERTED_NOK 0x307F
-#endif /* EGL_NOK_texture_from_pixmap */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+#ifndef __eglext_h_
+#define __eglext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2010 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#include <EGL/eglplatform.h>
+
+/*************************************************************/
+
+/* Header file version number */
+/* Current version at http://www.khronos.org/registry/egl/ */
+/* $Revision$ on $Date: 2010-07-27 20:12:35 -0700 (Tue, 27 Jul 2010) $ */
+#define EGL_EGLEXT_VERSION 7
+
+#ifndef EGL_KHR_config_attribs
+#define EGL_KHR_config_attribs 1
+#define EGL_CONFORMANT_KHR 0x3042 /* EGLConfig attribute */
+#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 /* EGL_SURFACE_TYPE bitfield */
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 /* EGL_SURFACE_TYPE bitfield */
+#endif
+
+#ifndef EGL_KHR_lock_surface
+#define EGL_KHR_lock_surface 1
+#define EGL_READ_SURFACE_BIT_KHR 0x0001 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
+#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
+#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 /* EGL_SURFACE_TYPE bitfield */
+#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 /* EGL_SURFACE_TYPE bitfield */
+#define EGL_MATCH_FORMAT_KHR 0x3043 /* EGLConfig attribute */
+#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 /* EGL_MATCH_FORMAT_KHR value */
+#define EGL_FORMAT_RGB_565_KHR 0x30C1 /* EGL_MATCH_FORMAT_KHR value */
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 /* EGL_MATCH_FORMAT_KHR value */
+#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 /* EGL_MATCH_FORMAT_KHR value */
+#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 /* eglLockSurfaceKHR attribute */
+#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 /* eglLockSurfaceKHR attribute */
+#define EGL_BITMAP_POINTER_KHR 0x30C6 /* eglQuerySurface attribute */
+#define EGL_BITMAP_PITCH_KHR 0x30C7 /* eglQuerySurface attribute */
+#define EGL_BITMAP_ORIGIN_KHR 0x30C8 /* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 /* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA /* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB /* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC /* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD /* eglQuerySurface attribute */
+#define EGL_LOWER_LEFT_KHR 0x30CE /* EGL_BITMAP_ORIGIN_KHR value */
+#define EGL_UPPER_LEFT_KHR 0x30CF /* EGL_BITMAP_ORIGIN_KHR value */
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface);
+#endif
+
+#ifndef EGL_KHR_image
+#define EGL_KHR_image 1
+#define EGL_NATIVE_PIXMAP_KHR 0x30B0 /* eglCreateImageKHR target */
+typedef void *EGLImageKHR;
+#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
+#endif
+
+#ifndef EGL_KHR_vg_parent_image
+#define EGL_KHR_vg_parent_image 1
+#define EGL_VG_PARENT_IMAGE_KHR 0x30BA /* eglCreateImageKHR target */
+#endif
+
+#ifndef EGL_KHR_gl_texture_2D_image
+#define EGL_KHR_gl_texture_2D_image 1
+#define EGL_GL_TEXTURE_2D_KHR 0x30B1 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC /* eglCreateImageKHR attribute */
+#endif
+
+#ifndef EGL_KHR_gl_texture_cubemap_image
+#define EGL_KHR_gl_texture_cubemap_image 1
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 /* eglCreateImageKHR target */
+#endif
+
+#ifndef EGL_KHR_gl_texture_3D_image
+#define EGL_KHR_gl_texture_3D_image 1
+#define EGL_GL_TEXTURE_3D_KHR 0x30B2 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD /* eglCreateImageKHR attribute */
+#endif
+
+#ifndef EGL_KHR_gl_renderbuffer_image
+#define EGL_KHR_gl_renderbuffer_image 1
+#define EGL_GL_RENDERBUFFER_KHR 0x30B9 /* eglCreateImageKHR target */
+#endif
+
+#ifndef EGL_MESA_drm_image
+#define EGL_MESA_drm_image 1
+#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 /* eglCreateImageKHR attribute */
+#define EGL_DRM_BUFFER_USE_MESA 0x31D1
+
+/* EGL_DRM_BUFFER_FORMAT_MESA tokens */
+#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
+
+/* EGL_DRM_BUFFER_USE_MESA bits */
+#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x0001
+#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x0002
+
+#define EGL_DRM_BUFFER_MESA 0x31D3 /* eglCreateImageKHR target */
+#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 /* eglCreateImageKHR attribute */
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#endif
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESA) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESA) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#endif
+
+#ifndef EGL_WL_bind_wayland_display
+#define EGL_WL_bind_wayland_display 1
+
+#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */
+struct wl_display;
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
+#else
+typedef EGLBoolean (EGLAPIENTRY PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
+typedef EGLBoolean (EGLAPIENTRY PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
+#endif
+#endif
+
+#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
+#ifndef EGL_KHR_reusable_sync
+#define EGL_KHR_reusable_sync 1
+
+typedef void* EGLSyncKHR;
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
+
+#define EGL_SYNC_STATUS_KHR 0x30F1
+#define EGL_SIGNALED_KHR 0x30F2
+#define EGL_UNSIGNALED_KHR 0x30F3
+#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
+#define EGL_CONDITION_SATISFIED_KHR 0x30F6
+#define EGL_SYNC_TYPE_KHR 0x30F7
+#define EGL_SYNC_REUSABLE_KHR 0x30FA
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 /* eglClientWaitSyncKHR <flags> bitfield */
+#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
+#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif
+#endif
+
+/* EGL_MESA_screen extension >>> PRELIMINARY <<< */
+#ifndef EGL_MESA_screen_surface
+#define EGL_MESA_screen_surface 1
+
+#define EGL_BAD_SCREEN_MESA 0x4000
+#define EGL_BAD_MODE_MESA 0x4001
+#define EGL_SCREEN_COUNT_MESA 0x4002
+#define EGL_SCREEN_POSITION_MESA 0x4003
+#define EGL_SCREEN_POSITION_GRANULARITY_MESA 0x4004
+#define EGL_MODE_ID_MESA 0x4005
+#define EGL_REFRESH_RATE_MESA 0x4006
+#define EGL_OPTIMAL_MESA 0x4007
+#define EGL_INTERLACED_MESA 0x4008
+#define EGL_SCREEN_BIT_MESA 0x08
+
+typedef khronos_uint32_t EGLScreenMESA;
+typedef khronos_uint32_t EGLModeMESA;
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
+EGLAPI EGLSurface EGLAPIENTRY eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
+EGLAPI const char * EGLAPIENTRY eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSEMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMODESMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGetModeATTRIBMESA) (EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSCRREENSMESA) (EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESCREENSURFACEMESA) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSHOWSCREENSURFACEMESA) (EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSCREENPOSIITONMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENSURFACEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
+typedef const char * (EGLAPIENTRYP PFNEGLQUERYMODESTRINGMESA) (EGLDisplay dpy, EGLModeMESA mode);
+
+#endif /* EGL_MESA_screen_surface */
+
+
+#ifndef EGL_MESA_copy_context
+#define EGL_MESA_copy_context 1
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
+
+#endif /* EGL_MESA_copy_context */
+
+#ifndef EGL_MESA_drm_display
+#define EGL_MESA_drm_display 1
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDRMDisplayMESA(int fd);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDRMDISPLAYMESA) (int fd);
+
+#endif /* EGL_MESA_drm_display */
+
+#ifndef EGL_KHR_image_base
+#define EGL_KHR_image_base 1
+/* Most interfaces defined by EGL_KHR_image_pixmap above */
+#define EGL_IMAGE_PRESERVED_KHR 0x30D2 /* eglCreateImageKHR attribute */
+#endif
+
+#ifndef EGL_KHR_image_pixmap
+#define EGL_KHR_image_pixmap 1
+/* Interfaces defined by EGL_KHR_image above */
+#endif
+
+#ifndef EGL_IMG_context_priority
+#define EGL_IMG_context_priority 1
+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
+#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
+#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
+#endif
+
+#ifndef EGL_KHR_lock_surface2
+#define EGL_KHR_lock_surface2 1
+#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
+#endif
+
+#ifndef EGL_NV_coverage_sample
+#define EGL_NV_coverage_sample 1
+#define EGL_COVERAGE_BUFFERS_NV 0x30E0
+#define EGL_COVERAGE_SAMPLES_NV 0x30E1
+#endif
+
+#ifndef EGL_NV_depth_nonlinear
+#define EGL_NV_depth_nonlinear 1
+#define EGL_DEPTH_ENCODING_NV 0x30E2
+#define EGL_DEPTH_ENCODING_NONE_NV 0
+#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
+#endif
+
+#if KHRONOS_SUPPORT_INT64 /* EGLTimeNV requires 64-bit uint support */
+#ifndef EGL_NV_sync
+#define EGL_NV_sync 1
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
+#define EGL_SYNC_STATUS_NV 0x30E7
+#define EGL_SIGNALED_NV 0x30E8
+#define EGL_UNSIGNALED_NV 0x30E9
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
+#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
+#define EGL_ALREADY_SIGNALED_NV 0x30EA
+#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
+#define EGL_CONDITION_SATISFIED_NV 0x30EC
+#define EGL_SYNC_TYPE_NV 0x30ED
+#define EGL_SYNC_CONDITION_NV 0x30EE
+#define EGL_SYNC_FENCE_NV 0x30EF
+#define EGL_NO_SYNC_NV ((EGLSyncNV)0)
+typedef void* EGLSyncNV;
+typedef khronos_utime_nanoseconds_t EGLTimeNV;
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLSyncNV eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+EGLBoolean eglDestroySyncNV (EGLSyncNV sync);
+EGLBoolean eglFenceNV (EGLSyncNV sync);
+EGLint eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+EGLBoolean eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
+EGLBoolean eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#endif
+#endif
+
+#if KHRONOS_SUPPORT_INT64 /* Dependent on EGL_KHR_reusable_sync which requires 64-bit uint support */
+#ifndef EGL_KHR_fence_sync
+#define EGL_KHR_fence_sync 1
+/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
+#define EGL_SYNC_CONDITION_KHR 0x30F8
+#define EGL_SYNC_FENCE_KHR 0x30F9
+#endif
+#endif
+
+#ifndef EGL_HI_clientpixmap
+#define EGL_HI_clientpixmap 1
+
+/* Surface Attribute */
+#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
+/*
+ * Structure representing a client pixmap
+ * (pixmap's data is in client-space memory).
+ */
+struct EGLClientPixmapHI
+{
+ void* pData;
+ EGLint iWidth;
+ EGLint iHeight;
+ EGLint iStride;
+};
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
+#endif /* EGL_HI_clientpixmap */
+
+#ifndef EGL_HI_colorformats
+#define EGL_HI_colorformats 1
+/* Config Attribute */
+#define EGL_COLOR_FORMAT_HI 0x8F70
+/* Color Formats */
+#define EGL_COLOR_RGB_HI 0x8F71
+#define EGL_COLOR_RGBA_HI 0x8F72
+#define EGL_COLOR_ARGB_HI 0x8F73
+#endif /* EGL_HI_colorformats */
+
+#ifndef EGL_NOK_swap_region
+#define EGL_NOK_swap_region 1
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
+#endif
+
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
+#endif
+
+
+#ifndef EGL_NOK_texture_from_pixmap
+#define EGL_NOK_texture_from_pixmap 1
+
+#define EGL_Y_INVERTED_NOK 0x307F
+#endif /* EGL_NOK_texture_from_pixmap */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript
index bb02a87c7..d7c3459f2 100644
--- a/mesalib/src/glsl/SConscript
+++ b/mesalib/src/glsl/SConscript
@@ -1,170 +1,176 @@
-import common
-
-Import('*')
-
-from sys import executable as python_cmd
-
-env = env.Clone()
-
-env.Prepend(CPPPATH = [
- '#include',
- '#src/mapi',
- '#src/mesa',
- '#src/glsl',
- '#src/glsl/glcpp',
-])
-
-# Make glcpp/glcpp-parse.h and glsl_parser.h reacheable from the include path
-env.Append(CPPPATH = [Dir('.').abspath])
-
-env.Append(YACCFLAGS = '-d')
-
-parser_env = env.Clone()
-parser_env.Append(YACCFLAGS = [
- '--defines=%s' % File('glsl_parser.h').abspath,
- '-p', '_mesa_glsl_',
-])
-
-glcpp_lexer = env.CFile('glcpp/glcpp-lex.c', 'glcpp/glcpp-lex.l')
-glcpp_parser = env.CFile('glcpp/glcpp-parse.c', 'glcpp/glcpp-parse.y')
-glsl_lexer = parser_env.CXXFile('glsl_lexer.cpp', 'glsl_lexer.ll')
-glsl_parser = parser_env.CXXFile('glsl_parser.cpp', 'glsl_parser.yy')
-
-sources = [
- glcpp_lexer,
- glcpp_parser[0],
- 'glcpp/pp.c',
- 'ast_expr.cpp',
- 'ast_function.cpp',
- 'ast_to_hir.cpp',
- 'ast_type.cpp',
- glsl_lexer,
- glsl_parser[0],
- 'glsl_parser_extras.cpp',
- 'glsl_types.cpp',
- 'glsl_symbol_table.cpp',
- 'hir_field_selection.cpp',
- 'ir_basic_block.cpp',
- 'ir_clone.cpp',
- 'ir_constant_expression.cpp',
- 'ir.cpp',
- 'ir_expression_flattening.cpp',
- 'ir_function_can_inline.cpp',
- 'ir_function.cpp',
- 'ir_hierarchical_visitor.cpp',
- 'ir_hv_accept.cpp',
- 'ir_import_prototypes.cpp',
- 'ir_print_visitor.cpp',
- 'ir_reader.cpp',
- 'ir_rvalue_visitor.cpp',
- 'ir_set_program_inouts.cpp',
- 'ir_validate.cpp',
- 'ir_variable.cpp',
- 'ir_variable_refcount.cpp',
- 'linker.cpp',
- 'link_functions.cpp',
- 'loop_analysis.cpp',
- 'loop_controls.cpp',
- 'loop_unroll.cpp',
- 'lower_discard.cpp',
- 'lower_if_to_cond_assign.cpp',
- 'lower_instructions.cpp',
- 'lower_jumps.cpp',
- 'lower_mat_op_to_vec.cpp',
- 'lower_noise.cpp',
- 'lower_variable_index_to_cond_assign.cpp',
- 'lower_vec_index_to_cond_assign.cpp',
- 'lower_vec_index_to_swizzle.cpp',
- 'lower_vector.cpp',
- 'opt_algebraic.cpp',
- 'opt_constant_folding.cpp',
- 'opt_constant_propagation.cpp',
- 'opt_constant_variable.cpp',
- 'opt_copy_propagation.cpp',
- 'opt_copy_propagation_elements.cpp',
- 'opt_dead_code.cpp',
- 'opt_dead_code_local.cpp',
- 'opt_dead_functions.cpp',
- 'opt_discard_simplification.cpp',
- 'opt_function_inlining.cpp',
- 'opt_if_simplification.cpp',
- 'opt_noop_swizzle.cpp',
- 'opt_redundant_jumps.cpp',
- 'opt_structure_splitting.cpp',
- 'opt_swizzle_swizzle.cpp',
- 'opt_tree_grafting.cpp',
- 'ralloc.c',
- 's_expression.cpp',
- 'strtod.c',
-]
-
-
-if env['crosscompile'] and env['platform'] != 'embedded':
- Import('builtin_glsl_function')
-else:
- if env['msvc']:
- env.Prepend(CPPPATH = ['#/src/getopt'])
- env.PrependUnique(LIBS = [getopt])
-
- builtin_compiler = env.Program(
- target = 'builtin_compiler',
- source = sources + ['main.cpp', 'builtin_stubs.cpp',
- '#src/mesa/program/hash_table.c',
- '#src/mesa/program/symbol_table.c'],
- )
-
- # SCons builtin dependency scanner doesn't detect that glsl_lexer.ll
- # depends on glsl_parser.h
- env.Depends(builtin_compiler, glsl_parser)
-
- builtin_glsl_function = env.CodeGenerate(
- target = 'builtin_function.cpp',
- script = 'builtins/tools/generate_builtins.py',
- source = builtin_compiler,
- command = python_cmd + ' $SCRIPT $SOURCE > $TARGET'
- )
-
- env.Depends(builtin_glsl_function, ['builtins/tools/generate_builtins.py', 'builtins/tools/texture_builtins.py'] + Glob('builtins/ir/*'))
-
- Export('builtin_glsl_function')
-
- if env['hostonly']:
- Return()
-
-
-sources += builtin_glsl_function
-
-glsl = env.ConvenienceLibrary(
- target = 'glsl',
- source = sources,
-)
-
-# SCons builtin dependency scanner doesn't detect that glsl_lexer.ll depends on
-# glsl_parser.h
-env.Depends(glsl, glsl_parser)
-
-Export('glsl')
-
-# FIXME: We can't build the programs because there's a cyclic dependency between tis directory and src/mesa
-Return()
-
-env = env.Clone()
-
-if env['platform'] == 'windows':
- env.PrependUnique(LIBS = [
- 'user32',
- ])
-
-env.Prepend(LIBS = [glsl])
-
-env.Program(
- target = 'glsl2',
- source = [
- 'main.cpp',
- ]
-)
-
-env.Program(
- target = 'glcpp',
- source = ['glcpp/glcpp.c'],
-)
+import common
+
+Import('*')
+
+from sys import executable as python_cmd
+
+env = env.Clone()
+
+env.Prepend(CPPPATH = [
+ '#include',
+ '#src/mapi',
+ '#src/mesa',
+ '#src/glsl',
+ '#src/glsl/glcpp',
+])
+
+# Make glcpp/glcpp-parse.h and glsl_parser.h reacheable from the include path
+env.Append(CPPPATH = [Dir('.').abspath])
+
+env.Append(YACCFLAGS = '-d')
+
+parser_env = env.Clone()
+parser_env.Append(YACCFLAGS = [
+ '--defines=%s' % File('glsl_parser.h').abspath,
+ '-p', '_mesa_glsl_',
+])
+
+glcpp_lexer = env.CFile('glcpp/glcpp-lex.c', 'glcpp/glcpp-lex.l')
+glcpp_parser = env.CFile('glcpp/glcpp-parse.c', 'glcpp/glcpp-parse.y')
+glsl_lexer = parser_env.CXXFile('glsl_lexer.cpp', 'glsl_lexer.ll')
+glsl_parser = parser_env.CXXFile('glsl_parser.cpp', 'glsl_parser.yy')
+
+glsl_sources = [
+ glcpp_lexer,
+ glcpp_parser[0],
+ 'glcpp/pp.c',
+ 'ast_expr.cpp',
+ 'ast_function.cpp',
+ 'ast_to_hir.cpp',
+ 'ast_type.cpp',
+ glsl_lexer,
+ glsl_parser[0],
+ 'glsl_parser_extras.cpp',
+ 'glsl_types.cpp',
+ 'glsl_symbol_table.cpp',
+ 'hir_field_selection.cpp',
+ 'ir_basic_block.cpp',
+ 'ir_clone.cpp',
+ 'ir_constant_expression.cpp',
+ 'ir.cpp',
+ 'ir_expression_flattening.cpp',
+ 'ir_function_can_inline.cpp',
+ 'ir_function.cpp',
+ 'ir_hierarchical_visitor.cpp',
+ 'ir_hv_accept.cpp',
+ 'ir_import_prototypes.cpp',
+ 'ir_print_visitor.cpp',
+ 'ir_reader.cpp',
+ 'ir_rvalue_visitor.cpp',
+ 'ir_set_program_inouts.cpp',
+ 'ir_validate.cpp',
+ 'ir_variable.cpp',
+ 'ir_variable_refcount.cpp',
+ 'linker.cpp',
+ 'link_functions.cpp',
+ 'loop_analysis.cpp',
+ 'loop_controls.cpp',
+ 'loop_unroll.cpp',
+ 'lower_discard.cpp',
+ 'lower_if_to_cond_assign.cpp',
+ 'lower_instructions.cpp',
+ 'lower_jumps.cpp',
+ 'lower_mat_op_to_vec.cpp',
+ 'lower_noise.cpp',
+ 'lower_variable_index_to_cond_assign.cpp',
+ 'lower_vec_index_to_cond_assign.cpp',
+ 'lower_vec_index_to_swizzle.cpp',
+ 'lower_vector.cpp',
+ 'opt_algebraic.cpp',
+ 'opt_constant_folding.cpp',
+ 'opt_constant_propagation.cpp',
+ 'opt_constant_variable.cpp',
+ 'opt_copy_propagation.cpp',
+ 'opt_copy_propagation_elements.cpp',
+ 'opt_dead_code.cpp',
+ 'opt_dead_code_local.cpp',
+ 'opt_dead_functions.cpp',
+ 'opt_discard_simplification.cpp',
+ 'opt_function_inlining.cpp',
+ 'opt_if_simplification.cpp',
+ 'opt_noop_swizzle.cpp',
+ 'opt_redundant_jumps.cpp',
+ 'opt_structure_splitting.cpp',
+ 'opt_swizzle_swizzle.cpp',
+ 'opt_tree_grafting.cpp',
+ 'ralloc.c',
+ 's_expression.cpp',
+ 'strtod.c',
+]
+
+if env['msvc']:
+ env.Prepend(CPPPATH = ['#/src/getopt'])
+ env.PrependUnique(LIBS = [getopt])
+
+if env['crosscompile'] and env['platform'] != 'embedded':
+ Import('builtin_glsl_function')
+else:
+ main_obj = env.StaticObject('main.cpp')
+
+ mesa_objs = env.StaticObject([
+ '#src/mesa/program/hash_table.c',
+ '#src/mesa/program/symbol_table.c',
+ ])
+
+ builtin_compiler = env.Program(
+ target = 'builtin_compiler',
+ source = main_obj + glsl_sources + ['builtin_stubs.cpp'] + mesa_objs,
+ )
+
+ # SCons builtin dependency scanner doesn't detect that glsl_lexer.ll
+ # depends on glsl_parser.h
+ env.Depends(builtin_compiler, glsl_parser)
+
+ builtin_glsl_function = env.CodeGenerate(
+ target = 'builtin_function.cpp',
+ script = 'builtins/tools/generate_builtins.py',
+ source = builtin_compiler,
+ command = python_cmd + ' $SCRIPT $SOURCE > $TARGET'
+ )
+
+ env.Depends(builtin_glsl_function, ['builtins/tools/generate_builtins.py', 'builtins/tools/texture_builtins.py'] + Glob('builtins/ir/*'))
+
+ Export('builtin_glsl_function')
+
+ if env['hostonly']:
+ Return()
+
+
+glsl_sources += builtin_glsl_function
+
+glsl = env.ConvenienceLibrary(
+ target = 'glsl',
+ source = glsl_sources,
+)
+
+# SCons builtin dependency scanner doesn't detect that glsl_lexer.ll depends on
+# glsl_parser.h
+env.Depends(glsl, glsl_parser)
+
+Export('glsl')
+
+# Skip building these programs as they will cause SCons error "Two environments
+# with different actions were specified for the same target"
+if env['crosscompile'] or env['platform'] == 'embedded':
+ Return()
+
+env = env.Clone()
+
+if env['platform'] == 'windows':
+ env.PrependUnique(LIBS = [
+ 'user32',
+ ])
+
+env.Prepend(LIBS = [glsl])
+
+glsl2 = env.Program(
+ target = 'glsl2',
+ source = main_obj + mesa_objs,
+)
+env.Alias('glsl2', glsl2)
+
+glcpp = env.Program(
+ target = 'glcpp/glcpp',
+ source = ['glcpp/glcpp.c'] + mesa_objs,
+)
+env.Alias('glcpp', glcpp)
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index fd1f0b49f..b8a812d94 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -1,3461 +1,3499 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file ast_to_hir.c
- * Convert abstract syntax to to high-level intermediate reprensentation (HIR).
- *
- * During the conversion to HIR, the majority of the symantic checking is
- * preformed on the program. This includes:
- *
- * * Symbol table management
- * * Type checking
- * * Function binding
- *
- * The majority of this work could be done during parsing, and the parser could
- * probably generate HIR directly. However, this results in frequent changes
- * to the parser code. Since we do not assume that every system this complier
- * is built on will have Flex and Bison installed, we have to store the code
- * generated by these tools in our version control system. In other parts of
- * the system we've seen problems where a parser was changed but the generated
- * code was not committed, merge conflicts where created because two developers
- * had slightly different versions of Bison installed, etc.
- *
- * I have also noticed that running Bison generated parsers in GDB is very
- * irritating. When you get a segfault on '$$ = $1->foo', you can't very
- * well 'print $1' in GDB.
- *
- * As a result, my preference is to put as little C code as possible in the
- * parser (and lexer) sources.
- */
-
-#include "main/core.h" /* for struct gl_extensions */
-#include "glsl_symbol_table.h"
-#include "glsl_parser_extras.h"
-#include "ast.h"
-#include "glsl_types.h"
-#include "ir.h"
-
-void
-_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
-{
- _mesa_glsl_initialize_variables(instructions, state);
- _mesa_glsl_initialize_functions(state);
-
- state->symbols->language_version = state->language_version;
-
- state->current_function = NULL;
-
- /* Section 4.2 of the GLSL 1.20 specification states:
- * "The built-in functions are scoped in a scope outside the global scope
- * users declare global variables in. That is, a shader's global scope,
- * available for user-defined functions and global variables, is nested
- * inside the scope containing the built-in functions."
- *
- * Since built-in functions like ftransform() access built-in variables,
- * it follows that those must be in the outer scope as well.
- *
- * We push scope here to create this nesting effect...but don't pop.
- * This way, a shader's globals are still in the symbol table for use
- * by the linker.
- */
- state->symbols->push_scope();
-
- foreach_list_typed (ast_node, ast, link, & state->translation_unit)
- ast->hir(instructions, state);
-}
-
-
-/**
- * If a conversion is available, convert one operand to a different type
- *
- * The \c from \c ir_rvalue is converted "in place".
- *
- * \param to Type that the operand it to be converted to
- * \param from Operand that is being converted
- * \param state GLSL compiler state
- *
- * \return
- * If a conversion is possible (or unnecessary), \c true is returned.
- * Otherwise \c false is returned.
- */
-bool
-apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = state;
- if (to->base_type == from->type->base_type)
- return true;
-
- /* This conversion was added in GLSL 1.20. If the compilation mode is
- * GLSL 1.10, the conversion is skipped.
- */
- if (state->language_version < 120)
- return false;
-
- /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
- *
- * "There are no implicit array or structure conversions. For
- * example, an array of int cannot be implicitly converted to an
- * array of float. There are no implicit conversions between
- * signed and unsigned integers."
- */
- /* FINISHME: The above comment is partially a lie. There is int/uint
- * FINISHME: conversion for immediate constants.
- */
- if (!to->is_float() || !from->type->is_numeric())
- return false;
-
- /* Convert to a floating point type with the same number of components
- * as the original type - i.e. int to float, not int to vec4.
- */
- to = glsl_type::get_instance(GLSL_TYPE_FLOAT, from->type->vector_elements,
- from->type->matrix_columns);
-
- switch (from->type->base_type) {
- case GLSL_TYPE_INT:
- from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL);
- break;
- case GLSL_TYPE_UINT:
- from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL);
- break;
- case GLSL_TYPE_BOOL:
- from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL);
- break;
- default:
- assert(0);
- }
-
- return true;
-}
-
-
-static const struct glsl_type *
-arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
- bool multiply,
- struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
-{
- const glsl_type *type_a = value_a->type;
- const glsl_type *type_b = value_b->type;
-
- /* From GLSL 1.50 spec, page 56:
- *
- * "The arithmetic binary operators add (+), subtract (-),
- * multiply (*), and divide (/) operate on integer and
- * floating-point scalars, vectors, and matrices."
- */
- if (!type_a->is_numeric() || !type_b->is_numeric()) {
- _mesa_glsl_error(loc, state,
- "Operands to arithmetic operators must be numeric");
- return glsl_type::error_type;
- }
-
-
- /* "If one operand is floating-point based and the other is
- * not, then the conversions from Section 4.1.10 "Implicit
- * Conversions" are applied to the non-floating-point-based operand."
- */
- if (!apply_implicit_conversion(type_a, value_b, state)
- && !apply_implicit_conversion(type_b, value_a, state)) {
- _mesa_glsl_error(loc, state,
- "Could not implicitly convert operands to "
- "arithmetic operator");
- return glsl_type::error_type;
- }
- type_a = value_a->type;
- type_b = value_b->type;
-
- /* "If the operands are integer types, they must both be signed or
- * both be unsigned."
- *
- * From this rule and the preceeding conversion it can be inferred that
- * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT.
- * The is_numeric check above already filtered out the case where either
- * type is not one of these, so now the base types need only be tested for
- * equality.
- */
- if (type_a->base_type != type_b->base_type) {
- _mesa_glsl_error(loc, state,
- "base type mismatch for arithmetic operator");
- return glsl_type::error_type;
- }
-
- /* "All arithmetic binary operators result in the same fundamental type
- * (signed integer, unsigned integer, or floating-point) as the
- * operands they operate on, after operand type conversion. After
- * conversion, the following cases are valid
- *
- * * The two operands are scalars. In this case the operation is
- * applied, resulting in a scalar."
- */
- if (type_a->is_scalar() && type_b->is_scalar())
- return type_a;
-
- /* "* One operand is a scalar, and the other is a vector or matrix.
- * In this case, the scalar operation is applied independently to each
- * component of the vector or matrix, resulting in the same size
- * vector or matrix."
- */
- if (type_a->is_scalar()) {
- if (!type_b->is_scalar())
- return type_b;
- } else if (type_b->is_scalar()) {
- return type_a;
- }
-
- /* All of the combinations of <scalar, scalar>, <vector, scalar>,
- * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been
- * handled.
- */
- assert(!type_a->is_scalar());
- assert(!type_b->is_scalar());
-
- /* "* The two operands are vectors of the same size. In this case, the
- * operation is done component-wise resulting in the same size
- * vector."
- */
- if (type_a->is_vector() && type_b->is_vector()) {
- if (type_a == type_b) {
- return type_a;
- } else {
- _mesa_glsl_error(loc, state,
- "vector size mismatch for arithmetic operator");
- return glsl_type::error_type;
- }
- }
-
- /* All of the combinations of <scalar, scalar>, <vector, scalar>,
- * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and
- * <vector, vector> have been handled. At least one of the operands must
- * be matrix. Further, since there are no integer matrix types, the base
- * type of both operands must be float.
- */
- assert(type_a->is_matrix() || type_b->is_matrix());
- assert(type_a->base_type == GLSL_TYPE_FLOAT);
- assert(type_b->base_type == GLSL_TYPE_FLOAT);
-
- /* "* The operator is add (+), subtract (-), or divide (/), and the
- * operands are matrices with the same number of rows and the same
- * number of columns. In this case, the operation is done component-
- * wise resulting in the same size matrix."
- * * The operator is multiply (*), where both operands are matrices or
- * one operand is a vector and the other a matrix. A right vector
- * operand is treated as a column vector and a left vector operand as a
- * row vector. In all these cases, it is required that the number of
- * columns of the left operand is equal to the number of rows of the
- * right operand. Then, the multiply (*) operation does a linear
- * algebraic multiply, yielding an object that has the same number of
- * rows as the left operand and the same number of columns as the right
- * operand. Section 5.10 "Vector and Matrix Operations" explains in
- * more detail how vectors and matrices are operated on."
- */
- if (! multiply) {
- if (type_a == type_b)
- return type_a;
- } else {
- if (type_a->is_matrix() && type_b->is_matrix()) {
- /* Matrix multiply. The columns of A must match the rows of B. Given
- * the other previously tested constraints, this means the vector type
- * of a row from A must be the same as the vector type of a column from
- * B.
- */
- if (type_a->row_type() == type_b->column_type()) {
- /* The resulting matrix has the number of columns of matrix B and
- * the number of rows of matrix A. We get the row count of A by
- * looking at the size of a vector that makes up a column. The
- * transpose (size of a row) is done for B.
- */
- const glsl_type *const type =
- glsl_type::get_instance(type_a->base_type,
- type_a->column_type()->vector_elements,
- type_b->row_type()->vector_elements);
- assert(type != glsl_type::error_type);
-
- return type;
- }
- } else if (type_a->is_matrix()) {
- /* A is a matrix and B is a column vector. Columns of A must match
- * rows of B. Given the other previously tested constraints, this
- * means the vector type of a row from A must be the same as the
- * vector the type of B.
- */
- if (type_a->row_type() == type_b) {
- /* The resulting vector has a number of elements equal to
- * the number of rows of matrix A. */
- const glsl_type *const type =
- glsl_type::get_instance(type_a->base_type,
- type_a->column_type()->vector_elements,
- 1);
- assert(type != glsl_type::error_type);
-
- return type;
- }
- } else {
- assert(type_b->is_matrix());
-
- /* A is a row vector and B is a matrix. Columns of A must match rows
- * of B. Given the other previously tested constraints, this means
- * the type of A must be the same as the vector type of a column from
- * B.
- */
- if (type_a == type_b->column_type()) {
- /* The resulting vector has a number of elements equal to
- * the number of columns of matrix B. */
- const glsl_type *const type =
- glsl_type::get_instance(type_a->base_type,
- type_b->row_type()->vector_elements,
- 1);
- assert(type != glsl_type::error_type);
-
- return type;
- }
- }
-
- _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication");
- return glsl_type::error_type;
- }
-
-
- /* "All other cases are illegal."
- */
- _mesa_glsl_error(loc, state, "type mismatch");
- return glsl_type::error_type;
-}
-
-
-static const struct glsl_type *
-unary_arithmetic_result_type(const struct glsl_type *type,
- struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
-{
- /* From GLSL 1.50 spec, page 57:
- *
- * "The arithmetic unary operators negate (-), post- and pre-increment
- * and decrement (-- and ++) operate on integer or floating-point
- * values (including vectors and matrices). All unary operators work
- * component-wise on their operands. These result with the same type
- * they operated on."
- */
- if (!type->is_numeric()) {
- _mesa_glsl_error(loc, state,
- "Operands to arithmetic operators must be numeric");
- return glsl_type::error_type;
- }
-
- return type;
-}
-
-/**
- * \brief Return the result type of a bit-logic operation.
- *
- * If the given types to the bit-logic operator are invalid, return
- * glsl_type::error_type.
- *
- * \param type_a Type of LHS of bit-logic op
- * \param type_b Type of RHS of bit-logic op
- */
-static const struct glsl_type *
-bit_logic_result_type(const struct glsl_type *type_a,
- const struct glsl_type *type_b,
- ast_operators op,
- struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
-{
- if (state->language_version < 130) {
- _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
- return glsl_type::error_type;
- }
-
- /* From page 50 (page 56 of PDF) of GLSL 1.30 spec:
- *
- * "The bitwise operators and (&), exclusive-or (^), and inclusive-or
- * (|). The operands must be of type signed or unsigned integers or
- * integer vectors."
- */
- if (!type_a->is_integer()) {
- _mesa_glsl_error(loc, state, "LHS of `%s' must be an integer",
- ast_expression::operator_string(op));
- return glsl_type::error_type;
- }
- if (!type_b->is_integer()) {
- _mesa_glsl_error(loc, state, "RHS of `%s' must be an integer",
- ast_expression::operator_string(op));
- return glsl_type::error_type;
- }
-
- /* "The fundamental types of the operands (signed or unsigned) must
- * match,"
- */
- if (type_a->base_type != type_b->base_type) {
- _mesa_glsl_error(loc, state, "operands of `%s' must have the same "
- "base type", ast_expression::operator_string(op));
- return glsl_type::error_type;
- }
-
- /* "The operands cannot be vectors of differing size." */
- if (type_a->is_vector() &&
- type_b->is_vector() &&
- type_a->vector_elements != type_b->vector_elements) {
- _mesa_glsl_error(loc, state, "operands of `%s' cannot be vectors of "
- "different sizes", ast_expression::operator_string(op));
- return glsl_type::error_type;
- }
-
- /* "If one operand is a scalar and the other a vector, the scalar is
- * applied component-wise to the vector, resulting in the same type as
- * the vector. The fundamental types of the operands [...] will be the
- * resulting fundamental type."
- */
- if (type_a->is_scalar())
- return type_b;
- else
- return type_a;
-}
-
-static const struct glsl_type *
-modulus_result_type(const struct glsl_type *type_a,
- const struct glsl_type *type_b,
- struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
-{
- if (state->language_version < 130) {
- _mesa_glsl_error(loc, state,
- "operator '%%' is reserved in %s",
- state->version_string);
- return glsl_type::error_type;
- }
-
- /* From GLSL 1.50 spec, page 56:
- * "The operator modulus (%) operates on signed or unsigned integers or
- * integer vectors. The operand types must both be signed or both be
- * unsigned."
- */
- if (!type_a->is_integer() || !type_b->is_integer()
- || (type_a->base_type != type_b->base_type)) {
- _mesa_glsl_error(loc, state, "type mismatch");
- return glsl_type::error_type;
- }
-
- /* "The operands cannot be vectors of differing size. If one operand is
- * a scalar and the other vector, then the scalar is applied component-
- * wise to the vector, resulting in the same type as the vector. If both
- * are vectors of the same size, the result is computed component-wise."
- */
- if (type_a->is_vector()) {
- if (!type_b->is_vector()
- || (type_a->vector_elements == type_b->vector_elements))
- return type_a;
- } else
- return type_b;
-
- /* "The operator modulus (%) is not defined for any other data types
- * (non-integer types)."
- */
- _mesa_glsl_error(loc, state, "type mismatch");
- return glsl_type::error_type;
-}
-
-
-static const struct glsl_type *
-relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
- struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
-{
- const glsl_type *type_a = value_a->type;
- const glsl_type *type_b = value_b->type;
-
- /* From GLSL 1.50 spec, page 56:
- * "The relational operators greater than (>), less than (<), greater
- * than or equal (>=), and less than or equal (<=) operate only on
- * scalar integer and scalar floating-point expressions."
- */
- if (!type_a->is_numeric()
- || !type_b->is_numeric()
- || !type_a->is_scalar()
- || !type_b->is_scalar()) {
- _mesa_glsl_error(loc, state,
- "Operands to relational operators must be scalar and "
- "numeric");
- return glsl_type::error_type;
- }
-
- /* "Either the operands' types must match, or the conversions from
- * Section 4.1.10 "Implicit Conversions" will be applied to the integer
- * operand, after which the types must match."
- */
- if (!apply_implicit_conversion(type_a, value_b, state)
- && !apply_implicit_conversion(type_b, value_a, state)) {
- _mesa_glsl_error(loc, state,
- "Could not implicitly convert operands to "
- "relational operator");
- return glsl_type::error_type;
- }
- type_a = value_a->type;
- type_b = value_b->type;
-
- if (type_a->base_type != type_b->base_type) {
- _mesa_glsl_error(loc, state, "base type mismatch");
- return glsl_type::error_type;
- }
-
- /* "The result is scalar Boolean."
- */
- return glsl_type::bool_type;
-}
-
-/**
- * \brief Return the result type of a bit-shift operation.
- *
- * If the given types to the bit-shift operator are invalid, return
- * glsl_type::error_type.
- *
- * \param type_a Type of LHS of bit-shift op
- * \param type_b Type of RHS of bit-shift op
- */
-static const struct glsl_type *
-shift_result_type(const struct glsl_type *type_a,
- const struct glsl_type *type_b,
- ast_operators op,
- struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
-{
- if (state->language_version < 130) {
- _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
- return glsl_type::error_type;
- }
-
- /* From page 50 (page 56 of the PDF) of the GLSL 1.30 spec:
- *
- * "The shift operators (<<) and (>>). For both operators, the operands
- * must be signed or unsigned integers or integer vectors. One operand
- * can be signed while the other is unsigned."
- */
- if (!type_a->is_integer()) {
- _mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or "
- "integer vector", ast_expression::operator_string(op));
- return glsl_type::error_type;
-
- }
- if (!type_b->is_integer()) {
- _mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or "
- "integer vector", ast_expression::operator_string(op));
- return glsl_type::error_type;
- }
-
- /* "If the first operand is a scalar, the second operand has to be
- * a scalar as well."
- */
- if (type_a->is_scalar() && !type_b->is_scalar()) {
- _mesa_glsl_error(loc, state, "If the first operand of %s is scalar, the "
- "second must be scalar as well",
- ast_expression::operator_string(op));
- return glsl_type::error_type;
- }
-
- /* If both operands are vectors, check that they have same number of
- * elements.
- */
- if (type_a->is_vector() &&
- type_b->is_vector() &&
- type_a->vector_elements != type_b->vector_elements) {
- _mesa_glsl_error(loc, state, "Vector operands to operator %s must "
- "have same number of elements",
- ast_expression::operator_string(op));
- return glsl_type::error_type;
- }
-
- /* "In all cases, the resulting type will be the same type as the left
- * operand."
- */
- return type_a;
-}
-
-/**
- * Validates that a value can be assigned to a location with a specified type
- *
- * Validates that \c rhs can be assigned to some location. If the types are
- * not an exact match but an automatic conversion is possible, \c rhs will be
- * converted.
- *
- * \return
- * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type.
- * Otherwise the actual RHS to be assigned will be returned. This may be
- * \c rhs, or it may be \c rhs after some type conversion.
- *
- * \note
- * In addition to being used for assignments, this function is used to
- * type-check return values.
- */
-ir_rvalue *
-validate_assignment(struct _mesa_glsl_parse_state *state,
- const glsl_type *lhs_type, ir_rvalue *rhs)
-{
- /* If there is already some error in the RHS, just return it. Anything
- * else will lead to an avalanche of error message back to the user.
- */
- if (rhs->type->is_error())
- return rhs;
-
- /* If the types are identical, the assignment can trivially proceed.
- */
- if (rhs->type == lhs_type)
- return rhs;
-
- /* If the array element types are the same and the size of the LHS is zero,
- * the assignment is okay.
- *
- * Note: Whole-array assignments are not permitted in GLSL 1.10, but this
- * is handled by ir_dereference::is_lvalue.
- */
- if (lhs_type->is_array() && rhs->type->is_array()
- && (lhs_type->element_type() == rhs->type->element_type())
- && (lhs_type->array_size() == 0)) {
- return rhs;
- }
-
- /* Check for implicit conversion in GLSL 1.20 */
- if (apply_implicit_conversion(lhs_type, rhs, state)) {
- if (rhs->type == lhs_type)
- return rhs;
- }
-
- return NULL;
-}
-
-ir_rvalue *
-do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
- ir_rvalue *lhs, ir_rvalue *rhs,
- YYLTYPE lhs_loc)
-{
- void *ctx = state;
- bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
-
- if (!error_emitted) {
- if (lhs->variable_referenced() != NULL
- && lhs->variable_referenced()->read_only) {
- _mesa_glsl_error(&lhs_loc, state,
- "assignment to read-only variable '%s'",
- lhs->variable_referenced()->name);
- error_emitted = true;
-
- } else if (!lhs->is_lvalue()) {
- _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
- error_emitted = true;
- }
-
- if (state->es_shader && lhs->type->is_array()) {
- _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not "
- "allowed in GLSL ES 1.00.");
- error_emitted = true;
- }
- }
-
- ir_rvalue *new_rhs = validate_assignment(state, lhs->type, rhs);
- if (new_rhs == NULL) {
- _mesa_glsl_error(& lhs_loc, state, "type mismatch");
- } else {
- rhs = new_rhs;
-
- /* If the LHS array was not declared with a size, it takes it size from
- * the RHS. If the LHS is an l-value and a whole array, it must be a
- * dereference of a variable. Any other case would require that the LHS
- * is either not an l-value or not a whole array.
- */
- if (lhs->type->array_size() == 0) {
- ir_dereference *const d = lhs->as_dereference();
-
- assert(d != NULL);
-
- ir_variable *const var = d->variable_referenced();
-
- assert(var != NULL);
-
- if (var->max_array_access >= unsigned(rhs->type->array_size())) {
- /* FINISHME: This should actually log the location of the RHS. */
- _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
- "previous access",
- var->max_array_access);
- }
-
- var->type = glsl_type::get_array_instance(lhs->type->element_type(),
- rhs->type->array_size());
- d->type = var->type;
- }
- }
-
- /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
- * but not post_inc) need the converted assigned value as an rvalue
- * to handle things like:
- *
- * i = j += 1;
- *
- * So we always just store the computed value being assigned to a
- * temporary and return a deref of that temporary. If the rvalue
- * ends up not being used, the temp will get copy-propagated out.
- */
- ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp",
- ir_var_temporary);
- ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
- instructions->push_tail(var);
- instructions->push_tail(new(ctx) ir_assignment(deref_var,
- rhs,
- NULL));
- deref_var = new(ctx) ir_dereference_variable(var);
-
- if (!error_emitted)
- instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var, NULL));
-
- return new(ctx) ir_dereference_variable(var);
-}
-
-static ir_rvalue *
-get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
-{
- void *ctx = ralloc_parent(lvalue);
- ir_variable *var;
-
- var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
- ir_var_temporary);
- instructions->push_tail(var);
- var->mode = ir_var_auto;
-
- instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
- lvalue, NULL));
-
- /* Once we've created this temporary, mark it read only so it's no
- * longer considered an lvalue.
- */
- var->read_only = true;
-
- return new(ctx) ir_dereference_variable(var);
-}
-
-
-ir_rvalue *
-ast_node::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- (void) instructions;
- (void) state;
-
- return NULL;
-}
-
-static void
-mark_whole_array_access(ir_rvalue *access)
-{
- ir_dereference_variable *deref = access->as_dereference_variable();
-
- if (deref) {
- deref->var->max_array_access = deref->type->length - 1;
- }
-}
-
-static ir_rvalue *
-do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
-{
- int join_op;
- ir_rvalue *cmp = NULL;
-
- if (operation == ir_binop_all_equal)
- join_op = ir_binop_logic_and;
- else
- join_op = ir_binop_logic_or;
-
- switch (op0->type->base_type) {
- case GLSL_TYPE_FLOAT:
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- case GLSL_TYPE_BOOL:
- return new(mem_ctx) ir_expression(operation, op0, op1);
-
- case GLSL_TYPE_ARRAY: {
- for (unsigned int i = 0; i < op0->type->length; i++) {
- ir_rvalue *e0, *e1, *result;
-
- e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL),
- new(mem_ctx) ir_constant(i));
- e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL),
- new(mem_ctx) ir_constant(i));
- result = do_comparison(mem_ctx, operation, e0, e1);
-
- if (cmp) {
- cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
- } else {
- cmp = result;
- }
- }
-
- mark_whole_array_access(op0);
- mark_whole_array_access(op1);
- break;
- }
-
- case GLSL_TYPE_STRUCT: {
- for (unsigned int i = 0; i < op0->type->length; i++) {
- ir_rvalue *e0, *e1, *result;
- const char *field_name = op0->type->fields.structure[i].name;
-
- e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL),
- field_name);
- e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL),
- field_name);
- result = do_comparison(mem_ctx, operation, e0, e1);
-
- if (cmp) {
- cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
- } else {
- cmp = result;
- }
- }
- break;
- }
-
- case GLSL_TYPE_ERROR:
- case GLSL_TYPE_VOID:
- case GLSL_TYPE_SAMPLER:
- /* I assume a comparison of a struct containing a sampler just
- * ignores the sampler present in the type.
- */
- break;
-
- default:
- assert(!"Should not get here.");
- break;
- }
-
- if (cmp == NULL)
- cmp = new(mem_ctx) ir_constant(true);
-
- return cmp;
-}
-
-ir_rvalue *
-ast_expression::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = state;
- static const int operations[AST_NUM_OPERATORS] = {
- -1, /* ast_assign doesn't convert to ir_expression. */
- -1, /* ast_plus doesn't convert to ir_expression. */
- ir_unop_neg,
- ir_binop_add,
- ir_binop_sub,
- ir_binop_mul,
- ir_binop_div,
- ir_binop_mod,
- ir_binop_lshift,
- ir_binop_rshift,
- ir_binop_less,
- ir_binop_greater,
- ir_binop_lequal,
- ir_binop_gequal,
- ir_binop_all_equal,
- ir_binop_any_nequal,
- ir_binop_bit_and,
- ir_binop_bit_xor,
- ir_binop_bit_or,
- ir_unop_bit_not,
- ir_binop_logic_and,
- ir_binop_logic_xor,
- ir_binop_logic_or,
- ir_unop_logic_not,
-
- /* Note: The following block of expression types actually convert
- * to multiple IR instructions.
- */
- ir_binop_mul, /* ast_mul_assign */
- ir_binop_div, /* ast_div_assign */
- ir_binop_mod, /* ast_mod_assign */
- ir_binop_add, /* ast_add_assign */
- ir_binop_sub, /* ast_sub_assign */
- ir_binop_lshift, /* ast_ls_assign */
- ir_binop_rshift, /* ast_rs_assign */
- ir_binop_bit_and, /* ast_and_assign */
- ir_binop_bit_xor, /* ast_xor_assign */
- ir_binop_bit_or, /* ast_or_assign */
-
- -1, /* ast_conditional doesn't convert to ir_expression. */
- ir_binop_add, /* ast_pre_inc. */
- ir_binop_sub, /* ast_pre_dec. */
- ir_binop_add, /* ast_post_inc. */
- ir_binop_sub, /* ast_post_dec. */
- -1, /* ast_field_selection doesn't conv to ir_expression. */
- -1, /* ast_array_index doesn't convert to ir_expression. */
- -1, /* ast_function_call doesn't conv to ir_expression. */
- -1, /* ast_identifier doesn't convert to ir_expression. */
- -1, /* ast_int_constant doesn't convert to ir_expression. */
- -1, /* ast_uint_constant doesn't conv to ir_expression. */
- -1, /* ast_float_constant doesn't conv to ir_expression. */
- -1, /* ast_bool_constant doesn't conv to ir_expression. */
- -1, /* ast_sequence doesn't convert to ir_expression. */
- };
- ir_rvalue *result = NULL;
- ir_rvalue *op[3];
- const struct glsl_type *type = glsl_type::error_type;
- bool error_emitted = false;
- YYLTYPE loc;
-
- loc = this->get_location();
-
- switch (this->oper) {
- case ast_assign: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- result = do_assignment(instructions, state, op[0], op[1],
- this->subexpressions[0]->get_location());
- error_emitted = result->type->is_error();
- type = result->type;
- break;
- }
-
- case ast_plus:
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- type = unary_arithmetic_result_type(op[0]->type, state, & loc);
-
- error_emitted = type->is_error();
-
- result = op[0];
- break;
-
- case ast_neg:
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- type = unary_arithmetic_result_type(op[0]->type, state, & loc);
-
- error_emitted = type->is_error();
-
- result = new(ctx) ir_expression(operations[this->oper], type,
- op[0], NULL);
- break;
-
- case ast_add:
- case ast_sub:
- case ast_mul:
- case ast_div:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- type = arithmetic_result_type(op[0], op[1],
- (this->oper == ast_mul),
- state, & loc);
- error_emitted = type->is_error();
-
- result = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
- break;
-
- case ast_mod:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
-
- assert(operations[this->oper] == ir_binop_mod);
-
- result = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
- error_emitted = type->is_error();
- break;
-
- case ast_lshift:
- case ast_rshift:
- if (state->language_version < 130) {
- _mesa_glsl_error(&loc, state, "operator %s requires GLSL 1.30",
- operator_string(this->oper));
- error_emitted = true;
- }
-
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
- type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
- &loc);
- result = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
- error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
- break;
-
- case ast_less:
- case ast_greater:
- case ast_lequal:
- case ast_gequal:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- type = relational_result_type(op[0], op[1], state, & loc);
-
- /* The relational operators must either generate an error or result
- * in a scalar boolean. See page 57 of the GLSL 1.50 spec.
- */
- assert(type->is_error()
- || ((type->base_type == GLSL_TYPE_BOOL)
- && type->is_scalar()));
-
- result = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
- error_emitted = type->is_error();
- break;
-
- case ast_nequal:
- case ast_equal:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec:
- *
- * "The equality operators equal (==), and not equal (!=)
- * operate on all types. They result in a scalar Boolean. If
- * the operand types do not match, then there must be a
- * conversion from Section 4.1.10 "Implicit Conversions"
- * applied to one operand that can make them match, in which
- * case this conversion is done."
- */
- if ((!apply_implicit_conversion(op[0]->type, op[1], state)
- && !apply_implicit_conversion(op[1]->type, op[0], state))
- || (op[0]->type != op[1]->type)) {
- _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
- "type", (this->oper == ast_equal) ? "==" : "!=");
- error_emitted = true;
- } else if ((state->language_version <= 110)
- && (op[0]->type->is_array() || op[1]->type->is_array())) {
- _mesa_glsl_error(& loc, state, "array comparisons forbidden in "
- "GLSL 1.10");
- error_emitted = true;
- }
-
- result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
- type = glsl_type::bool_type;
-
- assert(error_emitted || (result->type == glsl_type::bool_type));
- break;
-
- case ast_bit_and:
- case ast_bit_xor:
- case ast_bit_or:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
- type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper,
- state, &loc);
- result = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
- error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
- break;
-
- case ast_bit_not:
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- if (state->language_version < 130) {
- _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30");
- error_emitted = true;
- }
-
- if (!op[0]->type->is_integer()) {
- _mesa_glsl_error(&loc, state, "operand of `~' must be an integer");
- error_emitted = true;
- }
-
- type = op[0]->type;
- result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL);
- break;
-
- case ast_logic_and: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[0]->get_location();
-
- _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
-
- ir_constant *op0_const = op[0]->constant_expression_value();
- if (op0_const) {
- if (op0_const->value.b[0]) {
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[1]->get_location();
-
- _mesa_glsl_error(& loc, state,
- "RHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
- result = op[1];
- } else {
- result = op0_const;
- }
- type = glsl_type::bool_type;
- } else {
- ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
- "and_tmp",
- ir_var_temporary);
- instructions->push_tail(tmp);
-
- ir_if *const stmt = new(ctx) ir_if(op[0]);
- instructions->push_tail(stmt);
-
- op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state);
-
- if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[1]->get_location();
-
- _mesa_glsl_error(& loc, state,
- "RHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
-
- ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const then_assign =
- new(ctx) ir_assignment(then_deref, op[1], NULL);
- stmt->then_instructions.push_tail(then_assign);
-
- ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const else_assign =
- new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false), NULL);
- stmt->else_instructions.push_tail(else_assign);
-
- result = new(ctx) ir_dereference_variable(tmp);
- type = tmp->type;
- }
- break;
- }
-
- case ast_logic_or: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[0]->get_location();
-
- _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
-
- ir_constant *op0_const = op[0]->constant_expression_value();
- if (op0_const) {
- if (op0_const->value.b[0]) {
- result = op0_const;
- } else {
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[1]->get_location();
-
- _mesa_glsl_error(& loc, state,
- "RHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
- result = op[1];
- }
- type = glsl_type::bool_type;
- } else {
- ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
- "or_tmp",
- ir_var_temporary);
- instructions->push_tail(tmp);
-
- ir_if *const stmt = new(ctx) ir_if(op[0]);
- instructions->push_tail(stmt);
-
- op[1] = this->subexpressions[1]->hir(&stmt->else_instructions, state);
-
- if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[1]->get_location();
-
- _mesa_glsl_error(& loc, state, "RHS of `%s' must be scalar boolean",
- operator_string(this->oper));
- error_emitted = true;
- }
-
- ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const then_assign =
- new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true), NULL);
- stmt->then_instructions.push_tail(then_assign);
-
- ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const else_assign =
- new(ctx) ir_assignment(else_deref, op[1], NULL);
- stmt->else_instructions.push_tail(else_assign);
-
- result = new(ctx) ir_dereference_variable(tmp);
- type = tmp->type;
- }
- break;
- }
-
- case ast_logic_xor:
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
-
- result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
- op[0], op[1]);
- type = glsl_type::bool_type;
- break;
-
- case ast_logic_not:
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[0]->get_location();
-
- _mesa_glsl_error(& loc, state,
- "operand of `!' must be scalar boolean");
- error_emitted = true;
- }
-
- result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
- op[0], NULL);
- type = glsl_type::bool_type;
- break;
-
- case ast_mul_assign:
- case ast_div_assign:
- case ast_add_assign:
- case ast_sub_assign: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- type = arithmetic_result_type(op[0], op[1],
- (this->oper == ast_mul_assign),
- state, & loc);
-
- ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
-
- result = do_assignment(instructions, state,
- op[0]->clone(ctx, NULL), temp_rhs,
- this->subexpressions[0]->get_location());
- type = result->type;
- error_emitted = (op[0]->type->is_error());
-
- /* GLSL 1.10 does not allow array assignment. However, we don't have to
- * explicitly test for this because none of the binary expression
- * operators allow array operands either.
- */
-
- break;
- }
-
- case ast_mod_assign: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
-
- type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
-
- assert(operations[this->oper] == ir_binop_mod);
-
- ir_rvalue *temp_rhs;
- temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
-
- result = do_assignment(instructions, state,
- op[0]->clone(ctx, NULL), temp_rhs,
- this->subexpressions[0]->get_location());
- type = result->type;
- error_emitted = type->is_error();
- break;
- }
-
- case ast_ls_assign:
- case ast_rs_assign: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
- type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
- &loc);
- ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
- type, op[0], op[1]);
- result = do_assignment(instructions, state, op[0]->clone(ctx, NULL),
- temp_rhs,
- this->subexpressions[0]->get_location());
- error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
- break;
- }
-
- case ast_and_assign:
- case ast_xor_assign:
- case ast_or_assign: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- op[1] = this->subexpressions[1]->hir(instructions, state);
- type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper,
- state, &loc);
- ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
- type, op[0], op[1]);
- result = do_assignment(instructions, state, op[0]->clone(ctx, NULL),
- temp_rhs,
- this->subexpressions[0]->get_location());
- error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
- break;
- }
-
- case ast_conditional: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
-
- /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
- *
- * "The ternary selection operator (?:). It operates on three
- * expressions (exp1 ? exp2 : exp3). This operator evaluates the
- * first expression, which must result in a scalar Boolean."
- */
- if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
- YYLTYPE loc = this->subexpressions[0]->get_location();
-
- _mesa_glsl_error(& loc, state, "?: condition must be scalar boolean");
- error_emitted = true;
- }
-
- /* The :? operator is implemented by generating an anonymous temporary
- * followed by an if-statement. The last instruction in each branch of
- * the if-statement assigns a value to the anonymous temporary. This
- * temporary is the r-value of the expression.
- */
- exec_list then_instructions;
- exec_list else_instructions;
-
- op[1] = this->subexpressions[1]->hir(&then_instructions, state);
- op[2] = this->subexpressions[2]->hir(&else_instructions, state);
-
- /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
- *
- * "The second and third expressions can be any type, as
- * long their types match, or there is a conversion in
- * Section 4.1.10 "Implicit Conversions" that can be applied
- * to one of the expressions to make their types match. This
- * resulting matching type is the type of the entire
- * expression."
- */
- if ((!apply_implicit_conversion(op[1]->type, op[2], state)
- && !apply_implicit_conversion(op[2]->type, op[1], state))
- || (op[1]->type != op[2]->type)) {
- YYLTYPE loc = this->subexpressions[1]->get_location();
-
- _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
- "operator must have matching types.");
- error_emitted = true;
- type = glsl_type::error_type;
- } else {
- type = op[1]->type;
- }
-
- /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
- *
- * "The second and third expressions must be the same type, but can
- * be of any type other than an array."
- */
- if ((state->language_version <= 110) && type->is_array()) {
- _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
- "operator must not be arrays.");
- error_emitted = true;
- }
-
- ir_constant *cond_val = op[0]->constant_expression_value();
- ir_constant *then_val = op[1]->constant_expression_value();
- ir_constant *else_val = op[2]->constant_expression_value();
-
- if (then_instructions.is_empty()
- && else_instructions.is_empty()
- && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) {
- result = (cond_val->value.b[0]) ? then_val : else_val;
- } else {
- ir_variable *const tmp =
- new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
- instructions->push_tail(tmp);
-
- ir_if *const stmt = new(ctx) ir_if(op[0]);
- instructions->push_tail(stmt);
-
- then_instructions.move_nodes_to(& stmt->then_instructions);
- ir_dereference *const then_deref =
- new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const then_assign =
- new(ctx) ir_assignment(then_deref, op[1], NULL);
- stmt->then_instructions.push_tail(then_assign);
-
- else_instructions.move_nodes_to(& stmt->else_instructions);
- ir_dereference *const else_deref =
- new(ctx) ir_dereference_variable(tmp);
- ir_assignment *const else_assign =
- new(ctx) ir_assignment(else_deref, op[2], NULL);
- stmt->else_instructions.push_tail(else_assign);
-
- result = new(ctx) ir_dereference_variable(tmp);
- }
- break;
- }
-
- case ast_pre_inc:
- case ast_pre_dec: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
- op[1] = new(ctx) ir_constant(1.0f);
- else
- op[1] = new(ctx) ir_constant(1);
-
- type = arithmetic_result_type(op[0], op[1], false, state, & loc);
-
- ir_rvalue *temp_rhs;
- temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
-
- result = do_assignment(instructions, state,
- op[0]->clone(ctx, NULL), temp_rhs,
- this->subexpressions[0]->get_location());
- type = result->type;
- error_emitted = op[0]->type->is_error();
- break;
- }
-
- case ast_post_inc:
- case ast_post_dec: {
- op[0] = this->subexpressions[0]->hir(instructions, state);
- if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
- op[1] = new(ctx) ir_constant(1.0f);
- else
- op[1] = new(ctx) ir_constant(1);
-
- error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
-
- type = arithmetic_result_type(op[0], op[1], false, state, & loc);
-
- ir_rvalue *temp_rhs;
- temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
- op[0], op[1]);
-
- /* Get a temporary of a copy of the lvalue before it's modified.
- * This may get thrown away later.
- */
- result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL));
-
- (void)do_assignment(instructions, state,
- op[0]->clone(ctx, NULL), temp_rhs,
- this->subexpressions[0]->get_location());
-
- type = result->type;
- error_emitted = op[0]->type->is_error();
- break;
- }
-
- case ast_field_selection:
- result = _mesa_ast_field_selection_to_hir(this, instructions, state);
- type = result->type;
- break;
-
- case ast_array_index: {
- YYLTYPE index_loc = subexpressions[1]->get_location();
-
- op[0] = subexpressions[0]->hir(instructions, state);
- op[1] = subexpressions[1]->hir(instructions, state);
-
- error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
-
- ir_rvalue *const array = op[0];
-
- result = new(ctx) ir_dereference_array(op[0], op[1]);
-
- /* Do not use op[0] after this point. Use array.
- */
- op[0] = NULL;
-
-
- if (error_emitted)
- break;
-
- if (!array->type->is_array()
- && !array->type->is_matrix()
- && !array->type->is_vector()) {
- _mesa_glsl_error(& index_loc, state,
- "cannot dereference non-array / non-matrix / "
- "non-vector");
- error_emitted = true;
- }
-
- if (!op[1]->type->is_integer()) {
- _mesa_glsl_error(& index_loc, state,
- "array index must be integer type");
- error_emitted = true;
- } else if (!op[1]->type->is_scalar()) {
- _mesa_glsl_error(& index_loc, state,
- "array index must be scalar");
- error_emitted = true;
- }
-
- /* If the array index is a constant expression and the array has a
- * declared size, ensure that the access is in-bounds. If the array
- * index is not a constant expression, ensure that the array has a
- * declared size.
- */
- ir_constant *const const_index = op[1]->constant_expression_value();
- if (const_index != NULL) {
- const int idx = const_index->value.i[0];
- const char *type_name;
- unsigned bound = 0;
-
- if (array->type->is_matrix()) {
- type_name = "matrix";
- } else if (array->type->is_vector()) {
- type_name = "vector";
- } else {
- type_name = "array";
- }
-
- /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec:
- *
- * "It is illegal to declare an array with a size, and then
- * later (in the same shader) index the same array with an
- * integral constant expression greater than or equal to the
- * declared size. It is also illegal to index an array with a
- * negative constant expression."
- */
- if (array->type->is_matrix()) {
- if (array->type->row_type()->vector_elements <= idx) {
- bound = array->type->row_type()->vector_elements;
- }
- } else if (array->type->is_vector()) {
- if (array->type->vector_elements <= idx) {
- bound = array->type->vector_elements;
- }
- } else {
- if ((array->type->array_size() > 0)
- && (array->type->array_size() <= idx)) {
- bound = array->type->array_size();
- }
- }
-
- if (bound > 0) {
- _mesa_glsl_error(& loc, state, "%s index must be < %u",
- type_name, bound);
- error_emitted = true;
- } else if (idx < 0) {
- _mesa_glsl_error(& loc, state, "%s index must be >= 0",
- type_name);
- error_emitted = true;
- }
-
- if (array->type->is_array()) {
- /* If the array is a variable dereference, it dereferences the
- * whole array, by definition. Use this to get the variable.
- *
- * FINISHME: Should some methods for getting / setting / testing
- * FINISHME: array access limits be added to ir_dereference?
- */
- ir_variable *const v = array->whole_variable_referenced();
- if ((v != NULL) && (unsigned(idx) > v->max_array_access))
- v->max_array_access = idx;
- }
- } else if (array->type->array_size() == 0) {
- _mesa_glsl_error(&loc, state, "unsized array index must be constant");
- } else {
- if (array->type->is_array()) {
- /* whole_variable_referenced can return NULL if the array is a
- * member of a structure. In this case it is safe to not update
- * the max_array_access field because it is never used for fields
- * of structures.
- */
- ir_variable *v = array->whole_variable_referenced();
- if (v != NULL)
- v->max_array_access = array->type->array_size();
- }
- }
-
- /* From page 23 (29 of the PDF) of the GLSL 1.30 spec:
- *
- * "Samplers aggregated into arrays within a shader (using square
- * brackets [ ]) can only be indexed with integral constant
- * expressions [...]."
- *
- * This restriction was added in GLSL 1.30. Shaders using earlier version
- * of the language should not be rejected by the compiler front-end for
- * using this construct. This allows useful things such as using a loop
- * counter as the index to an array of samplers. If the loop in unrolled,
- * the code should compile correctly. Instead, emit a warning.
- */
- if (array->type->is_array() &&
- array->type->element_type()->is_sampler() &&
- const_index == NULL) {
-
- if (state->language_version == 100) {
- _mesa_glsl_warning(&loc, state,
- "sampler arrays indexed with non-constant "
- "expressions is optional in GLSL ES 1.00");
- } else if (state->language_version < 130) {
- _mesa_glsl_warning(&loc, state,
- "sampler arrays indexed with non-constant "
- "expressions is forbidden in GLSL 1.30 and "
- "later");
- } else {
- _mesa_glsl_error(&loc, state,
- "sampler arrays indexed with non-constant "
- "expressions is forbidden in GLSL 1.30 and "
- "later");
- error_emitted = true;
- }
- }
-
- if (error_emitted)
- result->type = glsl_type::error_type;
-
- type = result->type;
- break;
- }
-
- case ast_function_call:
- /* Should *NEVER* get here. ast_function_call should always be handled
- * by ast_function_expression::hir.
- */
- assert(0);
- break;
-
- case ast_identifier: {
- /* ast_identifier can appear several places in a full abstract syntax
- * tree. This particular use must be at location specified in the grammar
- * as 'variable_identifier'.
- */
- ir_variable *var =
- state->symbols->get_variable(this->primary_expression.identifier);
-
- result = new(ctx) ir_dereference_variable(var);
-
- if (var != NULL) {
- var->used = true;
- type = result->type;
- } else {
- _mesa_glsl_error(& loc, state, "`%s' undeclared",
- this->primary_expression.identifier);
-
- error_emitted = true;
- }
- break;
- }
-
- case ast_int_constant:
- type = glsl_type::int_type;
- result = new(ctx) ir_constant(this->primary_expression.int_constant);
- break;
-
- case ast_uint_constant:
- type = glsl_type::uint_type;
- result = new(ctx) ir_constant(this->primary_expression.uint_constant);
- break;
-
- case ast_float_constant:
- type = glsl_type::float_type;
- result = new(ctx) ir_constant(this->primary_expression.float_constant);
- break;
-
- case ast_bool_constant:
- type = glsl_type::bool_type;
- result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
- break;
-
- case ast_sequence: {
- /* It should not be possible to generate a sequence in the AST without
- * any expressions in it.
- */
- assert(!this->expressions.is_empty());
-
- /* The r-value of a sequence is the last expression in the sequence. If
- * the other expressions in the sequence do not have side-effects (and
- * therefore add instructions to the instruction list), they get dropped
- * on the floor.
- */
- foreach_list_typed (ast_node, ast, link, &this->expressions)
- result = ast->hir(instructions, state);
-
- type = result->type;
-
- /* Any errors should have already been emitted in the loop above.
- */
- error_emitted = true;
- break;
- }
- }
-
- if (type->is_error() && !error_emitted)
- _mesa_glsl_error(& loc, state, "type mismatch");
-
- return result;
-}
-
-
-ir_rvalue *
-ast_expression_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- /* It is possible to have expression statements that don't have an
- * expression. This is the solitary semicolon:
- *
- * for (i = 0; i < 5; i++)
- * ;
- *
- * In this case the expression will be NULL. Test for NULL and don't do
- * anything in that case.
- */
- if (expression != NULL)
- expression->hir(instructions, state);
-
- /* Statements do not have r-values.
- */
- return NULL;
-}
-
-
-ir_rvalue *
-ast_compound_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- if (new_scope)
- state->symbols->push_scope();
-
- foreach_list_typed (ast_node, ast, link, &this->statements)
- ast->hir(instructions, state);
-
- if (new_scope)
- state->symbols->pop_scope();
-
- /* Compound statements do not have r-values.
- */
- return NULL;
-}
-
-
-static const glsl_type *
-process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
- struct _mesa_glsl_parse_state *state)
-{
- unsigned length = 0;
-
- /* FINISHME: Reject delcarations of multidimensional arrays. */
-
- if (array_size != NULL) {
- exec_list dummy_instructions;
- ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
- YYLTYPE loc = array_size->get_location();
-
- /* FINISHME: Verify that the grammar forbids side-effects in array
- * FINISHME: sizes. i.e., 'vec4 [x = 12] data'
- */
- assert(dummy_instructions.is_empty());
-
- if (ir != NULL) {
- if (!ir->type->is_integer()) {
- _mesa_glsl_error(& loc, state, "array size must be integer type");
- } else if (!ir->type->is_scalar()) {
- _mesa_glsl_error(& loc, state, "array size must be scalar type");
- } else {
- ir_constant *const size = ir->constant_expression_value();
-
- if (size == NULL) {
- _mesa_glsl_error(& loc, state, "array size must be a "
- "constant valued expression");
- } else if (size->value.i[0] <= 0) {
- _mesa_glsl_error(& loc, state, "array size must be > 0");
- } else {
- assert(size->type == ir->type);
- length = size->value.u[0];
- }
- }
- }
- } else if (state->es_shader) {
- /* Section 10.17 of the GLSL ES 1.00 specification states that unsized
- * array declarations have been removed from the language.
- */
- _mesa_glsl_error(loc, state, "unsized array declarations are not "
- "allowed in GLSL ES 1.00.");
- }
-
- return glsl_type::get_array_instance(base, length);
-}
-
-
-const glsl_type *
-ast_type_specifier::glsl_type(const char **name,
- struct _mesa_glsl_parse_state *state) const
-{
- const struct glsl_type *type;
-
- type = state->symbols->get_type(this->type_name);
- *name = this->type_name;
-
- if (this->is_array) {
- YYLTYPE loc = this->get_location();
- type = process_array_type(&loc, type, this->array_size, state);
- }
-
- return type;
-}
-
-
-static void
-apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
- ir_variable *var,
- struct _mesa_glsl_parse_state *state,
- YYLTYPE *loc)
-{
- if (qual->flags.q.invariant) {
- if (var->used) {
- _mesa_glsl_error(loc, state,
- "variable `%s' may not be redeclared "
- "`invariant' after being used",
- var->name);
- } else {
- var->invariant = 1;
- }
- }
-
- if (qual->flags.q.constant || qual->flags.q.attribute
- || qual->flags.q.uniform
- || (qual->flags.q.varying && (state->target == fragment_shader)))
- var->read_only = 1;
-
- if (qual->flags.q.centroid)
- var->centroid = 1;
-
- if (qual->flags.q.attribute && state->target != vertex_shader) {
- var->type = glsl_type::error_type;
- _mesa_glsl_error(loc, state,
- "`attribute' variables may not be declared in the "
- "%s shader",
- _mesa_glsl_shader_target_name(state->target));
- }
-
- /* From page 25 (page 31 of the PDF) of the GLSL 1.10 spec:
- *
- * "The varying qualifier can be used only with the data types
- * float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of
- * these."
- */
- if (qual->flags.q.varying) {
- const glsl_type *non_array_type;
-
- if (var->type && var->type->is_array())
- non_array_type = var->type->fields.array;
- else
- non_array_type = var->type;
-
- if (non_array_type && non_array_type->base_type != GLSL_TYPE_FLOAT) {
- var->type = glsl_type::error_type;
- _mesa_glsl_error(loc, state,
- "varying variables must be of base type float");
- }
- }
-
- /* If there is no qualifier that changes the mode of the variable, leave
- * the setting alone.
- */
- if (qual->flags.q.in && qual->flags.q.out)
- var->mode = ir_var_inout;
- else if (qual->flags.q.attribute || qual->flags.q.in
- || (qual->flags.q.varying && (state->target == fragment_shader)))
- var->mode = ir_var_in;
- else if (qual->flags.q.out
- || (qual->flags.q.varying && (state->target == vertex_shader)))
- var->mode = ir_var_out;
- else if (qual->flags.q.uniform)
- var->mode = ir_var_uniform;
-
- if (state->all_invariant && (state->current_function == NULL)) {
- switch (state->target) {
- case vertex_shader:
- if (var->mode == ir_var_out)
- var->invariant = true;
- break;
- case geometry_shader:
- if ((var->mode == ir_var_in) || (var->mode == ir_var_out))
- var->invariant = true;
- break;
- case fragment_shader:
- if (var->mode == ir_var_in)
- var->invariant = true;
- break;
- }
- }
-
- if (qual->flags.q.flat)
- var->interpolation = ir_var_flat;
- else if (qual->flags.q.noperspective)
- var->interpolation = ir_var_noperspective;
- else
- var->interpolation = ir_var_smooth;
-
- var->pixel_center_integer = qual->flags.q.pixel_center_integer;
- var->origin_upper_left = qual->flags.q.origin_upper_left;
- if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer)
- && (strcmp(var->name, "gl_FragCoord") != 0)) {
- const char *const qual_string = (qual->flags.q.origin_upper_left)
- ? "origin_upper_left" : "pixel_center_integer";
-
- _mesa_glsl_error(loc, state,
- "layout qualifier `%s' can only be applied to "
- "fragment shader input `gl_FragCoord'",
- qual_string);
- }
-
- if (qual->flags.q.explicit_location) {
- const bool global_scope = (state->current_function == NULL);
- bool fail = false;
- const char *string = "";
-
- /* In the vertex shader only shader inputs can be given explicit
- * locations.
- *
- * In the fragment shader only shader outputs can be given explicit
- * locations.
- */
- switch (state->target) {
- case vertex_shader:
- if (!global_scope || (var->mode != ir_var_in)) {
- fail = true;
- string = "input";
- }
- break;
-
- case geometry_shader:
- _mesa_glsl_error(loc, state,
- "geometry shader variables cannot be given "
- "explicit locations\n");
- break;
-
- case fragment_shader:
- if (!global_scope || (var->mode != ir_var_in)) {
- fail = true;
- string = "output";
- }
- break;
- };
-
- if (fail) {
- _mesa_glsl_error(loc, state,
- "only %s shader %s variables can be given an "
- "explicit location\n",
- _mesa_glsl_shader_target_name(state->target),
- string);
- } else {
- var->explicit_location = true;
-
- /* This bit of silliness is needed because invalid explicit locations
- * are supposed to be flagged during linking. Small negative values
- * biased by VERT_ATTRIB_GENERIC0 or FRAG_RESULT_DATA0 could alias
- * built-in values (e.g., -16+VERT_ATTRIB_GENERIC0 = VERT_ATTRIB_POS).
- * The linker needs to be able to differentiate these cases. This
- * ensures that negative values stay negative.
- */
- if (qual->location >= 0) {
- var->location = (state->target == vertex_shader)
- ? (qual->location + VERT_ATTRIB_GENERIC0)
- : (qual->location + FRAG_RESULT_DATA0);
- } else {
- var->location = qual->location;
- }
- }
- }
-
- /* Does the declaration use the 'layout' keyword?
- */
- const bool uses_layout = qual->flags.q.pixel_center_integer
- || qual->flags.q.origin_upper_left
- || qual->flags.q.explicit_location;
-
- /* Does the declaration use the deprecated 'attribute' or 'varying'
- * keywords?
- */
- const bool uses_deprecated_qualifier = qual->flags.q.attribute
- || qual->flags.q.varying;
-
- /* Is the 'layout' keyword used with parameters that allow relaxed checking.
- * Many implementations of GL_ARB_fragment_coord_conventions_enable and some
- * implementations (only Mesa?) GL_ARB_explicit_attrib_location_enable
- * allowed the layout qualifier to be used with 'varying' and 'attribute'.
- * These extensions and all following extensions that add the 'layout'
- * keyword have been modified to require the use of 'in' or 'out'.
- *
- * The following extension do not allow the deprecated keywords:
- *
- * GL_AMD_conservative_depth
- * GL_ARB_gpu_shader5
- * GL_ARB_separate_shader_objects
- * GL_ARB_tesselation_shader
- * GL_ARB_transform_feedback3
- * GL_ARB_uniform_buffer_object
- *
- * It is unknown whether GL_EXT_shader_image_load_store or GL_NV_gpu_shader5
- * allow layout with the deprecated keywords.
- */
- const bool relaxed_layout_qualifier_checking =
- state->ARB_fragment_coord_conventions_enable;
-
- if (uses_layout && uses_deprecated_qualifier) {
- if (relaxed_layout_qualifier_checking) {
- _mesa_glsl_warning(loc, state,
- "`layout' qualifier may not be used with "
- "`attribute' or `varying'");
- } else {
- _mesa_glsl_error(loc, state,
- "`layout' qualifier may not be used with "
- "`attribute' or `varying'");
- }
- }
-
- /* Layout qualifiers for gl_FragDepth, which are enabled by extension
- * AMD_conservative_depth.
- */
- int depth_layout_count = qual->flags.q.depth_any
- + qual->flags.q.depth_greater
- + qual->flags.q.depth_less
- + qual->flags.q.depth_unchanged;
- if (depth_layout_count > 0
- && !state->AMD_conservative_depth_enable) {
- _mesa_glsl_error(loc, state,
- "extension GL_AMD_conservative_depth must be enabled "
- "to use depth layout qualifiers");
- } else if (depth_layout_count > 0
- && strcmp(var->name, "gl_FragDepth") != 0) {
- _mesa_glsl_error(loc, state,
- "depth layout qualifiers can be applied only to "
- "gl_FragDepth");
- } else if (depth_layout_count > 1
- && strcmp(var->name, "gl_FragDepth") == 0) {
- _mesa_glsl_error(loc, state,
- "at most one depth layout qualifier can be applied to "
- "gl_FragDepth");
- }
- if (qual->flags.q.depth_any)
- var->depth_layout = ir_depth_layout_any;
- else if (qual->flags.q.depth_greater)
- var->depth_layout = ir_depth_layout_greater;
- else if (qual->flags.q.depth_less)
- var->depth_layout = ir_depth_layout_less;
- else if (qual->flags.q.depth_unchanged)
- var->depth_layout = ir_depth_layout_unchanged;
- else
- var->depth_layout = ir_depth_layout_none;
-
- if (var->type->is_array() && state->language_version != 110) {
- var->array_lvalue = true;
- }
-}
-
-
-ir_rvalue *
-ast_declarator_list::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = state;
- const struct glsl_type *decl_type;
- const char *type_name = NULL;
- ir_rvalue *result = NULL;
- YYLTYPE loc = this->get_location();
-
- /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec:
- *
- * "To ensure that a particular output variable is invariant, it is
- * necessary to use the invariant qualifier. It can either be used to
- * qualify a previously declared variable as being invariant
- *
- * invariant gl_Position; // make existing gl_Position be invariant"
- *
- * In these cases the parser will set the 'invariant' flag in the declarator
- * list, and the type will be NULL.
- */
- if (this->invariant) {
- assert(this->type == NULL);
-
- if (state->current_function != NULL) {
- _mesa_glsl_error(& loc, state,
- "All uses of `invariant' keyword must be at global "
- "scope\n");
- }
-
- foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
- assert(!decl->is_array);
- assert(decl->array_size == NULL);
- assert(decl->initializer == NULL);
-
- ir_variable *const earlier =
- state->symbols->get_variable(decl->identifier);
- if (earlier == NULL) {
- _mesa_glsl_error(& loc, state,
- "Undeclared variable `%s' cannot be marked "
- "invariant\n", decl->identifier);
- } else if ((state->target == vertex_shader)
- && (earlier->mode != ir_var_out)) {
- _mesa_glsl_error(& loc, state,
- "`%s' cannot be marked invariant, vertex shader "
- "outputs only\n", decl->identifier);
- } else if ((state->target == fragment_shader)
- && (earlier->mode != ir_var_in)) {
- _mesa_glsl_error(& loc, state,
- "`%s' cannot be marked invariant, fragment shader "
- "inputs only\n", decl->identifier);
- } else if (earlier->used) {
- _mesa_glsl_error(& loc, state,
- "variable `%s' may not be redeclared "
- "`invariant' after being used",
- earlier->name);
- } else {
- earlier->invariant = true;
- }
- }
-
- /* Invariant redeclarations do not have r-values.
- */
- return NULL;
- }
-
- assert(this->type != NULL);
- assert(!this->invariant);
-
- /* The type specifier may contain a structure definition. Process that
- * before any of the variable declarations.
- */
- (void) this->type->specifier->hir(instructions, state);
-
- decl_type = this->type->specifier->glsl_type(& type_name, state);
- if (this->declarations.is_empty()) {
- /* The only valid case where the declaration list can be empty is when
- * the declaration is setting the default precision of a built-in type
- * (e.g., 'precision highp vec4;').
- */
-
- if (decl_type != NULL) {
- } else {
- _mesa_glsl_error(& loc, state, "incomplete declaration");
- }
- }
-
- foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
- const struct glsl_type *var_type;
- ir_variable *var;
-
- /* FINISHME: Emit a warning if a variable declaration shadows a
- * FINISHME: declaration at a higher scope.
- */
-
- if ((decl_type == NULL) || decl_type->is_void()) {
- if (type_name != NULL) {
- _mesa_glsl_error(& loc, state,
- "invalid type `%s' in declaration of `%s'",
- type_name, decl->identifier);
- } else {
- _mesa_glsl_error(& loc, state,
- "invalid type in declaration of `%s'",
- decl->identifier);
- }
- continue;
- }
-
- if (decl->is_array) {
- var_type = process_array_type(&loc, decl_type, decl->array_size,
- state);
- } else {
- var_type = decl_type;
- }
-
- var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
-
- /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
- *
- * "Global variables can only use the qualifiers const,
- * attribute, uni form, or varying. Only one may be
- * specified.
- *
- * Local variables can only use the qualifier const."
- *
- * This is relaxed in GLSL 1.30. It is also relaxed by any extension
- * that adds the 'layout' keyword.
- */
- if ((state->language_version < 130)
- && !state->ARB_explicit_attrib_location_enable
- && !state->ARB_fragment_coord_conventions_enable) {
- if (this->type->qualifier.flags.q.out) {
- _mesa_glsl_error(& loc, state,
- "`out' qualifier in declaration of `%s' "
- "only valid for function parameters in %s.",
- decl->identifier, state->version_string);
- }
- if (this->type->qualifier.flags.q.in) {
- _mesa_glsl_error(& loc, state,
- "`in' qualifier in declaration of `%s' "
- "only valid for function parameters in %s.",
- decl->identifier, state->version_string);
- }
- /* FINISHME: Test for other invalid qualifiers. */
- }
-
- apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
- & loc);
-
- if (this->type->qualifier.flags.q.invariant) {
- if ((state->target == vertex_shader) && !(var->mode == ir_var_out ||
- var->mode == ir_var_inout)) {
- /* FINISHME: Note that this doesn't work for invariant on
- * a function signature outval
- */
- _mesa_glsl_error(& loc, state,
- "`%s' cannot be marked invariant, vertex shader "
- "outputs only\n", var->name);
- } else if ((state->target == fragment_shader) &&
- !(var->mode == ir_var_in || var->mode == ir_var_inout)) {
- /* FINISHME: Note that this doesn't work for invariant on
- * a function signature inval
- */
- _mesa_glsl_error(& loc, state,
- "`%s' cannot be marked invariant, fragment shader "
- "inputs only\n", var->name);
- }
- }
-
- if (state->current_function != NULL) {
- const char *mode = NULL;
- const char *extra = "";
-
- /* There is no need to check for 'inout' here because the parser will
- * only allow that in function parameter lists.
- */
- if (this->type->qualifier.flags.q.attribute) {
- mode = "attribute";
- } else if (this->type->qualifier.flags.q.uniform) {
- mode = "uniform";
- } else if (this->type->qualifier.flags.q.varying) {
- mode = "varying";
- } else if (this->type->qualifier.flags.q.in) {
- mode = "in";
- extra = " or in function parameter list";
- } else if (this->type->qualifier.flags.q.out) {
- mode = "out";
- extra = " or in function parameter list";
- }
-
- if (mode) {
- _mesa_glsl_error(& loc, state,
- "%s variable `%s' must be declared at "
- "global scope%s",
- mode, var->name, extra);
- }
- } else if (var->mode == ir_var_in) {
- var->read_only = true;
-
- if (state->target == vertex_shader) {
- bool error_emitted = false;
-
- /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
- *
- * "Vertex shader inputs can only be float, floating-point
- * vectors, matrices, signed and unsigned integers and integer
- * vectors. Vertex shader inputs can also form arrays of these
- * types, but not structures."
- *
- * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec:
- *
- * "Vertex shader inputs can only be float, floating-point
- * vectors, matrices, signed and unsigned integers and integer
- * vectors. They cannot be arrays or structures."
- *
- * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec:
- *
- * "The attribute qualifier can be used only with float,
- * floating-point vectors, and matrices. Attribute variables
- * cannot be declared as arrays or structures."
- */
- const glsl_type *check_type = var->type->is_array()
- ? var->type->fields.array : var->type;
-
- switch (check_type->base_type) {
- case GLSL_TYPE_FLOAT:
- break;
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- if (state->language_version > 120)
- break;
- /* FALLTHROUGH */
- default:
- _mesa_glsl_error(& loc, state,
- "vertex shader input / attribute cannot have "
- "type %s`%s'",
- var->type->is_array() ? "array of " : "",
- check_type->name);
- error_emitted = true;
- }
-
- if (!error_emitted && (state->language_version <= 130)
- && var->type->is_array()) {
- _mesa_glsl_error(& loc, state,
- "vertex shader input / attribute cannot have "
- "array type");
- error_emitted = true;
- }
- }
- }
-
- /* Integer vertex outputs must be qualified with 'flat'.
- *
- * From section 4.3.6 of the GLSL 1.30 spec:
- * "If a vertex output is a signed or unsigned integer or integer
- * vector, then it must be qualified with the interpolation qualifier
- * flat."
- */
- if (state->language_version >= 130
- && state->target == vertex_shader
- && state->current_function == NULL
- && var->type->is_integer()
- && var->mode == ir_var_out
- && var->interpolation != ir_var_flat) {
-
- _mesa_glsl_error(&loc, state, "If a vertex output is an integer, "
- "then it must be qualified with 'flat'");
- }
-
-
- /* Interpolation qualifiers cannot be applied to 'centroid' and
- * 'centroid varying'.
- *
- * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec:
- * "interpolation qualifiers may only precede the qualifiers in,
- * centroid in, out, or centroid out in a declaration. They do not apply
- * to the deprecated storage qualifiers varying or centroid varying."
- */
- if (state->language_version >= 130
- && this->type->qualifier.has_interpolation()
- && this->type->qualifier.flags.q.varying) {
-
- const char *i = this->type->qualifier.interpolation_string();
- assert(i != NULL);
- const char *s;
- if (this->type->qualifier.flags.q.centroid)
- s = "centroid varying";
- else
- s = "varying";
-
- _mesa_glsl_error(&loc, state,
- "qualifier '%s' cannot be applied to the "
- "deprecated storage qualifier '%s'", i, s);
- }
-
-
- /* Interpolation qualifiers can only apply to vertex shader outputs and
- * fragment shader inputs.
- *
- * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec:
- * "Outputs from a vertex shader (out) and inputs to a fragment
- * shader (in) can be further qualified with one or more of these
- * interpolation qualifiers"
- */
- if (state->language_version >= 130
- && this->type->qualifier.has_interpolation()) {
-
- const char *i = this->type->qualifier.interpolation_string();
- assert(i != NULL);
-
- switch (state->target) {
- case vertex_shader:
- if (this->type->qualifier.flags.q.in) {
- _mesa_glsl_error(&loc, state,
- "qualifier '%s' cannot be applied to vertex "
- "shader inputs", i);
- }
- break;
- case fragment_shader:
- if (this->type->qualifier.flags.q.out) {
- _mesa_glsl_error(&loc, state,
- "qualifier '%s' cannot be applied to fragment "
- "shader outputs", i);
- }
- break;
- default:
- assert(0);
- }
- }
-
-
- /* From section 4.3.4 of the GLSL 1.30 spec:
- * "It is an error to use centroid in in a vertex shader."
- */
- if (state->language_version >= 130
- && this->type->qualifier.flags.q.centroid
- && this->type->qualifier.flags.q.in
- && state->target == vertex_shader) {
-
- _mesa_glsl_error(&loc, state,
- "'centroid in' cannot be used in a vertex shader");
- }
-
-
- /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
- */
- if (this->type->specifier->precision != ast_precision_none
- && state->language_version != 100
- && state->language_version < 130) {
-
- _mesa_glsl_error(&loc, state,
- "precision qualifiers are supported only in GLSL ES "
- "1.00, and GLSL 1.30 and later");
- }
-
-
- /* Precision qualifiers only apply to floating point and integer types.
- *
- * From section 4.5.2 of the GLSL 1.30 spec:
- * "Any floating point or any integer declaration can have the type
- * preceded by one of these precision qualifiers [...] Literal
- * constants do not have precision qualifiers. Neither do Boolean
- * variables.
- */
- if (this->type->specifier->precision != ast_precision_none
- && !var->type->is_float()
- && !var->type->is_integer()
- && !(var->type->is_array()
- && (var->type->fields.array->is_float()
- || var->type->fields.array->is_integer()))) {
-
- _mesa_glsl_error(&loc, state,
- "precision qualifiers apply only to floating point "
- "and integer types");
- }
-
- /* Process the initializer and add its instructions to a temporary
- * list. This list will be added to the instruction stream (below) after
- * the declaration is added. This is done because in some cases (such as
- * redeclarations) the declaration may not actually be added to the
- * instruction stream.
- */
- exec_list initializer_instructions;
- if (decl->initializer != NULL) {
- YYLTYPE initializer_loc = decl->initializer->get_location();
-
- /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec:
- *
- * "All uniform variables are read-only and are initialized either
- * directly by an application via API commands, or indirectly by
- * OpenGL."
- */
- if ((state->language_version <= 110)
- && (var->mode == ir_var_uniform)) {
- _mesa_glsl_error(& initializer_loc, state,
- "cannot initialize uniforms in GLSL 1.10");
- }
-
- if (var->type->is_sampler()) {
- _mesa_glsl_error(& initializer_loc, state,
- "cannot initialize samplers");
- }
-
- if ((var->mode == ir_var_in) && (state->current_function == NULL)) {
- _mesa_glsl_error(& initializer_loc, state,
- "cannot initialize %s shader input / %s",
- _mesa_glsl_shader_target_name(state->target),
- (state->target == vertex_shader)
- ? "attribute" : "varying");
- }
-
- ir_dereference *const lhs = new(ctx) ir_dereference_variable(var);
- ir_rvalue *rhs = decl->initializer->hir(&initializer_instructions,
- state);
-
- /* Calculate the constant value if this is a const or uniform
- * declaration.
- */
- if (this->type->qualifier.flags.q.constant
- || this->type->qualifier.flags.q.uniform) {
- ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs);
- if (new_rhs != NULL) {
- rhs = new_rhs;
-
- ir_constant *constant_value = rhs->constant_expression_value();
- if (!constant_value) {
- _mesa_glsl_error(& initializer_loc, state,
- "initializer of %s variable `%s' must be a "
- "constant expression",
- (this->type->qualifier.flags.q.constant)
- ? "const" : "uniform",
- decl->identifier);
- if (var->type->is_numeric()) {
- /* Reduce cascading errors. */
- var->constant_value = ir_constant::zero(ctx, var->type);
- }
- } else {
- rhs = constant_value;
- var->constant_value = constant_value;
- }
- } else {
- _mesa_glsl_error(&initializer_loc, state,
- "initializer of type %s cannot be assigned to "
- "variable of type %s",
- rhs->type->name, var->type->name);
- if (var->type->is_numeric()) {
- /* Reduce cascading errors. */
- var->constant_value = ir_constant::zero(ctx, var->type);
- }
- }
- }
-
- if (rhs && !rhs->type->is_error()) {
- bool temp = var->read_only;
- if (this->type->qualifier.flags.q.constant)
- var->read_only = false;
-
- /* Never emit code to initialize a uniform.
- */
- const glsl_type *initializer_type;
- if (!this->type->qualifier.flags.q.uniform) {
- result = do_assignment(&initializer_instructions, state,
- lhs, rhs,
- this->get_location());
- initializer_type = result->type;
- } else
- initializer_type = rhs->type;
-
- /* If the declared variable is an unsized array, it must inherrit
- * its full type from the initializer. A declaration such as
- *
- * uniform float a[] = float[](1.0, 2.0, 3.0, 3.0);
- *
- * becomes
- *
- * uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0);
- *
- * The assignment generated in the if-statement (below) will also
- * automatically handle this case for non-uniforms.
- *
- * If the declared variable is not an array, the types must
- * already match exactly. As a result, the type assignment
- * here can be done unconditionally. For non-uniforms the call
- * to do_assignment can change the type of the initializer (via
- * the implicit conversion rules). For uniforms the initializer
- * must be a constant expression, and the type of that expression
- * was validated above.
- */
- var->type = initializer_type;
-
- var->read_only = temp;
- }
- }
-
- /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec:
- *
- * "It is an error to write to a const variable outside of
- * its declaration, so they must be initialized when
- * declared."
- */
- if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) {
- _mesa_glsl_error(& loc, state,
- "const declaration of `%s' must be initialized",
- decl->identifier);
- }
-
- /* Check if this declaration is actually a re-declaration, either to
- * resize an array or add qualifiers to an existing variable.
- *
- * This is allowed for variables in the current scope, or when at
- * global scope (for built-ins in the implicit outer scope).
- */
- ir_variable *earlier = state->symbols->get_variable(decl->identifier);
- if (earlier != NULL && (state->current_function == NULL ||
- state->symbols->name_declared_this_scope(decl->identifier))) {
-
- /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
- *
- * "It is legal to declare an array without a size and then
- * later re-declare the same name as an array of the same
- * type and specify a size."
- */
- if ((earlier->type->array_size() == 0)
- && var->type->is_array()
- && (var->type->element_type() == earlier->type->element_type())) {
- /* FINISHME: This doesn't match the qualifiers on the two
- * FINISHME: declarations. It's not 100% clear whether this is
- * FINISHME: required or not.
- */
-
- /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
- *
- * "The size [of gl_TexCoord] can be at most
- * gl_MaxTextureCoords."
- */
- const unsigned size = unsigned(var->type->array_size());
- if ((strcmp("gl_TexCoord", var->name) == 0)
- && (size > state->Const.MaxTextureCoords)) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "`gl_TexCoord' array size cannot "
- "be larger than gl_MaxTextureCoords (%u)\n",
- state->Const.MaxTextureCoords);
- } else if ((size > 0) && (size <= earlier->max_array_access)) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "array size must be > %u due to "
- "previous access",
- earlier->max_array_access);
- }
-
- earlier->type = var->type;
- delete var;
- var = NULL;
- } else if (state->ARB_fragment_coord_conventions_enable
- && strcmp(var->name, "gl_FragCoord") == 0
- && earlier->type == var->type
- && earlier->mode == var->mode) {
- /* Allow redeclaration of gl_FragCoord for ARB_fcc layout
- * qualifiers.
- */
- earlier->origin_upper_left = var->origin_upper_left;
- earlier->pixel_center_integer = var->pixel_center_integer;
-
- /* According to section 4.3.7 of the GLSL 1.30 spec,
- * the following built-in varaibles can be redeclared with an
- * interpolation qualifier:
- * * gl_FrontColor
- * * gl_BackColor
- * * gl_FrontSecondaryColor
- * * gl_BackSecondaryColor
- * * gl_Color
- * * gl_SecondaryColor
- */
- } else if (state->language_version >= 130
- && (strcmp(var->name, "gl_FrontColor") == 0
- || strcmp(var->name, "gl_BackColor") == 0
- || strcmp(var->name, "gl_FrontSecondaryColor") == 0
- || strcmp(var->name, "gl_BackSecondaryColor") == 0
- || strcmp(var->name, "gl_Color") == 0
- || strcmp(var->name, "gl_SecondaryColor") == 0)
- && earlier->type == var->type
- && earlier->mode == var->mode) {
- earlier->interpolation = var->interpolation;
-
- /* Layout qualifiers for gl_FragDepth. */
- } else if (state->AMD_conservative_depth_enable
- && strcmp(var->name, "gl_FragDepth") == 0
- && earlier->type == var->type
- && earlier->mode == var->mode) {
-
- /** From the AMD_conservative_depth spec:
- * Within any shader, the first redeclarations of gl_FragDepth
- * must appear before any use of gl_FragDepth.
- */
- if (earlier->used) {
- _mesa_glsl_error(&loc, state,
- "the first redeclaration of gl_FragDepth "
- "must appear before any use of gl_FragDepth");
- }
-
- /* Prevent inconsistent redeclaration of depth layout qualifier. */
- if (earlier->depth_layout != ir_depth_layout_none
- && earlier->depth_layout != var->depth_layout) {
- _mesa_glsl_error(&loc, state,
- "gl_FragDepth: depth layout is declared here "
- "as '%s, but it was previously declared as "
- "'%s'",
- depth_layout_string(var->depth_layout),
- depth_layout_string(earlier->depth_layout));
- }
-
- earlier->depth_layout = var->depth_layout;
-
- } else {
- YYLTYPE loc = this->get_location();
- _mesa_glsl_error(&loc, state, "`%s' redeclared", decl->identifier);
- }
-
- continue;
- }
-
- /* By now, we know it's a new variable declaration (we didn't hit the
- * above "continue").
- *
- * From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
- *
- * "Identifiers starting with "gl_" are reserved for use by
- * OpenGL, and may not be declared in a shader as either a
- * variable or a function."
- */
- if (strncmp(decl->identifier, "gl_", 3) == 0)
- _mesa_glsl_error(& loc, state,
- "identifier `%s' uses reserved `gl_' prefix",
- decl->identifier);
-
- /* Add the variable to the symbol table. Note that the initializer's
- * IR was already processed earlier (though it hasn't been emitted yet),
- * without the variable in scope.
- *
- * This differs from most C-like languages, but it follows the GLSL
- * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50
- * spec:
- *
- * "Within a declaration, the scope of a name starts immediately
- * after the initializer if present or immediately after the name
- * being declared if not."
- */
- if (!state->symbols->add_variable(var)) {
- YYLTYPE loc = this->get_location();
- _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
- "current scope", decl->identifier);
- continue;
- }
-
- /* Push the variable declaration to the top. It means that all
- * the variable declarations will appear in a funny
- * last-to-first order, but otherwise we run into trouble if a
- * function is prototyped, a global var is decled, then the
- * function is defined with usage of the global var. See
- * glslparsertest's CorrectModule.frag.
- */
- instructions->push_head(var);
- instructions->append_list(&initializer_instructions);
- }
-
-
- /* Generally, variable declarations do not have r-values. However,
- * one is used for the declaration in
- *
- * while (bool b = some_condition()) {
- * ...
- * }
- *
- * so we return the rvalue from the last seen declaration here.
- */
- return result;
-}
-
-
-ir_rvalue *
-ast_parameter_declarator::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = state;
- const struct glsl_type *type;
- const char *name = NULL;
- YYLTYPE loc = this->get_location();
-
- type = this->type->specifier->glsl_type(& name, state);
-
- if (type == NULL) {
- if (name != NULL) {
- _mesa_glsl_error(& loc, state,
- "invalid type `%s' in declaration of `%s'",
- name, this->identifier);
- } else {
- _mesa_glsl_error(& loc, state,
- "invalid type in declaration of `%s'",
- this->identifier);
- }
-
- type = glsl_type::error_type;
- }
-
- /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec:
- *
- * "Functions that accept no input arguments need not use void in the
- * argument list because prototypes (or definitions) are required and
- * therefore there is no ambiguity when an empty argument list "( )" is
- * declared. The idiom "(void)" as a parameter list is provided for
- * convenience."
- *
- * Placing this check here prevents a void parameter being set up
- * for a function, which avoids tripping up checks for main taking
- * parameters and lookups of an unnamed symbol.
- */
- if (type->is_void()) {
- if (this->identifier != NULL)
- _mesa_glsl_error(& loc, state,
- "named parameter cannot have type `void'");
-
- is_void = true;
- return NULL;
- }
-
- if (formal_parameter && (this->identifier == NULL)) {
- _mesa_glsl_error(& loc, state, "formal parameter lacks a name");
- return NULL;
- }
-
- /* This only handles "vec4 foo[..]". The earlier specifier->glsl_type(...)
- * call already handled the "vec4[..] foo" case.
- */
- if (this->is_array) {
- type = process_array_type(&loc, type, this->array_size, state);
- }
-
- if (type->array_size() == 0) {
- _mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
- "a declared size.");
- type = glsl_type::error_type;
- }
-
- is_void = false;
- ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in);
-
- /* Apply any specified qualifiers to the parameter declaration. Note that
- * for function parameters the default mode is 'in'.
- */
- apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc);
-
- instructions->push_tail(var);
-
- /* Parameter declarations do not have r-values.
- */
- return NULL;
-}
-
-
-void
-ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
- bool formal,
- exec_list *ir_parameters,
- _mesa_glsl_parse_state *state)
-{
- ast_parameter_declarator *void_param = NULL;
- unsigned count = 0;
-
- foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) {
- param->formal_parameter = formal;
- param->hir(ir_parameters, state);
-
- if (param->is_void)
- void_param = param;
-
- count++;
- }
-
- if ((void_param != NULL) && (count > 1)) {
- YYLTYPE loc = void_param->get_location();
-
- _mesa_glsl_error(& loc, state,
- "`void' parameter must be only parameter");
- }
-}
-
-
-void
-emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
- ir_function *f)
-{
- /* Emit the new function header */
- if (state->current_function == NULL) {
- instructions->push_tail(f);
- } else {
- /* IR invariants disallow function declarations or definitions nested
- * within other function definitions. Insert the new ir_function
- * block in the instruction sequence before the ir_function block
- * containing the current ir_function_signature.
- */
- ir_function *const curr =
- const_cast<ir_function *>(state->current_function->function());
-
- curr->insert_before(f);
- }
-}
-
-
-ir_rvalue *
-ast_function::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = state;
- ir_function *f = NULL;
- ir_function_signature *sig = NULL;
- exec_list hir_parameters;
-
- const char *const name = identifier;
-
- /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
- *
- * "Function declarations (prototypes) cannot occur inside of functions;
- * they must be at global scope, or for the built-in functions, outside
- * the global scope."
- *
- * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec,
- *
- * "User defined functions may only be defined within the global scope."
- *
- * Note that this language does not appear in GLSL 1.10.
- */
- if ((state->current_function != NULL) && (state->language_version != 110)) {
- YYLTYPE loc = this->get_location();
- _mesa_glsl_error(&loc, state,
- "declaration of function `%s' not allowed within "
- "function body", name);
- }
-
- /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
- *
- * "Identifiers starting with "gl_" are reserved for use by
- * OpenGL, and may not be declared in a shader as either a
- * variable or a function."
- */
- if (strncmp(name, "gl_", 3) == 0) {
- YYLTYPE loc = this->get_location();
- _mesa_glsl_error(&loc, state,
- "identifier `%s' uses reserved `gl_' prefix", name);
- }
-
- /* Convert the list of function parameters to HIR now so that they can be
- * used below to compare this function's signature with previously seen
- * signatures for functions with the same name.
- */
- ast_parameter_declarator::parameters_to_hir(& this->parameters,
- is_definition,
- & hir_parameters, state);
-
- const char *return_type_name;
- const glsl_type *return_type =
- this->return_type->specifier->glsl_type(& return_type_name, state);
-
- if (!return_type) {
- YYLTYPE loc = this->get_location();
- _mesa_glsl_error(&loc, state,
- "function `%s' has undeclared return type `%s'",
- name, return_type_name);
- return_type = glsl_type::error_type;
- }
-
- /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec:
- * "No qualifier is allowed on the return type of a function."
- */
- if (this->return_type->has_qualifiers()) {
- YYLTYPE loc = this->get_location();
- _mesa_glsl_error(& loc, state,
- "function `%s' return type has qualifiers", name);
- }
-
- /* Verify that this function's signature either doesn't match a previously
- * seen signature for a function with the same name, or, if a match is found,
- * that the previously seen signature does not have an associated definition.
- */
- f = state->symbols->get_function(name);
- if (f != NULL && (state->es_shader || f->has_user_signature())) {
- sig = f->exact_matching_signature(&hir_parameters);
- if (sig != NULL) {
- const char *badvar = sig->qualifiers_match(&hir_parameters);
- if (badvar != NULL) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' "
- "qualifiers don't match prototype", name, badvar);
- }
-
- if (sig->return_type != return_type) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(&loc, state, "function `%s' return type doesn't "
- "match prototype", name);
- }
-
- if (is_definition && sig->is_defined) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "function `%s' redefined", name);
- }
- }
- } else {
- f = new(ctx) ir_function(name);
- if (!state->symbols->add_function(f)) {
- /* This function name shadows a non-function use of the same name. */
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
- "non-function", name);
- return NULL;
- }
-
- emit_function(state, instructions, f);
- }
-
- /* Verify the return type of main() */
- if (strcmp(name, "main") == 0) {
- if (! return_type->is_void()) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "main() must return void");
- }
-
- if (!hir_parameters.is_empty()) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "main() must not take any parameters");
- }
- }
-
- /* Finish storing the information about this new function in its signature.
- */
- if (sig == NULL) {
- sig = new(ctx) ir_function_signature(return_type);
- f->add_signature(sig);
- }
-
- sig->replace_parameters(&hir_parameters);
- signature = sig;
-
- /* Function declarations (prototypes) do not have r-values.
- */
- return NULL;
-}
-
-
-ir_rvalue *
-ast_function_definition::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- prototype->is_definition = true;
- prototype->hir(instructions, state);
-
- ir_function_signature *signature = prototype->signature;
- if (signature == NULL)
- return NULL;
-
- assert(state->current_function == NULL);
- state->current_function = signature;
- state->found_return = false;
-
- /* Duplicate parameters declared in the prototype as concrete variables.
- * Add these to the symbol table.
- */
- state->symbols->push_scope();
- foreach_iter(exec_list_iterator, iter, signature->parameters) {
- ir_variable *const var = ((ir_instruction *) iter.get())->as_variable();
-
- assert(var != NULL);
-
- /* The only way a parameter would "exist" is if two parameters have
- * the same name.
- */
- if (state->symbols->name_declared_this_scope(var->name)) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
- } else {
- state->symbols->add_variable(var);
- }
- }
-
- /* Convert the body of the function to HIR. */
- this->body->hir(&signature->body, state);
- signature->is_defined = true;
-
- state->symbols->pop_scope();
-
- assert(state->current_function == signature);
- state->current_function = NULL;
-
- if (!signature->return_type->is_void() && !state->found_return) {
- YYLTYPE loc = this->get_location();
- _mesa_glsl_error(& loc, state, "function `%s' has non-void return type "
- "%s, but no return statement",
- signature->function_name(),
- signature->return_type->name);
- }
-
- /* Function definitions do not have r-values.
- */
- return NULL;
-}
-
-
-ir_rvalue *
-ast_jump_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = state;
-
- switch (mode) {
- case ast_return: {
- ir_return *inst;
- assert(state->current_function);
-
- if (opt_return_value) {
- ir_rvalue *const ret = opt_return_value->hir(instructions, state);
-
- /* The value of the return type can be NULL if the shader says
- * 'return foo();' and foo() is a function that returns void.
- *
- * NOTE: The GLSL spec doesn't say that this is an error. The type
- * of the return value is void. If the return type of the function is
- * also void, then this should compile without error. Seriously.
- */
- const glsl_type *const ret_type =
- (ret == NULL) ? glsl_type::void_type : ret->type;
-
- /* Implicit conversions are not allowed for return values. */
- if (state->current_function->return_type != ret_type) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state,
- "`return' with wrong type %s, in function `%s' "
- "returning %s",
- ret_type->name,
- state->current_function->function_name(),
- state->current_function->return_type->name);
- }
-
- inst = new(ctx) ir_return(ret);
- } else {
- if (state->current_function->return_type->base_type !=
- GLSL_TYPE_VOID) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state,
- "`return' with no value, in function %s returning "
- "non-void",
- state->current_function->function_name());
- }
- inst = new(ctx) ir_return;
- }
-
- state->found_return = true;
- instructions->push_tail(inst);
- break;
- }
-
- case ast_discard:
- if (state->target != fragment_shader) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state,
- "`discard' may only appear in a fragment shader");
- }
- instructions->push_tail(new(ctx) ir_discard);
- break;
-
- case ast_break:
- case ast_continue:
- /* FINISHME: Handle switch-statements. They cannot contain 'continue',
- * FINISHME: and they use a different IR instruction for 'break'.
- */
- /* FINISHME: Correctly handle the nesting. If a switch-statement is
- * FINISHME: inside a loop, a 'continue' is valid and will bind to the
- * FINISHME: loop.
- */
- if (state->loop_or_switch_nesting == NULL) {
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(& loc, state,
- "`%s' may only appear in a loop",
- (mode == ast_break) ? "break" : "continue");
- } else {
- ir_loop *const loop = state->loop_or_switch_nesting->as_loop();
-
- /* Inline the for loop expression again, since we don't know
- * where near the end of the loop body the normal copy of it
- * is going to be placed.
- */
- if (mode == ast_continue &&
- state->loop_or_switch_nesting_ast->rest_expression) {
- state->loop_or_switch_nesting_ast->rest_expression->hir(instructions,
- state);
- }
-
- if (loop != NULL) {
- ir_loop_jump *const jump =
- new(ctx) ir_loop_jump((mode == ast_break)
- ? ir_loop_jump::jump_break
- : ir_loop_jump::jump_continue);
- instructions->push_tail(jump);
- }
- }
-
- break;
- }
-
- /* Jump instructions do not have r-values.
- */
- return NULL;
-}
-
-
-ir_rvalue *
-ast_selection_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = state;
-
- ir_rvalue *const condition = this->condition->hir(instructions, state);
-
- /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec:
- *
- * "Any expression whose type evaluates to a Boolean can be used as the
- * conditional expression bool-expression. Vector types are not accepted
- * as the expression to if."
- *
- * The checks are separated so that higher quality diagnostics can be
- * generated for cases where both rules are violated.
- */
- if (!condition->type->is_boolean() || !condition->type->is_scalar()) {
- YYLTYPE loc = this->condition->get_location();
-
- _mesa_glsl_error(& loc, state, "if-statement condition must be scalar "
- "boolean");
- }
-
- ir_if *const stmt = new(ctx) ir_if(condition);
-
- if (then_statement != NULL) {
- state->symbols->push_scope();
- then_statement->hir(& stmt->then_instructions, state);
- state->symbols->pop_scope();
- }
-
- if (else_statement != NULL) {
- state->symbols->push_scope();
- else_statement->hir(& stmt->else_instructions, state);
- state->symbols->pop_scope();
- }
-
- instructions->push_tail(stmt);
-
- /* if-statements do not have r-values.
- */
- return NULL;
-}
-
-
-void
-ast_iteration_statement::condition_to_hir(ir_loop *stmt,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = state;
-
- if (condition != NULL) {
- ir_rvalue *const cond =
- condition->hir(& stmt->body_instructions, state);
-
- if ((cond == NULL)
- || !cond->type->is_boolean() || !cond->type->is_scalar()) {
- YYLTYPE loc = condition->get_location();
-
- _mesa_glsl_error(& loc, state,
- "loop condition must be scalar boolean");
- } else {
- /* As the first code in the loop body, generate a block that looks
- * like 'if (!condition) break;' as the loop termination condition.
- */
- ir_rvalue *const not_cond =
- new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond,
- NULL);
-
- ir_if *const if_stmt = new(ctx) ir_if(not_cond);
-
- ir_jump *const break_stmt =
- new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
-
- if_stmt->then_instructions.push_tail(break_stmt);
- stmt->body_instructions.push_tail(if_stmt);
- }
- }
-}
-
-
-ir_rvalue *
-ast_iteration_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- void *ctx = state;
-
- /* For-loops and while-loops start a new scope, but do-while loops do not.
- */
- if (mode != ast_do_while)
- state->symbols->push_scope();
-
- if (init_statement != NULL)
- init_statement->hir(instructions, state);
-
- ir_loop *const stmt = new(ctx) ir_loop();
- instructions->push_tail(stmt);
-
- /* Track the current loop and / or switch-statement nesting.
- */
- ir_instruction *const nesting = state->loop_or_switch_nesting;
- ast_iteration_statement *nesting_ast = state->loop_or_switch_nesting_ast;
-
- state->loop_or_switch_nesting = stmt;
- state->loop_or_switch_nesting_ast = this;
-
- if (mode != ast_do_while)
- condition_to_hir(stmt, state);
-
- if (body != NULL)
- body->hir(& stmt->body_instructions, state);
-
- if (rest_expression != NULL)
- rest_expression->hir(& stmt->body_instructions, state);
-
- if (mode == ast_do_while)
- condition_to_hir(stmt, state);
-
- if (mode != ast_do_while)
- state->symbols->pop_scope();
-
- /* Restore previous nesting before returning.
- */
- state->loop_or_switch_nesting = nesting;
- state->loop_or_switch_nesting_ast = nesting_ast;
-
- /* Loops do not have r-values.
- */
- return NULL;
-}
-
-
-ir_rvalue *
-ast_type_specifier::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- if (!this->is_precision_statement && this->structure == NULL)
- return NULL;
-
- YYLTYPE loc = this->get_location();
-
- if (this->precision != ast_precision_none
- && state->language_version != 100
- && state->language_version < 130) {
- _mesa_glsl_error(&loc, state,
- "precision qualifiers exist only in "
- "GLSL ES 1.00, and GLSL 1.30 and later");
- return NULL;
- }
- if (this->precision != ast_precision_none
- && this->structure != NULL) {
- _mesa_glsl_error(&loc, state,
- "precision qualifiers do not apply to structures");
- return NULL;
- }
-
- /* If this is a precision statement, check that the type to which it is
- * applied is either float or int.
- *
- * From section 4.5.3 of the GLSL 1.30 spec:
- * "The precision statement
- * precision precision-qualifier type;
- * can be used to establish a default precision qualifier. The type
- * field can be either int or float [...]. Any other types or
- * qualifiers will result in an error.
- */
- if (this->is_precision_statement) {
- assert(this->precision != ast_precision_none);
- assert(this->structure == NULL); /* The check for structures was
- * performed above. */
- if (this->is_array) {
- _mesa_glsl_error(&loc, state,
- "default precision statements do not apply to "
- "arrays");
- return NULL;
- }
- if (this->type_specifier != ast_float
- && this->type_specifier != ast_int) {
- _mesa_glsl_error(&loc, state,
- "default precision statements apply only to types "
- "float and int");
- return NULL;
- }
-
- /* FINISHME: Translate precision statements into IR. */
- return NULL;
- }
-
- if (this->structure != NULL)
- return this->structure->hir(instructions, state);
-
- return NULL;
-}
-
-
-ir_rvalue *
-ast_struct_specifier::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
-{
- unsigned decl_count = 0;
-
- /* Make an initial pass over the list of structure fields to determine how
- * many there are. Each element in this list is an ast_declarator_list.
- * This means that we actually need to count the number of elements in the
- * 'declarations' list in each of the elements.
- */
- foreach_list_typed (ast_declarator_list, decl_list, link,
- &this->declarations) {
- foreach_list_const (decl_ptr, & decl_list->declarations) {
- decl_count++;
- }
- }
-
- /* Allocate storage for the structure fields and process the field
- * declarations. As the declarations are processed, try to also convert
- * the types to HIR. This ensures that structure definitions embedded in
- * other structure definitions are processed.
- */
- glsl_struct_field *const fields = ralloc_array(state, glsl_struct_field,
- decl_count);
-
- unsigned i = 0;
- foreach_list_typed (ast_declarator_list, decl_list, link,
- &this->declarations) {
- const char *type_name;
-
- decl_list->type->specifier->hir(instructions, state);
-
- /* Section 10.9 of the GLSL ES 1.00 specification states that
- * embedded structure definitions have been removed from the language.
- */
- if (state->es_shader && decl_list->type->specifier->structure != NULL) {
- YYLTYPE loc = this->get_location();
- _mesa_glsl_error(&loc, state, "Embedded structure definitions are "
- "not allowed in GLSL ES 1.00.");
- }
-
- const glsl_type *decl_type =
- decl_list->type->specifier->glsl_type(& type_name, state);
-
- foreach_list_typed (ast_declaration, decl, link,
- &decl_list->declarations) {
- const struct glsl_type *field_type = decl_type;
- if (decl->is_array) {
- YYLTYPE loc = decl->get_location();
- field_type = process_array_type(&loc, decl_type, decl->array_size,
- state);
- }
- fields[i].type = (field_type != NULL)
- ? field_type : glsl_type::error_type;
- fields[i].name = decl->identifier;
- i++;
- }
- }
-
- assert(i == decl_count);
-
- const glsl_type *t =
- glsl_type::get_record_instance(fields, decl_count, this->name);
-
- YYLTYPE loc = this->get_location();
- if (!state->symbols->add_type(name, t)) {
- _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name);
- } else {
- const glsl_type **s = reralloc(state, state->user_structures,
- const glsl_type *,
- state->num_user_structures + 1);
- if (s != NULL) {
- s[state->num_user_structures] = t;
- state->user_structures = s;
- state->num_user_structures++;
- }
- }
-
- /* Structure type definitions do not have r-values.
- */
- return NULL;
-}
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file ast_to_hir.c
+ * Convert abstract syntax to to high-level intermediate reprensentation (HIR).
+ *
+ * During the conversion to HIR, the majority of the symantic checking is
+ * preformed on the program. This includes:
+ *
+ * * Symbol table management
+ * * Type checking
+ * * Function binding
+ *
+ * The majority of this work could be done during parsing, and the parser could
+ * probably generate HIR directly. However, this results in frequent changes
+ * to the parser code. Since we do not assume that every system this complier
+ * is built on will have Flex and Bison installed, we have to store the code
+ * generated by these tools in our version control system. In other parts of
+ * the system we've seen problems where a parser was changed but the generated
+ * code was not committed, merge conflicts where created because two developers
+ * had slightly different versions of Bison installed, etc.
+ *
+ * I have also noticed that running Bison generated parsers in GDB is very
+ * irritating. When you get a segfault on '$$ = $1->foo', you can't very
+ * well 'print $1' in GDB.
+ *
+ * As a result, my preference is to put as little C code as possible in the
+ * parser (and lexer) sources.
+ */
+
+#include "main/core.h" /* for struct gl_extensions */
+#include "glsl_symbol_table.h"
+#include "glsl_parser_extras.h"
+#include "ast.h"
+#include "glsl_types.h"
+#include "ir.h"
+
+void
+_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
+{
+ _mesa_glsl_initialize_variables(instructions, state);
+ _mesa_glsl_initialize_functions(state);
+
+ state->symbols->language_version = state->language_version;
+
+ state->current_function = NULL;
+
+ /* Section 4.2 of the GLSL 1.20 specification states:
+ * "The built-in functions are scoped in a scope outside the global scope
+ * users declare global variables in. That is, a shader's global scope,
+ * available for user-defined functions and global variables, is nested
+ * inside the scope containing the built-in functions."
+ *
+ * Since built-in functions like ftransform() access built-in variables,
+ * it follows that those must be in the outer scope as well.
+ *
+ * We push scope here to create this nesting effect...but don't pop.
+ * This way, a shader's globals are still in the symbol table for use
+ * by the linker.
+ */
+ state->symbols->push_scope();
+
+ foreach_list_typed (ast_node, ast, link, & state->translation_unit)
+ ast->hir(instructions, state);
+}
+
+
+/**
+ * If a conversion is available, convert one operand to a different type
+ *
+ * The \c from \c ir_rvalue is converted "in place".
+ *
+ * \param to Type that the operand it to be converted to
+ * \param from Operand that is being converted
+ * \param state GLSL compiler state
+ *
+ * \return
+ * If a conversion is possible (or unnecessary), \c true is returned.
+ * Otherwise \c false is returned.
+ */
+bool
+apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ if (to->base_type == from->type->base_type)
+ return true;
+
+ /* This conversion was added in GLSL 1.20. If the compilation mode is
+ * GLSL 1.10, the conversion is skipped.
+ */
+ if (state->language_version < 120)
+ return false;
+
+ /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "There are no implicit array or structure conversions. For
+ * example, an array of int cannot be implicitly converted to an
+ * array of float. There are no implicit conversions between
+ * signed and unsigned integers."
+ */
+ /* FINISHME: The above comment is partially a lie. There is int/uint
+ * FINISHME: conversion for immediate constants.
+ */
+ if (!to->is_float() || !from->type->is_numeric())
+ return false;
+
+ /* Convert to a floating point type with the same number of components
+ * as the original type - i.e. int to float, not int to vec4.
+ */
+ to = glsl_type::get_instance(GLSL_TYPE_FLOAT, from->type->vector_elements,
+ from->type->matrix_columns);
+
+ switch (from->type->base_type) {
+ case GLSL_TYPE_INT:
+ from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL);
+ break;
+ case GLSL_TYPE_UINT:
+ from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL);
+ break;
+ case GLSL_TYPE_BOOL:
+ from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL);
+ break;
+ default:
+ assert(0);
+ }
+
+ return true;
+}
+
+
+static const struct glsl_type *
+arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
+ bool multiply,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ const glsl_type *type_a = value_a->type;
+ const glsl_type *type_b = value_b->type;
+
+ /* From GLSL 1.50 spec, page 56:
+ *
+ * "The arithmetic binary operators add (+), subtract (-),
+ * multiply (*), and divide (/) operate on integer and
+ * floating-point scalars, vectors, and matrices."
+ */
+ if (!type_a->is_numeric() || !type_b->is_numeric()) {
+ _mesa_glsl_error(loc, state,
+ "Operands to arithmetic operators must be numeric");
+ return glsl_type::error_type;
+ }
+
+
+ /* "If one operand is floating-point based and the other is
+ * not, then the conversions from Section 4.1.10 "Implicit
+ * Conversions" are applied to the non-floating-point-based operand."
+ */
+ if (!apply_implicit_conversion(type_a, value_b, state)
+ && !apply_implicit_conversion(type_b, value_a, state)) {
+ _mesa_glsl_error(loc, state,
+ "Could not implicitly convert operands to "
+ "arithmetic operator");
+ return glsl_type::error_type;
+ }
+ type_a = value_a->type;
+ type_b = value_b->type;
+
+ /* "If the operands are integer types, they must both be signed or
+ * both be unsigned."
+ *
+ * From this rule and the preceeding conversion it can be inferred that
+ * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT.
+ * The is_numeric check above already filtered out the case where either
+ * type is not one of these, so now the base types need only be tested for
+ * equality.
+ */
+ if (type_a->base_type != type_b->base_type) {
+ _mesa_glsl_error(loc, state,
+ "base type mismatch for arithmetic operator");
+ return glsl_type::error_type;
+ }
+
+ /* "All arithmetic binary operators result in the same fundamental type
+ * (signed integer, unsigned integer, or floating-point) as the
+ * operands they operate on, after operand type conversion. After
+ * conversion, the following cases are valid
+ *
+ * * The two operands are scalars. In this case the operation is
+ * applied, resulting in a scalar."
+ */
+ if (type_a->is_scalar() && type_b->is_scalar())
+ return type_a;
+
+ /* "* One operand is a scalar, and the other is a vector or matrix.
+ * In this case, the scalar operation is applied independently to each
+ * component of the vector or matrix, resulting in the same size
+ * vector or matrix."
+ */
+ if (type_a->is_scalar()) {
+ if (!type_b->is_scalar())
+ return type_b;
+ } else if (type_b->is_scalar()) {
+ return type_a;
+ }
+
+ /* All of the combinations of <scalar, scalar>, <vector, scalar>,
+ * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been
+ * handled.
+ */
+ assert(!type_a->is_scalar());
+ assert(!type_b->is_scalar());
+
+ /* "* The two operands are vectors of the same size. In this case, the
+ * operation is done component-wise resulting in the same size
+ * vector."
+ */
+ if (type_a->is_vector() && type_b->is_vector()) {
+ if (type_a == type_b) {
+ return type_a;
+ } else {
+ _mesa_glsl_error(loc, state,
+ "vector size mismatch for arithmetic operator");
+ return glsl_type::error_type;
+ }
+ }
+
+ /* All of the combinations of <scalar, scalar>, <vector, scalar>,
+ * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and
+ * <vector, vector> have been handled. At least one of the operands must
+ * be matrix. Further, since there are no integer matrix types, the base
+ * type of both operands must be float.
+ */
+ assert(type_a->is_matrix() || type_b->is_matrix());
+ assert(type_a->base_type == GLSL_TYPE_FLOAT);
+ assert(type_b->base_type == GLSL_TYPE_FLOAT);
+
+ /* "* The operator is add (+), subtract (-), or divide (/), and the
+ * operands are matrices with the same number of rows and the same
+ * number of columns. In this case, the operation is done component-
+ * wise resulting in the same size matrix."
+ * * The operator is multiply (*), where both operands are matrices or
+ * one operand is a vector and the other a matrix. A right vector
+ * operand is treated as a column vector and a left vector operand as a
+ * row vector. In all these cases, it is required that the number of
+ * columns of the left operand is equal to the number of rows of the
+ * right operand. Then, the multiply (*) operation does a linear
+ * algebraic multiply, yielding an object that has the same number of
+ * rows as the left operand and the same number of columns as the right
+ * operand. Section 5.10 "Vector and Matrix Operations" explains in
+ * more detail how vectors and matrices are operated on."
+ */
+ if (! multiply) {
+ if (type_a == type_b)
+ return type_a;
+ } else {
+ if (type_a->is_matrix() && type_b->is_matrix()) {
+ /* Matrix multiply. The columns of A must match the rows of B. Given
+ * the other previously tested constraints, this means the vector type
+ * of a row from A must be the same as the vector type of a column from
+ * B.
+ */
+ if (type_a->row_type() == type_b->column_type()) {
+ /* The resulting matrix has the number of columns of matrix B and
+ * the number of rows of matrix A. We get the row count of A by
+ * looking at the size of a vector that makes up a column. The
+ * transpose (size of a row) is done for B.
+ */
+ const glsl_type *const type =
+ glsl_type::get_instance(type_a->base_type,
+ type_a->column_type()->vector_elements,
+ type_b->row_type()->vector_elements);
+ assert(type != glsl_type::error_type);
+
+ return type;
+ }
+ } else if (type_a->is_matrix()) {
+ /* A is a matrix and B is a column vector. Columns of A must match
+ * rows of B. Given the other previously tested constraints, this
+ * means the vector type of a row from A must be the same as the
+ * vector the type of B.
+ */
+ if (type_a->row_type() == type_b) {
+ /* The resulting vector has a number of elements equal to
+ * the number of rows of matrix A. */
+ const glsl_type *const type =
+ glsl_type::get_instance(type_a->base_type,
+ type_a->column_type()->vector_elements,
+ 1);
+ assert(type != glsl_type::error_type);
+
+ return type;
+ }
+ } else {
+ assert(type_b->is_matrix());
+
+ /* A is a row vector and B is a matrix. Columns of A must match rows
+ * of B. Given the other previously tested constraints, this means
+ * the type of A must be the same as the vector type of a column from
+ * B.
+ */
+ if (type_a == type_b->column_type()) {
+ /* The resulting vector has a number of elements equal to
+ * the number of columns of matrix B. */
+ const glsl_type *const type =
+ glsl_type::get_instance(type_a->base_type,
+ type_b->row_type()->vector_elements,
+ 1);
+ assert(type != glsl_type::error_type);
+
+ return type;
+ }
+ }
+
+ _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication");
+ return glsl_type::error_type;
+ }
+
+
+ /* "All other cases are illegal."
+ */
+ _mesa_glsl_error(loc, state, "type mismatch");
+ return glsl_type::error_type;
+}
+
+
+static const struct glsl_type *
+unary_arithmetic_result_type(const struct glsl_type *type,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ /* From GLSL 1.50 spec, page 57:
+ *
+ * "The arithmetic unary operators negate (-), post- and pre-increment
+ * and decrement (-- and ++) operate on integer or floating-point
+ * values (including vectors and matrices). All unary operators work
+ * component-wise on their operands. These result with the same type
+ * they operated on."
+ */
+ if (!type->is_numeric()) {
+ _mesa_glsl_error(loc, state,
+ "Operands to arithmetic operators must be numeric");
+ return glsl_type::error_type;
+ }
+
+ return type;
+}
+
+/**
+ * \brief Return the result type of a bit-logic operation.
+ *
+ * If the given types to the bit-logic operator are invalid, return
+ * glsl_type::error_type.
+ *
+ * \param type_a Type of LHS of bit-logic op
+ * \param type_b Type of RHS of bit-logic op
+ */
+static const struct glsl_type *
+bit_logic_result_type(const struct glsl_type *type_a,
+ const struct glsl_type *type_b,
+ ast_operators op,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ if (state->language_version < 130) {
+ _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
+ return glsl_type::error_type;
+ }
+
+ /* From page 50 (page 56 of PDF) of GLSL 1.30 spec:
+ *
+ * "The bitwise operators and (&), exclusive-or (^), and inclusive-or
+ * (|). The operands must be of type signed or unsigned integers or
+ * integer vectors."
+ */
+ if (!type_a->is_integer()) {
+ _mesa_glsl_error(loc, state, "LHS of `%s' must be an integer",
+ ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+ if (!type_b->is_integer()) {
+ _mesa_glsl_error(loc, state, "RHS of `%s' must be an integer",
+ ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* "The fundamental types of the operands (signed or unsigned) must
+ * match,"
+ */
+ if (type_a->base_type != type_b->base_type) {
+ _mesa_glsl_error(loc, state, "operands of `%s' must have the same "
+ "base type", ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* "The operands cannot be vectors of differing size." */
+ if (type_a->is_vector() &&
+ type_b->is_vector() &&
+ type_a->vector_elements != type_b->vector_elements) {
+ _mesa_glsl_error(loc, state, "operands of `%s' cannot be vectors of "
+ "different sizes", ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* "If one operand is a scalar and the other a vector, the scalar is
+ * applied component-wise to the vector, resulting in the same type as
+ * the vector. The fundamental types of the operands [...] will be the
+ * resulting fundamental type."
+ */
+ if (type_a->is_scalar())
+ return type_b;
+ else
+ return type_a;
+}
+
+static const struct glsl_type *
+modulus_result_type(const struct glsl_type *type_a,
+ const struct glsl_type *type_b,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ if (state->language_version < 130) {
+ _mesa_glsl_error(loc, state,
+ "operator '%%' is reserved in %s",
+ state->version_string);
+ return glsl_type::error_type;
+ }
+
+ /* From GLSL 1.50 spec, page 56:
+ * "The operator modulus (%) operates on signed or unsigned integers or
+ * integer vectors. The operand types must both be signed or both be
+ * unsigned."
+ */
+ if (!type_a->is_integer() || !type_b->is_integer()
+ || (type_a->base_type != type_b->base_type)) {
+ _mesa_glsl_error(loc, state, "type mismatch");
+ return glsl_type::error_type;
+ }
+
+ /* "The operands cannot be vectors of differing size. If one operand is
+ * a scalar and the other vector, then the scalar is applied component-
+ * wise to the vector, resulting in the same type as the vector. If both
+ * are vectors of the same size, the result is computed component-wise."
+ */
+ if (type_a->is_vector()) {
+ if (!type_b->is_vector()
+ || (type_a->vector_elements == type_b->vector_elements))
+ return type_a;
+ } else
+ return type_b;
+
+ /* "The operator modulus (%) is not defined for any other data types
+ * (non-integer types)."
+ */
+ _mesa_glsl_error(loc, state, "type mismatch");
+ return glsl_type::error_type;
+}
+
+
+static const struct glsl_type *
+relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ const glsl_type *type_a = value_a->type;
+ const glsl_type *type_b = value_b->type;
+
+ /* From GLSL 1.50 spec, page 56:
+ * "The relational operators greater than (>), less than (<), greater
+ * than or equal (>=), and less than or equal (<=) operate only on
+ * scalar integer and scalar floating-point expressions."
+ */
+ if (!type_a->is_numeric()
+ || !type_b->is_numeric()
+ || !type_a->is_scalar()
+ || !type_b->is_scalar()) {
+ _mesa_glsl_error(loc, state,
+ "Operands to relational operators must be scalar and "
+ "numeric");
+ return glsl_type::error_type;
+ }
+
+ /* "Either the operands' types must match, or the conversions from
+ * Section 4.1.10 "Implicit Conversions" will be applied to the integer
+ * operand, after which the types must match."
+ */
+ if (!apply_implicit_conversion(type_a, value_b, state)
+ && !apply_implicit_conversion(type_b, value_a, state)) {
+ _mesa_glsl_error(loc, state,
+ "Could not implicitly convert operands to "
+ "relational operator");
+ return glsl_type::error_type;
+ }
+ type_a = value_a->type;
+ type_b = value_b->type;
+
+ if (type_a->base_type != type_b->base_type) {
+ _mesa_glsl_error(loc, state, "base type mismatch");
+ return glsl_type::error_type;
+ }
+
+ /* "The result is scalar Boolean."
+ */
+ return glsl_type::bool_type;
+}
+
+/**
+ * \brief Return the result type of a bit-shift operation.
+ *
+ * If the given types to the bit-shift operator are invalid, return
+ * glsl_type::error_type.
+ *
+ * \param type_a Type of LHS of bit-shift op
+ * \param type_b Type of RHS of bit-shift op
+ */
+static const struct glsl_type *
+shift_result_type(const struct glsl_type *type_a,
+ const struct glsl_type *type_b,
+ ast_operators op,
+ struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
+{
+ if (state->language_version < 130) {
+ _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
+ return glsl_type::error_type;
+ }
+
+ /* From page 50 (page 56 of the PDF) of the GLSL 1.30 spec:
+ *
+ * "The shift operators (<<) and (>>). For both operators, the operands
+ * must be signed or unsigned integers or integer vectors. One operand
+ * can be signed while the other is unsigned."
+ */
+ if (!type_a->is_integer()) {
+ _mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or "
+ "integer vector", ast_expression::operator_string(op));
+ return glsl_type::error_type;
+
+ }
+ if (!type_b->is_integer()) {
+ _mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or "
+ "integer vector", ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* "If the first operand is a scalar, the second operand has to be
+ * a scalar as well."
+ */
+ if (type_a->is_scalar() && !type_b->is_scalar()) {
+ _mesa_glsl_error(loc, state, "If the first operand of %s is scalar, the "
+ "second must be scalar as well",
+ ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* If both operands are vectors, check that they have same number of
+ * elements.
+ */
+ if (type_a->is_vector() &&
+ type_b->is_vector() &&
+ type_a->vector_elements != type_b->vector_elements) {
+ _mesa_glsl_error(loc, state, "Vector operands to operator %s must "
+ "have same number of elements",
+ ast_expression::operator_string(op));
+ return glsl_type::error_type;
+ }
+
+ /* "In all cases, the resulting type will be the same type as the left
+ * operand."
+ */
+ return type_a;
+}
+
+/**
+ * Validates that a value can be assigned to a location with a specified type
+ *
+ * Validates that \c rhs can be assigned to some location. If the types are
+ * not an exact match but an automatic conversion is possible, \c rhs will be
+ * converted.
+ *
+ * \return
+ * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type.
+ * Otherwise the actual RHS to be assigned will be returned. This may be
+ * \c rhs, or it may be \c rhs after some type conversion.
+ *
+ * \note
+ * In addition to being used for assignments, this function is used to
+ * type-check return values.
+ */
+ir_rvalue *
+validate_assignment(struct _mesa_glsl_parse_state *state,
+ const glsl_type *lhs_type, ir_rvalue *rhs)
+{
+ /* If there is already some error in the RHS, just return it. Anything
+ * else will lead to an avalanche of error message back to the user.
+ */
+ if (rhs->type->is_error())
+ return rhs;
+
+ /* If the types are identical, the assignment can trivially proceed.
+ */
+ if (rhs->type == lhs_type)
+ return rhs;
+
+ /* If the array element types are the same and the size of the LHS is zero,
+ * the assignment is okay.
+ *
+ * Note: Whole-array assignments are not permitted in GLSL 1.10, but this
+ * is handled by ir_dereference::is_lvalue.
+ */
+ if (lhs_type->is_array() && rhs->type->is_array()
+ && (lhs_type->element_type() == rhs->type->element_type())
+ && (lhs_type->array_size() == 0)) {
+ return rhs;
+ }
+
+ /* Check for implicit conversion in GLSL 1.20 */
+ if (apply_implicit_conversion(lhs_type, rhs, state)) {
+ if (rhs->type == lhs_type)
+ return rhs;
+ }
+
+ return NULL;
+}
+
+ir_rvalue *
+do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
+ ir_rvalue *lhs, ir_rvalue *rhs,
+ YYLTYPE lhs_loc)
+{
+ void *ctx = state;
+ bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
+
+ if (!error_emitted) {
+ if (lhs->variable_referenced() != NULL
+ && lhs->variable_referenced()->read_only) {
+ _mesa_glsl_error(&lhs_loc, state,
+ "assignment to read-only variable '%s'",
+ lhs->variable_referenced()->name);
+ error_emitted = true;
+
+ } else if (!lhs->is_lvalue()) {
+ _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
+ error_emitted = true;
+ }
+
+ if (state->es_shader && lhs->type->is_array()) {
+ _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not "
+ "allowed in GLSL ES 1.00.");
+ error_emitted = true;
+ }
+ }
+
+ ir_rvalue *new_rhs = validate_assignment(state, lhs->type, rhs);
+ if (new_rhs == NULL) {
+ _mesa_glsl_error(& lhs_loc, state, "type mismatch");
+ } else {
+ rhs = new_rhs;
+
+ /* If the LHS array was not declared with a size, it takes it size from
+ * the RHS. If the LHS is an l-value and a whole array, it must be a
+ * dereference of a variable. Any other case would require that the LHS
+ * is either not an l-value or not a whole array.
+ */
+ if (lhs->type->array_size() == 0) {
+ ir_dereference *const d = lhs->as_dereference();
+
+ assert(d != NULL);
+
+ ir_variable *const var = d->variable_referenced();
+
+ assert(var != NULL);
+
+ if (var->max_array_access >= unsigned(rhs->type->array_size())) {
+ /* FINISHME: This should actually log the location of the RHS. */
+ _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
+ "previous access",
+ var->max_array_access);
+ }
+
+ var->type = glsl_type::get_array_instance(lhs->type->element_type(),
+ rhs->type->array_size());
+ d->type = var->type;
+ }
+ }
+
+ /* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
+ * but not post_inc) need the converted assigned value as an rvalue
+ * to handle things like:
+ *
+ * i = j += 1;
+ *
+ * So we always just store the computed value being assigned to a
+ * temporary and return a deref of that temporary. If the rvalue
+ * ends up not being used, the temp will get copy-propagated out.
+ */
+ ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp",
+ ir_var_temporary);
+ ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
+ instructions->push_tail(var);
+ instructions->push_tail(new(ctx) ir_assignment(deref_var,
+ rhs,
+ NULL));
+ deref_var = new(ctx) ir_dereference_variable(var);
+
+ if (!error_emitted)
+ instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var, NULL));
+
+ return new(ctx) ir_dereference_variable(var);
+}
+
+static ir_rvalue *
+get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
+{
+ void *ctx = ralloc_parent(lvalue);
+ ir_variable *var;
+
+ var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
+ ir_var_temporary);
+ instructions->push_tail(var);
+ var->mode = ir_var_auto;
+
+ instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
+ lvalue, NULL));
+
+ /* Once we've created this temporary, mark it read only so it's no
+ * longer considered an lvalue.
+ */
+ var->read_only = true;
+
+ return new(ctx) ir_dereference_variable(var);
+}
+
+
+ir_rvalue *
+ast_node::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ (void) instructions;
+ (void) state;
+
+ return NULL;
+}
+
+static void
+mark_whole_array_access(ir_rvalue *access)
+{
+ ir_dereference_variable *deref = access->as_dereference_variable();
+
+ if (deref) {
+ deref->var->max_array_access = deref->type->length - 1;
+ }
+}
+
+static ir_rvalue *
+do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
+{
+ int join_op;
+ ir_rvalue *cmp = NULL;
+
+ if (operation == ir_binop_all_equal)
+ join_op = ir_binop_logic_and;
+ else
+ join_op = ir_binop_logic_or;
+
+ switch (op0->type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_BOOL:
+ return new(mem_ctx) ir_expression(operation, op0, op1);
+
+ case GLSL_TYPE_ARRAY: {
+ for (unsigned int i = 0; i < op0->type->length; i++) {
+ ir_rvalue *e0, *e1, *result;
+
+ e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL),
+ new(mem_ctx) ir_constant(i));
+ e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL),
+ new(mem_ctx) ir_constant(i));
+ result = do_comparison(mem_ctx, operation, e0, e1);
+
+ if (cmp) {
+ cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
+ } else {
+ cmp = result;
+ }
+ }
+
+ mark_whole_array_access(op0);
+ mark_whole_array_access(op1);
+ break;
+ }
+
+ case GLSL_TYPE_STRUCT: {
+ for (unsigned int i = 0; i < op0->type->length; i++) {
+ ir_rvalue *e0, *e1, *result;
+ const char *field_name = op0->type->fields.structure[i].name;
+
+ e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL),
+ field_name);
+ e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL),
+ field_name);
+ result = do_comparison(mem_ctx, operation, e0, e1);
+
+ if (cmp) {
+ cmp = new(mem_ctx) ir_expression(join_op, cmp, result);
+ } else {
+ cmp = result;
+ }
+ }
+ break;
+ }
+
+ case GLSL_TYPE_ERROR:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_SAMPLER:
+ /* I assume a comparison of a struct containing a sampler just
+ * ignores the sampler present in the type.
+ */
+ break;
+
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+
+ if (cmp == NULL)
+ cmp = new(mem_ctx) ir_constant(true);
+
+ return cmp;
+}
+
+ir_rvalue *
+ast_expression::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ static const int operations[AST_NUM_OPERATORS] = {
+ -1, /* ast_assign doesn't convert to ir_expression. */
+ -1, /* ast_plus doesn't convert to ir_expression. */
+ ir_unop_neg,
+ ir_binop_add,
+ ir_binop_sub,
+ ir_binop_mul,
+ ir_binop_div,
+ ir_binop_mod,
+ ir_binop_lshift,
+ ir_binop_rshift,
+ ir_binop_less,
+ ir_binop_greater,
+ ir_binop_lequal,
+ ir_binop_gequal,
+ ir_binop_all_equal,
+ ir_binop_any_nequal,
+ ir_binop_bit_and,
+ ir_binop_bit_xor,
+ ir_binop_bit_or,
+ ir_unop_bit_not,
+ ir_binop_logic_and,
+ ir_binop_logic_xor,
+ ir_binop_logic_or,
+ ir_unop_logic_not,
+
+ /* Note: The following block of expression types actually convert
+ * to multiple IR instructions.
+ */
+ ir_binop_mul, /* ast_mul_assign */
+ ir_binop_div, /* ast_div_assign */
+ ir_binop_mod, /* ast_mod_assign */
+ ir_binop_add, /* ast_add_assign */
+ ir_binop_sub, /* ast_sub_assign */
+ ir_binop_lshift, /* ast_ls_assign */
+ ir_binop_rshift, /* ast_rs_assign */
+ ir_binop_bit_and, /* ast_and_assign */
+ ir_binop_bit_xor, /* ast_xor_assign */
+ ir_binop_bit_or, /* ast_or_assign */
+
+ -1, /* ast_conditional doesn't convert to ir_expression. */
+ ir_binop_add, /* ast_pre_inc. */
+ ir_binop_sub, /* ast_pre_dec. */
+ ir_binop_add, /* ast_post_inc. */
+ ir_binop_sub, /* ast_post_dec. */
+ -1, /* ast_field_selection doesn't conv to ir_expression. */
+ -1, /* ast_array_index doesn't convert to ir_expression. */
+ -1, /* ast_function_call doesn't conv to ir_expression. */
+ -1, /* ast_identifier doesn't convert to ir_expression. */
+ -1, /* ast_int_constant doesn't convert to ir_expression. */
+ -1, /* ast_uint_constant doesn't conv to ir_expression. */
+ -1, /* ast_float_constant doesn't conv to ir_expression. */
+ -1, /* ast_bool_constant doesn't conv to ir_expression. */
+ -1, /* ast_sequence doesn't convert to ir_expression. */
+ };
+ ir_rvalue *result = NULL;
+ ir_rvalue *op[3];
+ const struct glsl_type *type = glsl_type::error_type;
+ bool error_emitted = false;
+ YYLTYPE loc;
+
+ loc = this->get_location();
+
+ switch (this->oper) {
+ case ast_assign: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ result = do_assignment(instructions, state, op[0], op[1],
+ this->subexpressions[0]->get_location());
+ error_emitted = result->type->is_error();
+ type = result->type;
+ break;
+ }
+
+ case ast_plus:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ type = unary_arithmetic_result_type(op[0]->type, state, & loc);
+
+ error_emitted = type->is_error();
+
+ result = op[0];
+ break;
+
+ case ast_neg:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ type = unary_arithmetic_result_type(op[0]->type, state, & loc);
+
+ error_emitted = type->is_error();
+
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], NULL);
+ break;
+
+ case ast_add:
+ case ast_sub:
+ case ast_mul:
+ case ast_div:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ type = arithmetic_result_type(op[0], op[1],
+ (this->oper == ast_mul),
+ state, & loc);
+ error_emitted = type->is_error();
+
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+ break;
+
+ case ast_mod:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
+
+ assert(operations[this->oper] == ir_binop_mod);
+
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+ error_emitted = type->is_error();
+ break;
+
+ case ast_lshift:
+ case ast_rshift:
+ if (state->language_version < 130) {
+ _mesa_glsl_error(&loc, state, "operator %s requires GLSL 1.30",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+ type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
+ &loc);
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+ break;
+
+ case ast_less:
+ case ast_greater:
+ case ast_lequal:
+ case ast_gequal:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ type = relational_result_type(op[0], op[1], state, & loc);
+
+ /* The relational operators must either generate an error or result
+ * in a scalar boolean. See page 57 of the GLSL 1.50 spec.
+ */
+ assert(type->is_error()
+ || ((type->base_type == GLSL_TYPE_BOOL)
+ && type->is_scalar()));
+
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+ error_emitted = type->is_error();
+ break;
+
+ case ast_nequal:
+ case ast_equal:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "The equality operators equal (==), and not equal (!=)
+ * operate on all types. They result in a scalar Boolean. If
+ * the operand types do not match, then there must be a
+ * conversion from Section 4.1.10 "Implicit Conversions"
+ * applied to one operand that can make them match, in which
+ * case this conversion is done."
+ */
+ if ((!apply_implicit_conversion(op[0]->type, op[1], state)
+ && !apply_implicit_conversion(op[1]->type, op[0], state))
+ || (op[0]->type != op[1]->type)) {
+ _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
+ "type", (this->oper == ast_equal) ? "==" : "!=");
+ error_emitted = true;
+ } else if ((state->language_version <= 110)
+ && (op[0]->type->is_array() || op[1]->type->is_array())) {
+ _mesa_glsl_error(& loc, state, "array comparisons forbidden in "
+ "GLSL 1.10");
+ error_emitted = true;
+ }
+
+ result = do_comparison(ctx, operations[this->oper], op[0], op[1]);
+ type = glsl_type::bool_type;
+
+ assert(error_emitted || (result->type == glsl_type::bool_type));
+ break;
+
+ case ast_bit_and:
+ case ast_bit_xor:
+ case ast_bit_or:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+ type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper,
+ state, &loc);
+ result = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+ break;
+
+ case ast_bit_not:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ if (state->language_version < 130) {
+ _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30");
+ error_emitted = true;
+ }
+
+ if (!op[0]->type->is_integer()) {
+ _mesa_glsl_error(&loc, state, "operand of `~' must be an integer");
+ error_emitted = true;
+ }
+
+ type = op[0]->type;
+ result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL);
+ break;
+
+ case ast_logic_and: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[0]->get_location();
+
+ _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+
+ ir_constant *op0_const = op[0]->constant_expression_value();
+ if (op0_const) {
+ if (op0_const->value.b[0]) {
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[1]->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "RHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+ result = op[1];
+ } else {
+ result = op0_const;
+ }
+ type = glsl_type::bool_type;
+ } else {
+ ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
+ "and_tmp",
+ ir_var_temporary);
+ instructions->push_tail(tmp);
+
+ ir_if *const stmt = new(ctx) ir_if(op[0]);
+ instructions->push_tail(stmt);
+
+ op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state);
+
+ if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[1]->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "RHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+
+ ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const then_assign =
+ new(ctx) ir_assignment(then_deref, op[1], NULL);
+ stmt->then_instructions.push_tail(then_assign);
+
+ ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const else_assign =
+ new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false), NULL);
+ stmt->else_instructions.push_tail(else_assign);
+
+ result = new(ctx) ir_dereference_variable(tmp);
+ type = tmp->type;
+ }
+ break;
+ }
+
+ case ast_logic_or: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[0]->get_location();
+
+ _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+
+ ir_constant *op0_const = op[0]->constant_expression_value();
+ if (op0_const) {
+ if (op0_const->value.b[0]) {
+ result = op0_const;
+ } else {
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[1]->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "RHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+ result = op[1];
+ }
+ type = glsl_type::bool_type;
+ } else {
+ ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
+ "or_tmp",
+ ir_var_temporary);
+ instructions->push_tail(tmp);
+
+ ir_if *const stmt = new(ctx) ir_if(op[0]);
+ instructions->push_tail(stmt);
+
+ op[1] = this->subexpressions[1]->hir(&stmt->else_instructions, state);
+
+ if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[1]->get_location();
+
+ _mesa_glsl_error(& loc, state, "RHS of `%s' must be scalar boolean",
+ operator_string(this->oper));
+ error_emitted = true;
+ }
+
+ ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const then_assign =
+ new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true), NULL);
+ stmt->then_instructions.push_tail(then_assign);
+
+ ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const else_assign =
+ new(ctx) ir_assignment(else_deref, op[1], NULL);
+ stmt->else_instructions.push_tail(else_assign);
+
+ result = new(ctx) ir_dereference_variable(tmp);
+ type = tmp->type;
+ }
+ break;
+ }
+
+ case ast_logic_xor:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+
+ result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+ op[0], op[1]);
+ type = glsl_type::bool_type;
+ break;
+
+ case ast_logic_not:
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[0]->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "operand of `!' must be scalar boolean");
+ error_emitted = true;
+ }
+
+ result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type,
+ op[0], NULL);
+ type = glsl_type::bool_type;
+ break;
+
+ case ast_mul_assign:
+ case ast_div_assign:
+ case ast_add_assign:
+ case ast_sub_assign: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ type = arithmetic_result_type(op[0], op[1],
+ (this->oper == ast_mul_assign),
+ state, & loc);
+
+ ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+
+ result = do_assignment(instructions, state,
+ op[0]->clone(ctx, NULL), temp_rhs,
+ this->subexpressions[0]->get_location());
+ type = result->type;
+ error_emitted = (op[0]->type->is_error());
+
+ /* GLSL 1.10 does not allow array assignment. However, we don't have to
+ * explicitly test for this because none of the binary expression
+ * operators allow array operands either.
+ */
+
+ break;
+ }
+
+ case ast_mod_assign: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+
+ type = modulus_result_type(op[0]->type, op[1]->type, state, & loc);
+
+ assert(operations[this->oper] == ir_binop_mod);
+
+ ir_rvalue *temp_rhs;
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+
+ result = do_assignment(instructions, state,
+ op[0]->clone(ctx, NULL), temp_rhs,
+ this->subexpressions[0]->get_location());
+ type = result->type;
+ error_emitted = type->is_error();
+ break;
+ }
+
+ case ast_ls_assign:
+ case ast_rs_assign: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+ type = shift_result_type(op[0]->type, op[1]->type, this->oper, state,
+ &loc);
+ ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
+ type, op[0], op[1]);
+ result = do_assignment(instructions, state, op[0]->clone(ctx, NULL),
+ temp_rhs,
+ this->subexpressions[0]->get_location());
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+ break;
+ }
+
+ case ast_and_assign:
+ case ast_xor_assign:
+ case ast_or_assign: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ op[1] = this->subexpressions[1]->hir(instructions, state);
+ type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper,
+ state, &loc);
+ ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper],
+ type, op[0], op[1]);
+ result = do_assignment(instructions, state, op[0]->clone(ctx, NULL),
+ temp_rhs,
+ this->subexpressions[0]->get_location());
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+ break;
+ }
+
+ case ast_conditional: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+
+ /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "The ternary selection operator (?:). It operates on three
+ * expressions (exp1 ? exp2 : exp3). This operator evaluates the
+ * first expression, which must result in a scalar Boolean."
+ */
+ if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) {
+ YYLTYPE loc = this->subexpressions[0]->get_location();
+
+ _mesa_glsl_error(& loc, state, "?: condition must be scalar boolean");
+ error_emitted = true;
+ }
+
+ /* The :? operator is implemented by generating an anonymous temporary
+ * followed by an if-statement. The last instruction in each branch of
+ * the if-statement assigns a value to the anonymous temporary. This
+ * temporary is the r-value of the expression.
+ */
+ exec_list then_instructions;
+ exec_list else_instructions;
+
+ op[1] = this->subexpressions[1]->hir(&then_instructions, state);
+ op[2] = this->subexpressions[2]->hir(&else_instructions, state);
+
+ /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "The second and third expressions can be any type, as
+ * long their types match, or there is a conversion in
+ * Section 4.1.10 "Implicit Conversions" that can be applied
+ * to one of the expressions to make their types match. This
+ * resulting matching type is the type of the entire
+ * expression."
+ */
+ if ((!apply_implicit_conversion(op[1]->type, op[2], state)
+ && !apply_implicit_conversion(op[2]->type, op[1], state))
+ || (op[1]->type != op[2]->type)) {
+ YYLTYPE loc = this->subexpressions[1]->get_location();
+
+ _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
+ "operator must have matching types.");
+ error_emitted = true;
+ type = glsl_type::error_type;
+ } else {
+ type = op[1]->type;
+ }
+
+ /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "The second and third expressions must be the same type, but can
+ * be of any type other than an array."
+ */
+ if ((state->language_version <= 110) && type->is_array()) {
+ _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
+ "operator must not be arrays.");
+ error_emitted = true;
+ }
+
+ ir_constant *cond_val = op[0]->constant_expression_value();
+ ir_constant *then_val = op[1]->constant_expression_value();
+ ir_constant *else_val = op[2]->constant_expression_value();
+
+ if (then_instructions.is_empty()
+ && else_instructions.is_empty()
+ && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) {
+ result = (cond_val->value.b[0]) ? then_val : else_val;
+ } else {
+ ir_variable *const tmp =
+ new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
+ instructions->push_tail(tmp);
+
+ ir_if *const stmt = new(ctx) ir_if(op[0]);
+ instructions->push_tail(stmt);
+
+ then_instructions.move_nodes_to(& stmt->then_instructions);
+ ir_dereference *const then_deref =
+ new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const then_assign =
+ new(ctx) ir_assignment(then_deref, op[1], NULL);
+ stmt->then_instructions.push_tail(then_assign);
+
+ else_instructions.move_nodes_to(& stmt->else_instructions);
+ ir_dereference *const else_deref =
+ new(ctx) ir_dereference_variable(tmp);
+ ir_assignment *const else_assign =
+ new(ctx) ir_assignment(else_deref, op[2], NULL);
+ stmt->else_instructions.push_tail(else_assign);
+
+ result = new(ctx) ir_dereference_variable(tmp);
+ }
+ break;
+ }
+
+ case ast_pre_inc:
+ case ast_pre_dec: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
+ op[1] = new(ctx) ir_constant(1.0f);
+ else
+ op[1] = new(ctx) ir_constant(1);
+
+ type = arithmetic_result_type(op[0], op[1], false, state, & loc);
+
+ ir_rvalue *temp_rhs;
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+
+ result = do_assignment(instructions, state,
+ op[0]->clone(ctx, NULL), temp_rhs,
+ this->subexpressions[0]->get_location());
+ type = result->type;
+ error_emitted = op[0]->type->is_error();
+ break;
+ }
+
+ case ast_post_inc:
+ case ast_post_dec: {
+ op[0] = this->subexpressions[0]->hir(instructions, state);
+ if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
+ op[1] = new(ctx) ir_constant(1.0f);
+ else
+ op[1] = new(ctx) ir_constant(1);
+
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+
+ type = arithmetic_result_type(op[0], op[1], false, state, & loc);
+
+ ir_rvalue *temp_rhs;
+ temp_rhs = new(ctx) ir_expression(operations[this->oper], type,
+ op[0], op[1]);
+
+ /* Get a temporary of a copy of the lvalue before it's modified.
+ * This may get thrown away later.
+ */
+ result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL));
+
+ (void)do_assignment(instructions, state,
+ op[0]->clone(ctx, NULL), temp_rhs,
+ this->subexpressions[0]->get_location());
+
+ type = result->type;
+ error_emitted = op[0]->type->is_error();
+ break;
+ }
+
+ case ast_field_selection:
+ result = _mesa_ast_field_selection_to_hir(this, instructions, state);
+ type = result->type;
+ break;
+
+ case ast_array_index: {
+ YYLTYPE index_loc = subexpressions[1]->get_location();
+
+ op[0] = subexpressions[0]->hir(instructions, state);
+ op[1] = subexpressions[1]->hir(instructions, state);
+
+ error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+
+ ir_rvalue *const array = op[0];
+
+ result = new(ctx) ir_dereference_array(op[0], op[1]);
+
+ /* Do not use op[0] after this point. Use array.
+ */
+ op[0] = NULL;
+
+
+ if (error_emitted)
+ break;
+
+ if (!array->type->is_array()
+ && !array->type->is_matrix()
+ && !array->type->is_vector()) {
+ _mesa_glsl_error(& index_loc, state,
+ "cannot dereference non-array / non-matrix / "
+ "non-vector");
+ error_emitted = true;
+ }
+
+ if (!op[1]->type->is_integer()) {
+ _mesa_glsl_error(& index_loc, state,
+ "array index must be integer type");
+ error_emitted = true;
+ } else if (!op[1]->type->is_scalar()) {
+ _mesa_glsl_error(& index_loc, state,
+ "array index must be scalar");
+ error_emitted = true;
+ }
+
+ /* If the array index is a constant expression and the array has a
+ * declared size, ensure that the access is in-bounds. If the array
+ * index is not a constant expression, ensure that the array has a
+ * declared size.
+ */
+ ir_constant *const const_index = op[1]->constant_expression_value();
+ if (const_index != NULL) {
+ const int idx = const_index->value.i[0];
+ const char *type_name;
+ unsigned bound = 0;
+
+ if (array->type->is_matrix()) {
+ type_name = "matrix";
+ } else if (array->type->is_vector()) {
+ type_name = "vector";
+ } else {
+ type_name = "array";
+ }
+
+ /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "It is illegal to declare an array with a size, and then
+ * later (in the same shader) index the same array with an
+ * integral constant expression greater than or equal to the
+ * declared size. It is also illegal to index an array with a
+ * negative constant expression."
+ */
+ if (array->type->is_matrix()) {
+ if (array->type->row_type()->vector_elements <= idx) {
+ bound = array->type->row_type()->vector_elements;
+ }
+ } else if (array->type->is_vector()) {
+ if (array->type->vector_elements <= idx) {
+ bound = array->type->vector_elements;
+ }
+ } else {
+ if ((array->type->array_size() > 0)
+ && (array->type->array_size() <= idx)) {
+ bound = array->type->array_size();
+ }
+ }
+
+ if (bound > 0) {
+ _mesa_glsl_error(& loc, state, "%s index must be < %u",
+ type_name, bound);
+ error_emitted = true;
+ } else if (idx < 0) {
+ _mesa_glsl_error(& loc, state, "%s index must be >= 0",
+ type_name);
+ error_emitted = true;
+ }
+
+ if (array->type->is_array()) {
+ /* If the array is a variable dereference, it dereferences the
+ * whole array, by definition. Use this to get the variable.
+ *
+ * FINISHME: Should some methods for getting / setting / testing
+ * FINISHME: array access limits be added to ir_dereference?
+ */
+ ir_variable *const v = array->whole_variable_referenced();
+ if ((v != NULL) && (unsigned(idx) > v->max_array_access))
+ v->max_array_access = idx;
+ }
+ } else if (array->type->array_size() == 0) {
+ _mesa_glsl_error(&loc, state, "unsized array index must be constant");
+ } else {
+ if (array->type->is_array()) {
+ /* whole_variable_referenced can return NULL if the array is a
+ * member of a structure. In this case it is safe to not update
+ * the max_array_access field because it is never used for fields
+ * of structures.
+ */
+ ir_variable *v = array->whole_variable_referenced();
+ if (v != NULL)
+ v->max_array_access = array->type->array_size();
+ }
+ }
+
+ /* From page 23 (29 of the PDF) of the GLSL 1.30 spec:
+ *
+ * "Samplers aggregated into arrays within a shader (using square
+ * brackets [ ]) can only be indexed with integral constant
+ * expressions [...]."
+ *
+ * This restriction was added in GLSL 1.30. Shaders using earlier version
+ * of the language should not be rejected by the compiler front-end for
+ * using this construct. This allows useful things such as using a loop
+ * counter as the index to an array of samplers. If the loop in unrolled,
+ * the code should compile correctly. Instead, emit a warning.
+ */
+ if (array->type->is_array() &&
+ array->type->element_type()->is_sampler() &&
+ const_index == NULL) {
+
+ if (state->language_version == 100) {
+ _mesa_glsl_warning(&loc, state,
+ "sampler arrays indexed with non-constant "
+ "expressions is optional in GLSL ES 1.00");
+ } else if (state->language_version < 130) {
+ _mesa_glsl_warning(&loc, state,
+ "sampler arrays indexed with non-constant "
+ "expressions is forbidden in GLSL 1.30 and "
+ "later");
+ } else {
+ _mesa_glsl_error(&loc, state,
+ "sampler arrays indexed with non-constant "
+ "expressions is forbidden in GLSL 1.30 and "
+ "later");
+ error_emitted = true;
+ }
+ }
+
+ if (error_emitted)
+ result->type = glsl_type::error_type;
+
+ type = result->type;
+ break;
+ }
+
+ case ast_function_call:
+ /* Should *NEVER* get here. ast_function_call should always be handled
+ * by ast_function_expression::hir.
+ */
+ assert(0);
+ break;
+
+ case ast_identifier: {
+ /* ast_identifier can appear several places in a full abstract syntax
+ * tree. This particular use must be at location specified in the grammar
+ * as 'variable_identifier'.
+ */
+ ir_variable *var =
+ state->symbols->get_variable(this->primary_expression.identifier);
+
+ result = new(ctx) ir_dereference_variable(var);
+
+ if (var != NULL) {
+ var->used = true;
+ type = result->type;
+ } else {
+ _mesa_glsl_error(& loc, state, "`%s' undeclared",
+ this->primary_expression.identifier);
+
+ error_emitted = true;
+ }
+ break;
+ }
+
+ case ast_int_constant:
+ type = glsl_type::int_type;
+ result = new(ctx) ir_constant(this->primary_expression.int_constant);
+ break;
+
+ case ast_uint_constant:
+ type = glsl_type::uint_type;
+ result = new(ctx) ir_constant(this->primary_expression.uint_constant);
+ break;
+
+ case ast_float_constant:
+ type = glsl_type::float_type;
+ result = new(ctx) ir_constant(this->primary_expression.float_constant);
+ break;
+
+ case ast_bool_constant:
+ type = glsl_type::bool_type;
+ result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
+ break;
+
+ case ast_sequence: {
+ /* It should not be possible to generate a sequence in the AST without
+ * any expressions in it.
+ */
+ assert(!this->expressions.is_empty());
+
+ /* The r-value of a sequence is the last expression in the sequence. If
+ * the other expressions in the sequence do not have side-effects (and
+ * therefore add instructions to the instruction list), they get dropped
+ * on the floor.
+ */
+ foreach_list_typed (ast_node, ast, link, &this->expressions)
+ result = ast->hir(instructions, state);
+
+ type = result->type;
+
+ /* Any errors should have already been emitted in the loop above.
+ */
+ error_emitted = true;
+ break;
+ }
+ }
+
+ if (type->is_error() && !error_emitted)
+ _mesa_glsl_error(& loc, state, "type mismatch");
+
+ return result;
+}
+
+
+ir_rvalue *
+ast_expression_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ /* It is possible to have expression statements that don't have an
+ * expression. This is the solitary semicolon:
+ *
+ * for (i = 0; i < 5; i++)
+ * ;
+ *
+ * In this case the expression will be NULL. Test for NULL and don't do
+ * anything in that case.
+ */
+ if (expression != NULL)
+ expression->hir(instructions, state);
+
+ /* Statements do not have r-values.
+ */
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_compound_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ if (new_scope)
+ state->symbols->push_scope();
+
+ foreach_list_typed (ast_node, ast, link, &this->statements)
+ ast->hir(instructions, state);
+
+ if (new_scope)
+ state->symbols->pop_scope();
+
+ /* Compound statements do not have r-values.
+ */
+ return NULL;
+}
+
+
+static const glsl_type *
+process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
+ struct _mesa_glsl_parse_state *state)
+{
+ unsigned length = 0;
+
+ /* FINISHME: Reject delcarations of multidimensional arrays. */
+
+ if (array_size != NULL) {
+ exec_list dummy_instructions;
+ ir_rvalue *const ir = array_size->hir(& dummy_instructions, state);
+ YYLTYPE loc = array_size->get_location();
+
+ /* FINISHME: Verify that the grammar forbids side-effects in array
+ * FINISHME: sizes. i.e., 'vec4 [x = 12] data'
+ */
+ assert(dummy_instructions.is_empty());
+
+ if (ir != NULL) {
+ if (!ir->type->is_integer()) {
+ _mesa_glsl_error(& loc, state, "array size must be integer type");
+ } else if (!ir->type->is_scalar()) {
+ _mesa_glsl_error(& loc, state, "array size must be scalar type");
+ } else {
+ ir_constant *const size = ir->constant_expression_value();
+
+ if (size == NULL) {
+ _mesa_glsl_error(& loc, state, "array size must be a "
+ "constant valued expression");
+ } else if (size->value.i[0] <= 0) {
+ _mesa_glsl_error(& loc, state, "array size must be > 0");
+ } else {
+ assert(size->type == ir->type);
+ length = size->value.u[0];
+ }
+ }
+ }
+ } else if (state->es_shader) {
+ /* Section 10.17 of the GLSL ES 1.00 specification states that unsized
+ * array declarations have been removed from the language.
+ */
+ _mesa_glsl_error(loc, state, "unsized array declarations are not "
+ "allowed in GLSL ES 1.00.");
+ }
+
+ return glsl_type::get_array_instance(base, length);
+}
+
+
+const glsl_type *
+ast_type_specifier::glsl_type(const char **name,
+ struct _mesa_glsl_parse_state *state) const
+{
+ const struct glsl_type *type;
+
+ type = state->symbols->get_type(this->type_name);
+ *name = this->type_name;
+
+ if (this->is_array) {
+ YYLTYPE loc = this->get_location();
+ type = process_array_type(&loc, type, this->array_size, state);
+ }
+
+ return type;
+}
+
+
+static void
+apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
+ ir_variable *var,
+ struct _mesa_glsl_parse_state *state,
+ YYLTYPE *loc)
+{
+ if (qual->flags.q.invariant) {
+ if (var->used) {
+ _mesa_glsl_error(loc, state,
+ "variable `%s' may not be redeclared "
+ "`invariant' after being used",
+ var->name);
+ } else {
+ var->invariant = 1;
+ }
+ }
+
+ if (qual->flags.q.constant || qual->flags.q.attribute
+ || qual->flags.q.uniform
+ || (qual->flags.q.varying && (state->target == fragment_shader)))
+ var->read_only = 1;
+
+ if (qual->flags.q.centroid)
+ var->centroid = 1;
+
+ if (qual->flags.q.attribute && state->target != vertex_shader) {
+ var->type = glsl_type::error_type;
+ _mesa_glsl_error(loc, state,
+ "`attribute' variables may not be declared in the "
+ "%s shader",
+ _mesa_glsl_shader_target_name(state->target));
+ }
+
+ /* From page 25 (page 31 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "The varying qualifier can be used only with the data types
+ * float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of
+ * these."
+ */
+ if (qual->flags.q.varying) {
+ const glsl_type *non_array_type;
+
+ if (var->type && var->type->is_array())
+ non_array_type = var->type->fields.array;
+ else
+ non_array_type = var->type;
+
+ if (non_array_type && non_array_type->base_type != GLSL_TYPE_FLOAT) {
+ var->type = glsl_type::error_type;
+ _mesa_glsl_error(loc, state,
+ "varying variables must be of base type float");
+ }
+ }
+
+ /* If there is no qualifier that changes the mode of the variable, leave
+ * the setting alone.
+ */
+ if (qual->flags.q.in && qual->flags.q.out)
+ var->mode = ir_var_inout;
+ else if (qual->flags.q.attribute || qual->flags.q.in
+ || (qual->flags.q.varying && (state->target == fragment_shader)))
+ var->mode = ir_var_in;
+ else if (qual->flags.q.out
+ || (qual->flags.q.varying && (state->target == vertex_shader)))
+ var->mode = ir_var_out;
+ else if (qual->flags.q.uniform)
+ var->mode = ir_var_uniform;
+
+ if (state->all_invariant && (state->current_function == NULL)) {
+ switch (state->target) {
+ case vertex_shader:
+ if (var->mode == ir_var_out)
+ var->invariant = true;
+ break;
+ case geometry_shader:
+ if ((var->mode == ir_var_in) || (var->mode == ir_var_out))
+ var->invariant = true;
+ break;
+ case fragment_shader:
+ if (var->mode == ir_var_in)
+ var->invariant = true;
+ break;
+ }
+ }
+
+ if (qual->flags.q.flat)
+ var->interpolation = ir_var_flat;
+ else if (qual->flags.q.noperspective)
+ var->interpolation = ir_var_noperspective;
+ else
+ var->interpolation = ir_var_smooth;
+
+ var->pixel_center_integer = qual->flags.q.pixel_center_integer;
+ var->origin_upper_left = qual->flags.q.origin_upper_left;
+ if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer)
+ && (strcmp(var->name, "gl_FragCoord") != 0)) {
+ const char *const qual_string = (qual->flags.q.origin_upper_left)
+ ? "origin_upper_left" : "pixel_center_integer";
+
+ _mesa_glsl_error(loc, state,
+ "layout qualifier `%s' can only be applied to "
+ "fragment shader input `gl_FragCoord'",
+ qual_string);
+ }
+
+ if (qual->flags.q.explicit_location) {
+ const bool global_scope = (state->current_function == NULL);
+ bool fail = false;
+ const char *string = "";
+
+ /* In the vertex shader only shader inputs can be given explicit
+ * locations.
+ *
+ * In the fragment shader only shader outputs can be given explicit
+ * locations.
+ */
+ switch (state->target) {
+ case vertex_shader:
+ if (!global_scope || (var->mode != ir_var_in)) {
+ fail = true;
+ string = "input";
+ }
+ break;
+
+ case geometry_shader:
+ _mesa_glsl_error(loc, state,
+ "geometry shader variables cannot be given "
+ "explicit locations\n");
+ break;
+
+ case fragment_shader:
+ if (!global_scope || (var->mode != ir_var_in)) {
+ fail = true;
+ string = "output";
+ }
+ break;
+ };
+
+ if (fail) {
+ _mesa_glsl_error(loc, state,
+ "only %s shader %s variables can be given an "
+ "explicit location\n",
+ _mesa_glsl_shader_target_name(state->target),
+ string);
+ } else {
+ var->explicit_location = true;
+
+ /* This bit of silliness is needed because invalid explicit locations
+ * are supposed to be flagged during linking. Small negative values
+ * biased by VERT_ATTRIB_GENERIC0 or FRAG_RESULT_DATA0 could alias
+ * built-in values (e.g., -16+VERT_ATTRIB_GENERIC0 = VERT_ATTRIB_POS).
+ * The linker needs to be able to differentiate these cases. This
+ * ensures that negative values stay negative.
+ */
+ if (qual->location >= 0) {
+ var->location = (state->target == vertex_shader)
+ ? (qual->location + VERT_ATTRIB_GENERIC0)
+ : (qual->location + FRAG_RESULT_DATA0);
+ } else {
+ var->location = qual->location;
+ }
+ }
+ }
+
+ /* Does the declaration use the 'layout' keyword?
+ */
+ const bool uses_layout = qual->flags.q.pixel_center_integer
+ || qual->flags.q.origin_upper_left
+ || qual->flags.q.explicit_location;
+
+ /* Does the declaration use the deprecated 'attribute' or 'varying'
+ * keywords?
+ */
+ const bool uses_deprecated_qualifier = qual->flags.q.attribute
+ || qual->flags.q.varying;
+
+ /* Is the 'layout' keyword used with parameters that allow relaxed checking.
+ * Many implementations of GL_ARB_fragment_coord_conventions_enable and some
+ * implementations (only Mesa?) GL_ARB_explicit_attrib_location_enable
+ * allowed the layout qualifier to be used with 'varying' and 'attribute'.
+ * These extensions and all following extensions that add the 'layout'
+ * keyword have been modified to require the use of 'in' or 'out'.
+ *
+ * The following extension do not allow the deprecated keywords:
+ *
+ * GL_AMD_conservative_depth
+ * GL_ARB_gpu_shader5
+ * GL_ARB_separate_shader_objects
+ * GL_ARB_tesselation_shader
+ * GL_ARB_transform_feedback3
+ * GL_ARB_uniform_buffer_object
+ *
+ * It is unknown whether GL_EXT_shader_image_load_store or GL_NV_gpu_shader5
+ * allow layout with the deprecated keywords.
+ */
+ const bool relaxed_layout_qualifier_checking =
+ state->ARB_fragment_coord_conventions_enable;
+
+ if (uses_layout && uses_deprecated_qualifier) {
+ if (relaxed_layout_qualifier_checking) {
+ _mesa_glsl_warning(loc, state,
+ "`layout' qualifier may not be used with "
+ "`attribute' or `varying'");
+ } else {
+ _mesa_glsl_error(loc, state,
+ "`layout' qualifier may not be used with "
+ "`attribute' or `varying'");
+ }
+ }
+
+ /* Layout qualifiers for gl_FragDepth, which are enabled by extension
+ * AMD_conservative_depth.
+ */
+ int depth_layout_count = qual->flags.q.depth_any
+ + qual->flags.q.depth_greater
+ + qual->flags.q.depth_less
+ + qual->flags.q.depth_unchanged;
+ if (depth_layout_count > 0
+ && !state->AMD_conservative_depth_enable) {
+ _mesa_glsl_error(loc, state,
+ "extension GL_AMD_conservative_depth must be enabled "
+ "to use depth layout qualifiers");
+ } else if (depth_layout_count > 0
+ && strcmp(var->name, "gl_FragDepth") != 0) {
+ _mesa_glsl_error(loc, state,
+ "depth layout qualifiers can be applied only to "
+ "gl_FragDepth");
+ } else if (depth_layout_count > 1
+ && strcmp(var->name, "gl_FragDepth") == 0) {
+ _mesa_glsl_error(loc, state,
+ "at most one depth layout qualifier can be applied to "
+ "gl_FragDepth");
+ }
+ if (qual->flags.q.depth_any)
+ var->depth_layout = ir_depth_layout_any;
+ else if (qual->flags.q.depth_greater)
+ var->depth_layout = ir_depth_layout_greater;
+ else if (qual->flags.q.depth_less)
+ var->depth_layout = ir_depth_layout_less;
+ else if (qual->flags.q.depth_unchanged)
+ var->depth_layout = ir_depth_layout_unchanged;
+ else
+ var->depth_layout = ir_depth_layout_none;
+
+ if (var->type->is_array() && state->language_version != 110) {
+ var->array_lvalue = true;
+ }
+}
+
+/**
+ * Get the variable that is being redeclared by this declaration
+ *
+ * Semantic checks to verify the validity of the redeclaration are also
+ * performed. If semantic checks fail, compilation error will be emitted via
+ * \c _mesa_glsl_error, but a non-\c NULL pointer will still be returned.
+ *
+ * \returns
+ * A pointer to an existing variable in the current scope if the declaration
+ * is a redeclaration, \c NULL otherwise.
+ */
+ir_variable *
+get_variable_being_redeclared(ir_variable *var, ast_declaration *decl,
+ struct _mesa_glsl_parse_state *state)
+{
+ /* Check if this declaration is actually a re-declaration, either to
+ * resize an array or add qualifiers to an existing variable.
+ *
+ * This is allowed for variables in the current scope, or when at
+ * global scope (for built-ins in the implicit outer scope).
+ */
+ ir_variable *earlier = state->symbols->get_variable(decl->identifier);
+ if (earlier == NULL ||
+ (state->current_function != NULL &&
+ !state->symbols->name_declared_this_scope(decl->identifier))) {
+ return NULL;
+ }
+
+
+ YYLTYPE loc = decl->get_location();
+
+ /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
+ *
+ * "It is legal to declare an array without a size and then
+ * later re-declare the same name as an array of the same
+ * type and specify a size."
+ */
+ if ((earlier->type->array_size() == 0)
+ && var->type->is_array()
+ && (var->type->element_type() == earlier->type->element_type())) {
+ /* FINISHME: This doesn't match the qualifiers on the two
+ * FINISHME: declarations. It's not 100% clear whether this is
+ * FINISHME: required or not.
+ */
+
+ /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
+ *
+ * "The size [of gl_TexCoord] can be at most
+ * gl_MaxTextureCoords."
+ */
+ const unsigned size = unsigned(var->type->array_size());
+ if ((strcmp("gl_TexCoord", var->name) == 0)
+ && (size > state->Const.MaxTextureCoords)) {
+ _mesa_glsl_error(& loc, state, "`gl_TexCoord' array size cannot "
+ "be larger than gl_MaxTextureCoords (%u)\n",
+ state->Const.MaxTextureCoords);
+ } else if ((size > 0) && (size <= earlier->max_array_access)) {
+ _mesa_glsl_error(& loc, state, "array size must be > %u due to "
+ "previous access",
+ earlier->max_array_access);
+ }
+
+ earlier->type = var->type;
+ delete var;
+ var = NULL;
+ } else if (state->ARB_fragment_coord_conventions_enable
+ && strcmp(var->name, "gl_FragCoord") == 0
+ && earlier->type == var->type
+ && earlier->mode == var->mode) {
+ /* Allow redeclaration of gl_FragCoord for ARB_fcc layout
+ * qualifiers.
+ */
+ earlier->origin_upper_left = var->origin_upper_left;
+ earlier->pixel_center_integer = var->pixel_center_integer;
+
+ /* According to section 4.3.7 of the GLSL 1.30 spec,
+ * the following built-in varaibles can be redeclared with an
+ * interpolation qualifier:
+ * * gl_FrontColor
+ * * gl_BackColor
+ * * gl_FrontSecondaryColor
+ * * gl_BackSecondaryColor
+ * * gl_Color
+ * * gl_SecondaryColor
+ */
+ } else if (state->language_version >= 130
+ && (strcmp(var->name, "gl_FrontColor") == 0
+ || strcmp(var->name, "gl_BackColor") == 0
+ || strcmp(var->name, "gl_FrontSecondaryColor") == 0
+ || strcmp(var->name, "gl_BackSecondaryColor") == 0
+ || strcmp(var->name, "gl_Color") == 0
+ || strcmp(var->name, "gl_SecondaryColor") == 0)
+ && earlier->type == var->type
+ && earlier->mode == var->mode) {
+ earlier->interpolation = var->interpolation;
+
+ /* Layout qualifiers for gl_FragDepth. */
+ } else if (state->AMD_conservative_depth_enable
+ && strcmp(var->name, "gl_FragDepth") == 0
+ && earlier->type == var->type
+ && earlier->mode == var->mode) {
+
+ /** From the AMD_conservative_depth spec:
+ * Within any shader, the first redeclarations of gl_FragDepth
+ * must appear before any use of gl_FragDepth.
+ */
+ if (earlier->used) {
+ _mesa_glsl_error(&loc, state,
+ "the first redeclaration of gl_FragDepth "
+ "must appear before any use of gl_FragDepth");
+ }
+
+ /* Prevent inconsistent redeclaration of depth layout qualifier. */
+ if (earlier->depth_layout != ir_depth_layout_none
+ && earlier->depth_layout != var->depth_layout) {
+ _mesa_glsl_error(&loc, state,
+ "gl_FragDepth: depth layout is declared here "
+ "as '%s, but it was previously declared as "
+ "'%s'",
+ depth_layout_string(var->depth_layout),
+ depth_layout_string(earlier->depth_layout));
+ }
+
+ earlier->depth_layout = var->depth_layout;
+
+ } else {
+ _mesa_glsl_error(&loc, state, "`%s' redeclared", decl->identifier);
+ }
+
+ return earlier;
+}
+
+/**
+ * Generate the IR for an initializer in a variable declaration
+ */
+ir_rvalue *
+process_initializer(ir_variable *var, ast_declaration *decl,
+ ast_fully_specified_type *type,
+ exec_list *initializer_instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ ir_rvalue *result = NULL;
+
+ YYLTYPE initializer_loc = decl->initializer->get_location();
+
+ /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "All uniform variables are read-only and are initialized either
+ * directly by an application via API commands, or indirectly by
+ * OpenGL."
+ */
+ if ((state->language_version <= 110)
+ && (var->mode == ir_var_uniform)) {
+ _mesa_glsl_error(& initializer_loc, state,
+ "cannot initialize uniforms in GLSL 1.10");
+ }
+
+ if (var->type->is_sampler()) {
+ _mesa_glsl_error(& initializer_loc, state,
+ "cannot initialize samplers");
+ }
+
+ if ((var->mode == ir_var_in) && (state->current_function == NULL)) {
+ _mesa_glsl_error(& initializer_loc, state,
+ "cannot initialize %s shader input / %s",
+ _mesa_glsl_shader_target_name(state->target),
+ (state->target == vertex_shader)
+ ? "attribute" : "varying");
+ }
+
+ ir_dereference *const lhs = new(state) ir_dereference_variable(var);
+ ir_rvalue *rhs = decl->initializer->hir(initializer_instructions,
+ state);
+
+ /* Calculate the constant value if this is a const or uniform
+ * declaration.
+ */
+ if (type->qualifier.flags.q.constant
+ || type->qualifier.flags.q.uniform) {
+ ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs);
+ if (new_rhs != NULL) {
+ rhs = new_rhs;
+
+ ir_constant *constant_value = rhs->constant_expression_value();
+ if (!constant_value) {
+ _mesa_glsl_error(& initializer_loc, state,
+ "initializer of %s variable `%s' must be a "
+ "constant expression",
+ (type->qualifier.flags.q.constant)
+ ? "const" : "uniform",
+ decl->identifier);
+ if (var->type->is_numeric()) {
+ /* Reduce cascading errors. */
+ var->constant_value = ir_constant::zero(state, var->type);
+ }
+ } else {
+ rhs = constant_value;
+ var->constant_value = constant_value;
+ }
+ } else {
+ _mesa_glsl_error(&initializer_loc, state,
+ "initializer of type %s cannot be assigned to "
+ "variable of type %s",
+ rhs->type->name, var->type->name);
+ if (var->type->is_numeric()) {
+ /* Reduce cascading errors. */
+ var->constant_value = ir_constant::zero(state, var->type);
+ }
+ }
+ }
+
+ if (rhs && !rhs->type->is_error()) {
+ bool temp = var->read_only;
+ if (type->qualifier.flags.q.constant)
+ var->read_only = false;
+
+ /* Never emit code to initialize a uniform.
+ */
+ const glsl_type *initializer_type;
+ if (!type->qualifier.flags.q.uniform) {
+ result = do_assignment(initializer_instructions, state,
+ lhs, rhs,
+ type->get_location());
+ initializer_type = result->type;
+ } else
+ initializer_type = rhs->type;
+
+ /* If the declared variable is an unsized array, it must inherrit
+ * its full type from the initializer. A declaration such as
+ *
+ * uniform float a[] = float[](1.0, 2.0, 3.0, 3.0);
+ *
+ * becomes
+ *
+ * uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0);
+ *
+ * The assignment generated in the if-statement (below) will also
+ * automatically handle this case for non-uniforms.
+ *
+ * If the declared variable is not an array, the types must
+ * already match exactly. As a result, the type assignment
+ * here can be done unconditionally. For non-uniforms the call
+ * to do_assignment can change the type of the initializer (via
+ * the implicit conversion rules). For uniforms the initializer
+ * must be a constant expression, and the type of that expression
+ * was validated above.
+ */
+ var->type = initializer_type;
+
+ var->read_only = temp;
+ }
+
+ return result;
+}
+
+ir_rvalue *
+ast_declarator_list::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ const struct glsl_type *decl_type;
+ const char *type_name = NULL;
+ ir_rvalue *result = NULL;
+ YYLTYPE loc = this->get_location();
+
+ /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "To ensure that a particular output variable is invariant, it is
+ * necessary to use the invariant qualifier. It can either be used to
+ * qualify a previously declared variable as being invariant
+ *
+ * invariant gl_Position; // make existing gl_Position be invariant"
+ *
+ * In these cases the parser will set the 'invariant' flag in the declarator
+ * list, and the type will be NULL.
+ */
+ if (this->invariant) {
+ assert(this->type == NULL);
+
+ if (state->current_function != NULL) {
+ _mesa_glsl_error(& loc, state,
+ "All uses of `invariant' keyword must be at global "
+ "scope\n");
+ }
+
+ foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
+ assert(!decl->is_array);
+ assert(decl->array_size == NULL);
+ assert(decl->initializer == NULL);
+
+ ir_variable *const earlier =
+ state->symbols->get_variable(decl->identifier);
+ if (earlier == NULL) {
+ _mesa_glsl_error(& loc, state,
+ "Undeclared variable `%s' cannot be marked "
+ "invariant\n", decl->identifier);
+ } else if ((state->target == vertex_shader)
+ && (earlier->mode != ir_var_out)) {
+ _mesa_glsl_error(& loc, state,
+ "`%s' cannot be marked invariant, vertex shader "
+ "outputs only\n", decl->identifier);
+ } else if ((state->target == fragment_shader)
+ && (earlier->mode != ir_var_in)) {
+ _mesa_glsl_error(& loc, state,
+ "`%s' cannot be marked invariant, fragment shader "
+ "inputs only\n", decl->identifier);
+ } else if (earlier->used) {
+ _mesa_glsl_error(& loc, state,
+ "variable `%s' may not be redeclared "
+ "`invariant' after being used",
+ earlier->name);
+ } else {
+ earlier->invariant = true;
+ }
+ }
+
+ /* Invariant redeclarations do not have r-values.
+ */
+ return NULL;
+ }
+
+ assert(this->type != NULL);
+ assert(!this->invariant);
+
+ /* The type specifier may contain a structure definition. Process that
+ * before any of the variable declarations.
+ */
+ (void) this->type->specifier->hir(instructions, state);
+
+ decl_type = this->type->specifier->glsl_type(& type_name, state);
+ if (this->declarations.is_empty()) {
+ /* The only valid case where the declaration list can be empty is when
+ * the declaration is setting the default precision of a built-in type
+ * (e.g., 'precision highp vec4;').
+ */
+
+ if (decl_type != NULL) {
+ } else {
+ _mesa_glsl_error(& loc, state, "incomplete declaration");
+ }
+ }
+
+ foreach_list_typed (ast_declaration, decl, link, &this->declarations) {
+ const struct glsl_type *var_type;
+ ir_variable *var;
+
+ /* FINISHME: Emit a warning if a variable declaration shadows a
+ * FINISHME: declaration at a higher scope.
+ */
+
+ if ((decl_type == NULL) || decl_type->is_void()) {
+ if (type_name != NULL) {
+ _mesa_glsl_error(& loc, state,
+ "invalid type `%s' in declaration of `%s'",
+ type_name, decl->identifier);
+ } else {
+ _mesa_glsl_error(& loc, state,
+ "invalid type in declaration of `%s'",
+ decl->identifier);
+ }
+ continue;
+ }
+
+ if (decl->is_array) {
+ var_type = process_array_type(&loc, decl_type, decl->array_size,
+ state);
+ } else {
+ var_type = decl_type;
+ }
+
+ var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
+
+ /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
+ *
+ * "Global variables can only use the qualifiers const,
+ * attribute, uni form, or varying. Only one may be
+ * specified.
+ *
+ * Local variables can only use the qualifier const."
+ *
+ * This is relaxed in GLSL 1.30. It is also relaxed by any extension
+ * that adds the 'layout' keyword.
+ */
+ if ((state->language_version < 130)
+ && !state->ARB_explicit_attrib_location_enable
+ && !state->ARB_fragment_coord_conventions_enable) {
+ if (this->type->qualifier.flags.q.out) {
+ _mesa_glsl_error(& loc, state,
+ "`out' qualifier in declaration of `%s' "
+ "only valid for function parameters in %s.",
+ decl->identifier, state->version_string);
+ }
+ if (this->type->qualifier.flags.q.in) {
+ _mesa_glsl_error(& loc, state,
+ "`in' qualifier in declaration of `%s' "
+ "only valid for function parameters in %s.",
+ decl->identifier, state->version_string);
+ }
+ /* FINISHME: Test for other invalid qualifiers. */
+ }
+
+ apply_type_qualifier_to_variable(& this->type->qualifier, var, state,
+ & loc);
+
+ if (this->type->qualifier.flags.q.invariant) {
+ if ((state->target == vertex_shader) && !(var->mode == ir_var_out ||
+ var->mode == ir_var_inout)) {
+ /* FINISHME: Note that this doesn't work for invariant on
+ * a function signature outval
+ */
+ _mesa_glsl_error(& loc, state,
+ "`%s' cannot be marked invariant, vertex shader "
+ "outputs only\n", var->name);
+ } else if ((state->target == fragment_shader) &&
+ !(var->mode == ir_var_in || var->mode == ir_var_inout)) {
+ /* FINISHME: Note that this doesn't work for invariant on
+ * a function signature inval
+ */
+ _mesa_glsl_error(& loc, state,
+ "`%s' cannot be marked invariant, fragment shader "
+ "inputs only\n", var->name);
+ }
+ }
+
+ if (state->current_function != NULL) {
+ const char *mode = NULL;
+ const char *extra = "";
+
+ /* There is no need to check for 'inout' here because the parser will
+ * only allow that in function parameter lists.
+ */
+ if (this->type->qualifier.flags.q.attribute) {
+ mode = "attribute";
+ } else if (this->type->qualifier.flags.q.uniform) {
+ mode = "uniform";
+ } else if (this->type->qualifier.flags.q.varying) {
+ mode = "varying";
+ } else if (this->type->qualifier.flags.q.in) {
+ mode = "in";
+ extra = " or in function parameter list";
+ } else if (this->type->qualifier.flags.q.out) {
+ mode = "out";
+ extra = " or in function parameter list";
+ }
+
+ if (mode) {
+ _mesa_glsl_error(& loc, state,
+ "%s variable `%s' must be declared at "
+ "global scope%s",
+ mode, var->name, extra);
+ }
+ } else if (var->mode == ir_var_in) {
+ var->read_only = true;
+
+ if (state->target == vertex_shader) {
+ bool error_emitted = false;
+
+ /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "Vertex shader inputs can only be float, floating-point
+ * vectors, matrices, signed and unsigned integers and integer
+ * vectors. Vertex shader inputs can also form arrays of these
+ * types, but not structures."
+ *
+ * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec:
+ *
+ * "Vertex shader inputs can only be float, floating-point
+ * vectors, matrices, signed and unsigned integers and integer
+ * vectors. They cannot be arrays or structures."
+ *
+ * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec:
+ *
+ * "The attribute qualifier can be used only with float,
+ * floating-point vectors, and matrices. Attribute variables
+ * cannot be declared as arrays or structures."
+ */
+ const glsl_type *check_type = var->type->is_array()
+ ? var->type->fields.array : var->type;
+
+ switch (check_type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ break;
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ if (state->language_version > 120)
+ break;
+ /* FALLTHROUGH */
+ default:
+ _mesa_glsl_error(& loc, state,
+ "vertex shader input / attribute cannot have "
+ "type %s`%s'",
+ var->type->is_array() ? "array of " : "",
+ check_type->name);
+ error_emitted = true;
+ }
+
+ if (!error_emitted && (state->language_version <= 130)
+ && var->type->is_array()) {
+ _mesa_glsl_error(& loc, state,
+ "vertex shader input / attribute cannot have "
+ "array type");
+ error_emitted = true;
+ }
+ }
+ }
+
+ /* Integer vertex outputs must be qualified with 'flat'.
+ *
+ * From section 4.3.6 of the GLSL 1.30 spec:
+ * "If a vertex output is a signed or unsigned integer or integer
+ * vector, then it must be qualified with the interpolation qualifier
+ * flat."
+ */
+ if (state->language_version >= 130
+ && state->target == vertex_shader
+ && state->current_function == NULL
+ && var->type->is_integer()
+ && var->mode == ir_var_out
+ && var->interpolation != ir_var_flat) {
+
+ _mesa_glsl_error(&loc, state, "If a vertex output is an integer, "
+ "then it must be qualified with 'flat'");
+ }
+
+
+ /* Interpolation qualifiers cannot be applied to 'centroid' and
+ * 'centroid varying'.
+ *
+ * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec:
+ * "interpolation qualifiers may only precede the qualifiers in,
+ * centroid in, out, or centroid out in a declaration. They do not apply
+ * to the deprecated storage qualifiers varying or centroid varying."
+ */
+ if (state->language_version >= 130
+ && this->type->qualifier.has_interpolation()
+ && this->type->qualifier.flags.q.varying) {
+
+ const char *i = this->type->qualifier.interpolation_string();
+ assert(i != NULL);
+ const char *s;
+ if (this->type->qualifier.flags.q.centroid)
+ s = "centroid varying";
+ else
+ s = "varying";
+
+ _mesa_glsl_error(&loc, state,
+ "qualifier '%s' cannot be applied to the "
+ "deprecated storage qualifier '%s'", i, s);
+ }
+
+
+ /* Interpolation qualifiers can only apply to vertex shader outputs and
+ * fragment shader inputs.
+ *
+ * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec:
+ * "Outputs from a vertex shader (out) and inputs to a fragment
+ * shader (in) can be further qualified with one or more of these
+ * interpolation qualifiers"
+ */
+ if (state->language_version >= 130
+ && this->type->qualifier.has_interpolation()) {
+
+ const char *i = this->type->qualifier.interpolation_string();
+ assert(i != NULL);
+
+ switch (state->target) {
+ case vertex_shader:
+ if (this->type->qualifier.flags.q.in) {
+ _mesa_glsl_error(&loc, state,
+ "qualifier '%s' cannot be applied to vertex "
+ "shader inputs", i);
+ }
+ break;
+ case fragment_shader:
+ if (this->type->qualifier.flags.q.out) {
+ _mesa_glsl_error(&loc, state,
+ "qualifier '%s' cannot be applied to fragment "
+ "shader outputs", i);
+ }
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+
+ /* From section 4.3.4 of the GLSL 1.30 spec:
+ * "It is an error to use centroid in in a vertex shader."
+ */
+ if (state->language_version >= 130
+ && this->type->qualifier.flags.q.centroid
+ && this->type->qualifier.flags.q.in
+ && state->target == vertex_shader) {
+
+ _mesa_glsl_error(&loc, state,
+ "'centroid in' cannot be used in a vertex shader");
+ }
+
+
+ /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
+ */
+ if (this->type->specifier->precision != ast_precision_none
+ && state->language_version != 100
+ && state->language_version < 130) {
+
+ _mesa_glsl_error(&loc, state,
+ "precision qualifiers are supported only in GLSL ES "
+ "1.00, and GLSL 1.30 and later");
+ }
+
+
+ /* Precision qualifiers only apply to floating point and integer types.
+ *
+ * From section 4.5.2 of the GLSL 1.30 spec:
+ * "Any floating point or any integer declaration can have the type
+ * preceded by one of these precision qualifiers [...] Literal
+ * constants do not have precision qualifiers. Neither do Boolean
+ * variables.
+ */
+ if (this->type->specifier->precision != ast_precision_none
+ && !var->type->is_float()
+ && !var->type->is_integer()
+ && !(var->type->is_array()
+ && (var->type->fields.array->is_float()
+ || var->type->fields.array->is_integer()))) {
+
+ _mesa_glsl_error(&loc, state,
+ "precision qualifiers apply only to floating point "
+ "and integer types");
+ }
+
+ /* Process the initializer and add its instructions to a temporary
+ * list. This list will be added to the instruction stream (below) after
+ * the declaration is added. This is done because in some cases (such as
+ * redeclarations) the declaration may not actually be added to the
+ * instruction stream.
+ */
+ exec_list initializer_instructions;
+ ir_variable *earlier = get_variable_being_redeclared(var, decl, state);
+
+ if (decl->initializer != NULL) {
+ result = process_initializer((earlier == NULL) ? var : earlier,
+ decl, this->type,
+ &initializer_instructions, state);
+ }
+
+ /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "It is an error to write to a const variable outside of
+ * its declaration, so they must be initialized when
+ * declared."
+ */
+ if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) {
+ _mesa_glsl_error(& loc, state,
+ "const declaration of `%s' must be initialized",
+ decl->identifier);
+ }
+
+ /* If the declaration is not a redeclaration, there are a few additional
+ * semantic checks that must be applied. In addition, variable that was
+ * created for the declaration should be added to the IR stream.
+ */
+ if (earlier == NULL) {
+ /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
+ *
+ * "Identifiers starting with "gl_" are reserved for use by
+ * OpenGL, and may not be declared in a shader as either a
+ * variable or a function."
+ */
+ if (strncmp(decl->identifier, "gl_", 3) == 0)
+ _mesa_glsl_error(& loc, state,
+ "identifier `%s' uses reserved `gl_' prefix",
+ decl->identifier);
+
+ /* Add the variable to the symbol table. Note that the initializer's
+ * IR was already processed earlier (though it hasn't been emitted
+ * yet), without the variable in scope.
+ *
+ * This differs from most C-like languages, but it follows the GLSL
+ * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50
+ * spec:
+ *
+ * "Within a declaration, the scope of a name starts immediately
+ * after the initializer if present or immediately after the name
+ * being declared if not."
+ */
+ if (!state->symbols->add_variable(var)) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
+ "current scope", decl->identifier);
+ continue;
+ }
+
+ /* Push the variable declaration to the top. It means that all the
+ * variable declarations will appear in a funny last-to-first order,
+ * but otherwise we run into trouble if a function is prototyped, a
+ * global var is decled, then the function is defined with usage of
+ * the global var. See glslparsertest's CorrectModule.frag.
+ */
+ instructions->push_head(var);
+ }
+
+ instructions->append_list(&initializer_instructions);
+ }
+
+
+ /* Generally, variable declarations do not have r-values. However,
+ * one is used for the declaration in
+ *
+ * while (bool b = some_condition()) {
+ * ...
+ * }
+ *
+ * so we return the rvalue from the last seen declaration here.
+ */
+ return result;
+}
+
+
+ir_rvalue *
+ast_parameter_declarator::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ const struct glsl_type *type;
+ const char *name = NULL;
+ YYLTYPE loc = this->get_location();
+
+ type = this->type->specifier->glsl_type(& name, state);
+
+ if (type == NULL) {
+ if (name != NULL) {
+ _mesa_glsl_error(& loc, state,
+ "invalid type `%s' in declaration of `%s'",
+ name, this->identifier);
+ } else {
+ _mesa_glsl_error(& loc, state,
+ "invalid type in declaration of `%s'",
+ this->identifier);
+ }
+
+ type = glsl_type::error_type;
+ }
+
+ /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "Functions that accept no input arguments need not use void in the
+ * argument list because prototypes (or definitions) are required and
+ * therefore there is no ambiguity when an empty argument list "( )" is
+ * declared. The idiom "(void)" as a parameter list is provided for
+ * convenience."
+ *
+ * Placing this check here prevents a void parameter being set up
+ * for a function, which avoids tripping up checks for main taking
+ * parameters and lookups of an unnamed symbol.
+ */
+ if (type->is_void()) {
+ if (this->identifier != NULL)
+ _mesa_glsl_error(& loc, state,
+ "named parameter cannot have type `void'");
+
+ is_void = true;
+ return NULL;
+ }
+
+ if (formal_parameter && (this->identifier == NULL)) {
+ _mesa_glsl_error(& loc, state, "formal parameter lacks a name");
+ return NULL;
+ }
+
+ /* This only handles "vec4 foo[..]". The earlier specifier->glsl_type(...)
+ * call already handled the "vec4[..] foo" case.
+ */
+ if (this->is_array) {
+ type = process_array_type(&loc, type, this->array_size, state);
+ }
+
+ if (type->array_size() == 0) {
+ _mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
+ "a declared size.");
+ type = glsl_type::error_type;
+ }
+
+ is_void = false;
+ ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in);
+
+ /* Apply any specified qualifiers to the parameter declaration. Note that
+ * for function parameters the default mode is 'in'.
+ */
+ apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc);
+
+ instructions->push_tail(var);
+
+ /* Parameter declarations do not have r-values.
+ */
+ return NULL;
+}
+
+
+void
+ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
+ bool formal,
+ exec_list *ir_parameters,
+ _mesa_glsl_parse_state *state)
+{
+ ast_parameter_declarator *void_param = NULL;
+ unsigned count = 0;
+
+ foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) {
+ param->formal_parameter = formal;
+ param->hir(ir_parameters, state);
+
+ if (param->is_void)
+ void_param = param;
+
+ count++;
+ }
+
+ if ((void_param != NULL) && (count > 1)) {
+ YYLTYPE loc = void_param->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`void' parameter must be only parameter");
+ }
+}
+
+
+void
+emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
+ ir_function *f)
+{
+ /* Emit the new function header */
+ if (state->current_function == NULL) {
+ instructions->push_tail(f);
+ } else {
+ /* IR invariants disallow function declarations or definitions nested
+ * within other function definitions. Insert the new ir_function
+ * block in the instruction sequence before the ir_function block
+ * containing the current ir_function_signature.
+ */
+ ir_function *const curr =
+ const_cast<ir_function *>(state->current_function->function());
+
+ curr->insert_before(f);
+ }
+}
+
+
+ir_rvalue *
+ast_function::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+ ir_function *f = NULL;
+ ir_function_signature *sig = NULL;
+ exec_list hir_parameters;
+
+ const char *const name = identifier;
+
+ /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
+ *
+ * "Function declarations (prototypes) cannot occur inside of functions;
+ * they must be at global scope, or for the built-in functions, outside
+ * the global scope."
+ *
+ * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec,
+ *
+ * "User defined functions may only be defined within the global scope."
+ *
+ * Note that this language does not appear in GLSL 1.10.
+ */
+ if ((state->current_function != NULL) && (state->language_version != 110)) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state,
+ "declaration of function `%s' not allowed within "
+ "function body", name);
+ }
+
+ /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
+ *
+ * "Identifiers starting with "gl_" are reserved for use by
+ * OpenGL, and may not be declared in a shader as either a
+ * variable or a function."
+ */
+ if (strncmp(name, "gl_", 3) == 0) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state,
+ "identifier `%s' uses reserved `gl_' prefix", name);
+ }
+
+ /* Convert the list of function parameters to HIR now so that they can be
+ * used below to compare this function's signature with previously seen
+ * signatures for functions with the same name.
+ */
+ ast_parameter_declarator::parameters_to_hir(& this->parameters,
+ is_definition,
+ & hir_parameters, state);
+
+ const char *return_type_name;
+ const glsl_type *return_type =
+ this->return_type->specifier->glsl_type(& return_type_name, state);
+
+ if (!return_type) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state,
+ "function `%s' has undeclared return type `%s'",
+ name, return_type_name);
+ return_type = glsl_type::error_type;
+ }
+
+ /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec:
+ * "No qualifier is allowed on the return type of a function."
+ */
+ if (this->return_type->has_qualifiers()) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(& loc, state,
+ "function `%s' return type has qualifiers", name);
+ }
+
+ /* Verify that this function's signature either doesn't match a previously
+ * seen signature for a function with the same name, or, if a match is found,
+ * that the previously seen signature does not have an associated definition.
+ */
+ f = state->symbols->get_function(name);
+ if (f != NULL && (state->es_shader || f->has_user_signature())) {
+ sig = f->exact_matching_signature(&hir_parameters);
+ if (sig != NULL) {
+ const char *badvar = sig->qualifiers_match(&hir_parameters);
+ if (badvar != NULL) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' "
+ "qualifiers don't match prototype", name, badvar);
+ }
+
+ if (sig->return_type != return_type) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(&loc, state, "function `%s' return type doesn't "
+ "match prototype", name);
+ }
+
+ if (is_definition && sig->is_defined) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "function `%s' redefined", name);
+ }
+ }
+ } else {
+ f = new(ctx) ir_function(name);
+ if (!state->symbols->add_function(f)) {
+ /* This function name shadows a non-function use of the same name. */
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
+ "non-function", name);
+ return NULL;
+ }
+
+ emit_function(state, instructions, f);
+ }
+
+ /* Verify the return type of main() */
+ if (strcmp(name, "main") == 0) {
+ if (! return_type->is_void()) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "main() must return void");
+ }
+
+ if (!hir_parameters.is_empty()) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "main() must not take any parameters");
+ }
+ }
+
+ /* Finish storing the information about this new function in its signature.
+ */
+ if (sig == NULL) {
+ sig = new(ctx) ir_function_signature(return_type);
+ f->add_signature(sig);
+ }
+
+ sig->replace_parameters(&hir_parameters);
+ signature = sig;
+
+ /* Function declarations (prototypes) do not have r-values.
+ */
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_function_definition::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ prototype->is_definition = true;
+ prototype->hir(instructions, state);
+
+ ir_function_signature *signature = prototype->signature;
+ if (signature == NULL)
+ return NULL;
+
+ assert(state->current_function == NULL);
+ state->current_function = signature;
+ state->found_return = false;
+
+ /* Duplicate parameters declared in the prototype as concrete variables.
+ * Add these to the symbol table.
+ */
+ state->symbols->push_scope();
+ foreach_iter(exec_list_iterator, iter, signature->parameters) {
+ ir_variable *const var = ((ir_instruction *) iter.get())->as_variable();
+
+ assert(var != NULL);
+
+ /* The only way a parameter would "exist" is if two parameters have
+ * the same name.
+ */
+ if (state->symbols->name_declared_this_scope(var->name)) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name);
+ } else {
+ state->symbols->add_variable(var);
+ }
+ }
+
+ /* Convert the body of the function to HIR. */
+ this->body->hir(&signature->body, state);
+ signature->is_defined = true;
+
+ state->symbols->pop_scope();
+
+ assert(state->current_function == signature);
+ state->current_function = NULL;
+
+ if (!signature->return_type->is_void() && !state->found_return) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(& loc, state, "function `%s' has non-void return type "
+ "%s, but no return statement",
+ signature->function_name(),
+ signature->return_type->name);
+ }
+
+ /* Function definitions do not have r-values.
+ */
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_jump_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+
+ switch (mode) {
+ case ast_return: {
+ ir_return *inst;
+ assert(state->current_function);
+
+ if (opt_return_value) {
+ ir_rvalue *const ret = opt_return_value->hir(instructions, state);
+
+ /* The value of the return type can be NULL if the shader says
+ * 'return foo();' and foo() is a function that returns void.
+ *
+ * NOTE: The GLSL spec doesn't say that this is an error. The type
+ * of the return value is void. If the return type of the function is
+ * also void, then this should compile without error. Seriously.
+ */
+ const glsl_type *const ret_type =
+ (ret == NULL) ? glsl_type::void_type : ret->type;
+
+ /* Implicit conversions are not allowed for return values. */
+ if (state->current_function->return_type != ret_type) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`return' with wrong type %s, in function `%s' "
+ "returning %s",
+ ret_type->name,
+ state->current_function->function_name(),
+ state->current_function->return_type->name);
+ }
+
+ inst = new(ctx) ir_return(ret);
+ } else {
+ if (state->current_function->return_type->base_type !=
+ GLSL_TYPE_VOID) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`return' with no value, in function %s returning "
+ "non-void",
+ state->current_function->function_name());
+ }
+ inst = new(ctx) ir_return;
+ }
+
+ state->found_return = true;
+ instructions->push_tail(inst);
+ break;
+ }
+
+ case ast_discard:
+ if (state->target != fragment_shader) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`discard' may only appear in a fragment shader");
+ }
+ instructions->push_tail(new(ctx) ir_discard);
+ break;
+
+ case ast_break:
+ case ast_continue:
+ /* FINISHME: Handle switch-statements. They cannot contain 'continue',
+ * FINISHME: and they use a different IR instruction for 'break'.
+ */
+ /* FINISHME: Correctly handle the nesting. If a switch-statement is
+ * FINISHME: inside a loop, a 'continue' is valid and will bind to the
+ * FINISHME: loop.
+ */
+ if (state->loop_or_switch_nesting == NULL) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`%s' may only appear in a loop",
+ (mode == ast_break) ? "break" : "continue");
+ } else {
+ ir_loop *const loop = state->loop_or_switch_nesting->as_loop();
+
+ /* Inline the for loop expression again, since we don't know
+ * where near the end of the loop body the normal copy of it
+ * is going to be placed.
+ */
+ if (mode == ast_continue &&
+ state->loop_or_switch_nesting_ast->rest_expression) {
+ state->loop_or_switch_nesting_ast->rest_expression->hir(instructions,
+ state);
+ }
+
+ if (loop != NULL) {
+ ir_loop_jump *const jump =
+ new(ctx) ir_loop_jump((mode == ast_break)
+ ? ir_loop_jump::jump_break
+ : ir_loop_jump::jump_continue);
+ instructions->push_tail(jump);
+ }
+ }
+
+ break;
+ }
+
+ /* Jump instructions do not have r-values.
+ */
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_selection_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+
+ ir_rvalue *const condition = this->condition->hir(instructions, state);
+
+ /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "Any expression whose type evaluates to a Boolean can be used as the
+ * conditional expression bool-expression. Vector types are not accepted
+ * as the expression to if."
+ *
+ * The checks are separated so that higher quality diagnostics can be
+ * generated for cases where both rules are violated.
+ */
+ if (!condition->type->is_boolean() || !condition->type->is_scalar()) {
+ YYLTYPE loc = this->condition->get_location();
+
+ _mesa_glsl_error(& loc, state, "if-statement condition must be scalar "
+ "boolean");
+ }
+
+ ir_if *const stmt = new(ctx) ir_if(condition);
+
+ if (then_statement != NULL) {
+ state->symbols->push_scope();
+ then_statement->hir(& stmt->then_instructions, state);
+ state->symbols->pop_scope();
+ }
+
+ if (else_statement != NULL) {
+ state->symbols->push_scope();
+ else_statement->hir(& stmt->else_instructions, state);
+ state->symbols->pop_scope();
+ }
+
+ instructions->push_tail(stmt);
+
+ /* if-statements do not have r-values.
+ */
+ return NULL;
+}
+
+
+void
+ast_iteration_statement::condition_to_hir(ir_loop *stmt,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+
+ if (condition != NULL) {
+ ir_rvalue *const cond =
+ condition->hir(& stmt->body_instructions, state);
+
+ if ((cond == NULL)
+ || !cond->type->is_boolean() || !cond->type->is_scalar()) {
+ YYLTYPE loc = condition->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "loop condition must be scalar boolean");
+ } else {
+ /* As the first code in the loop body, generate a block that looks
+ * like 'if (!condition) break;' as the loop termination condition.
+ */
+ ir_rvalue *const not_cond =
+ new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond,
+ NULL);
+
+ ir_if *const if_stmt = new(ctx) ir_if(not_cond);
+
+ ir_jump *const break_stmt =
+ new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+
+ if_stmt->then_instructions.push_tail(break_stmt);
+ stmt->body_instructions.push_tail(if_stmt);
+ }
+ }
+}
+
+
+ir_rvalue *
+ast_iteration_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+
+ /* For-loops and while-loops start a new scope, but do-while loops do not.
+ */
+ if (mode != ast_do_while)
+ state->symbols->push_scope();
+
+ if (init_statement != NULL)
+ init_statement->hir(instructions, state);
+
+ ir_loop *const stmt = new(ctx) ir_loop();
+ instructions->push_tail(stmt);
+
+ /* Track the current loop and / or switch-statement nesting.
+ */
+ ir_instruction *const nesting = state->loop_or_switch_nesting;
+ ast_iteration_statement *nesting_ast = state->loop_or_switch_nesting_ast;
+
+ state->loop_or_switch_nesting = stmt;
+ state->loop_or_switch_nesting_ast = this;
+
+ if (mode != ast_do_while)
+ condition_to_hir(stmt, state);
+
+ if (body != NULL)
+ body->hir(& stmt->body_instructions, state);
+
+ if (rest_expression != NULL)
+ rest_expression->hir(& stmt->body_instructions, state);
+
+ if (mode == ast_do_while)
+ condition_to_hir(stmt, state);
+
+ if (mode != ast_do_while)
+ state->symbols->pop_scope();
+
+ /* Restore previous nesting before returning.
+ */
+ state->loop_or_switch_nesting = nesting;
+ state->loop_or_switch_nesting_ast = nesting_ast;
+
+ /* Loops do not have r-values.
+ */
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_type_specifier::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ if (!this->is_precision_statement && this->structure == NULL)
+ return NULL;
+
+ YYLTYPE loc = this->get_location();
+
+ if (this->precision != ast_precision_none
+ && state->language_version != 100
+ && state->language_version < 130) {
+ _mesa_glsl_error(&loc, state,
+ "precision qualifiers exist only in "
+ "GLSL ES 1.00, and GLSL 1.30 and later");
+ return NULL;
+ }
+ if (this->precision != ast_precision_none
+ && this->structure != NULL) {
+ _mesa_glsl_error(&loc, state,
+ "precision qualifiers do not apply to structures");
+ return NULL;
+ }
+
+ /* If this is a precision statement, check that the type to which it is
+ * applied is either float or int.
+ *
+ * From section 4.5.3 of the GLSL 1.30 spec:
+ * "The precision statement
+ * precision precision-qualifier type;
+ * can be used to establish a default precision qualifier. The type
+ * field can be either int or float [...]. Any other types or
+ * qualifiers will result in an error.
+ */
+ if (this->is_precision_statement) {
+ assert(this->precision != ast_precision_none);
+ assert(this->structure == NULL); /* The check for structures was
+ * performed above. */
+ if (this->is_array) {
+ _mesa_glsl_error(&loc, state,
+ "default precision statements do not apply to "
+ "arrays");
+ return NULL;
+ }
+ if (this->type_specifier != ast_float
+ && this->type_specifier != ast_int) {
+ _mesa_glsl_error(&loc, state,
+ "default precision statements apply only to types "
+ "float and int");
+ return NULL;
+ }
+
+ /* FINISHME: Translate precision statements into IR. */
+ return NULL;
+ }
+
+ if (this->structure != NULL)
+ return this->structure->hir(instructions, state);
+
+ return NULL;
+}
+
+
+ir_rvalue *
+ast_struct_specifier::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ unsigned decl_count = 0;
+
+ /* Make an initial pass over the list of structure fields to determine how
+ * many there are. Each element in this list is an ast_declarator_list.
+ * This means that we actually need to count the number of elements in the
+ * 'declarations' list in each of the elements.
+ */
+ foreach_list_typed (ast_declarator_list, decl_list, link,
+ &this->declarations) {
+ foreach_list_const (decl_ptr, & decl_list->declarations) {
+ decl_count++;
+ }
+ }
+
+ /* Allocate storage for the structure fields and process the field
+ * declarations. As the declarations are processed, try to also convert
+ * the types to HIR. This ensures that structure definitions embedded in
+ * other structure definitions are processed.
+ */
+ glsl_struct_field *const fields = ralloc_array(state, glsl_struct_field,
+ decl_count);
+
+ unsigned i = 0;
+ foreach_list_typed (ast_declarator_list, decl_list, link,
+ &this->declarations) {
+ const char *type_name;
+
+ decl_list->type->specifier->hir(instructions, state);
+
+ /* Section 10.9 of the GLSL ES 1.00 specification states that
+ * embedded structure definitions have been removed from the language.
+ */
+ if (state->es_shader && decl_list->type->specifier->structure != NULL) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(&loc, state, "Embedded structure definitions are "
+ "not allowed in GLSL ES 1.00.");
+ }
+
+ const glsl_type *decl_type =
+ decl_list->type->specifier->glsl_type(& type_name, state);
+
+ foreach_list_typed (ast_declaration, decl, link,
+ &decl_list->declarations) {
+ const struct glsl_type *field_type = decl_type;
+ if (decl->is_array) {
+ YYLTYPE loc = decl->get_location();
+ field_type = process_array_type(&loc, decl_type, decl->array_size,
+ state);
+ }
+ fields[i].type = (field_type != NULL)
+ ? field_type : glsl_type::error_type;
+ fields[i].name = decl->identifier;
+ i++;
+ }
+ }
+
+ assert(i == decl_count);
+
+ const glsl_type *t =
+ glsl_type::get_record_instance(fields, decl_count, this->name);
+
+ YYLTYPE loc = this->get_location();
+ if (!state->symbols->add_type(name, t)) {
+ _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name);
+ } else {
+ const glsl_type **s = reralloc(state, state->user_structures,
+ const glsl_type *,
+ state->num_user_structures + 1);
+ if (s != NULL) {
+ s[state->num_user_structures] = t;
+ state->user_structures = s;
+ state->num_user_structures++;
+ }
+ }
+
+ /* Structure type definitions do not have r-values.
+ */
+ return NULL;
+}
diff --git a/mesalib/src/glsl/glcpp/glcpp-lex.l b/mesalib/src/glsl/glcpp/glcpp-lex.l
index 68e44eb79..596c6db70 100644
--- a/mesalib/src/glsl/glcpp/glcpp-lex.l
+++ b/mesalib/src/glsl/glcpp/glcpp-lex.l
@@ -1,320 +1,324 @@
-%{
-/*
- * 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 <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "glcpp.h"
-#include "glcpp-parse.h"
-
-/* Flex annoyingly generates some functions without making them
- * static. Let's declare them here. */
-int glcpp_get_column (yyscan_t yyscanner);
-void glcpp_set_column (int column_no , yyscan_t yyscanner);
-
-#define YY_NO_INPUT
-
-#define YY_USER_ACTION \
- do { \
- yylloc->first_column = yycolumn + 1; \
- yylloc->first_line = yylineno; \
- yycolumn += yyleng; \
- } while(0);
-
-#define YY_USER_INIT \
- do { \
- yylineno = 1; \
- yycolumn = 1; \
- yylloc->source = 0; \
- } while(0)
-%}
-
-%option bison-bridge bison-locations reentrant noyywrap
-%option extra-type="glcpp_parser_t *"
-%option prefix="glcpp_"
-%option stack
-%option never-interactive
-
-%x DONE COMMENT UNREACHABLE SKIP
-
-SPACE [[:space:]]
-NONSPACE [^[:space:]]
-NEWLINE [\n]
-HSPACE [ \t]
-HASH ^{HSPACE}*#{HSPACE}*
-IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
-PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
-OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
-
-DIGITS [0-9][0-9]*
-DECIMAL_INTEGER [1-9][0-9]*[uU]?
-OCTAL_INTEGER 0[0-7]*[uU]?
-HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
-
-%%
- /* Implicitly switch between SKIP and INITIAL (non-skipping);
- * don't switch if some other state was explicitly set.
- */
- glcpp_parser_t *parser = yyextra;
- if (YY_START == 0 || YY_START == SKIP) {
- if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) {
- BEGIN 0;
- } else {
- BEGIN SKIP;
- }
- }
-
- /* Single-line comments */
-"//"[^\n]* {
-}
-
- /* Multi-line comments */
-"/*" { yy_push_state(COMMENT, yyscanner); }
-<COMMENT>[^*\n]*
-<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
-<COMMENT>"*"+[^*/\n]*
-<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
-<COMMENT>"*"+"/" {
- yy_pop_state(yyscanner);
- if (yyextra->space_tokens)
- return SPACE;
-}
-
-{HASH}version {
- yylval->str = ralloc_strdup (yyextra, yytext);
- yyextra->space_tokens = 0;
- return HASH_VERSION;
-}
-
- /* glcpp doesn't handle #extension, #version, or #pragma directives.
- * Simply pass them through to the main compiler's lexer/parser. */
-{HASH}(extension|pragma)[^\n]+ {
- yylval->str = ralloc_strdup (yyextra, yytext);
- yylineno++;
- yycolumn = 0;
- return OTHER;
-}
-
-{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ {
- /* Eat characters until the first digit is
- * encountered
- */
- char *ptr = yytext;
- while (!isdigit(*ptr))
- ptr++;
-
- /* Subtract one from the line number because
- * yylineno is zero-based instead of
- * one-based.
- */
- yylineno = strtol(ptr, &ptr, 0) - 1;
- yylloc->source = strtol(ptr, NULL, 0);
-}
-
-{HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ {
- /* Eat characters until the first digit is
- * encountered
- */
- char *ptr = yytext;
- while (!isdigit(*ptr))
- ptr++;
-
- /* Subtract one from the line number because
- * yylineno is zero-based instead of
- * one-based.
- */
- yylineno = strtol(ptr, &ptr, 0) - 1;
-}
-
-<SKIP,INITIAL>{
-{HASH}ifdef {
- yyextra->lexing_if = 1;
- yyextra->space_tokens = 0;
- return HASH_IFDEF;
-}
-
-{HASH}ifndef {
- yyextra->lexing_if = 1;
- yyextra->space_tokens = 0;
- return HASH_IFNDEF;
-}
-
-{HASH}if/[^_a-zA-Z0-9] {
- yyextra->lexing_if = 1;
- yyextra->space_tokens = 0;
- return HASH_IF;
-}
-
-{HASH}elif {
- yyextra->lexing_if = 1;
- yyextra->space_tokens = 0;
- return HASH_ELIF;
-}
-
-{HASH}else {
- yyextra->space_tokens = 0;
- return HASH_ELSE;
-}
-
-{HASH}endif {
- yyextra->space_tokens = 0;
- return HASH_ENDIF;
-}
-}
-
-<SKIP>[^\n] ;
-
-{HASH}error.* {
- char *p;
- for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */
- p += 5; /* skip "error" */
- glcpp_error(yylloc, yyextra, "#error%s", p);
-}
-
-{HASH}define{HSPACE}+/{IDENTIFIER}"(" {
- yyextra->space_tokens = 0;
- return HASH_DEFINE_FUNC;
-}
-
-{HASH}define {
- yyextra->space_tokens = 0;
- return HASH_DEFINE_OBJ;
-}
-
-{HASH}undef {
- yyextra->space_tokens = 0;
- return HASH_UNDEF;
-}
-
-{HASH} {
- yyextra->space_tokens = 0;
- return HASH;
-}
-
-{DECIMAL_INTEGER} {
- yylval->str = ralloc_strdup (yyextra, yytext);
- return INTEGER_STRING;
-}
-
-{OCTAL_INTEGER} {
- yylval->str = ralloc_strdup (yyextra, yytext);
- return INTEGER_STRING;
-}
-
-{HEXADECIMAL_INTEGER} {
- yylval->str = ralloc_strdup (yyextra, yytext);
- return INTEGER_STRING;
-}
-
-"<<" {
- return LEFT_SHIFT;
-}
-
-">>" {
- return RIGHT_SHIFT;
-}
-
-"<=" {
- return LESS_OR_EQUAL;
-}
-
-">=" {
- return GREATER_OR_EQUAL;
-}
-
-"==" {
- return EQUAL;
-}
-
-"!=" {
- return NOT_EQUAL;
-}
-
-"&&" {
- return AND;
-}
-
-"||" {
- return OR;
-}
-
-"##" {
- return PASTE;
-}
-
-"defined" {
- return DEFINED;
-}
-
-{IDENTIFIER} {
- yylval->str = ralloc_strdup (yyextra, yytext);
- return IDENTIFIER;
-}
-
-{PUNCTUATION} {
- return yytext[0];
-}
-
-{OTHER}+ {
- yylval->str = ralloc_strdup (yyextra, yytext);
- return OTHER;
-}
-
-{HSPACE}+ {
- if (yyextra->space_tokens) {
- return SPACE;
- }
-}
-
-<SKIP,INITIAL>\n {
- yyextra->lexing_if = 0;
- yylineno++;
- yycolumn = 0;
- return NEWLINE;
-}
-
- /* Handle missing newline at EOF. */
-<INITIAL><<EOF>> {
- BEGIN DONE; /* Don't keep matching this rule forever. */
- yyextra->lexing_if = 0;
- return NEWLINE;
-}
-
- /* We don't actually use the UNREACHABLE start condition. We
- only have this action here so that we can pretend to call some
- generated functions, (to avoid "defined but not used"
- warnings. */
-<UNREACHABLE>. {
- unput('.');
- yy_top_state(yyextra);
-}
-
-%%
-
-void
-glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
-{
- yy_scan_string(shader, parser->scanner);
-}
+%{
+/*
+ * 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 <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "glcpp.h"
+#include "glcpp-parse.h"
+
+/* Flex annoyingly generates some functions without making them
+ * static. Let's declare them here. */
+int glcpp_get_column (yyscan_t yyscanner);
+void glcpp_set_column (int column_no , yyscan_t yyscanner);
+
+#ifdef _MSC_VER
+#define YY_NO_UNISTD_H
+#endif
+
+#define YY_NO_INPUT
+
+#define YY_USER_ACTION \
+ do { \
+ yylloc->first_column = yycolumn + 1; \
+ yylloc->first_line = yylineno; \
+ yycolumn += yyleng; \
+ } while(0);
+
+#define YY_USER_INIT \
+ do { \
+ yylineno = 1; \
+ yycolumn = 1; \
+ yylloc->source = 0; \
+ } while(0)
+%}
+
+%option bison-bridge bison-locations reentrant noyywrap
+%option extra-type="glcpp_parser_t *"
+%option prefix="glcpp_"
+%option stack
+%option never-interactive
+
+%x DONE COMMENT UNREACHABLE SKIP
+
+SPACE [[:space:]]
+NONSPACE [^[:space:]]
+NEWLINE [\n]
+HSPACE [ \t]
+HASH ^{HSPACE}*#{HSPACE}*
+IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
+PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
+OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
+
+DIGITS [0-9][0-9]*
+DECIMAL_INTEGER [1-9][0-9]*[uU]?
+OCTAL_INTEGER 0[0-7]*[uU]?
+HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
+
+%%
+ /* Implicitly switch between SKIP and INITIAL (non-skipping);
+ * don't switch if some other state was explicitly set.
+ */
+ glcpp_parser_t *parser = yyextra;
+ if (YY_START == 0 || YY_START == SKIP) {
+ if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) {
+ BEGIN 0;
+ } else {
+ BEGIN SKIP;
+ }
+ }
+
+ /* Single-line comments */
+"//"[^\n]* {
+}
+
+ /* Multi-line comments */
+"/*" { yy_push_state(COMMENT, yyscanner); }
+<COMMENT>[^*\n]*
+<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
+<COMMENT>"*"+[^*/\n]*
+<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
+<COMMENT>"*"+"/" {
+ yy_pop_state(yyscanner);
+ if (yyextra->space_tokens)
+ return SPACE;
+}
+
+{HASH}version {
+ yylval->str = ralloc_strdup (yyextra, yytext);
+ yyextra->space_tokens = 0;
+ return HASH_VERSION;
+}
+
+ /* glcpp doesn't handle #extension, #version, or #pragma directives.
+ * Simply pass them through to the main compiler's lexer/parser. */
+{HASH}(extension|pragma)[^\n]+ {
+ yylval->str = ralloc_strdup (yyextra, yytext);
+ yylineno++;
+ yycolumn = 0;
+ return OTHER;
+}
+
+{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ {
+ /* Eat characters until the first digit is
+ * encountered
+ */
+ char *ptr = yytext;
+ while (!isdigit(*ptr))
+ ptr++;
+
+ /* Subtract one from the line number because
+ * yylineno is zero-based instead of
+ * one-based.
+ */
+ yylineno = strtol(ptr, &ptr, 0) - 1;
+ yylloc->source = strtol(ptr, NULL, 0);
+}
+
+{HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ {
+ /* Eat characters until the first digit is
+ * encountered
+ */
+ char *ptr = yytext;
+ while (!isdigit(*ptr))
+ ptr++;
+
+ /* Subtract one from the line number because
+ * yylineno is zero-based instead of
+ * one-based.
+ */
+ yylineno = strtol(ptr, &ptr, 0) - 1;
+}
+
+<SKIP,INITIAL>{
+{HASH}ifdef {
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_IFDEF;
+}
+
+{HASH}ifndef {
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_IFNDEF;
+}
+
+{HASH}if/[^_a-zA-Z0-9] {
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_IF;
+}
+
+{HASH}elif {
+ yyextra->lexing_if = 1;
+ yyextra->space_tokens = 0;
+ return HASH_ELIF;
+}
+
+{HASH}else {
+ yyextra->space_tokens = 0;
+ return HASH_ELSE;
+}
+
+{HASH}endif {
+ yyextra->space_tokens = 0;
+ return HASH_ENDIF;
+}
+}
+
+<SKIP>[^\n] ;
+
+{HASH}error.* {
+ char *p;
+ for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */
+ p += 5; /* skip "error" */
+ glcpp_error(yylloc, yyextra, "#error%s", p);
+}
+
+{HASH}define{HSPACE}+/{IDENTIFIER}"(" {
+ yyextra->space_tokens = 0;
+ return HASH_DEFINE_FUNC;
+}
+
+{HASH}define {
+ yyextra->space_tokens = 0;
+ return HASH_DEFINE_OBJ;
+}
+
+{HASH}undef {
+ yyextra->space_tokens = 0;
+ return HASH_UNDEF;
+}
+
+{HASH} {
+ yyextra->space_tokens = 0;
+ return HASH;
+}
+
+{DECIMAL_INTEGER} {
+ yylval->str = ralloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+
+{OCTAL_INTEGER} {
+ yylval->str = ralloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+
+{HEXADECIMAL_INTEGER} {
+ yylval->str = ralloc_strdup (yyextra, yytext);
+ return INTEGER_STRING;
+}
+
+"<<" {
+ return LEFT_SHIFT;
+}
+
+">>" {
+ return RIGHT_SHIFT;
+}
+
+"<=" {
+ return LESS_OR_EQUAL;
+}
+
+">=" {
+ return GREATER_OR_EQUAL;
+}
+
+"==" {
+ return EQUAL;
+}
+
+"!=" {
+ return NOT_EQUAL;
+}
+
+"&&" {
+ return AND;
+}
+
+"||" {
+ return OR;
+}
+
+"##" {
+ return PASTE;
+}
+
+"defined" {
+ return DEFINED;
+}
+
+{IDENTIFIER} {
+ yylval->str = ralloc_strdup (yyextra, yytext);
+ return IDENTIFIER;
+}
+
+{PUNCTUATION} {
+ return yytext[0];
+}
+
+{OTHER}+ {
+ yylval->str = ralloc_strdup (yyextra, yytext);
+ return OTHER;
+}
+
+{HSPACE}+ {
+ if (yyextra->space_tokens) {
+ return SPACE;
+ }
+}
+
+<SKIP,INITIAL>\n {
+ yyextra->lexing_if = 0;
+ yylineno++;
+ yycolumn = 0;
+ return NEWLINE;
+}
+
+ /* Handle missing newline at EOF. */
+<INITIAL><<EOF>> {
+ BEGIN DONE; /* Don't keep matching this rule forever. */
+ yyextra->lexing_if = 0;
+ return NEWLINE;
+}
+
+ /* We don't actually use the UNREACHABLE start condition. We
+ only have this action here so that we can pretend to call some
+ generated functions, (to avoid "defined but not used"
+ warnings. */
+<UNREACHABLE>. {
+ unput('.');
+ yy_top_state(yyextra);
+}
+
+%%
+
+void
+glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
+{
+ yy_scan_string(shader, parser->scanner);
+}
diff --git a/mesalib/src/glsl/glcpp/glcpp.c b/mesalib/src/glsl/glcpp/glcpp.c
index 564194caa..63eb061c2 100644
--- a/mesalib/src/glsl/glcpp/glcpp.c
+++ b/mesalib/src/glsl/glcpp/glcpp.c
@@ -1,131 +1,121 @@
-/*
- * 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 <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include "glcpp.h"
-#include "main/mtypes.h"
-#include "main/shaderobj.h"
-
-extern int yydebug;
-
-void
-_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
- struct gl_shader *sh)
-{
- *ptr = sh;
-}
-
-/* Read from fd until EOF and return a string of everything read.
- */
-static char *
-load_text_fd (void *ctx, int fd)
-{
-#define CHUNK 4096
- char *text = NULL;
- ssize_t text_size = 0;
- ssize_t total_read = 0;
- ssize_t bytes;
-
- while (1) {
- if (total_read + CHUNK + 1 > text_size) {
- text_size = text_size ? text_size * 2 : CHUNK + 1;
- text = reralloc_size (ctx, text, text_size);
- if (text == NULL) {
- fprintf (stderr, "Out of memory\n");
- return NULL;
- }
- }
- bytes = read (fd, text + total_read, CHUNK);
- if (bytes < 0) {
- fprintf (stderr, "Error while reading: %s\n",
- strerror (errno));
- ralloc_free (text);
- return NULL;
- }
-
- if (bytes == 0) {
- break;
- }
-
- total_read += bytes;
- }
-
- text[total_read] = '\0';
-
- return text;
-}
-
-static char *
-load_text_file(void *ctx, const char *filename)
-{
- char *text;
- int fd;
-
- if (filename == NULL || strcmp (filename, "-") == 0)
- return load_text_fd (ctx, STDIN_FILENO);
-
- fd = open (filename, O_RDONLY);
- if (fd < 0) {
- fprintf (stderr, "Failed to open file %s: %s\n",
- filename, strerror (errno));
- return NULL;
- }
-
- text = load_text_fd (ctx, fd);
-
- close(fd);
-
- return text;
-}
-
-int
-main (int argc, char *argv[])
-{
- char *filename = NULL;
- void *ctx = ralloc(NULL, void*);
- char *info_log = ralloc_strdup(ctx, "");
- const char *shader;
- int ret;
-
- if (argc) {
- filename = argv[1];
- }
-
- shader = load_text_file (ctx, filename);
- if (shader == NULL)
- return 1;
-
- ret = preprocess(ctx, &shader, &info_log, NULL, API_OPENGL);
-
- printf("%s", shader);
- fprintf(stderr, "%s", info_log);
-
- ralloc_free(ctx);
-
- return ret;
-}
+/*
+ * 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 <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "glcpp.h"
+#include "main/mtypes.h"
+#include "main/shaderobj.h"
+
+extern int yydebug;
+
+void
+_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
+ struct gl_shader *sh)
+{
+ *ptr = sh;
+}
+
+/* Read from fp until EOF and return a string of everything read.
+ */
+static char *
+load_text_fp (void *ctx, FILE *fp)
+{
+#define CHUNK 4096
+ char *text = NULL;
+ size_t text_size = 0;
+ size_t total_read = 0;
+ size_t bytes;
+
+ while (1) {
+ if (total_read + CHUNK + 1 > text_size) {
+ text_size = text_size ? text_size * 2 : CHUNK + 1;
+ text = reralloc_size (ctx, text, text_size);
+ if (text == NULL) {
+ fprintf (stderr, "Out of memory\n");
+ return NULL;
+ }
+ }
+ bytes = fread (text + total_read, 1, CHUNK, fp);
+ total_read += bytes;
+
+ if (bytes < CHUNK) {
+ break;
+ }
+ }
+
+ text[total_read] = '\0';
+
+ return text;
+}
+
+static char *
+load_text_file(void *ctx, const char *filename)
+{
+ char *text;
+ FILE *fp;
+
+ if (filename == NULL || strcmp (filename, "-") == 0)
+ return load_text_fp (ctx, stdin);
+
+ fp = fopen (filename, "r");
+ if (fp == NULL) {
+ fprintf (stderr, "Failed to open file %s: %s\n",
+ filename, strerror (errno));
+ return NULL;
+ }
+
+ text = load_text_fp (ctx, fp);
+
+ fclose(fp);
+
+ return text;
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *filename = NULL;
+ void *ctx = ralloc(NULL, void*);
+ char *info_log = ralloc_strdup(ctx, "");
+ const char *shader;
+ int ret;
+
+ if (argc) {
+ filename = argv[1];
+ }
+
+ shader = load_text_file (ctx, filename);
+ if (shader == NULL)
+ return 1;
+
+ ret = preprocess(ctx, &shader, &info_log, NULL, API_OPENGL);
+
+ printf("%s", shader);
+ fprintf(stderr, "%s", info_log);
+
+ ralloc_free(ctx);
+
+ return ret;
+}
diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll
index e6f45f413..267ca0f1c 100644
--- a/mesalib/src/glsl/glsl_lexer.ll
+++ b/mesalib/src/glsl/glsl_lexer.ll
@@ -29,6 +29,10 @@
static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
+#ifdef _MSC_VER
+#define YY_NO_UNISTD_H
+#endif
+
#define YY_USER_ACTION \
do { \
yylloc->source = 0; \
diff --git a/mesalib/src/mesa/sources.mak b/mesalib/src/mesa/sources.mak
index a8c0bbd2b..e1598869c 100644
--- a/mesalib/src/mesa/sources.mak
+++ b/mesalib/src/mesa/sources.mak
@@ -1,370 +1,371 @@
-### Lists of source files, included by Makefiles
-
-# this is part of MAIN_SOURCES
-MAIN_ES_SOURCES = \
- main/api_exec_es1.c \
- main/api_exec_es2.c
-
-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 \
- main/atifragshader.c \
- main/attrib.c \
- main/arrayobj.c \
- main/blend.c \
- main/bufferobj.c \
- main/buffers.c \
- main/clear.c \
- main/clip.c \
- main/colortab.c \
- main/condrender.c \
- main/context.c \
- main/convolve.c \
- main/cpuinfo.c \
- main/debug.c \
- main/depth.c \
- main/depthstencil.c \
- main/dlist.c \
- main/dlopen.c \
- main/drawpix.c \
- main/drawtex.c \
- main/enable.c \
- main/enums.c \
- main/eval.c \
- main/execmem.c \
- main/extensions.c \
- main/fbobject.c \
- main/feedback.c \
- main/ffvertex_prog.c \
- main/fog.c \
- main/formats.c \
- main/framebuffer.c \
- main/get.c \
- main/getstring.c \
- main/hash.c \
- main/hint.c \
- main/histogram.c \
- main/image.c \
- main/imports.c \
- main/light.c \
- main/lines.c \
- main/matrix.c \
- main/mipmap.c \
- main/mm.c \
- main/multisample.c \
- main/nvprogram.c \
- main/pack.c \
- main/pbo.c \
- main/pixel.c \
- main/pixelstore.c \
- main/pixeltransfer.c \
- main/points.c \
- main/polygon.c \
- main/queryobj.c \
- main/querymatrix.c \
- main/rastpos.c \
- main/readpix.c \
- main/remap.c \
- main/renderbuffer.c \
- main/scissor.c \
- main/shaderapi.c \
- main/shaderobj.c \
- main/shared.c \
- main/state.c \
- main/stencil.c \
- main/syncobj.c \
- main/texcompress.c \
- main/texcompress_rgtc.c \
- main/texcompress_s3tc.c \
- main/texcompress_fxt1.c \
- main/texenv.c \
- main/texenvprogram.c \
- main/texfetch.c \
- main/texformat.c \
- main/texgen.c \
- main/texgetimage.c \
- main/teximage.c \
- main/texobj.c \
- main/texpal.c \
- main/texparam.c \
- main/texrender.c \
- main/texstate.c \
- main/texstore.c \
- main/transformfeedback.c \
- main/uniforms.c \
- main/varray.c \
- main/version.c \
- main/viewport.c \
- main/vtxfmt.c \
- $(MAIN_ES_SOURCES)
-
-MATH_SOURCES = \
- math/m_debug_clip.c \
- math/m_debug_norm.c \
- math/m_debug_xform.c \
- math/m_eval.c \
- math/m_matrix.c \
- math/m_translate.c \
- math/m_vector.c
-
-MATH_XFORM_SOURCES = \
- math/m_xform.c
-
-SWRAST_SOURCES = \
- swrast/s_aaline.c \
- swrast/s_aatriangle.c \
- swrast/s_accum.c \
- swrast/s_alpha.c \
- swrast/s_atifragshader.c \
- swrast/s_bitmap.c \
- swrast/s_blend.c \
- swrast/s_blit.c \
- swrast/s_clear.c \
- swrast/s_copypix.c \
- swrast/s_context.c \
- swrast/s_depth.c \
- swrast/s_drawpix.c \
- swrast/s_feedback.c \
- swrast/s_fog.c \
- swrast/s_fragprog.c \
- swrast/s_lines.c \
- swrast/s_logic.c \
- swrast/s_masking.c \
- swrast/s_points.c \
- swrast/s_readpix.c \
- swrast/s_span.c \
- swrast/s_stencil.c \
- swrast/s_texcombine.c \
- swrast/s_texfilter.c \
- swrast/s_triangle.c \
- swrast/s_zoom.c
-
-SWRAST_SETUP_SOURCES = \
- swrast_setup/ss_context.c \
- swrast_setup/ss_triangle.c
-
-TNL_SOURCES = \
- tnl/t_context.c \
- tnl/t_pipeline.c \
- tnl/t_draw.c \
- tnl/t_rasterpos.c \
- tnl/t_vb_program.c \
- tnl/t_vb_render.c \
- tnl/t_vb_texgen.c \
- tnl/t_vb_texmat.c \
- tnl/t_vb_vertex.c \
- tnl/t_vb_fog.c \
- tnl/t_vb_light.c \
- tnl/t_vb_normals.c \
- tnl/t_vb_points.c \
- tnl/t_vp_build.c \
- tnl/t_vertex.c \
- tnl/t_vertex_sse.c \
- tnl/t_vertex_generic.c
-
-VBO_SOURCES = \
- vbo/vbo_context.c \
- vbo/vbo_exec.c \
- vbo/vbo_exec_api.c \
- vbo/vbo_exec_array.c \
- vbo/vbo_exec_draw.c \
- vbo/vbo_exec_eval.c \
- vbo/vbo_rebase.c \
- vbo/vbo_split.c \
- vbo/vbo_split_copy.c \
- vbo/vbo_split_inplace.c \
- vbo/vbo_save.c \
- vbo/vbo_save_api.c \
- vbo/vbo_save_draw.c \
- vbo/vbo_save_loopback.c
-
-STATETRACKER_SOURCES = \
- state_tracker/st_atom.c \
- state_tracker/st_atom_blend.c \
- state_tracker/st_atom_clip.c \
- state_tracker/st_atom_constbuf.c \
- state_tracker/st_atom_depth.c \
- state_tracker/st_atom_framebuffer.c \
- state_tracker/st_atom_msaa.c \
- state_tracker/st_atom_pixeltransfer.c \
- state_tracker/st_atom_sampler.c \
- state_tracker/st_atom_scissor.c \
- state_tracker/st_atom_shader.c \
- state_tracker/st_atom_rasterizer.c \
- state_tracker/st_atom_stipple.c \
- state_tracker/st_atom_texture.c \
- state_tracker/st_atom_viewport.c \
- state_tracker/st_cb_accum.c \
- state_tracker/st_cb_bitmap.c \
- state_tracker/st_cb_blit.c \
- state_tracker/st_cb_bufferobjects.c \
- state_tracker/st_cb_clear.c \
- state_tracker/st_cb_condrender.c \
- state_tracker/st_cb_flush.c \
- state_tracker/st_cb_drawpixels.c \
- state_tracker/st_cb_drawtex.c \
- state_tracker/st_cb_eglimage.c \
- state_tracker/st_cb_fbo.c \
- state_tracker/st_cb_feedback.c \
- state_tracker/st_cb_program.c \
- state_tracker/st_cb_queryobj.c \
- state_tracker/st_cb_rasterpos.c \
- state_tracker/st_cb_readpixels.c \
- state_tracker/st_cb_strings.c \
- state_tracker/st_cb_texture.c \
- state_tracker/st_cb_viewport.c \
- state_tracker/st_cb_xformfb.c \
- state_tracker/st_context.c \
- state_tracker/st_debug.c \
- state_tracker/st_draw.c \
- state_tracker/st_draw_feedback.c \
- state_tracker/st_extensions.c \
- state_tracker/st_format.c \
- state_tracker/st_gen_mipmap.c \
- state_tracker/st_manager.c \
- state_tracker/st_mesa_to_tgsi.c \
- state_tracker/st_program.c \
- state_tracker/st_texture.c
-
-PROGRAM_SOURCES = \
- program/arbprogparse.c \
- program/hash_table.c \
- program/lex.yy.c \
- program/nvfragparse.c \
- program/nvvertparse.c \
- program/program.c \
- program/program_parse.tab.c \
- program/program_parse_extra.c \
- program/prog_cache.c \
- program/prog_execute.c \
- program/prog_instruction.c \
- program/prog_noise.c \
- program/prog_optimize.c \
- program/prog_parameter.c \
- program/prog_parameter_layout.c \
- program/prog_print.c \
- program/prog_statevars.c \
- program/prog_uniform.c \
- program/programopt.c \
- program/register_allocate.c \
- program/symbol_table.c
-
-SHADER_CXX_SOURCES = \
- program/ir_to_mesa.cpp \
- program/sampler.cpp
-
-ASM_C_SOURCES = \
- x86/common_x86.c \
- x86/x86_xform.c \
- x86/3dnow.c \
- x86/sse.c \
- x86/rtasm/x86sse.c \
- sparc/sparc.c \
- ppc/common_ppc.c \
- x86-64/x86-64.c
-
-X86_SOURCES = \
- x86/common_x86_asm.S \
- x86/x86_xform2.S \
- x86/x86_xform3.S \
- x86/x86_xform4.S \
- x86/x86_cliptest.S \
- x86/mmx_blend.S \
- x86/3dnow_xform1.S \
- x86/3dnow_xform2.S \
- x86/3dnow_xform3.S \
- x86/3dnow_xform4.S \
- x86/3dnow_normal.S \
- x86/sse_xform1.S \
- x86/sse_xform2.S \
- x86/sse_xform3.S \
- x86/sse_xform4.S \
- x86/sse_normal.S \
- x86/read_rgba_span_x86.S
-
-X86-64_SOURCES = \
- x86-64/xform4.S
-
-SPARC_SOURCES = \
- sparc/clip.S \
- sparc/norm.S \
- sparc/xform.S
-
-COMMON_DRIVER_SOURCES = \
- drivers/common/driverfuncs.c \
- drivers/common/meta.c
-
-
-# Sources for building non-Gallium drivers
-MESA_SOURCES = \
- $(MAIN_SOURCES) \
- $(MATH_SOURCES) \
- $(MATH_XFORM_SOURCES) \
- $(VBO_SOURCES) \
- $(TNL_SOURCES) \
- $(PROGRAM_SOURCES) \
- $(SWRAST_SOURCES) \
- $(SWRAST_SETUP_SOURCES) \
- $(COMMON_DRIVER_SOURCES)\
- $(ASM_C_SOURCES)
-
-MESA_CXX_SOURCES = \
- $(SHADER_CXX_SOURCES)
-
-# Sources for building Gallium drivers
-MESA_GALLIUM_SOURCES = \
- $(MAIN_SOURCES) \
- $(MATH_SOURCES) \
- $(VBO_SOURCES) \
- $(STATETRACKER_SOURCES) \
- $(PROGRAM_SOURCES) \
- ppc/common_ppc.c \
- x86/common_x86.c
-
-MESA_GALLIUM_CXX_SOURCES = \
- $(SHADER_CXX_SOURCES)
-
-# All the core C sources, for dependency checking
-ALL_SOURCES = \
- $(MESA_SOURCES) \
- $(MESA_CXX_SOURCES) \
- $(MESA_ASM_SOURCES) \
- $(STATETRACKER_SOURCES)
-
-
-### Object files
-
-MESA_OBJECTS = \
- $(MESA_SOURCES:.c=.o) \
- $(MESA_CXX_SOURCES:.cpp=.o) \
- $(MESA_ASM_SOURCES:.S=.o)
-
-MESA_GALLIUM_OBJECTS = \
- $(MESA_GALLIUM_SOURCES:.c=.o) \
- $(MESA_GALLIUM_CXX_SOURCES:.cpp=.o) \
- $(MESA_ASM_SOURCES:.S=.o)
-
-
-COMMON_DRIVER_OBJECTS = $(COMMON_DRIVER_SOURCES:.c=.o)
-
-
-### Other archives/libraries
-
-GLSL_LIBS = \
- $(TOP)/src/glsl/libglsl.a
-
-
-### Include directories
-
-INCLUDE_DIRS = \
- -I$(TOP)/include \
- -I$(TOP)/src/glsl \
- -I$(TOP)/src/mesa \
- -I$(TOP)/src/mapi \
- -I$(TOP)/src/gallium/include \
- -I$(TOP)/src/gallium/auxiliary
+### Lists of source files, included by Makefiles
+
+# this is part of MAIN_SOURCES
+MAIN_ES_SOURCES = \
+ main/api_exec_es1.c \
+ main/api_exec_es2.c
+
+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 \
+ main/atifragshader.c \
+ main/attrib.c \
+ main/arrayobj.c \
+ main/blend.c \
+ main/bufferobj.c \
+ main/buffers.c \
+ main/clear.c \
+ main/clip.c \
+ main/colortab.c \
+ main/condrender.c \
+ main/context.c \
+ main/convolve.c \
+ main/cpuinfo.c \
+ main/debug.c \
+ main/depth.c \
+ main/depthstencil.c \
+ main/dlist.c \
+ main/dlopen.c \
+ main/drawpix.c \
+ main/drawtex.c \
+ main/enable.c \
+ main/enums.c \
+ main/eval.c \
+ main/execmem.c \
+ main/extensions.c \
+ main/fbobject.c \
+ main/feedback.c \
+ main/ffvertex_prog.c \
+ main/fog.c \
+ main/formats.c \
+ main/framebuffer.c \
+ main/get.c \
+ main/getstring.c \
+ main/hash.c \
+ main/hint.c \
+ main/histogram.c \
+ main/image.c \
+ main/imports.c \
+ main/light.c \
+ main/lines.c \
+ main/matrix.c \
+ main/mipmap.c \
+ main/mm.c \
+ main/multisample.c \
+ main/nvprogram.c \
+ main/pack.c \
+ main/pbo.c \
+ main/pixel.c \
+ main/pixelstore.c \
+ main/pixeltransfer.c \
+ main/points.c \
+ main/polygon.c \
+ main/queryobj.c \
+ main/querymatrix.c \
+ main/rastpos.c \
+ main/readpix.c \
+ main/remap.c \
+ main/renderbuffer.c \
+ main/scissor.c \
+ main/shaderapi.c \
+ main/shaderobj.c \
+ main/shared.c \
+ main/state.c \
+ main/stencil.c \
+ main/syncobj.c \
+ main/texcompress.c \
+ main/texcompress_rgtc.c \
+ main/texcompress_s3tc.c \
+ main/texcompress_fxt1.c \
+ main/texenv.c \
+ main/texenvprogram.c \
+ main/texfetch.c \
+ main/texformat.c \
+ main/texgen.c \
+ main/texgetimage.c \
+ main/teximage.c \
+ main/texobj.c \
+ main/texpal.c \
+ main/texparam.c \
+ main/texrender.c \
+ main/texstate.c \
+ main/texstore.c \
+ main/transformfeedback.c \
+ main/uniforms.c \
+ main/varray.c \
+ main/version.c \
+ main/viewport.c \
+ main/vtxfmt.c \
+ $(MAIN_ES_SOURCES)
+
+MATH_SOURCES = \
+ math/m_debug_clip.c \
+ math/m_debug_norm.c \
+ math/m_debug_xform.c \
+ math/m_eval.c \
+ math/m_matrix.c \
+ math/m_translate.c \
+ math/m_vector.c
+
+MATH_XFORM_SOURCES = \
+ math/m_xform.c
+
+SWRAST_SOURCES = \
+ swrast/s_aaline.c \
+ swrast/s_aatriangle.c \
+ swrast/s_accum.c \
+ swrast/s_alpha.c \
+ swrast/s_atifragshader.c \
+ swrast/s_bitmap.c \
+ swrast/s_blend.c \
+ swrast/s_blit.c \
+ swrast/s_clear.c \
+ swrast/s_copypix.c \
+ swrast/s_context.c \
+ swrast/s_depth.c \
+ swrast/s_drawpix.c \
+ swrast/s_feedback.c \
+ swrast/s_fog.c \
+ swrast/s_fragprog.c \
+ swrast/s_lines.c \
+ swrast/s_logic.c \
+ swrast/s_masking.c \
+ swrast/s_points.c \
+ swrast/s_readpix.c \
+ swrast/s_span.c \
+ swrast/s_stencil.c \
+ swrast/s_texcombine.c \
+ swrast/s_texfilter.c \
+ swrast/s_triangle.c \
+ swrast/s_zoom.c
+
+SWRAST_SETUP_SOURCES = \
+ swrast_setup/ss_context.c \
+ swrast_setup/ss_triangle.c
+
+TNL_SOURCES = \
+ tnl/t_context.c \
+ tnl/t_pipeline.c \
+ tnl/t_draw.c \
+ tnl/t_rasterpos.c \
+ tnl/t_vb_program.c \
+ tnl/t_vb_render.c \
+ tnl/t_vb_texgen.c \
+ tnl/t_vb_texmat.c \
+ tnl/t_vb_vertex.c \
+ tnl/t_vb_fog.c \
+ tnl/t_vb_light.c \
+ tnl/t_vb_normals.c \
+ tnl/t_vb_points.c \
+ tnl/t_vp_build.c \
+ tnl/t_vertex.c \
+ tnl/t_vertex_sse.c \
+ tnl/t_vertex_generic.c
+
+VBO_SOURCES = \
+ vbo/vbo_context.c \
+ vbo/vbo_exec.c \
+ vbo/vbo_exec_api.c \
+ vbo/vbo_exec_array.c \
+ vbo/vbo_exec_draw.c \
+ vbo/vbo_exec_eval.c \
+ vbo/vbo_rebase.c \
+ vbo/vbo_split.c \
+ vbo/vbo_split_copy.c \
+ vbo/vbo_split_inplace.c \
+ vbo/vbo_save.c \
+ vbo/vbo_save_api.c \
+ vbo/vbo_save_draw.c \
+ vbo/vbo_save_loopback.c
+
+STATETRACKER_SOURCES = \
+ state_tracker/st_atom.c \
+ state_tracker/st_atom_blend.c \
+ state_tracker/st_atom_clip.c \
+ state_tracker/st_atom_constbuf.c \
+ state_tracker/st_atom_depth.c \
+ state_tracker/st_atom_framebuffer.c \
+ state_tracker/st_atom_msaa.c \
+ state_tracker/st_atom_pixeltransfer.c \
+ state_tracker/st_atom_sampler.c \
+ state_tracker/st_atom_scissor.c \
+ state_tracker/st_atom_shader.c \
+ state_tracker/st_atom_rasterizer.c \
+ state_tracker/st_atom_stipple.c \
+ state_tracker/st_atom_texture.c \
+ state_tracker/st_atom_viewport.c \
+ state_tracker/st_cb_accum.c \
+ state_tracker/st_cb_bitmap.c \
+ state_tracker/st_cb_blit.c \
+ state_tracker/st_cb_bufferobjects.c \
+ state_tracker/st_cb_clear.c \
+ state_tracker/st_cb_condrender.c \
+ state_tracker/st_cb_flush.c \
+ state_tracker/st_cb_drawpixels.c \
+ state_tracker/st_cb_drawtex.c \
+ state_tracker/st_cb_eglimage.c \
+ state_tracker/st_cb_fbo.c \
+ state_tracker/st_cb_feedback.c \
+ state_tracker/st_cb_program.c \
+ state_tracker/st_cb_queryobj.c \
+ state_tracker/st_cb_rasterpos.c \
+ state_tracker/st_cb_readpixels.c \
+ state_tracker/st_cb_strings.c \
+ state_tracker/st_cb_texture.c \
+ state_tracker/st_cb_viewport.c \
+ state_tracker/st_cb_xformfb.c \
+ state_tracker/st_context.c \
+ state_tracker/st_debug.c \
+ state_tracker/st_draw.c \
+ state_tracker/st_draw_feedback.c \
+ state_tracker/st_extensions.c \
+ state_tracker/st_format.c \
+ state_tracker/st_gen_mipmap.c \
+ state_tracker/st_manager.c \
+ state_tracker/st_mesa_to_tgsi.c \
+ state_tracker/st_program.c \
+ state_tracker/st_texture.c
+
+PROGRAM_SOURCES = \
+ program/arbprogparse.c \
+ program/hash_table.c \
+ program/lex.yy.c \
+ program/nvfragparse.c \
+ program/nvvertparse.c \
+ program/program.c \
+ program/program_parse.tab.c \
+ program/program_parse_extra.c \
+ program/prog_cache.c \
+ program/prog_execute.c \
+ program/prog_instruction.c \
+ program/prog_noise.c \
+ program/prog_optimize.c \
+ program/prog_parameter.c \
+ program/prog_parameter_layout.c \
+ program/prog_print.c \
+ program/prog_statevars.c \
+ program/prog_uniform.c \
+ program/programopt.c \
+ program/register_allocate.c \
+ program/symbol_table.c
+
+
+SHADER_CXX_SOURCES = \
+ program/ir_to_mesa.cpp \
+ program/sampler.cpp
+
+ASM_C_SOURCES = \
+ x86/common_x86.c \
+ x86/x86_xform.c \
+ x86/3dnow.c \
+ x86/sse.c \
+ x86/rtasm/x86sse.c \
+ sparc/sparc.c \
+ ppc/common_ppc.c \
+ x86-64/x86-64.c
+
+X86_SOURCES = \
+ x86/common_x86_asm.S \
+ x86/x86_xform2.S \
+ x86/x86_xform3.S \
+ x86/x86_xform4.S \
+ x86/x86_cliptest.S \
+ x86/mmx_blend.S \
+ x86/3dnow_xform1.S \
+ x86/3dnow_xform2.S \
+ x86/3dnow_xform3.S \
+ x86/3dnow_xform4.S \
+ x86/3dnow_normal.S \
+ x86/sse_xform1.S \
+ x86/sse_xform2.S \
+ x86/sse_xform3.S \
+ x86/sse_xform4.S \
+ x86/sse_normal.S \
+ x86/read_rgba_span_x86.S
+
+X86-64_SOURCES = \
+ x86-64/xform4.S
+
+SPARC_SOURCES = \
+ sparc/clip.S \
+ sparc/norm.S \
+ sparc/xform.S
+
+COMMON_DRIVER_SOURCES = \
+ drivers/common/driverfuncs.c \
+ drivers/common/meta.c
+
+
+# Sources for building non-Gallium drivers
+MESA_SOURCES = \
+ $(MAIN_SOURCES) \
+ $(MATH_SOURCES) \
+ $(MATH_XFORM_SOURCES) \
+ $(VBO_SOURCES) \
+ $(TNL_SOURCES) \
+ $(PROGRAM_SOURCES) \
+ $(SWRAST_SOURCES) \
+ $(SWRAST_SETUP_SOURCES) \
+ $(COMMON_DRIVER_SOURCES)\
+ $(ASM_C_SOURCES)
+
+MESA_CXX_SOURCES = \
+ $(SHADER_CXX_SOURCES)
+
+# Sources for building Gallium drivers
+MESA_GALLIUM_SOURCES = \
+ $(MAIN_SOURCES) \
+ $(MATH_SOURCES) \
+ $(VBO_SOURCES) \
+ $(STATETRACKER_SOURCES) \
+ $(PROGRAM_SOURCES) \
+ ppc/common_ppc.c \
+ x86/common_x86.c
+
+MESA_GALLIUM_CXX_SOURCES = \
+ $(SHADER_CXX_SOURCES)
+
+# All the core C sources, for dependency checking
+ALL_SOURCES = \
+ $(MESA_SOURCES) \
+ $(MESA_CXX_SOURCES) \
+ $(MESA_ASM_SOURCES) \
+ $(STATETRACKER_SOURCES)
+
+
+### Object files
+
+MESA_OBJECTS = \
+ $(MESA_SOURCES:.c=.o) \
+ $(MESA_CXX_SOURCES:.cpp=.o) \
+ $(MESA_ASM_SOURCES:.S=.o)
+
+MESA_GALLIUM_OBJECTS = \
+ $(MESA_GALLIUM_SOURCES:.c=.o) \
+ $(MESA_GALLIUM_CXX_SOURCES:.cpp=.o) \
+ $(MESA_ASM_SOURCES:.S=.o)
+
+
+COMMON_DRIVER_OBJECTS = $(COMMON_DRIVER_SOURCES:.c=.o)
+
+
+### Other archives/libraries
+
+GLSL_LIBS = \
+ $(TOP)/src/glsl/libglsl.a
+
+
+### Include directories
+
+INCLUDE_DIRS = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/glsl \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/mapi \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/auxiliary
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index c3c4246d1..17dab2f1a 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -1,1931 +1,1938 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "main/mfeatures.h"
-#include "main/bufferobj.h"
-#include "main/enums.h"
-#include "main/fbobject.h"
-#include "main/formats.h"
-#include "main/image.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/mipmap.h"
-#include "main/pack.h"
-#include "main/pbo.h"
-#include "main/pixeltransfer.h"
-#include "main/texcompress.h"
-#include "main/texfetch.h"
-#include "main/texgetimage.h"
-#include "main/teximage.h"
-#include "main/texobj.h"
-#include "main/texstore.h"
-
-#include "state_tracker/st_debug.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_cb_fbo.h"
-#include "state_tracker/st_cb_flush.h"
-#include "state_tracker/st_cb_texture.h"
-#include "state_tracker/st_format.h"
-#include "state_tracker/st_texture.h"
-#include "state_tracker/st_gen_mipmap.h"
-#include "state_tracker/st_atom.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-#include "pipe/p_shader_tokens.h"
-#include "util/u_tile.h"
-#include "util/u_blit.h"
-#include "util/u_format.h"
-#include "util/u_surface.h"
-#include "util/u_sampler.h"
-#include "util/u_math.h"
-#include "util/u_box.h"
-
-#define DBG if (0) printf
-
-
-static enum pipe_texture_target
-gl_target_to_pipe(GLenum target)
-{
- switch (target) {
- case GL_TEXTURE_1D:
- return PIPE_TEXTURE_1D;
- case GL_TEXTURE_2D:
- return PIPE_TEXTURE_2D;
- case GL_TEXTURE_RECTANGLE_NV:
- return PIPE_TEXTURE_RECT;
- case GL_TEXTURE_3D:
- return PIPE_TEXTURE_3D;
- case GL_TEXTURE_CUBE_MAP_ARB:
- return PIPE_TEXTURE_CUBE;
- case GL_TEXTURE_1D_ARRAY_EXT:
- return PIPE_TEXTURE_1D_ARRAY;
- case GL_TEXTURE_2D_ARRAY_EXT:
- return PIPE_TEXTURE_2D_ARRAY;
- default:
- assert(0);
- return 0;
- }
-}
-
-
-/** called via ctx->Driver.NewTextureImage() */
-static struct gl_texture_image *
-st_NewTextureImage(struct gl_context * ctx)
-{
- DBG("%s\n", __FUNCTION__);
- (void) ctx;
- return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image);
-}
-
-
-/** called via ctx->Driver.NewTextureObject() */
-static struct gl_texture_object *
-st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
-{
- struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
-
- DBG("%s\n", __FUNCTION__);
- _mesa_initialize_texture_object(&obj->base, name, target);
-
- return &obj->base;
-}
-
-/** called via ctx->Driver.DeleteTextureObject() */
-static void
-st_DeleteTextureObject(struct gl_context *ctx,
- struct gl_texture_object *texObj)
-{
- struct st_context *st = st_context(ctx);
- struct st_texture_object *stObj = st_texture_object(texObj);
- if (stObj->pt)
- pipe_resource_reference(&stObj->pt, NULL);
- if (stObj->sampler_view) {
- if (stObj->sampler_view->context != st->pipe) {
- /* Take "ownership" of this texture sampler view by setting
- * its context pointer to this context. This avoids potential
- * crashes when the texture object is shared among contexts
- * and the original/owner context has already been destroyed.
- */
- stObj->sampler_view->context = st->pipe;
- }
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
- }
- _mesa_delete_texture_object(ctx, texObj);
-}
-
-
-/** called via ctx->Driver.FreeTexImageData() */
-static void
-st_FreeTextureImageData(struct gl_context * ctx, struct gl_texture_image *texImage)
-{
- struct st_texture_image *stImage = st_texture_image(texImage);
-
- DBG("%s\n", __FUNCTION__);
-
- if (stImage->pt) {
- pipe_resource_reference(&stImage->pt, NULL);
- }
-
- if (texImage->Data) {
- _mesa_align_free(texImage->Data);
- texImage->Data = NULL;
- }
-}
-
-
-/**
- * From linux kernel i386 header files, copes with odd sizes better
- * than COPY_DWORDS would:
- * XXX Put this in src/mesa/main/imports.h ???
- */
-#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)
-static INLINE void *
-__memcpy(void *to, const void *from, size_t n)
-{
- int d0, d1, d2;
- __asm__ __volatile__("rep ; movsl\n\t"
- "testb $2,%b4\n\t"
- "je 1f\n\t"
- "movsw\n"
- "1:\ttestb $1,%b4\n\t"
- "je 2f\n\t"
- "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2)
- :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from)
- :"memory");
- return (to);
-}
-#else
-#define __memcpy(a,b,c) memcpy(a,b,c)
-#endif
-
-
-/**
- * The system memcpy (at least on ubuntu 5.10) has problems copying
- * to agp (writecombined) memory from a source which isn't 64-byte
- * aligned - there is a 4x performance falloff.
- *
- * The x86 __memcpy is immune to this but is slightly slower
- * (10%-ish) than the system memcpy.
- *
- * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
- * isn't much faster than x86_memcpy for agp copies.
- *
- * TODO: switch dynamically.
- */
-static void *
-do_memcpy(void *dest, const void *src, size_t n)
-{
- if ((((unsigned long) src) & 63) || (((unsigned long) dest) & 63)) {
- return __memcpy(dest, src, n);
- }
- else
- return memcpy(dest, src, n);
-}
-
-
-/**
- * Return default texture resource binding bitmask for the given format.
- */
-static GLuint
-default_bindings(struct st_context *st, enum pipe_format format)
-{
- struct pipe_screen *screen = st->pipe->screen;
- const unsigned target = PIPE_TEXTURE_2D;
- const unsigned geom = 0x0;
- unsigned bindings;
-
- if (util_format_is_depth_or_stencil(format))
- bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL;
- else
- bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
-
- if (screen->is_format_supported(screen, format, target, 0, bindings, geom))
- return bindings;
- else
- return PIPE_BIND_SAMPLER_VIEW;
-}
-
-
-/** Return number of image dimensions (1, 2 or 3) for a texture target. */
-static GLuint
-get_texture_dims(GLenum target)
-{
- switch (target) {
- case GL_TEXTURE_1D:
- case GL_TEXTURE_1D_ARRAY_EXT:
- return 1;
- case GL_TEXTURE_2D:
- case GL_TEXTURE_CUBE_MAP_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
- case GL_TEXTURE_RECTANGLE_NV:
- case GL_TEXTURE_2D_ARRAY_EXT:
- return 2;
- case GL_TEXTURE_3D:
- return 3;
- default:
- assert(0 && "invalid texture target in get_texture_dims()");
- return 1;
- }
-}
-
-
-/**
- * Given the size of a mipmap image, try to compute the size of the level=0
- * mipmap image.
- *
- * Note that this isn't always accurate for odd-sized, non-POW textures.
- * For example, if level=1 and width=40 then the level=0 width may be 80 or 81.
- *
- * \return GL_TRUE for success, GL_FALSE for failure
- */
-static GLboolean
-guess_base_level_size(GLenum target,
- GLuint width, GLuint height, GLuint depth, GLuint level,
- GLuint *width0, GLuint *height0, GLuint *depth0)
-{
- const GLuint dims = get_texture_dims(target);
-
- assert(width >= 1);
- assert(height >= 1);
- assert(depth >= 1);
-
- if (level > 0) {
- /* Depending on the image's size, we can't always make a guess here */
- if ((dims >= 1 && width == 1) ||
- (dims >= 2 && height == 1) ||
- (dims >= 3 && depth == 1)) {
- /* we can't determine the image size at level=0 */
- return GL_FALSE;
- }
-
- /* grow the image size until we hit level = 0 */
- while (level > 0) {
- if (width > 1)
- width <<= 1;
- if (height > 1)
- height <<= 1;
- if (depth > 1)
- depth <<= 1;
- level--;
- }
- }
-
- *width0 = width;
- *height0 = height;
- *depth0 = depth;
-
- return GL_TRUE;
-}
-
-
-/**
- * Try to allocate a pipe_resource object for the given st_texture_object.
- *
- * We use the given st_texture_image as a clue to determine the size of the
- * mipmap image at level=0.
- *
- * \return GL_TRUE for success, GL_FALSE if out of memory.
- */
-static GLboolean
-guess_and_alloc_texture(struct st_context *st,
- struct st_texture_object *stObj,
- const struct st_texture_image *stImage)
-{
- GLuint lastLevel, width, height, depth;
- GLuint bindings;
- GLuint ptWidth, ptHeight, ptDepth, ptLayers;
- enum pipe_format fmt;
-
- DBG("%s\n", __FUNCTION__);
-
- assert(!stObj->pt);
-
- if (!guess_base_level_size(stObj->base.Target,
- stImage->base.Width2,
- stImage->base.Height2,
- stImage->base.Depth2,
- stImage->level,
- &width, &height, &depth)) {
- /* we can't determine the image size at level=0 */
- stObj->width0 = stObj->height0 = stObj->depth0 = 0;
- /* this is not an out of memory error */
- return GL_TRUE;
- }
-
- /* At this point, (width x height x depth) is the expected size of
- * the level=0 mipmap image.
- */
-
- /* Guess a reasonable value for lastLevel. With OpenGL we have no
- * idea how many mipmap levels will be in a texture until we start
- * to render with it. Make an educated guess here but be prepared
- * to re-allocating a texture buffer with space for more (or fewer)
- * mipmap levels later.
- */
- if ((stObj->base.MinFilter == GL_NEAREST ||
- stObj->base.MinFilter == GL_LINEAR ||
- stImage->base._BaseFormat == GL_DEPTH_COMPONENT ||
- stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) &&
- !stObj->base.GenerateMipmap &&
- stImage->level == 0) {
- /* only alloc space for a single mipmap level */
- lastLevel = 0;
- }
- else {
- /* alloc space for a full mipmap */
- GLuint l2width = util_logbase2(width);
- GLuint l2height = util_logbase2(height);
- GLuint l2depth = util_logbase2(depth);
- lastLevel = MAX2(MAX2(l2width, l2height), l2depth);
- }
-
- /* Save the level=0 dimensions */
- stObj->width0 = width;
- stObj->height0 = height;
- stObj->depth0 = depth;
-
- fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat);
-
- bindings = default_bindings(st, fmt);
-
- st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
- width, height, depth,
- &ptWidth, &ptHeight, &ptDepth, &ptLayers);
-
- stObj->pt = st_texture_create(st,
- gl_target_to_pipe(stObj->base.Target),
- fmt,
- lastLevel,
- ptWidth,
- ptHeight,
- ptDepth,
- ptLayers,
- bindings);
-
- DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
-
- return stObj->pt != NULL;
-}
-
-
-/**
- * Adjust pixel unpack params and image dimensions to strip off the
- * texture border.
- * Gallium doesn't support texture borders. They've seldem been used
- * and seldom been implemented correctly anyway.
- * \param unpackNew returns the new pixel unpack parameters
- */
-static void
-strip_texture_border(GLint border,
- GLint *width, GLint *height, GLint *depth,
- const struct gl_pixelstore_attrib *unpack,
- struct gl_pixelstore_attrib *unpackNew)
-{
- assert(border > 0); /* sanity check */
-
- *unpackNew = *unpack;
-
- if (unpackNew->RowLength == 0)
- unpackNew->RowLength = *width;
-
- if (depth && unpackNew->ImageHeight == 0)
- unpackNew->ImageHeight = *height;
-
- unpackNew->SkipPixels += border;
- if (height)
- unpackNew->SkipRows += border;
- if (depth)
- unpackNew->SkipImages += border;
-
- assert(*width >= 3);
- *width = *width - 2 * border;
- if (height && *height >= 3)
- *height = *height - 2 * border;
- if (depth && *depth >= 3)
- *depth = *depth - 2 * border;
-}
-
-
-/**
- * Do glTexImage1/2/3D().
- */
-static void
-st_TexImage(struct gl_context * ctx,
- GLint dims,
- GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint depth,
- GLint border,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *unpack,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- GLsizei imageSize, GLboolean compressed_src)
-{
- struct st_context *st = st_context(ctx);
- struct st_texture_object *stObj = st_texture_object(texObj);
- struct st_texture_image *stImage = st_texture_image(texImage);
- GLuint dstRowStride = 0;
- struct gl_pixelstore_attrib unpackNB;
- enum pipe_transfer_usage transfer_usage = 0;
-
- DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
-
- /* switch to "normal" */
- if (stObj->surface_based) {
- gl_format texFormat;
-
- _mesa_clear_texture_object(ctx, texObj);
- pipe_resource_reference(&stObj->pt, NULL);
-
- /* oops, need to init this image again */
- texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
- internalFormat, format, type);
-
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, height, depth, border,
- internalFormat, texFormat);
-
- stObj->surface_based = GL_FALSE;
- }
-
- /* gallium does not support texture borders, strip it off */
- if (border) {
- strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB);
- unpack = &unpackNB;
- texImage->Width = width;
- texImage->Height = height;
- texImage->Depth = depth;
- texImage->Border = 0;
- border = 0;
- }
- else {
- assert(texImage->Width == width);
- assert(texImage->Height == height);
- assert(texImage->Depth == depth);
- }
-
- stImage->face = _mesa_tex_target_to_face(target);
- stImage->level = level;
-
- _mesa_set_fetch_functions(texImage, dims);
-
- /* Release the reference to a potentially orphaned buffer.
- * Release any old malloced memory.
- */
- if (stImage->pt) {
- pipe_resource_reference(&stImage->pt, NULL);
- assert(!texImage->Data);
- }
- else if (texImage->Data) {
- _mesa_align_free(texImage->Data);
- }
-
- /*
- * See if the new image is somehow incompatible with the existing
- * mipmap. If so, free the old mipmap.
- */
- if (stObj->pt) {
- if (level > (GLint) stObj->pt->last_level ||
- !st_texture_match_image(stObj->pt, &stImage->base,
- stImage->face, stImage->level)) {
- DBG("release it\n");
- pipe_resource_reference(&stObj->pt, NULL);
- assert(!stObj->pt);
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
- }
- }
-
- if (width == 0 || height == 0 || depth == 0) {
- /* stop after freeing old image */
- return;
- }
-
- if (!stObj->pt) {
- if (!guess_and_alloc_texture(st, stObj, stImage)) {
- /* Probably out of memory.
- * Try flushing any pending rendering, then retry.
- */
- st_finish(st);
- if (!guess_and_alloc_texture(st, stObj, stImage)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
- return;
- }
- }
- }
-
- assert(!stImage->pt);
-
- /* Check if this texture image can live inside the texture object's buffer.
- * If so, store the image there. Otherwise the image will temporarily live
- * in its own buffer.
- */
- if (stObj->pt &&
- st_texture_match_image(stObj->pt, &stImage->base,
- stImage->face, stImage->level)) {
-
- pipe_resource_reference(&stImage->pt, stObj->pt);
- assert(stImage->pt);
- }
-
- if (!stImage->pt)
- DBG("XXX: Image did not fit into texture - storing in local memory!\n");
-
- /* Pixel data may come from regular user memory or a PBO. For the later,
- * do bounds checking and map the PBO to read pixels data from it.
- *
- * XXX we should try to use a GPU-accelerated path to copy the image data
- * from the PBO to the texture.
- */
- if (compressed_src) {
- pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
- unpack,
- "glCompressedTexImage");
- }
- else {
- pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
- format, type,
- pixels, unpack, "glTexImage");
- }
-
- /* for a 1D array upload the image as a series of layer with height = 1 */
- if (target == GL_TEXTURE_1D_ARRAY) {
- depth = height;
- height = 1;
- }
-
- /*
- * Prepare to store the texture data. Either map the gallium texture buffer
- * memory or malloc space for it.
- */
- if (stImage->pt) {
- /* Store the image in the gallium texture memory buffer */
- if (format == GL_DEPTH_COMPONENT &&
- util_format_is_depth_and_stencil(stImage->pt->format))
- transfer_usage = PIPE_TRANSFER_READ_WRITE;
- else
- transfer_usage = PIPE_TRANSFER_WRITE;
-
- texImage->Data = st_texture_image_map(st, stImage, 0,
- transfer_usage, 0, 0, width, height);
- if(stImage->transfer)
- dstRowStride = stImage->transfer->stride;
- }
- else {
- /* Allocate regular memory and store the image there temporarily. */
- GLuint imageSize = _mesa_format_image_size(texImage->TexFormat,
- width, height, depth);
- dstRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
-
- texImage->Data = _mesa_align_malloc(imageSize, 16);
- }
-
- if (!texImage->Data) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
- return;
- }
-
- if (!pixels) {
- /* We've allocated texture memory, but have no pixel data - all done. */
- goto done;
- }
-
- DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
- width, height, depth, width, dstRowStride);
-
- /* Copy user texture image into the texture buffer.
- */
- if (compressed_src) {
- const GLuint srcRowStride =
- _mesa_format_row_stride(texImage->TexFormat, width);
- if (dstRowStride == srcRowStride) {
- memcpy(texImage->Data, pixels, imageSize);
- }
- else {
- char *dst = texImage->Data;
- const char *src = pixels;
- GLuint i, bw, bh, lines;
- _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
- lines = (height + bh - 1) / bh;
-
- for (i = 0; i < lines; ++i) {
- memcpy(dst, src, srcRowStride);
- dst += dstRowStride;
- src += srcRowStride;
- }
- }
- }
- else {
- const GLuint srcImageStride =
- _mesa_image_image_stride(unpack, width, height, format, type);
- GLint i;
- const GLubyte *src = (const GLubyte *) pixels;
-
- for (i = 0; i < depth; i++) {
- if (!_mesa_texstore(ctx, dims,
- texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- texImage->ImageOffsets,
- width, height, 1,
- format, type, src, unpack)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
- }
-
- if (stImage->pt && i + 1 < depth) {
- /* unmap this slice */
- st_texture_image_unmap(st, stImage);
- /* map next slice of 3D texture */
- texImage->Data = st_texture_image_map(st, stImage, i + 1,
- transfer_usage, 0, 0,
- width, height);
- src += srcImageStride;
- }
- }
- }
-
-done:
- _mesa_unmap_teximage_pbo(ctx, unpack);
-
- if (stImage->pt && texImage->Data) {
- st_texture_image_unmap(st, stImage);
- texImage->Data = NULL;
- }
-}
-
-
-static void
-st_TexImage3D(struct gl_context * ctx,
- GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint depth,
- GLint border,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *unpack,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- st_TexImage(ctx, 3, target, level, internalFormat, width, height, depth,
- border, format, type, pixels, unpack, texObj, texImage,
- 0, GL_FALSE);
-}
-
-
-static void
-st_TexImage2D(struct gl_context * ctx,
- GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *unpack,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border,
- format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
-}
-
-
-static void
-st_TexImage1D(struct gl_context * ctx,
- GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint border,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *unpack,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- st_TexImage(ctx, 1, target, level, internalFormat, width, 1, 1, border,
- format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
-}
-
-
-static void
-st_CompressedTexImage2D(struct gl_context *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border,
- 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE);
-}
-
-
-
-/**
- * glGetTexImage() helper: decompress a compressed texture by rendering
- * a textured quad. Store the results in the user's buffer.
- */
-static void
-decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid *pixels,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
- struct st_texture_image *stImage = st_texture_image(texImage);
- struct st_texture_object *stObj = st_texture_object(texObj);
- struct pipe_sampler_view *src_view =
- st_get_texture_sampler_view(stObj, pipe);
- const GLuint width = texImage->Width;
- const GLuint height = texImage->Height;
- struct pipe_surface *dst_surface;
- struct pipe_resource *dst_texture;
- struct pipe_transfer *tex_xfer;
- unsigned bind = (PIPE_BIND_RENDER_TARGET | /* util_blit may choose to render */
- PIPE_BIND_TRANSFER_READ);
-
- /* create temp / dest surface */
- if (!util_create_rgba_surface(pipe, width, height, bind,
- &dst_texture, &dst_surface)) {
- _mesa_problem(ctx, "util_create_rgba_surface() failed "
- "in decompress_with_blit()");
- return;
- }
-
- /* blit/render/decompress */
- util_blit_pixels_tex(st->blit,
- src_view, /* pipe_resource (src) */
- 0, 0, /* src x0, y0 */
- width, height, /* src x1, y1 */
- dst_surface, /* pipe_surface (dst) */
- 0, 0, /* dst x0, y0 */
- width, height, /* dst x1, y1 */
- 0.0, /* z */
- PIPE_TEX_MIPFILTER_NEAREST);
-
- /* map the dst_surface so we can read from it */
- tex_xfer = pipe_get_transfer(st_context(ctx)->pipe,
- dst_texture, 0, 0,
- PIPE_TRANSFER_READ,
- 0, 0, width, height);
-
- pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
-
- /* copy/pack data into user buffer */
- if (st_equal_formats(stImage->pt->format, format, type)) {
- /* memcpy */
- const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format);
- ubyte *map = pipe_transfer_map(pipe, tex_xfer);
- GLuint row;
- for (row = 0; row < height; row++) {
- GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width,
- height, format, type, row, 0);
- memcpy(dest, map, bytesPerRow);
- map += tex_xfer->stride;
- }
- pipe_transfer_unmap(pipe, tex_xfer);
- }
- else {
- /* format translation via floats */
- GLuint row;
- enum pipe_format format = util_format_linear(dst_texture->format);
- for (row = 0; row < height; row++) {
- const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */
- GLfloat rgba[4 * MAX_WIDTH];
- GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width,
- height, format, type, row, 0);
-
- if (ST_DEBUG & DEBUG_FALLBACK)
- debug_printf("%s: fallback format translation\n", __FUNCTION__);
-
- /* get float[4] rgba row from surface */
- pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1,
- format, rgba);
-
- _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
- type, dest, &ctx->Pack, transferOps);
- }
- }
-
- _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
-
- pipe->transfer_destroy(pipe, tex_xfer);
-
- /* destroy the temp / dest surface */
- util_destroy_rgba_surface(dst_texture, dst_surface);
-}
-
-
-
-/**
- * Need to map texture image into memory before copying image data,
- * then unmap it.
- */
-static void
-st_get_tex_image(struct gl_context * ctx, GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid * pixels,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage, GLboolean compressed_dst)
-{
- struct st_context *st = st_context(ctx);
- struct st_texture_image *stImage = st_texture_image(texImage);
- const GLuint dstImageStride =
- _mesa_image_image_stride(&ctx->Pack, texImage->Width, texImage->Height,
- format, type);
- GLuint depth, i;
- GLubyte *dest;
-
- if (stImage->pt &&
- util_format_is_s3tc(stImage->pt->format) &&
- !compressed_dst) {
- /* Need to decompress the texture.
- * We'll do this by rendering a textured quad.
- * Note that we only expect RGBA formats (no Z/depth formats).
- */
- decompress_with_blit(ctx, target, level, format, type, pixels,
- texObj, texImage);
- return;
- }
-
- /* Map */
- if (stImage->pt) {
- /* Image is stored in hardware format in a buffer managed by the
- * kernel. Need to explicitly map and unmap it.
- */
- texImage->Data = st_texture_image_map(st, stImage, 0,
- PIPE_TRANSFER_READ, 0, 0,
- stImage->base.Width,
- stImage->base.Height);
- /* compute stride in texels from stride in bytes */
- texImage->RowStride = stImage->transfer->stride
- * util_format_get_blockwidth(stImage->pt->format)
- / util_format_get_blocksize(stImage->pt->format);
- }
- else {
- /* Otherwise, the image should actually be stored in
- * texImage->Data. This is pretty confusing for
- * everybody, I'd much prefer to separate the two functions of
- * texImage->Data - storage for texture images in main memory
- * and access (ie mappings) of images. In other words, we'd
- * create a new texImage->Map field and leave Data simply for
- * storage.
- */
- assert(texImage->Data);
- }
-
- depth = texImage->Depth;
- texImage->Depth = 1;
-
- dest = (GLubyte *) pixels;
-
- _mesa_set_fetch_functions(texImage, get_texture_dims(target));
-
- for (i = 0; i < depth; i++) {
- if (compressed_dst) {
- _mesa_get_compressed_teximage(ctx, target, level, dest,
- texObj, texImage);
- }
- else {
- _mesa_get_teximage(ctx, target, level, format, type, dest,
- texObj, texImage);
- }
-
- if (stImage->pt && i + 1 < depth) {
- /* unmap this slice */
- st_texture_image_unmap(st, stImage);
- /* map next slice of 3D texture */
- texImage->Data = st_texture_image_map(st, stImage, i + 1,
- PIPE_TRANSFER_READ, 0, 0,
- stImage->base.Width,
- stImage->base.Height);
- dest += dstImageStride;
- }
- }
-
- texImage->Depth = depth;
-
- /* Unmap */
- if (stImage->pt) {
- st_texture_image_unmap(st, stImage);
- texImage->Data = NULL;
- }
-}
-
-
-static void
-st_GetTexImage(struct gl_context * ctx, GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid * pixels,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- st_get_tex_image(ctx, target, level, format, type, pixels, texObj, texImage,
- GL_FALSE);
-}
-
-
-static void
-st_GetCompressedTexImage(struct gl_context *ctx, GLenum target, GLint level,
- GLvoid *pixels,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- st_get_tex_image(ctx, target, level, 0, 0, pixels, texObj, texImage,
- GL_TRUE);
-}
-
-
-
-static void
-st_TexSubimage(struct gl_context *ctx, GLint dims, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint width, GLint height, GLint depth,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- struct st_context *st = st_context(ctx);
- struct st_texture_image *stImage = st_texture_image(texImage);
- GLuint dstRowStride;
- const GLuint srcImageStride =
- _mesa_image_image_stride(packing, width, height, format, type);
- GLint i;
- const GLubyte *src;
- /* init to silence warning only: */
- enum pipe_transfer_usage transfer_usage = PIPE_TRANSFER_WRITE;
-
- DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr(target),
- level, xoffset, yoffset, width, height);
-
- pixels =
- _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
- type, pixels, packing, "glTexSubImage2D");
- if (!pixels)
- return;
-
- /* for a 1D array upload the image as a series of layer with height = 1 */
- if (target == GL_TEXTURE_1D_ARRAY) {
- depth = height;
- height = 1;
- }
-
- /* Map buffer if necessary. Need to lock to prevent other contexts
- * from uploading the buffer under us.
- */
- if (stImage->pt) {
- if (format == GL_DEPTH_COMPONENT &&
- util_format_is_depth_and_stencil(stImage->pt->format))
- transfer_usage = PIPE_TRANSFER_READ_WRITE;
- else
- transfer_usage = PIPE_TRANSFER_WRITE;
-
- texImage->Data = st_texture_image_map(st, stImage, zoffset,
- transfer_usage,
- xoffset, yoffset,
- width, height);
- }
-
- if (!texImage->Data) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
- goto done;
- }
-
- src = (const GLubyte *) pixels;
- dstRowStride = stImage->transfer->stride;
-
- for (i = 0; i < depth; i++) {
- if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- 0, 0, 0,
- dstRowStride,
- texImage->ImageOffsets,
- width, height, 1,
- format, type, src, packing)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
- }
-
- if (stImage->pt && i + 1 < depth) {
- /* unmap this slice */
- st_texture_image_unmap(st, stImage);
- /* map next slice of 3D texture */
- texImage->Data = st_texture_image_map(st, stImage,
- zoffset + i + 1,
- transfer_usage,
- xoffset, yoffset,
- width, height);
- src += srcImageStride;
- }
- }
-
-done:
- _mesa_unmap_teximage_pbo(ctx, packing);
-
- if (stImage->pt && texImage->Data) {
- st_texture_image_unmap(st, stImage);
- texImage->Data = NULL;
- }
-}
-
-
-
-static void
-st_TexSubImage3D(struct gl_context *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- st_TexSubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
- width, height, depth, format, type,
- pixels, packing, texObj, texImage);
-}
-
-
-static void
-st_TexSubImage2D(struct gl_context *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- st_TexSubimage(ctx, 2, target, level, xoffset, yoffset, 0,
- width, height, 1, format, type,
- pixels, packing, texObj, texImage);
-}
-
-
-static void
-st_TexSubImage1D(struct gl_context *ctx, GLenum target, GLint level,
- GLint xoffset, GLsizei width, GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- st_TexSubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1,
- format, type, pixels, packing, texObj, texImage);
-}
-
-
-static void
-st_CompressedTexSubImage1D(struct gl_context *ctx, GLenum target, GLint level,
- GLint xoffset, GLsizei width,
- GLenum format,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- assert(0);
-}
-
-
-static void
-st_CompressedTexSubImage2D(struct gl_context *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLint height,
- GLenum format,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- struct st_context *st = st_context(ctx);
- struct st_texture_image *stImage = st_texture_image(texImage);
- int srcBlockStride;
- int dstBlockStride;
- int y;
- enum pipe_format pformat;
-
- if (stImage->pt) {
- pformat = stImage->pt->format;
-
- texImage->Data = st_texture_image_map(st, stImage, 0,
- PIPE_TRANSFER_WRITE,
- xoffset, yoffset,
- width, height);
-
- srcBlockStride = util_format_get_stride(pformat, width);
- dstBlockStride = stImage->transfer->stride;
- } else {
- assert(stImage->pt);
- /* TODO find good values for block and strides */
- /* TODO also adjust texImage->data for yoffset/xoffset */
- return;
- }
-
- if (!texImage->Data) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage");
- return;
- }
-
- assert(xoffset % util_format_get_blockwidth(pformat) == 0);
- assert(yoffset % util_format_get_blockheight(pformat) == 0);
-
- for (y = 0; y < height; y += util_format_get_blockheight(pformat)) {
- /* don't need to adjust for xoffset and yoffset as st_texture_image_map does that */
- const char *src = (const char*)data + srcBlockStride * util_format_get_nblocksy(pformat, y);
- char *dst = (char*)texImage->Data + dstBlockStride * util_format_get_nblocksy(pformat, y);
- memcpy(dst, src, util_format_get_stride(pformat, width));
- }
-
- if (stImage->pt) {
- st_texture_image_unmap(st, stImage);
- texImage->Data = NULL;
- }
-}
-
-
-static void
-st_CompressedTexSubImage3D(struct gl_context *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLint height, GLint depth,
- GLenum format,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- assert(0);
-}
-
-
-
-/**
- * Do a CopyTexSubImage operation using a read transfer from the source,
- * a write transfer to the destination and get_tile()/put_tile() to access
- * the pixels/texels.
- *
- * Note: srcY=0=TOP of renderbuffer
- */
-static void
-fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level,
- struct st_renderbuffer *strb,
- struct st_texture_image *stImage,
- GLenum baseFormat,
- GLint destX, GLint destY, GLint destZ,
- GLint srcX, GLint srcY,
- GLsizei width, GLsizei height)
-{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
- struct pipe_transfer *src_trans;
- GLvoid *texDest;
- enum pipe_transfer_usage transfer_usage;
-
- if (ST_DEBUG & DEBUG_FALLBACK)
- debug_printf("%s: fallback processing\n", __FUNCTION__);
-
- assert(width <= MAX_WIDTH);
-
- if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
- srcY = strb->Base.Height - srcY - height;
- }
-
- src_trans = pipe_get_transfer(st_context(ctx)->pipe,
- strb->texture,
- 0, 0,
- PIPE_TRANSFER_READ,
- srcX, srcY,
- width, height);
-
- if ((baseFormat == GL_DEPTH_COMPONENT ||
- baseFormat == GL_DEPTH_STENCIL) &&
- util_format_is_depth_and_stencil(stImage->pt->format))
- transfer_usage = PIPE_TRANSFER_READ_WRITE;
- else
- transfer_usage = PIPE_TRANSFER_WRITE;
-
- /* XXX this used to ignore destZ param */
- texDest = st_texture_image_map(st, stImage, destZ, transfer_usage,
- destX, destY, width, height);
-
- if (baseFormat == GL_DEPTH_COMPONENT ||
- baseFormat == GL_DEPTH_STENCIL) {
- const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
- ctx->Pixel.DepthBias != 0.0F);
- GLint row, yStep;
-
- /* determine bottom-to-top vs. top-to-bottom order for src buffer */
- if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
- srcY = height - 1;
- yStep = -1;
- }
- else {
- srcY = 0;
- yStep = 1;
- }
-
- /* To avoid a large temp memory allocation, do copy row by row */
- for (row = 0; row < height; row++, srcY += yStep) {
- uint data[MAX_WIDTH];
- pipe_get_tile_z(pipe, src_trans, 0, srcY, width, 1, data);
- if (scaleOrBias) {
- _mesa_scale_and_bias_depth_uint(ctx, width, data);
- }
- pipe_put_tile_z(pipe, stImage->transfer, 0, row, width, 1, data);
- }
- }
- else {
- /* RGBA format */
- GLfloat *tempSrc =
- (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
-
- if (tempSrc && texDest) {
- const GLint dims = 2;
- const GLint dstRowStride = stImage->transfer->stride;
- struct gl_texture_image *texImage = &stImage->base;
- struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
-
- if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
- unpack.Invert = GL_TRUE;
- }
-
- /* get float/RGBA image from framebuffer */
- /* XXX this usually involves a lot of int/float conversion.
- * try to avoid that someday.
- */
- pipe_get_tile_rgba_format(pipe, src_trans, 0, 0, width, height,
- util_format_linear(strb->texture->format),
- tempSrc);
-
- /* Store into texture memory.
- * Note that this does some special things such as pixel transfer
- * ops and format conversion. In particular, if the dest tex format
- * is actually RGBA but the user created the texture as GL_RGB we
- * need to fill-in/override the alpha channel with 1.0.
- */
- _mesa_texstore(ctx, dims,
- texImage->_BaseFormat,
- texImage->TexFormat,
- texDest,
- 0, 0, 0,
- dstRowStride,
- texImage->ImageOffsets,
- width, height, 1,
- GL_RGBA, GL_FLOAT, tempSrc, /* src */
- &unpack);
- }
- else {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
- }
-
- if (tempSrc)
- free(tempSrc);
- }
-
- st_texture_image_unmap(st, stImage);
- pipe->transfer_destroy(pipe, src_trans);
-}
-
-
-
-/**
- * If the format of the src renderbuffer and the format of the dest
- * texture are compatible (in terms of blitting), return a TGSI writemask
- * to be used during the blit.
- * If the src/dest are incompatible, return 0.
- */
-static unsigned
-compatible_src_dst_formats(struct gl_context *ctx,
- const struct gl_renderbuffer *src,
- const struct gl_texture_image *dst)
-{
- /* Get logical base formats for the src and dest.
- * That is, use the user-requested formats and not the actual, device-
- * chosen formats.
- * For example, the user may have requested an A8 texture but the
- * driver may actually be using an RGBA texture format. When we
- * copy/blit to that texture, we only want to copy the Alpha channel
- * and not the RGB channels.
- *
- * Similarly, when the src FBO was created an RGB format may have been
- * requested but the driver actually chose an RGBA format. In that case,
- * we don't want to copy the undefined Alpha channel to the dest texture
- * (it should be 1.0).
- */
- const GLenum srcFormat = _mesa_base_fbo_format(ctx, src->InternalFormat);
- const GLenum dstFormat = _mesa_base_tex_format(ctx, dst->InternalFormat);
-
- /**
- * XXX when we have red-only and red/green renderbuffers we'll need
- * to add more cases here (or implement a general-purpose routine that
- * queries the existance of the R,G,B,A channels in the src and dest).
- */
- if (srcFormat == dstFormat) {
- /* This is the same as matching_base_formats, which should
- * always pass, as it did previously.
- */
- return TGSI_WRITEMASK_XYZW;
- }
- else if (srcFormat == GL_RGB && dstFormat == GL_RGBA) {
- /* Make sure that A in the dest is 1. The actual src format
- * may be RGBA and have undefined A values.
- */
- return TGSI_WRITEMASK_XYZ;
- }
- else if (srcFormat == GL_RGBA && dstFormat == GL_RGB) {
- /* Make sure that A in the dest is 1. The actual dst format
- * may be RGBA and will need A=1 to provide proper alpha values
- * when sampled later.
- */
- return TGSI_WRITEMASK_XYZ;
- }
- else {
- if (ST_DEBUG & DEBUG_FALLBACK)
- debug_printf("%s failed for src %s, dst %s\n",
- __FUNCTION__,
- _mesa_lookup_enum_by_nr(srcFormat),
- _mesa_lookup_enum_by_nr(dstFormat));
-
- /* Otherwise fail.
- */
- return 0;
- }
-}
-
-
-
-/**
- * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
- * Note that the region to copy has already been clipped so we know we
- * won't read from outside the source renderbuffer's bounds.
- *
- * Note: srcY=0=Bottom of renderbuffer (GL convention)
- */
-static void
-st_copy_texsubimage(struct gl_context *ctx,
- GLenum target, GLint level,
- GLint destX, GLint destY, GLint destZ,
- GLint srcX, GLint srcY,
- GLsizei width, GLsizei height)
-{
- struct gl_texture_unit *texUnit =
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- struct gl_texture_object *texObj =
- _mesa_select_tex_object(ctx, texUnit, target);
- struct gl_texture_image *texImage =
- _mesa_select_tex_image(ctx, texObj, target, level);
- struct st_texture_image *stImage = st_texture_image(texImage);
- const GLenum texBaseFormat = texImage->_BaseFormat;
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct st_renderbuffer *strb;
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
- struct pipe_screen *screen = pipe->screen;
- enum pipe_format dest_format, src_format;
- GLboolean use_fallback = GL_TRUE;
- GLboolean matching_base_formats;
- GLuint format_writemask, sample_count;
- struct pipe_surface *dest_surface = NULL;
- GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
-
- /* make sure finalize_textures has been called?
- */
- if (0) st_validate_state(st);
-
- /* determine if copying depth or color data */
- if (texBaseFormat == GL_DEPTH_COMPONENT ||
- texBaseFormat == GL_DEPTH_STENCIL) {
- strb = st_renderbuffer(fb->_DepthBuffer);
- if (strb->Base.Wrapped) {
- strb = st_renderbuffer(strb->Base.Wrapped);
- }
- }
- else {
- /* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
- strb = st_renderbuffer(fb->_ColorReadBuffer);
- }
-
- if (!strb || !strb->surface || !stImage->pt) {
- debug_printf("%s: null strb or stImage\n", __FUNCTION__);
- return;
- }
-
- sample_count = strb->surface->texture->nr_samples;
- /* I believe this would be legal, presumably would need to do a resolve
- for color, and for depth/stencil spec says to just use one of the
- depth/stencil samples per pixel? Need some transfer clarifications. */
- assert(sample_count < 2);
-
- if (srcX < 0) {
- width -= -srcX;
- destX += -srcX;
- srcX = 0;
- }
-
- if (srcY < 0) {
- height -= -srcY;
- destY += -srcY;
- srcY = 0;
- }
-
- if (destX < 0) {
- width -= -destX;
- srcX += -destX;
- destX = 0;
- }
-
- if (destY < 0) {
- height -= -destY;
- srcY += -destY;
- destY = 0;
- }
-
- if (width < 0 || height < 0)
- return;
-
-
- assert(strb);
- assert(strb->surface);
- assert(stImage->pt);
-
- src_format = strb->surface->format;
- dest_format = stImage->pt->format;
-
- /*
- * Determine if the src framebuffer and dest texture have the same
- * base format. We need this to detect a case such as the framebuffer
- * being GL_RGBA but the texture being GL_RGB. If the actual hardware
- * texture format stores RGBA we need to set A=1 (overriding the
- * framebuffer's alpha values). We can't do that with the blit or
- * textured-quad paths.
- */
- matching_base_formats =
- (_mesa_get_format_base_format(strb->Base.Format) ==
- _mesa_get_format_base_format(texImage->TexFormat));
- format_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage);
-
- if (ctx->_ImageTransferState == 0x0) {
-
- if (matching_base_formats &&
- src_format == dest_format &&
- !do_flip)
- {
- /* use surface_copy() / blit */
- struct pipe_box src_box;
- u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer,
- width, height, &src_box);
-
- /* for resource_copy_region(), y=0=top, always */
- pipe->resource_copy_region(pipe,
- /* dest */
- stImage->pt,
- stImage->level,
- destX, destY, destZ + stImage->face,
- /* src */
- strb->texture,
- strb->surface->u.tex.level,
- &src_box);
- use_fallback = GL_FALSE;
- }
- else if (format_writemask &&
- texBaseFormat != GL_DEPTH_COMPONENT &&
- texBaseFormat != GL_DEPTH_STENCIL &&
- screen->is_format_supported(screen, src_format,
- PIPE_TEXTURE_2D, sample_count,
- PIPE_BIND_SAMPLER_VIEW,
- 0) &&
- screen->is_format_supported(screen, dest_format,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET,
- 0)) {
- /* draw textured quad to do the copy */
- GLint srcY0, srcY1;
- struct pipe_surface surf_tmpl;
- memset(&surf_tmpl, 0, sizeof(surf_tmpl));
- surf_tmpl.format = stImage->pt->format;
- surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
- surf_tmpl.u.tex.level = stImage->level;
- surf_tmpl.u.tex.first_layer = stImage->face + destZ;
- surf_tmpl.u.tex.last_layer = stImage->face + destZ;
-
- dest_surface = pipe->create_surface(pipe, stImage->pt,
- &surf_tmpl);
-
- if (do_flip) {
- srcY1 = strb->Base.Height - srcY - height;
- srcY0 = srcY1 + height;
- }
- else {
- srcY0 = srcY;
- srcY1 = srcY0 + height;
- }
-
- util_blit_pixels_writemask(st->blit,
- strb->texture,
- strb->surface->u.tex.level,
- srcX, srcY0,
- srcX + width, srcY1,
- strb->surface->u.tex.first_layer,
- dest_surface,
- destX, destY,
- destX + width, destY + height,
- 0.0, PIPE_TEX_MIPFILTER_NEAREST,
- format_writemask);
- use_fallback = GL_FALSE;
- }
-
- if (dest_surface)
- pipe_surface_reference(&dest_surface, NULL);
- }
-
- if (use_fallback) {
- /* software fallback */
- fallback_copy_texsubimage(ctx, target, level,
- strb, stImage, texBaseFormat,
- destX, destY, destZ,
- srcX, srcY, width, height);
- }
-}
-
-
-
-static void
-st_CopyTexImage1D(struct gl_context * ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLint border)
-{
- struct gl_texture_unit *texUnit =
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- struct gl_texture_object *texObj =
- _mesa_select_tex_object(ctx, texUnit, target);
- struct gl_texture_image *texImage =
- _mesa_select_tex_image(ctx, texObj, target, level);
-
- /* Setup or redefine the texture object, texture and texture
- * image. Don't populate yet.
- */
- ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
- width, border,
- GL_RGBA, CHAN_TYPE, NULL,
- &ctx->DefaultPacking, texObj, texImage);
-
- st_copy_texsubimage(ctx, target, level,
- 0, 0, 0, /* destX,Y,Z */
- x, y, width, 1); /* src X, Y, size */
-}
-
-
-static void
-st_CopyTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border)
-{
- struct gl_texture_unit *texUnit =
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- struct gl_texture_object *texObj =
- _mesa_select_tex_object(ctx, texUnit, target);
- struct gl_texture_image *texImage =
- _mesa_select_tex_image(ctx, texObj, target, level);
-
- /* Setup or redefine the texture object, texture and texture
- * image. Don't populate yet.
- */
- ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
- width, height, border,
- GL_RGBA, CHAN_TYPE, NULL,
- &ctx->DefaultPacking, texObj, texImage);
-
- st_copy_texsubimage(ctx, target, level,
- 0, 0, 0, /* destX,Y,Z */
- x, y, width, height); /* src X, Y, size */
-}
-
-
-static void
-st_CopyTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level,
- GLint xoffset, GLint x, GLint y, GLsizei width)
-{
- const GLint yoffset = 0, zoffset = 0;
- const GLsizei height = 1;
- st_copy_texsubimage(ctx, target, level,
- xoffset, yoffset, zoffset, /* destX,Y,Z */
- x, y, width, height); /* src X, Y, size */
-}
-
-
-static void
-st_CopyTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLint x, GLint y, GLsizei width, GLsizei height)
-{
- const GLint zoffset = 0;
- st_copy_texsubimage(ctx, target, level,
- xoffset, yoffset, zoffset, /* destX,Y,Z */
- x, y, width, height); /* src X, Y, size */
-}
-
-
-static void
-st_CopyTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height)
-{
- st_copy_texsubimage(ctx, target, level,
- xoffset, yoffset, zoffset, /* destX,Y,Z */
- x, y, width, height); /* src X, Y, size */
-}
-
-
-/**
- * Copy image data from stImage into the texture object 'stObj' at level
- * 'dstLevel'.
- */
-static void
-copy_image_data_to_texture(struct st_context *st,
- struct st_texture_object *stObj,
- GLuint dstLevel,
- struct st_texture_image *stImage)
-{
- /* debug checks */
- {
- const struct gl_texture_image *dstImage =
- stObj->base.Image[stImage->face][stImage->level];
- assert(dstImage);
- assert(dstImage->Width == stImage->base.Width);
- assert(dstImage->Height == stImage->base.Height);
- assert(dstImage->Depth == stImage->base.Depth);
- }
-
- if (stImage->pt) {
- /* Copy potentially with the blitter:
- */
- st_texture_image_copy(st->pipe,
- stObj->pt, dstLevel, /* dest texture, level */
- stImage->pt, stImage->level, /* src texture, level */
- stImage->face);
-
- pipe_resource_reference(&stImage->pt, NULL);
- }
- else if (stImage->base.Data) {
- st_texture_image_data(st,
- stObj->pt,
- stImage->face,
- dstLevel,
- stImage->base.Data,
- stImage->base.RowStride *
- util_format_get_blocksize(stObj->pt->format),
- stImage->base.RowStride *
- stImage->base.Height *
- util_format_get_blocksize(stObj->pt->format));
- _mesa_align_free(stImage->base.Data);
- stImage->base.Data = NULL;
- }
-
- pipe_resource_reference(&stImage->pt, stObj->pt);
-}
-
-
-/**
- * Called during state validation. When this function is finished,
- * the texture object should be ready for rendering.
- * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
- */
-GLboolean
-st_finalize_texture(struct gl_context *ctx,
- struct pipe_context *pipe,
- struct gl_texture_object *tObj)
-{
- struct st_context *st = st_context(ctx);
- struct st_texture_object *stObj = st_texture_object(tObj);
- const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
- GLuint face;
- struct st_texture_image *firstImage;
- enum pipe_format firstImageFormat;
- GLuint ptWidth, ptHeight, ptDepth, ptLayers;
-
- if (stObj->base._Complete) {
- /* The texture is complete and we know exactly how many mipmap levels
- * are present/needed. This is conditional because we may be called
- * from the st_generate_mipmap() function when the texture object is
- * incomplete. In that case, we'll have set stObj->lastLevel before
- * we get here.
- */
- if (stObj->base.MinFilter == GL_LINEAR ||
- stObj->base.MinFilter == GL_NEAREST)
- stObj->lastLevel = stObj->base.BaseLevel;
- else
- stObj->lastLevel = stObj->base._MaxLevel;
- }
-
- firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
- assert(firstImage);
-
- /* If both firstImage and stObj point to a texture which can contain
- * all active images, favour firstImage. Note that because of the
- * completeness requirement, we know that the image dimensions
- * will match.
- */
- if (firstImage->pt &&
- firstImage->pt != stObj->pt &&
- (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
- pipe_resource_reference(&stObj->pt, firstImage->pt);
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
- }
-
- /* Find gallium format for the Mesa texture */
- firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
-
- /* Find size of level=0 Gallium mipmap image, plus number of texture layers */
- {
- GLuint width, height, depth;
- if (!guess_base_level_size(stObj->base.Target,
- firstImage->base.Width2,
- firstImage->base.Height2,
- firstImage->base.Depth2,
- stObj->base.BaseLevel,
- &width, &height, &depth)) {
- width = stObj->width0;
- height = stObj->height0;
- depth = stObj->depth0;
- }
- /* convert GL dims to Gallium dims */
- st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth,
- &ptWidth, &ptHeight, &ptDepth, &ptLayers);
- }
-
- /* If we already have a gallium texture, check that it matches the texture
- * object's format, target, size, num_levels, etc.
- */
- if (stObj->pt) {
- if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
- !st_sampler_compat_formats(stObj->pt->format, firstImageFormat) ||
- stObj->pt->last_level < stObj->lastLevel ||
- stObj->pt->width0 != ptWidth ||
- stObj->pt->height0 != ptHeight ||
- stObj->pt->depth0 != ptDepth ||
- stObj->pt->array_size != ptLayers)
- {
- /* The gallium texture does not match the Mesa texture so delete the
- * gallium texture now. We'll make a new one below.
- */
- pipe_resource_reference(&stObj->pt, NULL);
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
- st->dirty.st |= ST_NEW_FRAMEBUFFER;
- }
- }
-
- /* May need to create a new gallium texture:
- */
- if (!stObj->pt) {
- GLuint bindings = default_bindings(st, firstImageFormat);
-
- stObj->pt = st_texture_create(st,
- gl_target_to_pipe(stObj->base.Target),
- firstImageFormat,
- stObj->lastLevel,
- ptWidth,
- ptHeight,
- ptDepth,
- ptLayers,
- bindings);
-
- if (!stObj->pt) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
- return GL_FALSE;
- }
- }
-
- /* Pull in any images not in the object's texture:
- */
- for (face = 0; face < nr_faces; face++) {
- GLuint level;
- for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) {
- struct st_texture_image *stImage =
- st_texture_image(stObj->base.Image[face][level]);
-
- /* Need to import images in main memory or held in other textures.
- */
- if (stImage && stObj->pt != stImage->pt) {
- copy_image_data_to_texture(st, stObj, level, stImage);
- }
- }
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Returns pointer to a default/dummy texture.
- * This is typically used when the current shader has tex/sample instructions
- * but the user has not provided a (any) texture(s).
- */
-struct gl_texture_object *
-st_get_default_texture(struct st_context *st)
-{
- if (!st->default_texture) {
- static const GLenum target = GL_TEXTURE_2D;
- GLubyte pixels[16][16][4];
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImg;
- GLuint i, j;
-
- /* The ARB_fragment_program spec says (0,0,0,1) should be returned
- * when attempting to sample incomplete textures.
- */
- for (i = 0; i < 16; i++) {
- for (j = 0; j < 16; j++) {
- pixels[i][j][0] = 0;
- pixels[i][j][1] = 0;
- pixels[i][j][2] = 0;
- pixels[i][j][3] = 255;
- }
- }
-
- texObj = st->ctx->Driver.NewTextureObject(st->ctx, 0, target);
-
- texImg = _mesa_get_tex_image(st->ctx, texObj, target, 0);
-
- _mesa_init_teximage_fields(st->ctx, target, texImg,
- 16, 16, 1, 0, /* w, h, d, border */
- GL_RGBA, MESA_FORMAT_RGBA8888);
-
- st_TexImage(st->ctx, 2, target,
- 0, GL_RGBA, /* level, intformat */
- 16, 16, 1, 0, /* w, h, d, border */
- GL_RGBA, GL_UNSIGNED_BYTE, pixels,
- &st->ctx->DefaultPacking,
- texObj, texImg,
- 0, 0);
-
- texObj->MinFilter = GL_NEAREST;
- texObj->MagFilter = GL_NEAREST;
- texObj->_Complete = GL_TRUE;
-
- st->default_texture = texObj;
- }
- return st->default_texture;
-}
-
-
-void
-st_init_texture_functions(struct dd_function_table *functions)
-{
- functions->ChooseTextureFormat = st_ChooseTextureFormat;
- functions->TexImage1D = st_TexImage1D;
- functions->TexImage2D = st_TexImage2D;
- functions->TexImage3D = st_TexImage3D;
- functions->TexSubImage1D = st_TexSubImage1D;
- functions->TexSubImage2D = st_TexSubImage2D;
- functions->TexSubImage3D = st_TexSubImage3D;
- functions->CompressedTexSubImage1D = st_CompressedTexSubImage1D;
- functions->CompressedTexSubImage2D = st_CompressedTexSubImage2D;
- functions->CompressedTexSubImage3D = st_CompressedTexSubImage3D;
- functions->CopyTexImage1D = st_CopyTexImage1D;
- functions->CopyTexImage2D = st_CopyTexImage2D;
- functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
- functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
- functions->CopyTexSubImage3D = st_CopyTexSubImage3D;
- functions->GenerateMipmap = st_generate_mipmap;
-
- functions->GetTexImage = st_GetTexImage;
-
- /* compressed texture functions */
- functions->CompressedTexImage2D = st_CompressedTexImage2D;
- functions->GetCompressedTexImage = st_GetCompressedTexImage;
-
- functions->NewTextureObject = st_NewTextureObject;
- functions->NewTextureImage = st_NewTextureImage;
- functions->DeleteTexture = st_DeleteTextureObject;
- functions->FreeTexImageData = st_FreeTextureImageData;
-
- functions->TextureMemCpy = do_memcpy;
-
- /* XXX Temporary until we can query pipe's texture sizes */
- functions->TestProxyTexImage = _mesa_test_proxy_teximage;
-}
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "main/mfeatures.h"
+#include "main/bufferobj.h"
+#include "main/enums.h"
+#include "main/fbobject.h"
+#include "main/formats.h"
+#include "main/image.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mipmap.h"
+#include "main/pack.h"
+#include "main/pbo.h"
+#include "main/pixeltransfer.h"
+#include "main/texcompress.h"
+#include "main/texfetch.h"
+#include "main/texgetimage.h"
+#include "main/teximage.h"
+#include "main/texobj.h"
+#include "main/texstore.h"
+
+#include "state_tracker/st_debug.h"
+#include "state_tracker/st_context.h"
+#include "state_tracker/st_cb_fbo.h"
+#include "state_tracker/st_cb_flush.h"
+#include "state_tracker/st_cb_texture.h"
+#include "state_tracker/st_format.h"
+#include "state_tracker/st_texture.h"
+#include "state_tracker/st_gen_mipmap.h"
+#include "state_tracker/st_atom.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "util/u_inlines.h"
+#include "pipe/p_shader_tokens.h"
+#include "util/u_tile.h"
+#include "util/u_blit.h"
+#include "util/u_format.h"
+#include "util/u_surface.h"
+#include "util/u_sampler.h"
+#include "util/u_math.h"
+#include "util/u_box.h"
+
+#define DBG if (0) printf
+
+
+static enum pipe_texture_target
+gl_target_to_pipe(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_1D:
+ return PIPE_TEXTURE_1D;
+ case GL_TEXTURE_2D:
+ return PIPE_TEXTURE_2D;
+ case GL_TEXTURE_RECTANGLE_NV:
+ return PIPE_TEXTURE_RECT;
+ case GL_TEXTURE_3D:
+ return PIPE_TEXTURE_3D;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ return PIPE_TEXTURE_CUBE;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ return PIPE_TEXTURE_1D_ARRAY;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ return PIPE_TEXTURE_2D_ARRAY;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+
+/** called via ctx->Driver.NewTextureImage() */
+static struct gl_texture_image *
+st_NewTextureImage(struct gl_context * ctx)
+{
+ DBG("%s\n", __FUNCTION__);
+ (void) ctx;
+ return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image);
+}
+
+
+/** called via ctx->Driver.NewTextureObject() */
+static struct gl_texture_object *
+st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
+{
+ struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
+
+ DBG("%s\n", __FUNCTION__);
+ _mesa_initialize_texture_object(&obj->base, name, target);
+
+ return &obj->base;
+}
+
+/** called via ctx->Driver.DeleteTextureObject() */
+static void
+st_DeleteTextureObject(struct gl_context *ctx,
+ struct gl_texture_object *texObj)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_texture_object *stObj = st_texture_object(texObj);
+ if (stObj->pt)
+ pipe_resource_reference(&stObj->pt, NULL);
+ if (stObj->sampler_view) {
+ if (stObj->sampler_view->context != st->pipe) {
+ /* Take "ownership" of this texture sampler view by setting
+ * its context pointer to this context. This avoids potential
+ * crashes when the texture object is shared among contexts
+ * and the original/owner context has already been destroyed.
+ */
+ stObj->sampler_view->context = st->pipe;
+ }
+ pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ }
+ _mesa_delete_texture_object(ctx, texObj);
+}
+
+
+/** called via ctx->Driver.FreeTexImageData() */
+static void
+st_FreeTextureImageData(struct gl_context * ctx, struct gl_texture_image *texImage)
+{
+ struct st_texture_image *stImage = st_texture_image(texImage);
+
+ DBG("%s\n", __FUNCTION__);
+
+ if (stImage->pt) {
+ pipe_resource_reference(&stImage->pt, NULL);
+ }
+
+ if (texImage->Data) {
+ _mesa_align_free(texImage->Data);
+ texImage->Data = NULL;
+ }
+}
+
+
+/**
+ * From linux kernel i386 header files, copes with odd sizes better
+ * than COPY_DWORDS would:
+ * XXX Put this in src/mesa/main/imports.h ???
+ */
+#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)
+static INLINE void *
+__memcpy(void *to, const void *from, size_t n)
+{
+ int d0, d1, d2;
+ __asm__ __volatile__("rep ; movsl\n\t"
+ "testb $2,%b4\n\t"
+ "je 1f\n\t"
+ "movsw\n"
+ "1:\ttestb $1,%b4\n\t"
+ "je 2f\n\t"
+ "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2)
+ :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from)
+ :"memory");
+ return (to);
+}
+#else
+#define __memcpy(a,b,c) memcpy(a,b,c)
+#endif
+
+
+/**
+ * The system memcpy (at least on ubuntu 5.10) has problems copying
+ * to agp (writecombined) memory from a source which isn't 64-byte
+ * aligned - there is a 4x performance falloff.
+ *
+ * The x86 __memcpy is immune to this but is slightly slower
+ * (10%-ish) than the system memcpy.
+ *
+ * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
+ * isn't much faster than x86_memcpy for agp copies.
+ *
+ * TODO: switch dynamically.
+ */
+static void *
+do_memcpy(void *dest, const void *src, size_t n)
+{
+ if ((((unsigned long) src) & 63) || (((unsigned long) dest) & 63)) {
+ return __memcpy(dest, src, n);
+ }
+ else
+ return memcpy(dest, src, n);
+}
+
+
+/**
+ * Return default texture resource binding bitmask for the given format.
+ */
+static GLuint
+default_bindings(struct st_context *st, enum pipe_format format)
+{
+ struct pipe_screen *screen = st->pipe->screen;
+ const unsigned target = PIPE_TEXTURE_2D;
+ const unsigned geom = 0x0;
+ unsigned bindings;
+
+ if (util_format_is_depth_or_stencil(format))
+ bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL;
+ else
+ bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+
+ if (screen->is_format_supported(screen, format, target, 0, bindings, geom))
+ return bindings;
+ else {
+ /* Try non-sRGB. */
+ format = util_format_linear(format);
+
+ if (screen->is_format_supported(screen, format, target, 0, bindings, geom))
+ return bindings;
+ else
+ return PIPE_BIND_SAMPLER_VIEW;
+ }
+}
+
+
+/** Return number of image dimensions (1, 2 or 3) for a texture target. */
+static GLuint
+get_texture_dims(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ return 1;
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ return 2;
+ case GL_TEXTURE_3D:
+ return 3;
+ default:
+ assert(0 && "invalid texture target in get_texture_dims()");
+ return 1;
+ }
+}
+
+
+/**
+ * Given the size of a mipmap image, try to compute the size of the level=0
+ * mipmap image.
+ *
+ * Note that this isn't always accurate for odd-sized, non-POW textures.
+ * For example, if level=1 and width=40 then the level=0 width may be 80 or 81.
+ *
+ * \return GL_TRUE for success, GL_FALSE for failure
+ */
+static GLboolean
+guess_base_level_size(GLenum target,
+ GLuint width, GLuint height, GLuint depth, GLuint level,
+ GLuint *width0, GLuint *height0, GLuint *depth0)
+{
+ const GLuint dims = get_texture_dims(target);
+
+ assert(width >= 1);
+ assert(height >= 1);
+ assert(depth >= 1);
+
+ if (level > 0) {
+ /* Depending on the image's size, we can't always make a guess here */
+ if ((dims >= 1 && width == 1) ||
+ (dims >= 2 && height == 1) ||
+ (dims >= 3 && depth == 1)) {
+ /* we can't determine the image size at level=0 */
+ return GL_FALSE;
+ }
+
+ /* grow the image size until we hit level = 0 */
+ while (level > 0) {
+ if (width > 1)
+ width <<= 1;
+ if (height > 1)
+ height <<= 1;
+ if (depth > 1)
+ depth <<= 1;
+ level--;
+ }
+ }
+
+ *width0 = width;
+ *height0 = height;
+ *depth0 = depth;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Try to allocate a pipe_resource object for the given st_texture_object.
+ *
+ * We use the given st_texture_image as a clue to determine the size of the
+ * mipmap image at level=0.
+ *
+ * \return GL_TRUE for success, GL_FALSE if out of memory.
+ */
+static GLboolean
+guess_and_alloc_texture(struct st_context *st,
+ struct st_texture_object *stObj,
+ const struct st_texture_image *stImage)
+{
+ GLuint lastLevel, width, height, depth;
+ GLuint bindings;
+ GLuint ptWidth, ptHeight, ptDepth, ptLayers;
+ enum pipe_format fmt;
+
+ DBG("%s\n", __FUNCTION__);
+
+ assert(!stObj->pt);
+
+ if (!guess_base_level_size(stObj->base.Target,
+ stImage->base.Width2,
+ stImage->base.Height2,
+ stImage->base.Depth2,
+ stImage->level,
+ &width, &height, &depth)) {
+ /* we can't determine the image size at level=0 */
+ stObj->width0 = stObj->height0 = stObj->depth0 = 0;
+ /* this is not an out of memory error */
+ return GL_TRUE;
+ }
+
+ /* At this point, (width x height x depth) is the expected size of
+ * the level=0 mipmap image.
+ */
+
+ /* Guess a reasonable value for lastLevel. With OpenGL we have no
+ * idea how many mipmap levels will be in a texture until we start
+ * to render with it. Make an educated guess here but be prepared
+ * to re-allocating a texture buffer with space for more (or fewer)
+ * mipmap levels later.
+ */
+ if ((stObj->base.MinFilter == GL_NEAREST ||
+ stObj->base.MinFilter == GL_LINEAR ||
+ stImage->base._BaseFormat == GL_DEPTH_COMPONENT ||
+ stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) &&
+ !stObj->base.GenerateMipmap &&
+ stImage->level == 0) {
+ /* only alloc space for a single mipmap level */
+ lastLevel = 0;
+ }
+ else {
+ /* alloc space for a full mipmap */
+ GLuint l2width = util_logbase2(width);
+ GLuint l2height = util_logbase2(height);
+ GLuint l2depth = util_logbase2(depth);
+ lastLevel = MAX2(MAX2(l2width, l2height), l2depth);
+ }
+
+ /* Save the level=0 dimensions */
+ stObj->width0 = width;
+ stObj->height0 = height;
+ stObj->depth0 = depth;
+
+ fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat);
+
+ bindings = default_bindings(st, fmt);
+
+ st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
+ width, height, depth,
+ &ptWidth, &ptHeight, &ptDepth, &ptLayers);
+
+ stObj->pt = st_texture_create(st,
+ gl_target_to_pipe(stObj->base.Target),
+ fmt,
+ lastLevel,
+ ptWidth,
+ ptHeight,
+ ptDepth,
+ ptLayers,
+ bindings);
+
+ DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
+
+ return stObj->pt != NULL;
+}
+
+
+/**
+ * Adjust pixel unpack params and image dimensions to strip off the
+ * texture border.
+ * Gallium doesn't support texture borders. They've seldem been used
+ * and seldom been implemented correctly anyway.
+ * \param unpackNew returns the new pixel unpack parameters
+ */
+static void
+strip_texture_border(GLint border,
+ GLint *width, GLint *height, GLint *depth,
+ const struct gl_pixelstore_attrib *unpack,
+ struct gl_pixelstore_attrib *unpackNew)
+{
+ assert(border > 0); /* sanity check */
+
+ *unpackNew = *unpack;
+
+ if (unpackNew->RowLength == 0)
+ unpackNew->RowLength = *width;
+
+ if (depth && unpackNew->ImageHeight == 0)
+ unpackNew->ImageHeight = *height;
+
+ unpackNew->SkipPixels += border;
+ if (height)
+ unpackNew->SkipRows += border;
+ if (depth)
+ unpackNew->SkipImages += border;
+
+ assert(*width >= 3);
+ *width = *width - 2 * border;
+ if (height && *height >= 3)
+ *height = *height - 2 * border;
+ if (depth && *depth >= 3)
+ *depth = *depth - 2 * border;
+}
+
+
+/**
+ * Do glTexImage1/2/3D().
+ */
+static void
+st_TexImage(struct gl_context * ctx,
+ GLint dims,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth,
+ GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *unpack,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ GLsizei imageSize, GLboolean compressed_src)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_texture_object *stObj = st_texture_object(texObj);
+ struct st_texture_image *stImage = st_texture_image(texImage);
+ GLuint dstRowStride = 0;
+ struct gl_pixelstore_attrib unpackNB;
+ enum pipe_transfer_usage transfer_usage = 0;
+
+ DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
+ _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
+
+ /* switch to "normal" */
+ if (stObj->surface_based) {
+ gl_format texFormat;
+
+ _mesa_clear_texture_object(ctx, texObj);
+ pipe_resource_reference(&stObj->pt, NULL);
+
+ /* oops, need to init this image again */
+ texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
+ internalFormat, format, type);
+
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ width, height, depth, border,
+ internalFormat, texFormat);
+
+ stObj->surface_based = GL_FALSE;
+ }
+
+ /* gallium does not support texture borders, strip it off */
+ if (border) {
+ strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB);
+ unpack = &unpackNB;
+ texImage->Width = width;
+ texImage->Height = height;
+ texImage->Depth = depth;
+ texImage->Border = 0;
+ border = 0;
+ }
+ else {
+ assert(texImage->Width == width);
+ assert(texImage->Height == height);
+ assert(texImage->Depth == depth);
+ }
+
+ stImage->face = _mesa_tex_target_to_face(target);
+ stImage->level = level;
+
+ _mesa_set_fetch_functions(texImage, dims);
+
+ /* Release the reference to a potentially orphaned buffer.
+ * Release any old malloced memory.
+ */
+ if (stImage->pt) {
+ pipe_resource_reference(&stImage->pt, NULL);
+ assert(!texImage->Data);
+ }
+ else if (texImage->Data) {
+ _mesa_align_free(texImage->Data);
+ }
+
+ /*
+ * See if the new image is somehow incompatible with the existing
+ * mipmap. If so, free the old mipmap.
+ */
+ if (stObj->pt) {
+ if (level > (GLint) stObj->pt->last_level ||
+ !st_texture_match_image(stObj->pt, &stImage->base,
+ stImage->face, stImage->level)) {
+ DBG("release it\n");
+ pipe_resource_reference(&stObj->pt, NULL);
+ assert(!stObj->pt);
+ pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ }
+ }
+
+ if (width == 0 || height == 0 || depth == 0) {
+ /* stop after freeing old image */
+ return;
+ }
+
+ if (!stObj->pt) {
+ if (!guess_and_alloc_texture(st, stObj, stImage)) {
+ /* Probably out of memory.
+ * Try flushing any pending rendering, then retry.
+ */
+ st_finish(st);
+ if (!guess_and_alloc_texture(st, stObj, stImage)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ return;
+ }
+ }
+ }
+
+ assert(!stImage->pt);
+
+ /* Check if this texture image can live inside the texture object's buffer.
+ * If so, store the image there. Otherwise the image will temporarily live
+ * in its own buffer.
+ */
+ if (stObj->pt &&
+ st_texture_match_image(stObj->pt, &stImage->base,
+ stImage->face, stImage->level)) {
+
+ pipe_resource_reference(&stImage->pt, stObj->pt);
+ assert(stImage->pt);
+ }
+
+ if (!stImage->pt)
+ DBG("XXX: Image did not fit into texture - storing in local memory!\n");
+
+ /* Pixel data may come from regular user memory or a PBO. For the later,
+ * do bounds checking and map the PBO to read pixels data from it.
+ *
+ * XXX we should try to use a GPU-accelerated path to copy the image data
+ * from the PBO to the texture.
+ */
+ if (compressed_src) {
+ pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
+ unpack,
+ "glCompressedTexImage");
+ }
+ else {
+ pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
+ format, type,
+ pixels, unpack, "glTexImage");
+ }
+
+ /* for a 1D array upload the image as a series of layer with height = 1 */
+ if (target == GL_TEXTURE_1D_ARRAY) {
+ depth = height;
+ height = 1;
+ }
+
+ /*
+ * Prepare to store the texture data. Either map the gallium texture buffer
+ * memory or malloc space for it.
+ */
+ if (stImage->pt) {
+ /* Store the image in the gallium texture memory buffer */
+ if (format == GL_DEPTH_COMPONENT &&
+ util_format_is_depth_and_stencil(stImage->pt->format))
+ transfer_usage = PIPE_TRANSFER_READ_WRITE;
+ else
+ transfer_usage = PIPE_TRANSFER_WRITE;
+
+ texImage->Data = st_texture_image_map(st, stImage, 0,
+ transfer_usage, 0, 0, width, height);
+ if(stImage->transfer)
+ dstRowStride = stImage->transfer->stride;
+ }
+ else {
+ /* Allocate regular memory and store the image there temporarily. */
+ GLuint imageSize = _mesa_format_image_size(texImage->TexFormat,
+ width, height, depth);
+ dstRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
+
+ texImage->Data = _mesa_align_malloc(imageSize, 16);
+ }
+
+ if (!texImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ return;
+ }
+
+ if (!pixels) {
+ /* We've allocated texture memory, but have no pixel data - all done. */
+ goto done;
+ }
+
+ DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
+ width, height, depth, width, dstRowStride);
+
+ /* Copy user texture image into the texture buffer.
+ */
+ if (compressed_src) {
+ const GLuint srcRowStride =
+ _mesa_format_row_stride(texImage->TexFormat, width);
+ if (dstRowStride == srcRowStride) {
+ memcpy(texImage->Data, pixels, imageSize);
+ }
+ else {
+ char *dst = texImage->Data;
+ const char *src = pixels;
+ GLuint i, bw, bh, lines;
+ _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
+ lines = (height + bh - 1) / bh;
+
+ for (i = 0; i < lines; ++i) {
+ memcpy(dst, src, srcRowStride);
+ dst += dstRowStride;
+ src += srcRowStride;
+ }
+ }
+ }
+ else {
+ const GLuint srcImageStride =
+ _mesa_image_image_stride(unpack, width, height, format, type);
+ GLint i;
+ const GLubyte *src = (const GLubyte *) pixels;
+
+ for (i = 0; i < depth; i++) {
+ if (!_mesa_texstore(ctx, dims,
+ texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ format, type, src, unpack)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ }
+
+ if (stImage->pt && i + 1 < depth) {
+ /* unmap this slice */
+ st_texture_image_unmap(st, stImage);
+ /* map next slice of 3D texture */
+ texImage->Data = st_texture_image_map(st, stImage, i + 1,
+ transfer_usage, 0, 0,
+ width, height);
+ src += srcImageStride;
+ }
+ }
+ }
+
+done:
+ _mesa_unmap_teximage_pbo(ctx, unpack);
+
+ if (stImage->pt && texImage->Data) {
+ st_texture_image_unmap(st, stImage);
+ texImage->Data = NULL;
+ }
+}
+
+
+static void
+st_TexImage3D(struct gl_context * ctx,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth,
+ GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *unpack,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ st_TexImage(ctx, 3, target, level, internalFormat, width, height, depth,
+ border, format, type, pixels, unpack, texObj, texImage,
+ 0, GL_FALSE);
+}
+
+
+static void
+st_TexImage2D(struct gl_context * ctx,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *unpack,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border,
+ format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
+}
+
+
+static void
+st_TexImage1D(struct gl_context * ctx,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *unpack,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ st_TexImage(ctx, 1, target, level, internalFormat, width, 1, 1, border,
+ format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
+}
+
+
+static void
+st_CompressedTexImage2D(struct gl_context *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border,
+ 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE);
+}
+
+
+
+/**
+ * glGetTexImage() helper: decompress a compressed texture by rendering
+ * a textured quad. Store the results in the user's buffer.
+ */
+static void
+decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct st_texture_image *stImage = st_texture_image(texImage);
+ struct st_texture_object *stObj = st_texture_object(texObj);
+ struct pipe_sampler_view *src_view =
+ st_get_texture_sampler_view(stObj, pipe);
+ const GLuint width = texImage->Width;
+ const GLuint height = texImage->Height;
+ struct pipe_surface *dst_surface;
+ struct pipe_resource *dst_texture;
+ struct pipe_transfer *tex_xfer;
+ unsigned bind = (PIPE_BIND_RENDER_TARGET | /* util_blit may choose to render */
+ PIPE_BIND_TRANSFER_READ);
+
+ /* create temp / dest surface */
+ if (!util_create_rgba_surface(pipe, width, height, bind,
+ &dst_texture, &dst_surface)) {
+ _mesa_problem(ctx, "util_create_rgba_surface() failed "
+ "in decompress_with_blit()");
+ return;
+ }
+
+ /* blit/render/decompress */
+ util_blit_pixels_tex(st->blit,
+ src_view, /* pipe_resource (src) */
+ 0, 0, /* src x0, y0 */
+ width, height, /* src x1, y1 */
+ dst_surface, /* pipe_surface (dst) */
+ 0, 0, /* dst x0, y0 */
+ width, height, /* dst x1, y1 */
+ 0.0, /* z */
+ PIPE_TEX_MIPFILTER_NEAREST);
+
+ /* map the dst_surface so we can read from it */
+ tex_xfer = pipe_get_transfer(st_context(ctx)->pipe,
+ dst_texture, 0, 0,
+ PIPE_TRANSFER_READ,
+ 0, 0, width, height);
+
+ pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
+
+ /* copy/pack data into user buffer */
+ if (st_equal_formats(stImage->pt->format, format, type)) {
+ /* memcpy */
+ const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format);
+ ubyte *map = pipe_transfer_map(pipe, tex_xfer);
+ GLuint row;
+ for (row = 0; row < height; row++) {
+ GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width,
+ height, format, type, row, 0);
+ memcpy(dest, map, bytesPerRow);
+ map += tex_xfer->stride;
+ }
+ pipe_transfer_unmap(pipe, tex_xfer);
+ }
+ else {
+ /* format translation via floats */
+ GLuint row;
+ enum pipe_format format = util_format_linear(dst_texture->format);
+ for (row = 0; row < height; row++) {
+ const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */
+ GLfloat rgba[4 * MAX_WIDTH];
+ GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width,
+ height, format, type, row, 0);
+
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s: fallback format translation\n", __FUNCTION__);
+
+ /* get float[4] rgba row from surface */
+ pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1,
+ format, rgba);
+
+ _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
+ type, dest, &ctx->Pack, transferOps);
+ }
+ }
+
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
+
+ pipe->transfer_destroy(pipe, tex_xfer);
+
+ /* destroy the temp / dest surface */
+ util_destroy_rgba_surface(dst_texture, dst_surface);
+}
+
+
+
+/**
+ * Need to map texture image into memory before copying image data,
+ * then unmap it.
+ */
+static void
+st_get_tex_image(struct gl_context * ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid * pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage, GLboolean compressed_dst)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_texture_image *stImage = st_texture_image(texImage);
+ const GLuint dstImageStride =
+ _mesa_image_image_stride(&ctx->Pack, texImage->Width, texImage->Height,
+ format, type);
+ GLuint depth, i;
+ GLubyte *dest;
+
+ if (stImage->pt &&
+ util_format_is_s3tc(stImage->pt->format) &&
+ !compressed_dst) {
+ /* Need to decompress the texture.
+ * We'll do this by rendering a textured quad.
+ * Note that we only expect RGBA formats (no Z/depth formats).
+ */
+ decompress_with_blit(ctx, target, level, format, type, pixels,
+ texObj, texImage);
+ return;
+ }
+
+ /* Map */
+ if (stImage->pt) {
+ /* Image is stored in hardware format in a buffer managed by the
+ * kernel. Need to explicitly map and unmap it.
+ */
+ texImage->Data = st_texture_image_map(st, stImage, 0,
+ PIPE_TRANSFER_READ, 0, 0,
+ stImage->base.Width,
+ stImage->base.Height);
+ /* compute stride in texels from stride in bytes */
+ texImage->RowStride = stImage->transfer->stride
+ * util_format_get_blockwidth(stImage->pt->format)
+ / util_format_get_blocksize(stImage->pt->format);
+ }
+ else {
+ /* Otherwise, the image should actually be stored in
+ * texImage->Data. This is pretty confusing for
+ * everybody, I'd much prefer to separate the two functions of
+ * texImage->Data - storage for texture images in main memory
+ * and access (ie mappings) of images. In other words, we'd
+ * create a new texImage->Map field and leave Data simply for
+ * storage.
+ */
+ assert(texImage->Data);
+ }
+
+ depth = texImage->Depth;
+ texImage->Depth = 1;
+
+ dest = (GLubyte *) pixels;
+
+ _mesa_set_fetch_functions(texImage, get_texture_dims(target));
+
+ for (i = 0; i < depth; i++) {
+ if (compressed_dst) {
+ _mesa_get_compressed_teximage(ctx, target, level, dest,
+ texObj, texImage);
+ }
+ else {
+ _mesa_get_teximage(ctx, target, level, format, type, dest,
+ texObj, texImage);
+ }
+
+ if (stImage->pt && i + 1 < depth) {
+ /* unmap this slice */
+ st_texture_image_unmap(st, stImage);
+ /* map next slice of 3D texture */
+ texImage->Data = st_texture_image_map(st, stImage, i + 1,
+ PIPE_TRANSFER_READ, 0, 0,
+ stImage->base.Width,
+ stImage->base.Height);
+ dest += dstImageStride;
+ }
+ }
+
+ texImage->Depth = depth;
+
+ /* Unmap */
+ if (stImage->pt) {
+ st_texture_image_unmap(st, stImage);
+ texImage->Data = NULL;
+ }
+}
+
+
+static void
+st_GetTexImage(struct gl_context * ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid * pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ st_get_tex_image(ctx, target, level, format, type, pixels, texObj, texImage,
+ GL_FALSE);
+}
+
+
+static void
+st_GetCompressedTexImage(struct gl_context *ctx, GLenum target, GLint level,
+ GLvoid *pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ st_get_tex_image(ctx, target, level, 0, 0, pixels, texObj, texImage,
+ GL_TRUE);
+}
+
+
+
+static void
+st_TexSubimage(struct gl_context *ctx, GLint dims, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint width, GLint height, GLint depth,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_texture_image *stImage = st_texture_image(texImage);
+ GLuint dstRowStride;
+ const GLuint srcImageStride =
+ _mesa_image_image_stride(packing, width, height, format, type);
+ GLint i;
+ const GLubyte *src;
+ /* init to silence warning only: */
+ enum pipe_transfer_usage transfer_usage = PIPE_TRANSFER_WRITE;
+
+ DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
+ _mesa_lookup_enum_by_nr(target),
+ level, xoffset, yoffset, width, height);
+
+ pixels =
+ _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
+ type, pixels, packing, "glTexSubImage2D");
+ if (!pixels)
+ return;
+
+ /* for a 1D array upload the image as a series of layer with height = 1 */
+ if (target == GL_TEXTURE_1D_ARRAY) {
+ depth = height;
+ height = 1;
+ }
+
+ /* Map buffer if necessary. Need to lock to prevent other contexts
+ * from uploading the buffer under us.
+ */
+ if (stImage->pt) {
+ if (format == GL_DEPTH_COMPONENT &&
+ util_format_is_depth_and_stencil(stImage->pt->format))
+ transfer_usage = PIPE_TRANSFER_READ_WRITE;
+ else
+ transfer_usage = PIPE_TRANSFER_WRITE;
+
+ texImage->Data = st_texture_image_map(st, stImage, zoffset,
+ transfer_usage,
+ xoffset, yoffset,
+ width, height);
+ }
+
+ if (!texImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
+ goto done;
+ }
+
+ src = (const GLubyte *) pixels;
+ dstRowStride = stImage->transfer->stride;
+
+ for (i = 0; i < depth; i++) {
+ if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ format, type, src, packing)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
+ }
+
+ if (stImage->pt && i + 1 < depth) {
+ /* unmap this slice */
+ st_texture_image_unmap(st, stImage);
+ /* map next slice of 3D texture */
+ texImage->Data = st_texture_image_map(st, stImage,
+ zoffset + i + 1,
+ transfer_usage,
+ xoffset, yoffset,
+ width, height);
+ src += srcImageStride;
+ }
+ }
+
+done:
+ _mesa_unmap_teximage_pbo(ctx, packing);
+
+ if (stImage->pt && texImage->Data) {
+ st_texture_image_unmap(st, stImage);
+ texImage->Data = NULL;
+ }
+}
+
+
+
+static void
+st_TexSubImage3D(struct gl_context *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ st_TexSubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type,
+ pixels, packing, texObj, texImage);
+}
+
+
+static void
+st_TexSubImage2D(struct gl_context *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ st_TexSubimage(ctx, 2, target, level, xoffset, yoffset, 0,
+ width, height, 1, format, type,
+ pixels, packing, texObj, texImage);
+}
+
+
+static void
+st_TexSubImage1D(struct gl_context *ctx, GLenum target, GLint level,
+ GLint xoffset, GLsizei width, GLenum format, GLenum type,
+ const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ st_TexSubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1,
+ format, type, pixels, packing, texObj, texImage);
+}
+
+
+static void
+st_CompressedTexSubImage1D(struct gl_context *ctx, GLenum target, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ assert(0);
+}
+
+
+static void
+st_CompressedTexSubImage2D(struct gl_context *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLint height,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_texture_image *stImage = st_texture_image(texImage);
+ int srcBlockStride;
+ int dstBlockStride;
+ int y;
+ enum pipe_format pformat;
+
+ if (stImage->pt) {
+ pformat = stImage->pt->format;
+
+ texImage->Data = st_texture_image_map(st, stImage, 0,
+ PIPE_TRANSFER_WRITE,
+ xoffset, yoffset,
+ width, height);
+
+ srcBlockStride = util_format_get_stride(pformat, width);
+ dstBlockStride = stImage->transfer->stride;
+ } else {
+ assert(stImage->pt);
+ /* TODO find good values for block and strides */
+ /* TODO also adjust texImage->data for yoffset/xoffset */
+ return;
+ }
+
+ if (!texImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage");
+ return;
+ }
+
+ assert(xoffset % util_format_get_blockwidth(pformat) == 0);
+ assert(yoffset % util_format_get_blockheight(pformat) == 0);
+
+ for (y = 0; y < height; y += util_format_get_blockheight(pformat)) {
+ /* don't need to adjust for xoffset and yoffset as st_texture_image_map does that */
+ const char *src = (const char*)data + srcBlockStride * util_format_get_nblocksy(pformat, y);
+ char *dst = (char*)texImage->Data + dstBlockStride * util_format_get_nblocksy(pformat, y);
+ memcpy(dst, src, util_format_get_stride(pformat, width));
+ }
+
+ if (stImage->pt) {
+ st_texture_image_unmap(st, stImage);
+ texImage->Data = NULL;
+ }
+}
+
+
+static void
+st_CompressedTexSubImage3D(struct gl_context *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLint height, GLint depth,
+ GLenum format,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ assert(0);
+}
+
+
+
+/**
+ * Do a CopyTexSubImage operation using a read transfer from the source,
+ * a write transfer to the destination and get_tile()/put_tile() to access
+ * the pixels/texels.
+ *
+ * Note: srcY=0=TOP of renderbuffer
+ */
+static void
+fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level,
+ struct st_renderbuffer *strb,
+ struct st_texture_image *stImage,
+ GLenum baseFormat,
+ GLint destX, GLint destY, GLint destZ,
+ GLint srcX, GLint srcY,
+ GLsizei width, GLsizei height)
+{
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_transfer *src_trans;
+ GLvoid *texDest;
+ enum pipe_transfer_usage transfer_usage;
+
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s: fallback processing\n", __FUNCTION__);
+
+ assert(width <= MAX_WIDTH);
+
+ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
+ srcY = strb->Base.Height - srcY - height;
+ }
+
+ src_trans = pipe_get_transfer(st_context(ctx)->pipe,
+ strb->texture,
+ 0, 0,
+ PIPE_TRANSFER_READ,
+ srcX, srcY,
+ width, height);
+
+ if ((baseFormat == GL_DEPTH_COMPONENT ||
+ baseFormat == GL_DEPTH_STENCIL) &&
+ util_format_is_depth_and_stencil(stImage->pt->format))
+ transfer_usage = PIPE_TRANSFER_READ_WRITE;
+ else
+ transfer_usage = PIPE_TRANSFER_WRITE;
+
+ /* XXX this used to ignore destZ param */
+ texDest = st_texture_image_map(st, stImage, destZ, transfer_usage,
+ destX, destY, width, height);
+
+ if (baseFormat == GL_DEPTH_COMPONENT ||
+ baseFormat == GL_DEPTH_STENCIL) {
+ const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
+ ctx->Pixel.DepthBias != 0.0F);
+ GLint row, yStep;
+
+ /* determine bottom-to-top vs. top-to-bottom order for src buffer */
+ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
+ srcY = height - 1;
+ yStep = -1;
+ }
+ else {
+ srcY = 0;
+ yStep = 1;
+ }
+
+ /* To avoid a large temp memory allocation, do copy row by row */
+ for (row = 0; row < height; row++, srcY += yStep) {
+ uint data[MAX_WIDTH];
+ pipe_get_tile_z(pipe, src_trans, 0, srcY, width, 1, data);
+ if (scaleOrBias) {
+ _mesa_scale_and_bias_depth_uint(ctx, width, data);
+ }
+ pipe_put_tile_z(pipe, stImage->transfer, 0, row, width, 1, data);
+ }
+ }
+ else {
+ /* RGBA format */
+ GLfloat *tempSrc =
+ (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+
+ if (tempSrc && texDest) {
+ const GLint dims = 2;
+ const GLint dstRowStride = stImage->transfer->stride;
+ struct gl_texture_image *texImage = &stImage->base;
+ struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
+
+ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
+ unpack.Invert = GL_TRUE;
+ }
+
+ /* get float/RGBA image from framebuffer */
+ /* XXX this usually involves a lot of int/float conversion.
+ * try to avoid that someday.
+ */
+ pipe_get_tile_rgba_format(pipe, src_trans, 0, 0, width, height,
+ util_format_linear(strb->texture->format),
+ tempSrc);
+
+ /* Store into texture memory.
+ * Note that this does some special things such as pixel transfer
+ * ops and format conversion. In particular, if the dest tex format
+ * is actually RGBA but the user created the texture as GL_RGB we
+ * need to fill-in/override the alpha channel with 1.0.
+ */
+ _mesa_texstore(ctx, dims,
+ texImage->_BaseFormat,
+ texImage->TexFormat,
+ texDest,
+ 0, 0, 0,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ GL_RGBA, GL_FLOAT, tempSrc, /* src */
+ &unpack);
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
+ }
+
+ if (tempSrc)
+ free(tempSrc);
+ }
+
+ st_texture_image_unmap(st, stImage);
+ pipe->transfer_destroy(pipe, src_trans);
+}
+
+
+
+/**
+ * If the format of the src renderbuffer and the format of the dest
+ * texture are compatible (in terms of blitting), return a TGSI writemask
+ * to be used during the blit.
+ * If the src/dest are incompatible, return 0.
+ */
+static unsigned
+compatible_src_dst_formats(struct gl_context *ctx,
+ const struct gl_renderbuffer *src,
+ const struct gl_texture_image *dst)
+{
+ /* Get logical base formats for the src and dest.
+ * That is, use the user-requested formats and not the actual, device-
+ * chosen formats.
+ * For example, the user may have requested an A8 texture but the
+ * driver may actually be using an RGBA texture format. When we
+ * copy/blit to that texture, we only want to copy the Alpha channel
+ * and not the RGB channels.
+ *
+ * Similarly, when the src FBO was created an RGB format may have been
+ * requested but the driver actually chose an RGBA format. In that case,
+ * we don't want to copy the undefined Alpha channel to the dest texture
+ * (it should be 1.0).
+ */
+ const GLenum srcFormat = _mesa_base_fbo_format(ctx, src->InternalFormat);
+ const GLenum dstFormat = _mesa_base_tex_format(ctx, dst->InternalFormat);
+
+ /**
+ * XXX when we have red-only and red/green renderbuffers we'll need
+ * to add more cases here (or implement a general-purpose routine that
+ * queries the existance of the R,G,B,A channels in the src and dest).
+ */
+ if (srcFormat == dstFormat) {
+ /* This is the same as matching_base_formats, which should
+ * always pass, as it did previously.
+ */
+ return TGSI_WRITEMASK_XYZW;
+ }
+ else if (srcFormat == GL_RGB && dstFormat == GL_RGBA) {
+ /* Make sure that A in the dest is 1. The actual src format
+ * may be RGBA and have undefined A values.
+ */
+ return TGSI_WRITEMASK_XYZ;
+ }
+ else if (srcFormat == GL_RGBA && dstFormat == GL_RGB) {
+ /* Make sure that A in the dest is 1. The actual dst format
+ * may be RGBA and will need A=1 to provide proper alpha values
+ * when sampled later.
+ */
+ return TGSI_WRITEMASK_XYZ;
+ }
+ else {
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s failed for src %s, dst %s\n",
+ __FUNCTION__,
+ _mesa_lookup_enum_by_nr(srcFormat),
+ _mesa_lookup_enum_by_nr(dstFormat));
+
+ /* Otherwise fail.
+ */
+ return 0;
+ }
+}
+
+
+
+/**
+ * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
+ * Note that the region to copy has already been clipped so we know we
+ * won't read from outside the source renderbuffer's bounds.
+ *
+ * Note: srcY=0=Bottom of renderbuffer (GL convention)
+ */
+static void
+st_copy_texsubimage(struct gl_context *ctx,
+ GLenum target, GLint level,
+ GLint destX, GLint destY, GLint destZ,
+ GLint srcX, GLint srcY,
+ GLsizei width, GLsizei height)
+{
+ struct gl_texture_unit *texUnit =
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_object *texObj =
+ _mesa_select_tex_object(ctx, texUnit, target);
+ struct gl_texture_image *texImage =
+ _mesa_select_tex_image(ctx, texObj, target, level);
+ struct st_texture_image *stImage = st_texture_image(texImage);
+ const GLenum texBaseFormat = texImage->_BaseFormat;
+ struct gl_framebuffer *fb = ctx->ReadBuffer;
+ struct st_renderbuffer *strb;
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ enum pipe_format dest_format, src_format;
+ GLboolean use_fallback = GL_TRUE;
+ GLboolean matching_base_formats;
+ GLuint format_writemask, sample_count;
+ struct pipe_surface *dest_surface = NULL;
+ GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
+
+ /* make sure finalize_textures has been called?
+ */
+ if (0) st_validate_state(st);
+
+ /* determine if copying depth or color data */
+ if (texBaseFormat == GL_DEPTH_COMPONENT ||
+ texBaseFormat == GL_DEPTH_STENCIL) {
+ strb = st_renderbuffer(fb->_DepthBuffer);
+ if (strb->Base.Wrapped) {
+ strb = st_renderbuffer(strb->Base.Wrapped);
+ }
+ }
+ else {
+ /* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
+ strb = st_renderbuffer(fb->_ColorReadBuffer);
+ }
+
+ if (!strb || !strb->surface || !stImage->pt) {
+ debug_printf("%s: null strb or stImage\n", __FUNCTION__);
+ return;
+ }
+
+ sample_count = strb->surface->texture->nr_samples;
+ /* I believe this would be legal, presumably would need to do a resolve
+ for color, and for depth/stencil spec says to just use one of the
+ depth/stencil samples per pixel? Need some transfer clarifications. */
+ assert(sample_count < 2);
+
+ if (srcX < 0) {
+ width -= -srcX;
+ destX += -srcX;
+ srcX = 0;
+ }
+
+ if (srcY < 0) {
+ height -= -srcY;
+ destY += -srcY;
+ srcY = 0;
+ }
+
+ if (destX < 0) {
+ width -= -destX;
+ srcX += -destX;
+ destX = 0;
+ }
+
+ if (destY < 0) {
+ height -= -destY;
+ srcY += -destY;
+ destY = 0;
+ }
+
+ if (width < 0 || height < 0)
+ return;
+
+
+ assert(strb);
+ assert(strb->surface);
+ assert(stImage->pt);
+
+ src_format = strb->surface->format;
+ dest_format = stImage->pt->format;
+
+ /*
+ * Determine if the src framebuffer and dest texture have the same
+ * base format. We need this to detect a case such as the framebuffer
+ * being GL_RGBA but the texture being GL_RGB. If the actual hardware
+ * texture format stores RGBA we need to set A=1 (overriding the
+ * framebuffer's alpha values). We can't do that with the blit or
+ * textured-quad paths.
+ */
+ matching_base_formats =
+ (_mesa_get_format_base_format(strb->Base.Format) ==
+ _mesa_get_format_base_format(texImage->TexFormat));
+ format_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage);
+
+ if (ctx->_ImageTransferState == 0x0) {
+
+ if (matching_base_formats &&
+ src_format == dest_format &&
+ !do_flip)
+ {
+ /* use surface_copy() / blit */
+ struct pipe_box src_box;
+ u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer,
+ width, height, &src_box);
+
+ /* for resource_copy_region(), y=0=top, always */
+ pipe->resource_copy_region(pipe,
+ /* dest */
+ stImage->pt,
+ stImage->level,
+ destX, destY, destZ + stImage->face,
+ /* src */
+ strb->texture,
+ strb->surface->u.tex.level,
+ &src_box);
+ use_fallback = GL_FALSE;
+ }
+ else if (format_writemask &&
+ texBaseFormat != GL_DEPTH_COMPONENT &&
+ texBaseFormat != GL_DEPTH_STENCIL &&
+ screen->is_format_supported(screen, src_format,
+ PIPE_TEXTURE_2D, sample_count,
+ PIPE_BIND_SAMPLER_VIEW,
+ 0) &&
+ screen->is_format_supported(screen, dest_format,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET,
+ 0)) {
+ /* draw textured quad to do the copy */
+ GLint srcY0, srcY1;
+ struct pipe_surface surf_tmpl;
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ surf_tmpl.format = stImage->pt->format;
+ surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+ surf_tmpl.u.tex.level = stImage->level;
+ surf_tmpl.u.tex.first_layer = stImage->face + destZ;
+ surf_tmpl.u.tex.last_layer = stImage->face + destZ;
+
+ dest_surface = pipe->create_surface(pipe, stImage->pt,
+ &surf_tmpl);
+
+ if (do_flip) {
+ srcY1 = strb->Base.Height - srcY - height;
+ srcY0 = srcY1 + height;
+ }
+ else {
+ srcY0 = srcY;
+ srcY1 = srcY0 + height;
+ }
+
+ util_blit_pixels_writemask(st->blit,
+ strb->texture,
+ strb->surface->u.tex.level,
+ srcX, srcY0,
+ srcX + width, srcY1,
+ strb->surface->u.tex.first_layer,
+ dest_surface,
+ destX, destY,
+ destX + width, destY + height,
+ 0.0, PIPE_TEX_MIPFILTER_NEAREST,
+ format_writemask);
+ use_fallback = GL_FALSE;
+ }
+
+ if (dest_surface)
+ pipe_surface_reference(&dest_surface, NULL);
+ }
+
+ if (use_fallback) {
+ /* software fallback */
+ fallback_copy_texsubimage(ctx, target, level,
+ strb, stImage, texBaseFormat,
+ destX, destY, destZ,
+ srcX, srcY, width, height);
+ }
+}
+
+
+
+static void
+st_CopyTexImage1D(struct gl_context * ctx, GLenum target, GLint level,
+ GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLint border)
+{
+ struct gl_texture_unit *texUnit =
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_object *texObj =
+ _mesa_select_tex_object(ctx, texUnit, target);
+ struct gl_texture_image *texImage =
+ _mesa_select_tex_image(ctx, texObj, target, level);
+
+ /* Setup or redefine the texture object, texture and texture
+ * image. Don't populate yet.
+ */
+ ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
+ width, border,
+ GL_RGBA, CHAN_TYPE, NULL,
+ &ctx->DefaultPacking, texObj, texImage);
+
+ st_copy_texsubimage(ctx, target, level,
+ 0, 0, 0, /* destX,Y,Z */
+ x, y, width, 1); /* src X, Y, size */
+}
+
+
+static void
+st_CopyTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
+ GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border)
+{
+ struct gl_texture_unit *texUnit =
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_object *texObj =
+ _mesa_select_tex_object(ctx, texUnit, target);
+ struct gl_texture_image *texImage =
+ _mesa_select_tex_image(ctx, texObj, target, level);
+
+ /* Setup or redefine the texture object, texture and texture
+ * image. Don't populate yet.
+ */
+ ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
+ width, height, border,
+ GL_RGBA, CHAN_TYPE, NULL,
+ &ctx->DefaultPacking, texObj, texImage);
+
+ st_copy_texsubimage(ctx, target, level,
+ 0, 0, 0, /* destX,Y,Z */
+ x, y, width, height); /* src X, Y, size */
+}
+
+
+static void
+st_CopyTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level,
+ GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+ const GLint yoffset = 0, zoffset = 0;
+ const GLsizei height = 1;
+ st_copy_texsubimage(ctx, target, level,
+ xoffset, yoffset, zoffset, /* destX,Y,Z */
+ x, y, width, height); /* src X, Y, size */
+}
+
+
+static void
+st_CopyTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ const GLint zoffset = 0;
+ st_copy_texsubimage(ctx, target, level,
+ xoffset, yoffset, zoffset, /* destX,Y,Z */
+ x, y, width, height); /* src X, Y, size */
+}
+
+
+static void
+st_CopyTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ st_copy_texsubimage(ctx, target, level,
+ xoffset, yoffset, zoffset, /* destX,Y,Z */
+ x, y, width, height); /* src X, Y, size */
+}
+
+
+/**
+ * Copy image data from stImage into the texture object 'stObj' at level
+ * 'dstLevel'.
+ */
+static void
+copy_image_data_to_texture(struct st_context *st,
+ struct st_texture_object *stObj,
+ GLuint dstLevel,
+ struct st_texture_image *stImage)
+{
+ /* debug checks */
+ {
+ const struct gl_texture_image *dstImage =
+ stObj->base.Image[stImage->face][stImage->level];
+ assert(dstImage);
+ assert(dstImage->Width == stImage->base.Width);
+ assert(dstImage->Height == stImage->base.Height);
+ assert(dstImage->Depth == stImage->base.Depth);
+ }
+
+ if (stImage->pt) {
+ /* Copy potentially with the blitter:
+ */
+ st_texture_image_copy(st->pipe,
+ stObj->pt, dstLevel, /* dest texture, level */
+ stImage->pt, stImage->level, /* src texture, level */
+ stImage->face);
+
+ pipe_resource_reference(&stImage->pt, NULL);
+ }
+ else if (stImage->base.Data) {
+ st_texture_image_data(st,
+ stObj->pt,
+ stImage->face,
+ dstLevel,
+ stImage->base.Data,
+ stImage->base.RowStride *
+ util_format_get_blocksize(stObj->pt->format),
+ stImage->base.RowStride *
+ stImage->base.Height *
+ util_format_get_blocksize(stObj->pt->format));
+ _mesa_align_free(stImage->base.Data);
+ stImage->base.Data = NULL;
+ }
+
+ pipe_resource_reference(&stImage->pt, stObj->pt);
+}
+
+
+/**
+ * Called during state validation. When this function is finished,
+ * the texture object should be ready for rendering.
+ * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
+ */
+GLboolean
+st_finalize_texture(struct gl_context *ctx,
+ struct pipe_context *pipe,
+ struct gl_texture_object *tObj)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_texture_object *stObj = st_texture_object(tObj);
+ const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
+ GLuint face;
+ struct st_texture_image *firstImage;
+ enum pipe_format firstImageFormat;
+ GLuint ptWidth, ptHeight, ptDepth, ptLayers;
+
+ if (stObj->base._Complete) {
+ /* The texture is complete and we know exactly how many mipmap levels
+ * are present/needed. This is conditional because we may be called
+ * from the st_generate_mipmap() function when the texture object is
+ * incomplete. In that case, we'll have set stObj->lastLevel before
+ * we get here.
+ */
+ if (stObj->base.MinFilter == GL_LINEAR ||
+ stObj->base.MinFilter == GL_NEAREST)
+ stObj->lastLevel = stObj->base.BaseLevel;
+ else
+ stObj->lastLevel = stObj->base._MaxLevel;
+ }
+
+ firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
+ assert(firstImage);
+
+ /* If both firstImage and stObj point to a texture which can contain
+ * all active images, favour firstImage. Note that because of the
+ * completeness requirement, we know that the image dimensions
+ * will match.
+ */
+ if (firstImage->pt &&
+ firstImage->pt != stObj->pt &&
+ (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
+ pipe_resource_reference(&stObj->pt, firstImage->pt);
+ pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ }
+
+ /* Find gallium format for the Mesa texture */
+ firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
+
+ /* Find size of level=0 Gallium mipmap image, plus number of texture layers */
+ {
+ GLuint width, height, depth;
+ if (!guess_base_level_size(stObj->base.Target,
+ firstImage->base.Width2,
+ firstImage->base.Height2,
+ firstImage->base.Depth2,
+ stObj->base.BaseLevel,
+ &width, &height, &depth)) {
+ width = stObj->width0;
+ height = stObj->height0;
+ depth = stObj->depth0;
+ }
+ /* convert GL dims to Gallium dims */
+ st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth,
+ &ptWidth, &ptHeight, &ptDepth, &ptLayers);
+ }
+
+ /* If we already have a gallium texture, check that it matches the texture
+ * object's format, target, size, num_levels, etc.
+ */
+ if (stObj->pt) {
+ if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
+ !st_sampler_compat_formats(stObj->pt->format, firstImageFormat) ||
+ stObj->pt->last_level < stObj->lastLevel ||
+ stObj->pt->width0 != ptWidth ||
+ stObj->pt->height0 != ptHeight ||
+ stObj->pt->depth0 != ptDepth ||
+ stObj->pt->array_size != ptLayers)
+ {
+ /* The gallium texture does not match the Mesa texture so delete the
+ * gallium texture now. We'll make a new one below.
+ */
+ pipe_resource_reference(&stObj->pt, NULL);
+ pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ st->dirty.st |= ST_NEW_FRAMEBUFFER;
+ }
+ }
+
+ /* May need to create a new gallium texture:
+ */
+ if (!stObj->pt) {
+ GLuint bindings = default_bindings(st, firstImageFormat);
+
+ stObj->pt = st_texture_create(st,
+ gl_target_to_pipe(stObj->base.Target),
+ firstImageFormat,
+ stObj->lastLevel,
+ ptWidth,
+ ptHeight,
+ ptDepth,
+ ptLayers,
+ bindings);
+
+ if (!stObj->pt) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ return GL_FALSE;
+ }
+ }
+
+ /* Pull in any images not in the object's texture:
+ */
+ for (face = 0; face < nr_faces; face++) {
+ GLuint level;
+ for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) {
+ struct st_texture_image *stImage =
+ st_texture_image(stObj->base.Image[face][level]);
+
+ /* Need to import images in main memory or held in other textures.
+ */
+ if (stImage && stObj->pt != stImage->pt) {
+ copy_image_data_to_texture(st, stObj, level, stImage);
+ }
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Returns pointer to a default/dummy texture.
+ * This is typically used when the current shader has tex/sample instructions
+ * but the user has not provided a (any) texture(s).
+ */
+struct gl_texture_object *
+st_get_default_texture(struct st_context *st)
+{
+ if (!st->default_texture) {
+ static const GLenum target = GL_TEXTURE_2D;
+ GLubyte pixels[16][16][4];
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImg;
+ GLuint i, j;
+
+ /* The ARB_fragment_program spec says (0,0,0,1) should be returned
+ * when attempting to sample incomplete textures.
+ */
+ for (i = 0; i < 16; i++) {
+ for (j = 0; j < 16; j++) {
+ pixels[i][j][0] = 0;
+ pixels[i][j][1] = 0;
+ pixels[i][j][2] = 0;
+ pixels[i][j][3] = 255;
+ }
+ }
+
+ texObj = st->ctx->Driver.NewTextureObject(st->ctx, 0, target);
+
+ texImg = _mesa_get_tex_image(st->ctx, texObj, target, 0);
+
+ _mesa_init_teximage_fields(st->ctx, target, texImg,
+ 16, 16, 1, 0, /* w, h, d, border */
+ GL_RGBA, MESA_FORMAT_RGBA8888);
+
+ st_TexImage(st->ctx, 2, target,
+ 0, GL_RGBA, /* level, intformat */
+ 16, 16, 1, 0, /* w, h, d, border */
+ GL_RGBA, GL_UNSIGNED_BYTE, pixels,
+ &st->ctx->DefaultPacking,
+ texObj, texImg,
+ 0, 0);
+
+ texObj->MinFilter = GL_NEAREST;
+ texObj->MagFilter = GL_NEAREST;
+ texObj->_Complete = GL_TRUE;
+
+ st->default_texture = texObj;
+ }
+ return st->default_texture;
+}
+
+
+void
+st_init_texture_functions(struct dd_function_table *functions)
+{
+ functions->ChooseTextureFormat = st_ChooseTextureFormat;
+ functions->TexImage1D = st_TexImage1D;
+ functions->TexImage2D = st_TexImage2D;
+ functions->TexImage3D = st_TexImage3D;
+ functions->TexSubImage1D = st_TexSubImage1D;
+ functions->TexSubImage2D = st_TexSubImage2D;
+ functions->TexSubImage3D = st_TexSubImage3D;
+ functions->CompressedTexSubImage1D = st_CompressedTexSubImage1D;
+ functions->CompressedTexSubImage2D = st_CompressedTexSubImage2D;
+ functions->CompressedTexSubImage3D = st_CompressedTexSubImage3D;
+ functions->CopyTexImage1D = st_CopyTexImage1D;
+ functions->CopyTexImage2D = st_CopyTexImage2D;
+ functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
+ functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
+ functions->CopyTexSubImage3D = st_CopyTexSubImage3D;
+ functions->GenerateMipmap = st_generate_mipmap;
+
+ functions->GetTexImage = st_GetTexImage;
+
+ /* compressed texture functions */
+ functions->CompressedTexImage2D = st_CompressedTexImage2D;
+ functions->GetCompressedTexImage = st_GetCompressedTexImage;
+
+ functions->NewTextureObject = st_NewTextureObject;
+ functions->NewTextureImage = st_NewTextureImage;
+ functions->DeleteTexture = st_DeleteTextureObject;
+ functions->FreeTexImageData = st_FreeTextureImageData;
+
+ functions->TextureMemCpy = do_memcpy;
+
+ /* XXX Temporary until we can query pipe's texture sizes */
+ functions->TestProxyTexImage = _mesa_test_proxy_teximage;
+}
diff --git a/xorg-server/xkeyboard-config/rules/base.xml.in b/xorg-server/xkeyboard-config/rules/base.xml.in
index a870a24fc..1f4e66896 100644
--- a/xorg-server/xkeyboard-config/rules/base.xml.in
+++ b/xorg-server/xkeyboard-config/rules/base.xml.in
@@ -1,6155 +1,6195 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE xkbConfigRegistry SYSTEM "xkb.dtd">
-<xkbConfigRegistry version="1.1">
- <modelList>
- <model>
- <configItem>
- <name>pc101</name>
- <_description>Generic 101-key PC</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>pc102</name>
- <_description>Generic 102-key (Intl) PC</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>pc104</name>
- <_description>Generic 104-key PC</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>pc105</name>
- <_description>Generic 105-key (Intl) PC</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dell101</name>
- <_description>Dell 101-key PC</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>latitude</name>
- <_description>Dell Latitude series laptop</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dellm65</name>
- <_description>Dell Precision M65</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>everex</name>
- <_description>Everex STEPnote</_description>
- <vendor>Everex</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>flexpro</name>
- <_description>Keytronic FlexPro</_description>
- <vendor>Keytronic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoft</name>
- <_description>Microsoft Natural</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>omnikey101</name>
- <_description>Northgate OmniKey 101</_description>
- <vendor>Northgate</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>winbook</name>
- <_description>Winbook Model XP5</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>pc98</name>
- <_description>PC-98xx Series</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>a4techKB21</name>
- <_description>A4Tech KB-21</_description>
- <vendor>A4Tech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>a4techKBS8</name>
- <_description>A4Tech KBS-8</_description>
- <vendor>A4Tech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>a4_rfkb23</name>
- <_description>A4Tech Wireless Desktop RFKB-23</_description>
- <vendor>A4Tech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>airkey</name>
- <_description>Acer AirKey V</_description>
- <vendor>Acer</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>azonaRF2300</name>
- <_description>Azona RF2300 wireless Internet Keyboard</_description>
- <vendor>Azona</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>scorpius</name>
- <_description>Advance Scorpius KI</_description>
- <vendor>Scorpius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>brother</name>
- <_description>Brother Internet Keyboard</_description>
- <vendor>Brother</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc5113rf</name>
- <_description>BTC 5113RF Multimedia</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc5126t</name>
- <_description>BTC 5126T</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc6301urf</name>
- <_description>BTC 6301URF</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc9000</name>
- <_description>BTC 9000</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc9000a</name>
- <_description>BTC 9000A</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc9001ah</name>
- <_description>BTC 9001AH</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc5090</name>
- <_description>BTC 5090</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc9019u</name>
- <_description>BTC 9019U</_description>
- <vendor>BTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>btc9116u</name>
- <_description>BTC 9116U Mini Wireless Internet and Gaming</_description>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherryblue</name>
- <_description>Cherry Blue Line CyBo@rd</_description>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherryblueb</name>
- <_description>Cherry CyMotion Master XPress</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherrybluea</name>
- <_description>Cherry Blue Line CyBo@rd (alternate option)</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherrycyboard</name>
- <_description>Cherry CyBo@rd USB-Hub</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherrycmexpert</name>
- <_description>Cherry CyMotion Expert</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cherrybunlim</name>
- <_description>Cherry B.UNLIMITED</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>chicony</name>
- <_description>Chicony Internet Keyboard</_description>
- <vendor>Chicony</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>chicony0108</name>
- <_description>Chicony KU-0108</_description>
- <vendor>Chicony</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>chicony0420</name>
- <_description>Chicony KU-0420</_description>
- <vendor>Chicony</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>chicony9885</name>
- <_description>Chicony KB-9885</_description>
- <vendor>Chicony</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>compaqeak8</name>
- <_description>Compaq Easy Access Keyboard</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>compaqik7</name>
- <_description>Compaq Internet Keyboard (7 keys)</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>compaqik13</name>
- <_description>Compaq Internet Keyboard (13 keys)</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>compaqik18</name>
- <_description>Compaq Internet Keyboard (18 keys)</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>cymotionlinux</name>
- <_description>Cherry CyMotion Master Linux</_description>
- <vendor>Cherry</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>armada</name>
- <_description>Laptop/notebook Compaq (eg. Armada) Laptop Keyboard</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>presario</name>
- <_description>Laptop/notebook Compaq (eg. Presario) Internet Keyboard</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>ipaq</name>
- <_description>Compaq iPaq Keyboard</_description>
- <vendor>Compaq</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dell</name>
- <_description>Dell</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dellsk8125</name>
- <_description>Dell SK-8125</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dellsk8135</name>
- <_description>Dell SK-8135</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dellusbmm</name>
- <_description>Dell USB Multimedia Keyboard</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>inspiron</name>
- <_description>Dell Laptop/notebook Inspiron 6xxx/8xxx</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>precision_m</name>
- <_description>Dell Laptop/notebook Precision M series</_description>
- <vendor>Dell</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dexxa</name>
- <_description>Dexxa Wireless Desktop Keyboard</_description>
- <vendor>Dexxa</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>diamond</name>
- <_description>Diamond 9801 / 9802 series</_description>
- <vendor>Diamond</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>dtk2000</name>
- <_description>DTK2000</_description>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>ennyah_dkb1008</name>
- <_description>Ennyah DKB-1008</_description>
- <vendor>Ennyah</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>fscaa1667g</name>
- <_description>Fujitsu-Siemens Computers AMILO laptop</_description>
- <vendor>Fujitsu-Siemens</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>genius</name>
- <_description>Genius Comfy KB-16M / Genius MM Keyboard KWD-910</_description>
- <vendor>Genius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>geniuscomfy</name>
- <_description>Genius Comfy KB-12e</_description>
- <vendor>Genius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>geniuscomfy2</name>
- <_description>Genius Comfy KB-21e-Scroll</_description>
- <vendor>Genius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>geniuskb19e</name>
- <_description>Genius KB-19e NB</_description>
- <vendor>Genius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>geniuskkb2050hs</name>
- <_description>Genius KKB-2050HS</_description>
- <vendor>Genius</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>gyration</name>
- <_description>Gyration</_description>
- <vendor>Gyration</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>htcdream</name>
- <_description>HTC Dream</_description>
- <vendor>HTC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>kinesis</name>
- <_description>Kinesis</_description>
- <vendor>Kinesis</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logitech_base</name>
- <_description>Logitech Generic Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logitech_g15</name>
- <_description>Logitech G15 extra keys via G15daemon</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpi6</name>
- <_description>Hewlett-Packard Internet Keyboard</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hp250x</name>
- <_description>Hewlett-Packard SK-250x Multimedia Keyboard</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpxe3gc</name>
- <_description>Hewlett-Packard Omnibook XE3 GC</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpxe3gf</name>
- <_description>Hewlett-Packard Omnibook XE3 GF</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpxt1000</name>
- <_description>Hewlett-Packard Omnibook XT1000</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpdv5</name>
- <_description>Hewlett-Packard Pavilion dv5</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpzt11xx</name>
- <_description>Hewlett-Packard Pavilion ZT11xx</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hp500fa</name>
- <_description>Hewlett-Packard Omnibook 500 FA</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hp5xx</name>
- <_description>Hewlett-Packard Omnibook 5xx</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpnx9020</name>
- <_description>Hewlett-Packard nx9020</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hp6000</name>
- <_description>Hewlett-Packard Omnibook 6000/6100</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>honeywell_euroboard</name>
- <_description>Honeywell Euroboard</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hpmini110</name>
- <_description>Hewlett-Packard Mini 110 Notebook</_description>
- <vendor>Hewlett-Packard</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>rapidaccess</name>
- <_description>IBM Rapid Access</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>rapidaccess2</name>
- <_description>IBM Rapid Access II</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>thinkpad</name>
- <_description>IBM ThinkPad 560Z/600/600E/A22E</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>thinkpad60</name>
- <_description>IBM ThinkPad R60/T60/R61/T61</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>thinkpadz60</name>
- <_description>IBM ThinkPad Z60m/Z60t/Z61m/Z61t</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>ibm_spacesaver</name>
- <_description>IBM Space Saver</_description>
- <vendor>Lenovo (previously IBM)</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiaccess</name>
- <_description>Logitech Access Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiclx300</name>
- <_description>Logitech Cordless Desktop LX-300</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logii350</name>
- <_description>Logitech Internet 350 Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logimel</name>
- <_description>Logitech Media Elite Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicd</name>
- <_description>Logitech Cordless Desktop</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicd_it</name>
- <_description>Logitech Cordless Desktop iTouch</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicd_nav</name>
- <_description>Logitech Cordless Desktop Navigator</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicd_opt</name>
- <_description>Logitech Cordless Desktop Optical</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicda</name>
- <_description>Logitech Cordless Desktop (alternate option)</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicdpa2</name>
- <_description>Logitech Cordless Desktop Pro (alternate option 2)</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicfn</name>
- <_description>Logitech Cordless Freedom/Desktop Navigator</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicdn</name>
- <_description>Logitech Cordless Desktop Navigator</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiitc</name>
- <_description>Logitech iTouch Cordless Keyboard (model Y-RB6)</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiik</name>
- <_description>Logitech Internet Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>itouch</name>
- <_description>Logitech iTouch</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logicink</name>
- <_description>Logitech Internet Navigator Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiex110</name>
- <_description>Logitech Cordless Desktop EX110</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiinkse</name>
- <_description>Logitech iTouch Internet Navigator Keyboard SE</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiinkseusb</name>
- <_description>Logitech iTouch Internet Navigator Keyboard SE (USB)</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiultrax</name>
- <_description>Logitech Ultra-X Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logiultraxc</name>
- <_description>Logitech Ultra-X Cordless Media Desktop Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logidinovo</name>
- <_description>Logitech diNovo Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>logidinovoedge</name>
- <_description>Logitech diNovo Edge Keyboard</_description>
- <vendor>Logitech</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>mx1998</name>
- <_description>Memorex MX1998</_description>
- <vendor>Memorex</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>mx2500</name>
- <_description>Memorex MX2500 EZ-Access Keyboard</_description>
- <vendor>Memorex</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>mx2750</name>
- <_description>Memorex MX2750</_description>
- <vendor>Memorex</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoft7000</name>
- <_description>Microsoft Natural Wireless Ergonomic Keyboard 7000</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftinet</name>
- <_description>Microsoft Internet Keyboard</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftpro</name>
- <_description>Microsoft Natural Keyboard Pro / Microsoft Internet Keyboard Pro</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftprousb</name>
- <_description>Microsoft Natural Keyboard Pro USB / Microsoft Internet Keyboard Pro</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftprooem</name>
- <_description>Microsoft Natural Keyboard Pro OEM</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>vsonku306</name>
- <_description>ViewSonic KU-306 Internet Keyboard</_description>
- <vendor>ViewSonic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftprose</name>
- <_description>Microsoft Internet Keyboard Pro, Swedish</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftoffice</name>
- <_description>Microsoft Office Keyboard</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftmult</name>
- <_description>Microsoft Wireless Multimedia Keyboard 1.0A</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftelite</name>
- <_description>Microsoft Natural Keyboard Elite</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>microsoftccurve2k</name>
- <_description>Microsoft Comfort Curve Keyboard 2000</_description>
- <vendor>Microsoft Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>oretec</name>
- <_description>Ortek MCK-800 MM/Internet keyboard</_description>
- <vendor>Ortek</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>propeller</name>
- <_description>Propeller Voyager (KTEZ-1000)</_description>
- <vendor>KeyTronic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>qtronix</name>
- <_description>QTronix Scorpius 98N+</_description>
- <vendor>QTronix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>samsung4500</name>
- <_description>Samsung SDM 4500P</_description>
- <vendor>Samsung</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>samsung4510</name>
- <_description>Samsung SDM 4510P</_description>
- <vendor>Samsung</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sanwaskbkg3</name>
- <_description>Sanwa Supply SKB-KG3</_description>
- <vendor>Sanwa Supply Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sk1300</name>
- <_description>SK-1300</_description>
- <vendor>NEC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sk2500</name>
- <_description>SK-2500</_description>
- <vendor>NEC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sk6200</name>
- <_description>SK-6200</_description>
- <vendor>NEC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sk7100</name>
- <_description>SK-7100</_description>
- <vendor>NEC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sp_inet</name>
- <_description>Super Power Multimedia Keyboard</_description>
- <vendor>Generic</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sven</name>
- <_description>SVEN Ergonomic 2500</_description>
- <vendor>SVEN</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sven303</name>
- <_description>SVEN Slim 303</_description>
- <vendor>SVEN</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>symplon</name>
- <_description>Symplon PaceBook (tablet PC)</_description>
- <vendor>Symplon</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>toshiba_s3000</name>
- <_description>Toshiba Satellite S3000</_description>
- <vendor>Toshiba</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>trust</name>
- <_description>Trust Wireless Keyboard Classic</_description>
- <vendor>Trust</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>trustda</name>
- <_description>Trust Direct Access Keyboard</_description>
- <vendor>Trust</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>trust_slimline</name>
- <_description>Trust Slimline</_description>
- <vendor>Trust</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>tm2020</name>
- <_description>TypeMatrix EZ-Reach 2020</_description>
- <vendor>TypeMatrix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>tm2030PS2</name>
- <_description>TypeMatrix EZ-Reach 2030 PS2</_description>
- <vendor>TypeMatrix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>tm2030USB</name>
- <_description>TypeMatrix EZ-Reach 2030 USB</_description>
- <vendor>TypeMatrix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>tm2030USB-102</name>
- <_description>TypeMatrix EZ-Reach 2030 USB (102/105:EU mode)</_description>
- <vendor>TypeMatrix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>tm2030USB-106</name>
- <_description>TypeMatrix EZ-Reach 2030 USB (106:JP mode)</_description>
- <vendor>TypeMatrix</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>yahoo</name>
- <_description>Yahoo! Internet Keyboard</_description>
- <vendor>Yahoo!</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>macbook78</name>
- <_description>MacBook/MacBook Pro</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>macbook79</name>
- <_description>MacBook/MacBook Pro (Intl)</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>macintosh</name>
- <_description>Macintosh</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>macintosh_old</name>
- <_description>Macintosh Old</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>macintosh_hhk</name>
- <_description>Happy Hacking Keyboard for Mac</_description>
- <vendor>Fujitsu</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>acer_c300</name>
- <_description>Acer C300</_description>
- <vendor>Acer</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>acer_ferrari4k</name>
- <_description>Acer Ferrari 4000</_description>
- <vendor>Acer</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>acer_laptop</name>
- <_description>Acer Laptop</_description>
- <vendor>Acer</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>asus_laptop</name>
- <_description>Asus Laptop</_description>
- <vendor>Asus</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>apple</name>
- <_description>Apple</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>apple_laptop</name>
- <_description>Apple Laptop</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>applealu_ansi</name>
- <_description>Apple Aluminium Keyboard (ANSI)</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>applealu_iso</name>
- <_description>Apple Aluminium Keyboard (ISO)</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>applealu_jis</name>
- <_description>Apple Aluminium Keyboard (JIS)</_description>
- <vendor>Apple</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>silvercrest</name>
- <_description>SILVERCREST Multimedia Wireless Keyboard</_description>
- <vendor>Silvercrest</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>emachines</name>
- <_description>Laptop/notebook eMachines m68xx</_description>
- <vendor>eMachines</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>benqx</name>
- <_description>BenQ X-Touch</_description>
- <vendor>BenQ</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>benqx730</name>
- <_description>BenQ X-Touch 730</_description>
- <vendor>BenQ</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>benqx800</name>
- <_description>BenQ X-Touch 800</_description>
- <vendor>BenQ</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>hhk</name>
- <_description>Happy Hacking Keyboard</_description>
- <vendor>Fujitsu</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>classmate</name>
- <_description>Classmate PC</_description>
- <vendor>Intel</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>olpc</name>
- <_description>OLPC</_description>
- <vendor>OLPC</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>sun6</name>
- <_description>Sun Type 5/6</_description>
- <vendor>Sun Microsystems</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>targa_v811</name>
- <_description>Targa Visionary 811</_description>
- <vendor>Targa</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>unitekkb1925</name>
- <_description>Unitek KB-1925</_description>
- <vendor>Unitek Group</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>compalfl90</name>
- <_description>FL90</_description>
- <vendor>Compal Electronics Inc.</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>creativedw7000</name>
- <_description>Creative Desktop Wireless 7000</_description>
- <vendor>Creative</vendor>
- </configItem>
- </model>
- <model>
- <configItem>
- <name>htcdream</name>
- <_description>Htc Dream phone</_description>
- <vendor>htc</vendor>
- </configItem>
- </model>
- </modelList>
- <layoutList>
- <layout>
- <configItem>
- <name>us</name>
- <_shortDescription>USA</_shortDescription>
- <_description>USA</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>chr</name>
- <_description>USA - Cherokee</_description>
- <languageList>
- <iso639Id>chr</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>euro</name>
- <_description>USA - With EuroSign on 5</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>intl</name>
- <_description>USA - International (with dead keys)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>alt-intl</name>
- <_description>USA - Alternative international</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>colemak</name>
- <_description>USA - Colemak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>USA - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-intl</name>
- <_description>USA - Dvorak international (with dead keys)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-alt-intl</name>
- <_description>USA - Dvorak alternative international (no dead keys)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-l</name>
- <_description>USA - Left handed Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-r</name>
- <_description>USA - Right handed Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-classic</name>
- <_description>USA - Classic Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvp</name>
- <_description>USA - Programmer Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rus</name>
- <_description>USA - Russian phonetic</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>USA - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>altgr-intl</name>
- <_description>USA - International (AltGr dead keys)</_description>
- <languageList><iso639Id>eng</iso639Id>
- <iso639Id>fra</iso639Id>
- <iso639Id>ger</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>olpc2</name>
- <_description>USA - Layout toggle on multiply/divide key</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>hbs</name>
- <_description>USA - Serbo-Croatian</_description>
- <languageList><iso639Id>eng</iso639Id>
- <iso639Id>bos</iso639Id>
- <iso639Id>hbs</iso639Id>
- <iso639Id>hrv</iso639Id>
- <iso639Id>srp</iso639Id> </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ad</name>
- <_shortDescription>And</_shortDescription>
- <_description>Andorra</_description>
- <languageList>
- <iso639Id>cat</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>af</name>
- <_shortDescription>Afg</_shortDescription>
- <_description>Afghanistan</_description>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>ps</name>
- <_description>Afghanistan - Pashto</_description>
- <languageList>
- <iso639Id>pus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>uz</name>
- <_description>Afghanistan - Southern Uzbek</_description>
- <languageList>
- <iso639Id>uzb</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>olpc-ps</name>
- <_description>Afghanistan - OLPC Pashto</_description>
- <languageList>
- <iso639Id>pus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fa-olpc</name>
- <_description>Afghanistan - OLPC Dari</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>uz-olpc</name>
- <_description>Afghanistan - OLPC Southern Uzbek</_description>
- <languageList>
- <iso639Id>uzb</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ara</name>
- <_shortDescription>Ara</_shortDescription>
- <_description>Arabic</_description>
- <countryList>
- <iso3166Id>AE</iso3166Id>
- <iso3166Id>BH</iso3166Id>
- <iso3166Id>DZ</iso3166Id>
- <iso3166Id>EG</iso3166Id>
- <iso3166Id>EH</iso3166Id>
- <iso3166Id>JO</iso3166Id>
- <iso3166Id>KW</iso3166Id>
- <iso3166Id>LB</iso3166Id>
- <iso3166Id>LY</iso3166Id>
- <iso3166Id>MA</iso3166Id>
- <iso3166Id>MR</iso3166Id>
- <iso3166Id>OM</iso3166Id>
- <iso3166Id>PS</iso3166Id>
- <iso3166Id>QA</iso3166Id>
- <iso3166Id>SA</iso3166Id>
- <iso3166Id>SD</iso3166Id>
- <iso3166Id>SY</iso3166Id>
- <iso3166Id>TN</iso3166Id>
- <iso3166Id>YE</iso3166Id>
- </countryList>
- <languageList>
- <iso639Id>ara</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>azerty</name>
- <_description>Arabic - azerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>azerty_digits</name>
- <_description>Arabic - azerty/digits</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>digits</name>
- <_description>Arabic - digits</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty</name>
- <_description>Arabic - qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty_digits</name>
- <_description>Arabic - qwerty/digits</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>buckwalter</name>
- <_description>Arabic - Buckwalter</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>al</name>
- <_shortDescription>Alb</_shortDescription>
- <_description>Albania</_description>
- <languageList>
- <iso639Id>alb</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>am</name>
- <_shortDescription>Arm</_shortDescription>
- <_description>Armenia</_description>
- <languageList>
- <iso639Id>hye</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Armenia - Phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>phonetic-alt</name>
- <_description>Armenia - Alternative Phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>eastern</name>
- <_description>Armenia - Eastern</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>western</name>
- <_description>Armenia - Western</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>eastern-alt</name>
- <_description>Armenia - Alternative Eastern</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>at</name>
- <_shortDescription>Aut</_shortDescription>
- <_description>Austria</_description>
- <languageList>
- <iso639Id>ger</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Austria - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Austria - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Austria - Macintosh</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>az</name>
- <_shortDescription>Aze</_shortDescription>
- <_description>Azerbaijan</_description>
- <languageList>
- <iso639Id>aze</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>cyrillic</name>
- <_description>Azerbaijan - Cyrillic</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>by</name>
- <_shortDescription>Blr</_shortDescription>
- <_description>Belarus</_description>
- <languageList>
- <iso639Id>bel</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Belarus - Legacy</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latin</name>
- <_description>Belarus - Latin</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>be</name>
- <_shortDescription>Bel</_shortDescription>
- <_description>Belgium</_description>
- <languageList><iso639Id>ger</iso639Id>
- <iso639Id>nld</iso639Id>
- <iso639Id>fra</iso639Id></languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>oss</name>
- <_description>Belgium - Alternative</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss_latin9</name>
- <_description>Belgium - Alternative, latin-9 only</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss_sundeadkeys</name>
- <_description>Belgium - Alternative, Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>iso-alternate</name>
- <_description>Belgium - ISO Alternate</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Belgium - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Belgium - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>wang</name>
- <_description>Belgium - Wang model 724 azerty</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>bd</name>
- <_shortDescription>Bgd</_shortDescription>
- <_description>Bangladesh</_description>
- <languageList>
- <iso639Id>ben</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>probhat</name>
- <_description>Bangladesh - Probhat</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>in</name>
- <_shortDescription>Ind</_shortDescription>
- <_description>India</_description>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>ben</name>
- <_description>India - Bengali</_description>
- <languageList>
- <iso639Id>ben</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ben_probhat</name>
- <_description>India - Bengali Probhat</_description>
- <languageList>
- <iso639Id>ben</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>guj</name>
- <_description>India - Gujarati</_description>
- <languageList>
- <iso639Id>guj</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>guru</name>
- <_description>India - Gurmukhi</_description>
- <languageList>
- <iso639Id>pan</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>jhelum</name>
- <_description>India - Gurmukhi Jhelum</_description>
- <languageList>
- <iso639Id>pan</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>kan</name>
- <_description>India - Kannada</_description>
- <languageList>
- <iso639Id>kan</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mal</name>
- <_description>India - Malayalam</_description>
- <languageList>
- <iso639Id>mal</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mal_lalitha</name>
- <_description>India - Malayalam Lalitha</_description>
- <languageList>
- <iso639Id>mal</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ori</name>
- <_description>India - Oriya</_description>
- <languageList>
- <iso639Id>ori</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam_unicode</name>
- <_description>India - Tamil Unicode</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam_keyboard_with_numerals</name>
- <_description>India - Tamil Keyboard with Numerals</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam_TAB</name>
- <_description>India - Tamil TAB Typewriter</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam_TSCII</name>
- <_description>India - Tamil TSCII Typewriter</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam</name>
- <_description>India - Tamil</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tel</name>
- <_description>India - Telugu</_description>
- <languageList>
- <iso639Id>tel</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>urd-phonetic</name>
- <_description>India - Urdu, Phonetic</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>urd-phonetic3</name>
- <_description>India - Urdu, Alternative phonetic</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>urd-winkeys</name>
- <_description>India - Urdu, Winkeys</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bolnagri</name>
- <_description>India - Hindi Bolnagri</_description>
- <languageList>
- <iso639Id>hin</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>hin-wx</name>
- <_description>India - Hindi Wx</_description>
- <languageList>
- <iso639Id>hin</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>eng</name>
- <_description>India - English with RupeeSign</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ba</name>
- <_shortDescription>Bih</_shortDescription>
- <_description>Bosnia and Herzegovina</_description>
- <languageList>
- <iso639Id>bos</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>alternatequotes</name>
- <_description>Bosnia and Herzegovina - Use guillemets for quotes</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>unicode</name>
- <_description>Bosnia and Herzegovina - Use Bosnian digraphs</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>unicodeus</name>
- <_description>Bosnia and Herzegovina - US keyboard with Bosnian digraphs</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Bosnia and Herzegovina - US keyboard with Bosnian letters</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>br</name>
- <_shortDescription>Bra</_shortDescription>
- <_description>Brazil</_description>
- <languageList>
- <iso639Id>por</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Brazil - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Brazil - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo</name>
- <_description>Brazil - Nativo</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo-us</name>
- <_description>Brazil - Nativo for USA keyboards</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo-epo</name>
- <_description>Brazil - Nativo for Esperanto</_description>
- <languageList>
- <iso639Id>epo</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>bg</name>
- <_shortDescription>Bgr</_shortDescription>
- <_description>Bulgaria</_description>
- <languageList>
- <iso639Id>bul</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Bulgaria - Traditional phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bas_phonetic</name>
- <_description>Bulgaria - New phonetic</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ma</name>
- <_description>Morocco</_description>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>french</name>
- <_description>Morocco - French</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh</name>
- <_description>Morocco - Tifinagh</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh-alt</name>
- <_description>Morocco - Tifinagh alternative</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh-alt-phonetic</name>
- <_description>Morocco - Tifinagh alternative phonetic</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh-extended</name>
- <_description>Morocco - Tifinagh extended</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh-phonetic</name>
- <_description>Morocco - Tifinagh phonetic</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tifinagh-extended-phonetic</name>
- <_description>Morocco - Tifinagh extended phonetic</_description>
- <languageList>
- <iso639Id>ber</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mm</name>
- <_shortDescription>Mmr</_shortDescription>
- <_description>Myanmar</_description>
- <languageList>
- <iso639Id>mya</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>ca</name>
- <_shortDescription>Can</_shortDescription>
- <_description>Canada</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>fr-dvorak</name>
- <_description>Canada - French Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fr-legacy</name>
- <_description>Canada - French (legacy)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>multix</name>
- <_description>Canada - Multilingual</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>multi</name>
- <_description>Canada - Multilingual, first part</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>multi-2gr</name>
- <_description>Canada - Multilingual, second part</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ike</name>
- <_description>Canada - Inuktitut</_description>
- <languageList>
- <iso639Id>iku</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>shs</name>
- <_description>Canada - Secwepemctsin</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>kut</name>
- <_description>Canada - Ktunaxa</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>eng</name>
- <_description>Canada - English</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>cd</name>
- <_shortDescription>COD</_shortDescription>
- <_description>Congo, Democratic Republic of the</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>cn</name>
- <_shortDescription>Chn</_shortDescription>
- <_description>China</_description>
- <languageList>
- <iso639Id>chi</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>tib</name>
- <_description>China - Tibetan</_description>
- <languageList>
- <iso639Id>tib</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tib_asciinum</name>
- <_description>China - Tibetan (with ASCII numerals)</_description>
- <languageList>
- <iso639Id>tib</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>uig</name>
- <_description>China - Uyghur</_description>
- <languageList>
- <iso639Id>uig</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>hr</name>
- <_shortDescription>Hrv</_shortDescription>
- <_description>Croatia</_description>
- <languageList>
- <iso639Id>scr</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>alternatequotes</name>
- <_description>Croatia - Use guillemets for quotes</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>unicode</name>
- <_description>Croatia - Use Croatian digraphs</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>unicodeus</name>
- <_description>Croatia - US keyboard with Croatian digraphs</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Croatia - US keyboard with Croatian letters</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>cz</name>
- <_shortDescription>Cze</_shortDescription>
- <_description>Czechia</_description>
- <languageList>
- <iso639Id>cze</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>bksl</name>
- <_description>Czechia - With &lt;\|&gt; key</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty</name>
- <_description>Czechia - qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty_bksl</name>
- <_description>Czechia - qwerty, extended Backslash</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ucw</name>
- <_description>Czechia - UCW layout (accented letters only)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-ucw</name>
- <_description>Czechia - US Dvorak with CZ UCW support</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>dk</name>
- <_shortDescription>Dnk</_shortDescription>
- <_description>Denmark</_description>
- <languageList>
- <iso639Id>dan</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Denmark - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Denmark - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_nodeadkeys</name>
- <_description>Denmark - Macintosh, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Denmark - Dvorak</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>nl</name>
- <_shortDescription>Nld</_shortDescription>
- <_description>Netherlands</_description>
- <languageList>
- <iso639Id>nld</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Netherlands - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Netherlands - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>std</name>
- <_description>Netherlands - Standard</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>bt</name>
- <_shortDescription>Btn</_shortDescription>
- <_description>Bhutan</_description>
- <languageList>
- <iso639Id>dzo</iso639Id>
- </languageList>
- </configItem>
- </layout>
- <layout>
- <configItem>
- <name>ee</name>
- <_shortDescription>Est</_shortDescription>
- <_description>Estonia</_description>
- <languageList>
- <iso639Id>est</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Estonia - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Estonia - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Estonia - US keyboard with Estonian letters</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ir</name>
- <_shortDescription>Irn</_shortDescription>
- <_description>Iran</_description>
- <languageList>
- <iso639Id>per</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>pes_keypad</name>
- <_description>Iran - Persian, with Persian Keypad</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku</name>
- <_description>Iran - Kurdish, Latin Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_f</name>
- <_description>Iran - Kurdish, (F)</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_alt</name>
- <_description>Iran - Kurdish, Latin Alt-Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_ara</name>
- <_description>Iran - Kurdish, Arabic-Latin</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>iq</name>
- <_shortDescription>Irq</_shortDescription>
- <_description>Iraq</_description>
- <languageList><iso639Id>ara</iso639Id>
- <iso639Id>kur</iso639Id></languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>ku</name>
- <_description>Iraq - Kurdish, Latin Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_f</name>
- <_description>Iraq - Kurdish, (F)</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_alt</name>
- <_description>Iraq - Kurdish, Latin Alt-Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_ara</name>
- <_description>Iraq - Kurdish, Arabic-Latin</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>fo</name>
- <_shortDescription>Fro</_shortDescription>
- <_description>Faroe Islands</_description>
- <languageList>
- <iso639Id>fao</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Faroe Islands - Eliminate dead keys</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>fi</name>
- <_shortDescription>Fin</_shortDescription>
- <_description>Finland</_description>
- <languageList>
- <iso639Id>fin</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>classic</name>
- <_description>Finland - Classic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Finland - Classic, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>smi</name>
- <_description>Finland - Northern Saami</_description>
- <languageList><iso639Id>smi</iso639Id>
- <iso639Id>sme</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Finland - Macintosh</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>fr</name>
- <_shortDescription>Fra</_shortDescription>
- <_description>France</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>France - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>France - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss</name>
- <_description>France - Alternative</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss_latin9</name>
- <_description>France - Alternative, latin-9 only</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss_nodeadkeys</name>
- <_description>France - Alternative, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oss_sundeadkeys</name>
- <_description>France - Alternative, Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latin9</name>
- <_description>France - (Legacy) Alternative</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latin9_nodeadkeys</name>
- <_description>France - (Legacy) Alternative, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latin9_sundeadkeys</name>
- <_description>France - (Legacy) Alternative, Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bepo</name>
- <_description>France - Bepo, ergonomic, Dvorak way</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bepo_latin9</name>
- <_description>France - Bepo, ergonomic, Dvorak way, latin-9 only</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>France - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>France - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bre</name>
- <_description>France - Breton</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>oci</name>
- <_description>France - Occitan</_description>
- <languageList>
- <iso639Id>oci</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>geo</name>
- <_description>France - Georgian AZERTY Tskapo</_description>
- <languageList>
- <iso639Id>geo</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>gh</name>
- <_shortDescription>Gha</_shortDescription>
- <_description>Ghana</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>generic</name>
- <_description>Ghana - Multilingual</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>akan</name>
- <_description>Ghana - Akan</_description>
- <languageList>
- <iso639Id>aka</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ewe</name>
- <_description>Ghana - Ewe</_description>
- <languageList>
- <iso639Id>ewe</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fula</name>
- <_description>Ghana - Fula</_description>
- <languageList>
- <iso639Id>ful</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ga</name>
- <_description>Ghana - Ga</_description>
- <languageList>
- <iso639Id>gaa</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>hausa</name>
- <_description>Ghana - Hausa</_description>
- <languageList>
- <iso639Id>hau</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>avn</name>
- <_description>Ghana - Avatime</_description>
- <languageList>
- <iso639Id>avn</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>gillbt</name>
- <_description>Ghana - GILLBT</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>gn</name>
- <_shortDescription>Gin</_shortDescription>
- <_description>Guinea</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>ge</name>
- <_shortDescription>Geo</_shortDescription>
- <_description>Georgia</_description>
- <languageList>
- <iso639Id>geo</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>ergonomic</name>
- <_description>Georgia - Ergonomic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mess</name>
- <_description>Georgia - MESS</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ru</name>
- <_description>Georgia - Russian</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>os</name>
- <_description>Georgia - Ossetian</_description>
- <languageList>
- <iso639Id>oss</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>de</name>
- <_shortDescription>Deu</_shortDescription>
- <_description>Germany</_description>
- <languageList>
- <iso639Id>ger</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>deadacute</name>
- <_description>Germany - Dead acute</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>deadgraveacute</name>
- <_description>Germany - Dead grave acute</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Germany - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ro</name>
- <_description>Germany - Romanian keyboard with German letters</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ro_nodeadkeys</name>
- <_description>Germany - Romanian keyboard with German letters, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Germany - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Germany - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>neo</name>
- <_description>Germany - Neo 2</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Germany - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_nodeadkeys</name>
- <_description>Germany - Macintosh, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dsb</name>
- <_description>Germany - Lower Sorbian</_description>
- <languageList>
- <iso639Id>dsb</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dsb_qwertz</name>
- <_description>Germany - Lower Sorbian (qwertz)</_description>
- <languageList>
- <iso639Id>dsb</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty</name>
- <_description>Germany - qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ru</name>
- <_description>Germany - Russian phonetic</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>gr</name>
- <_shortDescription>Grc</_shortDescription>
- <_description>Greece</_description>
- <languageList>
- <iso639Id>gre</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>simple</name>
- <_description>Greece - Simple</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>extended</name>
- <_description>Greece - Extended</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Greece - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>polytonic</name>
- <_description>Greece - Polytonic</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>hu</name>
- <_shortDescription>Hun</_shortDescription>
- <_description>Hungary</_description>
- <languageList>
- <iso639Id>hun</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>standard</name>
- <_description>Hungary - Standard</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Hungary - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty</name>
- <_description>Hungary - qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwertz_comma_dead</name>
- <_description>Hungary - 101/qwertz/comma/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwertz_comma_nodead</name>
- <_description>Hungary - 101/qwertz/comma/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwertz_dot_dead</name>
- <_description>Hungary - 101/qwertz/dot/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwertz_dot_nodead</name>
- <_description>Hungary - 101/qwertz/dot/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwerty_comma_dead</name>
- <_description>Hungary - 101/qwerty/comma/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwerty_comma_nodead</name>
- <_description>Hungary - 101/qwerty/comma/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwerty_dot_dead</name>
- <_description>Hungary - 101/qwerty/dot/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>101_qwerty_dot_nodead</name>
- <_description>Hungary - 101/qwerty/dot/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwertz_comma_dead</name>
- <_description>Hungary - 102/qwertz/comma/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwertz_comma_nodead</name>
- <_description>Hungary - 102/qwertz/comma/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwertz_dot_dead</name>
- <_description>Hungary - 102/qwertz/dot/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwertz_dot_nodead</name>
- <_description>Hungary - 102/qwertz/dot/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwerty_comma_dead</name>
- <_description>Hungary - 102/qwerty/comma/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwerty_comma_nodead</name>
- <_description>Hungary - 102/qwerty/comma/Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwerty_dot_dead</name>
- <_description>Hungary - 102/qwerty/dot/Dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>102_qwerty_dot_nodead</name>
- <_description>Hungary - 102/qwerty/dot/Eliminate dead keys</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>is</name>
- <_shortDescription>Isl</_shortDescription>
- <_description>Iceland</_description>
- <languageList>
- <iso639Id>ice</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>Sundeadkeys</name>
- <_description>Iceland - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Iceland - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Iceland - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Iceland - Dvorak</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>il</name>
- <_shortDescription>Isr</_shortDescription>
- <_description>Israel</_description>
- <languageList>
- <iso639Id>heb</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>lyx</name>
- <_description>Israel - lyx</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Israel - Phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>biblical</name>
- <_description>Israel - Biblical Hebrew (Tiro)</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>it</name>
- <_shortDescription>Ita</_shortDescription>
- <_description>Italy</_description>
- <languageList>
- <iso639Id>ita</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Italy - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Italy - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Italy - US keyboard with Italian letters</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>geo</name>
- <_description>Italy - Georgian</_description>
- <languageList>
- <iso639Id>geo</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>jp</name>
- <_shortDescription>Jpn</_shortDescription>
- <_description>Japan</_description>
- <languageList>
- <iso639Id>jpn</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>kana</name>
- <_description>Japan - Kana</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>kana86</name>
- <_description>Japan - Kana 86</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>OADG109A</name>
- <_description>Japan - OADG 109A</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Japan - Macintosh</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>kg</name>
- <_shortDescription>Kgz</_shortDescription>
- <_description>Kyrgyzstan</_description>
- <languageList>
- <iso639Id>kir</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Kyrgyzstan - Phonetic</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>kh</name>
- <_shortDescription>Khm</_shortDescription>
- <_description>Cambodia</_description>
- <languageList>
- <iso639Id>khm</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>kz</name>
- <_shortDescription>Kaz</_shortDescription>
- <_description>Kazakhstan</_description>
- <languageList>
- <iso639Id>kaz</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>ruskaz</name>
- <_description>Kazakhstan - Russian with Kazakh</_description>
- <languageList><iso639Id>kaz</iso639Id>
- <iso639Id>rus</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>kazrus</name>
- <_description>Kazakhstan - Kazakh with Russian</_description>
- <languageList><iso639Id>kaz</iso639Id>
- <iso639Id>rus</iso639Id></languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>la</name>
- <_shortDescription>Lao</_shortDescription>
- <_description>Laos</_description>
- <languageList>
- <iso639Id>lao</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>stea</name>
- <_description>Laos - STEA (proposed standard layout)</_description>
- <languageList><iso639Id>lao</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>latam</name>
- <_shortDescription>Esp</_shortDescription>
- <_description>Latin American</_description>
- <countryList>
- <iso3166Id>AR</iso3166Id>
- <iso3166Id>BO</iso3166Id>
- <iso3166Id>CL</iso3166Id>
- <iso3166Id>CO</iso3166Id>
- <iso3166Id>CR</iso3166Id>
- <iso3166Id>CU</iso3166Id>
- <iso3166Id>DO</iso3166Id>
- <iso3166Id>EC</iso3166Id>
- <iso3166Id>GT</iso3166Id>
- <iso3166Id>HN</iso3166Id>
- <iso3166Id>HT</iso3166Id>
- <iso3166Id>MX</iso3166Id>
- <iso3166Id>NI</iso3166Id>
- <iso3166Id>PA</iso3166Id>
- <iso3166Id>PE</iso3166Id>
- <iso3166Id>PR</iso3166Id>
- <iso3166Id>PY</iso3166Id>
- <iso3166Id>SV</iso3166Id>
- <iso3166Id>US</iso3166Id>
- <iso3166Id>UY</iso3166Id>
- <iso3166Id>VE</iso3166Id>
- </countryList>
- <languageList>
- <iso639Id>spa</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Latin American - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>deadtilde</name>
- <_description>Latin American - Include dead tilde</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Latin American - Sun dead keys</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>lt</name>
- <_shortDescription>Ltu</_shortDescription>
- <_description>Lithuania</_description>
- <languageList>
- <iso639Id>lit</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>std</name>
- <_description>Lithuania - Standard</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Lithuania - US keyboard with Lithuanian letters</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ibm</name>
- <_description>Lithuania - IBM (LST 1205-92)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>lekp</name>
- <_description>Lithuania - LEKP</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>lekpa</name>
- <_description>Lithuania - LEKPa</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>lv</name>
- <_shortDescription>Lva</_shortDescription>
- <_description>Latvia</_description>
- <languageList>
- <iso639Id>lav</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>apostrophe</name>
- <_description>Latvia - Apostrophe (') variant</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tilde</name>
- <_description>Latvia - Tilde (~) variant</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fkey</name>
- <_description>Latvia - F-letter (F) variant</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mao</name>
- <_shortDescription>Mao</_shortDescription>
- <_description>Maori</_description>
- <languageList>
- <iso639Id>mao</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>me</name>
- <_shortDescription>MNE</_shortDescription>
- <_description>Montenegro</_description>
- <languageList>
- <iso639Id>srp</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>cyrillic</name>
- <_description>Montenegro - Cyrillic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>cyrillicyz</name>
- <_description>Montenegro - Cyrillic, Z and ZHE swapped</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinunicode</name>
- <_description>Montenegro - Latin unicode</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinyz</name>
- <_description>Montenegro - Latin qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinunicodeyz</name>
- <_description>Montenegro - Latin unicode qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>cyrillicalternatequotes</name>
- <_description>Montenegro - Cyrillic with guillemets</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinalternatequotes</name>
- <_description>Montenegro - Latin with guillemets</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mk</name>
- <_shortDescription>Mkd</_shortDescription>
- <_description>Macedonia</_description>
- <languageList>
- <iso639Id>mkd</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Macedonia - Eliminate dead keys</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mt</name>
- <_shortDescription>Mlt</_shortDescription>
- <_description>Malta</_description>
- <languageList>
- <iso639Id>mlt</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Malta - Maltese keyboard with US layout</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mn</name>
- <_shortDescription>Mng</_shortDescription>
- <_description>Mongolia</_description>
- <languageList>
- <iso639Id>mng</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>no</name>
- <_shortDescription>Nor</_shortDescription>
- <_description>Norway</_description>
- <languageList>
- <iso639Id>nor</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Norway - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Norway - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>smi</name>
- <_description>Norway - Northern Saami</_description>
- <languageList>
- <iso639Id>sme</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>smi_nodeadkeys</name>
- <_description>Norway - Northern Saami, eliminate dead keys</_description>
- <languageList>
- <iso639Id>sme</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Norway - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_nodeadkeys</name>
- <_description>Norway - Macintosh, eliminate dead keys</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>pl</name>
- <_shortDescription>Pol</_shortDescription>
- <_description>Poland</_description>
- <languageList>
- <iso639Id>pol</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>qwertz</name>
- <_description>Poland - qwertz</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Poland - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak_quotes</name>
- <_description>Poland - Dvorak, Polish quotes on quotemark key</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak_altquotes</name>
- <_description>Poland - Dvorak, Polish quotes on key 1</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>csb</name>
- <_description>Poland - Kashubian</_description>
- <languageList>
- <iso639Id>csb</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ru_phonetic_dvorak</name>
- <_description>Poland - Russian phonetic Dvorak</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvp</name>
- <_description>Poland - Programmer Dvorak</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>pt</name>
- <_shortDescription>Prt</_shortDescription>
- <_description>Portugal</_description>
- <languageList>
- <iso639Id>por</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Portugal - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Portugal - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Portugal - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_nodeadkeys</name>
- <_description>Portugal - Macintosh, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_sundeadkeys</name>
- <_description>Portugal - Macintosh, Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo</name>
- <_description>Portugal - Nativo</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo-us</name>
- <_description>Portugal - Nativo for USA keyboards</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>nativo-epo</name>
- <_description>Portugal - Nativo for Esperanto</_description>
- <languageList>
- <iso639Id>epo</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ro</name>
- <_shortDescription>Rou</_shortDescription>
- <_description>Romania</_description>
- <languageList>
- <iso639Id>rum</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>cedilla</name>
- <_description>Romania - Cedilla</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>std</name>
- <_description>Romania - Standard</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>std_cedilla</name>
- <_description>Romania - Standard (Cedilla)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>winkeys</name>
- <_description>Romania - Winkeys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_f</name>
- <_description>Romania - Crimean Tatar (Turkish F)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_alt</name>
- <_description>Romania - Crimean Tatar (Turkish Alt-Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_dobruca1</name>
- <_description>Romania - Crimean Tatar (Dobruca-1 Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_dobruca2</name>
- <_description>Romania - Crimean Tatar (Dobruca-2 Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ru</name>
- <_shortDescription>Rus</_shortDescription>
- <_description>Russia</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Russia - Phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>phonetic_winkeys</name>
- <_description>Russia - Phonetic Winkeys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>typewriter</name>
- <_description>Russia - Typewriter</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Russia - Legacy</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>typewriter-legacy</name>
- <_description>Russia - Typewriter, legacy</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tt</name>
- <_description>Russia - Tatar</_description>
- <languageList>
- <iso639Id>tat</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>os_legacy</name>
- <_description>Russia - Ossetian, legacy</_description>
- <languageList>
- <iso639Id>oss</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>os_winkeys</name>
- <_description>Russia - Ossetian, Winkeys</_description>
- <languageList>
- <iso639Id>oss</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>cv</name>
- <_description>Russia - Chuvash</_description>
- <languageList>
- <iso639Id>chv</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>cv_latin</name>
- <_description>Russia - Chuvash Latin</_description>
- <languageList>
- <iso639Id>chv</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>udm</name>
- <_description>Russia - Udmurt</_description>
- <languageList>
- <iso639Id>udm</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>kom</name>
- <_description>Russia - Komi</_description>
- <languageList>
- <iso639Id>kom</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sah</name>
- <_description>Russia - Yakut</_description>
- <languageList>
- <iso639Id>sah</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>xal</name>
- <_description>Russia - Kalmyk</_description>
- <languageList>
- <iso639Id>xal</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dos</name>
- <_description>Russia - DOS</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>srp</name>
- <_description>Russia - Serbian</_description>
- <languageList><iso639Id>rus</iso639Id>
- <iso639Id>srp</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>bak</name>
- <_description>Russia - Bashkirian</_description>
- <languageList>
- <iso639Id>bak</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>chm</name>
- <_description>Russia - Mari</_description>
- <languageList>
- <iso639Id>chm</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>rs</name>
- <_shortDescription>SRB</_shortDescription>
- <_description>Serbia</_description>
- <languageList>
- <iso639Id>srp</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>yz</name>
- <_description>Serbia - Z and ZHE swapped</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latin</name>
- <_description>Serbia - Latin</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinunicode</name>
- <_description>Serbia - Latin Unicode</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinyz</name>
- <_description>Serbia - Latin qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinunicodeyz</name>
- <_description>Serbia - Latin Unicode qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>alternatequotes</name>
- <_description>Serbia - With guillemets</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>latinalternatequotes</name>
- <_description>Serbia - Latin with guillemets</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rue</name>
- <_description>Serbia - Pannonian Rusyn Homophonic</_description>
- <languageList>
- <iso639Id>rue</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>si</name>
- <_shortDescription>Svn</_shortDescription>
- <_description>Slovenia</_description>
- <languageList>
- <iso639Id>slv</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>alternatequotes</name>
- <_description>Slovenia - Use guillemets for quotes</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us</name>
- <_description>Slovenia - US keyboard with Slovenian letters</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>sk</name>
- <_shortDescription>Svk</_shortDescription>
- <_description>Slovakia</_description>
- <languageList>
- <iso639Id>slo</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>bksl</name>
- <_description>Slovakia - Extended Backslash</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty</name>
- <_description>Slovakia - qwerty</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>qwerty_bksl</name>
- <_description>Slovakia - qwerty, extended Backslash</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>es</name>
- <_shortDescription>Esp</_shortDescription>
- <_description>Spain</_description>
- <languageList>
- <iso639Id>spa</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Spain - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>deadtilde</name>
- <_description>Spain - Include dead tilde</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Spain - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Spain - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ast</name>
- <_description>Spain - Asturian variant with bottom-dot H and bottom-dot L</_description>
- <languageList>
- <iso639Id>ast</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>cat</name>
- <_description>Spain - Catalan variant with middle-dot L</_description>
- <languageList>
- <iso639Id>cat</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Spain - Macintosh</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>se</name>
- <_shortDescription>Swe</_shortDescription>
- <_description>Sweden</_description>
- <languageList>
- <iso639Id>swe</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>nodeadkeys</name>
- <_description>Sweden - Eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Sweden - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rus</name>
- <_description>Sweden - Russian phonetic</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rus_nodeadkeys</name>
- <_description>Sweden - Russian phonetic, eliminate dead keys</_description>
- <languageList>
- <iso639Id>rus</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>smi</name>
- <_description>Sweden - Northern Saami</_description>
- <languageList>
- <iso639Id>sme</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>Sweden - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>svdvorak</name>
- <_description>Sweden - Svdvorak</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ch</name>
- <_shortDescription>Che</_shortDescription>
- <_description>Switzerland</_description>
- <languageList><iso639Id>ger</iso639Id>
- <iso639Id>gsw</iso639Id></languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Switzerland - Legacy</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>de_nodeadkeys</name>
- <_description>Switzerland - German, eliminate dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>de_sundeadkeys</name>
- <_description>Switzerland - German, Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fr</name>
- <_description>Switzerland - French</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fr_nodeadkeys</name>
- <_description>Switzerland - French, eliminate dead keys</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fr_sundeadkeys</name>
- <_description>Switzerland - French, Sun dead keys</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>fr_mac</name>
- <_description>Switzerland - French (Macintosh)</_description>
- <languageList>
- <iso639Id>fra</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>de_mac</name>
- <_description>Switzerland - German (Macintosh)</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>sy</name>
- <_shortDescription>Syr</_shortDescription>
- <_description>Syria</_description>
- <languageList>
- <iso639Id>syr</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>syc</name>
- <_description>Syria - Syriac</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>syc_phonetic</name>
- <_description>Syria - Syriac phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku</name>
- <_description>Syria - Kurdish, Latin Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_f</name>
- <_description>Syria - Kurdish, (F)</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_alt</name>
- <_description>Syria - Kurdish, Latin Alt-Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>tj</name>
- <_shortDescription>Tjk</_shortDescription>
- <_description>Tajikistan</_description>
- <languageList>
- <iso639Id>tgk</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Tajikistan - Legacy</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>lk</name>
- <_shortDescription>Lka</_shortDescription>
- <_description>Sri Lanka</_description>
- <languageList>
- <iso639Id>sin</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>tam_unicode</name>
- <_description>Sri Lanka - Tamil Unicode</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>tam_TAB</name>
- <_description>Sri Lanka - Tamil TAB Typewriter</_description>
- <languageList>
- <iso639Id>tam</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>th</name>
- <_shortDescription>Tha</_shortDescription>
- <_description>Thailand</_description>
- <languageList>
- <iso639Id>tha</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>tis</name>
- <_description>Thailand - TIS-820.2538</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>pat</name>
- <_description>Thailand - Pattachote</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>tr</name>
- <_shortDescription>Tur</_shortDescription>
- <_description>Turkey</_description>
- <languageList>
- <iso639Id>tur</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>f</name>
- <_description>Turkey - (F)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>alt</name>
- <_description>Turkey - Alt-Q</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>sundeadkeys</name>
- <_description>Turkey - Sun dead keys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku</name>
- <_description>Turkey - Kurdish, Latin Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_f</name>
- <_description>Turkey - Kurdish, (F)</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ku_alt</name>
- <_description>Turkey - Kurdish, Latin Alt-Q</_description>
- <languageList>
- <iso639Id>kur</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>intl</name>
- <_description>Turkey - International (with dead keys)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh</name>
- <_description>Turkey - Crimean Tatar (Turkish Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_f</name>
- <_description>Turkey - Crimean Tatar (Turkish F)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_alt</name>
- <_description>Turkey - Crimean Tatar (Turkish Alt-Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ua</name>
- <_shortDescription>Ukr</_shortDescription>
- <_description>Ukraine</_description>
- <languageList>
- <iso639Id>ukr</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>phonetic</name>
- <_description>Ukraine - Phonetic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>typewriter</name>
- <_description>Ukraine - Typewriter</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>winkeys</name>
- <_description>Ukraine - Winkeys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Ukraine - Legacy</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rstu</name>
- <_description>Ukraine - Standard RSTU</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>rstu_ru</name>
- <_description>Ukraine - Standard RSTU on Russian layout</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>homophonic</name>
- <_description>Ukraine - Homophonic</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh</name>
- <_description>Ukraine - Crimean Tatar (Turkish Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_f</name>
- <_description>Ukraine - Crimean Tatar (Turkish F)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_alt</name>
- <_description>Ukraine - Crimean Tatar (Turkish Alt-Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>gb</name>
- <_shortDescription>GBr</_shortDescription>
- <_description>United Kingdom</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>extd</name>
- <_description>United Kingdom - Extended - Winkeys</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>intl</name>
- <_description>United Kingdom - International (with dead keys)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>United Kingdom - Dvorak</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorakukp</name>
- <_description>United Kingdom - Dvorak (UK Punctuation)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac</name>
- <_description>United Kingdom - Macintosh</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>mac_intl</name>
- <_description>United Kingdom - Macintosh (International)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>colemak</name>
- <_description>United Kingdom - Colemak</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>uz</name>
- <_shortDescription>Uzb</_shortDescription>
- <_description>Uzbekistan</_description>
- <languageList>
- <iso639Id>uzb</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>latin</name>
- <_description>Uzbekistan - Latin</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh</name>
- <_description>Uzbekistan - Crimean Tatar (Turkish Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_f</name>
- <_description>Uzbekistan - Crimean Tatar (Turkish F)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>crh_alt</name>
- <_description>Uzbekistan - Crimean Tatar (Turkish Alt-Q)</_description>
- <languageList>
- <iso639Id>crh</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>vn</name>
- <_shortDescription>Vnm</_shortDescription>
- <_description>Vietnam</_description>
- <languageList>
- <iso639Id>vie</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>kr</name>
- <_shortDescription>Kor</_shortDescription>
- <_description>Korea, Republic of</_description>
- <languageList>
- <iso639Id>kor</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>kr104</name>
- <_description>Korea, Republic of - 101/104 key Compatible</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>nec_vndr/jp</name>
- <_shortDescription>Jpn</_shortDescription>
- <_description>Japan (PC-98xx Series)</_description>
- <countryList>
- <iso3166Id>JP</iso3166Id>
- </countryList>
- <languageList>
- <iso639Id>jpn</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>ie</name>
- <_shortDescription>Irl</_shortDescription>
- <_description>Ireland</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>CloGaelach</name>
- <_description>Ireland - CloGaelach</_description>
- <languageList>
- <iso639Id>gla</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>UnicodeExpert</name>
- <_description>Ireland - UnicodeExpert</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ogam</name>
- <_description>Ireland - Ogham</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ogam_is434</name>
- <_description>Ireland - Ogham IS434</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>pk</name>
- <_shortDescription>Pak</_shortDescription>
- <_description>Pakistan</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>urd-crulp</name>
- <_description>Pakistan - CRULP</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>urd-nla</name>
- <_description>Pakistan - NLA</_description>
- <languageList>
- <iso639Id>urd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>ara</name>
- <_description>Pakistan - Arabic</_description>
- <languageList>
- <iso639Id>ara</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>snd</name>
- <_description>Pakistan - Sindhi</_description>
- <languageList>
- <iso639Id>sd</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>mv</name>
- <_shortDescription>Mdv</_shortDescription>
- <_description>Maldives</_description>
- <languageList>
- <iso639Id>div</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>za</name>
- <_shortDescription>Zaf</_shortDescription>
- <_description>South Africa</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- </layout>
- <layout>
- <configItem>
- <name>epo</name>
- <_shortDescription>Epo</_shortDescription>
- <_description>Esperanto</_description>
- <languageList>
- <iso639Id>epo</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>legacy</name>
- <_description>Esperanto - displaced semicolon and quote (obsolete)</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>np</name>
- <_shortDescription>Npl</_shortDescription>
- <_description>Nepal</_description>
- <languageList>
- <iso639Id>nep</iso639Id>
- </languageList>
- </configItem>
- </layout>
- <layout>
- <configItem>
- <name>ng</name>
- <_shortDescription>Nga</_shortDescription>
- <_description>Nigeria</_description>
- <languageList>
- <iso639Id>eng</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>igbo</name>
- <_description>Nigeria - Igbo</_description>
- <languageList>
- <iso639Id>ibo</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>yoruba</name>
- <_description>Nigeria - Yoruba</_description>
- <languageList>
- <iso639Id>yor</iso639Id>
- </languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>hausa</name>
- <_description>Nigeria - Hausa</_description>
- <languageList>
- <iso639Id>hau</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>et</name>
- <_shortDescription>Eth</_shortDescription>
- <_description>Ethiopia</_description>
- <languageList>
- <iso639Id>amh</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>sn</name>
- <_shortDescription>Sen</_shortDescription>
- <_description>Senegal</_description>
- <languageList>
- <iso639Id>wol</iso639Id>
- </languageList>
- </configItem>
- <variantList/>
- </layout>
- <layout>
- <configItem>
- <name>brai</name>
- <_shortDescription>Brl</_shortDescription>
- <_description>Braille</_description>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>left_hand</name>
- <_description>Braille - Left hand</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>right_hand</name>
- <_description>Braille - Right hand</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>tm</name>
- <_shortDescription>Tkm</_shortDescription>
- <_description>Turkmenistan</_description>
- <languageList>
- <iso639Id>tuk</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>alt</name>
- <_description>Turkmenistan - Alt-Q</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>ml</name>
- <_shortDescription>Mli</_shortDescription>
- <_description>Mali</_description>
- <languageList>
- <iso639Id>bam</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>fr-oss</name>
- <_description>Mali - Français (France Alternative)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us-mac</name>
- <_description>Mali - English (USA Macintosh)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>us-intl</name>
- <_description>Mali - English (USA International)</_description>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>tz</name>
- <_shortDescription>Tza</_shortDescription>
- <_description>Tanzania</_description>
- <languageList>
- <iso639Id>swa</iso639Id>
- </languageList>
- </configItem>
- </layout>
- <layout>
- <configItem>
- <name>ke</name>
- <_shortDescription>Ken</_shortDescription>
- <_description>Kenya</_description>
- <languageList>
- <iso639Id>swa</iso639Id>
- </languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>kik</name>
- <_description>Kenya - Kikuyu</_description>
- <languageList>
- <iso639Id>kik</iso639Id>
- </languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- <layout>
- <configItem>
- <name>bw</name>
- <_shortDescription>Bwa</_shortDescription>
- <_description>Botswana</_description>
- <languageList>
- <iso639Id>tsn</iso639Id>
- </languageList>
- </configItem>
- </layout>
- <layout>
- <configItem>
- <name>ph</name>
- <_shortDescription>Phi</_shortDescription>
- <_description>Philippines</_description>
- <languageList><iso639Id>eng</iso639Id>
- <iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- <variantList>
- <variant>
- <configItem>
- <name>qwerty-bay</name>
- <_description>Philippines - QWERTY (Baybayin)</_description>
- <languageList><iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>capewell-dvorak</name>
- <_description>Philippines - Capewell-Dvorak (Latin)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>capewell-dvorak-bay</name>
- <_description>Philippines - Capewell-Dvorak (Baybayin)</_description>
- <languageList><iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>capewell-qwerf2k6</name>
- <_description>Philippines - Capewell-QWERF 2006 (Latin)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>capewell-qwerf2k6-bay</name>
- <_description>Philippines - Capewell-QWERF 2006 (Baybayin)</_description>
- <languageList><iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>colemak</name>
- <_description>Philippines - Colemak (Latin)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>colemak-bay</name>
- <_description>Philippines - Colemak (Baybayin)</_description>
- <languageList><iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak</name>
- <_description>Philippines - Dvorak (Latin)</_description>
- </configItem>
- </variant>
- <variant>
- <configItem>
- <name>dvorak-bay</name>
- <_description>Philippines - Dvorak (Baybayin)</_description>
- <languageList><iso639Id>bik</iso639Id>
- <iso639Id>ceb</iso639Id>
- <iso639Id>fil</iso639Id>
- <iso639Id>hil</iso639Id>
- <iso639Id>ilo</iso639Id>
- <iso639Id>pam</iso639Id>
- <iso639Id>pag</iso639Id>
- <iso639Id>phi</iso639Id>
- <iso639Id>tgl</iso639Id>
- <iso639Id>war</iso639Id></languageList>
- </configItem>
- </variant>
- </variantList>
- </layout>
- </layoutList>
- <optionList>
- <group allowMultipleSelection="true">
- <!-- The key combination used to switch between groups -->
- <configItem>
- <name>grp</name>
- <_description>Key(s) to change layout</_description>
- </configItem>
- <option>
- <configItem>
- <name>grp:switch</name>
- <_description>Right Alt (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lswitch</name>
- <_description>Left Alt (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lwin_switch</name>
- <_description>Left Win (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rwin_switch</name>
- <_description>Right Win (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:win_switch</name>
- <_description>Any Win key (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:caps_switch</name>
- <_description>Caps Lock (while pressed), Alt+Caps Lock does the original capslock action</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rctrl_switch</name>
- <_description>Right Ctrl (while pressed)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:toggle</name>
- <_description>Right Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lalt_toggle</name>
- <_description>Left Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:caps_toggle</name>
- <_description>Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:shift_caps_toggle</name>
- <_description>Shift+Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:shift_caps_switch</name>
- <_description>Caps Lock (to first layout), Shift+Caps Lock (to last layout)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:win_menu_switch</name>
- <_description>Left Win (to first layout), Right Win/Menu (to last layout)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lctrl_rctrl_switch</name>
- <_description>Left Ctrl (to first layout), Right Ctrl (to last layout)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:alt_caps_toggle</name>
- <_description>Alt+Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:shifts_toggle</name>
- <_description>Both Shift keys together</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:alts_toggle</name>
- <_description>Both Alt keys together</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:ctrls_toggle</name>
- <_description>Both Ctrl keys together</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:ctrl_shift_toggle</name>
- <_description>Ctrl+Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lctrl_lshift_toggle</name>
- <_description>Left Ctrl+Left Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rctrl_rshift_toggle</name>
- <_description>Right Ctrl+Right Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:ctrl_alt_toggle</name>
- <_description>Alt+Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:alt_shift_toggle</name>
- <_description>Alt+Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:alt_space_toggle</name>
- <_description>Alt+Space</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:menu_toggle</name>
- <_description>Menu</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lwin_toggle</name>
- <_description>Left Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rwin_toggle</name>
- <_description>Right Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lshift_toggle</name>
- <_description>Left Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rshift_toggle</name>
- <_description>Right Shift</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lctrl_toggle</name>
- <_description>Left Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:rctrl_toggle</name>
- <_description>Right Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:sclk_toggle</name>
- <_description>Scroll Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp:lctrl_lwin_rctrl_menu</name>
- <_description>LeftCtrl+LeftWin (to first layout), RightCtrl+Menu (to second layout)</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <!-- The key combination used to choose the 3rd (and 4th, together with Shift)
- level of symbols -->
- <configItem>
- <name>lv3</name>
- <_description>Key to choose 3rd level</_description>
- </configItem>
- <option>
- <configItem>
- <name>lv3:switch</name>
- <_description>Right Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:menu_switch</name>
- <_description>Menu</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:win_switch</name>
- <_description>Any Win key</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:lwin_switch</name>
- <_description>Left Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:rwin_switch</name>
- <_description>Right Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:alt_switch</name>
- <_description>Any Alt key</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:lalt_switch</name>
- <_description>Left Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:ralt_switch</name>
- <_description>Right Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:ralt_switch_multikey</name>
- <_description>Right Alt, Shift+Right Alt key is Multi_Key</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:ralt_alt</name>
- <_description>Right Alt key never chooses 3rd level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:enter_switch</name>
- <_description>Enter on keypad</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:caps_switch</name>
- <_description>Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:bksl_switch</name>
- <_description>Backslash</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:lsgt_switch</name>
- <_description>&lt;Less/Greater&gt;</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:caps_switch_latch</name>
- <_description>Caps Lock (chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:bksl_switch_latch</name>
- <_description>Backslash chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv3:lsgt_switch_latch</name>
- <_description>&lt;Less/Greater&gt; (chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <!-- Tweaking the position of the "Ctrl" key -->
- <configItem>
- <name>ctrl</name>
- <_description>Ctrl key position</_description>
- </configItem>
- <option>
- <configItem>
- <name>ctrl:nocaps</name>
- <_description>Make Caps Lock an additional Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:lctrl_meta</name>
- <_description>Meta on Left Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:swapcaps</name>
- <_description>Swap Ctrl and Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:ctrl_ac</name>
- <_description>At left of 'A'</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:ctrl_aa</name>
- <_description>At bottom left</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:ctrl_ra</name>
- <_description>Right Ctrl as Right Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>ctrl:ctrl_menu</name>
- <_description>Right Ctrl is mapped to Menu</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <!-- Using startard LEDs to indicate the alternative (not first) group(s) -->
- <configItem>
- <name>grp_led</name>
- <_description>Use keyboard LED to show alternative layout</_description>
- </configItem>
- <option>
- <configItem>
- <name>grp_led:num</name>
- <_description>Num Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp_led:caps</name>
- <_description>Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>grp_led:scroll</name>
- <_description>Scroll Lock</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="false">
- <!-- Select a keypad type -->
- <configItem>
- <name>keypad</name>
- <_description>Numeric keypad layout selection</_description>
- </configItem>
- <option>
- <configItem>
- <name>keypad:legacy</name>
- <_description>Legacy</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:oss</name>
- <_description>Unicode additions (arrows and math operators)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:future</name>
- <_description>Unicode additions (arrows and math operators). Math operators on default level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:legacy_wang</name>
- <_description>Legacy Wang 724</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:oss_wang</name>
- <_description>Wang 724 keypad with unicode additions (arrows and math operators)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:future_wang</name>
- <_description>Wang 724 keypad with unicode additions (arrows and math operators). Math operators on default level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:hex</name>
- <_description>Hexadecimal</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:atm</name>
- <_description>ATM/phone-style</_description>
- </configItem>
- </option>
- </group>
- <!-- This option should override the KPDL key defined in keypad; I hope it's declared in the right place -->
- <group allowMultipleSelection="false">
- <!-- Select a keypad KPDL variant -->
- <configItem>
- <name>kpdl</name>
- <_description>Numeric keypad delete key behaviour</_description>
- </configItem>
- <option>
- <configItem>
- <!-- Actually, with KP_DECIMAL, as the old keypad(dot) -->
- <name>kpdl:dot</name>
- <_description>Legacy key with dot</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:comma</name>
- <!-- Actually, with KP_SEPARATOR, as the old keypad(comma) -->
- <_description>Legacy key with comma</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:dotoss</name>
- <_description>Four-level key with dot</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:dotoss_latin9</name>
- <_description>Four-level key with dot, latin-9 restriction</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:commaoss</name>
- <_description>Four-level key with comma</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:momayyezoss</name>
- <_description>Four-level key with momayyez</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:kposs</name>
- <!-- This assumes the KP_ abstract symbols are actually useful for some apps
- The description needs to be rewritten -->
- <_description>Four-level key with abstract separators</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>kpdl:semi</name>
- <_description>Semi-colon on third level</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="false">
- <!-- Caps Lock tweaks.
- "Internal" capitalization means capitalization using some internal tables.
- Otherwise "as Shift" - means using next group. -->
- <configItem>
- <name>caps</name>
- <_description>Caps Lock key behavior</_description>
- </configItem>
- <option>
- <configItem>
- <name>caps:internal</name>
- <_description>Caps Lock uses internal capitalization. Shift "pauses" Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:internal_nocancel</name>
- <_description>Caps Lock uses internal capitalization. Shift doesn't affect Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:shift</name>
- <_description>Caps Lock acts as Shift with locking. Shift "pauses" Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:shift_nocancel</name>
- <_description>Caps Lock acts as Shift with locking. Shift doesn't affect Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:capslock</name>
- <_description>Caps Lock toggles normal capitalization of alphabetic characters</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:numlock</name>
- <_description>Make Caps Lock an additional Num Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:swapescape</name>
- <_description>Swap ESC and Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:escape</name>
- <_description>Make Caps Lock an additional ESC</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:backspace</name>
- <_description>Make Caps Lock an additional Backspace</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:super</name>
- <_description>Make Caps Lock an additional Super</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:hyper</name>
- <_description>Make Caps Lock an additional Hyper</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:shiftlock</name>
- <_description>Caps Lock toggles Shift so all keys are affected</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:none</name>
- <_description>Caps Lock is disabled</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>caps:ctrl_modifier</name>
- <_description>Make Caps Lock an additional Control but keep the Caps_Lock keysym</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="false">
- <!-- Using special PC keys (Win, Menu) to work as standard X keys (Super, Hyper, etc.) -->
- <configItem>
- <name>altwin</name>
- <_description>Alt/Win key behavior</_description>
- </configItem>
- <option>
- <configItem>
- <name>altwin:menu</name>
- <_description>Add the standard behavior to Menu key</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:meta_alt</name>
- <_description>Alt and Meta are on Alt keys</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:ctrl_win</name>
- <_description>Control is mapped to Win keys (and the usual Ctrl keys)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:ctrl_alt_win</name>
- <_description>Control is mapped to Alt keys, Alt is mapped to Win keys</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:meta_win</name>
- <_description>Meta is mapped to Win keys</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:left_meta_win</name>
- <_description>Meta is mapped to Left Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:hyper_win</name>
- <_description>Hyper is mapped to Win-keys</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:alt_super_win</name>
- <_description>Alt is mapped to Right Win, Super to Menu</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>altwin:swap_lalt_lwin</name>
- <_description>Left Alt is swapped with Left Win</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <!-- Tweaking the position of the "Compose" key: mapping to existing PC keys -->
- <configItem>
- <name>Compose key</name>
- <_description>Compose key position</_description>
- </configItem>
- <option>
- <configItem>
- <name>compose:ralt</name>
- <_description>Right Alt</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:lwin</name>
- <_description>Left Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:rwin</name>
- <_description>Right Win</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:menu</name>
- <_description>Menu</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:lctrl</name>
- <_description>Left Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:rctrl</name>
- <_description>Right Ctrl</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:caps</name>
- <_description>Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:102</name>
- <_description>&lt;Less/Greater&gt;</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:paus</name>
- <_description>Pause</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:prsc</name>
- <_description>PrtSc</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>compose:sclk</name>
- <_description>Scroll Lock</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <configItem>
- <name>compat</name>
- <_description>Miscellaneous compatibility options</_description>
- </configItem>
- <option>
- <configItem>
- <name>numpad:pc</name>
- <_description>Default numeric keypad keys</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>numpad:mac</name>
- <_description>Numeric keypad keys work as with Mac</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>numpad:microsoft</name>
- <_description>Shift with numeric keypad keys works as in MS Windows</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>numpad:shift3</name>
- <_description>Shift does not cancel Num Lock, chooses 3rd level instead</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>srvrkeys:none</name>
- <_description>Special keys (Ctrl+Alt+&lt;key&gt;) handled in a server</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>apple:alupckeys</name>
- <_description>Apple Aluminium Keyboard: emulate PC keys (Print, Scroll Lock, Pause, Num Lock)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>shift:breaks_caps</name>
- <_description>Shift cancels Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>misc:typo</name>
- <_description>Enable extra typographic characters</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>shift:both_capslock</name>
- <_description>Both Shift-Keys together toggle Caps Lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>shift:both_capslock_cancel</name>
- <_description>Both Shift-Keys together activate Caps Lock, one Shift-Key deactivates</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>shift:both_shiftlock</name>
- <_description>Both Shift-Keys together toggle ShiftLock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>keypad:pointerkeys</name>
- <_description>Toggle PointerKeys with Shift + NumLock.</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <!-- Special shortcuts for the Euro character -->
- <configItem>
- <name>eurosign</name>
- <_description>Adding currency signs to certain keys</_description>
- </configItem>
- <option>
- <configItem>
- <name>eurosign:e</name>
- <_description>Euro on E</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>eurosign:2</name>
- <_description>Euro on 2</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>eurosign:4</name>
- <_description>Euro on 4</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>eurosign:5</name>
- <_description>Euro on 5</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>rupeesign:4</name>
- <_description>Rupee on 4</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <configItem>
- <name>lv5</name>
- <_description>Key to choose 5th level</_description>
- </configItem>
- <option>
- <configItem>
- <name>lv5:lsgt_switch_lock</name>
- <_description>&lt;Less/Greater&gt; chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:ralt_switch_lock</name>
- <_description>Right Alt chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:lwin_switch_lock</name>
- <_description>Left Win chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:rwin_switch_lock</name>
- <_description>Right Win chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:lsgt_switch_lock_cancel</name>
- <_description>&lt;Less/Greater&gt; chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:ralt_switch_lock_cancel</name>
- <_description>Right Alt chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:lwin_switch_lock_cancel</name>
- <_description>Left Win chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:rwin_switch_lock_cancel</name>
- <_description>Right Win chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:lsgt_switch_lock_cancel</name>
- <_description>&lt;Less/Greater&gt; chooses 5th level and activates level5-Lock when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>lv5:ralt_switch_lock_cancel</name>
- <_description>Right Alt chooses 5th level and activates level5-Lock when pressed together with another 5th-level-chooser, one press releases the lock</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="false">
- <!-- Let space output NBSP, NNBSP, ZWNJ, and ZWJ for the desired level -->
- <configItem>
- <name>nbsp</name>
- <_description>Using space key to input non-breakable space character</_description>
- </configItem>
- <option>
- <configItem>
- <name>nbsp:none</name>
- <_description>Usual space at any level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level2</name>
- <_description>Non-breakable space character at second level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level3</name>
- <_description>Non-breakable space character at third level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level3s</name>
- <_description>Non-breakable space character at third level, nothing at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level3n</name>
- <_description>Non-breakable space character at third level, thin non-breakable space character at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level4</name>
- <_description>Non-breakable space character at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level4n</name>
- <_description>Non-breakable space character at fourth level, thin non-breakable space character at sixth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:level4nl</name>
- <_description>Non-breakable space character at fourth level, thin non-breakable space character at sixth level (via Ctrl+Shift)</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2</name>
- <_description>Zero-width non-joiner character at second level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2zwj3</name>
- <_description>Zero-width non-joiner character at second level, zero-width joiner character at third level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2zwj3nb4</name>
- <_description>Zero-width non-joiner character at second level, zero-width joiner character at third level, non-breakable space character at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2nb3</name>
- <_description>Zero-width non-joiner character at second level, non-breakable space character at third level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2nb3s</name>
- <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, nothing at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2nb3zwj4</name>
- <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, zero-width joiner at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj2nb3nnb4</name>
- <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, thin non-breakable space at fourth level</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>nbsp:zwnj3zwj4</name>
- <_description>Zero-width non-joiner character at third level, zero-width joiner at fourth level</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <configItem>
- <name>japan</name>
- <_description>Japanese keyboard options</_description>
- </configItem>
- <option>
- <configItem>
- <name>japan:kana_lock</name>
- <_description>Kana Lock key is locking</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>japan:nicola_f_bs</name>
- <_description>NICOLA-F style Backspace</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="false">
- <configItem>
- <name>esperanto</name>
- <_description>Adding Esperanto circumflexes (supersigno)</_description>
- </configItem>
- <option>
- <configItem>
- <name>esperanto:qwerty</name>
- <_description>To the corresponding key in a Qwerty keyboard.</_description>
- </configItem>
- </option>
- <option>
- <configItem>
- <name>esperanto:dvorak</name>
- <_description>To the corresponding key in a Dvorak keyboard.</_description>
- </configItem>
- </option>
- </group>
- <group allowMultipleSelection="true">
- <configItem>
- <name>terminate</name>
- <_description>Key sequence to kill the X server</_description>
- </configItem>
- <option>
- <configItem>
- <name>terminate:ctrl_alt_bksp</name>
- <_description>Control + Alt + Backspace</_description>
- </configItem>
- </option>
- </group>
- </optionList>
-</xkbConfigRegistry>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE xkbConfigRegistry SYSTEM "xkb.dtd">
+<xkbConfigRegistry version="1.1">
+ <modelList>
+ <model>
+ <configItem>
+ <name>pc101</name>
+ <_description>Generic 101-key PC</_description>
+ <vendor>Generic</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>pc102</name>
+ <_description>Generic 102-key (Intl) PC</_description>
+ <vendor>Generic</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>pc104</name>
+ <_description>Generic 104-key PC</_description>
+ <vendor>Generic</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>pc105</name>
+ <_description>Generic 105-key (Intl) PC</_description>
+ <vendor>Generic</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>dell101</name>
+ <_description>Dell 101-key PC</_description>
+ <vendor>Dell</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>latitude</name>
+ <_description>Dell Latitude series laptop</_description>
+ <vendor>Dell</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>dellm65</name>
+ <_description>Dell Precision M65</_description>
+ <vendor>Dell</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>everex</name>
+ <_description>Everex STEPnote</_description>
+ <vendor>Everex</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>flexpro</name>
+ <_description>Keytronic FlexPro</_description>
+ <vendor>Keytronic</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoft</name>
+ <_description>Microsoft Natural</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>omnikey101</name>
+ <_description>Northgate OmniKey 101</_description>
+ <vendor>Northgate</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>winbook</name>
+ <_description>Winbook Model XP5</_description>
+ <vendor>Generic</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>pc98</name>
+ <_description>PC-98xx Series</_description>
+ <vendor>Generic</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>a4techKB21</name>
+ <_description>A4Tech KB-21</_description>
+ <vendor>A4Tech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>a4techKBS8</name>
+ <_description>A4Tech KBS-8</_description>
+ <vendor>A4Tech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>a4_rfkb23</name>
+ <_description>A4Tech Wireless Desktop RFKB-23</_description>
+ <vendor>A4Tech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>airkey</name>
+ <_description>Acer AirKey V</_description>
+ <vendor>Acer</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>azonaRF2300</name>
+ <_description>Azona RF2300 wireless Internet Keyboard</_description>
+ <vendor>Azona</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>scorpius</name>
+ <_description>Advance Scorpius KI</_description>
+ <vendor>Scorpius</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>brother</name>
+ <_description>Brother Internet Keyboard</_description>
+ <vendor>Brother</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>btc5113rf</name>
+ <_description>BTC 5113RF Multimedia</_description>
+ <vendor>BTC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>btc5126t</name>
+ <_description>BTC 5126T</_description>
+ <vendor>BTC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>btc6301urf</name>
+ <_description>BTC 6301URF</_description>
+ <vendor>BTC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>btc9000</name>
+ <_description>BTC 9000</_description>
+ <vendor>BTC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>btc9000a</name>
+ <_description>BTC 9000A</_description>
+ <vendor>BTC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>btc9001ah</name>
+ <_description>BTC 9001AH</_description>
+ <vendor>BTC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>btc5090</name>
+ <_description>BTC 5090</_description>
+ <vendor>BTC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>btc9019u</name>
+ <_description>BTC 9019U</_description>
+ <vendor>BTC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>btc9116u</name>
+ <_description>BTC 9116U Mini Wireless Internet and Gaming</_description>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>cherryblue</name>
+ <_description>Cherry Blue Line CyBo@rd</_description>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>cherryblueb</name>
+ <_description>Cherry CyMotion Master XPress</_description>
+ <vendor>Cherry</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>cherrybluea</name>
+ <_description>Cherry Blue Line CyBo@rd (alternate option)</_description>
+ <vendor>Cherry</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>cherrycyboard</name>
+ <_description>Cherry CyBo@rd USB-Hub</_description>
+ <vendor>Cherry</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>cherrycmexpert</name>
+ <_description>Cherry CyMotion Expert</_description>
+ <vendor>Cherry</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>cherrybunlim</name>
+ <_description>Cherry B.UNLIMITED</_description>
+ <vendor>Cherry</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>chicony</name>
+ <_description>Chicony Internet Keyboard</_description>
+ <vendor>Chicony</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>chicony0108</name>
+ <_description>Chicony KU-0108</_description>
+ <vendor>Chicony</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>chicony0420</name>
+ <_description>Chicony KU-0420</_description>
+ <vendor>Chicony</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>chicony9885</name>
+ <_description>Chicony KB-9885</_description>
+ <vendor>Chicony</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>compaqeak8</name>
+ <_description>Compaq Easy Access Keyboard</_description>
+ <vendor>Compaq</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>compaqik7</name>
+ <_description>Compaq Internet Keyboard (7 keys)</_description>
+ <vendor>Compaq</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>compaqik13</name>
+ <_description>Compaq Internet Keyboard (13 keys)</_description>
+ <vendor>Compaq</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>compaqik18</name>
+ <_description>Compaq Internet Keyboard (18 keys)</_description>
+ <vendor>Compaq</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>cymotionlinux</name>
+ <_description>Cherry CyMotion Master Linux</_description>
+ <vendor>Cherry</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>armada</name>
+ <_description>Laptop/notebook Compaq (eg. Armada) Laptop Keyboard</_description>
+ <vendor>Compaq</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>presario</name>
+ <_description>Laptop/notebook Compaq (eg. Presario) Internet Keyboard</_description>
+ <vendor>Compaq</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>ipaq</name>
+ <_description>Compaq iPaq Keyboard</_description>
+ <vendor>Compaq</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>dell</name>
+ <_description>Dell</_description>
+ <vendor>Dell</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>dellsk8125</name>
+ <_description>Dell SK-8125</_description>
+ <vendor>Dell</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>dellsk8135</name>
+ <_description>Dell SK-8135</_description>
+ <vendor>Dell</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>dellusbmm</name>
+ <_description>Dell USB Multimedia Keyboard</_description>
+ <vendor>Dell</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>inspiron</name>
+ <_description>Dell Laptop/notebook Inspiron 6xxx/8xxx</_description>
+ <vendor>Dell</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>precision_m</name>
+ <_description>Dell Laptop/notebook Precision M series</_description>
+ <vendor>Dell</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>dexxa</name>
+ <_description>Dexxa Wireless Desktop Keyboard</_description>
+ <vendor>Dexxa</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>diamond</name>
+ <_description>Diamond 9801 / 9802 series</_description>
+ <vendor>Diamond</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>dtk2000</name>
+ <_description>DTK2000</_description>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>ennyah_dkb1008</name>
+ <_description>Ennyah DKB-1008</_description>
+ <vendor>Ennyah</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>fscaa1667g</name>
+ <_description>Fujitsu-Siemens Computers AMILO laptop</_description>
+ <vendor>Fujitsu-Siemens</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>genius</name>
+ <_description>Genius Comfy KB-16M / Genius MM Keyboard KWD-910</_description>
+ <vendor>Genius</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>geniuscomfy</name>
+ <_description>Genius Comfy KB-12e</_description>
+ <vendor>Genius</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>geniuscomfy2</name>
+ <_description>Genius Comfy KB-21e-Scroll</_description>
+ <vendor>Genius</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>geniuskb19e</name>
+ <_description>Genius KB-19e NB</_description>
+ <vendor>Genius</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>geniuskkb2050hs</name>
+ <_description>Genius KKB-2050HS</_description>
+ <vendor>Genius</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>gyration</name>
+ <_description>Gyration</_description>
+ <vendor>Gyration</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>htcdream</name>
+ <_description>HTC Dream</_description>
+ <vendor>HTC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>kinesis</name>
+ <_description>Kinesis</_description>
+ <vendor>Kinesis</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logitech_base</name>
+ <_description>Logitech Generic Keyboard</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logitech_g15</name>
+ <_description>Logitech G15 extra keys via G15daemon</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hpi6</name>
+ <_description>Hewlett-Packard Internet Keyboard</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hp250x</name>
+ <_description>Hewlett-Packard SK-250x Multimedia Keyboard</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hpxe3gc</name>
+ <_description>Hewlett-Packard Omnibook XE3 GC</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hpxe3gf</name>
+ <_description>Hewlett-Packard Omnibook XE3 GF</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hpxt1000</name>
+ <_description>Hewlett-Packard Omnibook XT1000</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hpdv5</name>
+ <_description>Hewlett-Packard Pavilion dv5</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hpzt11xx</name>
+ <_description>Hewlett-Packard Pavilion ZT11xx</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hp500fa</name>
+ <_description>Hewlett-Packard Omnibook 500 FA</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hp5xx</name>
+ <_description>Hewlett-Packard Omnibook 5xx</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hpnx9020</name>
+ <_description>Hewlett-Packard nx9020</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hp6000</name>
+ <_description>Hewlett-Packard Omnibook 6000/6100</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>honeywell_euroboard</name>
+ <_description>Honeywell Euroboard</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hpmini110</name>
+ <_description>Hewlett-Packard Mini 110 Notebook</_description>
+ <vendor>Hewlett-Packard</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>rapidaccess</name>
+ <_description>IBM Rapid Access</_description>
+ <vendor>Lenovo (previously IBM)</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>rapidaccess2</name>
+ <_description>IBM Rapid Access II</_description>
+ <vendor>Lenovo (previously IBM)</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>thinkpad</name>
+ <_description>IBM ThinkPad 560Z/600/600E/A22E</_description>
+ <vendor>Lenovo (previously IBM)</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>thinkpad60</name>
+ <_description>IBM ThinkPad R60/T60/R61/T61</_description>
+ <vendor>Lenovo (previously IBM)</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>thinkpadz60</name>
+ <_description>IBM ThinkPad Z60m/Z60t/Z61m/Z61t</_description>
+ <vendor>Lenovo (previously IBM)</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>ibm_spacesaver</name>
+ <_description>IBM Space Saver</_description>
+ <vendor>Lenovo (previously IBM)</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logiaccess</name>
+ <_description>Logitech Access Keyboard</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logiclx300</name>
+ <_description>Logitech Cordless Desktop LX-300</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logii350</name>
+ <_description>Logitech Internet 350 Keyboard</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logimel</name>
+ <_description>Logitech Media Elite Keyboard</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logicd</name>
+ <_description>Logitech Cordless Desktop</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logicd_it</name>
+ <_description>Logitech Cordless Desktop iTouch</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logicd_nav</name>
+ <_description>Logitech Cordless Desktop Navigator</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logicd_opt</name>
+ <_description>Logitech Cordless Desktop Optical</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logicda</name>
+ <_description>Logitech Cordless Desktop (alternate option)</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logicdpa2</name>
+ <_description>Logitech Cordless Desktop Pro (alternate option 2)</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logicfn</name>
+ <_description>Logitech Cordless Freedom/Desktop Navigator</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logicdn</name>
+ <_description>Logitech Cordless Desktop Navigator</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logiitc</name>
+ <_description>Logitech iTouch Cordless Keyboard (model Y-RB6)</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logiik</name>
+ <_description>Logitech Internet Keyboard</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>itouch</name>
+ <_description>Logitech iTouch</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logicink</name>
+ <_description>Logitech Internet Navigator Keyboard</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logiex110</name>
+ <_description>Logitech Cordless Desktop EX110</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logiinkse</name>
+ <_description>Logitech iTouch Internet Navigator Keyboard SE</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logiinkseusb</name>
+ <_description>Logitech iTouch Internet Navigator Keyboard SE (USB)</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logiultrax</name>
+ <_description>Logitech Ultra-X Keyboard</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logiultraxc</name>
+ <_description>Logitech Ultra-X Cordless Media Desktop Keyboard</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logidinovo</name>
+ <_description>Logitech diNovo Keyboard</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>logidinovoedge</name>
+ <_description>Logitech diNovo Edge Keyboard</_description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>mx1998</name>
+ <_description>Memorex MX1998</_description>
+ <vendor>Memorex</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>mx2500</name>
+ <_description>Memorex MX2500 EZ-Access Keyboard</_description>
+ <vendor>Memorex</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>mx2750</name>
+ <_description>Memorex MX2750</_description>
+ <vendor>Memorex</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoft7000</name>
+ <_description>Microsoft Natural Wireless Ergonomic Keyboard 7000</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoftinet</name>
+ <_description>Microsoft Internet Keyboard</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoftpro</name>
+ <_description>Microsoft Natural Keyboard Pro / Microsoft Internet Keyboard Pro</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoftprousb</name>
+ <_description>Microsoft Natural Keyboard Pro USB / Microsoft Internet Keyboard Pro</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoftprooem</name>
+ <_description>Microsoft Natural Keyboard Pro OEM</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>vsonku306</name>
+ <_description>ViewSonic KU-306 Internet Keyboard</_description>
+ <vendor>ViewSonic</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoftprose</name>
+ <_description>Microsoft Internet Keyboard Pro, Swedish</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoftoffice</name>
+ <_description>Microsoft Office Keyboard</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoftmult</name>
+ <_description>Microsoft Wireless Multimedia Keyboard 1.0A</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoftelite</name>
+ <_description>Microsoft Natural Keyboard Elite</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>microsoftccurve2k</name>
+ <_description>Microsoft Comfort Curve Keyboard 2000</_description>
+ <vendor>Microsoft Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>oretec</name>
+ <_description>Ortek MCK-800 MM/Internet keyboard</_description>
+ <vendor>Ortek</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>propeller</name>
+ <_description>Propeller Voyager (KTEZ-1000)</_description>
+ <vendor>KeyTronic</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>qtronix</name>
+ <_description>QTronix Scorpius 98N+</_description>
+ <vendor>QTronix</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>samsung4500</name>
+ <_description>Samsung SDM 4500P</_description>
+ <vendor>Samsung</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>samsung4510</name>
+ <_description>Samsung SDM 4510P</_description>
+ <vendor>Samsung</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>sanwaskbkg3</name>
+ <_description>Sanwa Supply SKB-KG3</_description>
+ <vendor>Sanwa Supply Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>sk1300</name>
+ <_description>SK-1300</_description>
+ <vendor>NEC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>sk2500</name>
+ <_description>SK-2500</_description>
+ <vendor>NEC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>sk6200</name>
+ <_description>SK-6200</_description>
+ <vendor>NEC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>sk7100</name>
+ <_description>SK-7100</_description>
+ <vendor>NEC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>sp_inet</name>
+ <_description>Super Power Multimedia Keyboard</_description>
+ <vendor>Generic</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>sven</name>
+ <_description>SVEN Ergonomic 2500</_description>
+ <vendor>SVEN</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>sven303</name>
+ <_description>SVEN Slim 303</_description>
+ <vendor>SVEN</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>symplon</name>
+ <_description>Symplon PaceBook (tablet PC)</_description>
+ <vendor>Symplon</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>toshiba_s3000</name>
+ <_description>Toshiba Satellite S3000</_description>
+ <vendor>Toshiba</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>trust</name>
+ <_description>Trust Wireless Keyboard Classic</_description>
+ <vendor>Trust</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>trustda</name>
+ <_description>Trust Direct Access Keyboard</_description>
+ <vendor>Trust</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>trust_slimline</name>
+ <_description>Trust Slimline</_description>
+ <vendor>Trust</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>tm2020</name>
+ <_description>TypeMatrix EZ-Reach 2020</_description>
+ <vendor>TypeMatrix</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>tm2030PS2</name>
+ <_description>TypeMatrix EZ-Reach 2030 PS2</_description>
+ <vendor>TypeMatrix</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>tm2030USB</name>
+ <_description>TypeMatrix EZ-Reach 2030 USB</_description>
+ <vendor>TypeMatrix</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>tm2030USB-102</name>
+ <_description>TypeMatrix EZ-Reach 2030 USB (102/105:EU mode)</_description>
+ <vendor>TypeMatrix</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>tm2030USB-106</name>
+ <_description>TypeMatrix EZ-Reach 2030 USB (106:JP mode)</_description>
+ <vendor>TypeMatrix</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>yahoo</name>
+ <_description>Yahoo! Internet Keyboard</_description>
+ <vendor>Yahoo!</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>macbook78</name>
+ <_description>MacBook/MacBook Pro</_description>
+ <vendor>Apple</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>macbook79</name>
+ <_description>MacBook/MacBook Pro (Intl)</_description>
+ <vendor>Apple</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>macintosh</name>
+ <_description>Macintosh</_description>
+ <vendor>Apple</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>macintosh_old</name>
+ <_description>Macintosh Old</_description>
+ <vendor>Apple</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>macintosh_hhk</name>
+ <_description>Happy Hacking Keyboard for Mac</_description>
+ <vendor>Fujitsu</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>acer_c300</name>
+ <_description>Acer C300</_description>
+ <vendor>Acer</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>acer_ferrari4k</name>
+ <_description>Acer Ferrari 4000</_description>
+ <vendor>Acer</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>acer_laptop</name>
+ <_description>Acer Laptop</_description>
+ <vendor>Acer</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>asus_laptop</name>
+ <_description>Asus Laptop</_description>
+ <vendor>Asus</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>apple</name>
+ <_description>Apple</_description>
+ <vendor>Apple</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>apple_laptop</name>
+ <_description>Apple Laptop</_description>
+ <vendor>Apple</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>applealu_ansi</name>
+ <_description>Apple Aluminium Keyboard (ANSI)</_description>
+ <vendor>Apple</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>applealu_iso</name>
+ <_description>Apple Aluminium Keyboard (ISO)</_description>
+ <vendor>Apple</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>applealu_jis</name>
+ <_description>Apple Aluminium Keyboard (JIS)</_description>
+ <vendor>Apple</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>silvercrest</name>
+ <_description>SILVERCREST Multimedia Wireless Keyboard</_description>
+ <vendor>Silvercrest</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>emachines</name>
+ <_description>Laptop/notebook eMachines m68xx</_description>
+ <vendor>eMachines</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>benqx</name>
+ <_description>BenQ X-Touch</_description>
+ <vendor>BenQ</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>benqx730</name>
+ <_description>BenQ X-Touch 730</_description>
+ <vendor>BenQ</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>benqx800</name>
+ <_description>BenQ X-Touch 800</_description>
+ <vendor>BenQ</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>hhk</name>
+ <_description>Happy Hacking Keyboard</_description>
+ <vendor>Fujitsu</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>classmate</name>
+ <_description>Classmate PC</_description>
+ <vendor>Intel</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>olpc</name>
+ <_description>OLPC</_description>
+ <vendor>OLPC</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>sun6</name>
+ <_description>Sun Type 5/6</_description>
+ <vendor>Sun Microsystems</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>targa_v811</name>
+ <_description>Targa Visionary 811</_description>
+ <vendor>Targa</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>unitekkb1925</name>
+ <_description>Unitek KB-1925</_description>
+ <vendor>Unitek Group</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>compalfl90</name>
+ <_description>FL90</_description>
+ <vendor>Compal Electronics Inc.</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>creativedw7000</name>
+ <_description>Creative Desktop Wireless 7000</_description>
+ <vendor>Creative</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
+ <name>htcdream</name>
+ <_description>Htc Dream phone</_description>
+ <vendor>htc</vendor>
+ </configItem>
+ </model>
+ </modelList>
+ <layoutList>
+ <layout>
+ <configItem>
+ <name>us</name>
+ <_shortDescription>USA</_shortDescription>
+ <_description>USA</_description>
+ <languageList>
+ <iso639Id>eng</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>chr</name>
+ <_description>USA - Cherokee</_description>
+ <languageList>
+ <iso639Id>chr</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>euro</name>
+ <_description>USA - With EuroSign on 5</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>intl</name>
+ <_description>USA - International (with dead keys)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>alt-intl</name>
+ <_description>USA - Alternative international</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>colemak</name>
+ <_description>USA - Colemak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>USA - Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak-intl</name>
+ <_description>USA - Dvorak international (with dead keys)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak-alt-intl</name>
+ <_description>USA - Dvorak alternative international (no dead keys)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak-l</name>
+ <_description>USA - Left handed Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak-r</name>
+ <_description>USA - Right handed Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak-classic</name>
+ <_description>USA - Classic Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvp</name>
+ <_description>USA - Programmer Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>rus</name>
+ <_description>USA - Russian phonetic</_description>
+ <languageList>
+ <iso639Id>rus</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>USA - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>altgr-intl</name>
+ <_description>USA - International (AltGr dead keys)</_description>
+ <languageList><iso639Id>eng</iso639Id>
+ <iso639Id>fra</iso639Id>
+ <iso639Id>ger</iso639Id></languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>olpc2</name>
+ <_description>USA - Layout toggle on multiply/divide key</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>hbs</name>
+ <_description>USA - Serbo-Croatian</_description>
+ <languageList><iso639Id>eng</iso639Id>
+ <iso639Id>bos</iso639Id>
+ <iso639Id>hbs</iso639Id>
+ <iso639Id>hrv</iso639Id>
+ <iso639Id>srp</iso639Id> </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ad</name>
+ <_shortDescription>And</_shortDescription>
+ <_description>Andorra</_description>
+ <languageList>
+ <iso639Id>cat</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>af</name>
+ <_shortDescription>Afg</_shortDescription>
+ <_description>Afghanistan</_description>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>ps</name>
+ <_description>Afghanistan - Pashto</_description>
+ <languageList>
+ <iso639Id>pus</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>uz</name>
+ <_description>Afghanistan - Southern Uzbek</_description>
+ <languageList>
+ <iso639Id>uzb</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>olpc-ps</name>
+ <_description>Afghanistan - OLPC Pashto</_description>
+ <languageList>
+ <iso639Id>pus</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>fa-olpc</name>
+ <_description>Afghanistan - OLPC Dari</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>uz-olpc</name>
+ <_description>Afghanistan - OLPC Southern Uzbek</_description>
+ <languageList>
+ <iso639Id>uzb</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ara</name>
+ <_shortDescription>Ara</_shortDescription>
+ <_description>Arabic</_description>
+ <countryList>
+ <iso3166Id>AE</iso3166Id>
+ <iso3166Id>BH</iso3166Id>
+ <iso3166Id>DZ</iso3166Id>
+ <iso3166Id>EG</iso3166Id>
+ <iso3166Id>EH</iso3166Id>
+ <iso3166Id>JO</iso3166Id>
+ <iso3166Id>KW</iso3166Id>
+ <iso3166Id>LB</iso3166Id>
+ <iso3166Id>LY</iso3166Id>
+ <iso3166Id>MA</iso3166Id>
+ <iso3166Id>MR</iso3166Id>
+ <iso3166Id>OM</iso3166Id>
+ <iso3166Id>PS</iso3166Id>
+ <iso3166Id>QA</iso3166Id>
+ <iso3166Id>SA</iso3166Id>
+ <iso3166Id>SD</iso3166Id>
+ <iso3166Id>SY</iso3166Id>
+ <iso3166Id>TN</iso3166Id>
+ <iso3166Id>YE</iso3166Id>
+ </countryList>
+ <languageList>
+ <iso639Id>ara</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>azerty</name>
+ <_description>Arabic - azerty</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>azerty_digits</name>
+ <_description>Arabic - azerty/digits</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>digits</name>
+ <_description>Arabic - digits</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>qwerty</name>
+ <_description>Arabic - qwerty</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>qwerty_digits</name>
+ <_description>Arabic - qwerty/digits</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>buckwalter</name>
+ <_description>Arabic - Buckwalter</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>al</name>
+ <_shortDescription>Alb</_shortDescription>
+ <_description>Albania</_description>
+ <languageList>
+ <iso639Id>alb</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>am</name>
+ <_shortDescription>Arm</_shortDescription>
+ <_description>Armenia</_description>
+ <languageList>
+ <iso639Id>hye</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>phonetic</name>
+ <_description>Armenia - Phonetic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>phonetic-alt</name>
+ <_description>Armenia - Alternative Phonetic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>eastern</name>
+ <_description>Armenia - Eastern</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>western</name>
+ <_description>Armenia - Western</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>eastern-alt</name>
+ <_description>Armenia - Alternative Eastern</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>at</name>
+ <_shortDescription>Aut</_shortDescription>
+ <_description>Austria</_description>
+ <languageList>
+ <iso639Id>ger</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Austria - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>sundeadkeys</name>
+ <_description>Austria - Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Austria - Macintosh</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>az</name>
+ <_shortDescription>Aze</_shortDescription>
+ <_description>Azerbaijan</_description>
+ <languageList>
+ <iso639Id>aze</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>cyrillic</name>
+ <_description>Azerbaijan - Cyrillic</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>by</name>
+ <_shortDescription>Blr</_shortDescription>
+ <_description>Belarus</_description>
+ <languageList>
+ <iso639Id>bel</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>legacy</name>
+ <_description>Belarus - Legacy</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latin</name>
+ <_description>Belarus - Latin</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>be</name>
+ <_shortDescription>Bel</_shortDescription>
+ <_description>Belgium</_description>
+ <languageList><iso639Id>ger</iso639Id>
+ <iso639Id>nld</iso639Id>
+ <iso639Id>fra</iso639Id></languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>oss</name>
+ <_description>Belgium - Alternative</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>oss_latin9</name>
+ <_description>Belgium - Alternative, latin-9 only</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>oss_sundeadkeys</name>
+ <_description>Belgium - Alternative, Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>iso-alternate</name>
+ <_description>Belgium - ISO Alternate</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Belgium - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>sundeadkeys</name>
+ <_description>Belgium - Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>wang</name>
+ <_description>Belgium - Wang model 724 azerty</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>bd</name>
+ <_shortDescription>Bgd</_shortDescription>
+ <_description>Bangladesh</_description>
+ <languageList>
+ <iso639Id>ben</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>probhat</name>
+ <_description>Bangladesh - Probhat</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>in</name>
+ <_shortDescription>Ind</_shortDescription>
+ <_description>India</_description>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>ben</name>
+ <_description>India - Bengali</_description>
+ <languageList>
+ <iso639Id>ben</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ben_probhat</name>
+ <_description>India - Bengali Probhat</_description>
+ <languageList>
+ <iso639Id>ben</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>guj</name>
+ <_description>India - Gujarati</_description>
+ <languageList>
+ <iso639Id>guj</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>guru</name>
+ <_description>India - Gurmukhi</_description>
+ <languageList>
+ <iso639Id>pan</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>jhelum</name>
+ <_description>India - Gurmukhi Jhelum</_description>
+ <languageList>
+ <iso639Id>pan</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>kan</name>
+ <_description>India - Kannada</_description>
+ <languageList>
+ <iso639Id>kan</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mal</name>
+ <_description>India - Malayalam</_description>
+ <languageList>
+ <iso639Id>mal</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mal_lalitha</name>
+ <_description>India - Malayalam Lalitha</_description>
+ <languageList>
+ <iso639Id>mal</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ori</name>
+ <_description>India - Oriya</_description>
+ <languageList>
+ <iso639Id>ori</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tam_unicode</name>
+ <_description>India - Tamil Unicode</_description>
+ <languageList>
+ <iso639Id>tam</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tam_keyboard_with_numerals</name>
+ <_description>India - Tamil Keyboard with Numerals</_description>
+ <languageList>
+ <iso639Id>tam</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tam_TAB</name>
+ <_description>India - Tamil TAB Typewriter</_description>
+ <languageList>
+ <iso639Id>tam</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tam_TSCII</name>
+ <_description>India - Tamil TSCII Typewriter</_description>
+ <languageList>
+ <iso639Id>tam</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tam</name>
+ <_description>India - Tamil</_description>
+ <languageList>
+ <iso639Id>tam</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tel</name>
+ <_description>India - Telugu</_description>
+ <languageList>
+ <iso639Id>tel</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>urd-phonetic</name>
+ <_description>India - Urdu, Phonetic</_description>
+ <languageList>
+ <iso639Id>urd</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>urd-phonetic3</name>
+ <_description>India - Urdu, Alternative phonetic</_description>
+ <languageList>
+ <iso639Id>urd</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>urd-winkeys</name>
+ <_description>India - Urdu, Winkeys</_description>
+ <languageList>
+ <iso639Id>urd</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>bolnagri</name>
+ <_description>India - Hindi Bolnagri</_description>
+ <languageList>
+ <iso639Id>hin</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>hin-wx</name>
+ <_description>India - Hindi Wx</_description>
+ <languageList>
+ <iso639Id>hin</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>eng</name>
+ <_description>India - English with RupeeSign</_description>
+ <languageList>
+ <iso639Id>eng</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ba</name>
+ <_shortDescription>Bih</_shortDescription>
+ <_description>Bosnia and Herzegovina</_description>
+ <languageList>
+ <iso639Id>bos</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>alternatequotes</name>
+ <_description>Bosnia and Herzegovina - Use guillemets for quotes</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>unicode</name>
+ <_description>Bosnia and Herzegovina - Use Bosnian digraphs</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>unicodeus</name>
+ <_description>Bosnia and Herzegovina - US keyboard with Bosnian digraphs</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>us</name>
+ <_description>Bosnia and Herzegovina - US keyboard with Bosnian letters</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>br</name>
+ <_shortDescription>Bra</_shortDescription>
+ <_description>Brazil</_description>
+ <languageList>
+ <iso639Id>por</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Brazil - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Brazil - Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nativo</name>
+ <_description>Brazil - Nativo</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nativo-us</name>
+ <_description>Brazil - Nativo for USA keyboards</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nativo-epo</name>
+ <_description>Brazil - Nativo for Esperanto</_description>
+ <languageList>
+ <iso639Id>epo</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>bg</name>
+ <_shortDescription>Bgr</_shortDescription>
+ <_description>Bulgaria</_description>
+ <languageList>
+ <iso639Id>bul</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>phonetic</name>
+ <_description>Bulgaria - Traditional phonetic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>bas_phonetic</name>
+ <_description>Bulgaria - New phonetic</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ma</name>
+ <_description>Morocco</_description>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>french</name>
+ <_description>Morocco - French</_description>
+ <languageList>
+ <iso639Id>fra</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tifinagh</name>
+ <_description>Morocco - Tifinagh</_description>
+ <languageList>
+ <iso639Id>ber</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tifinagh-alt</name>
+ <_description>Morocco - Tifinagh alternative</_description>
+ <languageList>
+ <iso639Id>ber</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tifinagh-alt-phonetic</name>
+ <_description>Morocco - Tifinagh alternative phonetic</_description>
+ <languageList>
+ <iso639Id>ber</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tifinagh-extended</name>
+ <_description>Morocco - Tifinagh extended</_description>
+ <languageList>
+ <iso639Id>ber</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tifinagh-phonetic</name>
+ <_description>Morocco - Tifinagh phonetic</_description>
+ <languageList>
+ <iso639Id>ber</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tifinagh-extended-phonetic</name>
+ <_description>Morocco - Tifinagh extended phonetic</_description>
+ <languageList>
+ <iso639Id>ber</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>mm</name>
+ <_shortDescription>Mmr</_shortDescription>
+ <_description>Myanmar</_description>
+ <languageList>
+ <iso639Id>mya</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ca</name>
+ <_shortDescription>Can</_shortDescription>
+ <_description>Canada</_description>
+ <languageList>
+ <iso639Id>fra</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>fr-dvorak</name>
+ <_description>Canada - French Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>fr-legacy</name>
+ <_description>Canada - French (legacy)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>multix</name>
+ <_description>Canada - Multilingual</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>multi</name>
+ <_description>Canada - Multilingual, first part</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>multi-2gr</name>
+ <_description>Canada - Multilingual, second part</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ike</name>
+ <_description>Canada - Inuktitut</_description>
+ <languageList>
+ <iso639Id>iku</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>shs</name>
+ <_description>Canada - Secwepemctsin</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>kut</name>
+ <_description>Canada - Ktunaxa</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>eng</name>
+ <_description>Canada - English</_description>
+ <languageList>
+ <iso639Id>eng</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>cd</name>
+ <_shortDescription>COD</_shortDescription>
+ <_description>Congo, Democratic Republic of the</_description>
+ <languageList>
+ <iso639Id>fra</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>cn</name>
+ <_shortDescription>Chn</_shortDescription>
+ <_description>China</_description>
+ <languageList>
+ <iso639Id>chi</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>tib</name>
+ <_description>China - Tibetan</_description>
+ <languageList>
+ <iso639Id>tib</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tib_asciinum</name>
+ <_description>China - Tibetan (with ASCII numerals)</_description>
+ <languageList>
+ <iso639Id>tib</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>uig</name>
+ <_description>China - Uyghur</_description>
+ <languageList>
+ <iso639Id>uig</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>hr</name>
+ <_shortDescription>Hrv</_shortDescription>
+ <_description>Croatia</_description>
+ <languageList>
+ <iso639Id>scr</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>alternatequotes</name>
+ <_description>Croatia - Use guillemets for quotes</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>unicode</name>
+ <_description>Croatia - Use Croatian digraphs</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>unicodeus</name>
+ <_description>Croatia - US keyboard with Croatian digraphs</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>us</name>
+ <_description>Croatia - US keyboard with Croatian letters</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>cz</name>
+ <_shortDescription>Cze</_shortDescription>
+ <_description>Czechia</_description>
+ <languageList>
+ <iso639Id>cze</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>bksl</name>
+ <_description>Czechia - With &lt;\|&gt; key</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>qwerty</name>
+ <_description>Czechia - qwerty</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>qwerty_bksl</name>
+ <_description>Czechia - qwerty, extended Backslash</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ucw</name>
+ <_description>Czechia - UCW layout (accented letters only)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak-ucw</name>
+ <_description>Czechia - US Dvorak with CZ UCW support</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>dk</name>
+ <_shortDescription>Dnk</_shortDescription>
+ <_description>Denmark</_description>
+ <languageList>
+ <iso639Id>dan</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Denmark - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Denmark - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac_nodeadkeys</name>
+ <_description>Denmark - Macintosh, eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Denmark - Dvorak</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>nl</name>
+ <_shortDescription>Nld</_shortDescription>
+ <_description>Netherlands</_description>
+ <languageList>
+ <iso639Id>nld</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>sundeadkeys</name>
+ <_description>Netherlands - Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Netherlands - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>std</name>
+ <_description>Netherlands - Standard</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>bt</name>
+ <_shortDescription>Btn</_shortDescription>
+ <_description>Bhutan</_description>
+ <languageList>
+ <iso639Id>dzo</iso639Id>
+ </languageList>
+ </configItem>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ee</name>
+ <_shortDescription>Est</_shortDescription>
+ <_description>Estonia</_description>
+ <languageList>
+ <iso639Id>est</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Estonia - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Estonia - Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>us</name>
+ <_description>Estonia - US keyboard with Estonian letters</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ir</name>
+ <_shortDescription>Irn</_shortDescription>
+ <_description>Iran</_description>
+ <languageList>
+ <iso639Id>per</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>pes_keypad</name>
+ <_description>Iran - Persian, with Persian Keypad</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku</name>
+ <_description>Iran - Kurdish, Latin Q</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku_f</name>
+ <_description>Iran - Kurdish, (F)</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku_alt</name>
+ <_description>Iran - Kurdish, Latin Alt-Q</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku_ara</name>
+ <_description>Iran - Kurdish, Arabic-Latin</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>iq</name>
+ <_shortDescription>Irq</_shortDescription>
+ <_description>Iraq</_description>
+ <languageList><iso639Id>ara</iso639Id>
+ <iso639Id>kur</iso639Id></languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>ku</name>
+ <_description>Iraq - Kurdish, Latin Q</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku_f</name>
+ <_description>Iraq - Kurdish, (F)</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku_alt</name>
+ <_description>Iraq - Kurdish, Latin Alt-Q</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku_ara</name>
+ <_description>Iraq - Kurdish, Arabic-Latin</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>fo</name>
+ <_shortDescription>Fro</_shortDescription>
+ <_description>Faroe Islands</_description>
+ <languageList>
+ <iso639Id>fao</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Faroe Islands - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>fi</name>
+ <_shortDescription>Fin</_shortDescription>
+ <_description>Finland</_description>
+ <languageList>
+ <iso639Id>fin</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>classic</name>
+ <_description>Finland - Classic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Finland - Classic, eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>smi</name>
+ <_description>Finland - Northern Saami</_description>
+ <languageList><iso639Id>smi</iso639Id>
+ <iso639Id>sme</iso639Id></languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Finland - Macintosh</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>fr</name>
+ <_shortDescription>Fra</_shortDescription>
+ <_description>France</_description>
+ <languageList>
+ <iso639Id>fra</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>France - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>sundeadkeys</name>
+ <_description>France - Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>oss</name>
+ <_description>France - Alternative</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>oss_latin9</name>
+ <_description>France - Alternative, latin-9 only</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>oss_nodeadkeys</name>
+ <_description>France - Alternative, eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>oss_sundeadkeys</name>
+ <_description>France - Alternative, Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latin9</name>
+ <_description>France - (Legacy) Alternative</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latin9_nodeadkeys</name>
+ <_description>France - (Legacy) Alternative, eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latin9_sundeadkeys</name>
+ <_description>France - (Legacy) Alternative, Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>bepo</name>
+ <_description>France - Bepo, ergonomic, Dvorak way</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>bepo_latin9</name>
+ <_description>France - Bepo, ergonomic, Dvorak way, latin-9 only</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>France - Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>France - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>bre</name>
+ <_description>France - Breton</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>oci</name>
+ <_description>France - Occitan</_description>
+ <languageList>
+ <iso639Id>oci</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>geo</name>
+ <_description>France - Georgian AZERTY Tskapo</_description>
+ <languageList>
+ <iso639Id>geo</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>gh</name>
+ <_shortDescription>Gha</_shortDescription>
+ <_description>Ghana</_description>
+ <languageList>
+ <iso639Id>eng</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>generic</name>
+ <_description>Ghana - Multilingual</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>akan</name>
+ <_description>Ghana - Akan</_description>
+ <languageList>
+ <iso639Id>aka</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ewe</name>
+ <_description>Ghana - Ewe</_description>
+ <languageList>
+ <iso639Id>ewe</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>fula</name>
+ <_description>Ghana - Fula</_description>
+ <languageList>
+ <iso639Id>ful</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ga</name>
+ <_description>Ghana - Ga</_description>
+ <languageList>
+ <iso639Id>gaa</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>hausa</name>
+ <_description>Ghana - Hausa</_description>
+ <languageList>
+ <iso639Id>hau</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>avn</name>
+ <_description>Ghana - Avatime</_description>
+ <languageList>
+ <iso639Id>avn</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>gillbt</name>
+ <_description>Ghana - GILLBT</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>gn</name>
+ <_shortDescription>Gin</_shortDescription>
+ <_description>Guinea</_description>
+ <languageList>
+ <iso639Id>fra</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ge</name>
+ <_shortDescription>Geo</_shortDescription>
+ <_description>Georgia</_description>
+ <languageList>
+ <iso639Id>geo</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>ergonomic</name>
+ <_description>Georgia - Ergonomic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mess</name>
+ <_description>Georgia - MESS</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ru</name>
+ <_description>Georgia - Russian</_description>
+ <languageList>
+ <iso639Id>rus</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>os</name>
+ <_description>Georgia - Ossetian</_description>
+ <languageList>
+ <iso639Id>oss</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>de</name>
+ <_shortDescription>Deu</_shortDescription>
+ <_description>Germany</_description>
+ <languageList>
+ <iso639Id>ger</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>deadacute</name>
+ <_description>Germany - Dead acute</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>deadgraveacute</name>
+ <_description>Germany - Dead grave acute</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Germany - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ro</name>
+ <_description>Germany - Romanian keyboard with German letters</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ro_nodeadkeys</name>
+ <_description>Germany - Romanian keyboard with German letters, eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Germany - Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>sundeadkeys</name>
+ <_description>Germany - Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>neo</name>
+ <_description>Germany - Neo 2</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Germany - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac_nodeadkeys</name>
+ <_description>Germany - Macintosh, eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dsb</name>
+ <_description>Germany - Lower Sorbian</_description>
+ <languageList>
+ <iso639Id>dsb</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dsb_qwertz</name>
+ <_description>Germany - Lower Sorbian (qwertz)</_description>
+ <languageList>
+ <iso639Id>dsb</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>qwerty</name>
+ <_description>Germany - qwerty</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ru</name>
+ <_description>Germany - Russian phonetic</_description>
+ <languageList>
+ <iso639Id>rus</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>gr</name>
+ <_shortDescription>Grc</_shortDescription>
+ <_description>Greece</_description>
+ <languageList>
+ <iso639Id>gre</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>simple</name>
+ <_description>Greece - Simple</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>extended</name>
+ <_description>Greece - Extended</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Greece - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>polytonic</name>
+ <_description>Greece - Polytonic</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>hu</name>
+ <_shortDescription>Hun</_shortDescription>
+ <_description>Hungary</_description>
+ <languageList>
+ <iso639Id>hun</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>standard</name>
+ <_description>Hungary - Standard</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Hungary - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>qwerty</name>
+ <_description>Hungary - qwerty</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>101_qwertz_comma_dead</name>
+ <_description>Hungary - 101/qwertz/comma/Dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>101_qwertz_comma_nodead</name>
+ <_description>Hungary - 101/qwertz/comma/Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>101_qwertz_dot_dead</name>
+ <_description>Hungary - 101/qwertz/dot/Dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>101_qwertz_dot_nodead</name>
+ <_description>Hungary - 101/qwertz/dot/Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>101_qwerty_comma_dead</name>
+ <_description>Hungary - 101/qwerty/comma/Dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>101_qwerty_comma_nodead</name>
+ <_description>Hungary - 101/qwerty/comma/Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>101_qwerty_dot_dead</name>
+ <_description>Hungary - 101/qwerty/dot/Dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>101_qwerty_dot_nodead</name>
+ <_description>Hungary - 101/qwerty/dot/Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>102_qwertz_comma_dead</name>
+ <_description>Hungary - 102/qwertz/comma/Dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>102_qwertz_comma_nodead</name>
+ <_description>Hungary - 102/qwertz/comma/Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>102_qwertz_dot_dead</name>
+ <_description>Hungary - 102/qwertz/dot/Dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>102_qwertz_dot_nodead</name>
+ <_description>Hungary - 102/qwertz/dot/Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>102_qwerty_comma_dead</name>
+ <_description>Hungary - 102/qwerty/comma/Dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>102_qwerty_comma_nodead</name>
+ <_description>Hungary - 102/qwerty/comma/Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>102_qwerty_dot_dead</name>
+ <_description>Hungary - 102/qwerty/dot/Dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>102_qwerty_dot_nodead</name>
+ <_description>Hungary - 102/qwerty/dot/Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>is</name>
+ <_shortDescription>Isl</_shortDescription>
+ <_description>Iceland</_description>
+ <languageList>
+ <iso639Id>ice</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>Sundeadkeys</name>
+ <_description>Iceland - Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Iceland - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Iceland - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Iceland - Dvorak</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>il</name>
+ <_shortDescription>Isr</_shortDescription>
+ <_description>Israel</_description>
+ <languageList>
+ <iso639Id>heb</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>lyx</name>
+ <_description>Israel - lyx</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>phonetic</name>
+ <_description>Israel - Phonetic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>biblical</name>
+ <_description>Israel - Biblical Hebrew (Tiro)</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>it</name>
+ <_shortDescription>Ita</_shortDescription>
+ <_description>Italy</_description>
+ <languageList>
+ <iso639Id>ita</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Italy - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Italy - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>us</name>
+ <_description>Italy - US keyboard with Italian letters</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>geo</name>
+ <_description>Italy - Georgian</_description>
+ <languageList>
+ <iso639Id>geo</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>jp</name>
+ <_shortDescription>Jpn</_shortDescription>
+ <_description>Japan</_description>
+ <languageList>
+ <iso639Id>jpn</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>kana</name>
+ <_description>Japan - Kana</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>kana86</name>
+ <_description>Japan - Kana 86</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>OADG109A</name>
+ <_description>Japan - OADG 109A</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Japan - Macintosh</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>kg</name>
+ <_shortDescription>Kgz</_shortDescription>
+ <_description>Kyrgyzstan</_description>
+ <languageList>
+ <iso639Id>kir</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>phonetic</name>
+ <_description>Kyrgyzstan - Phonetic</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>kh</name>
+ <_shortDescription>Khm</_shortDescription>
+ <_description>Cambodia</_description>
+ <languageList>
+ <iso639Id>khm</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>kz</name>
+ <_shortDescription>Kaz</_shortDescription>
+ <_description>Kazakhstan</_description>
+ <languageList>
+ <iso639Id>kaz</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>ruskaz</name>
+ <_description>Kazakhstan - Russian with Kazakh</_description>
+ <languageList><iso639Id>kaz</iso639Id>
+ <iso639Id>rus</iso639Id></languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>kazrus</name>
+ <_description>Kazakhstan - Kazakh with Russian</_description>
+ <languageList><iso639Id>kaz</iso639Id>
+ <iso639Id>rus</iso639Id></languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>la</name>
+ <_shortDescription>Lao</_shortDescription>
+ <_description>Laos</_description>
+ <languageList>
+ <iso639Id>lao</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>stea</name>
+ <_description>Laos - STEA (proposed standard layout)</_description>
+ <languageList><iso639Id>lao</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>latam</name>
+ <_shortDescription>Esp</_shortDescription>
+ <_description>Latin American</_description>
+ <countryList>
+ <iso3166Id>AR</iso3166Id>
+ <iso3166Id>BO</iso3166Id>
+ <iso3166Id>CL</iso3166Id>
+ <iso3166Id>CO</iso3166Id>
+ <iso3166Id>CR</iso3166Id>
+ <iso3166Id>CU</iso3166Id>
+ <iso3166Id>DO</iso3166Id>
+ <iso3166Id>EC</iso3166Id>
+ <iso3166Id>GT</iso3166Id>
+ <iso3166Id>HN</iso3166Id>
+ <iso3166Id>HT</iso3166Id>
+ <iso3166Id>MX</iso3166Id>
+ <iso3166Id>NI</iso3166Id>
+ <iso3166Id>PA</iso3166Id>
+ <iso3166Id>PE</iso3166Id>
+ <iso3166Id>PR</iso3166Id>
+ <iso3166Id>PY</iso3166Id>
+ <iso3166Id>SV</iso3166Id>
+ <iso3166Id>US</iso3166Id>
+ <iso3166Id>UY</iso3166Id>
+ <iso3166Id>VE</iso3166Id>
+ </countryList>
+ <languageList>
+ <iso639Id>spa</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Latin American - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>deadtilde</name>
+ <_description>Latin American - Include dead tilde</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>sundeadkeys</name>
+ <_description>Latin American - Sun dead keys</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>lt</name>
+ <_shortDescription>Ltu</_shortDescription>
+ <_description>Lithuania</_description>
+ <languageList>
+ <iso639Id>lit</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>std</name>
+ <_description>Lithuania - Standard</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>us</name>
+ <_description>Lithuania - US keyboard with Lithuanian letters</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ibm</name>
+ <_description>Lithuania - IBM (LST 1205-92)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>lekp</name>
+ <_description>Lithuania - LEKP</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>lekpa</name>
+ <_description>Lithuania - LEKPa</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>lv</name>
+ <_shortDescription>Lva</_shortDescription>
+ <_description>Latvia</_description>
+ <languageList>
+ <iso639Id>lav</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>apostrophe</name>
+ <_description>Latvia - Apostrophe (') variant</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tilde</name>
+ <_description>Latvia - Tilde (~) variant</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>fkey</name>
+ <_description>Latvia - F-letter (F) variant</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>mao</name>
+ <_shortDescription>Mao</_shortDescription>
+ <_description>Maori</_description>
+ <languageList>
+ <iso639Id>mao</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>me</name>
+ <_shortDescription>MNE</_shortDescription>
+ <_description>Montenegro</_description>
+ <languageList>
+ <iso639Id>srp</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>cyrillic</name>
+ <_description>Montenegro - Cyrillic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>cyrillicyz</name>
+ <_description>Montenegro - Cyrillic, Z and ZHE swapped</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latinunicode</name>
+ <_description>Montenegro - Latin unicode</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latinyz</name>
+ <_description>Montenegro - Latin qwerty</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latinunicodeyz</name>
+ <_description>Montenegro - Latin unicode qwerty</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>cyrillicalternatequotes</name>
+ <_description>Montenegro - Cyrillic with guillemets</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latinalternatequotes</name>
+ <_description>Montenegro - Latin with guillemets</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>mk</name>
+ <_shortDescription>Mkd</_shortDescription>
+ <_description>Macedonia</_description>
+ <languageList>
+ <iso639Id>mkd</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Macedonia - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>mt</name>
+ <_shortDescription>Mlt</_shortDescription>
+ <_description>Malta</_description>
+ <languageList>
+ <iso639Id>mlt</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>us</name>
+ <_description>Malta - Maltese keyboard with US layout</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>mn</name>
+ <_shortDescription>Mng</_shortDescription>
+ <_description>Mongolia</_description>
+ <languageList>
+ <iso639Id>mng</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>no</name>
+ <_shortDescription>Nor</_shortDescription>
+ <_description>Norway</_description>
+ <languageList>
+ <iso639Id>nor</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Norway - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Norway - Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>smi</name>
+ <_description>Norway - Northern Saami</_description>
+ <languageList>
+ <iso639Id>sme</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>smi_nodeadkeys</name>
+ <_description>Norway - Northern Saami, eliminate dead keys</_description>
+ <languageList>
+ <iso639Id>sme</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Norway - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac_nodeadkeys</name>
+ <_description>Norway - Macintosh, eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>pl</name>
+ <_shortDescription>Pol</_shortDescription>
+ <_description>Poland</_description>
+ <languageList>
+ <iso639Id>pol</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>qwertz</name>
+ <_description>Poland - qwertz</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Poland - Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak_quotes</name>
+ <_description>Poland - Dvorak, Polish quotes on quotemark key</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak_altquotes</name>
+ <_description>Poland - Dvorak, Polish quotes on key 1</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>csb</name>
+ <_description>Poland - Kashubian</_description>
+ <languageList>
+ <iso639Id>csb</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ru_phonetic_dvorak</name>
+ <_description>Poland - Russian phonetic Dvorak</_description>
+ <languageList>
+ <iso639Id>rus</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvp</name>
+ <_description>Poland - Programmer Dvorak</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>pt</name>
+ <_shortDescription>Prt</_shortDescription>
+ <_description>Portugal</_description>
+ <languageList>
+ <iso639Id>por</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Portugal - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>sundeadkeys</name>
+ <_description>Portugal - Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Portugal - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac_nodeadkeys</name>
+ <_description>Portugal - Macintosh, eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac_sundeadkeys</name>
+ <_description>Portugal - Macintosh, Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nativo</name>
+ <_description>Portugal - Nativo</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nativo-us</name>
+ <_description>Portugal - Nativo for USA keyboards</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>nativo-epo</name>
+ <_description>Portugal - Nativo for Esperanto</_description>
+ <languageList>
+ <iso639Id>epo</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ro</name>
+ <_shortDescription>Rou</_shortDescription>
+ <_description>Romania</_description>
+ <languageList>
+ <iso639Id>rum</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>cedilla</name>
+ <_description>Romania - Cedilla</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>std</name>
+ <_description>Romania - Standard</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>std_cedilla</name>
+ <_description>Romania - Standard (Cedilla)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>winkeys</name>
+ <_description>Romania - Winkeys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh_f</name>
+ <_description>Romania - Crimean Tatar (Turkish F)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh_alt</name>
+ <_description>Romania - Crimean Tatar (Turkish Alt-Q)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh_dobruca1</name>
+ <_description>Romania - Crimean Tatar (Dobruca-1 Q)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh_dobruca2</name>
+ <_description>Romania - Crimean Tatar (Dobruca-2 Q)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ru</name>
+ <_shortDescription>Rus</_shortDescription>
+ <_description>Russia</_description>
+ <languageList>
+ <iso639Id>rus</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>phonetic</name>
+ <_description>Russia - Phonetic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>phonetic_winkeys</name>
+ <_description>Russia - Phonetic Winkeys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>typewriter</name>
+ <_description>Russia - Typewriter</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>legacy</name>
+ <_description>Russia - Legacy</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>typewriter-legacy</name>
+ <_description>Russia - Typewriter, legacy</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tt</name>
+ <_description>Russia - Tatar</_description>
+ <languageList>
+ <iso639Id>tat</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>os_legacy</name>
+ <_description>Russia - Ossetian, legacy</_description>
+ <languageList>
+ <iso639Id>oss</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>os_winkeys</name>
+ <_description>Russia - Ossetian, Winkeys</_description>
+ <languageList>
+ <iso639Id>oss</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>cv</name>
+ <_description>Russia - Chuvash</_description>
+ <languageList>
+ <iso639Id>chv</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>cv_latin</name>
+ <_description>Russia - Chuvash Latin</_description>
+ <languageList>
+ <iso639Id>chv</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>udm</name>
+ <_description>Russia - Udmurt</_description>
+ <languageList>
+ <iso639Id>udm</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>kom</name>
+ <_description>Russia - Komi</_description>
+ <languageList>
+ <iso639Id>kom</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>sah</name>
+ <_description>Russia - Yakut</_description>
+ <languageList>
+ <iso639Id>sah</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>xal</name>
+ <_description>Russia - Kalmyk</_description>
+ <languageList>
+ <iso639Id>xal</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dos</name>
+ <_description>Russia - DOS</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>srp</name>
+ <_description>Russia - Serbian</_description>
+ <languageList><iso639Id>rus</iso639Id>
+ <iso639Id>srp</iso639Id></languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>bak</name>
+ <_description>Russia - Bashkirian</_description>
+ <languageList>
+ <iso639Id>bak</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>chm</name>
+ <_description>Russia - Mari</_description>
+ <languageList>
+ <iso639Id>chm</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>rs</name>
+ <_shortDescription>SRB</_shortDescription>
+ <_description>Serbia</_description>
+ <languageList>
+ <iso639Id>srp</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>yz</name>
+ <_description>Serbia - Z and ZHE swapped</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latin</name>
+ <_description>Serbia - Latin</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latinunicode</name>
+ <_description>Serbia - Latin Unicode</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latinyz</name>
+ <_description>Serbia - Latin qwerty</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latinunicodeyz</name>
+ <_description>Serbia - Latin Unicode qwerty</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>alternatequotes</name>
+ <_description>Serbia - With guillemets</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>latinalternatequotes</name>
+ <_description>Serbia - Latin with guillemets</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>rue</name>
+ <_description>Serbia - Pannonian Rusyn Homophonic</_description>
+ <languageList>
+ <iso639Id>rue</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>si</name>
+ <_shortDescription>Svn</_shortDescription>
+ <_description>Slovenia</_description>
+ <languageList>
+ <iso639Id>slv</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>alternatequotes</name>
+ <_description>Slovenia - Use guillemets for quotes</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>us</name>
+ <_description>Slovenia - US keyboard with Slovenian letters</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>sk</name>
+ <_shortDescription>Svk</_shortDescription>
+ <_description>Slovakia</_description>
+ <languageList>
+ <iso639Id>slo</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>bksl</name>
+ <_description>Slovakia - Extended Backslash</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>qwerty</name>
+ <_description>Slovakia - qwerty</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>qwerty_bksl</name>
+ <_description>Slovakia - qwerty, extended Backslash</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>es</name>
+ <_shortDescription>Esp</_shortDescription>
+ <_description>Spain</_description>
+ <languageList>
+ <iso639Id>spa</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Spain - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>deadtilde</name>
+ <_description>Spain - Include dead tilde</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>sundeadkeys</name>
+ <_description>Spain - Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Spain - Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ast</name>
+ <_description>Spain - Asturian variant with bottom-dot H and bottom-dot L</_description>
+ <languageList>
+ <iso639Id>ast</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>cat</name>
+ <_description>Spain - Catalan variant with middle-dot L</_description>
+ <languageList>
+ <iso639Id>cat</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Spain - Macintosh</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>se</name>
+ <_shortDescription>Swe</_shortDescription>
+ <_description>Sweden</_description>
+ <languageList>
+ <iso639Id>swe</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>nodeadkeys</name>
+ <_description>Sweden - Eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Sweden - Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>rus</name>
+ <_description>Sweden - Russian phonetic</_description>
+ <languageList>
+ <iso639Id>rus</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>rus_nodeadkeys</name>
+ <_description>Sweden - Russian phonetic, eliminate dead keys</_description>
+ <languageList>
+ <iso639Id>rus</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>smi</name>
+ <_description>Sweden - Northern Saami</_description>
+ <languageList>
+ <iso639Id>sme</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>Sweden - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>svdvorak</name>
+ <_description>Sweden - Svdvorak</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ch</name>
+ <_shortDescription>Che</_shortDescription>
+ <_description>Switzerland</_description>
+ <languageList><iso639Id>ger</iso639Id>
+ <iso639Id>gsw</iso639Id></languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>legacy</name>
+ <_description>Switzerland - Legacy</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>de_nodeadkeys</name>
+ <_description>Switzerland - German, eliminate dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>de_sundeadkeys</name>
+ <_description>Switzerland - German, Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>fr</name>
+ <_description>Switzerland - French</_description>
+ <languageList>
+ <iso639Id>fra</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>fr_nodeadkeys</name>
+ <_description>Switzerland - French, eliminate dead keys</_description>
+ <languageList>
+ <iso639Id>fra</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>fr_sundeadkeys</name>
+ <_description>Switzerland - French, Sun dead keys</_description>
+ <languageList>
+ <iso639Id>fra</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>fr_mac</name>
+ <_description>Switzerland - French (Macintosh)</_description>
+ <languageList>
+ <iso639Id>fra</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>de_mac</name>
+ <_description>Switzerland - German (Macintosh)</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>sy</name>
+ <_shortDescription>Syr</_shortDescription>
+ <_description>Syria</_description>
+ <languageList>
+ <iso639Id>syr</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>syc</name>
+ <_description>Syria - Syriac</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>syc_phonetic</name>
+ <_description>Syria - Syriac phonetic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku</name>
+ <_description>Syria - Kurdish, Latin Q</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku_f</name>
+ <_description>Syria - Kurdish, (F)</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku_alt</name>
+ <_description>Syria - Kurdish, Latin Alt-Q</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>tj</name>
+ <_shortDescription>Tjk</_shortDescription>
+ <_description>Tajikistan</_description>
+ <languageList>
+ <iso639Id>tgk</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>legacy</name>
+ <_description>Tajikistan - Legacy</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>lk</name>
+ <_shortDescription>Lka</_shortDescription>
+ <_description>Sri Lanka</_description>
+ <languageList>
+ <iso639Id>sin</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>tam_unicode</name>
+ <_description>Sri Lanka - Tamil Unicode</_description>
+ <languageList>
+ <iso639Id>tam</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>tam_TAB</name>
+ <_description>Sri Lanka - Tamil TAB Typewriter</_description>
+ <languageList>
+ <iso639Id>tam</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>th</name>
+ <_shortDescription>Tha</_shortDescription>
+ <_description>Thailand</_description>
+ <languageList>
+ <iso639Id>tha</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>tis</name>
+ <_description>Thailand - TIS-820.2538</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>pat</name>
+ <_description>Thailand - Pattachote</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>tr</name>
+ <_shortDescription>Tur</_shortDescription>
+ <_description>Turkey</_description>
+ <languageList>
+ <iso639Id>tur</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>f</name>
+ <_description>Turkey - (F)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>alt</name>
+ <_description>Turkey - Alt-Q</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>sundeadkeys</name>
+ <_description>Turkey - Sun dead keys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku</name>
+ <_description>Turkey - Kurdish, Latin Q</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku_f</name>
+ <_description>Turkey - Kurdish, (F)</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ku_alt</name>
+ <_description>Turkey - Kurdish, Latin Alt-Q</_description>
+ <languageList>
+ <iso639Id>kur</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>intl</name>
+ <_description>Turkey - International (with dead keys)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh</name>
+ <_description>Turkey - Crimean Tatar (Turkish Q)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh_f</name>
+ <_description>Turkey - Crimean Tatar (Turkish F)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh_alt</name>
+ <_description>Turkey - Crimean Tatar (Turkish Alt-Q)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>tw</name>
+ <_shortDescription>Twn</_shortDescription>
+ <_description>Taiwan</_description>
+ <languageList>
+ <iso639Id>trv</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>indigenous</name>
+ <_description>Taiwan - Indigenous</_description>
+ <languageList>
+ <iso639Id>ami</iso639Id>
+ <iso639Id>tay</iso639Id>
+ <iso639Id>bnn</iso639Id>
+ <iso639Id>ckv</iso639Id>
+ <iso639Id>pwn</iso639Id>
+ <iso639Id>pyu</iso639Id>
+ <iso639Id>dru</iso639Id>
+ <iso639Id>ais</iso639Id>
+ <iso639Id>ssf</iso639Id>
+ <iso639Id>tao</iso639Id>
+ <iso639Id>tsu</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>saisiyat</name>
+ <_description>Taiwan - Saisiyat</_description>
+ <languageList>
+ <iso639Id>xsf</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ua</name>
+ <_shortDescription>Ukr</_shortDescription>
+ <_description>Ukraine</_description>
+ <languageList>
+ <iso639Id>ukr</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>phonetic</name>
+ <_description>Ukraine - Phonetic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>typewriter</name>
+ <_description>Ukraine - Typewriter</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>winkeys</name>
+ <_description>Ukraine - Winkeys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>legacy</name>
+ <_description>Ukraine - Legacy</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>rstu</name>
+ <_description>Ukraine - Standard RSTU</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>rstu_ru</name>
+ <_description>Ukraine - Standard RSTU on Russian layout</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>homophonic</name>
+ <_description>Ukraine - Homophonic</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh</name>
+ <_description>Ukraine - Crimean Tatar (Turkish Q)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh_f</name>
+ <_description>Ukraine - Crimean Tatar (Turkish F)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh_alt</name>
+ <_description>Ukraine - Crimean Tatar (Turkish Alt-Q)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>gb</name>
+ <_shortDescription>GBr</_shortDescription>
+ <_description>United Kingdom</_description>
+ <languageList>
+ <iso639Id>eng</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>extd</name>
+ <_description>United Kingdom - Extended - Winkeys</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>intl</name>
+ <_description>United Kingdom - International (with dead keys)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>United Kingdom - Dvorak</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorakukp</name>
+ <_description>United Kingdom - Dvorak (UK Punctuation)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac</name>
+ <_description>United Kingdom - Macintosh</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mac_intl</name>
+ <_description>United Kingdom - Macintosh (International)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>colemak</name>
+ <_description>United Kingdom - Colemak</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>uz</name>
+ <_shortDescription>Uzb</_shortDescription>
+ <_description>Uzbekistan</_description>
+ <languageList>
+ <iso639Id>uzb</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>latin</name>
+ <_description>Uzbekistan - Latin</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh</name>
+ <_description>Uzbekistan - Crimean Tatar (Turkish Q)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh_f</name>
+ <_description>Uzbekistan - Crimean Tatar (Turkish F)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>crh_alt</name>
+ <_description>Uzbekistan - Crimean Tatar (Turkish Alt-Q)</_description>
+ <languageList>
+ <iso639Id>crh</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>vn</name>
+ <_shortDescription>Vnm</_shortDescription>
+ <_description>Vietnam</_description>
+ <languageList>
+ <iso639Id>vie</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>kr</name>
+ <_shortDescription>Kor</_shortDescription>
+ <_description>Korea, Republic of</_description>
+ <languageList>
+ <iso639Id>kor</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>kr104</name>
+ <_description>Korea, Republic of - 101/104 key Compatible</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>nec_vndr/jp</name>
+ <_shortDescription>Jpn</_shortDescription>
+ <_description>Japan (PC-98xx Series)</_description>
+ <countryList>
+ <iso3166Id>JP</iso3166Id>
+ </countryList>
+ <languageList>
+ <iso639Id>jpn</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ie</name>
+ <_shortDescription>Irl</_shortDescription>
+ <_description>Ireland</_description>
+ <languageList>
+ <iso639Id>eng</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>CloGaelach</name>
+ <_description>Ireland - CloGaelach</_description>
+ <languageList>
+ <iso639Id>gla</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>UnicodeExpert</name>
+ <_description>Ireland - UnicodeExpert</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ogam</name>
+ <_description>Ireland - Ogham</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ogam_is434</name>
+ <_description>Ireland - Ogham IS434</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>pk</name>
+ <_shortDescription>Pak</_shortDescription>
+ <_description>Pakistan</_description>
+ <languageList>
+ <iso639Id>urd</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>urd-crulp</name>
+ <_description>Pakistan - CRULP</_description>
+ <languageList>
+ <iso639Id>urd</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>urd-nla</name>
+ <_description>Pakistan - NLA</_description>
+ <languageList>
+ <iso639Id>urd</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>ara</name>
+ <_description>Pakistan - Arabic</_description>
+ <languageList>
+ <iso639Id>ara</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>snd</name>
+ <_description>Pakistan - Sindhi</_description>
+ <languageList>
+ <iso639Id>sd</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>mv</name>
+ <_shortDescription>Mdv</_shortDescription>
+ <_description>Maldives</_description>
+ <languageList>
+ <iso639Id>div</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>za</name>
+ <_shortDescription>Zaf</_shortDescription>
+ <_description>South Africa</_description>
+ <languageList>
+ <iso639Id>eng</iso639Id>
+ </languageList>
+ </configItem>
+ </layout>
+ <layout>
+ <configItem>
+ <name>epo</name>
+ <_shortDescription>Epo</_shortDescription>
+ <_description>Esperanto</_description>
+ <languageList>
+ <iso639Id>epo</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>legacy</name>
+ <_description>Esperanto - displaced semicolon and quote (obsolete)</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>np</name>
+ <_shortDescription>Npl</_shortDescription>
+ <_description>Nepal</_description>
+ <languageList>
+ <iso639Id>nep</iso639Id>
+ </languageList>
+ </configItem>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ng</name>
+ <_shortDescription>Nga</_shortDescription>
+ <_description>Nigeria</_description>
+ <languageList>
+ <iso639Id>eng</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>igbo</name>
+ <_description>Nigeria - Igbo</_description>
+ <languageList>
+ <iso639Id>ibo</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>yoruba</name>
+ <_description>Nigeria - Yoruba</_description>
+ <languageList>
+ <iso639Id>yor</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>hausa</name>
+ <_description>Nigeria - Hausa</_description>
+ <languageList>
+ <iso639Id>hau</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>et</name>
+ <_shortDescription>Eth</_shortDescription>
+ <_description>Ethiopia</_description>
+ <languageList>
+ <iso639Id>amh</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>sn</name>
+ <_shortDescription>Sen</_shortDescription>
+ <_description>Senegal</_description>
+ <languageList>
+ <iso639Id>wol</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList/>
+ </layout>
+ <layout>
+ <configItem>
+ <name>brai</name>
+ <_shortDescription>Brl</_shortDescription>
+ <_description>Braille</_description>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>left_hand</name>
+ <_description>Braille - Left hand</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>right_hand</name>
+ <_description>Braille - Right hand</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>tm</name>
+ <_shortDescription>Tkm</_shortDescription>
+ <_description>Turkmenistan</_description>
+ <languageList>
+ <iso639Id>tuk</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>alt</name>
+ <_description>Turkmenistan - Alt-Q</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ml</name>
+ <_shortDescription>Mli</_shortDescription>
+ <_description>Mali</_description>
+ <languageList>
+ <iso639Id>bam</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>fr-oss</name>
+ <_description>Mali - Français (France Alternative)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>us-mac</name>
+ <_description>Mali - English (USA Macintosh)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>us-intl</name>
+ <_description>Mali - English (USA International)</_description>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>tz</name>
+ <_shortDescription>Tza</_shortDescription>
+ <_description>Tanzania</_description>
+ <languageList>
+ <iso639Id>swa</iso639Id>
+ </languageList>
+ </configItem>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ke</name>
+ <_shortDescription>Ken</_shortDescription>
+ <_description>Kenya</_description>
+ <languageList>
+ <iso639Id>swa</iso639Id>
+ </languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>kik</name>
+ <_description>Kenya - Kikuyu</_description>
+ <languageList>
+ <iso639Id>kik</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ <layout>
+ <configItem>
+ <name>bw</name>
+ <_shortDescription>Bwa</_shortDescription>
+ <_description>Botswana</_description>
+ <languageList>
+ <iso639Id>tsn</iso639Id>
+ </languageList>
+ </configItem>
+ </layout>
+ <layout>
+ <configItem>
+ <name>ph</name>
+ <_shortDescription>Phi</_shortDescription>
+ <_description>Philippines</_description>
+ <languageList><iso639Id>eng</iso639Id>
+ <iso639Id>bik</iso639Id>
+ <iso639Id>ceb</iso639Id>
+ <iso639Id>fil</iso639Id>
+ <iso639Id>hil</iso639Id>
+ <iso639Id>ilo</iso639Id>
+ <iso639Id>pam</iso639Id>
+ <iso639Id>pag</iso639Id>
+ <iso639Id>phi</iso639Id>
+ <iso639Id>tgl</iso639Id>
+ <iso639Id>war</iso639Id></languageList>
+ </configItem>
+ <variantList>
+ <variant>
+ <configItem>
+ <name>qwerty-bay</name>
+ <_description>Philippines - QWERTY (Baybayin)</_description>
+ <languageList><iso639Id>bik</iso639Id>
+ <iso639Id>ceb</iso639Id>
+ <iso639Id>fil</iso639Id>
+ <iso639Id>hil</iso639Id>
+ <iso639Id>ilo</iso639Id>
+ <iso639Id>pam</iso639Id>
+ <iso639Id>pag</iso639Id>
+ <iso639Id>phi</iso639Id>
+ <iso639Id>tgl</iso639Id>
+ <iso639Id>war</iso639Id></languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>capewell-dvorak</name>
+ <_description>Philippines - Capewell-Dvorak (Latin)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>capewell-dvorak-bay</name>
+ <_description>Philippines - Capewell-Dvorak (Baybayin)</_description>
+ <languageList><iso639Id>bik</iso639Id>
+ <iso639Id>ceb</iso639Id>
+ <iso639Id>fil</iso639Id>
+ <iso639Id>hil</iso639Id>
+ <iso639Id>ilo</iso639Id>
+ <iso639Id>pam</iso639Id>
+ <iso639Id>pag</iso639Id>
+ <iso639Id>phi</iso639Id>
+ <iso639Id>tgl</iso639Id>
+ <iso639Id>war</iso639Id></languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>capewell-qwerf2k6</name>
+ <_description>Philippines - Capewell-QWERF 2006 (Latin)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>capewell-qwerf2k6-bay</name>
+ <_description>Philippines - Capewell-QWERF 2006 (Baybayin)</_description>
+ <languageList><iso639Id>bik</iso639Id>
+ <iso639Id>ceb</iso639Id>
+ <iso639Id>fil</iso639Id>
+ <iso639Id>hil</iso639Id>
+ <iso639Id>ilo</iso639Id>
+ <iso639Id>pam</iso639Id>
+ <iso639Id>pag</iso639Id>
+ <iso639Id>phi</iso639Id>
+ <iso639Id>tgl</iso639Id>
+ <iso639Id>war</iso639Id></languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>colemak</name>
+ <_description>Philippines - Colemak (Latin)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>colemak-bay</name>
+ <_description>Philippines - Colemak (Baybayin)</_description>
+ <languageList><iso639Id>bik</iso639Id>
+ <iso639Id>ceb</iso639Id>
+ <iso639Id>fil</iso639Id>
+ <iso639Id>hil</iso639Id>
+ <iso639Id>ilo</iso639Id>
+ <iso639Id>pam</iso639Id>
+ <iso639Id>pag</iso639Id>
+ <iso639Id>phi</iso639Id>
+ <iso639Id>tgl</iso639Id>
+ <iso639Id>war</iso639Id></languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Philippines - Dvorak (Latin)</_description>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>dvorak-bay</name>
+ <_description>Philippines - Dvorak (Baybayin)</_description>
+ <languageList><iso639Id>bik</iso639Id>
+ <iso639Id>ceb</iso639Id>
+ <iso639Id>fil</iso639Id>
+ <iso639Id>hil</iso639Id>
+ <iso639Id>ilo</iso639Id>
+ <iso639Id>pam</iso639Id>
+ <iso639Id>pag</iso639Id>
+ <iso639Id>phi</iso639Id>
+ <iso639Id>tgl</iso639Id>
+ <iso639Id>war</iso639Id></languageList>
+ </configItem>
+ </variant>
+ </variantList>
+ </layout>
+ </layoutList>
+ <optionList>
+ <group allowMultipleSelection="true">
+ <!-- The key combination used to switch between groups -->
+ <configItem>
+ <name>grp</name>
+ <_description>Key(s) to change layout</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>grp:switch</name>
+ <_description>Right Alt (while pressed)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:lswitch</name>
+ <_description>Left Alt (while pressed)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:lwin_switch</name>
+ <_description>Left Win (while pressed)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:rwin_switch</name>
+ <_description>Right Win (while pressed)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:win_switch</name>
+ <_description>Any Win key (while pressed)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:caps_switch</name>
+ <_description>Caps Lock (while pressed), Alt+Caps Lock does the original capslock action</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:rctrl_switch</name>
+ <_description>Right Ctrl (while pressed)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:toggle</name>
+ <_description>Right Alt</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:lalt_toggle</name>
+ <_description>Left Alt</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:caps_toggle</name>
+ <_description>Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:shift_caps_toggle</name>
+ <_description>Shift+Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:shift_caps_switch</name>
+ <_description>Caps Lock (to first layout), Shift+Caps Lock (to last layout)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:win_menu_switch</name>
+ <_description>Left Win (to first layout), Right Win/Menu (to last layout)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:lctrl_rctrl_switch</name>
+ <_description>Left Ctrl (to first layout), Right Ctrl (to last layout)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:alt_caps_toggle</name>
+ <_description>Alt+Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:shifts_toggle</name>
+ <_description>Both Shift keys together</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:alts_toggle</name>
+ <_description>Both Alt keys together</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:ctrls_toggle</name>
+ <_description>Both Ctrl keys together</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:ctrl_shift_toggle</name>
+ <_description>Ctrl+Shift</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:lctrl_lshift_toggle</name>
+ <_description>Left Ctrl+Left Shift</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:rctrl_rshift_toggle</name>
+ <_description>Right Ctrl+Right Shift</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:ctrl_alt_toggle</name>
+ <_description>Alt+Ctrl</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:alt_shift_toggle</name>
+ <_description>Alt+Shift</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:alt_space_toggle</name>
+ <_description>Alt+Space</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:menu_toggle</name>
+ <_description>Menu</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:lwin_toggle</name>
+ <_description>Left Win</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:rwin_toggle</name>
+ <_description>Right Win</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:lshift_toggle</name>
+ <_description>Left Shift</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:rshift_toggle</name>
+ <_description>Right Shift</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:lctrl_toggle</name>
+ <_description>Left Ctrl</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:rctrl_toggle</name>
+ <_description>Right Ctrl</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:sclk_toggle</name>
+ <_description>Scroll Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp:lctrl_lwin_rctrl_menu</name>
+ <_description>LeftCtrl+LeftWin (to first layout), RightCtrl+Menu (to second layout)</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="true">
+ <!-- The key combination used to choose the 3rd (and 4th, together with Shift)
+ level of symbols -->
+ <configItem>
+ <name>lv3</name>
+ <_description>Key to choose 3rd level</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>lv3:switch</name>
+ <_description>Right Ctrl</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:menu_switch</name>
+ <_description>Menu</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:win_switch</name>
+ <_description>Any Win key</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:lwin_switch</name>
+ <_description>Left Win</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:rwin_switch</name>
+ <_description>Right Win</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:alt_switch</name>
+ <_description>Any Alt key</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:lalt_switch</name>
+ <_description>Left Alt</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:ralt_switch</name>
+ <_description>Right Alt</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:ralt_switch_multikey</name>
+ <_description>Right Alt, Shift+Right Alt key is Multi_Key</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:ralt_alt</name>
+ <_description>Right Alt key never chooses 3rd level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:enter_switch</name>
+ <_description>Enter on keypad</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:caps_switch</name>
+ <_description>Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:bksl_switch</name>
+ <_description>Backslash</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:lsgt_switch</name>
+ <_description>&lt;Less/Greater&gt;</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:caps_switch_latch</name>
+ <_description>Caps Lock (chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:bksl_switch_latch</name>
+ <_description>Backslash chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv3:lsgt_switch_latch</name>
+ <_description>&lt;Less/Greater&gt; (chooses 3rd level, latches when pressed together with another 3rd-level-chooser)</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="true">
+ <!-- Tweaking the position of the "Ctrl" key -->
+ <configItem>
+ <name>ctrl</name>
+ <_description>Ctrl key position</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>ctrl:nocaps</name>
+ <_description>Make Caps Lock an additional Ctrl</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>ctrl:lctrl_meta</name>
+ <_description>Meta on Left Ctrl</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>ctrl:swapcaps</name>
+ <_description>Swap Ctrl and Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>ctrl:ctrl_ac</name>
+ <_description>At left of 'A'</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>ctrl:ctrl_aa</name>
+ <_description>At bottom left</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>ctrl:ctrl_ra</name>
+ <_description>Right Ctrl as Right Alt</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>ctrl:ctrl_menu</name>
+ <_description>Right Ctrl is mapped to Menu</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="true">
+ <!-- Using startard LEDs to indicate the alternative (not first) group(s) -->
+ <configItem>
+ <name>grp_led</name>
+ <_description>Use keyboard LED to show alternative layout</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>grp_led:num</name>
+ <_description>Num Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp_led:caps</name>
+ <_description>Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>grp_led:scroll</name>
+ <_description>Scroll Lock</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="false">
+ <!-- Select a keypad type -->
+ <configItem>
+ <name>keypad</name>
+ <_description>Numeric keypad layout selection</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>keypad:legacy</name>
+ <_description>Legacy</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>keypad:oss</name>
+ <_description>Unicode additions (arrows and math operators)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>keypad:future</name>
+ <_description>Unicode additions (arrows and math operators). Math operators on default level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>keypad:legacy_wang</name>
+ <_description>Legacy Wang 724</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>keypad:oss_wang</name>
+ <_description>Wang 724 keypad with unicode additions (arrows and math operators)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>keypad:future_wang</name>
+ <_description>Wang 724 keypad with unicode additions (arrows and math operators). Math operators on default level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>keypad:hex</name>
+ <_description>Hexadecimal</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>keypad:atm</name>
+ <_description>ATM/phone-style</_description>
+ </configItem>
+ </option>
+ </group>
+ <!-- This option should override the KPDL key defined in keypad; I hope it's declared in the right place -->
+ <group allowMultipleSelection="false">
+ <!-- Select a keypad KPDL variant -->
+ <configItem>
+ <name>kpdl</name>
+ <_description>Numeric keypad delete key behaviour</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <!-- Actually, with KP_DECIMAL, as the old keypad(dot) -->
+ <name>kpdl:dot</name>
+ <_description>Legacy key with dot</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>kpdl:comma</name>
+ <!-- Actually, with KP_SEPARATOR, as the old keypad(comma) -->
+ <_description>Legacy key with comma</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>kpdl:dotoss</name>
+ <_description>Four-level key with dot</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>kpdl:dotoss_latin9</name>
+ <_description>Four-level key with dot, latin-9 restriction</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>kpdl:commaoss</name>
+ <_description>Four-level key with comma</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>kpdl:momayyezoss</name>
+ <_description>Four-level key with momayyez</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>kpdl:kposs</name>
+ <!-- This assumes the KP_ abstract symbols are actually useful for some apps
+ The description needs to be rewritten -->
+ <_description>Four-level key with abstract separators</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>kpdl:semi</name>
+ <_description>Semi-colon on third level</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="false">
+ <!-- Caps Lock tweaks.
+ "Internal" capitalization means capitalization using some internal tables.
+ Otherwise "as Shift" - means using next group. -->
+ <configItem>
+ <name>caps</name>
+ <_description>Caps Lock key behavior</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>caps:internal</name>
+ <_description>Caps Lock uses internal capitalization. Shift "pauses" Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:internal_nocancel</name>
+ <_description>Caps Lock uses internal capitalization. Shift doesn't affect Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:shift</name>
+ <_description>Caps Lock acts as Shift with locking. Shift "pauses" Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:shift_nocancel</name>
+ <_description>Caps Lock acts as Shift with locking. Shift doesn't affect Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:capslock</name>
+ <_description>Caps Lock toggles normal capitalization of alphabetic characters</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:numlock</name>
+ <_description>Make Caps Lock an additional Num Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:swapescape</name>
+ <_description>Swap ESC and Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:escape</name>
+ <_description>Make Caps Lock an additional ESC</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:backspace</name>
+ <_description>Make Caps Lock an additional Backspace</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:super</name>
+ <_description>Make Caps Lock an additional Super</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:hyper</name>
+ <_description>Make Caps Lock an additional Hyper</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:shiftlock</name>
+ <_description>Caps Lock toggles Shift so all keys are affected</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:none</name>
+ <_description>Caps Lock is disabled</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>caps:ctrl_modifier</name>
+ <_description>Make Caps Lock an additional Control but keep the Caps_Lock keysym</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="false">
+ <!-- Using special PC keys (Win, Menu) to work as standard X keys (Super, Hyper, etc.) -->
+ <configItem>
+ <name>altwin</name>
+ <_description>Alt/Win key behavior</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>altwin:menu</name>
+ <_description>Add the standard behavior to Menu key</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>altwin:meta_alt</name>
+ <_description>Alt and Meta are on Alt keys</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>altwin:ctrl_win</name>
+ <_description>Control is mapped to Win keys (and the usual Ctrl keys)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>altwin:ctrl_alt_win</name>
+ <_description>Control is mapped to Alt keys, Alt is mapped to Win keys</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>altwin:meta_win</name>
+ <_description>Meta is mapped to Win keys</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>altwin:left_meta_win</name>
+ <_description>Meta is mapped to Left Win</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>altwin:hyper_win</name>
+ <_description>Hyper is mapped to Win-keys</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>altwin:alt_super_win</name>
+ <_description>Alt is mapped to Right Win, Super to Menu</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>altwin:swap_lalt_lwin</name>
+ <_description>Left Alt is swapped with Left Win</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="true">
+ <!-- Tweaking the position of the "Compose" key: mapping to existing PC keys -->
+ <configItem>
+ <name>Compose key</name>
+ <_description>Compose key position</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>compose:ralt</name>
+ <_description>Right Alt</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>compose:lwin</name>
+ <_description>Left Win</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>compose:rwin</name>
+ <_description>Right Win</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>compose:menu</name>
+ <_description>Menu</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>compose:lctrl</name>
+ <_description>Left Ctrl</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>compose:rctrl</name>
+ <_description>Right Ctrl</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>compose:caps</name>
+ <_description>Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>compose:102</name>
+ <_description>&lt;Less/Greater&gt;</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>compose:paus</name>
+ <_description>Pause</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>compose:prsc</name>
+ <_description>PrtSc</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>compose:sclk</name>
+ <_description>Scroll Lock</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="true">
+ <configItem>
+ <name>compat</name>
+ <_description>Miscellaneous compatibility options</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>numpad:pc</name>
+ <_description>Default numeric keypad keys</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>numpad:mac</name>
+ <_description>Numeric keypad keys work as with Mac</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>numpad:microsoft</name>
+ <_description>Shift with numeric keypad keys works as in MS Windows</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>numpad:shift3</name>
+ <_description>Shift does not cancel Num Lock, chooses 3rd level instead</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>srvrkeys:none</name>
+ <_description>Special keys (Ctrl+Alt+&lt;key&gt;) handled in a server</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>apple:alupckeys</name>
+ <_description>Apple Aluminium Keyboard: emulate PC keys (Print, Scroll Lock, Pause, Num Lock)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>shift:breaks_caps</name>
+ <_description>Shift cancels Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>misc:typo</name>
+ <_description>Enable extra typographic characters</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>shift:both_capslock</name>
+ <_description>Both Shift-Keys together toggle Caps Lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>shift:both_capslock_cancel</name>
+ <_description>Both Shift-Keys together activate Caps Lock, one Shift-Key deactivates</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>shift:both_shiftlock</name>
+ <_description>Both Shift-Keys together toggle ShiftLock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>keypad:pointerkeys</name>
+ <_description>Toggle PointerKeys with Shift + NumLock.</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="true">
+ <!-- Special shortcuts for the Euro character -->
+ <configItem>
+ <name>eurosign</name>
+ <_description>Adding currency signs to certain keys</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>eurosign:e</name>
+ <_description>Euro on E</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>eurosign:2</name>
+ <_description>Euro on 2</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>eurosign:4</name>
+ <_description>Euro on 4</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>eurosign:5</name>
+ <_description>Euro on 5</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>rupeesign:4</name>
+ <_description>Rupee on 4</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="true">
+ <configItem>
+ <name>lv5</name>
+ <_description>Key to choose 5th level</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>lv5:lsgt_switch_lock</name>
+ <_description>&lt;Less/Greater&gt; chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv5:ralt_switch_lock</name>
+ <_description>Right Alt chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv5:lwin_switch_lock</name>
+ <_description>Left Win chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv5:rwin_switch_lock</name>
+ <_description>Right Win chooses 5th level, locks when pressed together with another 5th-level-chooser</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv5:lsgt_switch_lock_cancel</name>
+ <_description>&lt;Less/Greater&gt; chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv5:ralt_switch_lock_cancel</name>
+ <_description>Right Alt chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv5:lwin_switch_lock_cancel</name>
+ <_description>Left Win chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv5:rwin_switch_lock_cancel</name>
+ <_description>Right Win chooses 5th level, locks when pressed together with another 5th-level-chooser, one press releases the lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv5:lsgt_switch_lock_cancel</name>
+ <_description>&lt;Less/Greater&gt; chooses 5th level and activates level5-Lock when pressed together with another 5th-level-chooser, one press releases the lock</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>lv5:ralt_switch_lock_cancel</name>
+ <_description>Right Alt chooses 5th level and activates level5-Lock when pressed together with another 5th-level-chooser, one press releases the lock</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="false">
+ <!-- Let space output NBSP, NNBSP, ZWNJ, and ZWJ for the desired level -->
+ <configItem>
+ <name>nbsp</name>
+ <_description>Using space key to input non-breakable space character</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>nbsp:none</name>
+ <_description>Usual space at any level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:level2</name>
+ <_description>Non-breakable space character at second level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:level3</name>
+ <_description>Non-breakable space character at third level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:level3s</name>
+ <_description>Non-breakable space character at third level, nothing at fourth level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:level3n</name>
+ <_description>Non-breakable space character at third level, thin non-breakable space character at fourth level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:level4</name>
+ <_description>Non-breakable space character at fourth level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:level4n</name>
+ <_description>Non-breakable space character at fourth level, thin non-breakable space character at sixth level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:level4nl</name>
+ <_description>Non-breakable space character at fourth level, thin non-breakable space character at sixth level (via Ctrl+Shift)</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:zwnj2</name>
+ <_description>Zero-width non-joiner character at second level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:zwnj2zwj3</name>
+ <_description>Zero-width non-joiner character at second level, zero-width joiner character at third level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:zwnj2zwj3nb4</name>
+ <_description>Zero-width non-joiner character at second level, zero-width joiner character at third level, non-breakable space character at fourth level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:zwnj2nb3</name>
+ <_description>Zero-width non-joiner character at second level, non-breakable space character at third level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:zwnj2nb3s</name>
+ <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, nothing at fourth level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:zwnj2nb3zwj4</name>
+ <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, zero-width joiner at fourth level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:zwnj2nb3nnb4</name>
+ <_description>Zero-width non-joiner character at second level, non-breakable space character at third level, thin non-breakable space at fourth level</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>nbsp:zwnj3zwj4</name>
+ <_description>Zero-width non-joiner character at third level, zero-width joiner at fourth level</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="true">
+ <configItem>
+ <name>japan</name>
+ <_description>Japanese keyboard options</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>japan:kana_lock</name>
+ <_description>Kana Lock key is locking</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>japan:nicola_f_bs</name>
+ <_description>NICOLA-F style Backspace</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="false">
+ <configItem>
+ <name>esperanto</name>
+ <_description>Adding Esperanto circumflexes (supersigno)</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>esperanto:qwerty</name>
+ <_description>To the corresponding key in a Qwerty keyboard.</_description>
+ </configItem>
+ </option>
+ <option>
+ <configItem>
+ <name>esperanto:dvorak</name>
+ <_description>To the corresponding key in a Dvorak keyboard.</_description>
+ </configItem>
+ </option>
+ </group>
+ <group allowMultipleSelection="true">
+ <configItem>
+ <name>terminate</name>
+ <_description>Key sequence to kill the X server</_description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>terminate:ctrl_alt_bksp</name>
+ <_description>Control + Alt + Backspace</_description>
+ </configItem>
+ </option>
+ </group>
+ </optionList>
+</xkbConfigRegistry>
diff --git a/xorg-server/xkeyboard-config/symbols/Makefile.am b/xorg-server/xkeyboard-config/symbols/Makefile.am
index 270b7a4d6..a56c1b700 100644
--- a/xorg-server/xkeyboard-config/symbols/Makefile.am
+++ b/xorg-server/xkeyboard-config/symbols/Makefile.am
@@ -1,41 +1,41 @@
-SUBDIRS = digital_vndr fujitsu_vndr hp_vndr macintosh_vndr nec_vndr nokia_vndr sgi_vndr sony_vndr sun_vndr xfree68_vndr
-
-symbolsdir = $(xkb_base)/symbols
-dist_symbols_DATA = \
-ad af al \
-am apl ara \
-at az \
-ba bd be \
-bg br brai \
-bt bw by \
-ca cd \
-ch cn cz \
-de dk \
-ee es et epo \
-fi fo fr \
-gb ge gh gn \
-gr hr hu \
-ie il in iq \
-ir is it jp \
-ke kg kh \
-kr kz \
-la latam latin \
-lk lt lv \
-ma mao me \
-mk ml mm \
-mn mt mv \
-ng nl no np \
-pc ph pk pl pt \
-ro rs ru \
-se si sk sn \
-sy th \
-terminate \
-tj tm tr tz \
-ua us uz vn \
-za \
-altwin capslock compose ctrl empty eurosign rupeesign group inet \
-keypad kpdl level3 level5 nbsp olpc shift srvr_ctrl typo
-
-dir_data = $(dist_symbols_DATA)
-
-include $(top_srcdir)/xkbrules.am
+SUBDIRS = digital_vndr fujitsu_vndr hp_vndr macintosh_vndr nec_vndr nokia_vndr sgi_vndr sony_vndr sun_vndr xfree68_vndr
+
+symbolsdir = $(xkb_base)/symbols
+dist_symbols_DATA = \
+ad af al \
+am apl ara \
+at az \
+ba bd be \
+bg br brai \
+bt bw by \
+ca cd \
+ch cn cz \
+de dk \
+ee es et epo \
+fi fo fr \
+gb ge gh gn \
+gr hr hu \
+ie il in iq \
+ir is it jp \
+ke kg kh \
+kr kz \
+la latam latin \
+lk lt lv \
+ma mao me \
+mk ml mm \
+mn mt mv \
+ng nl no np \
+pc ph pk pl pt \
+ro rs ru \
+se si sk sn \
+sy th \
+terminate \
+tj tm tr tw tz \
+ua us uz vn \
+za \
+altwin capslock compose ctrl empty eurosign rupeesign group inet \
+keypad kpdl level3 level5 nbsp olpc shift srvr_ctrl typo
+
+dir_data = $(dist_symbols_DATA)
+
+include $(top_srcdir)/xkbrules.am
diff --git a/xorg-server/xkeyboard-config/symbols/tw b/xorg-server/xkeyboard-config/symbols/tw
new file mode 100644
index 000000000..8c50023bb
--- /dev/null
+++ b/xorg-server/xkeyboard-config/symbols/tw
@@ -0,0 +1,73 @@
+// $XKeyboardConfig$
+
+partial default alphanumeric_keys
+xkb_symbols "tw" {
+
+ name[Group1]= "Taiwan";
+
+ include "us(basic)"
+
+ // Alphanumeric section
+ key <TLDE> { [ grave, asciitilde, dead_grave, dead_tilde ] };
+ key <AE01> { [ 1, exclam, U030D, exclamdown ] };
+ key <AE02> { [ 2, at, U0358, twosuperior ] };
+ key <AE03> { [ 3, numbersign, section, threesuperior ] };
+ key <AE04> { [ 4, dollar, yen, sterling ] };
+ key <AE05> { [ 5, percent, EuroSign, cent ] };
+ key <AE06> { [ 6,asciicircum, dead_circumflex, dead_caron ] };
+ key <AE07> { [ 7, ampersand, dead_acute, NoSymbol ] };
+ key <AE08> { [ 8, asterisk, dead_cedilla, dead_horn ] };
+ key <AE09> { [ 9, parenleft, dead_ogonek, dead_breve ] };
+ key <AE10> { [ 0, parenright, dead_abovedot, dead_abovering ] };
+ key <AE11> { [ minus, underscore, dead_macron, plusminus ] };
+ key <AE12> { [ equal, plus, multiply, division ] };
+
+ key <AD01> { [ q, Q, paragraph, degree ] };
+ key <AD03> { [ e, E, eacute, Eacute ] };
+ key <AD04> { [ r, R, U1E5F, U1E5E ] };
+ key <AD05> { [ t, T, U1E6F, U1E6E ] };
+ key <AD06> { [ y, Y, U1E73, U1E72 ] };
+ key <AD07> { [ u, U, U0289, U0244 ] };
+ key <AD08> { [ i, I, U0268, U0197 ] };
+ key <AD09> { [ o, O, oslash, Ooblique ] };
+
+ key <AC02> { [ s, S, ssharp, NoSymbol ] };
+ key <AC03> { [ d, D, U1E0F, U1E0E ] };
+ key <AC05> { [ g, G, eng, ENG ] };
+ key <AC10> { [ semicolon, colon, U02D0, dead_diaeresis ] };
+ key <AC11> { [apostrophe, quotedbl, U02BC, dead_doubleacute ] };
+
+ key <AB03> { [ c, C, ccedilla, Ccedilla ] };
+ key <AB06> { [ n, N, ntilde, Ntilde ] };
+ key <AB07> { [ m, M, mu, mu ] };
+ key <AB08> { [ comma, less, dead_belowcomma, guillemotleft ] };
+ key <AB09> { [ period, greater, dead_belowdot, guillemotright ] };
+ key <AB10> { [ slash, question, questiondown, dead_hook ] };
+ key <BKSL> { [ backslash, bar, notsign, brokenbar ] };
+
+ include "level3(ralt_switch)"
+};
+
+partial alphanumeric_keys
+xkb_symbols "indigenous" {
+
+ name[Group1]= "Taiwan - Indigenous";
+
+ include "tw(tw)"
+
+ key <AC11> { [ U02BC, quotedbl, apostrophe, dead_doubleacute ] };
+
+ include "level3(ralt_switch)"
+};
+
+partial alphanumeric_keys
+xkb_symbols "saisiyat" {
+
+ name[Group1]= "Taiwan - Saisiyat";
+
+ include "tw(indigenous)"
+
+ key <AC10> { [ U02D0, colon, semicolon, dead_diaeresis ] };
+
+ include "level3(ralt_switch)"
+};