aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/xkb
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2010-05-16 20:50:58 +0000
committermarha <marha@users.sourceforge.net>2010-05-16 20:50:58 +0000
commit1c94119ae26b94a60bb2c2b33494ed43c3b8a52f (patch)
treecfe0c736c95314edac7d9f1065be9c13026ed0c1 /xorg-server/xkb
parent6b29aa4559aeb6f795caee047561654bfa0a1954 (diff)
downloadvcxsrv-1c94119ae26b94a60bb2c2b33494ed43c3b8a52f.tar.gz
vcxsrv-1c94119ae26b94a60bb2c2b33494ed43c3b8a52f.tar.bz2
vcxsrv-1c94119ae26b94a60bb2c2b33494ed43c3b8a52f.zip
svn merge -r588:HEAD ^/branches/released .
Diffstat (limited to 'xorg-server/xkb')
-rw-r--r--xorg-server/xkb/XKBAlloc.c674
-rw-r--r--xorg-server/xkb/XKBGAlloc.c1994
-rw-r--r--xorg-server/xkb/XKBMAlloc.c1800
-rw-r--r--xorg-server/xkb/XKBMisc.c1678
-rw-r--r--xorg-server/xkb/ddxList.c596
-rw-r--r--xorg-server/xkb/ddxLoad.c924
-rw-r--r--xorg-server/xkb/maprules.c2038
-rw-r--r--xorg-server/xkb/xkb.c120
-rw-r--r--xorg-server/xkb/xkbActions.c6
-rw-r--r--xorg-server/xkb/xkbEvents.c2224
-rw-r--r--xorg-server/xkb/xkbInit.c1558
-rw-r--r--xorg-server/xkb/xkbLEDs.c1954
-rw-r--r--xorg-server/xkb/xkbUtils.c4384
-rw-r--r--xorg-server/xkb/xkmread.c2476
14 files changed, 11212 insertions, 11214 deletions
diff --git a/xorg-server/xkb/XKBAlloc.c b/xorg-server/xkb/XKBAlloc.c
index d40aa3345..4d342a0fa 100644
--- a/xorg-server/xkb/XKBAlloc.c
+++ b/xorg-server/xkb/XKBAlloc.c
@@ -1,337 +1,337 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-#include <xkbsrv.h>
-#include "xkbgeom.h"
-#include <os.h>
-#include <string.h>
-
-/***===================================================================***/
-
-/*ARGSUSED*/
-Status
-XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI)
-{
-XkbCompatMapPtr compat;
-XkbSymInterpretRec *prev_interpret;
-
- if (!xkb)
- return BadMatch;
- if (xkb->compat) {
- if (xkb->compat->size_si>=nSI)
- return Success;
- compat= xkb->compat;
- compat->size_si= nSI;
- if (compat->sym_interpret==NULL)
- compat->num_si= 0;
- prev_interpret = compat->sym_interpret;
- compat->sym_interpret= xrealloc(compat->sym_interpret,
- nSI * sizeof(XkbSymInterpretRec));
- if (compat->sym_interpret==NULL) {
- xfree(prev_interpret);
- compat->size_si= compat->num_si= 0;
- return BadAlloc;
- }
- if (compat->num_si!=0) {
- memset(&compat->sym_interpret[compat->num_si], 0,
- (compat->size_si - compat->num_si) * sizeof(XkbSymInterpretRec));
- }
- return Success;
- }
- compat= xcalloc(1, sizeof(XkbCompatMapRec));
- if (compat==NULL)
- return BadAlloc;
- if (nSI>0) {
- compat->sym_interpret= xcalloc(nSI, sizeof(XkbSymInterpretRec));
- if (!compat->sym_interpret) {
- xfree(compat);
- return BadAlloc;
- }
- }
- compat->size_si= nSI;
- compat->num_si= 0;
- bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
- xkb->compat= compat;
- return Success;
-}
-
-
-void
-XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap)
-{
-register XkbCompatMapPtr compat;
-
- if ((xkb==NULL)||(xkb->compat==NULL))
- return;
- compat= xkb->compat;
- if (freeMap)
- which= XkbAllCompatMask;
- if (which&XkbGroupCompatMask)
- bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
- if (which&XkbSymInterpMask) {
- if ((compat->sym_interpret)&&(compat->size_si>0))
- xfree(compat->sym_interpret);
- compat->size_si= compat->num_si= 0;
- compat->sym_interpret= NULL;
- }
- if (freeMap) {
- xfree(compat);
- xkb->compat= NULL;
- }
- return;
-}
-
-/***===================================================================***/
-
-Status
-XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases)
-{
-XkbNamesPtr names;
-
- if (xkb==NULL)
- return BadMatch;
- if (xkb->names==NULL) {
- xkb->names = xcalloc(1, sizeof(XkbNamesRec));
- if (xkb->names==NULL)
- return BadAlloc;
- }
- names= xkb->names;
- if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){
- register int i;
- XkbKeyTypePtr type;
-
- type= xkb->map->types;
- for (i=0;i<xkb->map->num_types;i++,type++) {
- if (type->level_names==NULL) {
- type->level_names= xcalloc(type->num_levels, sizeof(Atom));
- if (type->level_names==NULL)
- return BadAlloc;
- }
- }
- }
- if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadValue;
- names->keys= xcalloc((xkb->max_key_code+1), sizeof(XkbKeyNameRec));
- if (names->keys==NULL)
- return BadAlloc;
- }
- if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) {
- if (names->key_aliases==NULL) {
- names->key_aliases= xcalloc(nTotalAliases, sizeof(XkbKeyAliasRec));
- }
- else if (nTotalAliases>names->num_key_aliases) {
- XkbKeyAliasRec *prev_aliases = names->key_aliases;
-
- names->key_aliases= xrealloc(names->key_aliases,
- nTotalAliases * sizeof(XkbKeyAliasRec));
- if (names->key_aliases!=NULL) {
- memset(&names->key_aliases[names->num_key_aliases], 0,
- (nTotalAliases - names->num_key_aliases) * sizeof(XkbKeyAliasRec));
- } else {
- xfree(prev_aliases);
- }
- }
- if (names->key_aliases==NULL) {
- names->num_key_aliases= 0;
- return BadAlloc;
- }
- names->num_key_aliases= nTotalAliases;
- }
- if ((which&XkbRGNamesMask)&&(nTotalRG>0)) {
- if (names->radio_groups==NULL) {
- names->radio_groups= xcalloc(nTotalRG, sizeof(Atom));
- }
- else if (nTotalRG>names->num_rg) {
- Atom *prev_radio_groups = names->radio_groups;
-
- names->radio_groups= xrealloc(names->radio_groups,
- nTotalRG * sizeof(Atom));
- if (names->radio_groups!=NULL) {
- memset(&names->radio_groups[names->num_rg], 0,
- (nTotalRG - names->num_rg) * sizeof(Atom));
- } else {
- xfree(prev_radio_groups);
- }
- }
- if (names->radio_groups==NULL)
- return BadAlloc;
- names->num_rg= nTotalRG;
- }
- return Success;
-}
-
-void
-XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap)
-{
-XkbNamesPtr names;
-
- if ((xkb==NULL)||(xkb->names==NULL))
- return;
- names= xkb->names;
- if (freeMap)
- which= XkbAllNamesMask;
- if (which&XkbKTLevelNamesMask) {
- XkbClientMapPtr map= xkb->map;
- if ((map!=NULL)&&(map->types!=NULL)) {
- register int i;
- register XkbKeyTypePtr type;
- type= map->types;
- for (i=0;i<map->num_types;i++,type++) {
- if (type->level_names!=NULL) {
- xfree(type->level_names);
- type->level_names= NULL;
- }
- }
- }
- }
- if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
- xfree(names->keys);
- names->keys= NULL;
- names->num_keys= 0;
- }
- if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){
- xfree(names->key_aliases);
- names->key_aliases=NULL;
- names->num_key_aliases=0;
- }
- if ((which&XkbRGNamesMask)&&(names->radio_groups)) {
- xfree(names->radio_groups);
- names->radio_groups= NULL;
- names->num_rg= 0;
- }
- if (freeMap) {
- xfree(names);
- xkb->names= NULL;
- }
- return;
-}
-
-/***===================================================================***/
-
-/*ARGSUSED*/
-Status
-XkbAllocControls(XkbDescPtr xkb,unsigned which)
-{
- if (xkb==NULL)
- return BadMatch;
-
- if (xkb->ctrls==NULL) {
- xkb->ctrls= xcalloc(1, sizeof(XkbControlsRec));
- if (!xkb->ctrls)
- return BadAlloc;
- }
- return Success;
-}
-
-/*ARGSUSED*/
-static void
-XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap)
-{
- if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) {
- xfree(xkb->ctrls);
- xkb->ctrls= NULL;
- }
- return;
-}
-
-/***===================================================================***/
-
-Status
-XkbAllocIndicatorMaps(XkbDescPtr xkb)
-{
- if (xkb==NULL)
- return BadMatch;
- if (xkb->indicators==NULL) {
- xkb->indicators= xcalloc(1, sizeof(XkbIndicatorRec));
- if (!xkb->indicators)
- return BadAlloc;
- }
- return Success;
-}
-
-static void
-XkbFreeIndicatorMaps(XkbDescPtr xkb)
-{
- if ((xkb!=NULL)&&(xkb->indicators!=NULL)) {
- xfree(xkb->indicators);
- xkb->indicators= NULL;
- }
- return;
-}
-
-/***====================================================================***/
-
-XkbDescRec *
-XkbAllocKeyboard(void)
-{
-XkbDescRec *xkb;
-
- xkb = xcalloc(1, sizeof(XkbDescRec));
- if (xkb)
- xkb->device_spec= XkbUseCoreKbd;
- return xkb;
-}
-
-void
-XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll)
-{
- if (xkb==NULL)
- return;
- if (freeAll)
- which= XkbAllComponentsMask;
- if (which&XkbClientMapMask)
- XkbFreeClientMap(xkb,XkbAllClientInfoMask,TRUE);
- if (which&XkbServerMapMask)
- XkbFreeServerMap(xkb,XkbAllServerInfoMask,TRUE);
- if (which&XkbCompatMapMask)
- XkbFreeCompatMap(xkb,XkbAllCompatMask,TRUE);
- if (which&XkbIndicatorMapMask)
- XkbFreeIndicatorMaps(xkb);
- if (which&XkbNamesMask)
- XkbFreeNames(xkb,XkbAllNamesMask,TRUE);
- if ((which&XkbGeometryMask) && (xkb->geom!=NULL)) {
- XkbFreeGeometry(xkb->geom,XkbGeomAllMask,TRUE);
- /* PERHAPS BONGHITS etc */
- xkb->geom = NULL;
- }
- if (which&XkbControlsMask)
- XkbFreeControls(xkb,XkbAllControlsMask,TRUE);
- if (freeAll)
- xfree(xkb);
- return;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+#include <os.h>
+#include <string.h>
+
+/***===================================================================***/
+
+/*ARGSUSED*/
+Status
+XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI)
+{
+XkbCompatMapPtr compat;
+XkbSymInterpretRec *prev_interpret;
+
+ if (!xkb)
+ return BadMatch;
+ if (xkb->compat) {
+ if (xkb->compat->size_si>=nSI)
+ return Success;
+ compat= xkb->compat;
+ compat->size_si= nSI;
+ if (compat->sym_interpret==NULL)
+ compat->num_si= 0;
+ prev_interpret = compat->sym_interpret;
+ compat->sym_interpret= realloc(compat->sym_interpret,
+ nSI * sizeof(XkbSymInterpretRec));
+ if (compat->sym_interpret==NULL) {
+ free(prev_interpret);
+ compat->size_si= compat->num_si= 0;
+ return BadAlloc;
+ }
+ if (compat->num_si!=0) {
+ memset(&compat->sym_interpret[compat->num_si], 0,
+ (compat->size_si - compat->num_si) * sizeof(XkbSymInterpretRec));
+ }
+ return Success;
+ }
+ compat= calloc(1, sizeof(XkbCompatMapRec));
+ if (compat==NULL)
+ return BadAlloc;
+ if (nSI>0) {
+ compat->sym_interpret= calloc(nSI, sizeof(XkbSymInterpretRec));
+ if (!compat->sym_interpret) {
+ free(compat);
+ return BadAlloc;
+ }
+ }
+ compat->size_si= nSI;
+ compat->num_si= 0;
+ bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
+ xkb->compat= compat;
+ return Success;
+}
+
+
+void
+XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap)
+{
+register XkbCompatMapPtr compat;
+
+ if ((xkb==NULL)||(xkb->compat==NULL))
+ return;
+ compat= xkb->compat;
+ if (freeMap)
+ which= XkbAllCompatMask;
+ if (which&XkbGroupCompatMask)
+ bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
+ if (which&XkbSymInterpMask) {
+ if ((compat->sym_interpret)&&(compat->size_si>0))
+ free(compat->sym_interpret);
+ compat->size_si= compat->num_si= 0;
+ compat->sym_interpret= NULL;
+ }
+ if (freeMap) {
+ free(compat);
+ xkb->compat= NULL;
+ }
+ return;
+}
+
+/***===================================================================***/
+
+Status
+XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases)
+{
+XkbNamesPtr names;
+
+ if (xkb==NULL)
+ return BadMatch;
+ if (xkb->names==NULL) {
+ xkb->names = calloc(1, sizeof(XkbNamesRec));
+ if (xkb->names==NULL)
+ return BadAlloc;
+ }
+ names= xkb->names;
+ if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){
+ register int i;
+ XkbKeyTypePtr type;
+
+ type= xkb->map->types;
+ for (i=0;i<xkb->map->num_types;i++,type++) {
+ if (type->level_names==NULL) {
+ type->level_names= calloc(type->num_levels, sizeof(Atom));
+ if (type->level_names==NULL)
+ return BadAlloc;
+ }
+ }
+ }
+ if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadValue;
+ names->keys= calloc((xkb->max_key_code+1), sizeof(XkbKeyNameRec));
+ if (names->keys==NULL)
+ return BadAlloc;
+ }
+ if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) {
+ if (names->key_aliases==NULL) {
+ names->key_aliases= calloc(nTotalAliases, sizeof(XkbKeyAliasRec));
+ }
+ else if (nTotalAliases>names->num_key_aliases) {
+ XkbKeyAliasRec *prev_aliases = names->key_aliases;
+
+ names->key_aliases= realloc(names->key_aliases,
+ nTotalAliases * sizeof(XkbKeyAliasRec));
+ if (names->key_aliases!=NULL) {
+ memset(&names->key_aliases[names->num_key_aliases], 0,
+ (nTotalAliases - names->num_key_aliases) * sizeof(XkbKeyAliasRec));
+ } else {
+ free(prev_aliases);
+ }
+ }
+ if (names->key_aliases==NULL) {
+ names->num_key_aliases= 0;
+ return BadAlloc;
+ }
+ names->num_key_aliases= nTotalAliases;
+ }
+ if ((which&XkbRGNamesMask)&&(nTotalRG>0)) {
+ if (names->radio_groups==NULL) {
+ names->radio_groups= calloc(nTotalRG, sizeof(Atom));
+ }
+ else if (nTotalRG>names->num_rg) {
+ Atom *prev_radio_groups = names->radio_groups;
+
+ names->radio_groups= realloc(names->radio_groups,
+ nTotalRG * sizeof(Atom));
+ if (names->radio_groups!=NULL) {
+ memset(&names->radio_groups[names->num_rg], 0,
+ (nTotalRG - names->num_rg) * sizeof(Atom));
+ } else {
+ free(prev_radio_groups);
+ }
+ }
+ if (names->radio_groups==NULL)
+ return BadAlloc;
+ names->num_rg= nTotalRG;
+ }
+ return Success;
+}
+
+void
+XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap)
+{
+XkbNamesPtr names;
+
+ if ((xkb==NULL)||(xkb->names==NULL))
+ return;
+ names= xkb->names;
+ if (freeMap)
+ which= XkbAllNamesMask;
+ if (which&XkbKTLevelNamesMask) {
+ XkbClientMapPtr map= xkb->map;
+ if ((map!=NULL)&&(map->types!=NULL)) {
+ register int i;
+ register XkbKeyTypePtr type;
+ type= map->types;
+ for (i=0;i<map->num_types;i++,type++) {
+ if (type->level_names!=NULL) {
+ free(type->level_names);
+ type->level_names= NULL;
+ }
+ }
+ }
+ }
+ if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
+ free(names->keys);
+ names->keys= NULL;
+ names->num_keys= 0;
+ }
+ if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){
+ free(names->key_aliases);
+ names->key_aliases=NULL;
+ names->num_key_aliases=0;
+ }
+ if ((which&XkbRGNamesMask)&&(names->radio_groups)) {
+ free(names->radio_groups);
+ names->radio_groups= NULL;
+ names->num_rg= 0;
+ }
+ if (freeMap) {
+ free(names);
+ xkb->names= NULL;
+ }
+ return;
+}
+
+/***===================================================================***/
+
+/*ARGSUSED*/
+Status
+XkbAllocControls(XkbDescPtr xkb,unsigned which)
+{
+ if (xkb==NULL)
+ return BadMatch;
+
+ if (xkb->ctrls==NULL) {
+ xkb->ctrls= calloc(1, sizeof(XkbControlsRec));
+ if (!xkb->ctrls)
+ return BadAlloc;
+ }
+ return Success;
+}
+
+/*ARGSUSED*/
+static void
+XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap)
+{
+ if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) {
+ free(xkb->ctrls);
+ xkb->ctrls= NULL;
+ }
+ return;
+}
+
+/***===================================================================***/
+
+Status
+XkbAllocIndicatorMaps(XkbDescPtr xkb)
+{
+ if (xkb==NULL)
+ return BadMatch;
+ if (xkb->indicators==NULL) {
+ xkb->indicators= calloc(1, sizeof(XkbIndicatorRec));
+ if (!xkb->indicators)
+ return BadAlloc;
+ }
+ return Success;
+}
+
+static void
+XkbFreeIndicatorMaps(XkbDescPtr xkb)
+{
+ if ((xkb!=NULL)&&(xkb->indicators!=NULL)) {
+ free(xkb->indicators);
+ xkb->indicators= NULL;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+XkbDescRec *
+XkbAllocKeyboard(void)
+{
+XkbDescRec *xkb;
+
+ xkb = calloc(1, sizeof(XkbDescRec));
+ if (xkb)
+ xkb->device_spec= XkbUseCoreKbd;
+ return xkb;
+}
+
+void
+XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll)
+{
+ if (xkb==NULL)
+ return;
+ if (freeAll)
+ which= XkbAllComponentsMask;
+ if (which&XkbClientMapMask)
+ XkbFreeClientMap(xkb,XkbAllClientInfoMask,TRUE);
+ if (which&XkbServerMapMask)
+ XkbFreeServerMap(xkb,XkbAllServerInfoMask,TRUE);
+ if (which&XkbCompatMapMask)
+ XkbFreeCompatMap(xkb,XkbAllCompatMask,TRUE);
+ if (which&XkbIndicatorMapMask)
+ XkbFreeIndicatorMaps(xkb);
+ if (which&XkbNamesMask)
+ XkbFreeNames(xkb,XkbAllNamesMask,TRUE);
+ if ((which&XkbGeometryMask) && (xkb->geom!=NULL)) {
+ XkbFreeGeometry(xkb->geom,XkbGeomAllMask,TRUE);
+ /* PERHAPS BONGHITS etc */
+ xkb->geom = NULL;
+ }
+ if (which&XkbControlsMask)
+ XkbFreeControls(xkb,XkbAllControlsMask,TRUE);
+ if (freeAll)
+ free(xkb);
+ return;
+}
diff --git a/xorg-server/xkb/XKBGAlloc.c b/xorg-server/xkb/XKBGAlloc.c
index b01005dd0..4dc3e7017 100644
--- a/xorg-server/xkb/XKBGAlloc.c
+++ b/xorg-server/xkb/XKBGAlloc.c
@@ -1,997 +1,997 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-#include <xkbsrv.h>
-#include "xkbgeom.h"
-
-/***====================================================================***/
-
-static void
-_XkbFreeGeomLeafElems( Bool freeAll,
- int first,
- int count,
- unsigned short * num_inout,
- unsigned short * sz_inout,
- char ** elems,
- unsigned int elem_sz)
-{
- if ((freeAll)||(*elems==NULL)) {
- *num_inout= *sz_inout= 0;
- if (*elems!=NULL) {
- xfree(*elems);
- *elems= NULL;
- }
- return;
- }
-
- if ((first>=(*num_inout))||(first<0)||(count<1))
- return;
-
- if (first+count>=(*num_inout)) {
- /* truncating the array is easy */
- (*num_inout)= first;
- }
- else {
- char * ptr;
- int extra;
- ptr= *elems;
- extra= ((*num_inout)-(first+count))*elem_sz;
- if (extra>0)
- memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
- (*num_inout)-= count;
- }
- return;
-}
-
-typedef void (*ContentsClearFunc)(
- char * /* priv */
-);
-
-static void
-_XkbFreeGeomNonLeafElems( Bool freeAll,
- int first,
- int count,
- unsigned short * num_inout,
- unsigned short * sz_inout,
- char ** elems,
- unsigned int elem_sz,
- ContentsClearFunc freeFunc)
-{
-register int i;
-register char *ptr;
-
- if (freeAll) {
- first= 0;
- count= (*num_inout);
- }
- else if ((first>=(*num_inout))||(first<0)||(count<1))
- return;
- else if (first+count>(*num_inout))
- count= (*num_inout)-first;
- if (*elems==NULL)
- return;
-
- if (freeFunc) {
- ptr= *elems;
- ptr+= first*elem_sz;
- for (i=0;i<count;i++) {
- (*freeFunc)(ptr);
- ptr+= elem_sz;
- }
- }
- if (freeAll) {
- (*num_inout)= (*sz_inout)= 0;
- if (*elems) {
- xfree(*elems);
- *elems= NULL;
- }
- }
- else if (first+count>=(*num_inout))
- *num_inout= first;
- else {
- i= ((*num_inout)-(first+count))*elem_sz;
- ptr= *elems;
- memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
- (*num_inout)-= count;
- }
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearProperty(char *prop_in)
-{
-XkbPropertyPtr prop= (XkbPropertyPtr)prop_in;
-
- if (prop->name) {
- xfree(prop->name);
- prop->name= NULL;
- }
- if (prop->value) {
- xfree(prop->value);
- prop->value= NULL;
- }
- return;
-}
-
-void
-XkbFreeGeomProperties( XkbGeometryPtr geom,
- int first,
- int count,
- Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &geom->num_properties,&geom->sz_properties,
- (char **)&geom->properties,
- sizeof(XkbPropertyRec),_XkbClearProperty);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbFreeGeomKeyAliases( XkbGeometryPtr geom,
- int first,
- int count,
- Bool freeAll)
-{
- _XkbFreeGeomLeafElems(freeAll,first,count,
- &geom->num_key_aliases,&geom->sz_key_aliases,
- (char **)&geom->key_aliases,
- sizeof(XkbKeyAliasRec));
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearColor(char *color_in)
-{
-XkbColorPtr color= (XkbColorPtr)color_in;
-
- if (color->spec)
- xfree(color->spec);
- return;
-}
-
-void
-XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &geom->num_colors,&geom->sz_colors,
- (char **)&geom->colors,
- sizeof(XkbColorRec),_XkbClearColor);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomLeafElems(freeAll,first,count,
- &outline->num_points,&outline->sz_points,
- (char **)&outline->points,
- sizeof(XkbPointRec));
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearOutline(char *outline_in)
-{
-XkbOutlinePtr outline= (XkbOutlinePtr)outline_in;
-
- if (outline->points!=NULL)
- XkbFreeGeomPoints(outline,0,outline->num_points,TRUE);
- return;
-}
-
-void
-XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &shape->num_outlines,&shape->sz_outlines,
- (char **)&shape->outlines,
- sizeof(XkbOutlineRec),_XkbClearOutline);
-
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearShape(char *shape_in)
-{
-XkbShapePtr shape= (XkbShapePtr)shape_in;
-
- if (shape->outlines)
- XkbFreeGeomOutlines(shape,0,shape->num_outlines,TRUE);
- return;
-}
-
-void
-XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &geom->num_shapes,&geom->sz_shapes,
- (char **)&geom->shapes,
- sizeof(XkbShapeRec),_XkbClearShape);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomLeafElems(freeAll,first,count,
- &row->num_keys,&row->sz_keys,
- (char **)&row->keys,
- sizeof(XkbOverlayKeyRec));
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearOverlayRow(char *row_in)
-{
-XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in;
-
- if (row->keys!=NULL)
- XkbFreeGeomOverlayKeys(row,0,row->num_keys,TRUE);
- return;
-}
-
-void
-XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &overlay->num_rows,&overlay->sz_rows,
- (char **)&overlay->rows,
- sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearOverlay(char *overlay_in)
-{
-XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in;
-
- if (overlay->rows!=NULL)
- XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,TRUE);
- return;
-}
-
-void
-XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &section->num_overlays,&section->sz_overlays,
- (char **)&section->overlays,
- sizeof(XkbOverlayRec),_XkbClearOverlay);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomLeafElems(freeAll,first,count,
- &row->num_keys,&row->sz_keys,
- (char **)&row->keys,
- sizeof(XkbKeyRec));
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearRow(char *row_in)
-{
-XkbRowPtr row= (XkbRowPtr)row_in;
-
- if (row->keys!=NULL)
- XkbFreeGeomKeys(row,0,row->num_keys,TRUE);
- return;
-}
-
-void
-XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &section->num_rows,&section->sz_rows,
- (char **)&section->rows,
- sizeof(XkbRowRec),_XkbClearRow);
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearSection(char *section_in)
-{
-XkbSectionPtr section= (XkbSectionPtr)section_in;
-
- if (section->rows!=NULL)
- XkbFreeGeomRows(section,0,section->num_rows,TRUE);
- if (section->doodads!=NULL) {
- XkbFreeGeomDoodads(section->doodads,section->num_doodads,TRUE);
- section->doodads= NULL;
- }
- return;
-}
-
-void
-XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &geom->num_sections,&geom->sz_sections,
- (char **)&geom->sections,
- sizeof(XkbSectionRec),_XkbClearSection);
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearDoodad(char *doodad_in)
-{
-XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in;
-
- switch (doodad->any.type) {
- case XkbTextDoodad:
- {
- if (doodad->text.text!=NULL) {
- xfree(doodad->text.text);
- doodad->text.text= NULL;
- }
- if (doodad->text.font!=NULL) {
- xfree(doodad->text.font);
- doodad->text.font= NULL;
- }
- }
- break;
- case XkbLogoDoodad:
- {
- if (doodad->logo.logo_name!=NULL) {
- xfree(doodad->logo.logo_name);
- doodad->logo.logo_name= NULL;
- }
- }
- break;
- }
- return;
-}
-
-void
-XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
-{
-register int i;
-register XkbDoodadPtr doodad;
-
- if (doodads) {
- for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
- _XkbClearDoodad((char *)doodad);
- }
- if (freeAll)
- xfree(doodads);
- }
- return;
-}
-
-void
-XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
-{
- if (geom==NULL)
- return;
- if (freeMap)
- which= XkbGeomAllMask;
- if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
- XkbFreeGeomProperties(geom,0,geom->num_properties,TRUE);
- if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
- XkbFreeGeomColors(geom,0,geom->num_colors,TRUE);
- if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
- XkbFreeGeomShapes(geom,0,geom->num_shapes,TRUE);
- if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
- XkbFreeGeomSections(geom,0,geom->num_sections,TRUE);
- if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
- XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,TRUE);
- geom->doodads= NULL;
- geom->num_doodads= geom->sz_doodads= 0;
- }
- if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
- XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,TRUE);
- if (freeMap) {
- if (geom->label_font!=NULL) {
- xfree(geom->label_font);
- geom->label_font= NULL;
- }
- xfree(geom);
- }
- return;
-}
-
-/***====================================================================***/
-
-static Status
-_XkbGeomAlloc( void ** old,
- unsigned short * num,
- unsigned short * total,
- int num_new,
- size_t sz_elem)
-{
- if (num_new<1)
- return Success;
- if ((*old)==NULL)
- *num= *total= 0;
-
- if ((*num)+num_new<=(*total))
- return Success;
-
- *total= (*num)+num_new;
- if ((*old)!=NULL)
- (*old)= xrealloc((*old),(*total)*sz_elem);
- else (*old)= xcalloc((*total),sz_elem);
- if ((*old)==NULL) {
- *total= *num= 0;
- return BadAlloc;
- }
-
- if (*num>0) {
- char *tmp= (char *)(*old);
- bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
- }
- return Success;
-}
-
-#define _XkbAllocProps(g,n) _XkbGeomAlloc((void *)&(g)->properties,\
- &(g)->num_properties,&(g)->sz_properties,\
- (n),sizeof(XkbPropertyRec))
-#define _XkbAllocColors(g,n) _XkbGeomAlloc((void *)&(g)->colors,\
- &(g)->num_colors,&(g)->sz_colors,\
- (n),sizeof(XkbColorRec))
-#define _XkbAllocShapes(g,n) _XkbGeomAlloc((void *)&(g)->shapes,\
- &(g)->num_shapes,&(g)->sz_shapes,\
- (n),sizeof(XkbShapeRec))
-#define _XkbAllocSections(g,n) _XkbGeomAlloc((void *)&(g)->sections,\
- &(g)->num_sections,&(g)->sz_sections,\
- (n),sizeof(XkbSectionRec))
-#define _XkbAllocDoodads(g,n) _XkbGeomAlloc((void *)&(g)->doodads,\
- &(g)->num_doodads,&(g)->sz_doodads,\
- (n),sizeof(XkbDoodadRec))
-#define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((void *)&(g)->key_aliases,\
- &(g)->num_key_aliases,&(g)->sz_key_aliases,\
- (n),sizeof(XkbKeyAliasRec))
-
-#define _XkbAllocOutlines(s,n) _XkbGeomAlloc((void *)&(s)->outlines,\
- &(s)->num_outlines,&(s)->sz_outlines,\
- (n),sizeof(XkbOutlineRec))
-#define _XkbAllocRows(s,n) _XkbGeomAlloc((void *)&(s)->rows,\
- &(s)->num_rows,&(s)->sz_rows,\
- (n),sizeof(XkbRowRec))
-#define _XkbAllocPoints(o,n) _XkbGeomAlloc((void *)&(o)->points,\
- &(o)->num_points,&(o)->sz_points,\
- (n),sizeof(XkbPointRec))
-#define _XkbAllocKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\
- &(r)->num_keys,&(r)->sz_keys,\
- (n),sizeof(XkbKeyRec))
-#define _XkbAllocOverlays(s,n) _XkbGeomAlloc((void *)&(s)->overlays,\
- &(s)->num_overlays,&(s)->sz_overlays,\
- (n),sizeof(XkbOverlayRec))
-#define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((void *)&(o)->rows,\
- &(o)->num_rows,&(o)->sz_rows,\
- (n),sizeof(XkbOverlayRowRec))
-#define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\
- &(r)->num_keys,&(r)->sz_keys,\
- (n),sizeof(XkbOverlayKeyRec))
-
-Status
-XkbAllocGeomProps(XkbGeometryPtr geom,int nProps)
-{
- return _XkbAllocProps(geom,nProps);
-}
-
-Status
-XkbAllocGeomColors(XkbGeometryPtr geom,int nColors)
-{
- return _XkbAllocColors(geom,nColors);
-}
-
-Status
-XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases)
-{
- return _XkbAllocKeyAliases(geom,nKeyAliases);
-}
-
-Status
-XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes)
-{
- return _XkbAllocShapes(geom,nShapes);
-}
-
-Status
-XkbAllocGeomSections(XkbGeometryPtr geom,int nSections)
-{
- return _XkbAllocSections(geom,nSections);
-}
-
-Status
-XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays)
-{
- return _XkbAllocOverlays(section,nOverlays);
-}
-
-Status
-XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows)
-{
- return _XkbAllocOverlayRows(overlay,nRows);
-}
-
-Status
-XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys)
-{
- return _XkbAllocOverlayKeys(row,nKeys);
-}
-
-Status
-XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads)
-{
- return _XkbAllocDoodads(geom,nDoodads);
-}
-
-Status
-XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads)
-{
- return _XkbAllocDoodads(section,nDoodads);
-}
-
-Status
-XkbAllocGeomOutlines(XkbShapePtr shape,int nOL)
-{
- return _XkbAllocOutlines(shape,nOL);
-}
-
-Status
-XkbAllocGeomRows(XkbSectionPtr section,int nRows)
-{
- return _XkbAllocRows(section,nRows);
-}
-
-Status
-XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts)
-{
- return _XkbAllocPoints(ol,nPts);
-}
-
-Status
-XkbAllocGeomKeys(XkbRowPtr row,int nKeys)
-{
- return _XkbAllocKeys(row,nKeys);
-}
-
-Status
-XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes)
-{
-XkbGeometryPtr geom;
-Status rtrn;
-
- if (xkb->geom==NULL) {
- xkb->geom= xcalloc(1, sizeof(XkbGeometryRec));
- if (!xkb->geom)
- return BadAlloc;
- }
- geom= xkb->geom;
- if ((sizes->which&XkbGeomPropertiesMask)&&
- ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
- goto BAIL;
- }
- if ((sizes->which&XkbGeomColorsMask)&&
- ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
- goto BAIL;
- }
- if ((sizes->which&XkbGeomShapesMask)&&
- ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
- goto BAIL;
- }
- if ((sizes->which&XkbGeomSectionsMask)&&
- ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
- goto BAIL;
- }
- if ((sizes->which&XkbGeomDoodadsMask)&&
- ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
- goto BAIL;
- }
- if ((sizes->which&XkbGeomKeyAliasesMask)&&
- ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
- goto BAIL;
- }
- return Success;
-BAIL:
- XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
- xkb->geom= NULL;
- return rtrn;
-}
-
-/***====================================================================***/
-
-XkbPropertyPtr
-XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value)
-{
-register int i;
-register XkbPropertyPtr prop;
-
- if ((!geom)||(!name)||(!value))
- return NULL;
- for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
- if ((prop->name)&&(strcmp(name,prop->name)==0)) {
- if (prop->value)
- xfree(prop->value);
- prop->value= xalloc(strlen(value)+1);
- if (prop->value)
- strcpy(prop->value,value);
- return prop;
- }
- }
- if ((geom->num_properties>=geom->sz_properties)&&
- (_XkbAllocProps(geom,1)!=Success)) {
- return NULL;
- }
- prop= &geom->properties[geom->num_properties];
- prop->name= xalloc(strlen(name)+1);
- if (!name)
- return NULL;
- strcpy(prop->name,name);
- prop->value= xalloc(strlen(value)+1);
- if (!value) {
- xfree(prop->name);
- prop->name= NULL;
- return NULL;
- }
- strcpy(prop->value,value);
- geom->num_properties++;
- return prop;
-}
-
-XkbKeyAliasPtr
-XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr)
-{
-register int i;
-register XkbKeyAliasPtr alias;
-
- if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0]))
- return NULL;
- for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) {
- if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) {
- bzero(alias->real,XkbKeyNameLength);
- strncpy(alias->real,realStr,XkbKeyNameLength);
- return alias;
- }
- }
- if ((geom->num_key_aliases>=geom->sz_key_aliases)&&
- (_XkbAllocKeyAliases(geom,1)!=Success)) {
- return NULL;
- }
- alias= &geom->key_aliases[geom->num_key_aliases];
- bzero(alias,sizeof(XkbKeyAliasRec));
- strncpy(alias->alias,aliasStr,XkbKeyNameLength);
- strncpy(alias->real,realStr,XkbKeyNameLength);
- geom->num_key_aliases++;
- return alias;
-}
-
-XkbColorPtr
-XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel)
-{
-register int i;
-register XkbColorPtr color;
-
- if ((!geom)||(!spec))
- return NULL;
- for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
- if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
- color->pixel= pixel;
- return color;
- }
- }
- if ((geom->num_colors>=geom->sz_colors)&&
- (_XkbAllocColors(geom,1)!=Success)) {
- return NULL;
- }
- color= &geom->colors[geom->num_colors];
- color->pixel= pixel;
- color->spec= xalloc(strlen(spec)+1);
- if (!color->spec)
- return NULL;
- strcpy(color->spec,spec);
- geom->num_colors++;
- return color;
-}
-
-XkbOutlinePtr
-XkbAddGeomOutline(XkbShapePtr shape,int sz_points)
-{
-XkbOutlinePtr outline;
-
- if ((!shape)||(sz_points<0))
- return NULL;
- if ((shape->num_outlines>=shape->sz_outlines)&&
- (_XkbAllocOutlines(shape,1)!=Success)) {
- return NULL;
- }
- outline= &shape->outlines[shape->num_outlines];
- bzero(outline,sizeof(XkbOutlineRec));
- if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
- return NULL;
- shape->num_outlines++;
- return outline;
-}
-
-XkbShapePtr
-XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines)
-{
-XkbShapePtr shape;
-register int i;
-
- if ((!geom)||(!name)||(sz_outlines<0))
- return NULL;
- if (geom->num_shapes>0) {
- for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
- if (name==shape->name)
- return shape;
- }
- }
- if ((geom->num_shapes>=geom->sz_shapes)&&
- (_XkbAllocShapes(geom,1)!=Success))
- return NULL;
- shape= &geom->shapes[geom->num_shapes];
- bzero(shape,sizeof(XkbShapeRec));
- if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
- return NULL;
- shape->name= name;
- shape->primary= shape->approx= NULL;
- geom->num_shapes++;
- return shape;
-}
-
-XkbKeyPtr
-XkbAddGeomKey(XkbRowPtr row)
-{
-XkbKeyPtr key;
- if (!row)
- return NULL;
- if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
- return NULL;
- key= &row->keys[row->num_keys++];
- bzero(key,sizeof(XkbKeyRec));
- return key;
-}
-
-XkbRowPtr
-XkbAddGeomRow(XkbSectionPtr section,int sz_keys)
-{
-XkbRowPtr row;
-
- if ((!section)||(sz_keys<0))
- return NULL;
- if ((section->num_rows>=section->sz_rows)&&
- (_XkbAllocRows(section,1)!=Success))
- return NULL;
- row= &section->rows[section->num_rows];
- bzero(row,sizeof(XkbRowRec));
- if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
- return NULL;
- section->num_rows++;
- return row;
-}
-
-XkbSectionPtr
-XkbAddGeomSection( XkbGeometryPtr geom,
- Atom name,
- int sz_rows,
- int sz_doodads,
- int sz_over)
-{
-register int i;
-XkbSectionPtr section;
-
- if ((!geom)||(name==None)||(sz_rows<0))
- return NULL;
- for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
- if (section->name!=name)
- continue;
- if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
- ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
- ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
- return NULL;
- return section;
- }
- if ((geom->num_sections>=geom->sz_sections)&&
- (_XkbAllocSections(geom,1)!=Success))
- return NULL;
- section= &geom->sections[geom->num_sections];
- if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
- return NULL;
- if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
- if (section->rows) {
- xfree(section->rows);
- section->rows= NULL;
- section->sz_rows= section->num_rows= 0;
- }
- return NULL;
- }
- section->name= name;
- geom->num_sections++;
- return section;
-}
-
-XkbDoodadPtr
-XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name)
-{
-XkbDoodadPtr old,doodad;
-register int i,nDoodads;
-
- if ((!geom)||(name==None))
- return NULL;
- if ((section!=NULL)&&(section->num_doodads>0)) {
- old= section->doodads;
- nDoodads= section->num_doodads;
- }
- else {
- old= geom->doodads;
- nDoodads= geom->num_doodads;
- }
- for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
- if (doodad->any.name==name)
- return doodad;
- }
- if (section) {
- if ((section->num_doodads>=geom->sz_doodads)&&
- (_XkbAllocDoodads(section,1)!=Success)) {
- return NULL;
- }
- doodad= &section->doodads[section->num_doodads++];
- }
- else {
- if ((geom->num_doodads>=geom->sz_doodads)&&
- (_XkbAllocDoodads(geom,1)!=Success))
- return NULL;
- doodad= &geom->doodads[geom->num_doodads++];
- }
- bzero(doodad,sizeof(XkbDoodadRec));
- doodad->any.name= name;
- return doodad;
-}
-
-XkbOverlayKeyPtr
-XkbAddGeomOverlayKey( XkbOverlayPtr overlay,
- XkbOverlayRowPtr row,
- char * over,
- char * under)
-{
-register int i;
-XkbOverlayKeyPtr key;
-XkbSectionPtr section;
-XkbRowPtr row_under;
-Bool found;
-
- if ((!overlay)||(!row)||(!over)||(!under))
- return NULL;
- section= overlay->section_under;
- if (row->row_under>=section->num_rows)
- return NULL;
- row_under= &section->rows[row->row_under];
- for (i=0,found=FALSE;i<row_under->num_keys;i++) {
- if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) {
- found= TRUE;
- break;
- }
- }
- if (!found)
- return NULL;
- if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success))
- return NULL;
- key= &row->keys[row->num_keys];
- strncpy(key->under.name,under,XkbKeyNameLength);
- strncpy(key->over.name,over,XkbKeyNameLength);
- row->num_keys++;
- return key;
-}
-
-XkbOverlayRowPtr
-XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys)
-{
-register int i;
-XkbOverlayRowPtr row;
-
- if ((!overlay)||(sz_keys<0))
- return NULL;
- if (row_under>=overlay->section_under->num_rows)
- return NULL;
- for (i=0;i<overlay->num_rows;i++) {
- if (overlay->rows[i].row_under==row_under) {
- row= &overlay->rows[i];
- if ((row->sz_keys<sz_keys)&&
- (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
- return NULL;
- }
- return &overlay->rows[i];
- }
- }
- if ((overlay->num_rows>=overlay->sz_rows)&&
- (_XkbAllocOverlayRows(overlay,1)!=Success))
- return NULL;
- row= &overlay->rows[overlay->num_rows];
- bzero(row,sizeof(XkbOverlayRowRec));
- if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
- return NULL;
- row->row_under= row_under;
- overlay->num_rows++;
- return row;
-}
-
-XkbOverlayPtr
-XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows)
-{
-register int i;
-XkbOverlayPtr overlay;
-
- if ((!section)||(name==None)||(sz_rows==0))
- return NULL;
-
- for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
- if (overlay->name==name) {
- if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
- return NULL;
- return overlay;
- }
- }
- if ((section->num_overlays>=section->sz_overlays)&&
- (_XkbAllocOverlays(section,1)!=Success))
- return NULL;
- overlay= &section->overlays[section->num_overlays];
- if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
- return NULL;
- overlay->name= name;
- overlay->section_under= section;
- section->num_overlays++;
- return overlay;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+
+/***====================================================================***/
+
+static void
+_XkbFreeGeomLeafElems( Bool freeAll,
+ int first,
+ int count,
+ unsigned short * num_inout,
+ unsigned short * sz_inout,
+ char ** elems,
+ unsigned int elem_sz)
+{
+ if ((freeAll)||(*elems==NULL)) {
+ *num_inout= *sz_inout= 0;
+ if (*elems!=NULL) {
+ free(*elems);
+ *elems= NULL;
+ }
+ return;
+ }
+
+ if ((first>=(*num_inout))||(first<0)||(count<1))
+ return;
+
+ if (first+count>=(*num_inout)) {
+ /* truncating the array is easy */
+ (*num_inout)= first;
+ }
+ else {
+ char * ptr;
+ int extra;
+ ptr= *elems;
+ extra= ((*num_inout)-(first+count))*elem_sz;
+ if (extra>0)
+ memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
+ (*num_inout)-= count;
+ }
+ return;
+}
+
+typedef void (*ContentsClearFunc)(
+ char * /* priv */
+);
+
+static void
+_XkbFreeGeomNonLeafElems( Bool freeAll,
+ int first,
+ int count,
+ unsigned short * num_inout,
+ unsigned short * sz_inout,
+ char ** elems,
+ unsigned int elem_sz,
+ ContentsClearFunc freeFunc)
+{
+register int i;
+register char *ptr;
+
+ if (freeAll) {
+ first= 0;
+ count= (*num_inout);
+ }
+ else if ((first>=(*num_inout))||(first<0)||(count<1))
+ return;
+ else if (first+count>(*num_inout))
+ count= (*num_inout)-first;
+ if (*elems==NULL)
+ return;
+
+ if (freeFunc) {
+ ptr= *elems;
+ ptr+= first*elem_sz;
+ for (i=0;i<count;i++) {
+ (*freeFunc)(ptr);
+ ptr+= elem_sz;
+ }
+ }
+ if (freeAll) {
+ (*num_inout)= (*sz_inout)= 0;
+ if (*elems) {
+ free(*elems);
+ *elems= NULL;
+ }
+ }
+ else if (first+count>=(*num_inout))
+ *num_inout= first;
+ else {
+ i= ((*num_inout)-(first+count))*elem_sz;
+ ptr= *elems;
+ memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
+ (*num_inout)-= count;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearProperty(char *prop_in)
+{
+XkbPropertyPtr prop= (XkbPropertyPtr)prop_in;
+
+ if (prop->name) {
+ free(prop->name);
+ prop->name= NULL;
+ }
+ if (prop->value) {
+ free(prop->value);
+ prop->value= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeGeomProperties( XkbGeometryPtr geom,
+ int first,
+ int count,
+ Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_properties,&geom->sz_properties,
+ (char **)&geom->properties,
+ sizeof(XkbPropertyRec),_XkbClearProperty);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomKeyAliases( XkbGeometryPtr geom,
+ int first,
+ int count,
+ Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &geom->num_key_aliases,&geom->sz_key_aliases,
+ (char **)&geom->key_aliases,
+ sizeof(XkbKeyAliasRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearColor(char *color_in)
+{
+XkbColorPtr color= (XkbColorPtr)color_in;
+
+ if (color->spec)
+ free(color->spec);
+ return;
+}
+
+void
+XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_colors,&geom->sz_colors,
+ (char **)&geom->colors,
+ sizeof(XkbColorRec),_XkbClearColor);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &outline->num_points,&outline->sz_points,
+ (char **)&outline->points,
+ sizeof(XkbPointRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOutline(char *outline_in)
+{
+XkbOutlinePtr outline= (XkbOutlinePtr)outline_in;
+
+ if (outline->points!=NULL)
+ XkbFreeGeomPoints(outline,0,outline->num_points,TRUE);
+ return;
+}
+
+void
+XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &shape->num_outlines,&shape->sz_outlines,
+ (char **)&shape->outlines,
+ sizeof(XkbOutlineRec),_XkbClearOutline);
+
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearShape(char *shape_in)
+{
+XkbShapePtr shape= (XkbShapePtr)shape_in;
+
+ if (shape->outlines)
+ XkbFreeGeomOutlines(shape,0,shape->num_outlines,TRUE);
+ return;
+}
+
+void
+XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_shapes,&geom->sz_shapes,
+ (char **)&geom->shapes,
+ sizeof(XkbShapeRec),_XkbClearShape);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &row->num_keys,&row->sz_keys,
+ (char **)&row->keys,
+ sizeof(XkbOverlayKeyRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOverlayRow(char *row_in)
+{
+XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in;
+
+ if (row->keys!=NULL)
+ XkbFreeGeomOverlayKeys(row,0,row->num_keys,TRUE);
+ return;
+}
+
+void
+XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &overlay->num_rows,&overlay->sz_rows,
+ (char **)&overlay->rows,
+ sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOverlay(char *overlay_in)
+{
+XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in;
+
+ if (overlay->rows!=NULL)
+ XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,TRUE);
+ return;
+}
+
+void
+XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &section->num_overlays,&section->sz_overlays,
+ (char **)&section->overlays,
+ sizeof(XkbOverlayRec),_XkbClearOverlay);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &row->num_keys,&row->sz_keys,
+ (char **)&row->keys,
+ sizeof(XkbKeyRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearRow(char *row_in)
+{
+XkbRowPtr row= (XkbRowPtr)row_in;
+
+ if (row->keys!=NULL)
+ XkbFreeGeomKeys(row,0,row->num_keys,TRUE);
+ return;
+}
+
+void
+XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &section->num_rows,&section->sz_rows,
+ (char **)&section->rows,
+ sizeof(XkbRowRec),_XkbClearRow);
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearSection(char *section_in)
+{
+XkbSectionPtr section= (XkbSectionPtr)section_in;
+
+ if (section->rows!=NULL)
+ XkbFreeGeomRows(section,0,section->num_rows,TRUE);
+ if (section->doodads!=NULL) {
+ XkbFreeGeomDoodads(section->doodads,section->num_doodads,TRUE);
+ section->doodads= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_sections,&geom->sz_sections,
+ (char **)&geom->sections,
+ sizeof(XkbSectionRec),_XkbClearSection);
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearDoodad(char *doodad_in)
+{
+XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in;
+
+ switch (doodad->any.type) {
+ case XkbTextDoodad:
+ {
+ if (doodad->text.text!=NULL) {
+ free(doodad->text.text);
+ doodad->text.text= NULL;
+ }
+ if (doodad->text.font!=NULL) {
+ free(doodad->text.font);
+ doodad->text.font= NULL;
+ }
+ }
+ break;
+ case XkbLogoDoodad:
+ {
+ if (doodad->logo.logo_name!=NULL) {
+ free(doodad->logo.logo_name);
+ doodad->logo.logo_name= NULL;
+ }
+ }
+ break;
+ }
+ return;
+}
+
+void
+XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
+{
+register int i;
+register XkbDoodadPtr doodad;
+
+ if (doodads) {
+ for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
+ _XkbClearDoodad((char *)doodad);
+ }
+ if (freeAll)
+ free(doodads);
+ }
+ return;
+}
+
+void
+XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
+{
+ if (geom==NULL)
+ return;
+ if (freeMap)
+ which= XkbGeomAllMask;
+ if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
+ XkbFreeGeomProperties(geom,0,geom->num_properties,TRUE);
+ if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
+ XkbFreeGeomColors(geom,0,geom->num_colors,TRUE);
+ if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
+ XkbFreeGeomShapes(geom,0,geom->num_shapes,TRUE);
+ if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
+ XkbFreeGeomSections(geom,0,geom->num_sections,TRUE);
+ if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
+ XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,TRUE);
+ geom->doodads= NULL;
+ geom->num_doodads= geom->sz_doodads= 0;
+ }
+ if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
+ XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,TRUE);
+ if (freeMap) {
+ if (geom->label_font!=NULL) {
+ free(geom->label_font);
+ geom->label_font= NULL;
+ }
+ free(geom);
+ }
+ return;
+}
+
+/***====================================================================***/
+
+static Status
+_XkbGeomAlloc( void ** old,
+ unsigned short * num,
+ unsigned short * total,
+ int num_new,
+ size_t sz_elem)
+{
+ if (num_new<1)
+ return Success;
+ if ((*old)==NULL)
+ *num= *total= 0;
+
+ if ((*num)+num_new<=(*total))
+ return Success;
+
+ *total= (*num)+num_new;
+ if ((*old)!=NULL)
+ (*old)= realloc((*old),(*total)*sz_elem);
+ else (*old)= calloc((*total),sz_elem);
+ if ((*old)==NULL) {
+ *total= *num= 0;
+ return BadAlloc;
+ }
+
+ if (*num>0) {
+ char *tmp= (char *)(*old);
+ bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
+ }
+ return Success;
+}
+
+#define _XkbAllocProps(g,n) _XkbGeomAlloc((void *)&(g)->properties,\
+ &(g)->num_properties,&(g)->sz_properties,\
+ (n),sizeof(XkbPropertyRec))
+#define _XkbAllocColors(g,n) _XkbGeomAlloc((void *)&(g)->colors,\
+ &(g)->num_colors,&(g)->sz_colors,\
+ (n),sizeof(XkbColorRec))
+#define _XkbAllocShapes(g,n) _XkbGeomAlloc((void *)&(g)->shapes,\
+ &(g)->num_shapes,&(g)->sz_shapes,\
+ (n),sizeof(XkbShapeRec))
+#define _XkbAllocSections(g,n) _XkbGeomAlloc((void *)&(g)->sections,\
+ &(g)->num_sections,&(g)->sz_sections,\
+ (n),sizeof(XkbSectionRec))
+#define _XkbAllocDoodads(g,n) _XkbGeomAlloc((void *)&(g)->doodads,\
+ &(g)->num_doodads,&(g)->sz_doodads,\
+ (n),sizeof(XkbDoodadRec))
+#define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((void *)&(g)->key_aliases,\
+ &(g)->num_key_aliases,&(g)->sz_key_aliases,\
+ (n),sizeof(XkbKeyAliasRec))
+
+#define _XkbAllocOutlines(s,n) _XkbGeomAlloc((void *)&(s)->outlines,\
+ &(s)->num_outlines,&(s)->sz_outlines,\
+ (n),sizeof(XkbOutlineRec))
+#define _XkbAllocRows(s,n) _XkbGeomAlloc((void *)&(s)->rows,\
+ &(s)->num_rows,&(s)->sz_rows,\
+ (n),sizeof(XkbRowRec))
+#define _XkbAllocPoints(o,n) _XkbGeomAlloc((void *)&(o)->points,\
+ &(o)->num_points,&(o)->sz_points,\
+ (n),sizeof(XkbPointRec))
+#define _XkbAllocKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\
+ &(r)->num_keys,&(r)->sz_keys,\
+ (n),sizeof(XkbKeyRec))
+#define _XkbAllocOverlays(s,n) _XkbGeomAlloc((void *)&(s)->overlays,\
+ &(s)->num_overlays,&(s)->sz_overlays,\
+ (n),sizeof(XkbOverlayRec))
+#define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((void *)&(o)->rows,\
+ &(o)->num_rows,&(o)->sz_rows,\
+ (n),sizeof(XkbOverlayRowRec))
+#define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\
+ &(r)->num_keys,&(r)->sz_keys,\
+ (n),sizeof(XkbOverlayKeyRec))
+
+Status
+XkbAllocGeomProps(XkbGeometryPtr geom,int nProps)
+{
+ return _XkbAllocProps(geom,nProps);
+}
+
+Status
+XkbAllocGeomColors(XkbGeometryPtr geom,int nColors)
+{
+ return _XkbAllocColors(geom,nColors);
+}
+
+Status
+XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases)
+{
+ return _XkbAllocKeyAliases(geom,nKeyAliases);
+}
+
+Status
+XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes)
+{
+ return _XkbAllocShapes(geom,nShapes);
+}
+
+Status
+XkbAllocGeomSections(XkbGeometryPtr geom,int nSections)
+{
+ return _XkbAllocSections(geom,nSections);
+}
+
+Status
+XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays)
+{
+ return _XkbAllocOverlays(section,nOverlays);
+}
+
+Status
+XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows)
+{
+ return _XkbAllocOverlayRows(overlay,nRows);
+}
+
+Status
+XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys)
+{
+ return _XkbAllocOverlayKeys(row,nKeys);
+}
+
+Status
+XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads)
+{
+ return _XkbAllocDoodads(geom,nDoodads);
+}
+
+Status
+XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads)
+{
+ return _XkbAllocDoodads(section,nDoodads);
+}
+
+Status
+XkbAllocGeomOutlines(XkbShapePtr shape,int nOL)
+{
+ return _XkbAllocOutlines(shape,nOL);
+}
+
+Status
+XkbAllocGeomRows(XkbSectionPtr section,int nRows)
+{
+ return _XkbAllocRows(section,nRows);
+}
+
+Status
+XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts)
+{
+ return _XkbAllocPoints(ol,nPts);
+}
+
+Status
+XkbAllocGeomKeys(XkbRowPtr row,int nKeys)
+{
+ return _XkbAllocKeys(row,nKeys);
+}
+
+Status
+XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes)
+{
+XkbGeometryPtr geom;
+Status rtrn;
+
+ if (xkb->geom==NULL) {
+ xkb->geom= calloc(1, sizeof(XkbGeometryRec));
+ if (!xkb->geom)
+ return BadAlloc;
+ }
+ geom= xkb->geom;
+ if ((sizes->which&XkbGeomPropertiesMask)&&
+ ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomColorsMask)&&
+ ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomShapesMask)&&
+ ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomSectionsMask)&&
+ ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomDoodadsMask)&&
+ ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomKeyAliasesMask)&&
+ ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
+ goto BAIL;
+ }
+ return Success;
+BAIL:
+ XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
+ xkb->geom= NULL;
+ return rtrn;
+}
+
+/***====================================================================***/
+
+XkbPropertyPtr
+XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value)
+{
+register int i;
+register XkbPropertyPtr prop;
+
+ if ((!geom)||(!name)||(!value))
+ return NULL;
+ for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ if ((prop->name)&&(strcmp(name,prop->name)==0)) {
+ if (prop->value)
+ free(prop->value);
+ prop->value= malloc(strlen(value)+1);
+ if (prop->value)
+ strcpy(prop->value,value);
+ return prop;
+ }
+ }
+ if ((geom->num_properties>=geom->sz_properties)&&
+ (_XkbAllocProps(geom,1)!=Success)) {
+ return NULL;
+ }
+ prop= &geom->properties[geom->num_properties];
+ prop->name= malloc(strlen(name)+1);
+ if (!name)
+ return NULL;
+ strcpy(prop->name,name);
+ prop->value= malloc(strlen(value)+1);
+ if (!value) {
+ free(prop->name);
+ prop->name= NULL;
+ return NULL;
+ }
+ strcpy(prop->value,value);
+ geom->num_properties++;
+ return prop;
+}
+
+XkbKeyAliasPtr
+XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr)
+{
+register int i;
+register XkbKeyAliasPtr alias;
+
+ if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0]))
+ return NULL;
+ for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) {
+ if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) {
+ bzero(alias->real,XkbKeyNameLength);
+ strncpy(alias->real,realStr,XkbKeyNameLength);
+ return alias;
+ }
+ }
+ if ((geom->num_key_aliases>=geom->sz_key_aliases)&&
+ (_XkbAllocKeyAliases(geom,1)!=Success)) {
+ return NULL;
+ }
+ alias= &geom->key_aliases[geom->num_key_aliases];
+ bzero(alias,sizeof(XkbKeyAliasRec));
+ strncpy(alias->alias,aliasStr,XkbKeyNameLength);
+ strncpy(alias->real,realStr,XkbKeyNameLength);
+ geom->num_key_aliases++;
+ return alias;
+}
+
+XkbColorPtr
+XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel)
+{
+register int i;
+register XkbColorPtr color;
+
+ if ((!geom)||(!spec))
+ return NULL;
+ for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
+ color->pixel= pixel;
+ return color;
+ }
+ }
+ if ((geom->num_colors>=geom->sz_colors)&&
+ (_XkbAllocColors(geom,1)!=Success)) {
+ return NULL;
+ }
+ color= &geom->colors[geom->num_colors];
+ color->pixel= pixel;
+ color->spec= malloc(strlen(spec)+1);
+ if (!color->spec)
+ return NULL;
+ strcpy(color->spec,spec);
+ geom->num_colors++;
+ return color;
+}
+
+XkbOutlinePtr
+XkbAddGeomOutline(XkbShapePtr shape,int sz_points)
+{
+XkbOutlinePtr outline;
+
+ if ((!shape)||(sz_points<0))
+ return NULL;
+ if ((shape->num_outlines>=shape->sz_outlines)&&
+ (_XkbAllocOutlines(shape,1)!=Success)) {
+ return NULL;
+ }
+ outline= &shape->outlines[shape->num_outlines];
+ bzero(outline,sizeof(XkbOutlineRec));
+ if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
+ return NULL;
+ shape->num_outlines++;
+ return outline;
+}
+
+XkbShapePtr
+XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines)
+{
+XkbShapePtr shape;
+register int i;
+
+ if ((!geom)||(!name)||(sz_outlines<0))
+ return NULL;
+ if (geom->num_shapes>0) {
+ for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
+ if (name==shape->name)
+ return shape;
+ }
+ }
+ if ((geom->num_shapes>=geom->sz_shapes)&&
+ (_XkbAllocShapes(geom,1)!=Success))
+ return NULL;
+ shape= &geom->shapes[geom->num_shapes];
+ bzero(shape,sizeof(XkbShapeRec));
+ if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
+ return NULL;
+ shape->name= name;
+ shape->primary= shape->approx= NULL;
+ geom->num_shapes++;
+ return shape;
+}
+
+XkbKeyPtr
+XkbAddGeomKey(XkbRowPtr row)
+{
+XkbKeyPtr key;
+ if (!row)
+ return NULL;
+ if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
+ return NULL;
+ key= &row->keys[row->num_keys++];
+ bzero(key,sizeof(XkbKeyRec));
+ return key;
+}
+
+XkbRowPtr
+XkbAddGeomRow(XkbSectionPtr section,int sz_keys)
+{
+XkbRowPtr row;
+
+ if ((!section)||(sz_keys<0))
+ return NULL;
+ if ((section->num_rows>=section->sz_rows)&&
+ (_XkbAllocRows(section,1)!=Success))
+ return NULL;
+ row= &section->rows[section->num_rows];
+ bzero(row,sizeof(XkbRowRec));
+ if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
+ return NULL;
+ section->num_rows++;
+ return row;
+}
+
+XkbSectionPtr
+XkbAddGeomSection( XkbGeometryPtr geom,
+ Atom name,
+ int sz_rows,
+ int sz_doodads,
+ int sz_over)
+{
+register int i;
+XkbSectionPtr section;
+
+ if ((!geom)||(name==None)||(sz_rows<0))
+ return NULL;
+ for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ if (section->name!=name)
+ continue;
+ if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
+ ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
+ ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
+ return NULL;
+ return section;
+ }
+ if ((geom->num_sections>=geom->sz_sections)&&
+ (_XkbAllocSections(geom,1)!=Success))
+ return NULL;
+ section= &geom->sections[geom->num_sections];
+ if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
+ return NULL;
+ if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
+ if (section->rows) {
+ free(section->rows);
+ section->rows= NULL;
+ section->sz_rows= section->num_rows= 0;
+ }
+ return NULL;
+ }
+ section->name= name;
+ geom->num_sections++;
+ return section;
+}
+
+XkbDoodadPtr
+XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name)
+{
+XkbDoodadPtr old,doodad;
+register int i,nDoodads;
+
+ if ((!geom)||(name==None))
+ return NULL;
+ if ((section!=NULL)&&(section->num_doodads>0)) {
+ old= section->doodads;
+ nDoodads= section->num_doodads;
+ }
+ else {
+ old= geom->doodads;
+ nDoodads= geom->num_doodads;
+ }
+ for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
+ if (doodad->any.name==name)
+ return doodad;
+ }
+ if (section) {
+ if ((section->num_doodads>=geom->sz_doodads)&&
+ (_XkbAllocDoodads(section,1)!=Success)) {
+ return NULL;
+ }
+ doodad= &section->doodads[section->num_doodads++];
+ }
+ else {
+ if ((geom->num_doodads>=geom->sz_doodads)&&
+ (_XkbAllocDoodads(geom,1)!=Success))
+ return NULL;
+ doodad= &geom->doodads[geom->num_doodads++];
+ }
+ bzero(doodad,sizeof(XkbDoodadRec));
+ doodad->any.name= name;
+ return doodad;
+}
+
+XkbOverlayKeyPtr
+XkbAddGeomOverlayKey( XkbOverlayPtr overlay,
+ XkbOverlayRowPtr row,
+ char * over,
+ char * under)
+{
+register int i;
+XkbOverlayKeyPtr key;
+XkbSectionPtr section;
+XkbRowPtr row_under;
+Bool found;
+
+ if ((!overlay)||(!row)||(!over)||(!under))
+ return NULL;
+ section= overlay->section_under;
+ if (row->row_under>=section->num_rows)
+ return NULL;
+ row_under= &section->rows[row->row_under];
+ for (i=0,found=FALSE;i<row_under->num_keys;i++) {
+ if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) {
+ found= TRUE;
+ break;
+ }
+ }
+ if (!found)
+ return NULL;
+ if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success))
+ return NULL;
+ key= &row->keys[row->num_keys];
+ strncpy(key->under.name,under,XkbKeyNameLength);
+ strncpy(key->over.name,over,XkbKeyNameLength);
+ row->num_keys++;
+ return key;
+}
+
+XkbOverlayRowPtr
+XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys)
+{
+register int i;
+XkbOverlayRowPtr row;
+
+ if ((!overlay)||(sz_keys<0))
+ return NULL;
+ if (row_under>=overlay->section_under->num_rows)
+ return NULL;
+ for (i=0;i<overlay->num_rows;i++) {
+ if (overlay->rows[i].row_under==row_under) {
+ row= &overlay->rows[i];
+ if ((row->sz_keys<sz_keys)&&
+ (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
+ return NULL;
+ }
+ return &overlay->rows[i];
+ }
+ }
+ if ((overlay->num_rows>=overlay->sz_rows)&&
+ (_XkbAllocOverlayRows(overlay,1)!=Success))
+ return NULL;
+ row= &overlay->rows[overlay->num_rows];
+ bzero(row,sizeof(XkbOverlayRowRec));
+ if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
+ return NULL;
+ row->row_under= row_under;
+ overlay->num_rows++;
+ return row;
+}
+
+XkbOverlayPtr
+XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows)
+{
+register int i;
+XkbOverlayPtr overlay;
+
+ if ((!section)||(name==None)||(sz_rows==0))
+ return NULL;
+
+ for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
+ if (overlay->name==name) {
+ if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
+ return NULL;
+ return overlay;
+ }
+ }
+ if ((section->num_overlays>=section->sz_overlays)&&
+ (_XkbAllocOverlays(section,1)!=Success))
+ return NULL;
+ overlay= &section->overlays[section->num_overlays];
+ if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
+ return NULL;
+ overlay->name= name;
+ overlay->section_under= section;
+ section->num_overlays++;
+ return overlay;
+}
diff --git a/xorg-server/xkb/XKBMAlloc.c b/xorg-server/xkb/XKBMAlloc.c
index fd12e2b6c..34e52835d 100644
--- a/xorg-server/xkb/XKBMAlloc.c
+++ b/xorg-server/xkb/XKBMAlloc.c
@@ -1,900 +1,900 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#elif defined(HAVE_CONFIG_H)
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-#include <X11/keysym.h>
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-
-/***====================================================================***/
-
-Status
-XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes)
-{
-register int i;
-XkbClientMapPtr map;
-
- if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes)))
- return BadValue;
- if ((which&XkbKeySymsMask)&&
- ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))) {
- DebugF("bad keycode (%d,%d) in XkbAllocClientMap\n",
- xkb->min_key_code,xkb->max_key_code);
- return BadValue;
- }
-
- if (xkb->map==NULL) {
- map= xcalloc(1, sizeof(XkbClientMapRec));
- if (map==NULL)
- return BadAlloc;
- xkb->map= map;
- }
- else map= xkb->map;
-
- if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) {
- if (map->types==NULL) {
- map->types= xcalloc(nTotalTypes, sizeof(XkbKeyTypeRec));
- if (map->types==NULL)
- return BadAlloc;
- map->num_types= 0;
- map->size_types= nTotalTypes;
- }
- else if (map->size_types<nTotalTypes) {
- XkbKeyTypeRec *prev_types = map->types;
-
- map->types= xrealloc(map->types,nTotalTypes * sizeof(XkbKeyTypeRec));
- if (map->types==NULL) {
- xfree(prev_types);
- map->num_types= map->size_types= 0;
- return BadAlloc;
- }
- map->size_types= nTotalTypes;
- bzero(&map->types[map->num_types],
- ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec)));
- }
- }
- if (which&XkbKeySymsMask) {
- int nKeys= XkbNumKeys(xkb);
- if (map->syms==NULL) {
- map->size_syms= (nKeys*15)/10;
- map->syms= xcalloc(map->size_syms, sizeof(KeySym));
- if (!map->syms) {
- map->size_syms= 0;
- return BadAlloc;
- }
- map->num_syms= 1;
- map->syms[0]= NoSymbol;
- }
- if (map->key_sym_map==NULL) {
- i= xkb->max_key_code+1;
- map->key_sym_map= xcalloc(i, sizeof(XkbSymMapRec));
- if (map->key_sym_map==NULL)
- return BadAlloc;
- }
- }
- if (which&XkbModifierMapMask) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadMatch;
- if (map->modmap==NULL) {
- i= xkb->max_key_code+1;
- map->modmap= xcalloc(i, sizeof(unsigned char));
- if (map->modmap==NULL)
- return BadAlloc;
- }
- }
- return Success;
-}
-
-Status
-XkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions)
-{
-register int i;
-XkbServerMapPtr map;
-
- if (xkb==NULL)
- return BadMatch;
- if (xkb->server==NULL) {
- map= xcalloc(1, sizeof(XkbServerMapRec));
- if (map==NULL)
- return BadAlloc;
- for (i=0;i<XkbNumVirtualMods;i++) {
- map->vmods[i]= XkbNoModifierMask;
- }
- xkb->server= map;
- }
- else map= xkb->server;
- if (which&XkbExplicitComponentsMask) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadMatch;
- if (map->explicit==NULL) {
- i= xkb->max_key_code+1;
- map->explicit= xcalloc(i, sizeof(unsigned char));
- if (map->explicit==NULL)
- return BadAlloc;
- }
- }
- if (which&XkbKeyActionsMask) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadMatch;
- if (nNewActions<1)
- nNewActions= 1;
- if (map->acts==NULL) {
- map->acts= xcalloc((nNewActions+1), sizeof(XkbAction));
- if (map->acts==NULL)
- return BadAlloc;
- map->num_acts= 1;
- map->size_acts= nNewActions+1;
- }
- else if ((map->size_acts-map->num_acts)<nNewActions) {
- unsigned need;
- XkbAction *prev_acts = map->acts;
- need= map->num_acts+nNewActions;
- map->acts= xrealloc(map->acts,need * sizeof(XkbAction));
- if (map->acts==NULL) {
- xfree(prev_acts);
- map->num_acts= map->size_acts= 0;
- return BadAlloc;
- }
- map->size_acts= need;
- bzero(&map->acts[map->num_acts],
- ((map->size_acts-map->num_acts)*sizeof(XkbAction)));
- }
- if (map->key_acts==NULL) {
- i= xkb->max_key_code+1;
- map->key_acts= xcalloc(i, sizeof(unsigned short));
- if (map->key_acts==NULL)
- return BadAlloc;
- }
- }
- if (which&XkbKeyBehaviorsMask) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadMatch;
- if (map->behaviors==NULL) {
- i= xkb->max_key_code+1;
- map->behaviors= xcalloc(i, sizeof(XkbBehavior));
- if (map->behaviors==NULL)
- return BadAlloc;
- }
- }
- if (which&XkbVirtualModMapMask) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadMatch;
- if (map->vmodmap==NULL) {
- i= xkb->max_key_code+1;
- map->vmodmap= xcalloc(i, sizeof(unsigned short));
- if (map->vmodmap==NULL)
- return BadAlloc;
- }
- }
- return Success;
-}
-
-/***====================================================================***/
-
-static Status
-XkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into)
-{
- if ((!from)||(!into))
- return BadMatch;
- if (into->map) {
- xfree(into->map);
- into->map= NULL;
- }
- if (into->preserve) {
- xfree(into->preserve);
- into->preserve= NULL;
- }
- if (into->level_names) {
- xfree(into->level_names);
- into->level_names= NULL;
- }
- *into= *from;
- if ((from->map)&&(into->map_count>0)) {
- into->map= xcalloc(into->map_count, sizeof(XkbKTMapEntryRec));
- if (!into->map)
- return BadAlloc;
- memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec));
- }
- if ((from->preserve)&&(into->map_count>0)) {
- into->preserve= xcalloc(into->map_count, sizeof(XkbModsRec));
- if (!into->preserve)
- return BadAlloc;
- memcpy(into->preserve,from->preserve,
- into->map_count*sizeof(XkbModsRec));
- }
- if ((from->level_names)&&(into->num_levels>0)) {
- into->level_names= xcalloc(into->num_levels, sizeof(Atom));
- if (!into->level_names)
- return BadAlloc;
- memcpy(into->level_names,from->level_names,
- into->num_levels*sizeof(Atom));
- }
- return Success;
-}
-
-Status
-XkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types)
-{
-register int i,rtrn;
-
- if ((!from)||(!into)||(num_types<0))
- return BadMatch;
- for (i=0;i<num_types;i++) {
- if ((rtrn= XkbCopyKeyType(from++,into++))!=Success)
- return rtrn;
- }
- return Success;
-}
-
-Status
-XkbResizeKeyType( XkbDescPtr xkb,
- int type_ndx,
- int map_count,
- Bool want_preserve,
- int new_num_lvls)
-{
-XkbKeyTypePtr type;
-KeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys;
-
- if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)||
- (new_num_lvls<1))
- return BadValue;
- switch (type_ndx) {
- case XkbOneLevelIndex:
- if (new_num_lvls!=1)
- return BadMatch;
- break;
- case XkbTwoLevelIndex:
- case XkbAlphabeticIndex:
- case XkbKeypadIndex:
- if (new_num_lvls!=2)
- return BadMatch;
- break;
- }
- type= &xkb->map->types[type_ndx];
- if (map_count==0) {
- if (type->map!=NULL)
- xfree(type->map);
- type->map= NULL;
- if (type->preserve!=NULL)
- xfree(type->preserve);
- type->preserve= NULL;
- type->map_count= 0;
- }
- else {
- XkbKTMapEntryRec *prev_map = type->map;
-
- if ((map_count>type->map_count)||(type->map==NULL))
- type->map = xrealloc(type->map,map_count * sizeof(XkbKTMapEntryRec));
- if (!type->map) {
- if (prev_map)
- xfree(prev_map);
- return BadAlloc;
- }
- if (want_preserve) {
- XkbModsRec *prev_preserve = type->preserve;
-
- if ((map_count>type->map_count)||(type->preserve==NULL)) {
- type->preserve = xrealloc(type->preserve,
- map_count * sizeof(XkbModsRec));
- }
- if (!type->preserve) {
- if (prev_preserve)
- xfree(prev_preserve);
- return BadAlloc;
- }
- }
- else if (type->preserve!=NULL) {
- xfree(type->preserve);
- type->preserve= NULL;
- }
- type->map_count= map_count;
- }
-
- if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) {
- Atom * prev_level_names = type->level_names;
-
- type->level_names = xrealloc(type->level_names,
- new_num_lvls * sizeof(Atom));
- if (!type->level_names) {
- if (prev_level_names)
- xfree(prev_level_names);
- return BadAlloc;
- }
- }
- /*
- * Here's the theory:
- * If the width of the type changed, we might have to resize the symbol
- * maps for any keys that use the type for one or more groups. This is
- * expensive, so we'll try to cull out any keys that are obviously okay:
- * In any case:
- * - keys that have a group width <= the old width are okay (because
- * they could not possibly have been associated with the old type)
- * If the key type increased in size:
- * - keys that already have a group width >= to the new width are okay
- * + keys that have a group width >= the old width but < the new width
- * might have to be enlarged.
- * If the key type decreased in size:
- * - keys that have a group width > the old width don't have to be
- * resized (because they must have some other wider type associated
- * with some group).
- * + keys that have a group width == the old width might have to be
- * shrunk.
- * The possibilities marked with '+' require us to examine the key types
- * associated with each group for the key.
- */
- bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode));
- nMatchingKeys= 0;
- if (new_num_lvls>type->num_levels) {
- int nTotal;
- KeySym * newSyms;
- int width,match,nResize;
- register int i,g,nSyms;
-
- nResize= 0;
- for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- width= XkbKeyGroupsWidth(xkb,i);
- if (width<type->num_levels)
- continue;
- for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
- if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
- matchingKeys[nMatchingKeys++]= i;
- match= 1;
- }
- }
- if ((!match)||(width>=new_num_lvls))
- nTotal+= XkbKeyNumSyms(xkb,i);
- else {
- nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
- nResize++;
- }
- }
- if (nResize>0) {
- int nextMatch;
- xkb->map->size_syms= (nTotal*15)/10;
- newSyms = xcalloc(xkb->map->size_syms, sizeof(KeySym));
- if (newSyms==NULL)
- return BadAlloc;
- nextMatch= 0;
- nSyms= 1;
- for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- if (matchingKeys[nextMatch]==i) {
- KeySym *pOld;
- nextMatch++;
- width= XkbKeyGroupsWidth(xkb,i);
- pOld= XkbKeySymsPtr(xkb,i);
- for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) {
- memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g],
- width*sizeof(KeySym));
- }
- xkb->map->key_sym_map[i].offset= nSyms;
- nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
- }
- else {
- memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),
- XkbKeyNumSyms(xkb,i)*sizeof(KeySym));
- xkb->map->key_sym_map[i].offset= nSyms;
- nSyms+= XkbKeyNumSyms(xkb,i);
- }
- }
- type->num_levels= new_num_lvls;
- xfree(xkb->map->syms);
- xkb->map->syms= newSyms;
- xkb->map->num_syms= nSyms;
- return Success;
- }
- }
- else if (new_num_lvls<type->num_levels) {
- int width,match;
- register int g,i;
- for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- width= XkbKeyGroupsWidth(xkb,i);
- if (width<type->num_levels)
- continue;
- for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
- if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
- matchingKeys[nMatchingKeys++]= i;
- match= 1;
- }
- }
- }
- }
- if (nMatchingKeys>0) {
- int key,firstClear;
- register int i,g;
- if (new_num_lvls>type->num_levels)
- firstClear= type->num_levels;
- else firstClear= new_num_lvls;
- for (i=0;i<nMatchingKeys;i++) {
- KeySym * pSyms;
- int width,nClear;
-
- key= matchingKeys[i];
- width= XkbKeyGroupsWidth(xkb,key);
- nClear= width-firstClear;
- pSyms= XkbKeySymsPtr(xkb,key);
- for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) {
- if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) {
- if (nClear>0)
- bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym));
- }
- }
- }
- }
- type->num_levels= new_num_lvls;
- return Success;
-}
-
-KeySym *
-XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed)
-{
-register int i,nSyms,nKeySyms;
-unsigned nOldSyms;
-KeySym *newSyms;
-
- if (needed==0) {
- xkb->map->key_sym_map[key].offset= 0;
- return xkb->map->syms;
- }
- nOldSyms= XkbKeyNumSyms(xkb,key);
- if (nOldSyms>=(unsigned)needed) {
- return XkbKeySymsPtr(xkb,key);
- }
- if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) {
- if (nOldSyms>0) {
- memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key),
- nOldSyms*sizeof(KeySym));
- }
- if ((needed-nOldSyms)>0) {
- bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)],
- (needed-nOldSyms)*sizeof(KeySym));
- }
- xkb->map->key_sym_map[key].offset = xkb->map->num_syms;
- xkb->map->num_syms+= needed;
- return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
- }
- xkb->map->size_syms+= (needed>32?needed:32);
- newSyms = xcalloc(xkb->map->size_syms, sizeof(KeySym));
- if (newSyms==NULL)
- return NULL;
- newSyms[0]= NoSymbol;
- nSyms = 1;
- for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
- int nCopy;
-
- nCopy= nKeySyms= XkbKeyNumSyms(xkb,i);
- if ((nKeySyms==0)&&(i!=key))
- continue;
- if (i==key)
- nKeySyms= needed;
- if (nCopy!=0)
- memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym));
- if (nKeySyms>nCopy)
- bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym));
- xkb->map->key_sym_map[i].offset = nSyms;
- nSyms+= nKeySyms;
- }
- xfree(xkb->map->syms);
- xkb->map->syms = newSyms;
- xkb->map->num_syms = nSyms;
- return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
-}
-
-static unsigned
-_ExtendRange( unsigned int old_flags,
- unsigned int flag,
- KeyCode newKC,
- KeyCode * old_min,
- unsigned char * old_num)
-{
- if ((old_flags&flag)==0) {
- old_flags|= flag;
- *old_min= newKC;
- *old_num= 1;
- }
- else {
- int last= (*old_min)+(*old_num)-1;
- if (newKC<*old_min) {
- *old_min= newKC;
- *old_num= (last-newKC)+1;
- }
- else if (newKC>last) {
- *old_num= (newKC-(*old_min))+1;
- }
- }
- return old_flags;
-}
-
-Status
-XkbChangeKeycodeRange( XkbDescPtr xkb,
- int minKC,
- int maxKC,
- XkbChangesPtr changes)
-{
-int tmp;
-
- if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode))
- return BadValue;
- if (minKC>maxKC)
- return BadMatch;
- if (minKC<xkb->min_key_code) {
- if (changes)
- changes->map.min_key_code= minKC;
- tmp= xkb->min_key_code-minKC;
- if (xkb->map) {
- if (xkb->map->key_sym_map) {
- bzero((char *)&xkb->map->key_sym_map[minKC],
- tmp*sizeof(XkbSymMapRec));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeySymsMask,minKC,
- &changes->map.first_key_sym,
- &changes->map.num_key_syms);
- }
- }
- if (xkb->map->modmap) {
- bzero((char *)&xkb->map->modmap[minKC],tmp);
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbModifierMapMask,minKC,
- &changes->map.first_modmap_key,
- &changes->map.num_modmap_keys);
- }
- }
- }
- if (xkb->server) {
- if (xkb->server->behaviors) {
- bzero((char *)&xkb->server->behaviors[minKC],
- tmp*sizeof(XkbBehavior));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeyBehaviorsMask,minKC,
- &changes->map.first_key_behavior,
- &changes->map.num_key_behaviors);
- }
- }
- if (xkb->server->key_acts) {
- bzero((char *)&xkb->server->key_acts[minKC],
- tmp*sizeof(unsigned short));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeyActionsMask,minKC,
- &changes->map.first_key_act,
- &changes->map.num_key_acts);
- }
- }
- if (xkb->server->vmodmap) {
- bzero((char *)&xkb->server->vmodmap[minKC],
- tmp*sizeof(unsigned short));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbVirtualModMapMask,minKC,
- &changes->map.first_modmap_key,
- &changes->map.num_vmodmap_keys);
- }
- }
- }
- if ((xkb->names)&&(xkb->names->keys)) {
- bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec));
- if (changes) {
- changes->names.changed= _ExtendRange(changes->names.changed,
- XkbKeyNamesMask,minKC,
- &changes->names.first_key,
- &changes->names.num_keys);
- }
- }
- xkb->min_key_code= minKC;
- }
- if (maxKC>xkb->max_key_code) {
- if (changes)
- changes->map.max_key_code= maxKC;
- tmp= maxKC-xkb->max_key_code;
- if (xkb->map) {
- if (xkb->map->key_sym_map) {
- XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map;
-
- xkb->map->key_sym_map = xrealloc(xkb->map->key_sym_map,
- (maxKC+1) * sizeof(XkbSymMapRec));
- if (!xkb->map->key_sym_map) {
- xfree(prev_key_sym_map);
- return BadAlloc;
- }
- bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code],
- tmp*sizeof(XkbSymMapRec));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeySymsMask,maxKC,
- &changes->map.first_key_sym,
- &changes->map.num_key_syms);
- }
- }
- if (xkb->map->modmap) {
- unsigned char *prev_modmap = xkb->map->modmap;
-
- xkb->map->modmap = xrealloc(xkb->map->modmap,
- (maxKC+1) * sizeof(unsigned char));
- if (!xkb->map->modmap) {
- xfree(prev_modmap);
- return BadAlloc;
- }
- bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp);
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbModifierMapMask,maxKC,
- &changes->map.first_modmap_key,
- &changes->map.num_modmap_keys);
- }
- }
- }
- if (xkb->server) {
- if (xkb->server->behaviors) {
- XkbBehavior *prev_behaviors = xkb->server->behaviors;
-
- xkb->server->behaviors = xrealloc(xkb->server->behaviors,
- (maxKC+1) * sizeof(XkbBehavior));
- if (!xkb->server->behaviors) {
- xfree(prev_behaviors);
- return BadAlloc;
- }
- bzero((char *)&xkb->server->behaviors[xkb->max_key_code],
- tmp*sizeof(XkbBehavior));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeyBehaviorsMask,maxKC,
- &changes->map.first_key_behavior,
- &changes->map.num_key_behaviors);
- }
- }
- if (xkb->server->key_acts) {
- unsigned short *prev_key_acts = xkb->server->key_acts;
-
- xkb->server->key_acts= xrealloc(xkb->server->key_acts,
- (maxKC+1) * sizeof(unsigned short));
- if (!xkb->server->key_acts) {
- xfree(prev_key_acts);
- return BadAlloc;
- }
- bzero((char *)&xkb->server->key_acts[xkb->max_key_code],
- tmp*sizeof(unsigned short));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeyActionsMask,maxKC,
- &changes->map.first_key_act,
- &changes->map.num_key_acts);
- }
- }
- if (xkb->server->vmodmap) {
- unsigned short *prev_vmodmap = xkb->server->vmodmap;
-
- xkb->server->vmodmap= xrealloc(xkb->server->vmodmap,
- (maxKC+1) * sizeof(unsigned short));
- if (!xkb->server->vmodmap) {
- xfree(prev_vmodmap);
- return BadAlloc;
- }
- bzero((char *)&xkb->server->vmodmap[xkb->max_key_code],
- tmp*sizeof(unsigned short));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbVirtualModMapMask,maxKC,
- &changes->map.first_modmap_key,
- &changes->map.num_vmodmap_keys);
- }
- }
- }
- if ((xkb->names)&&(xkb->names->keys)) {
- XkbKeyNameRec *prev_keys = xkb->names->keys;
-
- xkb->names->keys = xrealloc(xkb->names->keys,
- (maxKC+1) * sizeof(XkbKeyNameRec));
- if (!xkb->names->keys) {
- xfree(prev_keys);
- return BadAlloc;
- }
- bzero((char *)&xkb->names->keys[xkb->max_key_code],
- tmp*sizeof(XkbKeyNameRec));
- if (changes) {
- changes->names.changed= _ExtendRange(changes->names.changed,
- XkbKeyNamesMask,maxKC,
- &changes->names.first_key,
- &changes->names.num_keys);
- }
- }
- xkb->max_key_code= maxKC;
- }
- return Success;
-}
-
-XkbAction *
-XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed)
-{
-register int i,nActs;
-XkbAction *newActs;
-
- if (needed==0) {
- xkb->server->key_acts[key]= 0;
- return NULL;
- }
- if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed))
- return XkbKeyActionsPtr(xkb,key);
- if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) {
- xkb->server->key_acts[key]= xkb->server->num_acts;
- xkb->server->num_acts+= needed;
- return &xkb->server->acts[xkb->server->key_acts[key]];
- }
- xkb->server->size_acts= xkb->server->num_acts+needed+8;
- newActs = xcalloc(xkb->server->size_acts, sizeof(XkbAction));
- if (newActs==NULL)
- return NULL;
- newActs[0].type = XkbSA_NoAction;
- nActs = 1;
- for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
- int nKeyActs,nCopy;
-
- if ((xkb->server->key_acts[i]==0)&&(i!=key))
- continue;
-
- nCopy= nKeyActs= XkbKeyNumActions(xkb,i);
- if (i==key) {
- nKeyActs= needed;
- if (needed<nCopy)
- nCopy= needed;
- }
-
- if (nCopy>0)
- memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i),
- nCopy*sizeof(XkbAction));
- if (nCopy<nKeyActs)
- bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction));
- xkb->server->key_acts[i]= nActs;
- nActs+= nKeyActs;
- }
- xfree(xkb->server->acts);
- xkb->server->acts = newActs;
- xkb->server->num_acts= nActs;
- return &xkb->server->acts[xkb->server->key_acts[key]];
-}
-
-void
-XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
-{
-XkbClientMapPtr map;
-
- if ((xkb==NULL)||(xkb->map==NULL))
- return;
- if (freeMap)
- what= XkbAllClientInfoMask;
- map= xkb->map;
- if (what&XkbKeyTypesMask) {
- if (map->types!=NULL) {
- if (map->num_types>0) {
- register int i;
- XkbKeyTypePtr type;
- for (i=0,type=map->types;i<map->num_types;i++,type++) {
- if (type->map!=NULL) {
- xfree(type->map);
- type->map= NULL;
- }
- if (type->preserve!=NULL) {
- xfree(type->preserve);
- type->preserve= NULL;
- }
- type->map_count= 0;
- if (type->level_names!=NULL) {
- xfree(type->level_names);
- type->level_names= NULL;
- }
- }
- }
- xfree(map->types);
- map->num_types= map->size_types= 0;
- map->types= NULL;
- }
- }
- if (what&XkbKeySymsMask) {
- if (map->key_sym_map!=NULL) {
- xfree(map->key_sym_map);
- map->key_sym_map= NULL;
- }
- if (map->syms!=NULL) {
- xfree(map->syms);
- map->size_syms= map->num_syms= 0;
- map->syms= NULL;
- }
- }
- if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) {
- xfree(map->modmap);
- map->modmap= NULL;
- }
- if (freeMap) {
- xfree(xkb->map);
- xkb->map= NULL;
- }
- return;
-}
-
-void
-XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
-{
-XkbServerMapPtr map;
-
- if ((xkb==NULL)||(xkb->server==NULL))
- return;
- if (freeMap)
- what= XkbAllServerInfoMask;
- map= xkb->server;
- if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) {
- xfree(map->explicit);
- map->explicit= NULL;
- }
- if (what&XkbKeyActionsMask) {
- if (map->key_acts!=NULL) {
- xfree(map->key_acts);
- map->key_acts= NULL;
- }
- if (map->acts!=NULL) {
- xfree(map->acts);
- map->num_acts= map->size_acts= 0;
- map->acts= NULL;
- }
- }
- if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) {
- xfree(map->behaviors);
- map->behaviors= NULL;
- }
- if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) {
- xfree(map->vmodmap);
- map->vmodmap= NULL;
- }
-
- if (freeMap) {
- xfree(xkb->server);
- xkb->server= NULL;
- }
- return;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <X11/keysym.h>
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+
+/***====================================================================***/
+
+Status
+XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes)
+{
+register int i;
+XkbClientMapPtr map;
+
+ if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes)))
+ return BadValue;
+ if ((which&XkbKeySymsMask)&&
+ ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))) {
+ DebugF("bad keycode (%d,%d) in XkbAllocClientMap\n",
+ xkb->min_key_code,xkb->max_key_code);
+ return BadValue;
+ }
+
+ if (xkb->map==NULL) {
+ map= calloc(1, sizeof(XkbClientMapRec));
+ if (map==NULL)
+ return BadAlloc;
+ xkb->map= map;
+ }
+ else map= xkb->map;
+
+ if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) {
+ if (map->types==NULL) {
+ map->types= calloc(nTotalTypes, sizeof(XkbKeyTypeRec));
+ if (map->types==NULL)
+ return BadAlloc;
+ map->num_types= 0;
+ map->size_types= nTotalTypes;
+ }
+ else if (map->size_types<nTotalTypes) {
+ XkbKeyTypeRec *prev_types = map->types;
+
+ map->types= realloc(map->types,nTotalTypes * sizeof(XkbKeyTypeRec));
+ if (map->types==NULL) {
+ free(prev_types);
+ map->num_types= map->size_types= 0;
+ return BadAlloc;
+ }
+ map->size_types= nTotalTypes;
+ bzero(&map->types[map->num_types],
+ ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec)));
+ }
+ }
+ if (which&XkbKeySymsMask) {
+ int nKeys= XkbNumKeys(xkb);
+ if (map->syms==NULL) {
+ map->size_syms= (nKeys*15)/10;
+ map->syms= calloc(map->size_syms, sizeof(KeySym));
+ if (!map->syms) {
+ map->size_syms= 0;
+ return BadAlloc;
+ }
+ map->num_syms= 1;
+ map->syms[0]= NoSymbol;
+ }
+ if (map->key_sym_map==NULL) {
+ i= xkb->max_key_code+1;
+ map->key_sym_map= calloc(i, sizeof(XkbSymMapRec));
+ if (map->key_sym_map==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbModifierMapMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->modmap==NULL) {
+ i= xkb->max_key_code+1;
+ map->modmap= calloc(i, sizeof(unsigned char));
+ if (map->modmap==NULL)
+ return BadAlloc;
+ }
+ }
+ return Success;
+}
+
+Status
+XkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions)
+{
+register int i;
+XkbServerMapPtr map;
+
+ if (xkb==NULL)
+ return BadMatch;
+ if (xkb->server==NULL) {
+ map= calloc(1, sizeof(XkbServerMapRec));
+ if (map==NULL)
+ return BadAlloc;
+ for (i=0;i<XkbNumVirtualMods;i++) {
+ map->vmods[i]= XkbNoModifierMask;
+ }
+ xkb->server= map;
+ }
+ else map= xkb->server;
+ if (which&XkbExplicitComponentsMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->explicit==NULL) {
+ i= xkb->max_key_code+1;
+ map->explicit= calloc(i, sizeof(unsigned char));
+ if (map->explicit==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbKeyActionsMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (nNewActions<1)
+ nNewActions= 1;
+ if (map->acts==NULL) {
+ map->acts= calloc((nNewActions+1), sizeof(XkbAction));
+ if (map->acts==NULL)
+ return BadAlloc;
+ map->num_acts= 1;
+ map->size_acts= nNewActions+1;
+ }
+ else if ((map->size_acts-map->num_acts)<nNewActions) {
+ unsigned need;
+ XkbAction *prev_acts = map->acts;
+ need= map->num_acts+nNewActions;
+ map->acts= realloc(map->acts,need * sizeof(XkbAction));
+ if (map->acts==NULL) {
+ free(prev_acts);
+ map->num_acts= map->size_acts= 0;
+ return BadAlloc;
+ }
+ map->size_acts= need;
+ bzero(&map->acts[map->num_acts],
+ ((map->size_acts-map->num_acts)*sizeof(XkbAction)));
+ }
+ if (map->key_acts==NULL) {
+ i= xkb->max_key_code+1;
+ map->key_acts= calloc(i, sizeof(unsigned short));
+ if (map->key_acts==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbKeyBehaviorsMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->behaviors==NULL) {
+ i= xkb->max_key_code+1;
+ map->behaviors= calloc(i, sizeof(XkbBehavior));
+ if (map->behaviors==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbVirtualModMapMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->vmodmap==NULL) {
+ i= xkb->max_key_code+1;
+ map->vmodmap= calloc(i, sizeof(unsigned short));
+ if (map->vmodmap==NULL)
+ return BadAlloc;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+static Status
+XkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into)
+{
+ if ((!from)||(!into))
+ return BadMatch;
+ if (into->map) {
+ free(into->map);
+ into->map= NULL;
+ }
+ if (into->preserve) {
+ free(into->preserve);
+ into->preserve= NULL;
+ }
+ if (into->level_names) {
+ free(into->level_names);
+ into->level_names= NULL;
+ }
+ *into= *from;
+ if ((from->map)&&(into->map_count>0)) {
+ into->map= calloc(into->map_count, sizeof(XkbKTMapEntryRec));
+ if (!into->map)
+ return BadAlloc;
+ memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec));
+ }
+ if ((from->preserve)&&(into->map_count>0)) {
+ into->preserve= calloc(into->map_count, sizeof(XkbModsRec));
+ if (!into->preserve)
+ return BadAlloc;
+ memcpy(into->preserve,from->preserve,
+ into->map_count*sizeof(XkbModsRec));
+ }
+ if ((from->level_names)&&(into->num_levels>0)) {
+ into->level_names= calloc(into->num_levels, sizeof(Atom));
+ if (!into->level_names)
+ return BadAlloc;
+ memcpy(into->level_names,from->level_names,
+ into->num_levels*sizeof(Atom));
+ }
+ return Success;
+}
+
+Status
+XkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types)
+{
+register int i,rtrn;
+
+ if ((!from)||(!into)||(num_types<0))
+ return BadMatch;
+ for (i=0;i<num_types;i++) {
+ if ((rtrn= XkbCopyKeyType(from++,into++))!=Success)
+ return rtrn;
+ }
+ return Success;
+}
+
+Status
+XkbResizeKeyType( XkbDescPtr xkb,
+ int type_ndx,
+ int map_count,
+ Bool want_preserve,
+ int new_num_lvls)
+{
+XkbKeyTypePtr type;
+KeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys;
+
+ if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)||
+ (new_num_lvls<1))
+ return BadValue;
+ switch (type_ndx) {
+ case XkbOneLevelIndex:
+ if (new_num_lvls!=1)
+ return BadMatch;
+ break;
+ case XkbTwoLevelIndex:
+ case XkbAlphabeticIndex:
+ case XkbKeypadIndex:
+ if (new_num_lvls!=2)
+ return BadMatch;
+ break;
+ }
+ type= &xkb->map->types[type_ndx];
+ if (map_count==0) {
+ if (type->map!=NULL)
+ free(type->map);
+ type->map= NULL;
+ if (type->preserve!=NULL)
+ free(type->preserve);
+ type->preserve= NULL;
+ type->map_count= 0;
+ }
+ else {
+ XkbKTMapEntryRec *prev_map = type->map;
+
+ if ((map_count>type->map_count)||(type->map==NULL))
+ type->map = realloc(type->map,map_count * sizeof(XkbKTMapEntryRec));
+ if (!type->map) {
+ if (prev_map)
+ free(prev_map);
+ return BadAlloc;
+ }
+ if (want_preserve) {
+ XkbModsRec *prev_preserve = type->preserve;
+
+ if ((map_count>type->map_count)||(type->preserve==NULL)) {
+ type->preserve = realloc(type->preserve,
+ map_count * sizeof(XkbModsRec));
+ }
+ if (!type->preserve) {
+ if (prev_preserve)
+ free(prev_preserve);
+ return BadAlloc;
+ }
+ }
+ else if (type->preserve!=NULL) {
+ free(type->preserve);
+ type->preserve= NULL;
+ }
+ type->map_count= map_count;
+ }
+
+ if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) {
+ Atom * prev_level_names = type->level_names;
+
+ type->level_names = realloc(type->level_names,
+ new_num_lvls * sizeof(Atom));
+ if (!type->level_names) {
+ if (prev_level_names)
+ free(prev_level_names);
+ return BadAlloc;
+ }
+ }
+ /*
+ * Here's the theory:
+ * If the width of the type changed, we might have to resize the symbol
+ * maps for any keys that use the type for one or more groups. This is
+ * expensive, so we'll try to cull out any keys that are obviously okay:
+ * In any case:
+ * - keys that have a group width <= the old width are okay (because
+ * they could not possibly have been associated with the old type)
+ * If the key type increased in size:
+ * - keys that already have a group width >= to the new width are okay
+ * + keys that have a group width >= the old width but < the new width
+ * might have to be enlarged.
+ * If the key type decreased in size:
+ * - keys that have a group width > the old width don't have to be
+ * resized (because they must have some other wider type associated
+ * with some group).
+ * + keys that have a group width == the old width might have to be
+ * shrunk.
+ * The possibilities marked with '+' require us to examine the key types
+ * associated with each group for the key.
+ */
+ bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode));
+ nMatchingKeys= 0;
+ if (new_num_lvls>type->num_levels) {
+ int nTotal;
+ KeySym * newSyms;
+ int width,match,nResize;
+ register int i,g,nSyms;
+
+ nResize= 0;
+ for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ width= XkbKeyGroupsWidth(xkb,i);
+ if (width<type->num_levels)
+ continue;
+ for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
+ if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
+ matchingKeys[nMatchingKeys++]= i;
+ match= 1;
+ }
+ }
+ if ((!match)||(width>=new_num_lvls))
+ nTotal+= XkbKeyNumSyms(xkb,i);
+ else {
+ nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
+ nResize++;
+ }
+ }
+ if (nResize>0) {
+ int nextMatch;
+ xkb->map->size_syms= (nTotal*15)/10;
+ newSyms = calloc(xkb->map->size_syms, sizeof(KeySym));
+ if (newSyms==NULL)
+ return BadAlloc;
+ nextMatch= 0;
+ nSyms= 1;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (matchingKeys[nextMatch]==i) {
+ KeySym *pOld;
+ nextMatch++;
+ width= XkbKeyGroupsWidth(xkb,i);
+ pOld= XkbKeySymsPtr(xkb,i);
+ for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) {
+ memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g],
+ width*sizeof(KeySym));
+ }
+ xkb->map->key_sym_map[i].offset= nSyms;
+ nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
+ }
+ else {
+ memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),
+ XkbKeyNumSyms(xkb,i)*sizeof(KeySym));
+ xkb->map->key_sym_map[i].offset= nSyms;
+ nSyms+= XkbKeyNumSyms(xkb,i);
+ }
+ }
+ type->num_levels= new_num_lvls;
+ free(xkb->map->syms);
+ xkb->map->syms= newSyms;
+ xkb->map->num_syms= nSyms;
+ return Success;
+ }
+ }
+ else if (new_num_lvls<type->num_levels) {
+ int width,match;
+ register int g,i;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ width= XkbKeyGroupsWidth(xkb,i);
+ if (width<type->num_levels)
+ continue;
+ for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
+ if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
+ matchingKeys[nMatchingKeys++]= i;
+ match= 1;
+ }
+ }
+ }
+ }
+ if (nMatchingKeys>0) {
+ int key,firstClear;
+ register int i,g;
+ if (new_num_lvls>type->num_levels)
+ firstClear= type->num_levels;
+ else firstClear= new_num_lvls;
+ for (i=0;i<nMatchingKeys;i++) {
+ KeySym * pSyms;
+ int width,nClear;
+
+ key= matchingKeys[i];
+ width= XkbKeyGroupsWidth(xkb,key);
+ nClear= width-firstClear;
+ pSyms= XkbKeySymsPtr(xkb,key);
+ for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) {
+ if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) {
+ if (nClear>0)
+ bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym));
+ }
+ }
+ }
+ }
+ type->num_levels= new_num_lvls;
+ return Success;
+}
+
+KeySym *
+XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed)
+{
+register int i,nSyms,nKeySyms;
+unsigned nOldSyms;
+KeySym *newSyms;
+
+ if (needed==0) {
+ xkb->map->key_sym_map[key].offset= 0;
+ return xkb->map->syms;
+ }
+ nOldSyms= XkbKeyNumSyms(xkb,key);
+ if (nOldSyms>=(unsigned)needed) {
+ return XkbKeySymsPtr(xkb,key);
+ }
+ if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) {
+ if (nOldSyms>0) {
+ memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key),
+ nOldSyms*sizeof(KeySym));
+ }
+ if ((needed-nOldSyms)>0) {
+ bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)],
+ (needed-nOldSyms)*sizeof(KeySym));
+ }
+ xkb->map->key_sym_map[key].offset = xkb->map->num_syms;
+ xkb->map->num_syms+= needed;
+ return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
+ }
+ xkb->map->size_syms+= (needed>32?needed:32);
+ newSyms = calloc(xkb->map->size_syms, sizeof(KeySym));
+ if (newSyms==NULL)
+ return NULL;
+ newSyms[0]= NoSymbol;
+ nSyms = 1;
+ for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
+ int nCopy;
+
+ nCopy= nKeySyms= XkbKeyNumSyms(xkb,i);
+ if ((nKeySyms==0)&&(i!=key))
+ continue;
+ if (i==key)
+ nKeySyms= needed;
+ if (nCopy!=0)
+ memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym));
+ if (nKeySyms>nCopy)
+ bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym));
+ xkb->map->key_sym_map[i].offset = nSyms;
+ nSyms+= nKeySyms;
+ }
+ free(xkb->map->syms);
+ xkb->map->syms = newSyms;
+ xkb->map->num_syms = nSyms;
+ return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
+}
+
+static unsigned
+_ExtendRange( unsigned int old_flags,
+ unsigned int flag,
+ KeyCode newKC,
+ KeyCode * old_min,
+ unsigned char * old_num)
+{
+ if ((old_flags&flag)==0) {
+ old_flags|= flag;
+ *old_min= newKC;
+ *old_num= 1;
+ }
+ else {
+ int last= (*old_min)+(*old_num)-1;
+ if (newKC<*old_min) {
+ *old_min= newKC;
+ *old_num= (last-newKC)+1;
+ }
+ else if (newKC>last) {
+ *old_num= (newKC-(*old_min))+1;
+ }
+ }
+ return old_flags;
+}
+
+Status
+XkbChangeKeycodeRange( XkbDescPtr xkb,
+ int minKC,
+ int maxKC,
+ XkbChangesPtr changes)
+{
+int tmp;
+
+ if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode))
+ return BadValue;
+ if (minKC>maxKC)
+ return BadMatch;
+ if (minKC<xkb->min_key_code) {
+ if (changes)
+ changes->map.min_key_code= minKC;
+ tmp= xkb->min_key_code-minKC;
+ if (xkb->map) {
+ if (xkb->map->key_sym_map) {
+ bzero((char *)&xkb->map->key_sym_map[minKC],
+ tmp*sizeof(XkbSymMapRec));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeySymsMask,minKC,
+ &changes->map.first_key_sym,
+ &changes->map.num_key_syms);
+ }
+ }
+ if (xkb->map->modmap) {
+ bzero((char *)&xkb->map->modmap[minKC],tmp);
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbModifierMapMask,minKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_modmap_keys);
+ }
+ }
+ }
+ if (xkb->server) {
+ if (xkb->server->behaviors) {
+ bzero((char *)&xkb->server->behaviors[minKC],
+ tmp*sizeof(XkbBehavior));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyBehaviorsMask,minKC,
+ &changes->map.first_key_behavior,
+ &changes->map.num_key_behaviors);
+ }
+ }
+ if (xkb->server->key_acts) {
+ bzero((char *)&xkb->server->key_acts[minKC],
+ tmp*sizeof(unsigned short));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyActionsMask,minKC,
+ &changes->map.first_key_act,
+ &changes->map.num_key_acts);
+ }
+ }
+ if (xkb->server->vmodmap) {
+ bzero((char *)&xkb->server->vmodmap[minKC],
+ tmp*sizeof(unsigned short));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbVirtualModMapMask,minKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_vmodmap_keys);
+ }
+ }
+ }
+ if ((xkb->names)&&(xkb->names->keys)) {
+ bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec));
+ if (changes) {
+ changes->names.changed= _ExtendRange(changes->names.changed,
+ XkbKeyNamesMask,minKC,
+ &changes->names.first_key,
+ &changes->names.num_keys);
+ }
+ }
+ xkb->min_key_code= minKC;
+ }
+ if (maxKC>xkb->max_key_code) {
+ if (changes)
+ changes->map.max_key_code= maxKC;
+ tmp= maxKC-xkb->max_key_code;
+ if (xkb->map) {
+ if (xkb->map->key_sym_map) {
+ XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map;
+
+ xkb->map->key_sym_map = realloc(xkb->map->key_sym_map,
+ (maxKC+1) * sizeof(XkbSymMapRec));
+ if (!xkb->map->key_sym_map) {
+ free(prev_key_sym_map);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code],
+ tmp*sizeof(XkbSymMapRec));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeySymsMask,maxKC,
+ &changes->map.first_key_sym,
+ &changes->map.num_key_syms);
+ }
+ }
+ if (xkb->map->modmap) {
+ unsigned char *prev_modmap = xkb->map->modmap;
+
+ xkb->map->modmap = realloc(xkb->map->modmap,
+ (maxKC+1) * sizeof(unsigned char));
+ if (!xkb->map->modmap) {
+ free(prev_modmap);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp);
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbModifierMapMask,maxKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_modmap_keys);
+ }
+ }
+ }
+ if (xkb->server) {
+ if (xkb->server->behaviors) {
+ XkbBehavior *prev_behaviors = xkb->server->behaviors;
+
+ xkb->server->behaviors = realloc(xkb->server->behaviors,
+ (maxKC+1) * sizeof(XkbBehavior));
+ if (!xkb->server->behaviors) {
+ free(prev_behaviors);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->server->behaviors[xkb->max_key_code],
+ tmp*sizeof(XkbBehavior));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyBehaviorsMask,maxKC,
+ &changes->map.first_key_behavior,
+ &changes->map.num_key_behaviors);
+ }
+ }
+ if (xkb->server->key_acts) {
+ unsigned short *prev_key_acts = xkb->server->key_acts;
+
+ xkb->server->key_acts= realloc(xkb->server->key_acts,
+ (maxKC+1) * sizeof(unsigned short));
+ if (!xkb->server->key_acts) {
+ free(prev_key_acts);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->server->key_acts[xkb->max_key_code],
+ tmp*sizeof(unsigned short));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyActionsMask,maxKC,
+ &changes->map.first_key_act,
+ &changes->map.num_key_acts);
+ }
+ }
+ if (xkb->server->vmodmap) {
+ unsigned short *prev_vmodmap = xkb->server->vmodmap;
+
+ xkb->server->vmodmap= realloc(xkb->server->vmodmap,
+ (maxKC+1) * sizeof(unsigned short));
+ if (!xkb->server->vmodmap) {
+ free(prev_vmodmap);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->server->vmodmap[xkb->max_key_code],
+ tmp*sizeof(unsigned short));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbVirtualModMapMask,maxKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_vmodmap_keys);
+ }
+ }
+ }
+ if ((xkb->names)&&(xkb->names->keys)) {
+ XkbKeyNameRec *prev_keys = xkb->names->keys;
+
+ xkb->names->keys = realloc(xkb->names->keys,
+ (maxKC+1) * sizeof(XkbKeyNameRec));
+ if (!xkb->names->keys) {
+ free(prev_keys);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->names->keys[xkb->max_key_code],
+ tmp*sizeof(XkbKeyNameRec));
+ if (changes) {
+ changes->names.changed= _ExtendRange(changes->names.changed,
+ XkbKeyNamesMask,maxKC,
+ &changes->names.first_key,
+ &changes->names.num_keys);
+ }
+ }
+ xkb->max_key_code= maxKC;
+ }
+ return Success;
+}
+
+XkbAction *
+XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed)
+{
+register int i,nActs;
+XkbAction *newActs;
+
+ if (needed==0) {
+ xkb->server->key_acts[key]= 0;
+ return NULL;
+ }
+ if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed))
+ return XkbKeyActionsPtr(xkb,key);
+ if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) {
+ xkb->server->key_acts[key]= xkb->server->num_acts;
+ xkb->server->num_acts+= needed;
+ return &xkb->server->acts[xkb->server->key_acts[key]];
+ }
+ xkb->server->size_acts= xkb->server->num_acts+needed+8;
+ newActs = calloc(xkb->server->size_acts, sizeof(XkbAction));
+ if (newActs==NULL)
+ return NULL;
+ newActs[0].type = XkbSA_NoAction;
+ nActs = 1;
+ for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
+ int nKeyActs,nCopy;
+
+ if ((xkb->server->key_acts[i]==0)&&(i!=key))
+ continue;
+
+ nCopy= nKeyActs= XkbKeyNumActions(xkb,i);
+ if (i==key) {
+ nKeyActs= needed;
+ if (needed<nCopy)
+ nCopy= needed;
+ }
+
+ if (nCopy>0)
+ memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i),
+ nCopy*sizeof(XkbAction));
+ if (nCopy<nKeyActs)
+ bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction));
+ xkb->server->key_acts[i]= nActs;
+ nActs+= nKeyActs;
+ }
+ free(xkb->server->acts);
+ xkb->server->acts = newActs;
+ xkb->server->num_acts= nActs;
+ return &xkb->server->acts[xkb->server->key_acts[key]];
+}
+
+void
+XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
+{
+XkbClientMapPtr map;
+
+ if ((xkb==NULL)||(xkb->map==NULL))
+ return;
+ if (freeMap)
+ what= XkbAllClientInfoMask;
+ map= xkb->map;
+ if (what&XkbKeyTypesMask) {
+ if (map->types!=NULL) {
+ if (map->num_types>0) {
+ register int i;
+ XkbKeyTypePtr type;
+ for (i=0,type=map->types;i<map->num_types;i++,type++) {
+ if (type->map!=NULL) {
+ free(type->map);
+ type->map= NULL;
+ }
+ if (type->preserve!=NULL) {
+ free(type->preserve);
+ type->preserve= NULL;
+ }
+ type->map_count= 0;
+ if (type->level_names!=NULL) {
+ free(type->level_names);
+ type->level_names= NULL;
+ }
+ }
+ }
+ free(map->types);
+ map->num_types= map->size_types= 0;
+ map->types= NULL;
+ }
+ }
+ if (what&XkbKeySymsMask) {
+ if (map->key_sym_map!=NULL) {
+ free(map->key_sym_map);
+ map->key_sym_map= NULL;
+ }
+ if (map->syms!=NULL) {
+ free(map->syms);
+ map->size_syms= map->num_syms= 0;
+ map->syms= NULL;
+ }
+ }
+ if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) {
+ free(map->modmap);
+ map->modmap= NULL;
+ }
+ if (freeMap) {
+ free(xkb->map);
+ xkb->map= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
+{
+XkbServerMapPtr map;
+
+ if ((xkb==NULL)||(xkb->server==NULL))
+ return;
+ if (freeMap)
+ what= XkbAllServerInfoMask;
+ map= xkb->server;
+ if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) {
+ free(map->explicit);
+ map->explicit= NULL;
+ }
+ if (what&XkbKeyActionsMask) {
+ if (map->key_acts!=NULL) {
+ free(map->key_acts);
+ map->key_acts= NULL;
+ }
+ if (map->acts!=NULL) {
+ free(map->acts);
+ map->num_acts= map->size_acts= 0;
+ map->acts= NULL;
+ }
+ }
+ if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) {
+ free(map->behaviors);
+ map->behaviors= NULL;
+ }
+ if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) {
+ free(map->vmodmap);
+ map->vmodmap= NULL;
+ }
+
+ if (freeMap) {
+ free(xkb->server);
+ xkb->server= NULL;
+ }
+ return;
+}
diff --git a/xorg-server/xkb/XKBMisc.c b/xorg-server/xkb/XKBMisc.c
index 2bb4a2452..758638f4b 100644
--- a/xorg-server/xkb/XKBMisc.c
+++ b/xorg-server/xkb/XKBMisc.c
@@ -1,839 +1,839 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#elif defined(HAVE_CONFIG_H)
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-#include <X11/keysym.h>
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-
-/***====================================================================***/
-
-#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
-#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
-
-int
-XkbKeyTypesForCoreSymbols( XkbDescPtr xkb,
- int map_width,
- KeySym * core_syms,
- unsigned int protected,
- int * types_inout,
- KeySym * xkb_syms_rtrn)
-{
-register int i;
-unsigned int empty;
-int nSyms[XkbNumKbdGroups];
-int nGroups,tmp,groupsWidth;
-BOOL replicated = FALSE;
-
- /* Section 12.2 of the protocol describes this process in more detail */
- /* Step 1: find the # of symbols in the core mapping per group */
- groupsWidth= 2;
- for (i=0;i<XkbNumKbdGroups;i++) {
- if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) {
- nSyms[i]= xkb->map->types[types_inout[i]].num_levels;
- if (nSyms[i]>groupsWidth)
- groupsWidth= nSyms[i];
- }
- else {
- types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */
- nSyms[i]= 2;
- }
- }
- if (nSyms[XkbGroup1Index]<2)
- nSyms[XkbGroup1Index]= 2;
- if (nSyms[XkbGroup2Index]<2)
- nSyms[XkbGroup2Index]= 2;
- /* Step 2: Copy the symbols from the core ordering to XKB ordering */
- /* symbols in the core are in the order: */
- /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0);
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1);
- for (i=2;i<nSyms[XkbGroup1Index];i++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i);
- }
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2);
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3);
- tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */
- for (i=2;i<nSyms[XkbGroup2Index];i++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i);
- }
-
- /* Special case: if only the first group is explicit, and the symbols
- * replicate across all groups, then we have a Section 12.4 replication */
- if ((protected & ~XkbExplicitKeyType1Mask) == 0)
- {
- int j, width = nSyms[XkbGroup1Index];
-
- replicated = TRUE;
-
- /* Check ABAB in ABABCDECDEABCDE */
- if ((width > 0 && CORE_SYM(0) != CORE_SYM(2)) ||
- (width > 1 && CORE_SYM(1) != CORE_SYM(3)))
- replicated = FALSE;
-
- /* Check CDECDE in ABABCDECDEABCDE */
- for (i = 2; i < width && replicated; i++)
- {
- if (CORE_SYM(2 + i) != CORE_SYM(i + width))
- replicated = FALSE;
- }
-
- /* Check ABCDE in ABABCDECDEABCDE */
- for (j = 2; replicated &&
- j < XkbNumKbdGroups &&
- map_width >= width * (j + 1); j++)
- {
- for (i = 0; i < width && replicated; i++)
- {
- if (CORE_SYM(((i < 2) ? i : 2 + i)) != CORE_SYM(i + width * j))
- replicated = FALSE;
- }
- }
- }
-
- if (replicated)
- {
- nSyms[XkbGroup2Index]= 0;
- nSyms[XkbGroup3Index]= 0;
- nSyms[XkbGroup4Index]= 0;
- nGroups= 1;
- } else
- {
- tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index];
- if ((tmp>=map_width)&&
- ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) {
- nSyms[XkbGroup3Index]= 0;
- nSyms[XkbGroup4Index]= 0;
- nGroups= 2;
- } else
- {
- nGroups= 3;
- for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp);
- }
- if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) {
- nGroups= 4;
- for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp);
- }
- }
- else {
- nSyms[XkbGroup4Index]= 0;
- }
- }
- }
- /* steps 3&4: alphanumeric expansion, assign canonical types */
- empty= 0;
- for (i=0;i<nGroups;i++) {
- KeySym *syms;
- syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
- if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) {
- KeySym upper,lower;
- XkbConvertCase(syms[0],&lower,&upper);
- if (upper!=lower) {
- xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower;
- xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper;
- if ((protected&(1<<i))==0)
- types_inout[i]= XkbAlphabeticIndex;
- }
- else if ((protected&(1<<i))==0) {
- types_inout[i]= XkbOneLevelIndex;
- /* nSyms[i]= 1;*/
- }
- }
- if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) {
- if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1]))
- types_inout[i]= XkbKeypadIndex;
- else {
- KeySym upper,lower;
- XkbConvertCase(syms[0],&lower,&upper);
- if ((syms[0]==lower)&&(syms[1]==upper))
- types_inout[i]= XkbAlphabeticIndex;
- }
- }
- if (syms[0]==NoSymbol) {
- register int n;
- Bool found;
- for (n=1,found=FALSE;(!found)&&(n<nSyms[i]);n++) {
- found= (syms[n]!=NoSymbol);
- }
- if (!found)
- empty|= (1<<i);
- }
- }
- /* step 5: squoosh out empty groups */
- if (empty) {
- for (i=nGroups-1;i>=0;i--) {
- if (((empty&(1<<i))==0)||(protected&(1<<i)))
- break;
- nGroups--;
- }
- }
- if (nGroups<1)
- return 0;
-
- /* step 6: replicate group 1 into group two, if necessary */
- if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) {
- if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) {
- nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index];
- types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index];
- memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn,
- 2*sizeof(KeySym));
- }
- else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) {
- memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]],
- (char *)xkb_syms_rtrn,
- nSyms[XkbGroup1Index]*sizeof(KeySym));
- }
- }
-
- /* step 7: check for all groups identical or all width 1
- *
- * Special feature: if group 1 has an explicit type and all other groups
- * have canonical types with same symbols, we assume it's info lost from
- * the core replication.
- */
- if (nGroups>1) {
- Bool sameType,allOneLevel, canonical = TRUE;
- allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1);
- for (i=1,sameType=TRUE;(allOneLevel||sameType)&&(i<nGroups);i++) {
- sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index]));
- if (allOneLevel)
- allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
- if (types_inout[i] > XkbLastRequiredType)
- canonical = FALSE;
- }
- if (((sameType) || canonical)&&
- (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
- register int s;
- Bool identical;
- for (i=1,identical=TRUE;identical&&(i<nGroups);i++) {
- KeySym *syms;
- if (nSyms[i] != nSyms[XkbGroup1Index])
- identical = FALSE;
- syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
- for (s=0;identical&&(s<nSyms[i]);s++) {
- if (syms[s]!=xkb_syms_rtrn[s])
- identical= FALSE;
- }
- }
- if (identical)
- nGroups= 1;
- }
- if (allOneLevel && (nGroups>1)) {
- KeySym *syms;
- syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]];
- nSyms[XkbGroup1Index]= 1;
- for (i=1;i<nGroups;i++) {
- xkb_syms_rtrn[i]= syms[0];
- syms+= nSyms[i];
- nSyms[i]= 1;
- }
- }
- }
- return nGroups;
-}
-
-static XkbSymInterpretPtr
-_XkbFindMatchingInterp( XkbDescPtr xkb,
- KeySym sym,
- unsigned int real_mods,
- unsigned int level)
-{
-register unsigned i;
-XkbSymInterpretPtr interp,rtrn;
-CARD8 mods;
-
- rtrn= NULL;
- interp= xkb->compat->sym_interpret;
- for (i=0;i<xkb->compat->num_si;i++,interp++) {
- if ((interp->sym==NoSymbol)||(sym==interp->sym)) {
- int match;
- if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0))
- mods= real_mods;
- else mods= 0;
- switch (interp->match&XkbSI_OpMask) {
- case XkbSI_NoneOf:
- match= ((interp->mods&mods)==0);
- break;
- case XkbSI_AnyOfOrNone:
- match= ((mods==0)||((interp->mods&mods)!=0));
- break;
- case XkbSI_AnyOf:
- match= ((interp->mods&mods)!=0);
- break;
- case XkbSI_AllOf:
- match= ((interp->mods&mods)==interp->mods);
- break;
- case XkbSI_Exactly:
- match= (interp->mods==mods);
- break;
- default:
- match= 0;
- break;
- }
- if (match) {
- if (interp->sym!=NoSymbol) {
- return interp;
- }
- else if (rtrn==NULL) {
- rtrn= interp;
- }
- }
- }
- }
- return rtrn;
-}
-
-static void
-_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey)
-{
-KeyCode last;
-
- last= (*pFirst)+(*pNum);
- if (newKey<*pFirst) {
- *pFirst= newKey;
- *pNum= (last-newKey)+1;
- }
- else if (newKey>last) {
- *pNum= (last-*pFirst)+1;
- }
- return;
-}
-
-static void
-_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
-{
-unsigned tmp;
-
- switch (act->type) {
- case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
- if (act->mods.flags&XkbSA_UseModMapMods)
- act->mods.real_mods= act->mods.mask= mods;
- if ((tmp= XkbModActionVMods(&act->mods))!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->mods.mask|= tmp;
- }
- break;
- case XkbSA_ISOLock:
- if (act->iso.flags&XkbSA_UseModMapMods)
- act->iso.real_mods= act->iso.mask= mods;
- if ((tmp= XkbModActionVMods(&act->iso))!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->iso.mask|= tmp;
- }
- break;
- }
- return;
-}
-
-#define IBUF_SIZE 8
-
-Bool
-XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes)
-{
-KeySym * syms;
-unsigned char explicit,mods;
-XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE];
-int n,nSyms,found;
-unsigned changed,tmp;
-
- if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)||
- (!xkb->compat)||(!xkb->compat->sym_interpret)||
- (key<xkb->min_key_code)||(key>xkb->max_key_code)) {
- return FALSE;
- }
- if (((!xkb->server)||(!xkb->server->key_acts))&&
- (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) {
- return FALSE;
- }
- changed= 0; /* keeps track of what has changed in _this_ call */
- explicit= xkb->server->explicit[key];
- if (explicit&XkbExplicitInterpretMask) /* nothing to do */
- return TRUE;
- mods= (xkb->map->modmap?xkb->map->modmap[key]:0);
- nSyms= XkbKeyNumSyms(xkb,key);
- syms= XkbKeySymsPtr(xkb,key);
- if (nSyms>IBUF_SIZE) {
- interps= xcalloc(nSyms, sizeof(XkbSymInterpretPtr));
- if (interps==NULL) {
- interps= ibuf;
- nSyms= IBUF_SIZE;
- }
- }
- else {
- interps= ibuf;
- }
- found= 0;
- for (n=0;n<nSyms;n++) {
- unsigned level= (n%XkbKeyGroupsWidth(xkb,key));
- interps[n]= NULL;
- if (syms[n]!=NoSymbol) {
- interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level);
- if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction)
- found++;
- else interps[n]= NULL;
- }
- }
- /* 1/28/96 (ef) -- XXX! WORKING HERE */
- if (!found) {
- if (xkb->server->key_acts[key]!=0) {
- xkb->server->key_acts[key]= 0;
- changed|= XkbKeyActionsMask;
- }
- }
- else {
- XkbAction *pActs;
- unsigned int new_vmodmask;
- changed|= XkbKeyActionsMask;
- pActs= XkbResizeKeyActions(xkb,key,nSyms);
- if (!pActs) {
- if (nSyms > IBUF_SIZE)
- xfree(interps);
- return FALSE;
- }
- new_vmodmask= 0;
- for (n=0;n<nSyms;n++) {
- if (interps[n]) {
- unsigned effMods;
-
- pActs[n]= *((XkbAction *)&interps[n]->act);
- if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) {
- effMods= mods;
- if (interps[n]->virtual_mod!=XkbNoModifier)
- new_vmodmask|= (1<<interps[n]->virtual_mod);
- }
- else effMods= 0;
- _XkbSetActionKeyMods(xkb,&pActs[n],effMods);
- }
- else pActs[n].type= XkbSA_NoAction;
- }
- if (((explicit&XkbExplicitVModMapMask)==0)&&
- (xkb->server->vmodmap[key]!=new_vmodmask)) {
- changed|= XkbVirtualModMapMask;
- xkb->server->vmodmap[key]= new_vmodmask;
- }
- if (interps[0]) {
- if ((interps[0]->flags&XkbSI_LockingKey)&&
- ((explicit&XkbExplicitBehaviorMask)==0)) {
- xkb->server->behaviors[key].type= XkbKB_Lock;
- changed|= XkbKeyBehaviorsMask;
- }
- if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
- CARD8 old;
- old= xkb->ctrls->per_key_repeat[key/8];
- if (interps[0]->flags&XkbSI_AutoRepeat)
- xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
- else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8));
- if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
- changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
- }
- }
- }
- if ((!found)||(interps[0]==NULL)) {
- if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
- CARD8 old;
- old= xkb->ctrls->per_key_repeat[key/8];
- xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
- if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
- changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
- }
- if (((explicit&XkbExplicitBehaviorMask)==0)&&
- (xkb->server->behaviors[key].type==XkbKB_Lock)) {
- xkb->server->behaviors[key].type= XkbKB_Default;
- changed|= XkbKeyBehaviorsMask;
- }
- }
- if (changes) {
- XkbMapChangesPtr mc;
- mc= &changes->map;
- tmp= (changed&mc->changed);
- if (tmp&XkbKeyActionsMask)
- _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key);
- else if (changed&XkbKeyActionsMask) {
- mc->changed|= XkbKeyActionsMask;
- mc->first_key_act= key;
- mc->num_key_acts= 1;
- }
- if (tmp&XkbKeyBehaviorsMask) {
- _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors,
- key);
- }
- else if (changed&XkbKeyBehaviorsMask) {
- mc->changed|= XkbKeyBehaviorsMask;
- mc->first_key_behavior= key;
- mc->num_key_behaviors= 1;
- }
- if (tmp&XkbVirtualModMapMask)
- _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key);
- else if (changed&XkbVirtualModMapMask) {
- mc->changed|= XkbVirtualModMapMask;
- mc->first_vmodmap_key= key;
- mc->num_vmodmap_keys= 1;
- }
- mc->changed|= changed;
- }
- if (interps!=ibuf)
- xfree(interps);
- return TRUE;
-}
-
-Status
-XkbChangeTypesOfKey( XkbDescPtr xkb,
- int key,
- int nGroups,
- unsigned groups,
- int * newTypesIn,
- XkbMapChangesPtr changes)
-{
-XkbKeyTypePtr pOldType,pNewType;
-register int i;
-int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
-
- if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
- (!xkb->map->types)||(!newTypesIn)||((groups&XkbAllGroupsMask)==0)||
- (nGroups>XkbNumKbdGroups)) {
- return BadMatch;
- }
- if (nGroups==0) {
- for (i=0;i<XkbNumKbdGroups;i++) {
- xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex;
- }
- i= xkb->map->key_sym_map[key].group_info;
- i= XkbSetNumGroups(i,0);
- xkb->map->key_sym_map[key].group_info= i;
- XkbResizeKeySyms(xkb,key,0);
- return Success;
- }
-
- nOldGroups= XkbKeyNumGroups(xkb,key);
- oldWidth= XkbKeyGroupsWidth(xkb,key);
- for (width=i=0;i<nGroups;i++) {
- if (groups&(1<<i))
- newTypes[i]= newTypesIn[i];
- else if (i<nOldGroups)
- newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i);
- else if (nOldGroups>0)
- newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
- else newTypes[i]= XkbTwoLevelIndex;
- if (newTypes[i]>xkb->map->num_types)
- return BadMatch;
- pNewType= &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels>width)
- width= pNewType->num_levels;
- }
- if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups))
- xkb->ctrls->num_groups= nGroups;
- if ((width!=oldWidth)||(nGroups!=nOldGroups)) {
- KeySym oldSyms[XkbMaxSymsPerKey],*pSyms;
- int nCopy;
-
- if (nOldGroups==0) {
- pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
- if (pSyms!=NULL) {
- i= xkb->map->key_sym_map[key].group_info;
- i= XkbSetNumGroups(i,nGroups);
- xkb->map->key_sym_map[key].group_info= i;
- xkb->map->key_sym_map[key].width= width;
- for (i=0;i<nGroups;i++) {
- xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
- }
- return Success;
- }
- return BadAlloc;
- }
- pSyms= XkbKeySymsPtr(xkb,key);
- memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
- pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
- if (pSyms==NULL)
- return BadAlloc;
- bzero(pSyms,width*nGroups*sizeof(KeySym));
- for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
- pOldType= XkbKeyKeyType(xkb,key,i);
- pNewType= &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels>pOldType->num_levels)
- nCopy= pOldType->num_levels;
- else nCopy= pNewType->num_levels;
- memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym));
- }
- if (XkbKeyHasActions(xkb,key)) {
- XkbAction oldActs[XkbMaxSymsPerKey],*pActs;
- pActs= XkbKeyActionsPtr(xkb,key);
- memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction));
- pActs= XkbResizeKeyActions(xkb,key,width*nGroups);
- if (pActs==NULL)
- return BadAlloc;
- bzero(pActs,width*nGroups*sizeof(XkbAction));
- for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
- pOldType= XkbKeyKeyType(xkb,key,i);
- pNewType= &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels>pOldType->num_levels)
- nCopy= pOldType->num_levels;
- else nCopy= pNewType->num_levels;
- memcpy(&pActs[i*width],&oldActs[i*oldWidth],
- nCopy*sizeof(XkbAction));
- }
- }
- i= xkb->map->key_sym_map[key].group_info;
- i= XkbSetNumGroups(i,nGroups);
- xkb->map->key_sym_map[key].group_info= i;
- xkb->map->key_sym_map[key].width= width;
- }
- width= 0;
- for (i=0;i<nGroups;i++) {
- xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
- if (xkb->map->types[newTypes[i]].num_levels>width)
- width= xkb->map->types[newTypes[i]].num_levels;
- }
- xkb->map->key_sym_map[key].width= width;
- if (changes!=NULL) {
- if (changes->changed&XkbKeySymsMask) {
- _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms,
- key);
- }
- else {
- changes->changed|= XkbKeySymsMask;
- changes->first_key_sym= key;
- changes->num_key_syms= 1;
- }
- }
- return Success;
-}
-
-/***====================================================================***/
-
-Bool
-XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn)
-{
-register int i,bit;
-register unsigned mask;
-
- if (xkb==NULL)
- return FALSE;
- if (virtual_mask==0) {
- *mask_rtrn= 0;
- return TRUE;
- }
- if (xkb->server==NULL)
- return FALSE;
- for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (virtual_mask&bit)
- mask|= xkb->server->vmods[i];
- }
- *mask_rtrn= mask;
- return TRUE;
-}
-
-/***====================================================================***/
-
-static Bool
-XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed)
-{
-unsigned int tmp;
-
- switch (act->type) {
- case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
- if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->mods.mask= act->mods.real_mods;
- act->mods.mask|= tmp;
- return TRUE;
- }
- break;
- case XkbSA_ISOLock:
- if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->iso.mask= act->iso.real_mods;
- act->iso.mask|= tmp;
- return TRUE;
- }
- break;
- }
- return FALSE;
-}
-
-static void
-XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb,
- XkbKeyTypePtr type,
- unsigned int changed,
- XkbChangesPtr changes)
-{
-register unsigned int i;
-unsigned int mask;
-
- XkbVirtualModsToReal(xkb,type->mods.vmods,&mask);
- type->mods.mask= type->mods.real_mods|mask;
- if ((type->map_count>0)&&(type->mods.vmods!=0)) {
- XkbKTMapEntryPtr entry;
- for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
- if (entry->mods.vmods!=0) {
- XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask);
- entry->mods.mask=entry->mods.real_mods|mask;
- /* entry is active if vmods are bound*/
- entry->active= (mask!=0);
- }
- else entry->active= 1;
- }
- }
- if (changes) {
- int type_ndx;
- type_ndx= type-xkb->map->types;
- if ((type_ndx<0)||(type_ndx>xkb->map->num_types))
- return;
- if (changes->map.changed&XkbKeyTypesMask) {
- int last;
- last= changes->map.first_type+changes->map.num_types-1;
- if (type_ndx<changes->map.first_type) {
- changes->map.first_type= type_ndx;
- changes->map.num_types= (last-type_ndx)+1;
- }
- else if (type_ndx>last) {
- changes->map.num_types= (type_ndx-changes->map.first_type)+1;
- }
- }
- else {
- changes->map.changed|= XkbKeyTypesMask;
- changes->map.first_type= type_ndx;
- changes->map.num_types= 1;
- }
- }
- return;
-}
-
-Bool
-XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes)
-{
-register int i;
-unsigned int checkState = 0;
-
- if ((!xkb) || (!xkb->map) || (changed==0))
- return FALSE;
- for (i=0;i<xkb->map->num_types;i++) {
- if (xkb->map->types[i].mods.vmods & changed)
- XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes);
- }
- if (changed&xkb->ctrls->internal.vmods) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask);
- newMask|= xkb->ctrls->internal.real_mods;
- if (xkb->ctrls->internal.mask!=newMask) {
- xkb->ctrls->internal.mask= newMask;
- if (changes) {
- changes->ctrls.changed_ctrls|= XkbInternalModsMask;
- checkState= TRUE;
- }
- }
- }
- if (changed&xkb->ctrls->ignore_lock.vmods) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask);
- newMask|= xkb->ctrls->ignore_lock.real_mods;
- if (xkb->ctrls->ignore_lock.mask!=newMask) {
- xkb->ctrls->ignore_lock.mask= newMask;
- if (changes) {
- changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask;
- checkState= TRUE;
- }
- }
- }
- if (xkb->indicators!=NULL) {
- XkbIndicatorMapPtr map;
- map= &xkb->indicators->maps[0];
- for (i=0;i<XkbNumIndicators;i++,map++) {
- if (map->mods.vmods&changed) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask);
- newMask|= map->mods.real_mods;
- if (newMask!=map->mods.mask) {
- map->mods.mask= newMask;
- if (changes) {
- changes->indicators.map_changes|= (1<<i);
- checkState= TRUE;
- }
- }
- }
- }
- }
- if (xkb->compat!=NULL) {
- XkbCompatMapPtr compat;
- compat= xkb->compat;
- for (i=0;i<XkbNumKbdGroups;i++) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask);
- newMask|= compat->groups[i].real_mods;
- if (compat->groups[i].mask!=newMask) {
- compat->groups[i].mask= newMask;
- if (changes) {
- changes->compat.changed_groups|= (1<<i);
- checkState= TRUE;
- }
- }
- }
- }
- if (xkb->map && xkb->server) {
- int highChange = 0, lowChange = -1;
- for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- if (XkbKeyHasActions(xkb,i)) {
- register XkbAction *pAct;
- register int n;
-
- pAct= XkbKeyActionsPtr(xkb,i);
- for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) {
- if ((pAct->type!=XkbSA_NoAction)&&
- XkbUpdateActionVirtualMods(xkb,pAct,changed)) {
- if (lowChange<0)
- lowChange= i;
- highChange= i;
- }
- }
- }
- }
- if (changes && (lowChange>0)) { /* something changed */
- if (changes->map.changed&XkbKeyActionsMask) {
- int last;
- if (changes->map.first_key_act<lowChange)
- lowChange= changes->map.first_key_act;
- last= changes->map.first_key_act+changes->map.num_key_acts-1;
- if (last>highChange)
- highChange= last;
- }
- changes->map.changed|= XkbKeyActionsMask;
- changes->map.first_key_act= lowChange;
- changes->map.num_key_acts= (highChange-lowChange)+1;
- }
- }
- return checkState;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <X11/keysym.h>
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+
+/***====================================================================***/
+
+#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
+#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
+
+int
+XkbKeyTypesForCoreSymbols( XkbDescPtr xkb,
+ int map_width,
+ KeySym * core_syms,
+ unsigned int protected,
+ int * types_inout,
+ KeySym * xkb_syms_rtrn)
+{
+register int i;
+unsigned int empty;
+int nSyms[XkbNumKbdGroups];
+int nGroups,tmp,groupsWidth;
+BOOL replicated = FALSE;
+
+ /* Section 12.2 of the protocol describes this process in more detail */
+ /* Step 1: find the # of symbols in the core mapping per group */
+ groupsWidth= 2;
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) {
+ nSyms[i]= xkb->map->types[types_inout[i]].num_levels;
+ if (nSyms[i]>groupsWidth)
+ groupsWidth= nSyms[i];
+ }
+ else {
+ types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */
+ nSyms[i]= 2;
+ }
+ }
+ if (nSyms[XkbGroup1Index]<2)
+ nSyms[XkbGroup1Index]= 2;
+ if (nSyms[XkbGroup2Index]<2)
+ nSyms[XkbGroup2Index]= 2;
+ /* Step 2: Copy the symbols from the core ordering to XKB ordering */
+ /* symbols in the core are in the order: */
+ /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0);
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1);
+ for (i=2;i<nSyms[XkbGroup1Index];i++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i);
+ }
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2);
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3);
+ tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */
+ for (i=2;i<nSyms[XkbGroup2Index];i++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i);
+ }
+
+ /* Special case: if only the first group is explicit, and the symbols
+ * replicate across all groups, then we have a Section 12.4 replication */
+ if ((protected & ~XkbExplicitKeyType1Mask) == 0)
+ {
+ int j, width = nSyms[XkbGroup1Index];
+
+ replicated = TRUE;
+
+ /* Check ABAB in ABABCDECDEABCDE */
+ if ((width > 0 && CORE_SYM(0) != CORE_SYM(2)) ||
+ (width > 1 && CORE_SYM(1) != CORE_SYM(3)))
+ replicated = FALSE;
+
+ /* Check CDECDE in ABABCDECDEABCDE */
+ for (i = 2; i < width && replicated; i++)
+ {
+ if (CORE_SYM(2 + i) != CORE_SYM(i + width))
+ replicated = FALSE;
+ }
+
+ /* Check ABCDE in ABABCDECDEABCDE */
+ for (j = 2; replicated &&
+ j < XkbNumKbdGroups &&
+ map_width >= width * (j + 1); j++)
+ {
+ for (i = 0; i < width && replicated; i++)
+ {
+ if (CORE_SYM(((i < 2) ? i : 2 + i)) != CORE_SYM(i + width * j))
+ replicated = FALSE;
+ }
+ }
+ }
+
+ if (replicated)
+ {
+ nSyms[XkbGroup2Index]= 0;
+ nSyms[XkbGroup3Index]= 0;
+ nSyms[XkbGroup4Index]= 0;
+ nGroups= 1;
+ } else
+ {
+ tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index];
+ if ((tmp>=map_width)&&
+ ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) {
+ nSyms[XkbGroup3Index]= 0;
+ nSyms[XkbGroup4Index]= 0;
+ nGroups= 2;
+ } else
+ {
+ nGroups= 3;
+ for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp);
+ }
+ if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) {
+ nGroups= 4;
+ for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp);
+ }
+ }
+ else {
+ nSyms[XkbGroup4Index]= 0;
+ }
+ }
+ }
+ /* steps 3&4: alphanumeric expansion, assign canonical types */
+ empty= 0;
+ for (i=0;i<nGroups;i++) {
+ KeySym *syms;
+ syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
+ if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) {
+ KeySym upper,lower;
+ XkbConvertCase(syms[0],&lower,&upper);
+ if (upper!=lower) {
+ xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower;
+ xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper;
+ if ((protected&(1<<i))==0)
+ types_inout[i]= XkbAlphabeticIndex;
+ }
+ else if ((protected&(1<<i))==0) {
+ types_inout[i]= XkbOneLevelIndex;
+ /* nSyms[i]= 1;*/
+ }
+ }
+ if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) {
+ if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1]))
+ types_inout[i]= XkbKeypadIndex;
+ else {
+ KeySym upper,lower;
+ XkbConvertCase(syms[0],&lower,&upper);
+ if ((syms[0]==lower)&&(syms[1]==upper))
+ types_inout[i]= XkbAlphabeticIndex;
+ }
+ }
+ if (syms[0]==NoSymbol) {
+ register int n;
+ Bool found;
+ for (n=1,found=FALSE;(!found)&&(n<nSyms[i]);n++) {
+ found= (syms[n]!=NoSymbol);
+ }
+ if (!found)
+ empty|= (1<<i);
+ }
+ }
+ /* step 5: squoosh out empty groups */
+ if (empty) {
+ for (i=nGroups-1;i>=0;i--) {
+ if (((empty&(1<<i))==0)||(protected&(1<<i)))
+ break;
+ nGroups--;
+ }
+ }
+ if (nGroups<1)
+ return 0;
+
+ /* step 6: replicate group 1 into group two, if necessary */
+ if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) {
+ if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) {
+ nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index];
+ types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index];
+ memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn,
+ 2*sizeof(KeySym));
+ }
+ else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) {
+ memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]],
+ (char *)xkb_syms_rtrn,
+ nSyms[XkbGroup1Index]*sizeof(KeySym));
+ }
+ }
+
+ /* step 7: check for all groups identical or all width 1
+ *
+ * Special feature: if group 1 has an explicit type and all other groups
+ * have canonical types with same symbols, we assume it's info lost from
+ * the core replication.
+ */
+ if (nGroups>1) {
+ Bool sameType,allOneLevel, canonical = TRUE;
+ allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1);
+ for (i=1,sameType=TRUE;(allOneLevel||sameType)&&(i<nGroups);i++) {
+ sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index]));
+ if (allOneLevel)
+ allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
+ if (types_inout[i] > XkbLastRequiredType)
+ canonical = FALSE;
+ }
+ if (((sameType) || canonical)&&
+ (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
+ register int s;
+ Bool identical;
+ for (i=1,identical=TRUE;identical&&(i<nGroups);i++) {
+ KeySym *syms;
+ if (nSyms[i] != nSyms[XkbGroup1Index])
+ identical = FALSE;
+ syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
+ for (s=0;identical&&(s<nSyms[i]);s++) {
+ if (syms[s]!=xkb_syms_rtrn[s])
+ identical= FALSE;
+ }
+ }
+ if (identical)
+ nGroups= 1;
+ }
+ if (allOneLevel && (nGroups>1)) {
+ KeySym *syms;
+ syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]];
+ nSyms[XkbGroup1Index]= 1;
+ for (i=1;i<nGroups;i++) {
+ xkb_syms_rtrn[i]= syms[0];
+ syms+= nSyms[i];
+ nSyms[i]= 1;
+ }
+ }
+ }
+ return nGroups;
+}
+
+static XkbSymInterpretPtr
+_XkbFindMatchingInterp( XkbDescPtr xkb,
+ KeySym sym,
+ unsigned int real_mods,
+ unsigned int level)
+{
+register unsigned i;
+XkbSymInterpretPtr interp,rtrn;
+CARD8 mods;
+
+ rtrn= NULL;
+ interp= xkb->compat->sym_interpret;
+ for (i=0;i<xkb->compat->num_si;i++,interp++) {
+ if ((interp->sym==NoSymbol)||(sym==interp->sym)) {
+ int match;
+ if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0))
+ mods= real_mods;
+ else mods= 0;
+ switch (interp->match&XkbSI_OpMask) {
+ case XkbSI_NoneOf:
+ match= ((interp->mods&mods)==0);
+ break;
+ case XkbSI_AnyOfOrNone:
+ match= ((mods==0)||((interp->mods&mods)!=0));
+ break;
+ case XkbSI_AnyOf:
+ match= ((interp->mods&mods)!=0);
+ break;
+ case XkbSI_AllOf:
+ match= ((interp->mods&mods)==interp->mods);
+ break;
+ case XkbSI_Exactly:
+ match= (interp->mods==mods);
+ break;
+ default:
+ match= 0;
+ break;
+ }
+ if (match) {
+ if (interp->sym!=NoSymbol) {
+ return interp;
+ }
+ else if (rtrn==NULL) {
+ rtrn= interp;
+ }
+ }
+ }
+ }
+ return rtrn;
+}
+
+static void
+_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey)
+{
+KeyCode last;
+
+ last= (*pFirst)+(*pNum);
+ if (newKey<*pFirst) {
+ *pFirst= newKey;
+ *pNum= (last-newKey)+1;
+ }
+ else if (newKey>last) {
+ *pNum= (last-*pFirst)+1;
+ }
+ return;
+}
+
+static void
+_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
+{
+unsigned tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (act->mods.flags&XkbSA_UseModMapMods)
+ act->mods.real_mods= act->mods.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->mods))!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->mods.mask|= tmp;
+ }
+ break;
+ case XkbSA_ISOLock:
+ if (act->iso.flags&XkbSA_UseModMapMods)
+ act->iso.real_mods= act->iso.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->iso))!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->iso.mask|= tmp;
+ }
+ break;
+ }
+ return;
+}
+
+#define IBUF_SIZE 8
+
+Bool
+XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes)
+{
+KeySym * syms;
+unsigned char explicit,mods;
+XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE];
+int n,nSyms,found;
+unsigned changed,tmp;
+
+ if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)||
+ (!xkb->compat)||(!xkb->compat->sym_interpret)||
+ (key<xkb->min_key_code)||(key>xkb->max_key_code)) {
+ return FALSE;
+ }
+ if (((!xkb->server)||(!xkb->server->key_acts))&&
+ (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) {
+ return FALSE;
+ }
+ changed= 0; /* keeps track of what has changed in _this_ call */
+ explicit= xkb->server->explicit[key];
+ if (explicit&XkbExplicitInterpretMask) /* nothing to do */
+ return TRUE;
+ mods= (xkb->map->modmap?xkb->map->modmap[key]:0);
+ nSyms= XkbKeyNumSyms(xkb,key);
+ syms= XkbKeySymsPtr(xkb,key);
+ if (nSyms>IBUF_SIZE) {
+ interps= calloc(nSyms, sizeof(XkbSymInterpretPtr));
+ if (interps==NULL) {
+ interps= ibuf;
+ nSyms= IBUF_SIZE;
+ }
+ }
+ else {
+ interps= ibuf;
+ }
+ found= 0;
+ for (n=0;n<nSyms;n++) {
+ unsigned level= (n%XkbKeyGroupsWidth(xkb,key));
+ interps[n]= NULL;
+ if (syms[n]!=NoSymbol) {
+ interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level);
+ if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction)
+ found++;
+ else interps[n]= NULL;
+ }
+ }
+ /* 1/28/96 (ef) -- XXX! WORKING HERE */
+ if (!found) {
+ if (xkb->server->key_acts[key]!=0) {
+ xkb->server->key_acts[key]= 0;
+ changed|= XkbKeyActionsMask;
+ }
+ }
+ else {
+ XkbAction *pActs;
+ unsigned int new_vmodmask;
+ changed|= XkbKeyActionsMask;
+ pActs= XkbResizeKeyActions(xkb,key,nSyms);
+ if (!pActs) {
+ if (nSyms > IBUF_SIZE)
+ free(interps);
+ return FALSE;
+ }
+ new_vmodmask= 0;
+ for (n=0;n<nSyms;n++) {
+ if (interps[n]) {
+ unsigned effMods;
+
+ pActs[n]= *((XkbAction *)&interps[n]->act);
+ if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) {
+ effMods= mods;
+ if (interps[n]->virtual_mod!=XkbNoModifier)
+ new_vmodmask|= (1<<interps[n]->virtual_mod);
+ }
+ else effMods= 0;
+ _XkbSetActionKeyMods(xkb,&pActs[n],effMods);
+ }
+ else pActs[n].type= XkbSA_NoAction;
+ }
+ if (((explicit&XkbExplicitVModMapMask)==0)&&
+ (xkb->server->vmodmap[key]!=new_vmodmask)) {
+ changed|= XkbVirtualModMapMask;
+ xkb->server->vmodmap[key]= new_vmodmask;
+ }
+ if (interps[0]) {
+ if ((interps[0]->flags&XkbSI_LockingKey)&&
+ ((explicit&XkbExplicitBehaviorMask)==0)) {
+ xkb->server->behaviors[key].type= XkbKB_Lock;
+ changed|= XkbKeyBehaviorsMask;
+ }
+ if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
+ CARD8 old;
+ old= xkb->ctrls->per_key_repeat[key/8];
+ if (interps[0]->flags&XkbSI_AutoRepeat)
+ xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
+ else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8));
+ if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
+ changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
+ }
+ }
+ }
+ if ((!found)||(interps[0]==NULL)) {
+ if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
+ CARD8 old;
+ old= xkb->ctrls->per_key_repeat[key/8];
+ xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
+ if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
+ changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
+ }
+ if (((explicit&XkbExplicitBehaviorMask)==0)&&
+ (xkb->server->behaviors[key].type==XkbKB_Lock)) {
+ xkb->server->behaviors[key].type= XkbKB_Default;
+ changed|= XkbKeyBehaviorsMask;
+ }
+ }
+ if (changes) {
+ XkbMapChangesPtr mc;
+ mc= &changes->map;
+ tmp= (changed&mc->changed);
+ if (tmp&XkbKeyActionsMask)
+ _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key);
+ else if (changed&XkbKeyActionsMask) {
+ mc->changed|= XkbKeyActionsMask;
+ mc->first_key_act= key;
+ mc->num_key_acts= 1;
+ }
+ if (tmp&XkbKeyBehaviorsMask) {
+ _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors,
+ key);
+ }
+ else if (changed&XkbKeyBehaviorsMask) {
+ mc->changed|= XkbKeyBehaviorsMask;
+ mc->first_key_behavior= key;
+ mc->num_key_behaviors= 1;
+ }
+ if (tmp&XkbVirtualModMapMask)
+ _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key);
+ else if (changed&XkbVirtualModMapMask) {
+ mc->changed|= XkbVirtualModMapMask;
+ mc->first_vmodmap_key= key;
+ mc->num_vmodmap_keys= 1;
+ }
+ mc->changed|= changed;
+ }
+ if (interps!=ibuf)
+ free(interps);
+ return TRUE;
+}
+
+Status
+XkbChangeTypesOfKey( XkbDescPtr xkb,
+ int key,
+ int nGroups,
+ unsigned groups,
+ int * newTypesIn,
+ XkbMapChangesPtr changes)
+{
+XkbKeyTypePtr pOldType,pNewType;
+register int i;
+int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
+
+ if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
+ (!xkb->map->types)||(!newTypesIn)||((groups&XkbAllGroupsMask)==0)||
+ (nGroups>XkbNumKbdGroups)) {
+ return BadMatch;
+ }
+ if (nGroups==0) {
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex;
+ }
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,0);
+ xkb->map->key_sym_map[key].group_info= i;
+ XkbResizeKeySyms(xkb,key,0);
+ return Success;
+ }
+
+ nOldGroups= XkbKeyNumGroups(xkb,key);
+ oldWidth= XkbKeyGroupsWidth(xkb,key);
+ for (width=i=0;i<nGroups;i++) {
+ if (groups&(1<<i))
+ newTypes[i]= newTypesIn[i];
+ else if (i<nOldGroups)
+ newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i);
+ else if (nOldGroups>0)
+ newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
+ else newTypes[i]= XkbTwoLevelIndex;
+ if (newTypes[i]>xkb->map->num_types)
+ return BadMatch;
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>width)
+ width= pNewType->num_levels;
+ }
+ if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups))
+ xkb->ctrls->num_groups= nGroups;
+ if ((width!=oldWidth)||(nGroups!=nOldGroups)) {
+ KeySym oldSyms[XkbMaxSymsPerKey],*pSyms;
+ int nCopy;
+
+ if (nOldGroups==0) {
+ pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
+ if (pSyms!=NULL) {
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,nGroups);
+ xkb->map->key_sym_map[key].group_info= i;
+ xkb->map->key_sym_map[key].width= width;
+ for (i=0;i<nGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
+ }
+ return Success;
+ }
+ return BadAlloc;
+ }
+ pSyms= XkbKeySymsPtr(xkb,key);
+ memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
+ pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
+ if (pSyms==NULL)
+ return BadAlloc;
+ bzero(pSyms,width*nGroups*sizeof(KeySym));
+ for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
+ pOldType= XkbKeyKeyType(xkb,key,i);
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>pOldType->num_levels)
+ nCopy= pOldType->num_levels;
+ else nCopy= pNewType->num_levels;
+ memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym));
+ }
+ if (XkbKeyHasActions(xkb,key)) {
+ XkbAction oldActs[XkbMaxSymsPerKey],*pActs;
+ pActs= XkbKeyActionsPtr(xkb,key);
+ memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction));
+ pActs= XkbResizeKeyActions(xkb,key,width*nGroups);
+ if (pActs==NULL)
+ return BadAlloc;
+ bzero(pActs,width*nGroups*sizeof(XkbAction));
+ for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
+ pOldType= XkbKeyKeyType(xkb,key,i);
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>pOldType->num_levels)
+ nCopy= pOldType->num_levels;
+ else nCopy= pNewType->num_levels;
+ memcpy(&pActs[i*width],&oldActs[i*oldWidth],
+ nCopy*sizeof(XkbAction));
+ }
+ }
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,nGroups);
+ xkb->map->key_sym_map[key].group_info= i;
+ xkb->map->key_sym_map[key].width= width;
+ }
+ width= 0;
+ for (i=0;i<nGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
+ if (xkb->map->types[newTypes[i]].num_levels>width)
+ width= xkb->map->types[newTypes[i]].num_levels;
+ }
+ xkb->map->key_sym_map[key].width= width;
+ if (changes!=NULL) {
+ if (changes->changed&XkbKeySymsMask) {
+ _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms,
+ key);
+ }
+ else {
+ changes->changed|= XkbKeySymsMask;
+ changes->first_key_sym= key;
+ changes->num_key_syms= 1;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+Bool
+XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn)
+{
+register int i,bit;
+register unsigned mask;
+
+ if (xkb==NULL)
+ return FALSE;
+ if (virtual_mask==0) {
+ *mask_rtrn= 0;
+ return TRUE;
+ }
+ if (xkb->server==NULL)
+ return FALSE;
+ for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (virtual_mask&bit)
+ mask|= xkb->server->vmods[i];
+ }
+ *mask_rtrn= mask;
+ return TRUE;
+}
+
+/***====================================================================***/
+
+static Bool
+XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed)
+{
+unsigned int tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->mods.mask= act->mods.real_mods;
+ act->mods.mask|= tmp;
+ return TRUE;
+ }
+ break;
+ case XkbSA_ISOLock:
+ if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->iso.mask= act->iso.real_mods;
+ act->iso.mask|= tmp;
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static void
+XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb,
+ XkbKeyTypePtr type,
+ unsigned int changed,
+ XkbChangesPtr changes)
+{
+register unsigned int i;
+unsigned int mask;
+
+ XkbVirtualModsToReal(xkb,type->mods.vmods,&mask);
+ type->mods.mask= type->mods.real_mods|mask;
+ if ((type->map_count>0)&&(type->mods.vmods!=0)) {
+ XkbKTMapEntryPtr entry;
+ for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
+ if (entry->mods.vmods!=0) {
+ XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask);
+ entry->mods.mask=entry->mods.real_mods|mask;
+ /* entry is active if vmods are bound*/
+ entry->active= (mask!=0);
+ }
+ else entry->active= 1;
+ }
+ }
+ if (changes) {
+ int type_ndx;
+ type_ndx= type-xkb->map->types;
+ if ((type_ndx<0)||(type_ndx>xkb->map->num_types))
+ return;
+ if (changes->map.changed&XkbKeyTypesMask) {
+ int last;
+ last= changes->map.first_type+changes->map.num_types-1;
+ if (type_ndx<changes->map.first_type) {
+ changes->map.first_type= type_ndx;
+ changes->map.num_types= (last-type_ndx)+1;
+ }
+ else if (type_ndx>last) {
+ changes->map.num_types= (type_ndx-changes->map.first_type)+1;
+ }
+ }
+ else {
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type= type_ndx;
+ changes->map.num_types= 1;
+ }
+ }
+ return;
+}
+
+Bool
+XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes)
+{
+register int i;
+unsigned int checkState = 0;
+
+ if ((!xkb) || (!xkb->map) || (changed==0))
+ return FALSE;
+ for (i=0;i<xkb->map->num_types;i++) {
+ if (xkb->map->types[i].mods.vmods & changed)
+ XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes);
+ }
+ if (changed&xkb->ctrls->internal.vmods) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask);
+ newMask|= xkb->ctrls->internal.real_mods;
+ if (xkb->ctrls->internal.mask!=newMask) {
+ xkb->ctrls->internal.mask= newMask;
+ if (changes) {
+ changes->ctrls.changed_ctrls|= XkbInternalModsMask;
+ checkState= TRUE;
+ }
+ }
+ }
+ if (changed&xkb->ctrls->ignore_lock.vmods) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask);
+ newMask|= xkb->ctrls->ignore_lock.real_mods;
+ if (xkb->ctrls->ignore_lock.mask!=newMask) {
+ xkb->ctrls->ignore_lock.mask= newMask;
+ if (changes) {
+ changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask;
+ checkState= TRUE;
+ }
+ }
+ }
+ if (xkb->indicators!=NULL) {
+ XkbIndicatorMapPtr map;
+ map= &xkb->indicators->maps[0];
+ for (i=0;i<XkbNumIndicators;i++,map++) {
+ if (map->mods.vmods&changed) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask);
+ newMask|= map->mods.real_mods;
+ if (newMask!=map->mods.mask) {
+ map->mods.mask= newMask;
+ if (changes) {
+ changes->indicators.map_changes|= (1<<i);
+ checkState= TRUE;
+ }
+ }
+ }
+ }
+ }
+ if (xkb->compat!=NULL) {
+ XkbCompatMapPtr compat;
+ compat= xkb->compat;
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask);
+ newMask|= compat->groups[i].real_mods;
+ if (compat->groups[i].mask!=newMask) {
+ compat->groups[i].mask= newMask;
+ if (changes) {
+ changes->compat.changed_groups|= (1<<i);
+ checkState= TRUE;
+ }
+ }
+ }
+ }
+ if (xkb->map && xkb->server) {
+ int highChange = 0, lowChange = -1;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (XkbKeyHasActions(xkb,i)) {
+ register XkbAction *pAct;
+ register int n;
+
+ pAct= XkbKeyActionsPtr(xkb,i);
+ for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) {
+ if ((pAct->type!=XkbSA_NoAction)&&
+ XkbUpdateActionVirtualMods(xkb,pAct,changed)) {
+ if (lowChange<0)
+ lowChange= i;
+ highChange= i;
+ }
+ }
+ }
+ }
+ if (changes && (lowChange>0)) { /* something changed */
+ if (changes->map.changed&XkbKeyActionsMask) {
+ int last;
+ if (changes->map.first_key_act<lowChange)
+ lowChange= changes->map.first_key_act;
+ last= changes->map.first_key_act+changes->map.num_key_acts-1;
+ if (last>highChange)
+ highChange= last;
+ }
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act= lowChange;
+ changes->map.num_key_acts= (highChange-lowChange)+1;
+ }
+ }
+ return checkState;
+}
diff --git a/xorg-server/xkb/ddxList.c b/xorg-server/xkb/ddxList.c
index 421a2eae7..b148c714f 100644
--- a/xorg-server/xkb/ddxList.c
+++ b/xorg-server/xkb/ddxList.c
@@ -1,298 +1,298 @@
-/************************************************************
-Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-#include <X11/X.h>
-#include <X11/Xos.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include <X11/extensions/XKM.h>
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-#include <X11/extensions/XI.h>
-
-#ifdef WIN32
-/* from ddxLoad.c */
-extern const char* Win32TempDir();
-extern int Win32System(const char *cmdline);
-#undef System
-#define System Win32System
-
-#define W32_tmparg " '%s'"
-#define W32_tmpfile ,tmpname
-#define W32_tmplen strlen(tmpname)+3
-#else
-#define W32_tmparg
-#define W32_tmpfile
-#define W32_tmplen 0
-#endif
-
-/***====================================================================***/
-
-static char *componentDirs[_XkbListNumComponents] = {
- "keycodes", "types", "compat", "symbols", "geometry"
-};
-
-/***====================================================================***/
-
-static Status
-_AddListComponent( XkbSrvListInfoPtr list,
- int what,
- unsigned flags,
- char * str,
- ClientPtr client)
-{
-int slen,wlen;
-unsigned char * wire8;
-unsigned short *wire16;
-char * tmp;
-
- if (list->nTotal>=list->maxRtrn) {
- list->nTotal++;
- return Success;
- }
- tmp= strchr(str,')');
- if ((tmp==NULL)&&((tmp=strchr(str,'('))==NULL)) {
- slen= strlen(str);
- while ((slen>0) && isspace(str[slen-1])) {
- slen--;
- }
- }
- else {
- slen= (tmp-str+1);
- }
- wlen= (((slen+1)/2)*2)+4; /* four bytes for flags and length, pad to */
- /* 2-byte boundary */
- if ((list->szPool-list->nPool)<wlen) {
- if (wlen>1024) list->szPool+= XkbPaddedSize(wlen*2);
- else list->szPool+= 1024;
- list->pool= xrealloc(list->pool, list->szPool * sizeof(char));
- if (!list->pool)
- return BadAlloc;
- }
- wire16= (unsigned short *)&list->pool[list->nPool];
- wire8= (unsigned char *)&wire16[2];
- wire16[0]= flags;
- wire16[1]= slen;
- memcpy(wire8,str,slen);
- if (client->swapped) {
- register int n;
- swaps(&wire16[0],n);
- swaps(&wire16[1],n);
- }
- list->nPool+= wlen;
- list->nFound[what]++;
- list->nTotal++;
- return Success;
-}
-
-/***====================================================================***/
-static Status
-XkbDDXListComponent( DeviceIntPtr dev,
- int what,
- XkbSrvListInfoPtr list,
- ClientPtr client)
-{
-char *file,*map,*tmp,*buf=NULL;
-FILE *in;
-Status status;
-int rval;
-Bool haveDir;
-#ifdef WIN32
-char tmpname[PATH_MAX];
-#endif
-
- if ((list->pattern[what]==NULL)||(list->pattern[what][0]=='\0'))
- return Success;
- file= list->pattern[what];
- map= strrchr(file,'(');
- if (map!=NULL) {
- char *tmp;
- map++;
- tmp= strrchr(map,')');
- if ((tmp==NULL)||(tmp[1]!='\0')) {
- /* illegal pattern. No error, but no match */
- return Success;
- }
- }
-
- in= NULL;
- haveDir= TRUE;
-#ifdef WIN32
- strcpy(tmpname, Win32TempDir());
- strcat(tmpname, "\\xkb_XXXXXX");
- (void) mktemp(tmpname);
-#endif
- if (XkbBaseDirectory!=NULL) {
- if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) {
- buf = Xprintf("%s/%s.dir",XkbBaseDirectory,componentDirs[what]);
- in= fopen(buf,"r");
- }
- if (!in) {
- haveDir= FALSE;
- buf = Xprintf(
- "'%s/xkbcomp' '-R%s/%s' -w %ld -l -vlfhpR '%s'" W32_tmparg,
- XkbBinDirectory,XkbBaseDirectory,componentDirs[what],(long)
- ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:xkbDebugFlags)),
- file W32_tmpfile
- );
- }
- }
- else {
- if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) {
- buf = Xprintf("%s.dir",componentDirs[what]);
- in= fopen(buf,"r");
- }
- if (!in) {
- haveDir= FALSE;
- buf = Xprintf(
- "xkbcomp -R%s -w %ld -l -vlfhpR '%s'" W32_tmparg,
- componentDirs[what],(long)
- ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:xkbDebugFlags)),
- file W32_tmpfile
- );
- }
- }
- status= Success;
- if (!haveDir)
- {
-#ifndef WIN32
- in= Popen(buf,"r");
-#else
- if (xkbDebugFlags)
- DebugF("[xkb] xkbList executes: %s\n",buf);
- if (System(buf) < 0)
- ErrorF("[xkb] Could not invoke keymap compiler\n");
- else
- in= fopen(tmpname, "r");
-#endif
- }
- if (!in)
- {
- if (buf != NULL)
- xfree (buf);
-#ifdef WIN32
- unlink(tmpname);
-#endif
- return BadImplementation;
- }
- list->nFound[what]= 0;
- if (buf) {
- xfree(buf);
- buf = NULL;
- }
- buf = xalloc(PATH_MAX * sizeof(char));
- if (!buf)
- {
-#ifdef WIN32
- unlink(tmpname);
-#endif
- return BadAlloc;
- }
- while ((status==Success)&&((tmp=fgets(buf,PATH_MAX,in))!=NULL)) {
- unsigned flags;
- register unsigned int i;
- if (*tmp=='#') /* comment, skip it */
- continue;
- if (!strncmp(tmp, "Warning:", 8) || !strncmp(tmp, " ", 8))
- /* skip warnings too */
- continue;
- flags= 0;
- /* each line in the listing is supposed to start with two */
- /* groups of eight characters, which specify the general */
- /* flags and the flags that are specific to the component */
- /* if they're missing, fail with BadImplementation */
- for (i=0;(i<8)&&(status==Success);i++) { /* read the general flags */
- if (isalpha(*tmp)) flags|= (1L<<i);
- else if (*tmp!='-') status= BadImplementation;
- tmp++;
- }
- if (status != Success) break;
- if (!isspace(*tmp)) {
- status= BadImplementation;
- break;
- }
- else tmp++;
- for (i=0;(i<8)&&(status==Success);i++) { /* read the component flags */
- if (isalpha(*tmp)) flags|= (1L<<(i+8));
- else if (*tmp!='-') status= BadImplementation;
- tmp++;
- }
- if (status != Success) break;
- if (isspace(*tmp)) {
- while (isspace(*tmp)) {
- tmp++;
- }
- }
- else {
- status= BadImplementation;
- break;
- }
- status= _AddListComponent(list,what,flags,tmp,client);
- }
-#ifndef WIN32
- if (haveDir)
- fclose(in);
- else if ((rval=Pclose(in))!=0) {
- if (xkbDebugFlags)
- ErrorF("[xkb] xkbcomp returned exit code %d\n",rval);
- }
-#else
- fclose(in);
- unlink(tmpname);
-#endif
- if (buf != NULL)
- xfree (buf);
- return status;
-}
-
-/***====================================================================***/
-
-/* ARGSUSED */
-Status
-XkbDDXList(DeviceIntPtr dev,XkbSrvListInfoPtr list,ClientPtr client)
-{
-Status status;
-
- status= XkbDDXListComponent(dev,_XkbListKeycodes,list,client);
- if (status==Success)
- status= XkbDDXListComponent(dev,_XkbListTypes,list,client);
- if (status==Success)
- status= XkbDDXListComponent(dev,_XkbListCompat,list,client);
- if (status==Success)
- status= XkbDDXListComponent(dev,_XkbListSymbols,list,client);
- if (status==Success)
- status= XkbDDXListComponent(dev,_XkbListGeometry,list,client);
- return status;
-}
+/************************************************************
+Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <X11/X.h>
+#include <X11/Xos.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XKM.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+#include <X11/extensions/XI.h>
+
+#ifdef WIN32
+/* from ddxLoad.c */
+extern const char* Win32TempDir();
+extern int Win32System(const char *cmdline);
+#undef System
+#define System Win32System
+
+#define W32_tmparg " '%s'"
+#define W32_tmpfile ,tmpname
+#define W32_tmplen strlen(tmpname)+3
+#else
+#define W32_tmparg
+#define W32_tmpfile
+#define W32_tmplen 0
+#endif
+
+/***====================================================================***/
+
+static char *componentDirs[_XkbListNumComponents] = {
+ "keycodes", "types", "compat", "symbols", "geometry"
+};
+
+/***====================================================================***/
+
+static Status
+_AddListComponent( XkbSrvListInfoPtr list,
+ int what,
+ unsigned flags,
+ char * str,
+ ClientPtr client)
+{
+int slen,wlen;
+unsigned char * wire8;
+unsigned short *wire16;
+char * tmp;
+
+ if (list->nTotal>=list->maxRtrn) {
+ list->nTotal++;
+ return Success;
+ }
+ tmp= strchr(str,')');
+ if ((tmp==NULL)&&((tmp=strchr(str,'('))==NULL)) {
+ slen= strlen(str);
+ while ((slen>0) && isspace(str[slen-1])) {
+ slen--;
+ }
+ }
+ else {
+ slen= (tmp-str+1);
+ }
+ wlen= (((slen+1)/2)*2)+4; /* four bytes for flags and length, pad to */
+ /* 2-byte boundary */
+ if ((list->szPool-list->nPool)<wlen) {
+ if (wlen>1024) list->szPool+= XkbPaddedSize(wlen*2);
+ else list->szPool+= 1024;
+ list->pool= realloc(list->pool, list->szPool * sizeof(char));
+ if (!list->pool)
+ return BadAlloc;
+ }
+ wire16= (unsigned short *)&list->pool[list->nPool];
+ wire8= (unsigned char *)&wire16[2];
+ wire16[0]= flags;
+ wire16[1]= slen;
+ memcpy(wire8,str,slen);
+ if (client->swapped) {
+ register int n;
+ swaps(&wire16[0],n);
+ swaps(&wire16[1],n);
+ }
+ list->nPool+= wlen;
+ list->nFound[what]++;
+ list->nTotal++;
+ return Success;
+}
+
+/***====================================================================***/
+static Status
+XkbDDXListComponent( DeviceIntPtr dev,
+ int what,
+ XkbSrvListInfoPtr list,
+ ClientPtr client)
+{
+char *file,*map,*tmp,*buf=NULL;
+FILE *in;
+Status status;
+int rval;
+Bool haveDir;
+#ifdef WIN32
+char tmpname[PATH_MAX];
+#endif
+
+ if ((list->pattern[what]==NULL)||(list->pattern[what][0]=='\0'))
+ return Success;
+ file= list->pattern[what];
+ map= strrchr(file,'(');
+ if (map!=NULL) {
+ char *tmp;
+ map++;
+ tmp= strrchr(map,')');
+ if ((tmp==NULL)||(tmp[1]!='\0')) {
+ /* illegal pattern. No error, but no match */
+ return Success;
+ }
+ }
+
+ in= NULL;
+ haveDir= TRUE;
+#ifdef WIN32
+ strcpy(tmpname, Win32TempDir());
+ strcat(tmpname, "\\xkb_XXXXXX");
+ (void) mktemp(tmpname);
+#endif
+ if (XkbBaseDirectory!=NULL) {
+ if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) {
+ buf = Xprintf("%s/%s.dir",XkbBaseDirectory,componentDirs[what]);
+ in= fopen(buf,"r");
+ }
+ if (!in) {
+ haveDir= FALSE;
+ buf = Xprintf(
+ "'%s/xkbcomp' '-R%s/%s' -w %ld -l -vlfhpR '%s'" W32_tmparg,
+ XkbBinDirectory,XkbBaseDirectory,componentDirs[what],(long)
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:xkbDebugFlags)),
+ file W32_tmpfile
+ );
+ }
+ }
+ else {
+ if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) {
+ buf = Xprintf("%s.dir",componentDirs[what]);
+ in= fopen(buf,"r");
+ }
+ if (!in) {
+ haveDir= FALSE;
+ buf = Xprintf(
+ "xkbcomp -R%s -w %ld -l -vlfhpR '%s'" W32_tmparg,
+ componentDirs[what],(long)
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:xkbDebugFlags)),
+ file W32_tmpfile
+ );
+ }
+ }
+ status= Success;
+ if (!haveDir)
+ {
+#ifndef WIN32
+ in= Popen(buf,"r");
+#else
+ if (xkbDebugFlags)
+ DebugF("[xkb] xkbList executes: %s\n",buf);
+ if (System(buf) < 0)
+ ErrorF("[xkb] Could not invoke keymap compiler\n");
+ else
+ in= fopen(tmpname, "r");
+#endif
+ }
+ if (!in)
+ {
+ if (buf != NULL)
+ free(buf);
+#ifdef WIN32
+ unlink(tmpname);
+#endif
+ return BadImplementation;
+ }
+ list->nFound[what]= 0;
+ if (buf) {
+ free(buf);
+ buf = NULL;
+ }
+ buf = malloc(PATH_MAX * sizeof(char));
+ if (!buf)
+ {
+#ifdef WIN32
+ unlink(tmpname);
+#endif
+ return BadAlloc;
+ }
+ while ((status==Success)&&((tmp=fgets(buf,PATH_MAX,in))!=NULL)) {
+ unsigned flags;
+ register unsigned int i;
+ if (*tmp=='#') /* comment, skip it */
+ continue;
+ if (!strncmp(tmp, "Warning:", 8) || !strncmp(tmp, " ", 8))
+ /* skip warnings too */
+ continue;
+ flags= 0;
+ /* each line in the listing is supposed to start with two */
+ /* groups of eight characters, which specify the general */
+ /* flags and the flags that are specific to the component */
+ /* if they're missing, fail with BadImplementation */
+ for (i=0;(i<8)&&(status==Success);i++) { /* read the general flags */
+ if (isalpha(*tmp)) flags|= (1L<<i);
+ else if (*tmp!='-') status= BadImplementation;
+ tmp++;
+ }
+ if (status != Success) break;
+ if (!isspace(*tmp)) {
+ status= BadImplementation;
+ break;
+ }
+ else tmp++;
+ for (i=0;(i<8)&&(status==Success);i++) { /* read the component flags */
+ if (isalpha(*tmp)) flags|= (1L<<(i+8));
+ else if (*tmp!='-') status= BadImplementation;
+ tmp++;
+ }
+ if (status != Success) break;
+ if (isspace(*tmp)) {
+ while (isspace(*tmp)) {
+ tmp++;
+ }
+ }
+ else {
+ status= BadImplementation;
+ break;
+ }
+ status= _AddListComponent(list,what,flags,tmp,client);
+ }
+#ifndef WIN32
+ if (haveDir)
+ fclose(in);
+ else if ((rval=Pclose(in))!=0) {
+ if (xkbDebugFlags)
+ ErrorF("[xkb] xkbcomp returned exit code %d\n",rval);
+ }
+#else
+ fclose(in);
+ unlink(tmpname);
+#endif
+ if (buf != NULL)
+ free(buf);
+ return status;
+}
+
+/***====================================================================***/
+
+/* ARGSUSED */
+Status
+XkbDDXList(DeviceIntPtr dev,XkbSrvListInfoPtr list,ClientPtr client)
+{
+Status status;
+
+ status= XkbDDXListComponent(dev,_XkbListKeycodes,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListTypes,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListCompat,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListSymbols,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListGeometry,list,client);
+ return status;
+}
diff --git a/xorg-server/xkb/ddxLoad.c b/xorg-server/xkb/ddxLoad.c
index bf7adb8e1..6cf8e7ee9 100644
--- a/xorg-server/xkb/ddxLoad.c
+++ b/xorg-server/xkb/ddxLoad.c
@@ -1,463 +1,461 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <xkb-config.h>
-
-#include <stdio.h>
-#include <ctype.h>
-#include <X11/X.h>
-#include <X11/Xos.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include <X11/extensions/XKM.h>
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-#include <X11/extensions/XI.h>
-#include "xkb.h"
-
-#if defined(CSRG_BASED) || defined(linux) || defined(__GNU__)
-#include <paths.h>
-#endif
-
- /*
- * If XKM_OUTPUT_DIR specifies a path without a leading slash, it is
- * relative to the top-level XKB configuration directory.
- * Making the server write to a subdirectory of that directory
- * requires some work in the general case (install procedure
- * has to create links to /var or somesuch on many machines),
- * so we just compile into /usr/tmp for now.
- */
-#ifndef XKM_OUTPUT_DIR
-#define XKM_OUTPUT_DIR "compiled/"
-#endif
-
-#define PRE_ERROR_MSG "\"The XKEYBOARD keymap compiler (xkbcomp) reports:\""
-#define ERROR_PREFIX "\"> \""
-#define POST_ERROR_MSG1 "\"Errors from xkbcomp are not fatal to the X server\""
-#define POST_ERROR_MSG2 "\"End of messages from xkbcomp\""
-
-#if defined(WIN32)
-#define PATHSEPARATOR "\\"
-#else
-#define PATHSEPARATOR "/"
-#endif
-
-#ifdef WIN32
-
-#include <X11/Xwindows.h>
-const char*
-Win32TempDir()
-{
- static char buffer[PATH_MAX];
- if (GetTempPath(sizeof(buffer), buffer))
- {
- int len;
- buffer[sizeof(buffer)-1] = 0;
- len = strlen(buffer);
- if (len > 0)
- if (buffer[len-1] == '\\')
- buffer[len-1] = 0;
- return buffer;
- }
- if (getenv("TEMP") != NULL)
- return getenv("TEMP");
- else if (getenv("TMP") != NULL)
- return getenv("TEMP");
- else
- return "/tmp";
-}
-
-int
-Win32System(const char *cmdline)
-{
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- DWORD dwExitCode;
- char *cmd = xstrdup(cmdline);
-
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory( &pi, sizeof(pi) );
-
- if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
- {
- LPVOID buffer;
- if (!FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &buffer,
- 0,
- NULL ))
- {
- ErrorF("[xkb] Starting '%s' failed!\n", cmdline);
- }
- else
- {
- ErrorF("[xkb] Starting '%s' failed: %s", cmdline, (char *)buffer);
- LocalFree(buffer);
- }
-
- xfree(cmd);
- return -1;
- }
- /* Wait until child process exits. */
- WaitForSingleObject( pi.hProcess, INFINITE );
-
- GetExitCodeProcess( pi.hProcess, &dwExitCode);
-
- /* Close process and thread handles. */
- CloseHandle( pi.hProcess );
- CloseHandle( pi.hThread );
- xfree(cmd);
-
- return dwExitCode;
-}
-#undef System
-#define System(x) Win32System(x)
-#endif
-
-static void
-OutputDirectory(
- char* outdir,
- size_t size)
-{
-#ifndef WIN32
- /* Can we write an xkm and then open it too? */
- if (access(XKM_OUTPUT_DIR, W_OK | X_OK) == 0 && (strlen(XKM_OUTPUT_DIR) < size))
- {
- (void) strcpy (outdir, XKM_OUTPUT_DIR);
- } else
-#else
- if (strlen(Win32TempDir()) + 1 < size)
- {
- (void) strcpy(outdir, Win32TempDir());
- (void) strcat(outdir, "\\");
- } else
-#endif
- if (strlen("/tmp/") < size)
- {
- (void) strcpy (outdir, "/tmp/");
- }
-}
-
-static Bool
-XkbDDXCompileKeymapByNames( XkbDescPtr xkb,
- XkbComponentNamesPtr names,
- unsigned want,
- unsigned need,
- char * nameRtrn,
- int nameRtrnLen)
-{
- FILE * out;
- char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
-
- const char *emptystring = "";
- const char *xkbbasedirflag = emptystring;
- const char *xkbbindir = emptystring;
- const char *xkbbindirsep = emptystring;
-
-#ifdef WIN32
- /* WIN32 has no popen. The input must be stored in a file which is
- used as input for xkbcomp. xkbcomp does not read from stdin. */
- char tmpname[PATH_MAX];
- const char *xkmfile = tmpname;
-#else
- const char *xkmfile = "-";
-#endif
-
- snprintf(keymap, sizeof(keymap), "server-%s", display);
-
- OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
-
-#ifdef WIN32
- strcpy(tmpname, Win32TempDir());
- strcat(tmpname, "\\xkb_XXXXXX");
- (void) mktemp(tmpname);
-#endif
-
- if (XkbBaseDirectory != NULL) {
- xkbbasedirflag = Xprintf("\"-R%s\"", XkbBaseDirectory);
- }
-
- if (XkbBinDirectory != NULL) {
- int ld = strlen(XkbBinDirectory);
- int lps = strlen(PATHSEPARATOR);
-
- xkbbindir = XkbBinDirectory;
-
- if ((ld >= lps) &&
- (strcmp(xkbbindir + ld - lps, PATHSEPARATOR) != 0)) {
- xkbbindirsep = PATHSEPARATOR;
- }
- }
-
- buf = Xprintf("\"%s%sxkbcomp\" -w %d %s -xkm \"%s\" "
- "-em1 %s -emp %s -eml %s \"%s%s.xkm\"",
- xkbbindir, xkbbindirsep,
- ( (xkbDebugFlags < 2) ? 1 :
- ((xkbDebugFlags > 10) ? 10 : (int)xkbDebugFlags) ),
- xkbbasedirflag, xkmfile,
- PRE_ERROR_MSG, ERROR_PREFIX, POST_ERROR_MSG1,
- xkm_output_dir, keymap);
-
- if (xkbbasedirflag != emptystring) {
- xfree(xkbbasedirflag);
- }
-
-#ifndef WIN32
- out= Popen(buf,"w");
-#else
- out= fopen(tmpname, "w");
-#endif
-
- if (out!=NULL) {
-#ifdef DEBUG
- if (xkbDebugFlags) {
- ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
- XkbWriteXKBKeymapForNames(stderr,names,xkb,want,need);
- }
-#endif
- XkbWriteXKBKeymapForNames(out,names,xkb,want,need);
-#ifndef WIN32
- if (Pclose(out)==0)
-#else
- if (fclose(out)==0 && System(buf) >= 0)
-#endif
- {
- if (xkbDebugFlags)
- DebugF("[xkb] xkb executes: %s\n",buf);
- if (nameRtrn) {
- strncpy(nameRtrn,keymap,nameRtrnLen);
- nameRtrn[nameRtrnLen-1]= '\0';
- }
- if (buf != NULL)
- xfree (buf);
-#ifdef WIN32
- /* remove the temporary file */
- unlink(tmpname);
-#endif
- return TRUE;
- }
- else
- LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap);
-#ifdef WIN32
- /* remove the temporary file */
- unlink(tmpname);
-#endif
- }
- else {
-#ifndef WIN32
- LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp\n");
-#else
- LogMessage(X_ERROR, "Could not open file %s\n", tmpname);
-#endif
- }
- if (nameRtrn)
- nameRtrn[0]= '\0';
- if (buf != NULL)
- xfree (buf);
- return FALSE;
-}
-
-static FILE *
-XkbDDXOpenConfigFile(char *mapName,char *fileNameRtrn,int fileNameRtrnLen)
-{
-char buf[PATH_MAX],xkm_output_dir[PATH_MAX];
-FILE * file;
-
- buf[0]= '\0';
- if (mapName!=NULL) {
- OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
- if ((XkbBaseDirectory!=NULL)&&(xkm_output_dir[0]!='/')
-#ifdef WIN32
- &&(!isalpha(xkm_output_dir[0]) || xkm_output_dir[1]!=':')
-#endif
- ) {
- if (strlen(XkbBaseDirectory)+strlen(xkm_output_dir)
- +strlen(mapName)+6 <= PATH_MAX)
- {
- sprintf(buf,"%s/%s%s.xkm",XkbBaseDirectory,
- xkm_output_dir,mapName);
- }
- }
- else if (strlen(xkm_output_dir)+strlen(mapName)+5 <= PATH_MAX)
- sprintf(buf,"%s%s.xkm",xkm_output_dir,mapName);
- if (buf[0] != '\0')
- file= fopen(buf,"rb");
- else file= NULL;
- }
- else file= NULL;
- if ((fileNameRtrn!=NULL)&&(fileNameRtrnLen>0)) {
- strncpy(fileNameRtrn,buf,fileNameRtrnLen);
- buf[fileNameRtrnLen-1]= '\0';
- }
- return file;
-}
-
-unsigned
-XkbDDXLoadKeymapByNames( DeviceIntPtr keybd,
- XkbComponentNamesPtr names,
- unsigned want,
- unsigned need,
- XkbDescPtr * xkbRtrn,
- char * nameRtrn,
- int nameRtrnLen)
-{
-XkbDescPtr xkb;
-FILE * file;
-char fileName[PATH_MAX];
-unsigned missing;
-
- *xkbRtrn = NULL;
- if ((keybd==NULL)||(keybd->key==NULL)||(keybd->key->xkbInfo==NULL))
- xkb= NULL;
- else xkb= keybd->key->xkbInfo->desc;
- if ((names->keycodes==NULL)&&(names->types==NULL)&&
- (names->compat==NULL)&&(names->symbols==NULL)&&
- (names->geometry==NULL)) {
- LogMessage(X_ERROR, "XKB: No components provided for device %s\n",
- keybd->name ? keybd->name : "(unnamed keyboard)");
- return 0;
- }
- else if (!XkbDDXCompileKeymapByNames(xkb,names,want,need,
- nameRtrn,nameRtrnLen)){
- LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
- return 0;
- }
- file= XkbDDXOpenConfigFile(nameRtrn,fileName,PATH_MAX);
- if (file==NULL) {
- LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",fileName);
- return 0;
- }
- missing= XkmReadFile(file,need,want,xkbRtrn);
- if (*xkbRtrn==NULL) {
- LogMessage(X_ERROR, "Error loading keymap %s\n",fileName);
- fclose(file);
- (void) unlink (fileName);
- return 0;
- }
- else {
- DebugF("Loaded XKB keymap %s, defined=0x%x\n",fileName,(*xkbRtrn)->defined);
- }
- fclose(file);
- (void) unlink (fileName);
- return (need|want)&(~missing);
-}
-
-Bool
-XkbDDXNamesFromRules( DeviceIntPtr keybd,
- char * rules_name,
- XkbRF_VarDefsPtr defs,
- XkbComponentNamesPtr names)
-{
-char buf[PATH_MAX];
-FILE * file;
-Bool complete;
-XkbRF_RulesPtr rules;
-
- if (!rules_name)
- return FALSE;
-
- if (strlen(XkbBaseDirectory) + strlen(rules_name) + 8 > PATH_MAX) {
- LogMessage(X_ERROR, "XKB: Rules name is too long\n");
- return FALSE;
- }
- sprintf(buf,"%s/rules/%s", XkbBaseDirectory, rules_name);
-
- file = fopen(buf, "r");
- if (!file) {
- LogMessage(X_ERROR, "XKB: Couldn't open rules file %s\n", buf);
- return FALSE;
- }
-
- rules = XkbRF_Create();
- if (!rules) {
- LogMessage(X_ERROR, "XKB: Couldn't create rules struct\n");
- fclose(file);
- return FALSE;
- }
-
- if (!XkbRF_LoadRules(file, rules)) {
- LogMessage(X_ERROR, "XKB: Couldn't parse rules file %s\n", rules_name);
- fclose(file);
- XkbRF_Free(rules,TRUE);
- return FALSE;
- }
-
- memset(names, 0, sizeof(*names));
- complete = XkbRF_GetComponents(rules,defs,names);
- fclose(file);
- XkbRF_Free(rules, TRUE);
-
- if (!complete)
- LogMessage(X_ERROR, "XKB: Rules returned no components\n");
-
- return complete;
-}
-
-XkbDescPtr
-XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet *rmlvo)
-{
- XkbComponentNamesRec kccgst;
- XkbRF_VarDefsRec mlvo;
- XkbDescPtr xkb;
- char name[PATH_MAX];
-
- if (!dev || !rmlvo) {
- LogMessage(X_ERROR, "XKB: No device or RMLVO specified\n");
- return NULL;
- }
-
- mlvo.model = rmlvo->model;
- mlvo.layout = rmlvo->layout;
- mlvo.variant = rmlvo->variant;
- mlvo.options = rmlvo->options;
-
- /* XDNFR already logs for us. */
- if (!XkbDDXNamesFromRules(dev, rmlvo->rules, &mlvo, &kccgst))
- return NULL;
-
- /* XDLKBN too, but it might return 0 as well as allocating. */
- if (!XkbDDXLoadKeymapByNames(dev, &kccgst, XkmAllIndicesMask, 0, &xkb, name,
- PATH_MAX)) {
- if (xkb)
- XkbFreeKeyboard(xkb, 0, TRUE);
- return NULL;
- }
-
- return xkb;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <xkb-config.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <X11/X.h>
+#include <X11/Xos.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XKM.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+#include <X11/extensions/XI.h>
+#include "xkb.h"
+
+#if defined(CSRG_BASED) || defined(linux) || defined(__GNU__)
+#include <paths.h>
+#endif
+
+ /*
+ * If XKM_OUTPUT_DIR specifies a path without a leading slash, it is
+ * relative to the top-level XKB configuration directory.
+ * Making the server write to a subdirectory of that directory
+ * requires some work in the general case (install procedure
+ * has to create links to /var or somesuch on many machines),
+ * so we just compile into /usr/tmp for now.
+ */
+#ifndef XKM_OUTPUT_DIR
+#define XKM_OUTPUT_DIR "compiled/"
+#endif
+
+#define PRE_ERROR_MSG "\"The XKEYBOARD keymap compiler (xkbcomp) reports:\""
+#define ERROR_PREFIX "\"> \""
+#define POST_ERROR_MSG1 "\"Errors from xkbcomp are not fatal to the X server\""
+#define POST_ERROR_MSG2 "\"End of messages from xkbcomp\""
+
+#if defined(WIN32)
+#define PATHSEPARATOR "\\"
+#else
+#define PATHSEPARATOR "/"
+#endif
+
+#ifdef WIN32
+
+#include <X11/Xwindows.h>
+const char*
+Win32TempDir()
+{
+ static char buffer[PATH_MAX];
+ if (GetTempPath(sizeof(buffer), buffer))
+ {
+ int len;
+ buffer[sizeof(buffer)-1] = 0;
+ len = strlen(buffer);
+ if (len > 0)
+ if (buffer[len-1] == '\\')
+ buffer[len-1] = 0;
+ return buffer;
+ }
+ if (getenv("TEMP") != NULL)
+ return getenv("TEMP");
+ else if (getenv("TMP") != NULL)
+ return getenv("TEMP");
+ else
+ return "/tmp";
+}
+
+int
+Win32System(const char *cmdline)
+{
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ DWORD dwExitCode;
+ char *cmd = xstrdup(cmdline);
+
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZeroMemory( &pi, sizeof(pi) );
+
+ if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
+ {
+ LPVOID buffer;
+ if (!FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &buffer,
+ 0,
+ NULL ))
+ {
+ ErrorF("[xkb] Starting '%s' failed!\n", cmdline);
+ }
+ else
+ {
+ ErrorF("[xkb] Starting '%s' failed: %s", cmdline, (char *)buffer);
+ LocalFree(buffer);
+ }
+
+ free(cmd);
+ return -1;
+ }
+ /* Wait until child process exits. */
+ WaitForSingleObject( pi.hProcess, INFINITE );
+
+ GetExitCodeProcess( pi.hProcess, &dwExitCode);
+
+ /* Close process and thread handles. */
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+ free(cmd);
+
+ return dwExitCode;
+}
+#undef System
+#define System(x) Win32System(x)
+#endif
+
+static void
+OutputDirectory(
+ char* outdir,
+ size_t size)
+{
+#ifndef WIN32
+ /* Can we write an xkm and then open it too? */
+ if (access(XKM_OUTPUT_DIR, W_OK | X_OK) == 0 && (strlen(XKM_OUTPUT_DIR) < size))
+ {
+ (void) strcpy (outdir, XKM_OUTPUT_DIR);
+ } else
+#else
+ if (strlen(Win32TempDir()) + 1 < size)
+ {
+ (void) strcpy(outdir, Win32TempDir());
+ (void) strcat(outdir, "\\");
+ } else
+#endif
+ if (strlen("/tmp/") < size)
+ {
+ (void) strcpy (outdir, "/tmp/");
+ }
+}
+
+static Bool
+XkbDDXCompileKeymapByNames( XkbDescPtr xkb,
+ XkbComponentNamesPtr names,
+ unsigned want,
+ unsigned need,
+ char * nameRtrn,
+ int nameRtrnLen)
+{
+ FILE * out;
+ char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
+
+ const char *emptystring = "";
+ char *xkbbasedirflag = NULL;
+ const char *xkbbindir = emptystring;
+ const char *xkbbindirsep = emptystring;
+
+#ifdef WIN32
+ /* WIN32 has no popen. The input must be stored in a file which is
+ used as input for xkbcomp. xkbcomp does not read from stdin. */
+ char tmpname[PATH_MAX];
+ const char *xkmfile = tmpname;
+#else
+ const char *xkmfile = "-";
+#endif
+
+ snprintf(keymap, sizeof(keymap), "server-%s", display);
+
+ OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
+
+#ifdef WIN32
+ strcpy(tmpname, Win32TempDir());
+ strcat(tmpname, "\\xkb_XXXXXX");
+ (void) mktemp(tmpname);
+#endif
+
+ if (XkbBaseDirectory != NULL) {
+ xkbbasedirflag = Xprintf("\"-R%s\"", XkbBaseDirectory);
+ }
+
+ if (XkbBinDirectory != NULL) {
+ int ld = strlen(XkbBinDirectory);
+ int lps = strlen(PATHSEPARATOR);
+
+ xkbbindir = XkbBinDirectory;
+
+ if ((ld >= lps) &&
+ (strcmp(xkbbindir + ld - lps, PATHSEPARATOR) != 0)) {
+ xkbbindirsep = PATHSEPARATOR;
+ }
+ }
+
+ buf = Xprintf("\"%s%sxkbcomp\" -w %d %s -xkm \"%s\" "
+ "-em1 %s -emp %s -eml %s \"%s%s.xkm\"",
+ xkbbindir, xkbbindirsep,
+ ( (xkbDebugFlags < 2) ? 1 :
+ ((xkbDebugFlags > 10) ? 10 : (int)xkbDebugFlags) ),
+ xkbbasedirflag ? xkbbasedirflag : "", xkmfile,
+ PRE_ERROR_MSG, ERROR_PREFIX, POST_ERROR_MSG1,
+ xkm_output_dir, keymap);
+
+ free(xkbbasedirflag);
+
+#ifndef WIN32
+ out= Popen(buf,"w");
+#else
+ out= fopen(tmpname, "w");
+#endif
+
+ if (out!=NULL) {
+#ifdef DEBUG
+ if (xkbDebugFlags) {
+ ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
+ XkbWriteXKBKeymapForNames(stderr,names,xkb,want,need);
+ }
+#endif
+ XkbWriteXKBKeymapForNames(out,names,xkb,want,need);
+#ifndef WIN32
+ if (Pclose(out)==0)
+#else
+ if (fclose(out)==0 && System(buf) >= 0)
+#endif
+ {
+ if (xkbDebugFlags)
+ DebugF("[xkb] xkb executes: %s\n",buf);
+ if (nameRtrn) {
+ strncpy(nameRtrn,keymap,nameRtrnLen);
+ nameRtrn[nameRtrnLen-1]= '\0';
+ }
+ if (buf != NULL)
+ free(buf);
+#ifdef WIN32
+ /* remove the temporary file */
+ unlink(tmpname);
+#endif
+ return TRUE;
+ }
+ else
+ LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap);
+#ifdef WIN32
+ /* remove the temporary file */
+ unlink(tmpname);
+#endif
+ }
+ else {
+#ifndef WIN32
+ LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp\n");
+#else
+ LogMessage(X_ERROR, "Could not open file %s\n", tmpname);
+#endif
+ }
+ if (nameRtrn)
+ nameRtrn[0]= '\0';
+ if (buf != NULL)
+ free(buf);
+ return FALSE;
+}
+
+static FILE *
+XkbDDXOpenConfigFile(char *mapName,char *fileNameRtrn,int fileNameRtrnLen)
+{
+char buf[PATH_MAX],xkm_output_dir[PATH_MAX];
+FILE * file;
+
+ buf[0]= '\0';
+ if (mapName!=NULL) {
+ OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
+ if ((XkbBaseDirectory!=NULL)&&(xkm_output_dir[0]!='/')
+#ifdef WIN32
+ &&(!isalpha(xkm_output_dir[0]) || xkm_output_dir[1]!=':')
+#endif
+ ) {
+ if (strlen(XkbBaseDirectory)+strlen(xkm_output_dir)
+ +strlen(mapName)+6 <= PATH_MAX)
+ {
+ sprintf(buf,"%s/%s%s.xkm",XkbBaseDirectory,
+ xkm_output_dir,mapName);
+ }
+ }
+ else if (strlen(xkm_output_dir)+strlen(mapName)+5 <= PATH_MAX)
+ sprintf(buf,"%s%s.xkm",xkm_output_dir,mapName);
+ if (buf[0] != '\0')
+ file= fopen(buf,"rb");
+ else file= NULL;
+ }
+ else file= NULL;
+ if ((fileNameRtrn!=NULL)&&(fileNameRtrnLen>0)) {
+ strncpy(fileNameRtrn,buf,fileNameRtrnLen);
+ buf[fileNameRtrnLen-1]= '\0';
+ }
+ return file;
+}
+
+unsigned
+XkbDDXLoadKeymapByNames( DeviceIntPtr keybd,
+ XkbComponentNamesPtr names,
+ unsigned want,
+ unsigned need,
+ XkbDescPtr * xkbRtrn,
+ char * nameRtrn,
+ int nameRtrnLen)
+{
+XkbDescPtr xkb;
+FILE * file;
+char fileName[PATH_MAX];
+unsigned missing;
+
+ *xkbRtrn = NULL;
+ if ((keybd==NULL)||(keybd->key==NULL)||(keybd->key->xkbInfo==NULL))
+ xkb= NULL;
+ else xkb= keybd->key->xkbInfo->desc;
+ if ((names->keycodes==NULL)&&(names->types==NULL)&&
+ (names->compat==NULL)&&(names->symbols==NULL)&&
+ (names->geometry==NULL)) {
+ LogMessage(X_ERROR, "XKB: No components provided for device %s\n",
+ keybd->name ? keybd->name : "(unnamed keyboard)");
+ return 0;
+ }
+ else if (!XkbDDXCompileKeymapByNames(xkb,names,want,need,
+ nameRtrn,nameRtrnLen)){
+ LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
+ return 0;
+ }
+ file= XkbDDXOpenConfigFile(nameRtrn,fileName,PATH_MAX);
+ if (file==NULL) {
+ LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",fileName);
+ return 0;
+ }
+ missing= XkmReadFile(file,need,want,xkbRtrn);
+ if (*xkbRtrn==NULL) {
+ LogMessage(X_ERROR, "Error loading keymap %s\n",fileName);
+ fclose(file);
+ (void) unlink (fileName);
+ return 0;
+ }
+ else {
+ DebugF("Loaded XKB keymap %s, defined=0x%x\n",fileName,(*xkbRtrn)->defined);
+ }
+ fclose(file);
+ (void) unlink (fileName);
+ return (need|want)&(~missing);
+}
+
+Bool
+XkbDDXNamesFromRules( DeviceIntPtr keybd,
+ char * rules_name,
+ XkbRF_VarDefsPtr defs,
+ XkbComponentNamesPtr names)
+{
+char buf[PATH_MAX];
+FILE * file;
+Bool complete;
+XkbRF_RulesPtr rules;
+
+ if (!rules_name)
+ return FALSE;
+
+ if (strlen(XkbBaseDirectory) + strlen(rules_name) + 8 > PATH_MAX) {
+ LogMessage(X_ERROR, "XKB: Rules name is too long\n");
+ return FALSE;
+ }
+ sprintf(buf,"%s/rules/%s", XkbBaseDirectory, rules_name);
+
+ file = fopen(buf, "r");
+ if (!file) {
+ LogMessage(X_ERROR, "XKB: Couldn't open rules file %s\n", buf);
+ return FALSE;
+ }
+
+ rules = XkbRF_Create();
+ if (!rules) {
+ LogMessage(X_ERROR, "XKB: Couldn't create rules struct\n");
+ fclose(file);
+ return FALSE;
+ }
+
+ if (!XkbRF_LoadRules(file, rules)) {
+ LogMessage(X_ERROR, "XKB: Couldn't parse rules file %s\n", rules_name);
+ fclose(file);
+ XkbRF_Free(rules,TRUE);
+ return FALSE;
+ }
+
+ memset(names, 0, sizeof(*names));
+ complete = XkbRF_GetComponents(rules,defs,names);
+ fclose(file);
+ XkbRF_Free(rules, TRUE);
+
+ if (!complete)
+ LogMessage(X_ERROR, "XKB: Rules returned no components\n");
+
+ return complete;
+}
+
+XkbDescPtr
+XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet *rmlvo)
+{
+ XkbComponentNamesRec kccgst;
+ XkbRF_VarDefsRec mlvo;
+ XkbDescPtr xkb;
+ char name[PATH_MAX];
+
+ if (!dev || !rmlvo) {
+ LogMessage(X_ERROR, "XKB: No device or RMLVO specified\n");
+ return NULL;
+ }
+
+ mlvo.model = rmlvo->model;
+ mlvo.layout = rmlvo->layout;
+ mlvo.variant = rmlvo->variant;
+ mlvo.options = rmlvo->options;
+
+ /* XDNFR already logs for us. */
+ if (!XkbDDXNamesFromRules(dev, rmlvo->rules, &mlvo, &kccgst))
+ return NULL;
+
+ /* XDLKBN too, but it might return 0 as well as allocating. */
+ if (!XkbDDXLoadKeymapByNames(dev, &kccgst, XkmAllIndicesMask, 0, &xkb, name,
+ PATH_MAX)) {
+ if (xkb)
+ XkbFreeKeyboard(xkb, 0, TRUE);
+ return NULL;
+ }
+
+ return xkb;
+}
diff --git a/xorg-server/xkb/maprules.c b/xorg-server/xkb/maprules.c
index 3467c4238..a717aa456 100644
--- a/xorg-server/xkb/maprules.c
+++ b/xorg-server/xkb/maprules.c
@@ -1,1019 +1,1019 @@
-/************************************************************
- Copyright (c) 1996 by Silicon Graphics Computer Systems, Inc.
-
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
-
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- ********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-#define X_INCLUDE_STRING_H
-#define XOS_USE_NO_LOCKING
-#include <X11/Xos_r.h>
-
-#include <X11/Xproto.h>
-#include <X11/X.h>
-#include <X11/Xos.h>
-#include <X11/Xfuncs.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-#include "misc.h"
-#include "inputstr.h"
-#include "dix.h"
-#include "os.h"
-#include "xkbstr.h"
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-
-/***====================================================================***/
-
-
-
-#define DFLT_LINE_SIZE 128
-
-typedef struct {
- int line_num;
- int sz_line;
- int num_line;
- char buf[DFLT_LINE_SIZE];
- char * line;
-} InputLine;
-
-static void
-InitInputLine(InputLine *line)
-{
- line->line_num= 1;
- line->num_line= 0;
- line->sz_line= DFLT_LINE_SIZE;
- line->line= line->buf;
- return;
-}
-
-static void
-FreeInputLine(InputLine *line)
-{
- if (line->line!=line->buf)
- xfree(line->line);
- line->line_num= 1;
- line->num_line= 0;
- line->sz_line= DFLT_LINE_SIZE;
- line->line= line->buf;
- return;
-}
-
-static int
-InputLineAddChar(InputLine *line,int ch)
-{
- if (line->num_line>=line->sz_line) {
- if (line->line==line->buf) {
- line->line= xalloc(line->sz_line*2);
- memcpy(line->line,line->buf,line->sz_line);
- }
- else {
- line->line= xrealloc((char *)line->line,line->sz_line*2);
- }
- line->sz_line*= 2;
- }
- line->line[line->num_line++]= ch;
- return ch;
-}
-
-#define ADD_CHAR(l,c) ((l)->num_line<(l)->sz_line?\
- (int)((l)->line[(l)->num_line++]= (c)):\
- InputLineAddChar(l,c))
-
-static Bool
-GetInputLine(FILE *file,InputLine *line,Bool checkbang)
-{
-int ch;
-Bool endOfFile,spacePending,slashPending,inComment;
-
- endOfFile= FALSE;
- while ((!endOfFile)&&(line->num_line==0)) {
- spacePending= slashPending= inComment= FALSE;
- while (((ch=getc(file))!='\n')&&(ch!=EOF)) {
- if (ch=='\\') {
- if ((ch=getc(file))==EOF)
- break;
- if (ch=='\n') {
- inComment= FALSE;
- ch= ' ';
- line->line_num++;
- }
- }
- if (inComment)
- continue;
- if (ch=='/') {
- if (slashPending) {
- inComment= TRUE;
- slashPending= FALSE;
- }
- else {
- slashPending= TRUE;
- }
- continue;
- }
- else if (slashPending) {
- if (spacePending) {
- ADD_CHAR(line,' ');
- spacePending= FALSE;
- }
- ADD_CHAR(line,'/');
- slashPending= FALSE;
- }
- if (isspace(ch)) {
- while (isspace(ch)&&(ch!='\n')&&(ch!=EOF)) {
- ch= getc(file);
- }
- if (ch==EOF)
- break;
- if ((ch!='\n')&&(line->num_line>0))
- spacePending= TRUE;
- ungetc(ch,file);
- }
- else {
- if (spacePending) {
- ADD_CHAR(line,' ');
- spacePending= FALSE;
- }
- if (checkbang && ch=='!') {
- if (line->num_line!=0) {
- DebugF("The '!' legal only at start of line\n");
- DebugF("Line containing '!' ignored\n");
- line->num_line= 0;
- inComment= 0;
- break;
- }
-
- }
- ADD_CHAR(line,ch);
- }
- }
- if (ch==EOF)
- endOfFile= TRUE;
-/* else line->num_line++;*/
- }
- if ((line->num_line==0)&&(endOfFile))
- return FALSE;
- ADD_CHAR(line,'\0');
- return TRUE;
-}
-
-/***====================================================================***/
-
-#define MODEL 0
-#define LAYOUT 1
-#define VARIANT 2
-#define OPTION 3
-#define KEYCODES 4
-#define SYMBOLS 5
-#define TYPES 6
-#define COMPAT 7
-#define GEOMETRY 8
-#define MAX_WORDS 9
-
-#define PART_MASK 0x000F
-#define COMPONENT_MASK 0x03F0
-
-static char * cname[MAX_WORDS] = {
- "model", "layout", "variant", "option",
- "keycodes", "symbols", "types", "compat", "geometry"
-};
-
-typedef struct _RemapSpec {
- int number;
- int num_remap;
- struct {
- int word;
- int index;
- } remap[MAX_WORDS];
-} RemapSpec;
-
-typedef struct _FileSpec {
- char * name[MAX_WORDS];
- struct _FileSpec * pending;
-} FileSpec;
-
-typedef struct {
- char * model;
- char * layout[XkbNumKbdGroups+1];
- char * variant[XkbNumKbdGroups+1];
- char * options;
-} XkbRF_MultiDefsRec, *XkbRF_MultiDefsPtr;
-
-#define NDX_BUFF_SIZE 4
-
-/***====================================================================***/
-
-static char*
-get_index(char *str, int *ndx)
-{
- char ndx_buf[NDX_BUFF_SIZE];
- char *end;
-
- if (*str != '[') {
- *ndx = 0;
- return str;
- }
- str++;
- end = strchr(str, ']');
- if (end == NULL) {
- *ndx = -1;
- return str - 1;
- }
- if ( (end - str) >= NDX_BUFF_SIZE) {
- *ndx = -1;
- return end + 1;
- }
- strncpy(ndx_buf, str, end - str);
- ndx_buf[end - str] = '\0';
- *ndx = atoi(ndx_buf);
- return end + 1;
-}
-
-static void
-SetUpRemap(InputLine *line,RemapSpec *remap)
-{
-char * tok,*str;
-unsigned present, l_ndx_present, v_ndx_present;
-register int i;
-int len, ndx;
-_Xstrtokparams strtok_buf;
-Bool found;
-
-
- l_ndx_present = v_ndx_present = present= 0;
- str= &line->line[1];
- len = remap->number;
- bzero((char *)remap,sizeof(RemapSpec));
- remap->number = len;
- while ((tok=_XStrtok(str," ",strtok_buf))!=NULL) {
- found= FALSE;
- str= NULL;
- if (strcmp(tok,"=")==0)
- continue;
- for (i=0;i<MAX_WORDS;i++) {
- len = strlen(cname[i]);
- if (strncmp(cname[i],tok,len)==0) {
- if(strlen(tok) > len) {
- char *end = get_index(tok+len, &ndx);
- if ((i != LAYOUT && i != VARIANT) ||
- *end != '\0' || ndx == -1)
- break;
- if (ndx < 1 || ndx > XkbNumKbdGroups) {
- DebugF("Illegal %s index: %d\n", cname[i], ndx);
- DebugF("Index must be in range 1..%d\n",
- XkbNumKbdGroups);
- break;
- }
- } else {
- ndx = 0;
- }
- found= TRUE;
- if (present&(1<<i)) {
- if ((i == LAYOUT && l_ndx_present&(1<<ndx)) ||
- (i == VARIANT && v_ndx_present&(1<<ndx)) ) {
- DebugF("Component \"%s\" listed twice\n",tok);
- DebugF("Second definition ignored\n");
- break;
- }
- }
- present |= (1<<i);
- if (i == LAYOUT)
- l_ndx_present |= 1 << ndx;
- if (i == VARIANT)
- v_ndx_present |= 1 << ndx;
- remap->remap[remap->num_remap].word= i;
- remap->remap[remap->num_remap++].index= ndx;
- break;
- }
- }
- if (!found) {
- fprintf(stderr,"Unknown component \"%s\" ignored\n",tok);
- }
- }
- if ((present&PART_MASK)==0) {
- unsigned mask= PART_MASK;
- ErrorF("Mapping needs at least one of ");
- for (i=0; (i<MAX_WORDS); i++) {
- if ((1L<<i)&mask) {
- mask&= ~(1L<<i);
- if (mask) DebugF("\"%s,\" ",cname[i]);
- else DebugF("or \"%s\"\n",cname[i]);
- }
- }
- DebugF("Illegal mapping ignored\n");
- remap->num_remap= 0;
- return;
- }
- if ((present&COMPONENT_MASK)==0) {
- DebugF("Mapping needs at least one component\n");
- DebugF("Illegal mapping ignored\n");
- remap->num_remap= 0;
- return;
- }
- remap->number++;
- return;
-}
-
-static Bool
-MatchOneOf(char *wanted,char *vals_defined)
-{
-char *str,*next;
-int want_len= strlen(wanted);
-
- for (str=vals_defined,next=NULL;str!=NULL;str=next) {
- int len;
- next= strchr(str,',');
- if (next) {
- len= next-str;
- next++;
- }
- else {
- len= strlen(str);
- }
- if ((len==want_len)&&(strncmp(wanted,str,len)==0))
- return TRUE;
- }
- return FALSE;
-}
-
-/***====================================================================***/
-
-static Bool
-CheckLine( InputLine * line,
- RemapSpec * remap,
- XkbRF_RulePtr rule,
- XkbRF_GroupPtr group)
-{
-char * str,*tok;
-register int nread, i;
-FileSpec tmp;
-_Xstrtokparams strtok_buf;
-Bool append = FALSE;
-
- if (line->line[0]=='!') {
- if (line->line[1] == '$' ||
- (line->line[1] == ' ' && line->line[2] == '$')) {
- char *gname = strchr(line->line, '$');
- char *words = strchr(gname, ' ');
- if(!words)
- return FALSE;
- *words++ = '\0';
- for (; *words; words++) {
- if (*words != '=' && *words != ' ')
- break;
- }
- if (*words == '\0')
- return FALSE;
- group->name = _XkbDupString(gname);
- group->words = _XkbDupString(words);
- for (i = 1, words = group->words; *words; words++) {
- if ( *words == ' ') {
- *words++ = '\0';
- i++;
- }
- }
- group->number = i;
- return TRUE;
- } else {
- SetUpRemap(line,remap);
- return FALSE;
- }
- }
-
- if (remap->num_remap==0) {
- DebugF("Must have a mapping before first line of data\n");
- DebugF("Illegal line of data ignored\n");
- return FALSE;
- }
- bzero((char *)&tmp,sizeof(FileSpec));
- str= line->line;
- for (nread= 0;(tok=_XStrtok(str," ",strtok_buf))!=NULL;nread++) {
- str= NULL;
- if (strcmp(tok,"=")==0) {
- nread--;
- continue;
- }
- if (nread>remap->num_remap) {
- DebugF("Too many words on a line\n");
- DebugF("Extra word \"%s\" ignored\n",tok);
- continue;
- }
- tmp.name[remap->remap[nread].word]= tok;
- if (*tok == '+' || *tok == '|')
- append = TRUE;
- }
- if (nread<remap->num_remap) {
- DebugF("Too few words on a line: %s\n", line->line);
- DebugF("line ignored\n");
- return FALSE;
- }
-
- rule->flags= 0;
- rule->number = remap->number;
- if (tmp.name[OPTION])
- rule->flags|= XkbRF_Option;
- else if (append)
- rule->flags|= XkbRF_Append;
- else
- rule->flags|= XkbRF_Normal;
- rule->model= _XkbDupString(tmp.name[MODEL]);
- rule->layout= _XkbDupString(tmp.name[LAYOUT]);
- rule->variant= _XkbDupString(tmp.name[VARIANT]);
- rule->option= _XkbDupString(tmp.name[OPTION]);
-
- rule->keycodes= _XkbDupString(tmp.name[KEYCODES]);
- rule->symbols= _XkbDupString(tmp.name[SYMBOLS]);
- rule->types= _XkbDupString(tmp.name[TYPES]);
- rule->compat= _XkbDupString(tmp.name[COMPAT]);
- rule->geometry= _XkbDupString(tmp.name[GEOMETRY]);
-
- rule->layout_num = rule->variant_num = 0;
- for (i = 0; i < nread; i++) {
- if (remap->remap[i].index) {
- if (remap->remap[i].word == LAYOUT)
- rule->layout_num = remap->remap[i].index;
- if (remap->remap[i].word == VARIANT)
- rule->variant_num = remap->remap[i].index;
- }
- }
- return TRUE;
-}
-
-static char *
-_Concat(char *str1,char *str2)
-{
-int len;
-
- if ((!str1)||(!str2))
- return str1;
- len= strlen(str1)+strlen(str2)+1;
- str1= xrealloc(str1,len * sizeof(char));
- if (str1)
- strcat(str1,str2);
- return str1;
-}
-
-static void
-squeeze_spaces(char *p1)
-{
- char *p2;
- for (p2 = p1; *p2; p2++) {
- *p1 = *p2;
- if (*p1 != ' ') p1++;
- }
- *p1 = '\0';
-}
-
-static Bool
-MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
-{
-
- bzero((char *)mdefs,sizeof(XkbRF_MultiDefsRec));
- mdefs->model = defs->model;
- mdefs->options = _XkbDupString(defs->options);
- if (mdefs->options) squeeze_spaces(mdefs->options);
-
- if (defs->layout) {
- if (!strchr(defs->layout, ',')) {
- mdefs->layout[0] = defs->layout;
- } else {
- char *p;
- int i;
- mdefs->layout[1] = _XkbDupString(defs->layout);
- if (mdefs->layout[1] == NULL)
- return FALSE;
- squeeze_spaces(mdefs->layout[1]);
- p = mdefs->layout[1];
- for (i = 2; i <= XkbNumKbdGroups; i++) {
- if ((p = strchr(p, ','))) {
- *p++ = '\0';
- mdefs->layout[i] = p;
- } else {
- break;
- }
- }
- if (p && (p = strchr(p, ',')))
- *p = '\0';
- }
- }
-
- if (defs->variant) {
- if (!strchr(defs->variant, ',')) {
- mdefs->variant[0] = defs->variant;
- } else {
- char *p;
- int i;
- mdefs->variant[1] = _XkbDupString(defs->variant);
- if (mdefs->variant[1] == NULL)
- return FALSE;
- squeeze_spaces(mdefs->variant[1]);
- p = mdefs->variant[1];
- for (i = 2; i <= XkbNumKbdGroups; i++) {
- if ((p = strchr(p, ','))) {
- *p++ = '\0';
- mdefs->variant[i] = p;
- } else {
- break;
- }
- }
- if (p && (p = strchr(p, ',')))
- *p = '\0';
- }
- }
- return TRUE;
-}
-
-static void
-FreeMultiDefs(XkbRF_MultiDefsPtr defs)
-{
- if (defs->options) xfree(defs->options);
- if (defs->layout[1]) xfree(defs->layout[1]);
- if (defs->variant[1]) xfree(defs->variant[1]);
-}
-
-static void
-Apply(char *src, char **dst)
-{
- if (src) {
- if (*src == '+' || *src == '!') {
- *dst= _Concat(*dst, src);
- } else {
- if (*dst == NULL)
- *dst= _XkbDupString(src);
- }
- }
-}
-
-static void
-XkbRF_ApplyRule( XkbRF_RulePtr rule,
- XkbComponentNamesPtr names)
-{
- rule->flags&= ~XkbRF_PendingMatch; /* clear the flag because it's applied */
-
- Apply(rule->keycodes, &names->keycodes);
- Apply(rule->symbols, &names->symbols);
- Apply(rule->types, &names->types);
- Apply(rule->compat, &names->compat);
- Apply(rule->geometry, &names->geometry);
-}
-
-static Bool
-CheckGroup( XkbRF_RulesPtr rules,
- char * group_name,
- char * name)
-{
- int i;
- char *p;
- XkbRF_GroupPtr group;
-
- for (i = 0, group = rules->groups; i < rules->num_groups; i++, group++) {
- if (! strcmp(group->name, group_name)) {
- break;
- }
- }
- if (i == rules->num_groups)
- return FALSE;
- for (i = 0, p = group->words; i < group->number; i++, p += strlen(p)+1) {
- if (! strcmp(p, name)) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static int
-XkbRF_CheckApplyRule( XkbRF_RulePtr rule,
- XkbRF_MultiDefsPtr mdefs,
- XkbComponentNamesPtr names,
- XkbRF_RulesPtr rules)
-{
- Bool pending = FALSE;
-
- if (rule->model != NULL) {
- if(mdefs->model == NULL)
- return 0;
- if (strcmp(rule->model, "*") == 0) {
- pending = TRUE;
- } else {
- if (rule->model[0] == '$') {
- if (!CheckGroup(rules, rule->model, mdefs->model))
- return 0;
- } else {
- if (strcmp(rule->model, mdefs->model) != 0)
- return 0;
- }
- }
- }
- if (rule->option != NULL) {
- if (mdefs->options == NULL)
- return 0;
- if ((!MatchOneOf(rule->option,mdefs->options)))
- return 0;
- }
-
- if (rule->layout != NULL) {
- if(mdefs->layout[rule->layout_num] == NULL ||
- *mdefs->layout[rule->layout_num] == '\0')
- return 0;
- if (strcmp(rule->layout, "*") == 0) {
- pending = TRUE;
- } else {
- if (rule->layout[0] == '$') {
- if (!CheckGroup(rules, rule->layout,
- mdefs->layout[rule->layout_num]))
- return 0;
- } else {
- if (strcmp(rule->layout, mdefs->layout[rule->layout_num]) != 0)
- return 0;
- }
- }
- }
- if (rule->variant != NULL) {
- if (mdefs->variant[rule->variant_num] == NULL ||
- *mdefs->variant[rule->variant_num] == '\0')
- return 0;
- if (strcmp(rule->variant, "*") == 0) {
- pending = TRUE;
- } else {
- if (rule->variant[0] == '$') {
- if (!CheckGroup(rules, rule->variant,
- mdefs->variant[rule->variant_num]))
- return 0;
- } else {
- if (strcmp(rule->variant,
- mdefs->variant[rule->variant_num]) != 0)
- return 0;
- }
- }
- }
- if (pending) {
- rule->flags|= XkbRF_PendingMatch;
- return rule->number;
- }
- /* exact match, apply it now */
- XkbRF_ApplyRule(rule,names);
- return rule->number;
-}
-
-static void
-XkbRF_ClearPartialMatches(XkbRF_RulesPtr rules)
-{
-register int i;
-XkbRF_RulePtr rule;
-
- for (i=0,rule=rules->rules;i<rules->num_rules;i++,rule++) {
- rule->flags&= ~XkbRF_PendingMatch;
- }
-}
-
-static void
-XkbRF_ApplyPartialMatches(XkbRF_RulesPtr rules,XkbComponentNamesPtr names)
-{
-int i;
-XkbRF_RulePtr rule;
-
- for (rule = rules->rules, i = 0; i < rules->num_rules; i++, rule++) {
- if ((rule->flags&XkbRF_PendingMatch)==0)
- continue;
- XkbRF_ApplyRule(rule,names);
- }
-}
-
-static void
-XkbRF_CheckApplyRules( XkbRF_RulesPtr rules,
- XkbRF_MultiDefsPtr mdefs,
- XkbComponentNamesPtr names,
- int flags)
-{
-int i;
-XkbRF_RulePtr rule;
-int skip;
-
- for (rule = rules->rules, i=0; i < rules->num_rules; rule++, i++) {
- if ((rule->flags & flags) != flags)
- continue;
- skip = XkbRF_CheckApplyRule(rule, mdefs, names, rules);
- if (skip && !(flags & XkbRF_Option)) {
- for ( ;(i < rules->num_rules) && (rule->number == skip);
- rule++, i++);
- rule--; i--;
- }
- }
-}
-
-/***====================================================================***/
-
-static char *
-XkbRF_SubstituteVars(char *name, XkbRF_MultiDefsPtr mdefs)
-{
-char *str, *outstr, *orig, *var;
-int len, ndx;
-
- orig= name;
- str= index(name,'%');
- if (str==NULL)
- return name;
- len= strlen(name);
- while (str!=NULL) {
- char pfx= str[1];
- int extra_len= 0;
- if ((pfx=='+')||(pfx=='|')||(pfx=='_')||(pfx=='-')) {
- extra_len= 1;
- str++;
- }
- else if (pfx=='(') {
- extra_len= 2;
- str++;
- }
- var = str + 1;
- str = get_index(var + 1, &ndx);
- if (ndx == -1) {
- str = index(str,'%');
- continue;
- }
- if ((*var=='l') && mdefs->layout[ndx] && *mdefs->layout[ndx])
- len+= strlen(mdefs->layout[ndx])+extra_len;
- else if ((*var=='m')&&mdefs->model)
- len+= strlen(mdefs->model)+extra_len;
- else if ((*var=='v') && mdefs->variant[ndx] && *mdefs->variant[ndx])
- len+= strlen(mdefs->variant[ndx])+extra_len;
- if ((pfx=='(')&&(*str==')')) {
- str++;
- }
- str= index(&str[0],'%');
- }
- name= xalloc(len+1);
- str= orig;
- outstr= name;
- while (*str!='\0') {
- if (str[0]=='%') {
- char pfx,sfx;
- str++;
- pfx= str[0];
- sfx= '\0';
- if ((pfx=='+')||(pfx=='|')||(pfx=='_')||(pfx=='-')) {
- str++;
- }
- else if (pfx=='(') {
- sfx= ')';
- str++;
- }
- else pfx= '\0';
-
- var = str;
- str = get_index(var + 1, &ndx);
- if (ndx == -1) {
- continue;
- }
- if ((*var=='l') && mdefs->layout[ndx] && *mdefs->layout[ndx]) {
- if (pfx) *outstr++= pfx;
- strcpy(outstr,mdefs->layout[ndx]);
- outstr+= strlen(mdefs->layout[ndx]);
- if (sfx) *outstr++= sfx;
- }
- else if ((*var=='m')&&(mdefs->model)) {
- if (pfx) *outstr++= pfx;
- strcpy(outstr,mdefs->model);
- outstr+= strlen(mdefs->model);
- if (sfx) *outstr++= sfx;
- }
- else if ((*var=='v') && mdefs->variant[ndx] && *mdefs->variant[ndx]) {
- if (pfx) *outstr++= pfx;
- strcpy(outstr,mdefs->variant[ndx]);
- outstr+= strlen(mdefs->variant[ndx]);
- if (sfx) *outstr++= sfx;
- }
- if ((pfx=='(')&&(*str==')'))
- str++;
- }
- else {
- *outstr++= *str++;
- }
- }
- *outstr++= '\0';
- if (orig!=name)
- xfree(orig);
- return name;
-}
-
-/***====================================================================***/
-
-Bool
-XkbRF_GetComponents( XkbRF_RulesPtr rules,
- XkbRF_VarDefsPtr defs,
- XkbComponentNamesPtr names)
-{
- XkbRF_MultiDefsRec mdefs;
-
- MakeMultiDefs(&mdefs, defs);
-
- bzero((char *)names,sizeof(XkbComponentNamesRec));
- XkbRF_ClearPartialMatches(rules);
- XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Normal);
- XkbRF_ApplyPartialMatches(rules, names);
- XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Append);
- XkbRF_ApplyPartialMatches(rules, names);
- XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Option);
-
- if (names->keycodes)
- names->keycodes= XkbRF_SubstituteVars(names->keycodes, &mdefs);
- if (names->symbols)
- names->symbols= XkbRF_SubstituteVars(names->symbols, &mdefs);
- if (names->types)
- names->types= XkbRF_SubstituteVars(names->types, &mdefs);
- if (names->compat)
- names->compat= XkbRF_SubstituteVars(names->compat, &mdefs);
- if (names->geometry)
- names->geometry= XkbRF_SubstituteVars(names->geometry, &mdefs);
-
- FreeMultiDefs(&mdefs);
- return (names->keycodes && names->symbols && names->types &&
- names->compat && names->geometry);
-}
-
-static XkbRF_RulePtr
-XkbRF_AddRule(XkbRF_RulesPtr rules)
-{
- if (rules->sz_rules<1) {
- rules->sz_rules= 16;
- rules->num_rules= 0;
- rules->rules= xcalloc(rules->sz_rules, sizeof(XkbRF_RuleRec));
- }
- else if (rules->num_rules>=rules->sz_rules) {
- rules->sz_rules*= 2;
- rules->rules= xrealloc(rules->rules,
- rules->sz_rules * sizeof(XkbRF_RuleRec));
- }
- if (!rules->rules) {
- rules->sz_rules= rules->num_rules= 0;
- DebugF("Allocation failure in XkbRF_AddRule\n");
- return NULL;
- }
- bzero((char *)&rules->rules[rules->num_rules],sizeof(XkbRF_RuleRec));
- return &rules->rules[rules->num_rules++];
-}
-
-static XkbRF_GroupPtr
-XkbRF_AddGroup(XkbRF_RulesPtr rules)
-{
- if (rules->sz_groups<1) {
- rules->sz_groups= 16;
- rules->num_groups= 0;
- rules->groups= xcalloc(rules->sz_groups, sizeof(XkbRF_GroupRec));
- }
- else if (rules->num_groups >= rules->sz_groups) {
- rules->sz_groups *= 2;
- rules->groups= xrealloc(rules->groups,
- rules->sz_groups * sizeof(XkbRF_GroupRec));
- }
- if (!rules->groups) {
- rules->sz_groups= rules->num_groups= 0;
- return NULL;
- }
-
- bzero((char *)&rules->groups[rules->num_groups],sizeof(XkbRF_GroupRec));
- return &rules->groups[rules->num_groups++];
-}
-
-Bool
-XkbRF_LoadRules(FILE *file, XkbRF_RulesPtr rules)
-{
-InputLine line;
-RemapSpec remap;
-XkbRF_RuleRec trule,*rule;
-XkbRF_GroupRec tgroup,*group;
-
- if (!(rules && file))
- return FALSE;
- bzero((char *)&remap,sizeof(RemapSpec));
- bzero((char *)&tgroup,sizeof(XkbRF_GroupRec));
- InitInputLine(&line);
- while (GetInputLine(file,&line,TRUE)) {
- if (CheckLine(&line,&remap,&trule,&tgroup)) {
- if (tgroup.number) {
- if ((group= XkbRF_AddGroup(rules))!=NULL) {
- *group= tgroup;
- bzero((char *)&tgroup,sizeof(XkbRF_GroupRec));
- }
- } else {
- if ((rule= XkbRF_AddRule(rules))!=NULL) {
- *rule= trule;
- bzero((char *)&trule,sizeof(XkbRF_RuleRec));
- }
- }
- }
- line.num_line= 0;
- }
- FreeInputLine(&line);
- return TRUE;
-}
-
-Bool
-XkbRF_LoadRulesByName(char *base,char *locale,XkbRF_RulesPtr rules)
-{
-FILE * file;
-char buf[PATH_MAX];
-Bool ok;
-
- if ((!base)||(!rules))
- return FALSE;
- if (locale) {
- if (strlen(base)+strlen(locale)+2 > PATH_MAX)
- return FALSE;
- sprintf(buf,"%s-%s", base, locale);
- }
- else {
- if (strlen(base)+1 > PATH_MAX)
- return FALSE;
- strcpy(buf,base);
- }
-
- file= fopen(buf, "r");
- if ((!file)&&(locale)) { /* fallback if locale was specified */
- strcpy(buf,base);
- file= fopen(buf, "r");
- }
- if (!file)
- return FALSE;
- ok= XkbRF_LoadRules(file,rules);
- fclose(file);
- return ok;
-}
-
-/***====================================================================***/
-
-XkbRF_RulesPtr
-XkbRF_Create(void)
-{
- return xcalloc(1, sizeof( XkbRF_RulesRec));
-}
-
-/***====================================================================***/
-
-void
-XkbRF_Free(XkbRF_RulesPtr rules,Bool freeRules)
-{
-int i;
-XkbRF_RulePtr rule;
-XkbRF_GroupPtr group;
-
- if (!rules)
- return;
- if (rules->rules) {
- for (i=0,rule=rules->rules;i<rules->num_rules;i++,rule++) {
- if (rule->model) xfree(rule->model);
- if (rule->layout) xfree(rule->layout);
- if (rule->variant) xfree(rule->variant);
- if (rule->option) xfree(rule->option);
- if (rule->keycodes) xfree(rule->keycodes);
- if (rule->symbols) xfree(rule->symbols);
- if (rule->types) xfree(rule->types);
- if (rule->compat) xfree(rule->compat);
- if (rule->geometry) xfree(rule->geometry);
- bzero((char *)rule,sizeof(XkbRF_RuleRec));
- }
- xfree(rules->rules);
- rules->num_rules= rules->sz_rules= 0;
- rules->rules= NULL;
- }
-
- if (rules->groups) {
- for (i=0, group=rules->groups;i<rules->num_groups;i++,group++) {
- if (group->name) xfree(group->name);
- if (group->words) xfree(group->words);
- }
- xfree(rules->groups);
- rules->num_groups= 0;
- rules->groups= NULL;
- }
- if (freeRules)
- xfree(rules);
- return;
-}
+/************************************************************
+ Copyright (c) 1996 by Silicon Graphics Computer Systems, Inc.
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation, and that the name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#define X_INCLUDE_STRING_H
+#define XOS_USE_NO_LOCKING
+#include <X11/Xos_r.h>
+
+#include <X11/Xproto.h>
+#include <X11/X.h>
+#include <X11/Xos.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "dix.h"
+#include "os.h"
+#include "xkbstr.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+
+/***====================================================================***/
+
+
+
+#define DFLT_LINE_SIZE 128
+
+typedef struct {
+ int line_num;
+ int sz_line;
+ int num_line;
+ char buf[DFLT_LINE_SIZE];
+ char * line;
+} InputLine;
+
+static void
+InitInputLine(InputLine *line)
+{
+ line->line_num= 1;
+ line->num_line= 0;
+ line->sz_line= DFLT_LINE_SIZE;
+ line->line= line->buf;
+ return;
+}
+
+static void
+FreeInputLine(InputLine *line)
+{
+ if (line->line!=line->buf)
+ free(line->line);
+ line->line_num= 1;
+ line->num_line= 0;
+ line->sz_line= DFLT_LINE_SIZE;
+ line->line= line->buf;
+ return;
+}
+
+static int
+InputLineAddChar(InputLine *line,int ch)
+{
+ if (line->num_line>=line->sz_line) {
+ if (line->line==line->buf) {
+ line->line= malloc(line->sz_line*2);
+ memcpy(line->line,line->buf,line->sz_line);
+ }
+ else {
+ line->line= realloc((char *)line->line,line->sz_line*2);
+ }
+ line->sz_line*= 2;
+ }
+ line->line[line->num_line++]= ch;
+ return ch;
+}
+
+#define ADD_CHAR(l,c) ((l)->num_line<(l)->sz_line?\
+ (int)((l)->line[(l)->num_line++]= (c)):\
+ InputLineAddChar(l,c))
+
+static Bool
+GetInputLine(FILE *file,InputLine *line,Bool checkbang)
+{
+int ch;
+Bool endOfFile,spacePending,slashPending,inComment;
+
+ endOfFile= FALSE;
+ while ((!endOfFile)&&(line->num_line==0)) {
+ spacePending= slashPending= inComment= FALSE;
+ while (((ch=getc(file))!='\n')&&(ch!=EOF)) {
+ if (ch=='\\') {
+ if ((ch=getc(file))==EOF)
+ break;
+ if (ch=='\n') {
+ inComment= FALSE;
+ ch= ' ';
+ line->line_num++;
+ }
+ }
+ if (inComment)
+ continue;
+ if (ch=='/') {
+ if (slashPending) {
+ inComment= TRUE;
+ slashPending= FALSE;
+ }
+ else {
+ slashPending= TRUE;
+ }
+ continue;
+ }
+ else if (slashPending) {
+ if (spacePending) {
+ ADD_CHAR(line,' ');
+ spacePending= FALSE;
+ }
+ ADD_CHAR(line,'/');
+ slashPending= FALSE;
+ }
+ if (isspace(ch)) {
+ while (isspace(ch)&&(ch!='\n')&&(ch!=EOF)) {
+ ch= getc(file);
+ }
+ if (ch==EOF)
+ break;
+ if ((ch!='\n')&&(line->num_line>0))
+ spacePending= TRUE;
+ ungetc(ch,file);
+ }
+ else {
+ if (spacePending) {
+ ADD_CHAR(line,' ');
+ spacePending= FALSE;
+ }
+ if (checkbang && ch=='!') {
+ if (line->num_line!=0) {
+ DebugF("The '!' legal only at start of line\n");
+ DebugF("Line containing '!' ignored\n");
+ line->num_line= 0;
+ inComment= 0;
+ break;
+ }
+
+ }
+ ADD_CHAR(line,ch);
+ }
+ }
+ if (ch==EOF)
+ endOfFile= TRUE;
+/* else line->num_line++;*/
+ }
+ if ((line->num_line==0)&&(endOfFile))
+ return FALSE;
+ ADD_CHAR(line,'\0');
+ return TRUE;
+}
+
+/***====================================================================***/
+
+#define MODEL 0
+#define LAYOUT 1
+#define VARIANT 2
+#define OPTION 3
+#define KEYCODES 4
+#define SYMBOLS 5
+#define TYPES 6
+#define COMPAT 7
+#define GEOMETRY 8
+#define MAX_WORDS 9
+
+#define PART_MASK 0x000F
+#define COMPONENT_MASK 0x03F0
+
+static char * cname[MAX_WORDS] = {
+ "model", "layout", "variant", "option",
+ "keycodes", "symbols", "types", "compat", "geometry"
+};
+
+typedef struct _RemapSpec {
+ int number;
+ int num_remap;
+ struct {
+ int word;
+ int index;
+ } remap[MAX_WORDS];
+} RemapSpec;
+
+typedef struct _FileSpec {
+ char * name[MAX_WORDS];
+ struct _FileSpec * pending;
+} FileSpec;
+
+typedef struct {
+ char * model;
+ char * layout[XkbNumKbdGroups+1];
+ char * variant[XkbNumKbdGroups+1];
+ char * options;
+} XkbRF_MultiDefsRec, *XkbRF_MultiDefsPtr;
+
+#define NDX_BUFF_SIZE 4
+
+/***====================================================================***/
+
+static char*
+get_index(char *str, int *ndx)
+{
+ char ndx_buf[NDX_BUFF_SIZE];
+ char *end;
+
+ if (*str != '[') {
+ *ndx = 0;
+ return str;
+ }
+ str++;
+ end = strchr(str, ']');
+ if (end == NULL) {
+ *ndx = -1;
+ return str - 1;
+ }
+ if ( (end - str) >= NDX_BUFF_SIZE) {
+ *ndx = -1;
+ return end + 1;
+ }
+ strncpy(ndx_buf, str, end - str);
+ ndx_buf[end - str] = '\0';
+ *ndx = atoi(ndx_buf);
+ return end + 1;
+}
+
+static void
+SetUpRemap(InputLine *line,RemapSpec *remap)
+{
+char * tok,*str;
+unsigned present, l_ndx_present, v_ndx_present;
+register int i;
+int len, ndx;
+_Xstrtokparams strtok_buf;
+Bool found;
+
+
+ l_ndx_present = v_ndx_present = present= 0;
+ str= &line->line[1];
+ len = remap->number;
+ bzero((char *)remap,sizeof(RemapSpec));
+ remap->number = len;
+ while ((tok=_XStrtok(str," ",strtok_buf))!=NULL) {
+ found= FALSE;
+ str= NULL;
+ if (strcmp(tok,"=")==0)
+ continue;
+ for (i=0;i<MAX_WORDS;i++) {
+ len = strlen(cname[i]);
+ if (strncmp(cname[i],tok,len)==0) {
+ if(strlen(tok) > len) {
+ char *end = get_index(tok+len, &ndx);
+ if ((i != LAYOUT && i != VARIANT) ||
+ *end != '\0' || ndx == -1)
+ break;
+ if (ndx < 1 || ndx > XkbNumKbdGroups) {
+ DebugF("Illegal %s index: %d\n", cname[i], ndx);
+ DebugF("Index must be in range 1..%d\n",
+ XkbNumKbdGroups);
+ break;
+ }
+ } else {
+ ndx = 0;
+ }
+ found= TRUE;
+ if (present&(1<<i)) {
+ if ((i == LAYOUT && l_ndx_present&(1<<ndx)) ||
+ (i == VARIANT && v_ndx_present&(1<<ndx)) ) {
+ DebugF("Component \"%s\" listed twice\n",tok);
+ DebugF("Second definition ignored\n");
+ break;
+ }
+ }
+ present |= (1<<i);
+ if (i == LAYOUT)
+ l_ndx_present |= 1 << ndx;
+ if (i == VARIANT)
+ v_ndx_present |= 1 << ndx;
+ remap->remap[remap->num_remap].word= i;
+ remap->remap[remap->num_remap++].index= ndx;
+ break;
+ }
+ }
+ if (!found) {
+ fprintf(stderr,"Unknown component \"%s\" ignored\n",tok);
+ }
+ }
+ if ((present&PART_MASK)==0) {
+ unsigned mask= PART_MASK;
+ ErrorF("Mapping needs at least one of ");
+ for (i=0; (i<MAX_WORDS); i++) {
+ if ((1L<<i)&mask) {
+ mask&= ~(1L<<i);
+ if (mask) DebugF("\"%s,\" ",cname[i]);
+ else DebugF("or \"%s\"\n",cname[i]);
+ }
+ }
+ DebugF("Illegal mapping ignored\n");
+ remap->num_remap= 0;
+ return;
+ }
+ if ((present&COMPONENT_MASK)==0) {
+ DebugF("Mapping needs at least one component\n");
+ DebugF("Illegal mapping ignored\n");
+ remap->num_remap= 0;
+ return;
+ }
+ remap->number++;
+ return;
+}
+
+static Bool
+MatchOneOf(char *wanted,char *vals_defined)
+{
+char *str,*next;
+int want_len= strlen(wanted);
+
+ for (str=vals_defined,next=NULL;str!=NULL;str=next) {
+ int len;
+ next= strchr(str,',');
+ if (next) {
+ len= next-str;
+ next++;
+ }
+ else {
+ len= strlen(str);
+ }
+ if ((len==want_len)&&(strncmp(wanted,str,len)==0))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/***====================================================================***/
+
+static Bool
+CheckLine( InputLine * line,
+ RemapSpec * remap,
+ XkbRF_RulePtr rule,
+ XkbRF_GroupPtr group)
+{
+char * str,*tok;
+register int nread, i;
+FileSpec tmp;
+_Xstrtokparams strtok_buf;
+Bool append = FALSE;
+
+ if (line->line[0]=='!') {
+ if (line->line[1] == '$' ||
+ (line->line[1] == ' ' && line->line[2] == '$')) {
+ char *gname = strchr(line->line, '$');
+ char *words = strchr(gname, ' ');
+ if(!words)
+ return FALSE;
+ *words++ = '\0';
+ for (; *words; words++) {
+ if (*words != '=' && *words != ' ')
+ break;
+ }
+ if (*words == '\0')
+ return FALSE;
+ group->name = _XkbDupString(gname);
+ group->words = _XkbDupString(words);
+ for (i = 1, words = group->words; *words; words++) {
+ if ( *words == ' ') {
+ *words++ = '\0';
+ i++;
+ }
+ }
+ group->number = i;
+ return TRUE;
+ } else {
+ SetUpRemap(line,remap);
+ return FALSE;
+ }
+ }
+
+ if (remap->num_remap==0) {
+ DebugF("Must have a mapping before first line of data\n");
+ DebugF("Illegal line of data ignored\n");
+ return FALSE;
+ }
+ bzero((char *)&tmp,sizeof(FileSpec));
+ str= line->line;
+ for (nread= 0;(tok=_XStrtok(str," ",strtok_buf))!=NULL;nread++) {
+ str= NULL;
+ if (strcmp(tok,"=")==0) {
+ nread--;
+ continue;
+ }
+ if (nread>remap->num_remap) {
+ DebugF("Too many words on a line\n");
+ DebugF("Extra word \"%s\" ignored\n",tok);
+ continue;
+ }
+ tmp.name[remap->remap[nread].word]= tok;
+ if (*tok == '+' || *tok == '|')
+ append = TRUE;
+ }
+ if (nread<remap->num_remap) {
+ DebugF("Too few words on a line: %s\n", line->line);
+ DebugF("line ignored\n");
+ return FALSE;
+ }
+
+ rule->flags= 0;
+ rule->number = remap->number;
+ if (tmp.name[OPTION])
+ rule->flags|= XkbRF_Option;
+ else if (append)
+ rule->flags|= XkbRF_Append;
+ else
+ rule->flags|= XkbRF_Normal;
+ rule->model= _XkbDupString(tmp.name[MODEL]);
+ rule->layout= _XkbDupString(tmp.name[LAYOUT]);
+ rule->variant= _XkbDupString(tmp.name[VARIANT]);
+ rule->option= _XkbDupString(tmp.name[OPTION]);
+
+ rule->keycodes= _XkbDupString(tmp.name[KEYCODES]);
+ rule->symbols= _XkbDupString(tmp.name[SYMBOLS]);
+ rule->types= _XkbDupString(tmp.name[TYPES]);
+ rule->compat= _XkbDupString(tmp.name[COMPAT]);
+ rule->geometry= _XkbDupString(tmp.name[GEOMETRY]);
+
+ rule->layout_num = rule->variant_num = 0;
+ for (i = 0; i < nread; i++) {
+ if (remap->remap[i].index) {
+ if (remap->remap[i].word == LAYOUT)
+ rule->layout_num = remap->remap[i].index;
+ if (remap->remap[i].word == VARIANT)
+ rule->variant_num = remap->remap[i].index;
+ }
+ }
+ return TRUE;
+}
+
+static char *
+_Concat(char *str1,char *str2)
+{
+int len;
+
+ if ((!str1)||(!str2))
+ return str1;
+ len= strlen(str1)+strlen(str2)+1;
+ str1= realloc(str1,len * sizeof(char));
+ if (str1)
+ strcat(str1,str2);
+ return str1;
+}
+
+static void
+squeeze_spaces(char *p1)
+{
+ char *p2;
+ for (p2 = p1; *p2; p2++) {
+ *p1 = *p2;
+ if (*p1 != ' ') p1++;
+ }
+ *p1 = '\0';
+}
+
+static Bool
+MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
+{
+
+ bzero((char *)mdefs,sizeof(XkbRF_MultiDefsRec));
+ mdefs->model = defs->model;
+ mdefs->options = _XkbDupString(defs->options);
+ if (mdefs->options) squeeze_spaces(mdefs->options);
+
+ if (defs->layout) {
+ if (!strchr(defs->layout, ',')) {
+ mdefs->layout[0] = defs->layout;
+ } else {
+ char *p;
+ int i;
+ mdefs->layout[1] = _XkbDupString(defs->layout);
+ if (mdefs->layout[1] == NULL)
+ return FALSE;
+ squeeze_spaces(mdefs->layout[1]);
+ p = mdefs->layout[1];
+ for (i = 2; i <= XkbNumKbdGroups; i++) {
+ if ((p = strchr(p, ','))) {
+ *p++ = '\0';
+ mdefs->layout[i] = p;
+ } else {
+ break;
+ }
+ }
+ if (p && (p = strchr(p, ',')))
+ *p = '\0';
+ }
+ }
+
+ if (defs->variant) {
+ if (!strchr(defs->variant, ',')) {
+ mdefs->variant[0] = defs->variant;
+ } else {
+ char *p;
+ int i;
+ mdefs->variant[1] = _XkbDupString(defs->variant);
+ if (mdefs->variant[1] == NULL)
+ return FALSE;
+ squeeze_spaces(mdefs->variant[1]);
+ p = mdefs->variant[1];
+ for (i = 2; i <= XkbNumKbdGroups; i++) {
+ if ((p = strchr(p, ','))) {
+ *p++ = '\0';
+ mdefs->variant[i] = p;
+ } else {
+ break;
+ }
+ }
+ if (p && (p = strchr(p, ',')))
+ *p = '\0';
+ }
+ }
+ return TRUE;
+}
+
+static void
+FreeMultiDefs(XkbRF_MultiDefsPtr defs)
+{
+ if (defs->options) free(defs->options);
+ if (defs->layout[1]) free(defs->layout[1]);
+ if (defs->variant[1]) free(defs->variant[1]);
+}
+
+static void
+Apply(char *src, char **dst)
+{
+ if (src) {
+ if (*src == '+' || *src == '!') {
+ *dst= _Concat(*dst, src);
+ } else {
+ if (*dst == NULL)
+ *dst= _XkbDupString(src);
+ }
+ }
+}
+
+static void
+XkbRF_ApplyRule( XkbRF_RulePtr rule,
+ XkbComponentNamesPtr names)
+{
+ rule->flags&= ~XkbRF_PendingMatch; /* clear the flag because it's applied */
+
+ Apply(rule->keycodes, &names->keycodes);
+ Apply(rule->symbols, &names->symbols);
+ Apply(rule->types, &names->types);
+ Apply(rule->compat, &names->compat);
+ Apply(rule->geometry, &names->geometry);
+}
+
+static Bool
+CheckGroup( XkbRF_RulesPtr rules,
+ char * group_name,
+ char * name)
+{
+ int i;
+ char *p;
+ XkbRF_GroupPtr group;
+
+ for (i = 0, group = rules->groups; i < rules->num_groups; i++, group++) {
+ if (! strcmp(group->name, group_name)) {
+ break;
+ }
+ }
+ if (i == rules->num_groups)
+ return FALSE;
+ for (i = 0, p = group->words; i < group->number; i++, p += strlen(p)+1) {
+ if (! strcmp(p, name)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static int
+XkbRF_CheckApplyRule( XkbRF_RulePtr rule,
+ XkbRF_MultiDefsPtr mdefs,
+ XkbComponentNamesPtr names,
+ XkbRF_RulesPtr rules)
+{
+ Bool pending = FALSE;
+
+ if (rule->model != NULL) {
+ if(mdefs->model == NULL)
+ return 0;
+ if (strcmp(rule->model, "*") == 0) {
+ pending = TRUE;
+ } else {
+ if (rule->model[0] == '$') {
+ if (!CheckGroup(rules, rule->model, mdefs->model))
+ return 0;
+ } else {
+ if (strcmp(rule->model, mdefs->model) != 0)
+ return 0;
+ }
+ }
+ }
+ if (rule->option != NULL) {
+ if (mdefs->options == NULL)
+ return 0;
+ if ((!MatchOneOf(rule->option,mdefs->options)))
+ return 0;
+ }
+
+ if (rule->layout != NULL) {
+ if(mdefs->layout[rule->layout_num] == NULL ||
+ *mdefs->layout[rule->layout_num] == '\0')
+ return 0;
+ if (strcmp(rule->layout, "*") == 0) {
+ pending = TRUE;
+ } else {
+ if (rule->layout[0] == '$') {
+ if (!CheckGroup(rules, rule->layout,
+ mdefs->layout[rule->layout_num]))
+ return 0;
+ } else {
+ if (strcmp(rule->layout, mdefs->layout[rule->layout_num]) != 0)
+ return 0;
+ }
+ }
+ }
+ if (rule->variant != NULL) {
+ if (mdefs->variant[rule->variant_num] == NULL ||
+ *mdefs->variant[rule->variant_num] == '\0')
+ return 0;
+ if (strcmp(rule->variant, "*") == 0) {
+ pending = TRUE;
+ } else {
+ if (rule->variant[0] == '$') {
+ if (!CheckGroup(rules, rule->variant,
+ mdefs->variant[rule->variant_num]))
+ return 0;
+ } else {
+ if (strcmp(rule->variant,
+ mdefs->variant[rule->variant_num]) != 0)
+ return 0;
+ }
+ }
+ }
+ if (pending) {
+ rule->flags|= XkbRF_PendingMatch;
+ return rule->number;
+ }
+ /* exact match, apply it now */
+ XkbRF_ApplyRule(rule,names);
+ return rule->number;
+}
+
+static void
+XkbRF_ClearPartialMatches(XkbRF_RulesPtr rules)
+{
+register int i;
+XkbRF_RulePtr rule;
+
+ for (i=0,rule=rules->rules;i<rules->num_rules;i++,rule++) {
+ rule->flags&= ~XkbRF_PendingMatch;
+ }
+}
+
+static void
+XkbRF_ApplyPartialMatches(XkbRF_RulesPtr rules,XkbComponentNamesPtr names)
+{
+int i;
+XkbRF_RulePtr rule;
+
+ for (rule = rules->rules, i = 0; i < rules->num_rules; i++, rule++) {
+ if ((rule->flags&XkbRF_PendingMatch)==0)
+ continue;
+ XkbRF_ApplyRule(rule,names);
+ }
+}
+
+static void
+XkbRF_CheckApplyRules( XkbRF_RulesPtr rules,
+ XkbRF_MultiDefsPtr mdefs,
+ XkbComponentNamesPtr names,
+ int flags)
+{
+int i;
+XkbRF_RulePtr rule;
+int skip;
+
+ for (rule = rules->rules, i=0; i < rules->num_rules; rule++, i++) {
+ if ((rule->flags & flags) != flags)
+ continue;
+ skip = XkbRF_CheckApplyRule(rule, mdefs, names, rules);
+ if (skip && !(flags & XkbRF_Option)) {
+ for ( ;(i < rules->num_rules) && (rule->number == skip);
+ rule++, i++);
+ rule--; i--;
+ }
+ }
+}
+
+/***====================================================================***/
+
+static char *
+XkbRF_SubstituteVars(char *name, XkbRF_MultiDefsPtr mdefs)
+{
+char *str, *outstr, *orig, *var;
+int len, ndx;
+
+ orig= name;
+ str= index(name,'%');
+ if (str==NULL)
+ return name;
+ len= strlen(name);
+ while (str!=NULL) {
+ char pfx= str[1];
+ int extra_len= 0;
+ if ((pfx=='+')||(pfx=='|')||(pfx=='_')||(pfx=='-')) {
+ extra_len= 1;
+ str++;
+ }
+ else if (pfx=='(') {
+ extra_len= 2;
+ str++;
+ }
+ var = str + 1;
+ str = get_index(var + 1, &ndx);
+ if (ndx == -1) {
+ str = index(str,'%');
+ continue;
+ }
+ if ((*var=='l') && mdefs->layout[ndx] && *mdefs->layout[ndx])
+ len+= strlen(mdefs->layout[ndx])+extra_len;
+ else if ((*var=='m')&&mdefs->model)
+ len+= strlen(mdefs->model)+extra_len;
+ else if ((*var=='v') && mdefs->variant[ndx] && *mdefs->variant[ndx])
+ len+= strlen(mdefs->variant[ndx])+extra_len;
+ if ((pfx=='(')&&(*str==')')) {
+ str++;
+ }
+ str= index(&str[0],'%');
+ }
+ name= malloc(len+1);
+ str= orig;
+ outstr= name;
+ while (*str!='\0') {
+ if (str[0]=='%') {
+ char pfx,sfx;
+ str++;
+ pfx= str[0];
+ sfx= '\0';
+ if ((pfx=='+')||(pfx=='|')||(pfx=='_')||(pfx=='-')) {
+ str++;
+ }
+ else if (pfx=='(') {
+ sfx= ')';
+ str++;
+ }
+ else pfx= '\0';
+
+ var = str;
+ str = get_index(var + 1, &ndx);
+ if (ndx == -1) {
+ continue;
+ }
+ if ((*var=='l') && mdefs->layout[ndx] && *mdefs->layout[ndx]) {
+ if (pfx) *outstr++= pfx;
+ strcpy(outstr,mdefs->layout[ndx]);
+ outstr+= strlen(mdefs->layout[ndx]);
+ if (sfx) *outstr++= sfx;
+ }
+ else if ((*var=='m')&&(mdefs->model)) {
+ if (pfx) *outstr++= pfx;
+ strcpy(outstr,mdefs->model);
+ outstr+= strlen(mdefs->model);
+ if (sfx) *outstr++= sfx;
+ }
+ else if ((*var=='v') && mdefs->variant[ndx] && *mdefs->variant[ndx]) {
+ if (pfx) *outstr++= pfx;
+ strcpy(outstr,mdefs->variant[ndx]);
+ outstr+= strlen(mdefs->variant[ndx]);
+ if (sfx) *outstr++= sfx;
+ }
+ if ((pfx=='(')&&(*str==')'))
+ str++;
+ }
+ else {
+ *outstr++= *str++;
+ }
+ }
+ *outstr++= '\0';
+ if (orig!=name)
+ free(orig);
+ return name;
+}
+
+/***====================================================================***/
+
+Bool
+XkbRF_GetComponents( XkbRF_RulesPtr rules,
+ XkbRF_VarDefsPtr defs,
+ XkbComponentNamesPtr names)
+{
+ XkbRF_MultiDefsRec mdefs;
+
+ MakeMultiDefs(&mdefs, defs);
+
+ bzero((char *)names,sizeof(XkbComponentNamesRec));
+ XkbRF_ClearPartialMatches(rules);
+ XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Normal);
+ XkbRF_ApplyPartialMatches(rules, names);
+ XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Append);
+ XkbRF_ApplyPartialMatches(rules, names);
+ XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Option);
+
+ if (names->keycodes)
+ names->keycodes= XkbRF_SubstituteVars(names->keycodes, &mdefs);
+ if (names->symbols)
+ names->symbols= XkbRF_SubstituteVars(names->symbols, &mdefs);
+ if (names->types)
+ names->types= XkbRF_SubstituteVars(names->types, &mdefs);
+ if (names->compat)
+ names->compat= XkbRF_SubstituteVars(names->compat, &mdefs);
+ if (names->geometry)
+ names->geometry= XkbRF_SubstituteVars(names->geometry, &mdefs);
+
+ FreeMultiDefs(&mdefs);
+ return (names->keycodes && names->symbols && names->types &&
+ names->compat && names->geometry);
+}
+
+static XkbRF_RulePtr
+XkbRF_AddRule(XkbRF_RulesPtr rules)
+{
+ if (rules->sz_rules<1) {
+ rules->sz_rules= 16;
+ rules->num_rules= 0;
+ rules->rules= calloc(rules->sz_rules, sizeof(XkbRF_RuleRec));
+ }
+ else if (rules->num_rules>=rules->sz_rules) {
+ rules->sz_rules*= 2;
+ rules->rules= realloc(rules->rules,
+ rules->sz_rules * sizeof(XkbRF_RuleRec));
+ }
+ if (!rules->rules) {
+ rules->sz_rules= rules->num_rules= 0;
+ DebugF("Allocation failure in XkbRF_AddRule\n");
+ return NULL;
+ }
+ bzero((char *)&rules->rules[rules->num_rules],sizeof(XkbRF_RuleRec));
+ return &rules->rules[rules->num_rules++];
+}
+
+static XkbRF_GroupPtr
+XkbRF_AddGroup(XkbRF_RulesPtr rules)
+{
+ if (rules->sz_groups<1) {
+ rules->sz_groups= 16;
+ rules->num_groups= 0;
+ rules->groups= calloc(rules->sz_groups, sizeof(XkbRF_GroupRec));
+ }
+ else if (rules->num_groups >= rules->sz_groups) {
+ rules->sz_groups *= 2;
+ rules->groups= realloc(rules->groups,
+ rules->sz_groups * sizeof(XkbRF_GroupRec));
+ }
+ if (!rules->groups) {
+ rules->sz_groups= rules->num_groups= 0;
+ return NULL;
+ }
+
+ bzero((char *)&rules->groups[rules->num_groups],sizeof(XkbRF_GroupRec));
+ return &rules->groups[rules->num_groups++];
+}
+
+Bool
+XkbRF_LoadRules(FILE *file, XkbRF_RulesPtr rules)
+{
+InputLine line;
+RemapSpec remap;
+XkbRF_RuleRec trule,*rule;
+XkbRF_GroupRec tgroup,*group;
+
+ if (!(rules && file))
+ return FALSE;
+ bzero((char *)&remap,sizeof(RemapSpec));
+ bzero((char *)&tgroup,sizeof(XkbRF_GroupRec));
+ InitInputLine(&line);
+ while (GetInputLine(file,&line,TRUE)) {
+ if (CheckLine(&line,&remap,&trule,&tgroup)) {
+ if (tgroup.number) {
+ if ((group= XkbRF_AddGroup(rules))!=NULL) {
+ *group= tgroup;
+ bzero((char *)&tgroup,sizeof(XkbRF_GroupRec));
+ }
+ } else {
+ if ((rule= XkbRF_AddRule(rules))!=NULL) {
+ *rule= trule;
+ bzero((char *)&trule,sizeof(XkbRF_RuleRec));
+ }
+ }
+ }
+ line.num_line= 0;
+ }
+ FreeInputLine(&line);
+ return TRUE;
+}
+
+Bool
+XkbRF_LoadRulesByName(char *base,char *locale,XkbRF_RulesPtr rules)
+{
+FILE * file;
+char buf[PATH_MAX];
+Bool ok;
+
+ if ((!base)||(!rules))
+ return FALSE;
+ if (locale) {
+ if (strlen(base)+strlen(locale)+2 > PATH_MAX)
+ return FALSE;
+ sprintf(buf,"%s-%s", base, locale);
+ }
+ else {
+ if (strlen(base)+1 > PATH_MAX)
+ return FALSE;
+ strcpy(buf,base);
+ }
+
+ file= fopen(buf, "r");
+ if ((!file)&&(locale)) { /* fallback if locale was specified */
+ strcpy(buf,base);
+ file= fopen(buf, "r");
+ }
+ if (!file)
+ return FALSE;
+ ok= XkbRF_LoadRules(file,rules);
+ fclose(file);
+ return ok;
+}
+
+/***====================================================================***/
+
+XkbRF_RulesPtr
+XkbRF_Create(void)
+{
+ return calloc(1, sizeof( XkbRF_RulesRec));
+}
+
+/***====================================================================***/
+
+void
+XkbRF_Free(XkbRF_RulesPtr rules,Bool freeRules)
+{
+int i;
+XkbRF_RulePtr rule;
+XkbRF_GroupPtr group;
+
+ if (!rules)
+ return;
+ if (rules->rules) {
+ for (i=0,rule=rules->rules;i<rules->num_rules;i++,rule++) {
+ if (rule->model) free(rule->model);
+ if (rule->layout) free(rule->layout);
+ if (rule->variant) free(rule->variant);
+ if (rule->option) free(rule->option);
+ if (rule->keycodes) free(rule->keycodes);
+ if (rule->symbols) free(rule->symbols);
+ if (rule->types) free(rule->types);
+ if (rule->compat) free(rule->compat);
+ if (rule->geometry) free(rule->geometry);
+ bzero((char *)rule,sizeof(XkbRF_RuleRec));
+ }
+ free(rules->rules);
+ rules->num_rules= rules->sz_rules= 0;
+ rules->rules= NULL;
+ }
+
+ if (rules->groups) {
+ for (i=0, group=rules->groups;i<rules->num_groups;i++,group++) {
+ if (group->name) free(group->name);
+ if (group->words) free(group->words);
+ }
+ free(rules->groups);
+ rules->num_groups= 0;
+ rules->groups= NULL;
+ }
+ if (freeRules)
+ free(rules);
+ return;
+}
diff --git a/xorg-server/xkb/xkb.c b/xorg-server/xkb/xkb.c
index 666d50f8e..3c337b63e 100644
--- a/xorg-server/xkb/xkb.c
+++ b/xorg-server/xkb/xkb.c
@@ -194,7 +194,7 @@ ProcXkbUseExtension(ClientPtr client)
swaps(&rep.serverMinor, n);
}
WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep);
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -219,7 +219,7 @@ ProcXkbSelectEvents(ClientPtr client)
client->mapNotifyMask|= (stuff->affectMap&stuff->map);
}
if ((stuff->affectWhich&(~XkbMapNotifyMask))==0)
- return client->noClientException;
+ return Success;
masks = XkbFindClientResource((DevicePtr)dev,client);
if (!masks){
@@ -343,7 +343,7 @@ ProcXkbSelectEvents(ClientPtr client)
ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",dataLeft);
return BadLength;
}
- return client->noClientException;
+ return Success;
}
return BadAlloc;
}
@@ -578,7 +578,7 @@ ProcXkbGetState(ClientPtr client)
swaps(&rep.ptrBtnState,n);
}
WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep);
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -646,7 +646,7 @@ ProcXkbLatchLockState(ClientPtr client)
}
}
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -722,7 +722,7 @@ ProcXkbGetControls(ClientPtr client)
swaps(&rep.axOptions, n);
}
WriteToClient(client, SIZEOF(xkbGetControlsReply), (char *)&rep);
- return(client->noClientException);
+ return Success;
}
int
@@ -942,7 +942,7 @@ ProcXkbSetControls(ClientPtr client)
}
}
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -1365,7 +1365,7 @@ unsigned i,len;
char *desc,*start;
len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply));
- start= desc= xcalloc(1, len);
+ start= desc= calloc(1, len);
if (!start)
return BadAlloc;
if ( rep->nTypes>0 )
@@ -1405,8 +1405,8 @@ char *desc,*start;
}
WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep);
WriteToClient(client, len, start);
- xfree((char *)start);
- return client->noClientException;
+ free((char *)start);
+ return Success;
}
int
@@ -2186,8 +2186,8 @@ unsigned first,last;
if (maxRG>(int)xkbi->nRadioGroups) {
int sz = maxRG*sizeof(XkbRadioGroupRec);
if (xkbi->radioGroups)
- xkbi->radioGroups= xrealloc(xkbi->radioGroups,sz);
- else xkbi->radioGroups= xcalloc(1, sz);
+ xkbi->radioGroups= realloc(xkbi->radioGroups,sz);
+ else xkbi->radioGroups= calloc(1, sz);
if (xkbi->radioGroups) {
if (xkbi->nRadioGroups)
bzero(&xkbi->radioGroups[xkbi->nRadioGroups],
@@ -2594,7 +2594,7 @@ ProcXkbSetMap(ClientPtr client)
}
}
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -2629,7 +2629,7 @@ int size;
size= rep->length*4;
if (size>0) {
- data = xalloc(size);
+ data = malloc(size);
if (data) {
register unsigned i,bit;
xkbModsWireDesc * grp;
@@ -2680,9 +2680,9 @@ int size;
WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep);
if (data) {
WriteToClient(client, size, data);
- xfree((char *)data);
+ free((char *)data);
}
- return client->noClientException;
+ return Success;
}
int
@@ -2777,7 +2777,7 @@ _XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
XkbSymInterpretPtr sym;
if ((unsigned)(req->firstSI+req->nSI)>compat->num_si) {
compat->num_si= req->firstSI+req->nSI;
- compat->sym_interpret= xrealloc(compat->sym_interpret,
+ compat->sym_interpret= realloc(compat->sym_interpret,
compat->num_si * sizeof(XkbSymInterpretRec));
if (!compat->sym_interpret) {
compat->num_si= 0;
@@ -2923,7 +2923,7 @@ ProcXkbSetCompatMap(ClientPtr client)
}
}
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -2960,7 +2960,7 @@ ProcXkbGetIndicatorState(ClientPtr client)
swapl(&rep.state,i);
}
WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), (char *)&rep);
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -2995,7 +2995,7 @@ register unsigned bit;
length = rep->length*4;
if (length>0) {
CARD8 *to;
- to= map= xalloc(length);
+ to= map= malloc(length);
if (map) {
xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to;
for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
@@ -3034,9 +3034,9 @@ register unsigned bit;
WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), (char *)rep);
if (map) {
WriteToClient(client, length, (char *)map);
- xfree((char *)map);
+ free((char *)map);
}
- return client->noClientException;
+ return Success;
}
int
@@ -3130,7 +3130,7 @@ ProcXkbSetIndicatorMap(ClientPtr client)
CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
if (stuff->which==0)
- return client->noClientException;
+ return Success;
for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
if (stuff->which&bit)
@@ -3257,7 +3257,7 @@ ProcXkbGetNamedIndicator(ClientPtr client)
}
WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), (char *)&rep);
- return client->noClientException;
+ return Success;
}
@@ -3467,7 +3467,7 @@ ProcXkbSetNamedIndicator(ClientPtr client)
}
}
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -3632,7 +3632,7 @@ register int n;
swapl(&rep->indicators,n);
}
- start = desc = xalloc(length);
+ start = desc = malloc(length);
if ( !start )
return BadAlloc;
if (xkb->names) {
@@ -3756,8 +3756,8 @@ register int n;
}
WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep);
WriteToClient(client, length, start);
- xfree((char *)start);
- return client->noClientException;
+ free((char *)start);
+ return Success;
}
int
@@ -4118,7 +4118,7 @@ _XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff)
tmp+= stuff->nKeyAliases*2;
}
else if (names->key_aliases!=NULL) {
- xfree(names->key_aliases);
+ free(names->key_aliases);
names->key_aliases= NULL;
names->num_key_aliases= 0;
}
@@ -4137,7 +4137,7 @@ _XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff)
tmp+= stuff->nRadioGroups;
}
else if (names->radio_groups) {
- xfree(names->radio_groups);
+ free(names->radio_groups);
names->radio_groups= NULL;
names->num_rg= 0;
}
@@ -4286,7 +4286,7 @@ ProcXkbSetNames(ClientPtr client)
/* everything is okay -- update names */
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -4740,7 +4740,7 @@ XkbSendGeometry( ClientPtr client,
if (geom!=NULL) {
len= rep->length*4;
- start= desc= xalloc(len);
+ start= desc= malloc(len);
if (!start)
return BadAlloc;
desc= XkbWriteCountedString(desc,geom->label_font,client->swapped);
@@ -4784,10 +4784,10 @@ XkbSendGeometry( ClientPtr client,
if (len>0)
WriteToClient(client, len, start);
if (start!=NULL)
- xfree((char *)start);
+ free((char *)start);
if (freeGeom)
XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
- return client->noClientException;
+ return Success;
}
int
@@ -4834,7 +4834,7 @@ CARD16 len,*plen;
swaps(plen,n);
}
len= *plen;
- str= xalloc(len+1);
+ str= malloc(len+1);
if (str) {
memcpy(str,&wire[2],len);
str[len]= '\0';
@@ -5182,16 +5182,16 @@ char * wire;
return BadAlloc;
val= _GetCountedString(&wire,client->swapped);
if (!val) {
- xfree(name);
+ free(name);
return BadAlloc;
}
if (XkbAddGeomProperty(geom,name,val)==NULL) {
- xfree(name);
- xfree(val);
+ free(name);
+ free(val);
return BadAlloc;
}
- xfree(name);
- xfree(val);
+ free(name);
+ free(val);
}
if (req->nColors<2) {
@@ -5218,10 +5218,10 @@ char * wire;
if (!name)
return BadAlloc;
if (!XkbAddGeomColor(geom,name,geom->num_colors)) {
- xfree(name);
+ free(name);
return BadAlloc;
}
- xfree(name);
+ free(name);
}
if (req->nColors!=geom->num_colors) {
client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors);
@@ -5414,7 +5414,7 @@ ProcXkbPerClientFlags(ClientPtr client)
swapl(&rep.autoCtrlValues,n);
}
WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep);
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -5449,7 +5449,7 @@ unsigned char *wire,*str,*tmp,*legal;
wire= *pWire;
len= (*(unsigned char *)wire++);
if (len>0) {
- str= xcalloc(1, len+1);
+ str= calloc(1, len+1);
if (str) {
tmp= str;
for (i=0;i<len;i++) {
@@ -5460,7 +5460,7 @@ unsigned char *wire,*str,*tmp,*legal;
if (tmp!=str)
*tmp++= '\0';
else {
- xfree(str);
+ free(str);
str= NULL;
}
}
@@ -5511,7 +5511,7 @@ ProcXkbListComponents(ClientPtr client)
return BadLength;
if ((status=XkbDDXList(dev,&list,client))!=Success) {
if (list.pool) {
- xfree(list.pool);
+ free(list.pool);
list.pool= NULL;
}
return status;
@@ -5545,10 +5545,10 @@ ProcXkbListComponents(ClientPtr client)
WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep);
if (list.nPool && list.pool) {
WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool);
- xfree(list.pool);
+ free(list.pool);
list.pool= NULL;
}
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -5888,12 +5888,12 @@ ProcXkbGetKbdByName(ClientPtr client)
XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE);
new= NULL;
}
- if (names.keycodes) { xfree(names.keycodes); names.keycodes= NULL; }
- if (names.types) { xfree(names.types); names.types= NULL; }
- if (names.compat) { xfree(names.compat); names.compat= NULL; }
- if (names.symbols) { xfree(names.symbols); names.symbols= NULL; }
- if (names.geometry) { xfree(names.geometry); names.geometry= NULL; }
- return client->noClientException;
+ if (names.keycodes) { free(names.keycodes); names.keycodes= NULL; }
+ if (names.types) { free(names.types); names.types= NULL; }
+ if (names.compat) { free(names.compat); names.compat= NULL; }
+ if (names.symbols) { free(names.symbols); names.symbols= NULL; }
+ if (names.geometry) { free(names.geometry); names.geometry= NULL; }
+ return Success;
}
/***====================================================================***/
@@ -6207,12 +6207,12 @@ char * str;
}
WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep);
- str= xalloc(nameLen);
+ str= malloc(nameLen);
if (!str)
return BadAlloc;
XkbWriteCountedString(str,dev->name,client->swapped);
WriteToClient(client,nameLen,str);
- xfree(str);
+ free(str);
length-= nameLen;
if (rep.nBtnsRtrn>0) {
@@ -6233,7 +6233,7 @@ char * str;
ErrorF("[xkb] Wrote %d fewer bytes than expected\n",length);
return BadLength;
}
- return client->noClientException;
+ return Success;
}
static char *
@@ -6461,7 +6461,7 @@ _XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
nBtns= dev->button->numButtons;
acts= dev->button->xkb_acts;
if (acts==NULL) {
- acts= xcalloc(nBtns, sizeof(XkbAction));
+ acts= calloc(nBtns, sizeof(XkbAction));
if (!acts)
return BadAlloc;
dev->button->xkb_acts= acts;
@@ -6558,7 +6558,7 @@ ProcXkbSetDeviceInfo(ClientPtr client)
}
}
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
@@ -6621,7 +6621,7 @@ int rc;
swapl(&rep.supportedCtrls, n);
}
WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep);
- return client->noClientException;
+ return Success;
}
/***====================================================================***/
diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c
index 766466296..03f23a777 100644
--- a/xorg-server/xkb/xkbActions.c
+++ b/xorg-server/xkb/xkbActions.c
@@ -70,7 +70,7 @@ XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
{
xkbDeviceInfoPtr xkbPrivPtr;
- xkbPrivPtr = (xkbDeviceInfoPtr) xcalloc(1, sizeof(xkbDeviceInfoRec));
+ xkbPrivPtr = (xkbDeviceInfoPtr) calloc(1, sizeof(xkbDeviceInfoRec));
if (!xkbPrivPtr)
return;
xkbPrivPtr->unwrapProc = NULL;
@@ -1020,7 +1020,7 @@ register int i;
if (xkbi->szFilters==0) {
xkbi->szFilters = 4;
- xkbi->filters = xcalloc(xkbi->szFilters, sizeof(XkbFilterRec));
+ xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
/* 6/21/93 (ef) -- XXX! deal with allocation failure */
}
for (i=0;i<xkbi->szFilters;i++) {
@@ -1030,7 +1030,7 @@ register int i;
}
}
xkbi->szFilters*=2;
- xkbi->filters= xrealloc(xkbi->filters,
+ xkbi->filters= realloc(xkbi->filters,
xkbi->szFilters * sizeof(XkbFilterRec));
/* 6/21/93 (ef) -- XXX! deal with allocation failure */
bzero(&xkbi->filters[xkbi->szFilters/2],
diff --git a/xorg-server/xkb/xkbEvents.c b/xorg-server/xkb/xkbEvents.c
index 9755f9846..659c8c89d 100644
--- a/xorg-server/xkb/xkbEvents.c
+++ b/xorg-server/xkb/xkbEvents.c
@@ -1,1112 +1,1112 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "inputstr.h"
-#include "exevents.h"
-#include "exglobals.h"
-#include "windowstr.h"
-#include "exevents.h"
-#include <xkbsrv.h>
-#include "xkb.h"
-
-/***====================================================================***/
-
-/*
- * This function sends out two kinds of notification:
- * - Core mapping notify events sent to clients for whom kbd is the
- * current core ('picked') keyboard _and_ have not explicitly
- * selected for XKB mapping notify events;
- * - Xi mapping events, sent unconditionally to all clients who have
- * explicitly selected for them (including those who have explicitly
- * selected for XKB mapping notify events!).
- */
-static void
-XkbSendLegacyMapNotify(DeviceIntPtr kbd, CARD16 xkb_event, CARD16 changed,
- int first_key, int num_keys)
-{
- int i;
- int keymap_changed = 0;
- int modmap_changed = 0;
- xEvent core_mn;
- deviceMappingNotify xi_mn;
- CARD32 time = GetTimeInMillis();
-
- if (xkb_event == XkbNewKeyboardNotify) {
- if (changed & XkbNKN_KeycodesMask) {
- keymap_changed = 1;
- modmap_changed = 1;
- }
- }
- else if (xkb_event == XkbMapNotify) {
- if (changed & XkbKeySymsMask)
- keymap_changed = 1;
- if (changed & XkbModifierMapMask)
- modmap_changed = 1;
- }
- if (!keymap_changed && !modmap_changed)
- return;
-
- core_mn.u.u.type = MappingNotify;
- xi_mn.type = DeviceMappingNotify;
- xi_mn.deviceid = kbd->id;
- xi_mn.time = time;
-
- /* 0 is serverClient. */
- for (i = 1; i < currentMaxClients; i++) {
- if (!clients[i] || clients[i]->clientState != ClientStateRunning)
- continue;
-
- /* Ignore clients which will have already received this.
- * Inconsistent with themselves, but consistent with previous
- * behaviour.*/
- if (xkb_event == XkbMapNotify && (clients[i]->mapNotifyMask & changed))
- continue;
- if (xkb_event == XkbNewKeyboardNotify &&
- (clients[i]->xkbClientFlags & _XkbClientInitialized))
- continue;
-
- /* Don't send core events to clients who don't know about us. */
- if (!XIShouldNotify(clients[i], kbd))
- continue;
-
- core_mn.u.u.sequenceNumber = clients[i]->sequence;
- if (keymap_changed) {
- core_mn.u.mappingNotify.request = MappingKeyboard;
-
- /* Clip the keycode range to what the client knows about, so it
- * doesn't freak out. */
- if (first_key >= clients[i]->minKC)
- core_mn.u.mappingNotify.firstKeyCode = first_key;
- else
- core_mn.u.mappingNotify.firstKeyCode = clients[i]->minKC;
- if (first_key + num_keys - 1 <= clients[i]->maxKC)
- core_mn.u.mappingNotify.count = num_keys;
- else
- core_mn.u.mappingNotify.count = clients[i]->maxKC -
- clients[i]->minKC + 1;
-
- WriteEventsToClient(clients[i], 1, &core_mn);
- }
- if (modmap_changed) {
- core_mn.u.mappingNotify.request = MappingModifier;
- core_mn.u.mappingNotify.firstKeyCode = 0;
- core_mn.u.mappingNotify.count = 0;
- WriteEventsToClient(clients[i], 1, &core_mn);
- }
- }
-
- /* Hmm, maybe we can accidentally generate Xi events for core devices
- * here? Clients might be upset, but that seems better than the
- * alternative of stale keymaps. -ds */
- if (keymap_changed) {
- xi_mn.request = MappingKeyboard;
- xi_mn.firstKeyCode = first_key;
- xi_mn.count = num_keys;
- SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn,
- 1);
- }
- if (modmap_changed) {
- xi_mn.request = MappingModifier;
- xi_mn.firstKeyCode = 0;
- xi_mn.count = 0;
- SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn,
- 1);
- }
-}
-
-/***====================================================================***/
-
-void
-XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN)
-{
- int i;
- Time time = GetTimeInMillis();
- CARD16 changed = pNKN->changed;
-
- pNKN->type = XkbEventCode + XkbEventBase;
- pNKN->xkbType = XkbNewKeyboardNotify;
-
- for (i=1; i<currentMaxClients; i++) {
- if (!clients[i] || clients[i]->clientState != ClientStateRunning)
- continue;
-
- if (!(clients[i]->newKeyboardNotifyMask & changed))
- continue;
-
- if (!XIShouldNotify(clients[i], kbd))
- continue;
-
- pNKN->sequenceNumber = clients[i]->sequence;
- pNKN->time = time;
- pNKN->changed = changed;
- if (clients[i]->swapped) {
- int n;
- swaps(&pNKN->sequenceNumber,n);
- swapl(&pNKN->time,n);
- swaps(&pNKN->changed,n);
- }
- WriteToClient(clients[i], sizeof(xEvent), pNKN);
-
- if (changed & XkbNKN_KeycodesMask) {
- clients[i]->minKC = pNKN->minKeyCode;
- clients[i]->maxKC = pNKN->maxKeyCode;
- }
- }
-
- XkbSendLegacyMapNotify(kbd, XkbNewKeyboardNotify, changed, pNKN->minKeyCode,
- pNKN->maxKeyCode - pNKN->minKeyCode + 1);
-
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbSendStateNotify(DeviceIntPtr kbd,xkbStateNotify *pSN)
-{
-XkbSrvInfoPtr xkbi;
-XkbStatePtr state;
-XkbInterestPtr interest;
-Time time;
-register CARD16 changed,bState;
-
- interest = kbd->xkb_interest;
- if (!interest || !kbd->key || !kbd->key->xkbInfo)
- return;
- xkbi = kbd->key->xkbInfo;
- state= &xkbi->state;
-
- pSN->type = XkbEventCode + XkbEventBase;
- pSN->xkbType = XkbStateNotify;
- pSN->deviceID = kbd->id;
- pSN->time = time = GetTimeInMillis();
- pSN->mods = state->mods;
- pSN->baseMods = state->base_mods;
- pSN->latchedMods = state->latched_mods;
- pSN->lockedMods = state->locked_mods;
- pSN->group = state->group;
- pSN->baseGroup = state->base_group;
- pSN->latchedGroup = state->latched_group;
- pSN->lockedGroup = state->locked_group;
- pSN->compatState = state->compat_state;
- pSN->grabMods = state->grab_mods;
- pSN->compatGrabMods = state->compat_grab_mods;
- pSN->lookupMods = state->lookup_mods;
- pSN->compatLookupMods = state->compat_lookup_mods;
- pSN->ptrBtnState = state->ptr_buttons;
- changed = pSN->changed;
- bState= pSN->ptrBtnState;
-
- while (interest) {
- if ((!interest->client->clientGone) &&
- (interest->client->requestVector != InitialVector) &&
- (interest->client->xkbClientFlags&_XkbClientInitialized) &&
- (interest->stateNotifyMask&changed) &&
- XIShouldNotify(interest->client,kbd)) {
- pSN->sequenceNumber = interest->client->sequence;
- pSN->time = time;
- pSN->changed = changed;
- pSN->ptrBtnState = bState;
- if ( interest->client->swapped ) {
- register int n;
- swaps(&pSN->sequenceNumber,n);
- swapl(&pSN->time,n);
- swaps(&pSN->changed,n);
- swaps(&pSN->ptrBtnState,n);
- }
- WriteToClient(interest->client, sizeof(xEvent), (char *)pSN);
- }
- interest= interest->next;
- }
- return;
-}
-
-/***====================================================================***/
-
-/*
- * This function sends out XKB mapping notify events to clients which
- * have explicitly selected for them. Core and Xi events are handled by
- * XkbSendLegacyMapNotify. */
-void
-XkbSendMapNotify(DeviceIntPtr kbd, xkbMapNotify *pMN)
-{
- int i;
- CARD32 time = GetTimeInMillis();
- CARD16 changed = pMN->changed;
- XkbSrvInfoPtr xkbi = kbd->key->xkbInfo;
-
- pMN->minKeyCode = xkbi->desc->min_key_code;
- pMN->maxKeyCode = xkbi->desc->max_key_code;
- pMN->type = XkbEventCode + XkbEventBase;
- pMN->xkbType = XkbMapNotify;
- pMN->deviceID = kbd->id;
-
- /* 0 is serverClient. */
- for (i = 1; i < currentMaxClients; i++) {
- if (!clients[i] || clients[i]->clientState != ClientStateRunning)
- continue;
-
- if (!(clients[i]->mapNotifyMask & changed))
- continue;
-
- if (!XIShouldNotify(clients[i], kbd))
- continue;
-
- pMN->time = time;
- pMN->sequenceNumber = clients[i]->sequence;
- pMN->changed = changed;
-
- if (clients[i]->swapped) {
- int n;
- swaps(&pMN->sequenceNumber, n);
- swapl(&pMN->time, n);
- swaps(&pMN->changed, n);
- }
- WriteToClient(clients[i], sizeof(xEvent), pMN);
- }
-
- XkbSendLegacyMapNotify(kbd, XkbMapNotify, changed, pMN->firstKeySym,
- pMN->nKeySyms);
-}
-
-int
-XkbComputeControlsNotify( DeviceIntPtr kbd,
- XkbControlsPtr old,
- XkbControlsPtr new,
- xkbControlsNotify * pCN,
- Bool forceCtrlProc)
-{
-int i;
-CARD32 changedControls;
-
- changedControls= 0;
-
- if (!kbd || !kbd->kbdfeed)
- return 0;
-
- if (old->enabled_ctrls!=new->enabled_ctrls)
- changedControls|= XkbControlsEnabledMask;
- if ((old->repeat_delay!=new->repeat_delay)||
- (old->repeat_interval!=new->repeat_interval))
- changedControls|= XkbRepeatKeysMask;
- for (i = 0; i < XkbPerKeyBitArraySize; i++)
- if (old->per_key_repeat[i] != new->per_key_repeat[i])
- changedControls|= XkbPerKeyRepeatMask;
- if (old->slow_keys_delay!=new->slow_keys_delay)
- changedControls|= XkbSlowKeysMask;
- if (old->debounce_delay!=new->debounce_delay)
- changedControls|= XkbBounceKeysMask;
- if ((old->mk_delay!=new->mk_delay)||
- (old->mk_interval!=new->mk_interval)||
- (old->mk_dflt_btn!=new->mk_dflt_btn))
- changedControls|= XkbMouseKeysMask;
- if ((old->mk_time_to_max!=new->mk_time_to_max)||
- (old->mk_curve!=new->mk_curve)||
- (old->mk_max_speed!=new->mk_max_speed))
- changedControls|= XkbMouseKeysAccelMask;
- if (old->ax_options!=new->ax_options)
- changedControls|= XkbAccessXKeysMask;
- if ((old->ax_options^new->ax_options) & XkbAX_SKOptionsMask)
- changedControls|= XkbStickyKeysMask;
- if ((old->ax_options^new->ax_options) & XkbAX_FBOptionsMask)
- changedControls|= XkbAccessXFeedbackMask;
- if ((old->ax_timeout!=new->ax_timeout)||
- (old->axt_ctrls_mask!=new->axt_ctrls_mask)||
- (old->axt_ctrls_values!=new->axt_ctrls_values)||
- (old->axt_opts_mask!=new->axt_opts_mask)||
- (old->axt_opts_values!= new->axt_opts_values)) {
- changedControls|= XkbAccessXTimeoutMask;
- }
- if ((old->internal.mask!=new->internal.mask)||
- (old->internal.real_mods!=new->internal.real_mods)||
- (old->internal.vmods!=new->internal.vmods))
- changedControls|= XkbInternalModsMask;
- if ((old->ignore_lock.mask!=new->ignore_lock.mask)||
- (old->ignore_lock.real_mods!=new->ignore_lock.real_mods)||
- (old->ignore_lock.vmods!=new->ignore_lock.vmods))
- changedControls|= XkbIgnoreLockModsMask;
-
- if (new->enabled_ctrls&XkbRepeatKeysMask)
- kbd->kbdfeed->ctrl.autoRepeat=TRUE;
- else kbd->kbdfeed->ctrl.autoRepeat=FALSE;
-
- if (kbd->kbdfeed && kbd->kbdfeed->CtrlProc &&
- (changedControls || forceCtrlProc))
- (*kbd->kbdfeed->CtrlProc)(kbd, &kbd->kbdfeed->ctrl);
-
- if ((!changedControls)&&(old->num_groups==new->num_groups))
- return 0;
-
- if (!kbd->xkb_interest)
- return 0;
-
- pCN->changedControls = changedControls;
- pCN->enabledControls = new->enabled_ctrls;
- pCN->enabledControlChanges = (new->enabled_ctrls^old->enabled_ctrls);
- pCN->numGroups = new->num_groups;
-
- return 1;
-}
-
-void
-XkbSendControlsNotify(DeviceIntPtr kbd,xkbControlsNotify *pCN)
-{
-int initialized;
-CARD32 changedControls, enabledControls, enabledChanges = 0;
-XkbSrvInfoPtr xkbi;
-XkbInterestPtr interest;
-Time time = 0;
-
- interest = kbd->xkb_interest;
- if (!interest || !kbd->key || !kbd->key->xkbInfo)
- return;
- xkbi = kbd->key->xkbInfo;
-
- initialized = 0;
- enabledControls = xkbi->desc->ctrls->enabled_ctrls;
- changedControls = pCN->changedControls;
- pCN->numGroups= xkbi->desc->ctrls->num_groups;
- while (interest) {
- if ((!interest->client->clientGone) &&
- (interest->client->requestVector != InitialVector) &&
- (interest->client->xkbClientFlags&_XkbClientInitialized) &&
- (interest->ctrlsNotifyMask&changedControls) &&
- XIShouldNotify(interest->client, kbd)) {
- if (!initialized) {
- pCN->type = XkbEventCode + XkbEventBase;
- pCN->xkbType = XkbControlsNotify;
- pCN->deviceID = kbd->id;
- pCN->time = time = GetTimeInMillis();
- enabledChanges = pCN->enabledControlChanges;
- initialized= 1;
- }
- pCN->changedControls = changedControls;
- pCN->enabledControls = enabledControls;
- pCN->enabledControlChanges = enabledChanges;
- pCN->sequenceNumber = interest->client->sequence;
- pCN->time = time;
- if ( interest->client->swapped ) {
- register int n;
- swaps(&pCN->sequenceNumber,n);
- swapl(&pCN->changedControls,n);
- swapl(&pCN->enabledControls,n);
- swapl(&pCN->enabledControlChanges,n);
- swapl(&pCN->time,n);
- }
- WriteToClient(interest->client, sizeof(xEvent), (char *)pCN);
- }
- interest= interest->next;
- }
- return;
-}
-
-static void
-XkbSendIndicatorNotify(DeviceIntPtr kbd,int xkbType,xkbIndicatorNotify *pEv)
-{
-int initialized;
-XkbInterestPtr interest;
-Time time = 0;
-CARD32 state,changed;
-
- interest = kbd->xkb_interest;
- if (!interest)
- return;
-
- initialized = 0;
- state = pEv->state;
- changed = pEv->changed;
- while (interest) {
- if ((!interest->client->clientGone) &&
- (interest->client->requestVector != InitialVector) &&
- (interest->client->xkbClientFlags&_XkbClientInitialized) &&
- XIShouldNotify(interest->client, kbd) &&
- (((xkbType==XkbIndicatorStateNotify)&&
- (interest->iStateNotifyMask&changed))||
- ((xkbType==XkbIndicatorMapNotify)&&
- (interest->iMapNotifyMask&changed)))) {
- if (!initialized) {
- pEv->type = XkbEventCode + XkbEventBase;
- pEv->xkbType = xkbType;
- pEv->deviceID = kbd->id;
- pEv->time = time = GetTimeInMillis();
- initialized= 1;
- }
- pEv->sequenceNumber = interest->client->sequence;
- pEv->time = time;
- pEv->changed = changed;
- pEv->state = state;
- if ( interest->client->swapped ) {
- register int n;
- swaps(&pEv->sequenceNumber,n);
- swapl(&pEv->time,n);
- swapl(&pEv->changed,n);
- swapl(&pEv->state,n);
- }
- WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
- }
- interest= interest->next;
- }
- return;
-}
-
-
-void
-XkbHandleBell( BOOL force,
- BOOL eventOnly,
- DeviceIntPtr kbd,
- CARD8 percent,
- pointer pCtrl,
- CARD8 class,
- Atom name,
- WindowPtr pWin,
- ClientPtr pClient)
-{
-xkbBellNotify bn;
-int initialized;
-XkbSrvInfoPtr xkbi;
-XkbInterestPtr interest;
-CARD8 id;
-CARD16 pitch,duration;
-Time time = 0;
-XID winID = 0;
-
- if (!kbd->key || !kbd->key->xkbInfo)
- return;
-
- xkbi = kbd->key->xkbInfo;
-
- if ((force||(xkbi->desc->ctrls->enabled_ctrls&XkbAudibleBellMask))&&
- (!eventOnly)) {
- if (kbd->kbdfeed->BellProc)
- (*kbd->kbdfeed->BellProc)(percent,kbd,(pointer)pCtrl,class);
- }
- interest = kbd->xkb_interest;
- if ((!interest)||(force))
- return;
-
- if ((class==0)||(class==KbdFeedbackClass)) {
- KeybdCtrl *pKeyCtrl= (KeybdCtrl *)pCtrl;
- id= pKeyCtrl->id;
- pitch= pKeyCtrl->bell_pitch;
- duration= pKeyCtrl->bell_duration;
- }
- else if (class==BellFeedbackClass) {
- BellCtrl *pBellCtrl= (BellCtrl *)pCtrl;
- id= pBellCtrl->id;
- pitch= pBellCtrl->pitch;
- duration= pBellCtrl->duration;
- }
- else return;
-
- initialized = 0;
- while (interest) {
- if ((!interest->client->clientGone) &&
- (interest->client->requestVector != InitialVector) &&
- (interest->client->xkbClientFlags&_XkbClientInitialized) &&
- (interest->bellNotifyMask) &&
- XIShouldNotify(interest->client,kbd)) {
- if (!initialized) {
- time = GetTimeInMillis();
- bn.type = XkbEventCode + XkbEventBase;
- bn.xkbType = XkbBellNotify;
- bn.deviceID = kbd->id;
- bn.bellClass = class;
- bn.bellID = id;
- bn.percent= percent;
- bn.eventOnly = (eventOnly!=0);
- winID= (pWin?pWin->drawable.id:None);
- initialized= 1;
- }
- bn.sequenceNumber = interest->client->sequence;
- bn.time = time;
- bn.pitch = pitch;
- bn.duration = duration;
- bn.name = name;
- bn.window= winID;
- if ( interest->client->swapped ) {
- register int n;
- swaps(&bn.sequenceNumber,n);
- swapl(&bn.time,n);
- swaps(&bn.pitch,n);
- swaps(&bn.duration,n);
- swapl(&bn.name,n);
- swapl(&bn.window,n);
- }
- WriteToClient(interest->client, sizeof(xEvent), (char *)&bn);
- }
- interest= interest->next;
- }
- return;
-}
-
-void
-XkbSendAccessXNotify(DeviceIntPtr kbd,xkbAccessXNotify *pEv)
-{
-int initialized;
-XkbInterestPtr interest;
-Time time = 0;
-CARD16 sk_delay,db_delay;
-
- interest = kbd->xkb_interest;
- if (!interest)
- return;
-
- initialized = 0;
- sk_delay= pEv->slowKeysDelay;
- db_delay= pEv->debounceDelay;
- while (interest) {
- if ((!interest->client->clientGone) &&
- (interest->client->requestVector != InitialVector) &&
- (interest->client->xkbClientFlags&_XkbClientInitialized) &&
- (interest->accessXNotifyMask&(1<<pEv->detail)) &&
- XIShouldNotify(interest->client, kbd)) {
- if (!initialized) {
- pEv->type = XkbEventCode + XkbEventBase;
- pEv->xkbType = XkbAccessXNotify;
- pEv->deviceID = kbd->id;
- pEv->time = time = GetTimeInMillis();
- initialized= 1;
- }
- pEv->sequenceNumber = interest->client->sequence;
- pEv->time = time;
- pEv->slowKeysDelay = sk_delay;
- pEv->debounceDelay = db_delay;
- if ( interest->client->swapped ) {
- register int n;
- swaps(&pEv->sequenceNumber,n);
- swapl(&pEv->time,n);
- swaps(&pEv->slowKeysDelay,n);
- swaps(&pEv->debounceDelay,n);
- }
- WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
- }
- interest= interest->next;
- }
- return;
-}
-
-void
-XkbSendNamesNotify(DeviceIntPtr kbd,xkbNamesNotify *pEv)
-{
-int initialized;
-XkbInterestPtr interest;
-Time time = 0;
-CARD16 changed,changedVirtualMods;
-CARD32 changedIndicators;
-
- interest = kbd->xkb_interest;
- if (!interest)
- return;
-
- initialized = 0;
- changed= pEv->changed;
- changedIndicators= pEv->changedIndicators;
- changedVirtualMods= pEv->changedVirtualMods;
- while (interest) {
- if ((!interest->client->clientGone) &&
- (interest->client->requestVector != InitialVector) &&
- (interest->client->xkbClientFlags&_XkbClientInitialized) &&
- (interest->namesNotifyMask&pEv->changed) &&
- XIShouldNotify(interest->client, kbd)) {
- if (!initialized) {
- pEv->type = XkbEventCode + XkbEventBase;
- pEv->xkbType = XkbNamesNotify;
- pEv->deviceID = kbd->id;
- pEv->time = time = GetTimeInMillis();
- initialized= 1;
- }
- pEv->sequenceNumber = interest->client->sequence;
- pEv->time = time;
- pEv->changed = changed;
- pEv->changedIndicators = changedIndicators;
- pEv->changedVirtualMods= changedVirtualMods;
- if ( interest->client->swapped ) {
- register int n;
- swaps(&pEv->sequenceNumber,n);
- swapl(&pEv->time,n);
- swaps(&pEv->changed,n);
- swapl(&pEv->changedIndicators,n);
- swaps(&pEv->changedVirtualMods,n);
- }
- WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
- }
- interest= interest->next;
- }
- return;
-}
-
-void
-XkbSendCompatMapNotify(DeviceIntPtr kbd,xkbCompatMapNotify *pEv)
-{
-int initialized;
-XkbInterestPtr interest;
-Time time = 0;
-CARD16 firstSI = 0, nSI = 0, nTotalSI = 0;
-
- interest = kbd->xkb_interest;
- if (!interest)
- return;
-
- initialized = 0;
- while (interest) {
- if ((!interest->client->clientGone) &&
- (interest->client->requestVector != InitialVector) &&
- (interest->client->xkbClientFlags&_XkbClientInitialized) &&
- (interest->compatNotifyMask) &&
- XIShouldNotify(interest->client, kbd)) {
- if (!initialized) {
- pEv->type = XkbEventCode + XkbEventBase;
- pEv->xkbType = XkbCompatMapNotify;
- pEv->deviceID = kbd->id;
- pEv->time = time = GetTimeInMillis();
- firstSI= pEv->firstSI;
- nSI= pEv->nSI;
- nTotalSI= pEv->nTotalSI;
- initialized= 1;
- }
- pEv->sequenceNumber = interest->client->sequence;
- pEv->time = time;
- pEv->firstSI = firstSI;
- pEv->nSI = nSI;
- pEv->nTotalSI = nTotalSI;
- if ( interest->client->swapped ) {
- register int n;
- swaps(&pEv->sequenceNumber,n);
- swapl(&pEv->time,n);
- swaps(&pEv->firstSI,n);
- swaps(&pEv->nSI,n);
- swaps(&pEv->nTotalSI,n);
- }
- WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
- }
- interest= interest->next;
- }
- return;
-}
-
-void
-XkbSendActionMessage(DeviceIntPtr kbd,xkbActionMessage *pEv)
-{
-int initialized;
-XkbSrvInfoPtr xkbi;
-XkbInterestPtr interest;
-Time time = 0;
-
- interest = kbd->xkb_interest;
- if (!interest || !kbd->key || !kbd->key->xkbInfo)
- return;
-
- xkbi = kbd->key->xkbInfo;
-
- initialized = 0;
- pEv->mods= xkbi->state.mods;
- pEv->group= xkbi->state.group;
- while (interest) {
- if ((!interest->client->clientGone) &&
- (interest->client->requestVector != InitialVector) &&
- (interest->client->xkbClientFlags&_XkbClientInitialized) &&
- (interest->actionMessageMask) &&
- XIShouldNotify(interest->client, kbd)) {
- if (!initialized) {
- pEv->type = XkbEventCode + XkbEventBase;
- pEv->xkbType = XkbActionMessage;
- pEv->deviceID = kbd->id;
- pEv->sequenceNumber = interest->client->sequence;
- pEv->time = time = GetTimeInMillis();
- initialized= 1;
- }
- pEv->sequenceNumber = interest->client->sequence;
- pEv->time = time;
- if ( interest->client->swapped ) {
- register int n;
- swaps(&pEv->sequenceNumber,n);
- swapl(&pEv->time,n);
- }
- WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
- }
- interest= interest->next;
- }
- return;
-}
-
-void
-XkbSendExtensionDeviceNotify( DeviceIntPtr dev,
- ClientPtr client,
- xkbExtensionDeviceNotify * pEv)
-{
-int initialized;
-XkbInterestPtr interest;
-Time time = 0;
-CARD32 defined, state;
-CARD16 reason;
-
- interest = dev->xkb_interest;
- if (!interest)
- return;
-
- initialized = 0;
- reason= pEv->reason;
- defined= pEv->ledsDefined;
- state= pEv->ledState;
- while (interest) {
- if ((!interest->client->clientGone) &&
- (interest->client->requestVector != InitialVector) &&
- (interest->client->xkbClientFlags&_XkbClientInitialized) &&
- (interest->extDevNotifyMask&reason) &&
- XIShouldNotify(interest->client, dev)) {
- if (!initialized) {
- pEv->type = XkbEventCode + XkbEventBase;
- pEv->xkbType = XkbExtensionDeviceNotify;
- pEv->deviceID = dev->id;
- pEv->sequenceNumber = interest->client->sequence;
- pEv->time = time = GetTimeInMillis();
- initialized= 1;
- }
- else {
- pEv->sequenceNumber = interest->client->sequence;
- pEv->time = time;
- pEv->ledsDefined= defined;
- pEv->ledState= state;
- pEv->reason= reason;
- pEv->supported= XkbXI_AllFeaturesMask;
- }
- if ( interest->client->swapped ) {
- register int n;
- swaps(&pEv->sequenceNumber,n);
- swapl(&pEv->time,n);
- swapl(&pEv->ledsDefined,n);
- swapl(&pEv->ledState,n);
- swaps(&pEv->reason,n);
- swaps(&pEv->supported,n);
- }
- WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
- }
- interest= interest->next;
- }
- return;
-}
-
-void
-XkbSendNotification( DeviceIntPtr kbd,
- XkbChangesPtr pChanges,
- XkbEventCausePtr cause)
-{
-XkbSrvLedInfoPtr sli;
-
- sli= NULL;
- if (pChanges->state_changes) {
- xkbStateNotify sn;
- sn.changed= pChanges->state_changes;
- sn.keycode= cause->kc;
- sn.eventType= cause->event;
- sn.requestMajor= cause->mjr;
- sn.requestMinor= cause->mnr;
- XkbSendStateNotify(kbd,&sn);
- }
- if (pChanges->map.changed) {
- xkbMapNotify mn;
- memset(&mn, 0, sizeof(xkbMapNotify));
- mn.changed= pChanges->map.changed;
- mn.firstType= pChanges->map.first_type;
- mn.nTypes= pChanges->map.num_types;
- mn.firstKeySym= pChanges->map.first_key_sym;
- mn.nKeySyms= pChanges->map.num_key_syms;
- mn.firstKeyAct= pChanges->map.first_key_act;
- mn.nKeyActs= pChanges->map.num_key_acts;
- mn.firstKeyBehavior= pChanges->map.first_key_behavior;
- mn.nKeyBehaviors= pChanges->map.num_key_behaviors;
- mn.virtualMods= pChanges->map.vmods;
- mn.firstKeyExplicit= pChanges->map.first_key_explicit;
- mn.nKeyExplicit= pChanges->map.num_key_explicit;
- mn.firstModMapKey= pChanges->map.first_modmap_key;
- mn.nModMapKeys= pChanges->map.num_modmap_keys;
- mn.firstVModMapKey= pChanges->map.first_vmodmap_key;
- mn.nVModMapKeys= pChanges->map.num_vmodmap_keys;
- XkbSendMapNotify(kbd,&mn);
- }
- if ((pChanges->ctrls.changed_ctrls)||
- (pChanges->ctrls.enabled_ctrls_changes)) {
- xkbControlsNotify cn;
- memset(&cn, 0, sizeof(xkbControlsNotify));
- cn.changedControls= pChanges->ctrls.changed_ctrls;
- cn.enabledControlChanges= pChanges->ctrls.enabled_ctrls_changes;
- cn.keycode= cause->kc;
- cn.eventType= cause->event;
- cn.requestMajor= cause->mjr;
- cn.requestMinor= cause->mnr;
- XkbSendControlsNotify(kbd,&cn);
- }
- if (pChanges->indicators.map_changes) {
- xkbIndicatorNotify in;
- if (sli==NULL)
- sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
- memset(&in, 0, sizeof(xkbIndicatorNotify));
- in.state= sli->effectiveState;
- in.changed= pChanges->indicators.map_changes;
- XkbSendIndicatorNotify(kbd,XkbIndicatorMapNotify,&in);
- }
- if (pChanges->indicators.state_changes) {
- xkbIndicatorNotify in;
- if (sli==NULL)
- sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
- memset(&in, 0, sizeof(xkbIndicatorNotify));
- in.state= sli->effectiveState;
- in.changed= pChanges->indicators.state_changes;
- XkbSendIndicatorNotify(kbd,XkbIndicatorStateNotify,&in);
- }
- if (pChanges->names.changed) {
- xkbNamesNotify nn;
- memset(&nn, 0, sizeof(xkbNamesNotify));
- nn.changed= pChanges->names.changed;
- nn.firstType= pChanges->names.first_type;
- nn.nTypes= pChanges->names.num_types;
- nn.firstLevelName= pChanges->names.first_lvl;
- nn.nLevelNames= pChanges->names.num_lvls;
- nn.nRadioGroups= pChanges->names.num_rg;
- nn.changedVirtualMods= pChanges->names.changed_vmods;
- nn.changedIndicators= pChanges->names.changed_indicators;
- XkbSendNamesNotify(kbd,&nn);
- }
- if ((pChanges->compat.changed_groups)||(pChanges->compat.num_si>0)) {
- xkbCompatMapNotify cmn;
- memset(&cmn, 0, sizeof(xkbCompatMapNotify));
- cmn.changedGroups= pChanges->compat.changed_groups;
- cmn.firstSI= pChanges->compat.first_si;
- cmn.nSI= pChanges->compat.num_si;
- cmn.nTotalSI= kbd->key->xkbInfo->desc->compat->num_si;
- XkbSendCompatMapNotify(kbd,&cmn);
- }
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbFilterEvents(ClientPtr client,int nEvents,xEvent *xE)
-{
- DeviceIntPtr dev = NULL;
- XkbSrvInfoPtr xkbi;
- CARD8 type = xE[0].u.u.type;
-
- if (xE->u.u.type & EXTENSION_EVENT_BASE)
- dev = XIGetDevice(xE);
-
- if (!dev)
- dev = PickKeyboard(client);
-
- if (!dev->key)
- return;
-
- xkbi = dev->key->xkbInfo;
-
- if (client->xkbClientFlags & _XkbClientInitialized) {
- if ((xkbDebugFlags&0x10)&&
- (type == KeyPress || type == KeyRelease ||
- type == DeviceKeyPress || type == DeviceKeyRelease))
- DebugF("[xkb] XkbFilterWriteEvents (XKB client): state 0x%04x\n",
- xE[0].u.keyButtonPointer.state);
-
- if (dev->deviceGrab.grab != NullGrab && dev->deviceGrab.fromPassiveGrab &&
- (type == KeyPress || type == KeyRelease ||
- type == DeviceKeyPress || type == DeviceKeyRelease)) {
- unsigned int state, flags;
-
- flags = client->xkbClientFlags;
- state = xkbi->state.compat_grab_mods;
- if (flags & XkbPCF_GrabsUseXKBStateMask) {
- int group;
- if (flags & XkbPCF_LookupStateWhenGrabbed) {
- group = xkbi->state.group;
- state = xkbi->state.lookup_mods;
- }
- else {
- state = xkbi->state.grab_mods;
- group = xkbi->state.base_group + xkbi->state.latched_group;
- if (group < 0 || group >= xkbi->desc->ctrls->num_groups)
- group = XkbAdjustGroup(group, xkbi->desc->ctrls);
- }
- state = XkbBuildCoreState(state, group);
- }
- else if (flags & XkbPCF_LookupStateWhenGrabbed) {
- state = xkbi->state.compat_lookup_mods;
- }
- xE[0].u.keyButtonPointer.state = state;
- }
- }
- else {
- if ((xkbDebugFlags & 0x4) &&
- (xE[0].u.u.type == KeyPress || xE[0].u.u.type==KeyRelease ||
- xE[0].u.u.type == DeviceKeyPress ||
- xE[0].u.u.type == DeviceKeyRelease)) {
- DebugF("[xkb] XKbFilterWriteEvents (non-XKB):\n");
- DebugF("[xkb] event= 0x%04x\n",xE[0].u.keyButtonPointer.state);
- DebugF("[xkb] lookup= 0x%02x, grab= 0x%02x\n",
- xkbi->state.lookup_mods, xkbi->state.grab_mods);
- DebugF("[xkb] compat lookup= 0x%02x, grab= 0x%02x\n",
- xkbi->state.compat_lookup_mods, xkbi->state.compat_grab_mods);
- }
- if (type >= KeyPress && type <= MotionNotify) {
- CARD16 old, new;
-
- old = xE[0].u.keyButtonPointer.state & ~0x1f00;
- new = xE[0].u.keyButtonPointer.state & 0x1F00;
-
- if (old == XkbStateFieldFromRec(&xkbi->state))
- new |= xkbi->state.compat_lookup_mods;
- else
- new |= xkbi->state.compat_grab_mods;
- xE[0].u.keyButtonPointer.state = new;
- }
- else if (type == EnterNotify || type == LeaveNotify) {
- xE[0].u.enterLeave.state &= 0x1F00;
- xE[0].u.enterLeave.state |= xkbi->state.compat_grab_mods;
- }
- else if (type >= DeviceKeyPress && type <= DeviceMotionNotify) {
- CARD16 old, new;
- deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer*) &xE[0];
-
- old = kbp->state & ~0x1F00;
- new = kbp->state & 0x1F00;
- if (old == XkbStateFieldFromRec(&xkbi->state))
- new |= xkbi->state.compat_lookup_mods;
- else
- new |= xkbi->state.compat_grab_mods;
- kbp->state = new;
- }
- }
-}
-
-/***====================================================================***/
-
-XkbInterestPtr
-XkbFindClientResource(DevicePtr inDev,ClientPtr client)
-{
-DeviceIntPtr dev = (DeviceIntPtr)inDev;
-XkbInterestPtr interest;
-
- if ( dev->xkb_interest ) {
- interest = dev->xkb_interest;
- while (interest){
- if (interest->client==client) {
- return interest;
- }
- interest = interest->next;
- }
- }
- return NULL;
-}
-
-XkbInterestPtr
-XkbAddClientResource(DevicePtr inDev,ClientPtr client,XID id)
-{
-DeviceIntPtr dev = (DeviceIntPtr)inDev;
-XkbInterestPtr interest;
-
- interest = dev->xkb_interest;
- while (interest) {
- if (interest->client==client)
- return ((interest->resource==id)?interest:NULL);
- interest = interest->next;
- }
- interest = xcalloc(1, sizeof(XkbInterestRec));
- if (interest) {
- interest->dev = dev;
- interest->client = client;
- interest->resource = id;
- interest->stateNotifyMask= 0;
- interest->ctrlsNotifyMask= 0;
- interest->namesNotifyMask= 0;
- interest->compatNotifyMask= 0;
- interest->bellNotifyMask= FALSE;
- interest->accessXNotifyMask= 0;
- interest->iStateNotifyMask= 0;
- interest->iMapNotifyMask= 0;
- interest->altSymsNotifyMask= 0;
- interest->next = dev->xkb_interest;
- dev->xkb_interest= interest;
- return interest;
- }
- return NULL;
-}
-
-int
-XkbRemoveResourceClient(DevicePtr inDev,XID id)
-{
-XkbSrvInfoPtr xkbi;
-DeviceIntPtr dev = (DeviceIntPtr)inDev;
-XkbInterestPtr interest;
-Bool found;
-unsigned long autoCtrls,autoValues;
-ClientPtr client = NULL;
-
- found= FALSE;
-
- if (!dev->key || !dev->key->xkbInfo)
- return found;
-
- autoCtrls= autoValues= 0;
- if ( dev->xkb_interest ) {
- interest = dev->xkb_interest;
- if (interest && (interest->resource==id)){
- dev->xkb_interest = interest->next;
- autoCtrls= interest->autoCtrls;
- autoValues= interest->autoCtrlValues;
- client= interest->client;
- xfree(interest);
- found= TRUE;
- }
- while ((!found)&&(interest->next)) {
- if (interest->next->resource==id) {
- XkbInterestPtr victim = interest->next;
- interest->next = victim->next;
- autoCtrls= victim->autoCtrls;
- autoValues= victim->autoCtrlValues;
- client= victim->client;
- xfree(victim);
- found= TRUE;
- }
- interest = interest->next;
- }
- }
- if (found && autoCtrls && dev->key && dev->key->xkbInfo ) {
- XkbEventCauseRec cause;
-
- xkbi= dev->key->xkbInfo;
- XkbSetCauseXkbReq(&cause,X_kbPerClientFlags,client);
- XkbEnableDisableControls(xkbi,autoCtrls,autoValues,NULL,&cause);
- }
- return found;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "inputstr.h"
+#include "exevents.h"
+#include "exglobals.h"
+#include "windowstr.h"
+#include "exevents.h"
+#include <xkbsrv.h>
+#include "xkb.h"
+
+/***====================================================================***/
+
+/*
+ * This function sends out two kinds of notification:
+ * - Core mapping notify events sent to clients for whom kbd is the
+ * current core ('picked') keyboard _and_ have not explicitly
+ * selected for XKB mapping notify events;
+ * - Xi mapping events, sent unconditionally to all clients who have
+ * explicitly selected for them (including those who have explicitly
+ * selected for XKB mapping notify events!).
+ */
+static void
+XkbSendLegacyMapNotify(DeviceIntPtr kbd, CARD16 xkb_event, CARD16 changed,
+ int first_key, int num_keys)
+{
+ int i;
+ int keymap_changed = 0;
+ int modmap_changed = 0;
+ xEvent core_mn;
+ deviceMappingNotify xi_mn;
+ CARD32 time = GetTimeInMillis();
+
+ if (xkb_event == XkbNewKeyboardNotify) {
+ if (changed & XkbNKN_KeycodesMask) {
+ keymap_changed = 1;
+ modmap_changed = 1;
+ }
+ }
+ else if (xkb_event == XkbMapNotify) {
+ if (changed & XkbKeySymsMask)
+ keymap_changed = 1;
+ if (changed & XkbModifierMapMask)
+ modmap_changed = 1;
+ }
+ if (!keymap_changed && !modmap_changed)
+ return;
+
+ core_mn.u.u.type = MappingNotify;
+ xi_mn.type = DeviceMappingNotify;
+ xi_mn.deviceid = kbd->id;
+ xi_mn.time = time;
+
+ /* 0 is serverClient. */
+ for (i = 1; i < currentMaxClients; i++) {
+ if (!clients[i] || clients[i]->clientState != ClientStateRunning)
+ continue;
+
+ /* Ignore clients which will have already received this.
+ * Inconsistent with themselves, but consistent with previous
+ * behaviour.*/
+ if (xkb_event == XkbMapNotify && (clients[i]->mapNotifyMask & changed))
+ continue;
+ if (xkb_event == XkbNewKeyboardNotify &&
+ (clients[i]->xkbClientFlags & _XkbClientInitialized))
+ continue;
+
+ /* Don't send core events to clients who don't know about us. */
+ if (!XIShouldNotify(clients[i], kbd))
+ continue;
+
+ core_mn.u.u.sequenceNumber = clients[i]->sequence;
+ if (keymap_changed) {
+ core_mn.u.mappingNotify.request = MappingKeyboard;
+
+ /* Clip the keycode range to what the client knows about, so it
+ * doesn't freak out. */
+ if (first_key >= clients[i]->minKC)
+ core_mn.u.mappingNotify.firstKeyCode = first_key;
+ else
+ core_mn.u.mappingNotify.firstKeyCode = clients[i]->minKC;
+ if (first_key + num_keys - 1 <= clients[i]->maxKC)
+ core_mn.u.mappingNotify.count = num_keys;
+ else
+ core_mn.u.mappingNotify.count = clients[i]->maxKC -
+ clients[i]->minKC + 1;
+
+ WriteEventsToClient(clients[i], 1, &core_mn);
+ }
+ if (modmap_changed) {
+ core_mn.u.mappingNotify.request = MappingModifier;
+ core_mn.u.mappingNotify.firstKeyCode = 0;
+ core_mn.u.mappingNotify.count = 0;
+ WriteEventsToClient(clients[i], 1, &core_mn);
+ }
+ }
+
+ /* Hmm, maybe we can accidentally generate Xi events for core devices
+ * here? Clients might be upset, but that seems better than the
+ * alternative of stale keymaps. -ds */
+ if (keymap_changed) {
+ xi_mn.request = MappingKeyboard;
+ xi_mn.firstKeyCode = first_key;
+ xi_mn.count = num_keys;
+ SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn,
+ 1);
+ }
+ if (modmap_changed) {
+ xi_mn.request = MappingModifier;
+ xi_mn.firstKeyCode = 0;
+ xi_mn.count = 0;
+ SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn,
+ 1);
+ }
+}
+
+/***====================================================================***/
+
+void
+XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN)
+{
+ int i;
+ Time time = GetTimeInMillis();
+ CARD16 changed = pNKN->changed;
+
+ pNKN->type = XkbEventCode + XkbEventBase;
+ pNKN->xkbType = XkbNewKeyboardNotify;
+
+ for (i=1; i<currentMaxClients; i++) {
+ if (!clients[i] || clients[i]->clientState != ClientStateRunning)
+ continue;
+
+ if (!(clients[i]->newKeyboardNotifyMask & changed))
+ continue;
+
+ if (!XIShouldNotify(clients[i], kbd))
+ continue;
+
+ pNKN->sequenceNumber = clients[i]->sequence;
+ pNKN->time = time;
+ pNKN->changed = changed;
+ if (clients[i]->swapped) {
+ int n;
+ swaps(&pNKN->sequenceNumber,n);
+ swapl(&pNKN->time,n);
+ swaps(&pNKN->changed,n);
+ }
+ WriteToClient(clients[i], sizeof(xEvent), pNKN);
+
+ if (changed & XkbNKN_KeycodesMask) {
+ clients[i]->minKC = pNKN->minKeyCode;
+ clients[i]->maxKC = pNKN->maxKeyCode;
+ }
+ }
+
+ XkbSendLegacyMapNotify(kbd, XkbNewKeyboardNotify, changed, pNKN->minKeyCode,
+ pNKN->maxKeyCode - pNKN->minKeyCode + 1);
+
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbSendStateNotify(DeviceIntPtr kbd,xkbStateNotify *pSN)
+{
+XkbSrvInfoPtr xkbi;
+XkbStatePtr state;
+XkbInterestPtr interest;
+Time time;
+register CARD16 changed,bState;
+
+ interest = kbd->xkb_interest;
+ if (!interest || !kbd->key || !kbd->key->xkbInfo)
+ return;
+ xkbi = kbd->key->xkbInfo;
+ state= &xkbi->state;
+
+ pSN->type = XkbEventCode + XkbEventBase;
+ pSN->xkbType = XkbStateNotify;
+ pSN->deviceID = kbd->id;
+ pSN->time = time = GetTimeInMillis();
+ pSN->mods = state->mods;
+ pSN->baseMods = state->base_mods;
+ pSN->latchedMods = state->latched_mods;
+ pSN->lockedMods = state->locked_mods;
+ pSN->group = state->group;
+ pSN->baseGroup = state->base_group;
+ pSN->latchedGroup = state->latched_group;
+ pSN->lockedGroup = state->locked_group;
+ pSN->compatState = state->compat_state;
+ pSN->grabMods = state->grab_mods;
+ pSN->compatGrabMods = state->compat_grab_mods;
+ pSN->lookupMods = state->lookup_mods;
+ pSN->compatLookupMods = state->compat_lookup_mods;
+ pSN->ptrBtnState = state->ptr_buttons;
+ changed = pSN->changed;
+ bState= pSN->ptrBtnState;
+
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->stateNotifyMask&changed) &&
+ XIShouldNotify(interest->client,kbd)) {
+ pSN->sequenceNumber = interest->client->sequence;
+ pSN->time = time;
+ pSN->changed = changed;
+ pSN->ptrBtnState = bState;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pSN->sequenceNumber,n);
+ swapl(&pSN->time,n);
+ swaps(&pSN->changed,n);
+ swaps(&pSN->ptrBtnState,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pSN);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+/*
+ * This function sends out XKB mapping notify events to clients which
+ * have explicitly selected for them. Core and Xi events are handled by
+ * XkbSendLegacyMapNotify. */
+void
+XkbSendMapNotify(DeviceIntPtr kbd, xkbMapNotify *pMN)
+{
+ int i;
+ CARD32 time = GetTimeInMillis();
+ CARD16 changed = pMN->changed;
+ XkbSrvInfoPtr xkbi = kbd->key->xkbInfo;
+
+ pMN->minKeyCode = xkbi->desc->min_key_code;
+ pMN->maxKeyCode = xkbi->desc->max_key_code;
+ pMN->type = XkbEventCode + XkbEventBase;
+ pMN->xkbType = XkbMapNotify;
+ pMN->deviceID = kbd->id;
+
+ /* 0 is serverClient. */
+ for (i = 1; i < currentMaxClients; i++) {
+ if (!clients[i] || clients[i]->clientState != ClientStateRunning)
+ continue;
+
+ if (!(clients[i]->mapNotifyMask & changed))
+ continue;
+
+ if (!XIShouldNotify(clients[i], kbd))
+ continue;
+
+ pMN->time = time;
+ pMN->sequenceNumber = clients[i]->sequence;
+ pMN->changed = changed;
+
+ if (clients[i]->swapped) {
+ int n;
+ swaps(&pMN->sequenceNumber, n);
+ swapl(&pMN->time, n);
+ swaps(&pMN->changed, n);
+ }
+ WriteToClient(clients[i], sizeof(xEvent), pMN);
+ }
+
+ XkbSendLegacyMapNotify(kbd, XkbMapNotify, changed, pMN->firstKeySym,
+ pMN->nKeySyms);
+}
+
+int
+XkbComputeControlsNotify( DeviceIntPtr kbd,
+ XkbControlsPtr old,
+ XkbControlsPtr new,
+ xkbControlsNotify * pCN,
+ Bool forceCtrlProc)
+{
+int i;
+CARD32 changedControls;
+
+ changedControls= 0;
+
+ if (!kbd || !kbd->kbdfeed)
+ return 0;
+
+ if (old->enabled_ctrls!=new->enabled_ctrls)
+ changedControls|= XkbControlsEnabledMask;
+ if ((old->repeat_delay!=new->repeat_delay)||
+ (old->repeat_interval!=new->repeat_interval))
+ changedControls|= XkbRepeatKeysMask;
+ for (i = 0; i < XkbPerKeyBitArraySize; i++)
+ if (old->per_key_repeat[i] != new->per_key_repeat[i])
+ changedControls|= XkbPerKeyRepeatMask;
+ if (old->slow_keys_delay!=new->slow_keys_delay)
+ changedControls|= XkbSlowKeysMask;
+ if (old->debounce_delay!=new->debounce_delay)
+ changedControls|= XkbBounceKeysMask;
+ if ((old->mk_delay!=new->mk_delay)||
+ (old->mk_interval!=new->mk_interval)||
+ (old->mk_dflt_btn!=new->mk_dflt_btn))
+ changedControls|= XkbMouseKeysMask;
+ if ((old->mk_time_to_max!=new->mk_time_to_max)||
+ (old->mk_curve!=new->mk_curve)||
+ (old->mk_max_speed!=new->mk_max_speed))
+ changedControls|= XkbMouseKeysAccelMask;
+ if (old->ax_options!=new->ax_options)
+ changedControls|= XkbAccessXKeysMask;
+ if ((old->ax_options^new->ax_options) & XkbAX_SKOptionsMask)
+ changedControls|= XkbStickyKeysMask;
+ if ((old->ax_options^new->ax_options) & XkbAX_FBOptionsMask)
+ changedControls|= XkbAccessXFeedbackMask;
+ if ((old->ax_timeout!=new->ax_timeout)||
+ (old->axt_ctrls_mask!=new->axt_ctrls_mask)||
+ (old->axt_ctrls_values!=new->axt_ctrls_values)||
+ (old->axt_opts_mask!=new->axt_opts_mask)||
+ (old->axt_opts_values!= new->axt_opts_values)) {
+ changedControls|= XkbAccessXTimeoutMask;
+ }
+ if ((old->internal.mask!=new->internal.mask)||
+ (old->internal.real_mods!=new->internal.real_mods)||
+ (old->internal.vmods!=new->internal.vmods))
+ changedControls|= XkbInternalModsMask;
+ if ((old->ignore_lock.mask!=new->ignore_lock.mask)||
+ (old->ignore_lock.real_mods!=new->ignore_lock.real_mods)||
+ (old->ignore_lock.vmods!=new->ignore_lock.vmods))
+ changedControls|= XkbIgnoreLockModsMask;
+
+ if (new->enabled_ctrls&XkbRepeatKeysMask)
+ kbd->kbdfeed->ctrl.autoRepeat=TRUE;
+ else kbd->kbdfeed->ctrl.autoRepeat=FALSE;
+
+ if (kbd->kbdfeed && kbd->kbdfeed->CtrlProc &&
+ (changedControls || forceCtrlProc))
+ (*kbd->kbdfeed->CtrlProc)(kbd, &kbd->kbdfeed->ctrl);
+
+ if ((!changedControls)&&(old->num_groups==new->num_groups))
+ return 0;
+
+ if (!kbd->xkb_interest)
+ return 0;
+
+ pCN->changedControls = changedControls;
+ pCN->enabledControls = new->enabled_ctrls;
+ pCN->enabledControlChanges = (new->enabled_ctrls^old->enabled_ctrls);
+ pCN->numGroups = new->num_groups;
+
+ return 1;
+}
+
+void
+XkbSendControlsNotify(DeviceIntPtr kbd,xkbControlsNotify *pCN)
+{
+int initialized;
+CARD32 changedControls, enabledControls, enabledChanges = 0;
+XkbSrvInfoPtr xkbi;
+XkbInterestPtr interest;
+Time time = 0;
+
+ interest = kbd->xkb_interest;
+ if (!interest || !kbd->key || !kbd->key->xkbInfo)
+ return;
+ xkbi = kbd->key->xkbInfo;
+
+ initialized = 0;
+ enabledControls = xkbi->desc->ctrls->enabled_ctrls;
+ changedControls = pCN->changedControls;
+ pCN->numGroups= xkbi->desc->ctrls->num_groups;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->ctrlsNotifyMask&changedControls) &&
+ XIShouldNotify(interest->client, kbd)) {
+ if (!initialized) {
+ pCN->type = XkbEventCode + XkbEventBase;
+ pCN->xkbType = XkbControlsNotify;
+ pCN->deviceID = kbd->id;
+ pCN->time = time = GetTimeInMillis();
+ enabledChanges = pCN->enabledControlChanges;
+ initialized= 1;
+ }
+ pCN->changedControls = changedControls;
+ pCN->enabledControls = enabledControls;
+ pCN->enabledControlChanges = enabledChanges;
+ pCN->sequenceNumber = interest->client->sequence;
+ pCN->time = time;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pCN->sequenceNumber,n);
+ swapl(&pCN->changedControls,n);
+ swapl(&pCN->enabledControls,n);
+ swapl(&pCN->enabledControlChanges,n);
+ swapl(&pCN->time,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pCN);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+static void
+XkbSendIndicatorNotify(DeviceIntPtr kbd,int xkbType,xkbIndicatorNotify *pEv)
+{
+int initialized;
+XkbInterestPtr interest;
+Time time = 0;
+CARD32 state,changed;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ state = pEv->state;
+ changed = pEv->changed;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ XIShouldNotify(interest->client, kbd) &&
+ (((xkbType==XkbIndicatorStateNotify)&&
+ (interest->iStateNotifyMask&changed))||
+ ((xkbType==XkbIndicatorMapNotify)&&
+ (interest->iMapNotifyMask&changed)))) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = xkbType;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->changed = changed;
+ pEv->state = state;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ swapl(&pEv->changed,n);
+ swapl(&pEv->state,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+
+void
+XkbHandleBell( BOOL force,
+ BOOL eventOnly,
+ DeviceIntPtr kbd,
+ CARD8 percent,
+ pointer pCtrl,
+ CARD8 class,
+ Atom name,
+ WindowPtr pWin,
+ ClientPtr pClient)
+{
+xkbBellNotify bn;
+int initialized;
+XkbSrvInfoPtr xkbi;
+XkbInterestPtr interest;
+CARD8 id;
+CARD16 pitch,duration;
+Time time = 0;
+XID winID = 0;
+
+ if (!kbd->key || !kbd->key->xkbInfo)
+ return;
+
+ xkbi = kbd->key->xkbInfo;
+
+ if ((force||(xkbi->desc->ctrls->enabled_ctrls&XkbAudibleBellMask))&&
+ (!eventOnly)) {
+ if (kbd->kbdfeed->BellProc)
+ (*kbd->kbdfeed->BellProc)(percent,kbd,(pointer)pCtrl,class);
+ }
+ interest = kbd->xkb_interest;
+ if ((!interest)||(force))
+ return;
+
+ if ((class==0)||(class==KbdFeedbackClass)) {
+ KeybdCtrl *pKeyCtrl= (KeybdCtrl *)pCtrl;
+ id= pKeyCtrl->id;
+ pitch= pKeyCtrl->bell_pitch;
+ duration= pKeyCtrl->bell_duration;
+ }
+ else if (class==BellFeedbackClass) {
+ BellCtrl *pBellCtrl= (BellCtrl *)pCtrl;
+ id= pBellCtrl->id;
+ pitch= pBellCtrl->pitch;
+ duration= pBellCtrl->duration;
+ }
+ else return;
+
+ initialized = 0;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->bellNotifyMask) &&
+ XIShouldNotify(interest->client,kbd)) {
+ if (!initialized) {
+ time = GetTimeInMillis();
+ bn.type = XkbEventCode + XkbEventBase;
+ bn.xkbType = XkbBellNotify;
+ bn.deviceID = kbd->id;
+ bn.bellClass = class;
+ bn.bellID = id;
+ bn.percent= percent;
+ bn.eventOnly = (eventOnly!=0);
+ winID= (pWin?pWin->drawable.id:None);
+ initialized= 1;
+ }
+ bn.sequenceNumber = interest->client->sequence;
+ bn.time = time;
+ bn.pitch = pitch;
+ bn.duration = duration;
+ bn.name = name;
+ bn.window= winID;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&bn.sequenceNumber,n);
+ swapl(&bn.time,n);
+ swaps(&bn.pitch,n);
+ swaps(&bn.duration,n);
+ swapl(&bn.name,n);
+ swapl(&bn.window,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)&bn);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendAccessXNotify(DeviceIntPtr kbd,xkbAccessXNotify *pEv)
+{
+int initialized;
+XkbInterestPtr interest;
+Time time = 0;
+CARD16 sk_delay,db_delay;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ sk_delay= pEv->slowKeysDelay;
+ db_delay= pEv->debounceDelay;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->accessXNotifyMask&(1<<pEv->detail)) &&
+ XIShouldNotify(interest->client, kbd)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbAccessXNotify;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->slowKeysDelay = sk_delay;
+ pEv->debounceDelay = db_delay;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ swaps(&pEv->slowKeysDelay,n);
+ swaps(&pEv->debounceDelay,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendNamesNotify(DeviceIntPtr kbd,xkbNamesNotify *pEv)
+{
+int initialized;
+XkbInterestPtr interest;
+Time time = 0;
+CARD16 changed,changedVirtualMods;
+CARD32 changedIndicators;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ changed= pEv->changed;
+ changedIndicators= pEv->changedIndicators;
+ changedVirtualMods= pEv->changedVirtualMods;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->namesNotifyMask&pEv->changed) &&
+ XIShouldNotify(interest->client, kbd)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbNamesNotify;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->changed = changed;
+ pEv->changedIndicators = changedIndicators;
+ pEv->changedVirtualMods= changedVirtualMods;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ swaps(&pEv->changed,n);
+ swapl(&pEv->changedIndicators,n);
+ swaps(&pEv->changedVirtualMods,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendCompatMapNotify(DeviceIntPtr kbd,xkbCompatMapNotify *pEv)
+{
+int initialized;
+XkbInterestPtr interest;
+Time time = 0;
+CARD16 firstSI = 0, nSI = 0, nTotalSI = 0;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->compatNotifyMask) &&
+ XIShouldNotify(interest->client, kbd)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbCompatMapNotify;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ firstSI= pEv->firstSI;
+ nSI= pEv->nSI;
+ nTotalSI= pEv->nTotalSI;
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->firstSI = firstSI;
+ pEv->nSI = nSI;
+ pEv->nTotalSI = nTotalSI;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ swaps(&pEv->firstSI,n);
+ swaps(&pEv->nSI,n);
+ swaps(&pEv->nTotalSI,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendActionMessage(DeviceIntPtr kbd,xkbActionMessage *pEv)
+{
+int initialized;
+XkbSrvInfoPtr xkbi;
+XkbInterestPtr interest;
+Time time = 0;
+
+ interest = kbd->xkb_interest;
+ if (!interest || !kbd->key || !kbd->key->xkbInfo)
+ return;
+
+ xkbi = kbd->key->xkbInfo;
+
+ initialized = 0;
+ pEv->mods= xkbi->state.mods;
+ pEv->group= xkbi->state.group;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->actionMessageMask) &&
+ XIShouldNotify(interest->client, kbd)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbActionMessage;
+ pEv->deviceID = kbd->id;
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendExtensionDeviceNotify( DeviceIntPtr dev,
+ ClientPtr client,
+ xkbExtensionDeviceNotify * pEv)
+{
+int initialized;
+XkbInterestPtr interest;
+Time time = 0;
+CARD32 defined, state;
+CARD16 reason;
+
+ interest = dev->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ reason= pEv->reason;
+ defined= pEv->ledsDefined;
+ state= pEv->ledState;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->extDevNotifyMask&reason) &&
+ XIShouldNotify(interest->client, dev)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbExtensionDeviceNotify;
+ pEv->deviceID = dev->id;
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ else {
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->ledsDefined= defined;
+ pEv->ledState= state;
+ pEv->reason= reason;
+ pEv->supported= XkbXI_AllFeaturesMask;
+ }
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ swapl(&pEv->ledsDefined,n);
+ swapl(&pEv->ledState,n);
+ swaps(&pEv->reason,n);
+ swaps(&pEv->supported,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendNotification( DeviceIntPtr kbd,
+ XkbChangesPtr pChanges,
+ XkbEventCausePtr cause)
+{
+XkbSrvLedInfoPtr sli;
+
+ sli= NULL;
+ if (pChanges->state_changes) {
+ xkbStateNotify sn;
+ sn.changed= pChanges->state_changes;
+ sn.keycode= cause->kc;
+ sn.eventType= cause->event;
+ sn.requestMajor= cause->mjr;
+ sn.requestMinor= cause->mnr;
+ XkbSendStateNotify(kbd,&sn);
+ }
+ if (pChanges->map.changed) {
+ xkbMapNotify mn;
+ memset(&mn, 0, sizeof(xkbMapNotify));
+ mn.changed= pChanges->map.changed;
+ mn.firstType= pChanges->map.first_type;
+ mn.nTypes= pChanges->map.num_types;
+ mn.firstKeySym= pChanges->map.first_key_sym;
+ mn.nKeySyms= pChanges->map.num_key_syms;
+ mn.firstKeyAct= pChanges->map.first_key_act;
+ mn.nKeyActs= pChanges->map.num_key_acts;
+ mn.firstKeyBehavior= pChanges->map.first_key_behavior;
+ mn.nKeyBehaviors= pChanges->map.num_key_behaviors;
+ mn.virtualMods= pChanges->map.vmods;
+ mn.firstKeyExplicit= pChanges->map.first_key_explicit;
+ mn.nKeyExplicit= pChanges->map.num_key_explicit;
+ mn.firstModMapKey= pChanges->map.first_modmap_key;
+ mn.nModMapKeys= pChanges->map.num_modmap_keys;
+ mn.firstVModMapKey= pChanges->map.first_vmodmap_key;
+ mn.nVModMapKeys= pChanges->map.num_vmodmap_keys;
+ XkbSendMapNotify(kbd,&mn);
+ }
+ if ((pChanges->ctrls.changed_ctrls)||
+ (pChanges->ctrls.enabled_ctrls_changes)) {
+ xkbControlsNotify cn;
+ memset(&cn, 0, sizeof(xkbControlsNotify));
+ cn.changedControls= pChanges->ctrls.changed_ctrls;
+ cn.enabledControlChanges= pChanges->ctrls.enabled_ctrls_changes;
+ cn.keycode= cause->kc;
+ cn.eventType= cause->event;
+ cn.requestMajor= cause->mjr;
+ cn.requestMinor= cause->mnr;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+ if (pChanges->indicators.map_changes) {
+ xkbIndicatorNotify in;
+ if (sli==NULL)
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ memset(&in, 0, sizeof(xkbIndicatorNotify));
+ in.state= sli->effectiveState;
+ in.changed= pChanges->indicators.map_changes;
+ XkbSendIndicatorNotify(kbd,XkbIndicatorMapNotify,&in);
+ }
+ if (pChanges->indicators.state_changes) {
+ xkbIndicatorNotify in;
+ if (sli==NULL)
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ memset(&in, 0, sizeof(xkbIndicatorNotify));
+ in.state= sli->effectiveState;
+ in.changed= pChanges->indicators.state_changes;
+ XkbSendIndicatorNotify(kbd,XkbIndicatorStateNotify,&in);
+ }
+ if (pChanges->names.changed) {
+ xkbNamesNotify nn;
+ memset(&nn, 0, sizeof(xkbNamesNotify));
+ nn.changed= pChanges->names.changed;
+ nn.firstType= pChanges->names.first_type;
+ nn.nTypes= pChanges->names.num_types;
+ nn.firstLevelName= pChanges->names.first_lvl;
+ nn.nLevelNames= pChanges->names.num_lvls;
+ nn.nRadioGroups= pChanges->names.num_rg;
+ nn.changedVirtualMods= pChanges->names.changed_vmods;
+ nn.changedIndicators= pChanges->names.changed_indicators;
+ XkbSendNamesNotify(kbd,&nn);
+ }
+ if ((pChanges->compat.changed_groups)||(pChanges->compat.num_si>0)) {
+ xkbCompatMapNotify cmn;
+ memset(&cmn, 0, sizeof(xkbCompatMapNotify));
+ cmn.changedGroups= pChanges->compat.changed_groups;
+ cmn.firstSI= pChanges->compat.first_si;
+ cmn.nSI= pChanges->compat.num_si;
+ cmn.nTotalSI= kbd->key->xkbInfo->desc->compat->num_si;
+ XkbSendCompatMapNotify(kbd,&cmn);
+ }
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFilterEvents(ClientPtr client,int nEvents,xEvent *xE)
+{
+ DeviceIntPtr dev = NULL;
+ XkbSrvInfoPtr xkbi;
+ CARD8 type = xE[0].u.u.type;
+
+ if (xE->u.u.type & EXTENSION_EVENT_BASE)
+ dev = XIGetDevice(xE);
+
+ if (!dev)
+ dev = PickKeyboard(client);
+
+ if (!dev->key)
+ return;
+
+ xkbi = dev->key->xkbInfo;
+
+ if (client->xkbClientFlags & _XkbClientInitialized) {
+ if ((xkbDebugFlags&0x10)&&
+ (type == KeyPress || type == KeyRelease ||
+ type == DeviceKeyPress || type == DeviceKeyRelease))
+ DebugF("[xkb] XkbFilterWriteEvents (XKB client): state 0x%04x\n",
+ xE[0].u.keyButtonPointer.state);
+
+ if (dev->deviceGrab.grab != NullGrab && dev->deviceGrab.fromPassiveGrab &&
+ (type == KeyPress || type == KeyRelease ||
+ type == DeviceKeyPress || type == DeviceKeyRelease)) {
+ unsigned int state, flags;
+
+ flags = client->xkbClientFlags;
+ state = xkbi->state.compat_grab_mods;
+ if (flags & XkbPCF_GrabsUseXKBStateMask) {
+ int group;
+ if (flags & XkbPCF_LookupStateWhenGrabbed) {
+ group = xkbi->state.group;
+ state = xkbi->state.lookup_mods;
+ }
+ else {
+ state = xkbi->state.grab_mods;
+ group = xkbi->state.base_group + xkbi->state.latched_group;
+ if (group < 0 || group >= xkbi->desc->ctrls->num_groups)
+ group = XkbAdjustGroup(group, xkbi->desc->ctrls);
+ }
+ state = XkbBuildCoreState(state, group);
+ }
+ else if (flags & XkbPCF_LookupStateWhenGrabbed) {
+ state = xkbi->state.compat_lookup_mods;
+ }
+ xE[0].u.keyButtonPointer.state = state;
+ }
+ }
+ else {
+ if ((xkbDebugFlags & 0x4) &&
+ (xE[0].u.u.type == KeyPress || xE[0].u.u.type==KeyRelease ||
+ xE[0].u.u.type == DeviceKeyPress ||
+ xE[0].u.u.type == DeviceKeyRelease)) {
+ DebugF("[xkb] XKbFilterWriteEvents (non-XKB):\n");
+ DebugF("[xkb] event= 0x%04x\n",xE[0].u.keyButtonPointer.state);
+ DebugF("[xkb] lookup= 0x%02x, grab= 0x%02x\n",
+ xkbi->state.lookup_mods, xkbi->state.grab_mods);
+ DebugF("[xkb] compat lookup= 0x%02x, grab= 0x%02x\n",
+ xkbi->state.compat_lookup_mods, xkbi->state.compat_grab_mods);
+ }
+ if (type >= KeyPress && type <= MotionNotify) {
+ CARD16 old, new;
+
+ old = xE[0].u.keyButtonPointer.state & ~0x1f00;
+ new = xE[0].u.keyButtonPointer.state & 0x1F00;
+
+ if (old == XkbStateFieldFromRec(&xkbi->state))
+ new |= xkbi->state.compat_lookup_mods;
+ else
+ new |= xkbi->state.compat_grab_mods;
+ xE[0].u.keyButtonPointer.state = new;
+ }
+ else if (type == EnterNotify || type == LeaveNotify) {
+ xE[0].u.enterLeave.state &= 0x1F00;
+ xE[0].u.enterLeave.state |= xkbi->state.compat_grab_mods;
+ }
+ else if (type >= DeviceKeyPress && type <= DeviceMotionNotify) {
+ CARD16 old, new;
+ deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer*) &xE[0];
+
+ old = kbp->state & ~0x1F00;
+ new = kbp->state & 0x1F00;
+ if (old == XkbStateFieldFromRec(&xkbi->state))
+ new |= xkbi->state.compat_lookup_mods;
+ else
+ new |= xkbi->state.compat_grab_mods;
+ kbp->state = new;
+ }
+ }
+}
+
+/***====================================================================***/
+
+XkbInterestPtr
+XkbFindClientResource(DevicePtr inDev,ClientPtr client)
+{
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+
+ if ( dev->xkb_interest ) {
+ interest = dev->xkb_interest;
+ while (interest){
+ if (interest->client==client) {
+ return interest;
+ }
+ interest = interest->next;
+ }
+ }
+ return NULL;
+}
+
+XkbInterestPtr
+XkbAddClientResource(DevicePtr inDev,ClientPtr client,XID id)
+{
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+
+ interest = dev->xkb_interest;
+ while (interest) {
+ if (interest->client==client)
+ return ((interest->resource==id)?interest:NULL);
+ interest = interest->next;
+ }
+ interest = calloc(1, sizeof(XkbInterestRec));
+ if (interest) {
+ interest->dev = dev;
+ interest->client = client;
+ interest->resource = id;
+ interest->stateNotifyMask= 0;
+ interest->ctrlsNotifyMask= 0;
+ interest->namesNotifyMask= 0;
+ interest->compatNotifyMask= 0;
+ interest->bellNotifyMask= FALSE;
+ interest->accessXNotifyMask= 0;
+ interest->iStateNotifyMask= 0;
+ interest->iMapNotifyMask= 0;
+ interest->altSymsNotifyMask= 0;
+ interest->next = dev->xkb_interest;
+ dev->xkb_interest= interest;
+ return interest;
+ }
+ return NULL;
+}
+
+int
+XkbRemoveResourceClient(DevicePtr inDev,XID id)
+{
+XkbSrvInfoPtr xkbi;
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+Bool found;
+unsigned long autoCtrls,autoValues;
+ClientPtr client = NULL;
+
+ found= FALSE;
+
+ if (!dev->key || !dev->key->xkbInfo)
+ return found;
+
+ autoCtrls= autoValues= 0;
+ if ( dev->xkb_interest ) {
+ interest = dev->xkb_interest;
+ if (interest && (interest->resource==id)){
+ dev->xkb_interest = interest->next;
+ autoCtrls= interest->autoCtrls;
+ autoValues= interest->autoCtrlValues;
+ client= interest->client;
+ free(interest);
+ found= TRUE;
+ }
+ while ((!found)&&(interest->next)) {
+ if (interest->next->resource==id) {
+ XkbInterestPtr victim = interest->next;
+ interest->next = victim->next;
+ autoCtrls= victim->autoCtrls;
+ autoValues= victim->autoCtrlValues;
+ client= victim->client;
+ free(victim);
+ found= TRUE;
+ }
+ interest = interest->next;
+ }
+ }
+ if (found && autoCtrls && dev->key && dev->key->xkbInfo ) {
+ XkbEventCauseRec cause;
+
+ xkbi= dev->key->xkbInfo;
+ XkbSetCauseXkbReq(&cause,X_kbPerClientFlags,client);
+ XkbEnableDisableControls(xkbi,autoCtrls,autoValues,NULL,&cause);
+ }
+ return found;
+}
diff --git a/xorg-server/xkb/xkbInit.c b/xorg-server/xkb/xkbInit.c
index 57b450c49..3da625a5b 100644
--- a/xorg-server/xkb/xkbInit.c
+++ b/xorg-server/xkb/xkbInit.c
@@ -1,779 +1,779 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <xkb-config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <math.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-#include "misc.h"
-#include "inputstr.h"
-#include "opaque.h"
-#include "property.h"
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-#include "xkbgeom.h"
-#include <X11/extensions/XKMformat.h>
-#include "xkbfile.h"
-#include "xkb.h"
-
-#define CREATE_ATOM(s) MakeAtom(s,sizeof(s)-1,1)
-
-#if defined(__alpha) || defined(__alpha__)
-#define LED_COMPOSE 2
-#define LED_CAPS 3
-#define LED_SCROLL 4
-#define LED_NUM 5
-#define PHYS_LEDS 0x1f
-#else
-#ifdef sun
-#define LED_NUM 1
-#define LED_SCROLL 2
-#define LED_COMPOSE 3
-#define LED_CAPS 4
-#define PHYS_LEDS 0x0f
-#else
-#define LED_CAPS 1
-#define LED_NUM 2
-#define LED_SCROLL 3
-#define PHYS_LEDS 0x07
-#endif
-#endif
-
-#define MAX_TOC 16
-typedef struct _SrvXkmInfo {
- DeviceIntPtr dev;
- FILE * file;
- XkbDescPtr xkb;
-} SrvXkmInfo;
-
-
-/***====================================================================***/
-
-#ifndef XKB_DFLT_RULES_PROP
-#define XKB_DFLT_RULES_PROP TRUE
-#endif
-
-const char * XkbBaseDirectory= XKB_BASE_DIRECTORY;
-const char * XkbBinDirectory= XKB_BIN_DIRECTORY;
-static int XkbWantAccessX= 0;
-
-static char * XkbRulesDflt= NULL;
-static char * XkbModelDflt= NULL;
-static char * XkbLayoutDflt= NULL;
-static char * XkbVariantDflt= NULL;
-static char * XkbOptionsDflt= NULL;
-
-static char * XkbRulesUsed= NULL;
-static char * XkbModelUsed= NULL;
-static char * XkbLayoutUsed= NULL;
-static char * XkbVariantUsed= NULL;
-static char * XkbOptionsUsed= NULL;
-
-static XkbDescPtr xkb_cached_map = NULL;
-
-static Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP;
-
-/***====================================================================***/
-
-/**
- * Get the current default XKB rules.
- * Caller must free the data in rmlvo.
- */
-void
-XkbGetRulesDflts(XkbRMLVOSet *rmlvo)
-{
- if (XkbRulesDflt) rmlvo->rules = XkbRulesDflt;
- else rmlvo->rules = XKB_DFLT_RULES;
- if (XkbModelDflt) rmlvo->model= XkbModelDflt;
- else rmlvo->model= XKB_DFLT_MODEL;
- if (XkbLayoutDflt) rmlvo->layout= XkbLayoutDflt;
- else rmlvo->layout= XKB_DFLT_LAYOUT;
- if (XkbVariantDflt) rmlvo->variant= XkbVariantDflt;
- else rmlvo->variant= XKB_DFLT_VARIANT;
- if (XkbOptionsDflt) rmlvo->options= XkbOptionsDflt;
- else rmlvo->options= XKB_DFLT_OPTIONS;
-
- rmlvo->rules = strdup(rmlvo->rules);
- rmlvo->model = strdup(rmlvo->model);
- rmlvo->layout = strdup(rmlvo->layout);
- rmlvo->variant = strdup(rmlvo->variant);
- rmlvo->options = strdup(rmlvo->options);
-}
-
-void
-XkbFreeRMLVOSet(XkbRMLVOSet *rmlvo, Bool freeRMLVO)
-{
- if (!rmlvo)
- return;
-
- xfree(rmlvo->rules);
- xfree(rmlvo->model);
- xfree(rmlvo->layout);
- xfree(rmlvo->variant);
- xfree(rmlvo->options);
-
- if (freeRMLVO)
- xfree(rmlvo);
- else
- memset(rmlvo, 0, sizeof(XkbRMLVOSet));
-}
-
-static Bool
-XkbWriteRulesProp(ClientPtr client, pointer closure)
-{
-int len,out;
-Atom name;
-char * pval;
-
- len= (XkbRulesUsed?strlen(XkbRulesUsed):0);
- len+= (XkbModelUsed?strlen(XkbModelUsed):0);
- len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0);
- len+= (XkbVariantUsed?strlen(XkbVariantUsed):0);
- len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0);
- if (len<1)
- return TRUE;
-
- len+= 5; /* trailing NULs */
-
- name= MakeAtom(_XKB_RF_NAMES_PROP_ATOM,strlen(_XKB_RF_NAMES_PROP_ATOM),1);
- if (name==None) {
- ErrorF("[xkb] Atom error: %s not created\n",_XKB_RF_NAMES_PROP_ATOM);
- return TRUE;
- }
- pval= (char*) xalloc(len);
- if (!pval) {
- ErrorF("[xkb] Allocation error: %s proprerty not created\n",
- _XKB_RF_NAMES_PROP_ATOM);
- return TRUE;
- }
- out= 0;
- if (XkbRulesUsed) {
- strcpy(&pval[out],XkbRulesUsed);
- out+= strlen(XkbRulesUsed);
- }
- pval[out++]= '\0';
- if (XkbModelUsed) {
- strcpy(&pval[out],XkbModelUsed);
- out+= strlen(XkbModelUsed);
- }
- pval[out++]= '\0';
- if (XkbLayoutUsed) {
- strcpy(&pval[out],XkbLayoutUsed);
- out+= strlen(XkbLayoutUsed);
- }
- pval[out++]= '\0';
- if (XkbVariantUsed) {
- strcpy(&pval[out],XkbVariantUsed);
- out+= strlen(XkbVariantUsed);
- }
- pval[out++]= '\0';
- if (XkbOptionsUsed) {
- strcpy(&pval[out],XkbOptionsUsed);
- out+= strlen(XkbOptionsUsed);
- }
- pval[out++]= '\0';
- if (out!=len) {
- ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
- out,len);
- }
- dixChangeWindowProperty(serverClient, WindowTable[0], name, XA_STRING, 8,
- PropModeReplace, len, pval, TRUE);
- xfree(pval);
- return TRUE;
-}
-
-static void
-XkbSetRulesUsed(XkbRMLVOSet *rmlvo)
-{
- if (XkbRulesUsed)
- xfree(XkbRulesUsed);
- XkbRulesUsed= (rmlvo->rules?_XkbDupString(rmlvo->rules):NULL);
- if (XkbModelUsed)
- xfree(XkbModelUsed);
- XkbModelUsed= (rmlvo->model?_XkbDupString(rmlvo->model):NULL);
- if (XkbLayoutUsed)
- xfree(XkbLayoutUsed);
- XkbLayoutUsed= (rmlvo->layout?_XkbDupString(rmlvo->layout):NULL);
- if (XkbVariantUsed)
- xfree(XkbVariantUsed);
- XkbVariantUsed= (rmlvo->variant?_XkbDupString(rmlvo->variant):NULL);
- if (XkbOptionsUsed)
- xfree(XkbOptionsUsed);
- XkbOptionsUsed= (rmlvo->options?_XkbDupString(rmlvo->options):NULL);
- if (XkbWantRulesProp)
- QueueWorkProc(XkbWriteRulesProp,NULL,NULL);
- return;
-}
-
-void
-XkbSetRulesDflts(XkbRMLVOSet *rmlvo)
-{
- if (rmlvo->rules) {
- if (XkbRulesDflt)
- xfree(XkbRulesDflt);
- XkbRulesDflt= _XkbDupString(rmlvo->rules);
- }
- if (rmlvo->model) {
- if (XkbModelDflt)
- xfree(XkbModelDflt);
- XkbModelDflt= _XkbDupString(rmlvo->model);
- }
- if (rmlvo->layout) {
- if (XkbLayoutDflt)
- xfree(XkbLayoutDflt);
- XkbLayoutDflt= _XkbDupString(rmlvo->layout);
- }
- if (rmlvo->variant) {
- if (XkbVariantDflt)
- xfree(XkbVariantDflt);
- XkbVariantDflt= _XkbDupString(rmlvo->variant);
- }
- if (rmlvo->options) {
- if (XkbOptionsDflt)
- xfree(XkbOptionsDflt);
- XkbOptionsDflt= _XkbDupString(rmlvo->options);
- }
- return;
-}
-
-void
-XkbDeleteRulesDflts(void)
-{
- xfree(XkbRulesDflt);
- XkbRulesDflt = NULL;
- xfree(XkbModelDflt);
- XkbModelDflt = NULL;
- xfree(XkbLayoutDflt);
- XkbLayoutDflt = NULL;
- xfree(XkbVariantDflt);
- XkbVariantDflt = NULL;
- xfree(XkbOptionsDflt);
- XkbOptionsDflt = NULL;
-
- XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
- xkb_cached_map = NULL;
-}
-
-#define DIFFERS(a, b) (strcmp((a) ? (a) : "", (b) ? (b) : "") != 0)
-
-static Bool
-XkbCompareUsedRMLVO(XkbRMLVOSet *rmlvo)
-{
- if (DIFFERS(rmlvo->rules, XkbRulesUsed) ||
- DIFFERS(rmlvo->model, XkbModelUsed) ||
- DIFFERS(rmlvo->layout, XkbLayoutUsed) ||
- DIFFERS(rmlvo->variant, XkbVariantUsed) ||
- DIFFERS(rmlvo->options, XkbOptionsUsed))
- return FALSE;
- return TRUE;
-}
-
-#undef DIFFERS
-
-/***====================================================================***/
-
-#include "xkbDflts.h"
-
-static Bool
-XkbInitKeyTypes(XkbDescPtr xkb)
-{
- if (xkb->defined & XkmTypesMask)
- return TRUE;
-
- initTypeNames(NULL);
- if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_dflt_types)!=Success)
- return FALSE;
- if (XkbCopyKeyTypes(dflt_types,xkb->map->types,num_dflt_types)!=
- Success) {
- return FALSE;
- }
- xkb->map->size_types= xkb->map->num_types= num_dflt_types;
- return TRUE;
-}
-
-static void
-XkbInitRadioGroups(XkbSrvInfoPtr xkbi)
-{
- xkbi->nRadioGroups = 0;
- xkbi->radioGroups = NULL;
- return;
-}
-
-
-static Status
-XkbInitCompatStructs(XkbDescPtr xkb)
-{
-register int i;
-XkbCompatMapPtr compat;
-
- if (xkb->defined & XkmCompatMapMask)
- return TRUE;
-
- if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_dfltSI)!=Success)
- return BadAlloc;
- compat = xkb->compat;
- if (compat->sym_interpret) {
- compat->num_si = num_dfltSI;
- memcpy((char *)compat->sym_interpret,(char *)dfltSI,sizeof(dfltSI));
- }
- for (i=0;i<XkbNumKbdGroups;i++) {
- compat->groups[i]= compatMap.groups[i];
- if (compat->groups[i].vmods!=0) {
- unsigned mask;
- mask= XkbMaskForVMask(xkb,compat->groups[i].vmods);
- compat->groups[i].mask= compat->groups[i].real_mods|mask;
- }
- else compat->groups[i].mask= compat->groups[i].real_mods;
- }
- return Success;
-}
-
-static void
-XkbInitSemantics(XkbDescPtr xkb)
-{
- XkbInitKeyTypes(xkb);
- XkbInitCompatStructs(xkb);
- return;
-}
-
-/***====================================================================***/
-
-static Status
-XkbInitNames(XkbSrvInfoPtr xkbi)
-{
-XkbDescPtr xkb;
-XkbNamesPtr names;
-Status rtrn;
-Atom unknown;
-
- xkb= xkbi->desc;
- if ((rtrn=XkbAllocNames(xkb,XkbAllNamesMask,0,0))!=Success)
- return rtrn;
- unknown= CREATE_ATOM("unknown");
- names = xkb->names;
- if (names->keycodes==None) names->keycodes= unknown;
- if (names->geometry==None) names->geometry= unknown;
- if (names->phys_symbols==None) names->phys_symbols= unknown;
- if (names->symbols==None) names->symbols= unknown;
- if (names->types==None) names->types= unknown;
- if (names->compat==None) names->compat= unknown;
- if (!(xkb->defined & XkmVirtualModsMask)) {
- if (names->vmods[vmod_NumLock]==None)
- names->vmods[vmod_NumLock]= CREATE_ATOM("NumLock");
- if (names->vmods[vmod_Alt]==None)
- names->vmods[vmod_Alt]= CREATE_ATOM("Alt");
- if (names->vmods[vmod_AltGr]==None)
- names->vmods[vmod_AltGr]= CREATE_ATOM("ModeSwitch");
- }
-
- if (!(xkb->defined & XkmIndicatorsMask) ||
- !(xkb->defined & XkmGeometryMask)) {
- initIndicatorNames(NULL,xkb);
- if (names->indicators[LED_CAPS-1]==None)
- names->indicators[LED_CAPS-1] = CREATE_ATOM("Caps Lock");
- if (names->indicators[LED_NUM-1]==None)
- names->indicators[LED_NUM-1] = CREATE_ATOM("Num Lock");
- if (names->indicators[LED_SCROLL-1]==None)
- names->indicators[LED_SCROLL-1] = CREATE_ATOM("Scroll Lock");
-#ifdef LED_COMPOSE
- if (names->indicators[LED_COMPOSE-1]==None)
- names->indicators[LED_COMPOSE-1] = CREATE_ATOM("Compose");
-#endif
- }
-
- if (xkb->geom!=NULL)
- names->geometry= xkb->geom->name;
- else names->geometry= unknown;
-
- return Success;
-}
-
-static Status
-XkbInitIndicatorMap(XkbSrvInfoPtr xkbi)
-{
-XkbDescPtr xkb;
-XkbIndicatorPtr map;
-XkbSrvLedInfoPtr sli;
-
- xkb= xkbi->desc;
- if (XkbAllocIndicatorMaps(xkb)!=Success)
- return BadAlloc;
-
- if (!(xkb->defined & XkmIndicatorsMask)) {
- map= xkb->indicators;
- map->phys_indicators = PHYS_LEDS;
- map->maps[LED_CAPS-1].flags= XkbIM_NoExplicit;
- map->maps[LED_CAPS-1].which_mods= XkbIM_UseLocked;
- map->maps[LED_CAPS-1].mods.mask= LockMask;
- map->maps[LED_CAPS-1].mods.real_mods= LockMask;
-
- map->maps[LED_NUM-1].flags= XkbIM_NoExplicit;
- map->maps[LED_NUM-1].which_mods= XkbIM_UseLocked;
- map->maps[LED_NUM-1].mods.mask= 0;
- map->maps[LED_NUM-1].mods.real_mods= 0;
- map->maps[LED_NUM-1].mods.vmods= vmod_NumLockMask;
-
- map->maps[LED_SCROLL-1].flags= XkbIM_NoExplicit;
- map->maps[LED_SCROLL-1].which_mods= XkbIM_UseLocked;
- map->maps[LED_SCROLL-1].mods.mask= Mod3Mask;
- map->maps[LED_SCROLL-1].mods.real_mods= Mod3Mask;
- }
-
- sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
- if (sli)
- XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask);
-
- return Success;
-}
-
-static Status
-XkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi)
-{
-XkbDescPtr xkb;
-XkbControlsPtr ctrls;
-
- xkb= xkbi->desc;
- /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */
- if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success)
- FatalError("Couldn't allocate keyboard controls\n");
- ctrls= xkb->ctrls;
- if (!(xkb->defined & XkmSymbolsMask))
- ctrls->num_groups = 1;
- ctrls->groups_wrap = XkbSetGroupInfo(1,XkbWrapIntoRange,0);
- ctrls->internal.mask = 0;
- ctrls->internal.real_mods = 0;
- ctrls->internal.vmods = 0;
- ctrls->ignore_lock.mask = 0;
- ctrls->ignore_lock.real_mods = 0;
- ctrls->ignore_lock.vmods = 0;
- ctrls->enabled_ctrls = XkbAccessXTimeoutMask|XkbRepeatKeysMask|
- XkbMouseKeysAccelMask|XkbAudibleBellMask|
- XkbIgnoreGroupLockMask;
- if (XkbWantAccessX)
- ctrls->enabled_ctrls|= XkbAccessXKeysMask;
- AccessXInit(pXDev);
- return Success;
-}
-
-_X_EXPORT Bool
-InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo,
- BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
-{
- int i;
- unsigned int check;
- XkbSrvInfoPtr xkbi;
- XkbDescPtr xkb;
- XkbSrvLedInfoPtr sli;
- XkbChangesRec changes;
- XkbEventCauseRec cause;
- XkbRMLVOSet rmlvo_dflts = { NULL };
-
- if (dev->key || dev->kbdfeed)
- return FALSE;
-
- if (!rmlvo)
- {
- rmlvo = &rmlvo_dflts;
- XkbGetRulesDflts(rmlvo);
- }
-
-
- memset(&changes, 0, sizeof(changes));
- XkbSetCauseUnknown(&cause);
-
- dev->key = xcalloc(1, sizeof(*dev->key));
- if (!dev->key) {
- ErrorF("XKB: Failed to allocate key class\n");
- return FALSE;
- }
- dev->key->sourceid = dev->id;
-
- dev->kbdfeed = xcalloc(1, sizeof(*dev->kbdfeed));
- if (!dev->kbdfeed) {
- ErrorF("XKB: Failed to allocate key feedback class\n");
- goto unwind_key;
- }
-
- xkbi = xcalloc(1, sizeof(*xkbi));
- if (!xkbi) {
- ErrorF("XKB: Failed to allocate XKB info\n");
- goto unwind_kbdfeed;
- }
- dev->key->xkbInfo = xkbi;
-
- if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
- XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
- xkb_cached_map = NULL;
- }
-
- if (xkb_cached_map)
- LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
- else {
- xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
- if (!xkb_cached_map) {
- ErrorF("XKB: Failed to compile keymap\n");
- goto unwind_info;
- }
- }
-
- xkb = XkbAllocKeyboard();
- if (!xkb) {
- ErrorF("XKB: Failed to allocate keyboard description\n");
- goto unwind_info;
- }
-
- if (!XkbCopyKeymap(xkb, xkb_cached_map)) {
- ErrorF("XKB: Failed to copy keymap\n");
- goto unwind_desc;
- }
- xkb->defined = xkb_cached_map->defined;
- xkb->flags = xkb_cached_map->flags;
- xkb->device_spec = xkb_cached_map->device_spec;
- xkbi->desc = xkb;
-
- if (xkb->min_key_code == 0)
- xkb->min_key_code = 8;
- if (xkb->max_key_code == 0)
- xkb->max_key_code = 255;
-
- i = XkbNumKeys(xkb) / 3 + 1;
- if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success)
- goto unwind_desc;
- if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success)
- goto unwind_desc;
-
- xkbi->dfltPtrDelta = 1;
- xkbi->device = dev;
-
- XkbInitSemantics(xkb);
- XkbInitNames(xkbi);
- XkbInitRadioGroups(xkbi);
-
- XkbInitControls(dev, xkbi);
-
- XkbInitIndicatorMap(xkbi);
-
- XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
- &check, &cause);
-
- InitFocusClassDeviceStruct(dev);
-
- xkbi->kbdProc = ctrl_func;
- dev->kbdfeed->BellProc = bell_func;
- dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc;
-
- dev->kbdfeed->ctrl = defaultKeyboardControl;
- if (dev->kbdfeed->ctrl.autoRepeat)
- xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask;
-
- memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat,
- XkbPerKeyBitArraySize);
-
- sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
- if (sli)
- XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask);
- else
- DebugF("XKB: No indicator feedback in XkbFinishInit!\n");
-
- dev->kbdfeed->CtrlProc(dev,&dev->kbdfeed->ctrl);
-
- XkbSetRulesDflts(rmlvo);
- XkbSetRulesUsed(rmlvo);
- XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
-
- return TRUE;
-
-unwind_desc:
- XkbFreeKeyboard(xkb, 0, TRUE);
-unwind_info:
- xfree(xkbi);
- dev->key->xkbInfo = NULL;
-unwind_kbdfeed:
- xfree(dev->kbdfeed);
- dev->kbdfeed = NULL;
-unwind_key:
- xfree(dev->key);
- dev->key = NULL;
- return FALSE;
-}
-
-
-/***====================================================================***/
-
- /*
- * Be very careful about what does and doesn't get freed by this
- * function. To reduce fragmentation, XkbInitDevice allocates a
- * single huge block per device and divides it up into most of the
- * fixed-size structures for the device. Don't free anything that
- * is part of this larger block.
- */
-void
-XkbFreeInfo(XkbSrvInfoPtr xkbi)
-{
- if (xkbi->radioGroups) {
- xfree(xkbi->radioGroups);
- xkbi->radioGroups= NULL;
- }
- if (xkbi->mouseKeyTimer) {
- TimerFree(xkbi->mouseKeyTimer);
- xkbi->mouseKeyTimer= NULL;
- }
- if (xkbi->slowKeysTimer) {
- TimerFree(xkbi->slowKeysTimer);
- xkbi->slowKeysTimer= NULL;
- }
- if (xkbi->bounceKeysTimer) {
- TimerFree(xkbi->bounceKeysTimer);
- xkbi->bounceKeysTimer= NULL;
- }
- if (xkbi->repeatKeyTimer) {
- TimerFree(xkbi->repeatKeyTimer);
- xkbi->repeatKeyTimer= NULL;
- }
- if (xkbi->krgTimer) {
- TimerFree(xkbi->krgTimer);
- xkbi->krgTimer= NULL;
- }
- xkbi->beepType= _BEEP_NONE;
- if (xkbi->beepTimer) {
- TimerFree(xkbi->beepTimer);
- xkbi->beepTimer= NULL;
- }
- if (xkbi->desc) {
- XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,TRUE);
- xkbi->desc= NULL;
- }
- xfree(xkbi);
- return;
-}
-
-/***====================================================================***/
-
-extern int XkbDfltRepeatDelay;
-extern int XkbDfltRepeatInterval;
-
-extern unsigned short XkbDfltAccessXTimeout;
-extern unsigned int XkbDfltAccessXTimeoutMask;
-extern unsigned int XkbDfltAccessXFeedback;
-extern unsigned char XkbDfltAccessXOptions;
-
-int
-XkbProcessArguments(int argc,char *argv[],int i)
-{
- if (strncmp(argv[i], "-xkbdir", 7) == 0) {
- if(++i < argc) {
-#if !defined(WIN32) && !defined(__CYGWIN__)
- if (getuid() != geteuid()) {
- LogMessage(X_WARNING, "-xkbdir is not available for setuid X servers\n");
- return -1;
- } else
-#endif
- {
- if (strlen(argv[i]) < PATH_MAX) {
- XkbBaseDirectory= argv[i];
- return 2;
- } else {
- LogMessage(X_ERROR, "-xkbdir pathname too long\n");
- return -1;
- }
- }
- }
- else {
- return -1;
- }
- }
- else if ((strncmp(argv[i],"-accessx",8)==0)||
- (strncmp(argv[i],"+accessx",8)==0)) {
- int j=1;
- if (argv[i][0]=='-')
- XkbWantAccessX= 0;
- else {
- XkbWantAccessX= 1;
-
- if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
- XkbDfltAccessXTimeout = atoi(argv[++i]);
- j++;
-
- if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
- /*
- * presumption that the reasonably useful range of
- * values fits in 0..MAXINT since SunOS 4 doesn't
- * have strtoul.
- */
- XkbDfltAccessXTimeoutMask=(unsigned int)
- strtol(argv[++i],NULL,16);
- j++;
- }
- if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
- if (argv[++i][0] == '1' )
- XkbDfltAccessXFeedback=XkbAccessXFeedbackMask;
- else
- XkbDfltAccessXFeedback=0;
- j++;
- }
- if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
- XkbDfltAccessXOptions=(unsigned char)
- strtol(argv[++i],NULL,16);
- j++;
- }
- }
- }
- return j;
- }
- if ((strcmp(argv[i], "-ardelay") == 0) ||
- (strcmp (argv[i], "-ar1") == 0)) { /* -ardelay int */
- if (++i >= argc) UseMsg ();
- XkbDfltRepeatDelay = (long)atoi(argv[i]);
- return 2;
- }
- if ((strcmp(argv[i], "-arinterval") == 0) ||
- (strcmp (argv[i], "-ar2") == 0)) { /* -arinterval int */
- if (++i >= argc) UseMsg ();
- XkbDfltRepeatInterval = (long)atoi(argv[i]);
- return 2;
- }
- return 0;
-}
-
-void
-XkbUseMsg(void)
-{
- ErrorF("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n");
- ErrorF(" enable/disable accessx key sequences\n");
- ErrorF("-ardelay set XKB autorepeat delay\n");
- ErrorF("-arinterval set XKB autorepeat interval\n");
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <xkb-config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <math.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "opaque.h"
+#include "property.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+#include <X11/extensions/XKMformat.h>
+#include "xkbfile.h"
+#include "xkb.h"
+
+#define CREATE_ATOM(s) MakeAtom(s,sizeof(s)-1,1)
+
+#if defined(__alpha) || defined(__alpha__)
+#define LED_COMPOSE 2
+#define LED_CAPS 3
+#define LED_SCROLL 4
+#define LED_NUM 5
+#define PHYS_LEDS 0x1f
+#else
+#ifdef sun
+#define LED_NUM 1
+#define LED_SCROLL 2
+#define LED_COMPOSE 3
+#define LED_CAPS 4
+#define PHYS_LEDS 0x0f
+#else
+#define LED_CAPS 1
+#define LED_NUM 2
+#define LED_SCROLL 3
+#define PHYS_LEDS 0x07
+#endif
+#endif
+
+#define MAX_TOC 16
+typedef struct _SrvXkmInfo {
+ DeviceIntPtr dev;
+ FILE * file;
+ XkbDescPtr xkb;
+} SrvXkmInfo;
+
+
+/***====================================================================***/
+
+#ifndef XKB_DFLT_RULES_PROP
+#define XKB_DFLT_RULES_PROP TRUE
+#endif
+
+const char * XkbBaseDirectory= XKB_BASE_DIRECTORY;
+const char * XkbBinDirectory= XKB_BIN_DIRECTORY;
+static int XkbWantAccessX= 0;
+
+static char * XkbRulesDflt= NULL;
+static char * XkbModelDflt= NULL;
+static char * XkbLayoutDflt= NULL;
+static char * XkbVariantDflt= NULL;
+static char * XkbOptionsDflt= NULL;
+
+static char * XkbRulesUsed= NULL;
+static char * XkbModelUsed= NULL;
+static char * XkbLayoutUsed= NULL;
+static char * XkbVariantUsed= NULL;
+static char * XkbOptionsUsed= NULL;
+
+static XkbDescPtr xkb_cached_map = NULL;
+
+static Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP;
+
+/***====================================================================***/
+
+/**
+ * Get the current default XKB rules.
+ * Caller must free the data in rmlvo.
+ */
+void
+XkbGetRulesDflts(XkbRMLVOSet *rmlvo)
+{
+ if (XkbRulesDflt) rmlvo->rules = XkbRulesDflt;
+ else rmlvo->rules = XKB_DFLT_RULES;
+ if (XkbModelDflt) rmlvo->model= XkbModelDflt;
+ else rmlvo->model= XKB_DFLT_MODEL;
+ if (XkbLayoutDflt) rmlvo->layout= XkbLayoutDflt;
+ else rmlvo->layout= XKB_DFLT_LAYOUT;
+ if (XkbVariantDflt) rmlvo->variant= XkbVariantDflt;
+ else rmlvo->variant= XKB_DFLT_VARIANT;
+ if (XkbOptionsDflt) rmlvo->options= XkbOptionsDflt;
+ else rmlvo->options= XKB_DFLT_OPTIONS;
+
+ rmlvo->rules = strdup(rmlvo->rules);
+ rmlvo->model = strdup(rmlvo->model);
+ rmlvo->layout = strdup(rmlvo->layout);
+ rmlvo->variant = strdup(rmlvo->variant);
+ rmlvo->options = strdup(rmlvo->options);
+}
+
+void
+XkbFreeRMLVOSet(XkbRMLVOSet *rmlvo, Bool freeRMLVO)
+{
+ if (!rmlvo)
+ return;
+
+ free(rmlvo->rules);
+ free(rmlvo->model);
+ free(rmlvo->layout);
+ free(rmlvo->variant);
+ free(rmlvo->options);
+
+ if (freeRMLVO)
+ free(rmlvo);
+ else
+ memset(rmlvo, 0, sizeof(XkbRMLVOSet));
+}
+
+static Bool
+XkbWriteRulesProp(ClientPtr client, pointer closure)
+{
+int len,out;
+Atom name;
+char * pval;
+
+ len= (XkbRulesUsed?strlen(XkbRulesUsed):0);
+ len+= (XkbModelUsed?strlen(XkbModelUsed):0);
+ len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0);
+ len+= (XkbVariantUsed?strlen(XkbVariantUsed):0);
+ len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0);
+ if (len<1)
+ return TRUE;
+
+ len+= 5; /* trailing NULs */
+
+ name= MakeAtom(_XKB_RF_NAMES_PROP_ATOM,strlen(_XKB_RF_NAMES_PROP_ATOM),1);
+ if (name==None) {
+ ErrorF("[xkb] Atom error: %s not created\n",_XKB_RF_NAMES_PROP_ATOM);
+ return TRUE;
+ }
+ pval= (char*) malloc(len);
+ if (!pval) {
+ ErrorF("[xkb] Allocation error: %s proprerty not created\n",
+ _XKB_RF_NAMES_PROP_ATOM);
+ return TRUE;
+ }
+ out= 0;
+ if (XkbRulesUsed) {
+ strcpy(&pval[out],XkbRulesUsed);
+ out+= strlen(XkbRulesUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbModelUsed) {
+ strcpy(&pval[out],XkbModelUsed);
+ out+= strlen(XkbModelUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbLayoutUsed) {
+ strcpy(&pval[out],XkbLayoutUsed);
+ out+= strlen(XkbLayoutUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbVariantUsed) {
+ strcpy(&pval[out],XkbVariantUsed);
+ out+= strlen(XkbVariantUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbOptionsUsed) {
+ strcpy(&pval[out],XkbOptionsUsed);
+ out+= strlen(XkbOptionsUsed);
+ }
+ pval[out++]= '\0';
+ if (out!=len) {
+ ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
+ out,len);
+ }
+ dixChangeWindowProperty(serverClient, WindowTable[0], name, XA_STRING, 8,
+ PropModeReplace, len, pval, TRUE);
+ free(pval);
+ return TRUE;
+}
+
+static void
+XkbSetRulesUsed(XkbRMLVOSet *rmlvo)
+{
+ if (XkbRulesUsed)
+ free(XkbRulesUsed);
+ XkbRulesUsed= (rmlvo->rules?_XkbDupString(rmlvo->rules):NULL);
+ if (XkbModelUsed)
+ free(XkbModelUsed);
+ XkbModelUsed= (rmlvo->model?_XkbDupString(rmlvo->model):NULL);
+ if (XkbLayoutUsed)
+ free(XkbLayoutUsed);
+ XkbLayoutUsed= (rmlvo->layout?_XkbDupString(rmlvo->layout):NULL);
+ if (XkbVariantUsed)
+ free(XkbVariantUsed);
+ XkbVariantUsed= (rmlvo->variant?_XkbDupString(rmlvo->variant):NULL);
+ if (XkbOptionsUsed)
+ free(XkbOptionsUsed);
+ XkbOptionsUsed= (rmlvo->options?_XkbDupString(rmlvo->options):NULL);
+ if (XkbWantRulesProp)
+ QueueWorkProc(XkbWriteRulesProp,NULL,NULL);
+ return;
+}
+
+void
+XkbSetRulesDflts(XkbRMLVOSet *rmlvo)
+{
+ if (rmlvo->rules) {
+ if (XkbRulesDflt)
+ free(XkbRulesDflt);
+ XkbRulesDflt= _XkbDupString(rmlvo->rules);
+ }
+ if (rmlvo->model) {
+ if (XkbModelDflt)
+ free(XkbModelDflt);
+ XkbModelDflt= _XkbDupString(rmlvo->model);
+ }
+ if (rmlvo->layout) {
+ if (XkbLayoutDflt)
+ free(XkbLayoutDflt);
+ XkbLayoutDflt= _XkbDupString(rmlvo->layout);
+ }
+ if (rmlvo->variant) {
+ if (XkbVariantDflt)
+ free(XkbVariantDflt);
+ XkbVariantDflt= _XkbDupString(rmlvo->variant);
+ }
+ if (rmlvo->options) {
+ if (XkbOptionsDflt)
+ free(XkbOptionsDflt);
+ XkbOptionsDflt= _XkbDupString(rmlvo->options);
+ }
+ return;
+}
+
+void
+XkbDeleteRulesDflts(void)
+{
+ free(XkbRulesDflt);
+ XkbRulesDflt = NULL;
+ free(XkbModelDflt);
+ XkbModelDflt = NULL;
+ free(XkbLayoutDflt);
+ XkbLayoutDflt = NULL;
+ free(XkbVariantDflt);
+ XkbVariantDflt = NULL;
+ free(XkbOptionsDflt);
+ XkbOptionsDflt = NULL;
+
+ XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
+ xkb_cached_map = NULL;
+}
+
+#define DIFFERS(a, b) (strcmp((a) ? (a) : "", (b) ? (b) : "") != 0)
+
+static Bool
+XkbCompareUsedRMLVO(XkbRMLVOSet *rmlvo)
+{
+ if (DIFFERS(rmlvo->rules, XkbRulesUsed) ||
+ DIFFERS(rmlvo->model, XkbModelUsed) ||
+ DIFFERS(rmlvo->layout, XkbLayoutUsed) ||
+ DIFFERS(rmlvo->variant, XkbVariantUsed) ||
+ DIFFERS(rmlvo->options, XkbOptionsUsed))
+ return FALSE;
+ return TRUE;
+}
+
+#undef DIFFERS
+
+/***====================================================================***/
+
+#include "xkbDflts.h"
+
+static Bool
+XkbInitKeyTypes(XkbDescPtr xkb)
+{
+ if (xkb->defined & XkmTypesMask)
+ return TRUE;
+
+ initTypeNames(NULL);
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_dflt_types)!=Success)
+ return FALSE;
+ if (XkbCopyKeyTypes(dflt_types,xkb->map->types,num_dflt_types)!=
+ Success) {
+ return FALSE;
+ }
+ xkb->map->size_types= xkb->map->num_types= num_dflt_types;
+ return TRUE;
+}
+
+static void
+XkbInitRadioGroups(XkbSrvInfoPtr xkbi)
+{
+ xkbi->nRadioGroups = 0;
+ xkbi->radioGroups = NULL;
+ return;
+}
+
+
+static Status
+XkbInitCompatStructs(XkbDescPtr xkb)
+{
+register int i;
+XkbCompatMapPtr compat;
+
+ if (xkb->defined & XkmCompatMapMask)
+ return TRUE;
+
+ if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_dfltSI)!=Success)
+ return BadAlloc;
+ compat = xkb->compat;
+ if (compat->sym_interpret) {
+ compat->num_si = num_dfltSI;
+ memcpy((char *)compat->sym_interpret,(char *)dfltSI,sizeof(dfltSI));
+ }
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ compat->groups[i]= compatMap.groups[i];
+ if (compat->groups[i].vmods!=0) {
+ unsigned mask;
+ mask= XkbMaskForVMask(xkb,compat->groups[i].vmods);
+ compat->groups[i].mask= compat->groups[i].real_mods|mask;
+ }
+ else compat->groups[i].mask= compat->groups[i].real_mods;
+ }
+ return Success;
+}
+
+static void
+XkbInitSemantics(XkbDescPtr xkb)
+{
+ XkbInitKeyTypes(xkb);
+ XkbInitCompatStructs(xkb);
+ return;
+}
+
+/***====================================================================***/
+
+static Status
+XkbInitNames(XkbSrvInfoPtr xkbi)
+{
+XkbDescPtr xkb;
+XkbNamesPtr names;
+Status rtrn;
+Atom unknown;
+
+ xkb= xkbi->desc;
+ if ((rtrn=XkbAllocNames(xkb,XkbAllNamesMask,0,0))!=Success)
+ return rtrn;
+ unknown= CREATE_ATOM("unknown");
+ names = xkb->names;
+ if (names->keycodes==None) names->keycodes= unknown;
+ if (names->geometry==None) names->geometry= unknown;
+ if (names->phys_symbols==None) names->phys_symbols= unknown;
+ if (names->symbols==None) names->symbols= unknown;
+ if (names->types==None) names->types= unknown;
+ if (names->compat==None) names->compat= unknown;
+ if (!(xkb->defined & XkmVirtualModsMask)) {
+ if (names->vmods[vmod_NumLock]==None)
+ names->vmods[vmod_NumLock]= CREATE_ATOM("NumLock");
+ if (names->vmods[vmod_Alt]==None)
+ names->vmods[vmod_Alt]= CREATE_ATOM("Alt");
+ if (names->vmods[vmod_AltGr]==None)
+ names->vmods[vmod_AltGr]= CREATE_ATOM("ModeSwitch");
+ }
+
+ if (!(xkb->defined & XkmIndicatorsMask) ||
+ !(xkb->defined & XkmGeometryMask)) {
+ initIndicatorNames(NULL,xkb);
+ if (names->indicators[LED_CAPS-1]==None)
+ names->indicators[LED_CAPS-1] = CREATE_ATOM("Caps Lock");
+ if (names->indicators[LED_NUM-1]==None)
+ names->indicators[LED_NUM-1] = CREATE_ATOM("Num Lock");
+ if (names->indicators[LED_SCROLL-1]==None)
+ names->indicators[LED_SCROLL-1] = CREATE_ATOM("Scroll Lock");
+#ifdef LED_COMPOSE
+ if (names->indicators[LED_COMPOSE-1]==None)
+ names->indicators[LED_COMPOSE-1] = CREATE_ATOM("Compose");
+#endif
+ }
+
+ if (xkb->geom!=NULL)
+ names->geometry= xkb->geom->name;
+ else names->geometry= unknown;
+
+ return Success;
+}
+
+static Status
+XkbInitIndicatorMap(XkbSrvInfoPtr xkbi)
+{
+XkbDescPtr xkb;
+XkbIndicatorPtr map;
+XkbSrvLedInfoPtr sli;
+
+ xkb= xkbi->desc;
+ if (XkbAllocIndicatorMaps(xkb)!=Success)
+ return BadAlloc;
+
+ if (!(xkb->defined & XkmIndicatorsMask)) {
+ map= xkb->indicators;
+ map->phys_indicators = PHYS_LEDS;
+ map->maps[LED_CAPS-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_CAPS-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_CAPS-1].mods.mask= LockMask;
+ map->maps[LED_CAPS-1].mods.real_mods= LockMask;
+
+ map->maps[LED_NUM-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_NUM-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_NUM-1].mods.mask= 0;
+ map->maps[LED_NUM-1].mods.real_mods= 0;
+ map->maps[LED_NUM-1].mods.vmods= vmod_NumLockMask;
+
+ map->maps[LED_SCROLL-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_SCROLL-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_SCROLL-1].mods.mask= Mod3Mask;
+ map->maps[LED_SCROLL-1].mods.real_mods= Mod3Mask;
+ }
+
+ sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
+ if (sli)
+ XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask);
+
+ return Success;
+}
+
+static Status
+XkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi)
+{
+XkbDescPtr xkb;
+XkbControlsPtr ctrls;
+
+ xkb= xkbi->desc;
+ /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */
+ if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success)
+ FatalError("Couldn't allocate keyboard controls\n");
+ ctrls= xkb->ctrls;
+ if (!(xkb->defined & XkmSymbolsMask))
+ ctrls->num_groups = 1;
+ ctrls->groups_wrap = XkbSetGroupInfo(1,XkbWrapIntoRange,0);
+ ctrls->internal.mask = 0;
+ ctrls->internal.real_mods = 0;
+ ctrls->internal.vmods = 0;
+ ctrls->ignore_lock.mask = 0;
+ ctrls->ignore_lock.real_mods = 0;
+ ctrls->ignore_lock.vmods = 0;
+ ctrls->enabled_ctrls = XkbAccessXTimeoutMask|XkbRepeatKeysMask|
+ XkbMouseKeysAccelMask|XkbAudibleBellMask|
+ XkbIgnoreGroupLockMask;
+ if (XkbWantAccessX)
+ ctrls->enabled_ctrls|= XkbAccessXKeysMask;
+ AccessXInit(pXDev);
+ return Success;
+}
+
+_X_EXPORT Bool
+InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo,
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+ int i;
+ unsigned int check;
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ XkbSrvLedInfoPtr sli;
+ XkbChangesRec changes;
+ XkbEventCauseRec cause;
+ XkbRMLVOSet rmlvo_dflts = { NULL };
+
+ if (dev->key || dev->kbdfeed)
+ return FALSE;
+
+ if (!rmlvo)
+ {
+ rmlvo = &rmlvo_dflts;
+ XkbGetRulesDflts(rmlvo);
+ }
+
+
+ memset(&changes, 0, sizeof(changes));
+ XkbSetCauseUnknown(&cause);
+
+ dev->key = calloc(1, sizeof(*dev->key));
+ if (!dev->key) {
+ ErrorF("XKB: Failed to allocate key class\n");
+ return FALSE;
+ }
+ dev->key->sourceid = dev->id;
+
+ dev->kbdfeed = calloc(1, sizeof(*dev->kbdfeed));
+ if (!dev->kbdfeed) {
+ ErrorF("XKB: Failed to allocate key feedback class\n");
+ goto unwind_key;
+ }
+
+ xkbi = calloc(1, sizeof(*xkbi));
+ if (!xkbi) {
+ ErrorF("XKB: Failed to allocate XKB info\n");
+ goto unwind_kbdfeed;
+ }
+ dev->key->xkbInfo = xkbi;
+
+ if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
+ XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
+ xkb_cached_map = NULL;
+ }
+
+ if (xkb_cached_map)
+ LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
+ else {
+ xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
+ if (!xkb_cached_map) {
+ ErrorF("XKB: Failed to compile keymap\n");
+ goto unwind_info;
+ }
+ }
+
+ xkb = XkbAllocKeyboard();
+ if (!xkb) {
+ ErrorF("XKB: Failed to allocate keyboard description\n");
+ goto unwind_info;
+ }
+
+ if (!XkbCopyKeymap(xkb, xkb_cached_map)) {
+ ErrorF("XKB: Failed to copy keymap\n");
+ goto unwind_desc;
+ }
+ xkb->defined = xkb_cached_map->defined;
+ xkb->flags = xkb_cached_map->flags;
+ xkb->device_spec = xkb_cached_map->device_spec;
+ xkbi->desc = xkb;
+
+ if (xkb->min_key_code == 0)
+ xkb->min_key_code = 8;
+ if (xkb->max_key_code == 0)
+ xkb->max_key_code = 255;
+
+ i = XkbNumKeys(xkb) / 3 + 1;
+ if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success)
+ goto unwind_desc;
+ if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success)
+ goto unwind_desc;
+
+ xkbi->dfltPtrDelta = 1;
+ xkbi->device = dev;
+
+ XkbInitSemantics(xkb);
+ XkbInitNames(xkbi);
+ XkbInitRadioGroups(xkbi);
+
+ XkbInitControls(dev, xkbi);
+
+ XkbInitIndicatorMap(xkbi);
+
+ XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
+ &check, &cause);
+
+ InitFocusClassDeviceStruct(dev);
+
+ xkbi->kbdProc = ctrl_func;
+ dev->kbdfeed->BellProc = bell_func;
+ dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc;
+
+ dev->kbdfeed->ctrl = defaultKeyboardControl;
+ if (dev->kbdfeed->ctrl.autoRepeat)
+ xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask;
+
+ memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat,
+ XkbPerKeyBitArraySize);
+
+ sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
+ if (sli)
+ XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask);
+ else
+ DebugF("XKB: No indicator feedback in XkbFinishInit!\n");
+
+ dev->kbdfeed->CtrlProc(dev,&dev->kbdfeed->ctrl);
+
+ XkbSetRulesDflts(rmlvo);
+ XkbSetRulesUsed(rmlvo);
+ XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
+
+ return TRUE;
+
+unwind_desc:
+ XkbFreeKeyboard(xkb, 0, TRUE);
+unwind_info:
+ free(xkbi);
+ dev->key->xkbInfo = NULL;
+unwind_kbdfeed:
+ free(dev->kbdfeed);
+ dev->kbdfeed = NULL;
+unwind_key:
+ free(dev->key);
+ dev->key = NULL;
+ return FALSE;
+}
+
+
+/***====================================================================***/
+
+ /*
+ * Be very careful about what does and doesn't get freed by this
+ * function. To reduce fragmentation, XkbInitDevice allocates a
+ * single huge block per device and divides it up into most of the
+ * fixed-size structures for the device. Don't free anything that
+ * is part of this larger block.
+ */
+void
+XkbFreeInfo(XkbSrvInfoPtr xkbi)
+{
+ if (xkbi->radioGroups) {
+ free(xkbi->radioGroups);
+ xkbi->radioGroups= NULL;
+ }
+ if (xkbi->mouseKeyTimer) {
+ TimerFree(xkbi->mouseKeyTimer);
+ xkbi->mouseKeyTimer= NULL;
+ }
+ if (xkbi->slowKeysTimer) {
+ TimerFree(xkbi->slowKeysTimer);
+ xkbi->slowKeysTimer= NULL;
+ }
+ if (xkbi->bounceKeysTimer) {
+ TimerFree(xkbi->bounceKeysTimer);
+ xkbi->bounceKeysTimer= NULL;
+ }
+ if (xkbi->repeatKeyTimer) {
+ TimerFree(xkbi->repeatKeyTimer);
+ xkbi->repeatKeyTimer= NULL;
+ }
+ if (xkbi->krgTimer) {
+ TimerFree(xkbi->krgTimer);
+ xkbi->krgTimer= NULL;
+ }
+ xkbi->beepType= _BEEP_NONE;
+ if (xkbi->beepTimer) {
+ TimerFree(xkbi->beepTimer);
+ xkbi->beepTimer= NULL;
+ }
+ if (xkbi->desc) {
+ XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,TRUE);
+ xkbi->desc= NULL;
+ }
+ free(xkbi);
+ return;
+}
+
+/***====================================================================***/
+
+extern int XkbDfltRepeatDelay;
+extern int XkbDfltRepeatInterval;
+
+extern unsigned short XkbDfltAccessXTimeout;
+extern unsigned int XkbDfltAccessXTimeoutMask;
+extern unsigned int XkbDfltAccessXFeedback;
+extern unsigned char XkbDfltAccessXOptions;
+
+int
+XkbProcessArguments(int argc,char *argv[],int i)
+{
+ if (strncmp(argv[i], "-xkbdir", 7) == 0) {
+ if(++i < argc) {
+#if !defined(WIN32) && !defined(__CYGWIN__)
+ if (getuid() != geteuid()) {
+ LogMessage(X_WARNING, "-xkbdir is not available for setuid X servers\n");
+ return -1;
+ } else
+#endif
+ {
+ if (strlen(argv[i]) < PATH_MAX) {
+ XkbBaseDirectory= argv[i];
+ return 2;
+ } else {
+ LogMessage(X_ERROR, "-xkbdir pathname too long\n");
+ return -1;
+ }
+ }
+ }
+ else {
+ return -1;
+ }
+ }
+ else if ((strncmp(argv[i],"-accessx",8)==0)||
+ (strncmp(argv[i],"+accessx",8)==0)) {
+ int j=1;
+ if (argv[i][0]=='-')
+ XkbWantAccessX= 0;
+ else {
+ XkbWantAccessX= 1;
+
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ XkbDfltAccessXTimeout = atoi(argv[++i]);
+ j++;
+
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ /*
+ * presumption that the reasonably useful range of
+ * values fits in 0..MAXINT since SunOS 4 doesn't
+ * have strtoul.
+ */
+ XkbDfltAccessXTimeoutMask=(unsigned int)
+ strtol(argv[++i],NULL,16);
+ j++;
+ }
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ if (argv[++i][0] == '1' )
+ XkbDfltAccessXFeedback=XkbAccessXFeedbackMask;
+ else
+ XkbDfltAccessXFeedback=0;
+ j++;
+ }
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ XkbDfltAccessXOptions=(unsigned char)
+ strtol(argv[++i],NULL,16);
+ j++;
+ }
+ }
+ }
+ return j;
+ }
+ if ((strcmp(argv[i], "-ardelay") == 0) ||
+ (strcmp (argv[i], "-ar1") == 0)) { /* -ardelay int */
+ if (++i >= argc) UseMsg ();
+ XkbDfltRepeatDelay = (long)atoi(argv[i]);
+ return 2;
+ }
+ if ((strcmp(argv[i], "-arinterval") == 0) ||
+ (strcmp (argv[i], "-ar2") == 0)) { /* -arinterval int */
+ if (++i >= argc) UseMsg ();
+ XkbDfltRepeatInterval = (long)atoi(argv[i]);
+ return 2;
+ }
+ return 0;
+}
+
+void
+XkbUseMsg(void)
+{
+ ErrorF("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n");
+ ErrorF(" enable/disable accessx key sequences\n");
+ ErrorF("-ardelay set XKB autorepeat delay\n");
+ ErrorF("-arinterval set XKB autorepeat interval\n");
+}
diff --git a/xorg-server/xkb/xkbLEDs.c b/xorg-server/xkb/xkbLEDs.c
index 8c28513ec..a0a037fd7 100644
--- a/xorg-server/xkb/xkbLEDs.c
+++ b/xorg-server/xkb/xkbLEDs.c
@@ -1,977 +1,977 @@
-/************************************************************
-Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-#include <math.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-
-#include <X11/extensions/XI.h>
-#include <xkbsrv.h>
-#include "xkb.h"
-
-/***====================================================================***/
-
- /*
- * unsigned
- * XkbIndicatorsToUpdate(dev,changed,check_devs_rtrn)
- *
- * Given a keyboard and a set of state components that have changed,
- * this function returns the indicators on the default keyboard
- * feedback that might be affected. It also reports whether or not
- * any extension devices might be affected in check_devs_rtrn.
- */
-
-unsigned
-XkbIndicatorsToUpdate( DeviceIntPtr dev,
- unsigned long state_changes,
- Bool enable_changes)
-{
-register unsigned update= 0;
-XkbSrvLedInfoPtr sli;
-
- sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
-
- if (!sli)
- return update;
-
- if (state_changes&(XkbModifierStateMask|XkbGroupStateMask))
- update|= sli->usesEffective;
- if (state_changes&(XkbModifierBaseMask|XkbGroupBaseMask))
- update|= sli->usesBase;
- if (state_changes&(XkbModifierLatchMask|XkbGroupLatchMask))
- update|= sli->usesLatched;
- if (state_changes&(XkbModifierLockMask|XkbGroupLockMask))
- update|= sli->usesLocked;
- if (state_changes&XkbCompatStateMask)
- update|= sli->usesCompat;
- if (enable_changes)
- update|= sli->usesControls;
- return update;
-}
-
-/***====================================================================***/
-
- /*
- * Bool
- *XkbApplyLEDChangeToKeyboard(xkbi,map,on,change)
- *
- * Some indicators "drive" the keyboard when their state is explicitly
- * changed, as described in section 9.2.1 of the XKB protocol spec.
- * This function updates the state and controls for the keyboard
- * specified by 'xkbi' to reflect any changes that are required
- * when the indicator described by 'map' is turned on or off. The
- * extent of the changes is reported in change, which must be defined.
- */
-static Bool
-XkbApplyLEDChangeToKeyboard( XkbSrvInfoPtr xkbi,
- XkbIndicatorMapPtr map,
- Bool on,
- XkbChangesPtr change)
-{
-Bool ctrlChange,stateChange;
-XkbStatePtr state;
-
- if ((map->flags&XkbIM_NoExplicit)||((map->flags&XkbIM_LEDDrivesKB)==0))
- return FALSE;
- ctrlChange= stateChange= FALSE;
- if (map->ctrls) {
- XkbControlsPtr ctrls= xkbi->desc->ctrls;
- unsigned old;
-
- old= ctrls->enabled_ctrls;
- if (on) ctrls->enabled_ctrls|= map->ctrls;
- else ctrls->enabled_ctrls&= ~map->ctrls;
- if (old!=ctrls->enabled_ctrls) {
- change->ctrls.changed_ctrls= XkbControlsEnabledMask;
- change->ctrls.enabled_ctrls_changes= old^ctrls->enabled_ctrls;
- ctrlChange= TRUE;
- }
- }
- state= &xkbi->state;
- if ((map->groups)&&((map->which_groups&(~XkbIM_UseBase))!=0)) {
- register int i;
- register unsigned bit,match;
-
- if (on) match= (map->groups)&XkbAllGroupsMask;
- else match= (~map->groups)&XkbAllGroupsMask;
- if (map->which_groups&(XkbIM_UseLocked|XkbIM_UseEffective)) {
- for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
- if (bit&match)
- break;
- }
- if (map->which_groups&XkbIM_UseLatched)
- XkbLatchGroup(xkbi->device,0); /* unlatch group */
- state->locked_group= i;
- stateChange= TRUE;
- }
- else if (map->which_groups&(XkbIM_UseLatched|XkbIM_UseEffective)) {
- for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
- if (bit&match)
- break;
- }
- state->locked_group= 0;
- XkbLatchGroup(xkbi->device,i);
- stateChange= TRUE;
- }
- }
- if ((map->mods.mask)&&((map->which_mods&(~XkbIM_UseBase))!=0)) {
- if (map->which_mods&(XkbIM_UseLocked|XkbIM_UseEffective)) {
- register unsigned long old;
- old= state->locked_mods;
- if (on) state->locked_mods|= map->mods.mask;
- else state->locked_mods&= ~map->mods.mask;
- if (state->locked_mods!=old)
- stateChange= TRUE;
- }
- if (map->which_mods&(XkbIM_UseLatched|XkbIM_UseEffective)) {
- register unsigned long newmods;
- newmods= state->latched_mods;
- if (on) newmods|= map->mods.mask;
- else newmods&= ~map->mods.mask;
- if (newmods!=state->locked_mods) {
- newmods&= map->mods.mask;
- XkbLatchModifiers(xkbi->device,map->mods.mask,newmods);
- stateChange= TRUE;
- }
- }
- }
- return (stateChange || ctrlChange);
-}
-
- /*
- * Bool
- * ComputeAutoState(map,state,ctrls)
- *
- * This function reports the effect of applying the specified
- * indicator map given the specified state and controls, as
- * described in section 9.2 of the XKB protocol specification.
- */
-
-static Bool
-ComputeAutoState( XkbIndicatorMapPtr map,
- XkbStatePtr state,
- XkbControlsPtr ctrls)
-{
-Bool on;
-CARD8 mods,group;
-
- on= FALSE;
- mods= group= 0;
- if (map->which_mods&XkbIM_UseAnyMods) {
- if (map->which_mods&XkbIM_UseBase)
- mods|= state->base_mods;
- if (map->which_mods&XkbIM_UseLatched)
- mods|= state->latched_mods;
- if (map->which_mods&XkbIM_UseLocked)
- mods|= state->locked_mods;
- if (map->which_mods&XkbIM_UseEffective)
- mods|= state->mods;
- if (map->which_mods&XkbIM_UseCompat)
- mods|= state->compat_state;
- on = ((map->mods.mask&mods)!=0);
- on = on||((mods==0)&&(map->mods.mask==0)&&(map->mods.vmods==0));
- }
- if (map->which_groups&XkbIM_UseAnyGroup) {
- if (map->which_groups&XkbIM_UseBase)
- group|= (1L << state->base_group);
- if (map->which_groups&XkbIM_UseLatched)
- group|= (1L << state->latched_group);
- if (map->which_groups&XkbIM_UseLocked)
- group|= (1L << state->locked_group);
- if (map->which_groups&XkbIM_UseEffective)
- group|= (1L << state->group);
- on = on||(((map->groups&group)!=0)||(map->groups==0));
- }
- if (map->ctrls)
- on = on||(ctrls->enabled_ctrls&map->ctrls);
- return on;
-}
-
-
-static void
-XkbUpdateLedAutoState( DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned maps_to_check,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-DeviceIntPtr kbd;
-XkbStatePtr state;
-XkbControlsPtr ctrls;
-XkbChangesRec my_changes;
-xkbExtensionDeviceNotify my_ed;
-register unsigned i,bit,affected;
-register XkbIndicatorMapPtr map;
-unsigned oldState;
-
- if ((maps_to_check==0)||(sli->maps==NULL)||(sli->mapsPresent==0))
- return;
-
- if (dev->key && dev->key->xkbInfo)
- kbd= dev;
- else kbd= inputInfo.keyboard;
-
- state= &kbd->key->xkbInfo->state;
- ctrls= kbd->key->xkbInfo->desc->ctrls;
- affected= maps_to_check;
- oldState= sli->effectiveState;
- sli->autoState&= ~affected;
- for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
- if ((affected&bit)==0)
- continue;
- affected&= ~bit;
- map= &sli->maps[i];
- if((!(map->flags&XkbIM_NoAutomatic))&&ComputeAutoState(map,state,ctrls))
- sli->autoState|= bit;
- }
- sli->effectiveState= (sli->autoState|sli->explicitState);
- affected= sli->effectiveState^oldState;
- if (affected==0)
- return;
-
- if (ed==NULL) {
- ed= &my_ed;
- bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
- }
- else if ((ed->reason&XkbXI_IndicatorsMask)&&
- ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- }
-
- if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
- if (changes==NULL) {
- changes= &my_changes;
- bzero((char *)changes,sizeof(XkbChangesRec));
- }
- changes->indicators.state_changes|= affected;
- }
-
- ed->reason|= XkbXI_IndicatorStateMask;
- ed->ledClass= sli->class;
- ed->ledID= sli->id;
- ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
- ed->ledState= sli->effectiveState;
- ed->unsupported= 0;
- ed->supported= XkbXI_AllFeaturesMask;
-
- if (changes!=&my_changes) changes= NULL;
- if (ed!=&my_ed) ed= NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- return;
-}
-
-static void
-XkbUpdateAllDeviceIndicators(XkbChangesPtr changes,XkbEventCausePtr cause)
-{
-DeviceIntPtr edev;
-XkbSrvLedInfoPtr sli;
-
- for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) {
- if (edev->kbdfeed) {
- KbdFeedbackPtr kf;
- for (kf=edev->kbdfeed;kf!=NULL;kf=kf->next) {
- if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL))
- continue;
- sli= kf->xkb_sli;
- XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
- changes,cause);
-
- }
- }
- if (edev->leds) {
- LedFeedbackPtr lf;
- for (lf=edev->leds;lf!=NULL;lf=lf->next) {
- if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL))
- continue;
- sli= lf->xkb_sli;
- XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
- changes,cause);
-
- }
- }
- }
- return;
-}
-
-
-/***====================================================================***/
-
- /*
- * void
- * XkbSetIndicators(dev,affect,values,cause)
- *
- * Attempts to change the indicators specified in 'affect' to the
- * states specified in 'values' for the default keyboard feedback
- * on the keyboard specified by 'dev.' Attempts to change indicator
- * state might be ignored or have no affect, depending on the XKB
- * indicator map for any affected indicators, as described in section
- * 9.2 of the XKB protocol specification.
- *
- * If 'changes' is non-NULL, this function notes any changes to the
- * keyboard state, controls, or indicator state that result from this
- * attempted change. If 'changes' is NULL, this function generates
- * XKB events to report any such changes to interested clients.
- *
- * If 'cause' is non-NULL, it specifies the reason for the change,
- * as reported in some XKB events. If it is NULL, this function
- * assumes that the change is the result of a core protocol
- * ChangeKeyboardMapping request.
- */
-
-void
-XkbSetIndicators( DeviceIntPtr dev,
- CARD32 affect,
- CARD32 values,
- XkbEventCausePtr cause)
-{
-XkbSrvLedInfoPtr sli;
-XkbChangesRec changes;
-xkbExtensionDeviceNotify ed;
-unsigned side_affected;
-
- bzero((char *)&changes,sizeof(XkbChangesRec));
- bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
- sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
- sli->explicitState&= ~affect;
- sli->explicitState|= (affect&values);
- XkbApplyLedStateChanges(dev,sli,affect,&ed,&changes,cause);
-
- side_affected= 0;
- if (changes.state_changes!=0)
- side_affected|= XkbIndicatorsToUpdate(dev,changes.state_changes,FALSE);
- if (changes.ctrls.enabled_ctrls_changes)
- side_affected|= sli->usesControls;
-
- if (side_affected) {
- XkbUpdateLedAutoState(dev,sli,side_affected,&ed,&changes,cause);
- affect|= side_affected;
- }
- if (changes.state_changes || changes.ctrls.enabled_ctrls_changes)
- XkbUpdateAllDeviceIndicators(NULL,cause);
-
- XkbFlushLedEvents(dev,dev,sli,&ed,&changes,cause);
- return;
-}
-
-/***====================================================================***/
-
-/***====================================================================***/
-
- /*
- * void
- * XkbUpdateIndicators(dev,update,check_edevs,changes,cause)
- *
- * Applies the indicator maps for any indicators specified in
- * 'update' from the default keyboard feedback on the device
- * specified by 'dev.'
- *
- * If 'changes' is NULL, this function generates and XKB events
- * required to report the necessary changes, otherwise it simply
- * notes the indicators with changed state.
- *
- * If 'check_edevs' is TRUE, this function also checks the indicator
- * maps for any open extension devices that have them, and updates
- * the state of any extension device indicators as necessary.
- */
-
-void
-XkbUpdateIndicators( DeviceIntPtr dev,
- register CARD32 update,
- Bool check_edevs,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-XkbSrvLedInfoPtr sli;
-
- sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
- XkbUpdateLedAutoState(dev,sli,update,NULL,changes,cause);
- if (check_edevs)
- XkbUpdateAllDeviceIndicators(changes,cause);
- return;
-}
-
-/***====================================================================***/
-
-/***====================================================================***/
-
- /*
- * void
- * XkbCheckIndicatorMaps(dev,sli,which)
- *
- * Updates the 'indicator accelerators' for the indicators specified
- * by 'which' in the feedback specified by 'sli.' The indicator
- * accelerators are internal to the server and are used to simplify
- * and speed up the process of figuring out which indicators might
- * be affected by a particular change in keyboard state or controls.
- */
-
-void
-XkbCheckIndicatorMaps(DeviceIntPtr dev,XkbSrvLedInfoPtr sli,unsigned which)
-{
-register unsigned i,bit;
-XkbIndicatorMapPtr map;
-XkbDescPtr xkb;
-
- if ((sli->flags&XkbSLI_HasOwnState)==0)
- return;
-
- sli->usesBase&= ~which;
- sli->usesLatched&= ~which;
- sli->usesLocked&= ~which;
- sli->usesEffective&= ~which;
- sli->usesCompat&= ~which;
- sli->usesControls&= ~which;
- sli->mapsPresent&= ~which;
-
- xkb= dev->key->xkbInfo->desc;
- for (i=0,bit=1,map=sli->maps;i<XkbNumIndicators;i++,bit<<=1,map++) {
- if (which&bit) {
- CARD8 what;
-
- if (!map || !XkbIM_InUse(map))
- continue;
- sli->mapsPresent|= bit;
-
- what= (map->which_mods|map->which_groups);
- if (what&XkbIM_UseBase)
- sli->usesBase|= bit;
- if (what&XkbIM_UseLatched)
- sli->usesLatched|= bit;
- if (what&XkbIM_UseLocked)
- sli->usesLocked|= bit;
- if (what&XkbIM_UseEffective)
- sli->usesEffective|= bit;
- if (what&XkbIM_UseCompat)
- sli->usesCompat|= bit;
- if (map->ctrls)
- sli->usesControls|= bit;
-
- map->mods.mask= map->mods.real_mods;
- if (map->mods.vmods!=0) {
- map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods);
- }
- }
- }
- sli->usedComponents= 0;
- if (sli->usesBase)
- sli->usedComponents|= XkbModifierBaseMask|XkbGroupBaseMask;
- if (sli->usesLatched)
- sli->usedComponents|= XkbModifierLatchMask|XkbGroupLatchMask;
- if (sli->usesLocked)
- sli->usedComponents|= XkbModifierLockMask|XkbGroupLockMask;
- if (sli->usesEffective)
- sli->usedComponents|= XkbModifierStateMask|XkbGroupStateMask;
- if (sli->usesCompat)
- sli->usedComponents|= XkbCompatStateMask;
- return;
-}
-
-/***====================================================================***/
-
- /*
- * XkbSrvLedInfoPtr
- * XkbAllocSrvLedInfo(dev,kf,lf,needed_parts)
- *
- * Allocates an XkbSrvLedInfoPtr for the feedback specified by either
- * 'kf' or 'lf' on the keyboard specified by 'dev.'
- *
- * If 'needed_parts' is non-zero, this function makes sure that any
- * of the parts speicified therein are allocated.
- */
-XkbSrvLedInfoPtr
-XkbAllocSrvLedInfo( DeviceIntPtr dev,
- KbdFeedbackPtr kf,
- LedFeedbackPtr lf,
- unsigned needed_parts)
-{
-XkbSrvLedInfoPtr sli;
-Bool checkAccel;
-Bool checkNames;
-
- sli= NULL;
- checkAccel= checkNames= FALSE;
- if ((kf!=NULL)&&(kf->xkb_sli==NULL)) {
- kf->xkb_sli= sli= xcalloc(1, sizeof(XkbSrvLedInfoRec));
- if (sli==NULL)
- return NULL; /* ALLOCATION ERROR */
- if (dev->key && dev->key->xkbInfo)
- sli->flags= XkbSLI_HasOwnState;
- else sli->flags= 0;
- sli->class= KbdFeedbackClass;
- sli->id= kf->ctrl.id;
- sli->fb.kf= kf;
-
- sli->autoState= 0;
- sli->explicitState= kf->ctrl.leds;
- sli->effectiveState= kf->ctrl.leds;
-
- if ((kf==dev->kbdfeed) && (dev->key) && (dev->key->xkbInfo)) {
- XkbDescPtr xkb;
- xkb= dev->key->xkbInfo->desc;
- sli->flags|= XkbSLI_IsDefault;
- sli->physIndicators= xkb->indicators->phys_indicators;
- sli->names= xkb->names->indicators;
- sli->maps= xkb->indicators->maps;
- checkNames= checkAccel= TRUE;
- }
- else {
- sli->physIndicators= XkbAllIndicatorsMask;
- sli->names= NULL;
- sli->maps= NULL;
- }
- }
- else if ((kf!=NULL)&&((kf->xkb_sli->flags&XkbSLI_IsDefault)!=0)) {
- XkbDescPtr xkb;
- xkb= dev->key->xkbInfo->desc;
- sli->physIndicators= xkb->indicators->phys_indicators;
- if (xkb->names->indicators!=sli->names) {
- checkNames= TRUE;
- sli->names= xkb->names->indicators;
- }
- if (xkb->indicators->maps!=sli->maps) {
- checkAccel= TRUE;
- sli->maps= xkb->indicators->maps;
- }
- }
- else if ((lf!=NULL)&&(lf->xkb_sli==NULL)) {
- lf->xkb_sli= sli= xcalloc(1, sizeof(XkbSrvLedInfoRec));
- if (sli==NULL)
- return NULL; /* ALLOCATION ERROR */
- if (dev->key && dev->key->xkbInfo)
- sli->flags= XkbSLI_HasOwnState;
- else sli->flags= 0;
- sli->class= LedFeedbackClass;
- sli->id= lf->ctrl.id;
- sli->fb.lf= lf;
-
- sli->physIndicators= lf->ctrl.led_mask;
- sli->autoState= 0;
- sli->explicitState= lf->ctrl.led_values;
- sli->effectiveState= lf->ctrl.led_values;
- sli->maps= NULL;
- sli->names= NULL;
- }
- if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
- sli->names= xcalloc(XkbNumIndicators, sizeof(Atom));
- if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
- sli->maps= xcalloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
- if (checkNames) {
- register unsigned i,bit;
- sli->namesPresent= 0;
- for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
- if (sli->names[i]!=None)
- sli->namesPresent|= bit;
- }
- }
- if (checkAccel)
- XkbCheckIndicatorMaps(dev,sli,XkbAllIndicatorsMask);
- return sli;
-}
-
-void
-XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli)
-{
- if ((sli->flags&XkbSLI_IsDefault)==0) {
- if (sli->maps) xfree(sli->maps);
- if (sli->names) xfree(sli->names);
- }
- sli->maps= NULL;
- sli->names= NULL;
- xfree(sli);
- return;
-}
-
-/*
- * XkbSrvLedInfoPtr
- * XkbCopySrvLedInfo(dev,src,kf,lf)
- *
- * Takes the given XkbSrvLedInfoPtr and duplicates it. A deep copy is made,
- * thus the new copy behaves like the original one and can be freed with
- * XkbFreeSrvLedInfo.
- */
-XkbSrvLedInfoPtr
-XkbCopySrvLedInfo( DeviceIntPtr from,
- XkbSrvLedInfoPtr src,
- KbdFeedbackPtr kf,
- LedFeedbackPtr lf)
-{
- XkbSrvLedInfoPtr sli_new = NULL;
-
- if (!src)
- goto finish;
-
- sli_new = xcalloc(1, sizeof( XkbSrvLedInfoRec));
- if (!sli_new)
- goto finish;
-
- memcpy(sli_new, src, sizeof(XkbSrvLedInfoRec));
- if (sli_new->class == KbdFeedbackClass)
- sli_new->fb.kf = kf;
- else
- sli_new->fb.lf = lf;
-
- if (!(sli_new->flags & XkbSLI_IsDefault)) {
- sli_new->names= xcalloc(XkbNumIndicators, sizeof(Atom));
- sli_new->maps= xcalloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
- } /* else sli_new->names/maps is pointing to
- dev->key->xkbInfo->desc->names->indicators;
- dev->key->xkbInfo->desc->names->indicators; */
-
-finish:
- return sli_new;
-}
-
-/***====================================================================***/
-
- /*
- * XkbSrvLedInfoPtr
- * XkbFindSrvLedInfo(dev,class,id,needed_parts)
- *
- * Finds the XkbSrvLedInfoPtr for the specified 'class' and 'id'
- * on the device specified by 'dev.' If the class and id specify
- * a valid device feedback, this function returns the existing
- * feedback or allocates a new one.
- *
- */
-
-XkbSrvLedInfoPtr
-XkbFindSrvLedInfo( DeviceIntPtr dev,
- unsigned class,
- unsigned id,
- unsigned needed_parts)
-{
-XkbSrvLedInfoPtr sli;
-
- /* optimization to check for most common case */
- if (((class==XkbDfltXIClass)&&(id==XkbDfltXIId))&&(dev->kbdfeed)) {
- XkbSrvLedInfoPtr sli;
- sli= dev->kbdfeed->xkb_sli;
- if (dev->kbdfeed->xkb_sli==NULL) {
- sli= XkbAllocSrvLedInfo(dev,dev->kbdfeed,NULL,needed_parts);
- dev->kbdfeed->xkb_sli= sli;
- }
- return dev->kbdfeed->xkb_sli;
- }
-
- sli= NULL;
- if (class==XkbDfltXIClass) {
- if (dev->kbdfeed) class= KbdFeedbackClass;
- else if (dev->leds) class= LedFeedbackClass;
- else return NULL;
- }
- if (class==KbdFeedbackClass) {
- KbdFeedbackPtr kf;
- for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) {
- if ((id==XkbDfltXIId)||(id==kf->ctrl.id)) {
- if (kf->xkb_sli==NULL)
- kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,needed_parts);
- sli= kf->xkb_sli;
- break;
- }
- }
- }
- else if (class==LedFeedbackClass) {
- LedFeedbackPtr lf;
- for (lf=dev->leds;lf!=NULL;lf=lf->next) {
- if ((id==XkbDfltXIId)||(id==lf->ctrl.id)) {
- if (lf->xkb_sli==NULL)
- lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,needed_parts);
- sli= lf->xkb_sli;
- break;
- }
- }
- }
- if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
- sli->names= xcalloc(XkbNumIndicators, sizeof(Atom));
- if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
- sli->maps= xcalloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
- return sli;
-}
-
-/***====================================================================***/
-
-void
-XkbFlushLedEvents( DeviceIntPtr dev,
- DeviceIntPtr kbd,
- XkbSrvLedInfoPtr sli,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
- if (changes) {
- if (changes->indicators.state_changes)
- XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
- XkbSendNotification(kbd,changes,cause);
- bzero((char *)changes,sizeof(XkbChangesRec));
-
- if (XkbAX_NeedFeedback(kbd->key->xkbInfo->desc->ctrls, XkbAX_IndicatorFBMask)) {
- if (sli->effectiveState)
- /* it appears that the which parameter is not used */
- XkbDDXAccessXBeep(dev, _BEEP_LED_ON, XkbAccessXFeedbackMask);
- else
- XkbDDXAccessXBeep(dev, _BEEP_LED_OFF, XkbAccessXFeedbackMask);
- }
- }
- if (ed) {
- if (ed->reason) {
- if ((dev!=kbd)&&(ed->reason&XkbXI_IndicatorStateMask))
- XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
- XkbSendExtensionDeviceNotify(dev,cause->client,ed);
- }
- bzero((char *)ed,sizeof(XkbExtensionDeviceNotify));
- }
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbApplyLedNameChanges( DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned changed_names,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-DeviceIntPtr kbd;
-XkbChangesRec my_changes;
-xkbExtensionDeviceNotify my_ed;
-
- if (changed_names==0)
- return;
- if (dev->key && dev->key->xkbInfo)
- kbd= dev;
- else kbd= inputInfo.keyboard;
-
- if (ed==NULL) {
- ed= &my_ed;
- bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
- }
- else if ((ed->reason&XkbXI_IndicatorsMask)&&
- ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- }
-
- if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
- if (changes==NULL) {
- changes= &my_changes;
- bzero((char *)changes,sizeof(XkbChangesRec));
- }
- changes->names.changed|= XkbIndicatorNamesMask;
- changes->names.changed_indicators|= changed_names;
- }
-
- ed->reason|= XkbXI_IndicatorNamesMask;
- ed->ledClass= sli->class;
- ed->ledID= sli->id;
- ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
- ed->ledState= sli->effectiveState;
- ed->unsupported= 0;
- ed->supported= XkbXI_AllFeaturesMask;
-
- if (changes!=&my_changes) changes= NULL;
- if (ed!=&my_ed) ed= NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- return;
-}
-/***====================================================================***/
-
- /*
- * void
- * XkbApplyLedMapChanges(dev,sli,changed_maps,changes,cause)
- *
- * Handles all of the secondary effects of the changes to the
- * feedback specified by 'sli' on the device specified by 'dev.'
- *
- * If 'changed_maps' specifies any indicators, this function generates
- * XkbExtensionDeviceNotify events and possibly IndicatorMapNotify
- * events to report the changes, and recalculates the effective
- * state of each indicator with a changed map. If any indicators
- * change state, the server generates XkbExtensionDeviceNotify and
- * XkbIndicatorStateNotify events as appropriate.
- *
- * If 'changes' is non-NULL, this function updates it to reflect
- * any changes to the keyboard state or controls or to the 'core'
- * indicator names, maps, or state. If 'changes' is NULL, this
- * function generates XKB events as needed to report the changes.
- * If 'dev' is not a keyboard device, any changes are reported
- * for the core keyboard.
- *
- * The 'cause' specifies the reason for the event (key event or
- * request) for the change, as reported in some XKB events.
- */
-
-void
-XkbApplyLedMapChanges( DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned changed_maps,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-DeviceIntPtr kbd;
-XkbChangesRec my_changes;
-xkbExtensionDeviceNotify my_ed;
-
- if (changed_maps==0)
- return;
- if (dev->key && dev->key->xkbInfo)
- kbd= dev;
- else kbd= inputInfo.keyboard;
-
- if (ed==NULL) {
- ed= &my_ed;
- bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
- }
- else if ((ed->reason&XkbXI_IndicatorsMask)&&
- ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- }
-
- if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
- if (changes==NULL) {
- changes= &my_changes;
- bzero((char *)changes,sizeof(XkbChangesRec));
- }
- changes->indicators.map_changes|= changed_maps;
- }
-
- XkbCheckIndicatorMaps(dev,sli,changed_maps);
-
- ed->reason|= XkbXI_IndicatorMapsMask;
- ed->ledClass= sli->class;
- ed->ledID= sli->id;
- ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
- ed->ledState= sli->effectiveState;
- ed->unsupported= 0;
- ed->supported= XkbXI_AllFeaturesMask;
-
- XkbUpdateLedAutoState(dev,sli,changed_maps,ed,changes,cause);
-
- if (changes!=&my_changes) changes= NULL;
- if (ed!=&my_ed) ed= NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbApplyLedStateChanges(DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned changed_leds,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-XkbSrvInfoPtr xkbi;
-DeviceIntPtr kbd;
-XkbChangesRec my_changes;
-xkbExtensionDeviceNotify my_ed;
-register unsigned i,bit,affected;
-XkbIndicatorMapPtr map;
-unsigned oldState;
-Bool kb_changed;
-
- if (changed_leds==0)
- return;
- if (dev->key && dev->key->xkbInfo)
- kbd= dev;
- else kbd= inputInfo.keyboard;
- xkbi= kbd->key->xkbInfo;
-
- if (changes==NULL) {
- changes= &my_changes;
- bzero((char *)changes,sizeof(XkbChangesRec));
- }
-
- kb_changed= FALSE;
- affected= changed_leds;
- oldState= sli->effectiveState;
- for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
- if ((affected&bit)==0)
- continue;
- affected&= ~bit;
- map= &sli->maps[i];
- if (map->flags&XkbIM_NoExplicit) {
- sli->explicitState&= ~bit;
- continue;
- }
- if (map->flags&XkbIM_LEDDrivesKB) {
- Bool on= ((sli->explicitState&bit)!=0);
- if (XkbApplyLEDChangeToKeyboard(xkbi,map,on,changes))
- kb_changed= TRUE;
- }
- }
- sli->effectiveState= (sli->autoState|sli->explicitState);
- affected= sli->effectiveState^oldState;
-
- if (ed==NULL) {
- ed= &my_ed;
- bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
- }
- else if (affected&&(ed->reason&XkbXI_IndicatorsMask)&&
- ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- }
-
- if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault))
- changes->indicators.state_changes|= affected;
- if (affected) {
- ed->reason|= XkbXI_IndicatorStateMask;
- ed->ledClass= sli->class;
- ed->ledID= sli->id;
- ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
- ed->ledState= sli->effectiveState;
- ed->unsupported= 0;
- ed->supported= XkbXI_AllFeaturesMask;
- }
-
- if (kb_changed) {
- XkbComputeDerivedState(kbd->key->xkbInfo);
- XkbUpdateLedAutoState(dev,sli,sli->mapsPresent,ed,changes,cause);
- }
-
- if (changes!=&my_changes) changes= NULL;
- if (ed!=&my_ed) ed= NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- if (kb_changed)
- XkbUpdateAllDeviceIndicators(NULL,cause);
- return;
-}
+/************************************************************
+Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+
+#include <X11/extensions/XI.h>
+#include <xkbsrv.h>
+#include "xkb.h"
+
+/***====================================================================***/
+
+ /*
+ * unsigned
+ * XkbIndicatorsToUpdate(dev,changed,check_devs_rtrn)
+ *
+ * Given a keyboard and a set of state components that have changed,
+ * this function returns the indicators on the default keyboard
+ * feedback that might be affected. It also reports whether or not
+ * any extension devices might be affected in check_devs_rtrn.
+ */
+
+unsigned
+XkbIndicatorsToUpdate( DeviceIntPtr dev,
+ unsigned long state_changes,
+ Bool enable_changes)
+{
+register unsigned update= 0;
+XkbSrvLedInfoPtr sli;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+
+ if (!sli)
+ return update;
+
+ if (state_changes&(XkbModifierStateMask|XkbGroupStateMask))
+ update|= sli->usesEffective;
+ if (state_changes&(XkbModifierBaseMask|XkbGroupBaseMask))
+ update|= sli->usesBase;
+ if (state_changes&(XkbModifierLatchMask|XkbGroupLatchMask))
+ update|= sli->usesLatched;
+ if (state_changes&(XkbModifierLockMask|XkbGroupLockMask))
+ update|= sli->usesLocked;
+ if (state_changes&XkbCompatStateMask)
+ update|= sli->usesCompat;
+ if (enable_changes)
+ update|= sli->usesControls;
+ return update;
+}
+
+/***====================================================================***/
+
+ /*
+ * Bool
+ *XkbApplyLEDChangeToKeyboard(xkbi,map,on,change)
+ *
+ * Some indicators "drive" the keyboard when their state is explicitly
+ * changed, as described in section 9.2.1 of the XKB protocol spec.
+ * This function updates the state and controls for the keyboard
+ * specified by 'xkbi' to reflect any changes that are required
+ * when the indicator described by 'map' is turned on or off. The
+ * extent of the changes is reported in change, which must be defined.
+ */
+static Bool
+XkbApplyLEDChangeToKeyboard( XkbSrvInfoPtr xkbi,
+ XkbIndicatorMapPtr map,
+ Bool on,
+ XkbChangesPtr change)
+{
+Bool ctrlChange,stateChange;
+XkbStatePtr state;
+
+ if ((map->flags&XkbIM_NoExplicit)||((map->flags&XkbIM_LEDDrivesKB)==0))
+ return FALSE;
+ ctrlChange= stateChange= FALSE;
+ if (map->ctrls) {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ unsigned old;
+
+ old= ctrls->enabled_ctrls;
+ if (on) ctrls->enabled_ctrls|= map->ctrls;
+ else ctrls->enabled_ctrls&= ~map->ctrls;
+ if (old!=ctrls->enabled_ctrls) {
+ change->ctrls.changed_ctrls= XkbControlsEnabledMask;
+ change->ctrls.enabled_ctrls_changes= old^ctrls->enabled_ctrls;
+ ctrlChange= TRUE;
+ }
+ }
+ state= &xkbi->state;
+ if ((map->groups)&&((map->which_groups&(~XkbIM_UseBase))!=0)) {
+ register int i;
+ register unsigned bit,match;
+
+ if (on) match= (map->groups)&XkbAllGroupsMask;
+ else match= (~map->groups)&XkbAllGroupsMask;
+ if (map->which_groups&(XkbIM_UseLocked|XkbIM_UseEffective)) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (bit&match)
+ break;
+ }
+ if (map->which_groups&XkbIM_UseLatched)
+ XkbLatchGroup(xkbi->device,0); /* unlatch group */
+ state->locked_group= i;
+ stateChange= TRUE;
+ }
+ else if (map->which_groups&(XkbIM_UseLatched|XkbIM_UseEffective)) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (bit&match)
+ break;
+ }
+ state->locked_group= 0;
+ XkbLatchGroup(xkbi->device,i);
+ stateChange= TRUE;
+ }
+ }
+ if ((map->mods.mask)&&((map->which_mods&(~XkbIM_UseBase))!=0)) {
+ if (map->which_mods&(XkbIM_UseLocked|XkbIM_UseEffective)) {
+ register unsigned long old;
+ old= state->locked_mods;
+ if (on) state->locked_mods|= map->mods.mask;
+ else state->locked_mods&= ~map->mods.mask;
+ if (state->locked_mods!=old)
+ stateChange= TRUE;
+ }
+ if (map->which_mods&(XkbIM_UseLatched|XkbIM_UseEffective)) {
+ register unsigned long newmods;
+ newmods= state->latched_mods;
+ if (on) newmods|= map->mods.mask;
+ else newmods&= ~map->mods.mask;
+ if (newmods!=state->locked_mods) {
+ newmods&= map->mods.mask;
+ XkbLatchModifiers(xkbi->device,map->mods.mask,newmods);
+ stateChange= TRUE;
+ }
+ }
+ }
+ return (stateChange || ctrlChange);
+}
+
+ /*
+ * Bool
+ * ComputeAutoState(map,state,ctrls)
+ *
+ * This function reports the effect of applying the specified
+ * indicator map given the specified state and controls, as
+ * described in section 9.2 of the XKB protocol specification.
+ */
+
+static Bool
+ComputeAutoState( XkbIndicatorMapPtr map,
+ XkbStatePtr state,
+ XkbControlsPtr ctrls)
+{
+Bool on;
+CARD8 mods,group;
+
+ on= FALSE;
+ mods= group= 0;
+ if (map->which_mods&XkbIM_UseAnyMods) {
+ if (map->which_mods&XkbIM_UseBase)
+ mods|= state->base_mods;
+ if (map->which_mods&XkbIM_UseLatched)
+ mods|= state->latched_mods;
+ if (map->which_mods&XkbIM_UseLocked)
+ mods|= state->locked_mods;
+ if (map->which_mods&XkbIM_UseEffective)
+ mods|= state->mods;
+ if (map->which_mods&XkbIM_UseCompat)
+ mods|= state->compat_state;
+ on = ((map->mods.mask&mods)!=0);
+ on = on||((mods==0)&&(map->mods.mask==0)&&(map->mods.vmods==0));
+ }
+ if (map->which_groups&XkbIM_UseAnyGroup) {
+ if (map->which_groups&XkbIM_UseBase)
+ group|= (1L << state->base_group);
+ if (map->which_groups&XkbIM_UseLatched)
+ group|= (1L << state->latched_group);
+ if (map->which_groups&XkbIM_UseLocked)
+ group|= (1L << state->locked_group);
+ if (map->which_groups&XkbIM_UseEffective)
+ group|= (1L << state->group);
+ on = on||(((map->groups&group)!=0)||(map->groups==0));
+ }
+ if (map->ctrls)
+ on = on||(ctrls->enabled_ctrls&map->ctrls);
+ return on;
+}
+
+
+static void
+XkbUpdateLedAutoState( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned maps_to_check,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+DeviceIntPtr kbd;
+XkbStatePtr state;
+XkbControlsPtr ctrls;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+register unsigned i,bit,affected;
+register XkbIndicatorMapPtr map;
+unsigned oldState;
+
+ if ((maps_to_check==0)||(sli->maps==NULL)||(sli->mapsPresent==0))
+ return;
+
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= inputInfo.keyboard;
+
+ state= &kbd->key->xkbInfo->state;
+ ctrls= kbd->key->xkbInfo->desc->ctrls;
+ affected= maps_to_check;
+ oldState= sli->effectiveState;
+ sli->autoState&= ~affected;
+ for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
+ if ((affected&bit)==0)
+ continue;
+ affected&= ~bit;
+ map= &sli->maps[i];
+ if((!(map->flags&XkbIM_NoAutomatic))&&ComputeAutoState(map,state,ctrls))
+ sli->autoState|= bit;
+ }
+ sli->effectiveState= (sli->autoState|sli->explicitState);
+ affected= sli->effectiveState^oldState;
+ if (affected==0)
+ return;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->indicators.state_changes|= affected;
+ }
+
+ ed->reason|= XkbXI_IndicatorStateMask;
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported= 0;
+ ed->supported= XkbXI_AllFeaturesMask;
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+
+static void
+XkbUpdateAllDeviceIndicators(XkbChangesPtr changes,XkbEventCausePtr cause)
+{
+DeviceIntPtr edev;
+XkbSrvLedInfoPtr sli;
+
+ for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) {
+ if (edev->kbdfeed) {
+ KbdFeedbackPtr kf;
+ for (kf=edev->kbdfeed;kf!=NULL;kf=kf->next) {
+ if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL))
+ continue;
+ sli= kf->xkb_sli;
+ XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
+ changes,cause);
+
+ }
+ }
+ if (edev->leds) {
+ LedFeedbackPtr lf;
+ for (lf=edev->leds;lf!=NULL;lf=lf->next) {
+ if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL))
+ continue;
+ sli= lf->xkb_sli;
+ XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
+ changes,cause);
+
+ }
+ }
+ }
+ return;
+}
+
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbSetIndicators(dev,affect,values,cause)
+ *
+ * Attempts to change the indicators specified in 'affect' to the
+ * states specified in 'values' for the default keyboard feedback
+ * on the keyboard specified by 'dev.' Attempts to change indicator
+ * state might be ignored or have no affect, depending on the XKB
+ * indicator map for any affected indicators, as described in section
+ * 9.2 of the XKB protocol specification.
+ *
+ * If 'changes' is non-NULL, this function notes any changes to the
+ * keyboard state, controls, or indicator state that result from this
+ * attempted change. If 'changes' is NULL, this function generates
+ * XKB events to report any such changes to interested clients.
+ *
+ * If 'cause' is non-NULL, it specifies the reason for the change,
+ * as reported in some XKB events. If it is NULL, this function
+ * assumes that the change is the result of a core protocol
+ * ChangeKeyboardMapping request.
+ */
+
+void
+XkbSetIndicators( DeviceIntPtr dev,
+ CARD32 affect,
+ CARD32 values,
+ XkbEventCausePtr cause)
+{
+XkbSrvLedInfoPtr sli;
+XkbChangesRec changes;
+xkbExtensionDeviceNotify ed;
+unsigned side_affected;
+
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ sli->explicitState&= ~affect;
+ sli->explicitState|= (affect&values);
+ XkbApplyLedStateChanges(dev,sli,affect,&ed,&changes,cause);
+
+ side_affected= 0;
+ if (changes.state_changes!=0)
+ side_affected|= XkbIndicatorsToUpdate(dev,changes.state_changes,FALSE);
+ if (changes.ctrls.enabled_ctrls_changes)
+ side_affected|= sli->usesControls;
+
+ if (side_affected) {
+ XkbUpdateLedAutoState(dev,sli,side_affected,&ed,&changes,cause);
+ affect|= side_affected;
+ }
+ if (changes.state_changes || changes.ctrls.enabled_ctrls_changes)
+ XkbUpdateAllDeviceIndicators(NULL,cause);
+
+ XkbFlushLedEvents(dev,dev,sli,&ed,&changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbUpdateIndicators(dev,update,check_edevs,changes,cause)
+ *
+ * Applies the indicator maps for any indicators specified in
+ * 'update' from the default keyboard feedback on the device
+ * specified by 'dev.'
+ *
+ * If 'changes' is NULL, this function generates and XKB events
+ * required to report the necessary changes, otherwise it simply
+ * notes the indicators with changed state.
+ *
+ * If 'check_edevs' is TRUE, this function also checks the indicator
+ * maps for any open extension devices that have them, and updates
+ * the state of any extension device indicators as necessary.
+ */
+
+void
+XkbUpdateIndicators( DeviceIntPtr dev,
+ register CARD32 update,
+ Bool check_edevs,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+XkbSrvLedInfoPtr sli;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateLedAutoState(dev,sli,update,NULL,changes,cause);
+ if (check_edevs)
+ XkbUpdateAllDeviceIndicators(changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbCheckIndicatorMaps(dev,sli,which)
+ *
+ * Updates the 'indicator accelerators' for the indicators specified
+ * by 'which' in the feedback specified by 'sli.' The indicator
+ * accelerators are internal to the server and are used to simplify
+ * and speed up the process of figuring out which indicators might
+ * be affected by a particular change in keyboard state or controls.
+ */
+
+void
+XkbCheckIndicatorMaps(DeviceIntPtr dev,XkbSrvLedInfoPtr sli,unsigned which)
+{
+register unsigned i,bit;
+XkbIndicatorMapPtr map;
+XkbDescPtr xkb;
+
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ return;
+
+ sli->usesBase&= ~which;
+ sli->usesLatched&= ~which;
+ sli->usesLocked&= ~which;
+ sli->usesEffective&= ~which;
+ sli->usesCompat&= ~which;
+ sli->usesControls&= ~which;
+ sli->mapsPresent&= ~which;
+
+ xkb= dev->key->xkbInfo->desc;
+ for (i=0,bit=1,map=sli->maps;i<XkbNumIndicators;i++,bit<<=1,map++) {
+ if (which&bit) {
+ CARD8 what;
+
+ if (!map || !XkbIM_InUse(map))
+ continue;
+ sli->mapsPresent|= bit;
+
+ what= (map->which_mods|map->which_groups);
+ if (what&XkbIM_UseBase)
+ sli->usesBase|= bit;
+ if (what&XkbIM_UseLatched)
+ sli->usesLatched|= bit;
+ if (what&XkbIM_UseLocked)
+ sli->usesLocked|= bit;
+ if (what&XkbIM_UseEffective)
+ sli->usesEffective|= bit;
+ if (what&XkbIM_UseCompat)
+ sli->usesCompat|= bit;
+ if (map->ctrls)
+ sli->usesControls|= bit;
+
+ map->mods.mask= map->mods.real_mods;
+ if (map->mods.vmods!=0) {
+ map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods);
+ }
+ }
+ }
+ sli->usedComponents= 0;
+ if (sli->usesBase)
+ sli->usedComponents|= XkbModifierBaseMask|XkbGroupBaseMask;
+ if (sli->usesLatched)
+ sli->usedComponents|= XkbModifierLatchMask|XkbGroupLatchMask;
+ if (sli->usesLocked)
+ sli->usedComponents|= XkbModifierLockMask|XkbGroupLockMask;
+ if (sli->usesEffective)
+ sli->usedComponents|= XkbModifierStateMask|XkbGroupStateMask;
+ if (sli->usesCompat)
+ sli->usedComponents|= XkbCompatStateMask;
+ return;
+}
+
+/***====================================================================***/
+
+ /*
+ * XkbSrvLedInfoPtr
+ * XkbAllocSrvLedInfo(dev,kf,lf,needed_parts)
+ *
+ * Allocates an XkbSrvLedInfoPtr for the feedback specified by either
+ * 'kf' or 'lf' on the keyboard specified by 'dev.'
+ *
+ * If 'needed_parts' is non-zero, this function makes sure that any
+ * of the parts speicified therein are allocated.
+ */
+XkbSrvLedInfoPtr
+XkbAllocSrvLedInfo( DeviceIntPtr dev,
+ KbdFeedbackPtr kf,
+ LedFeedbackPtr lf,
+ unsigned needed_parts)
+{
+XkbSrvLedInfoPtr sli;
+Bool checkAccel;
+Bool checkNames;
+
+ sli= NULL;
+ checkAccel= checkNames= FALSE;
+ if ((kf!=NULL)&&(kf->xkb_sli==NULL)) {
+ kf->xkb_sli= sli= calloc(1, sizeof(XkbSrvLedInfoRec));
+ if (sli==NULL)
+ return NULL; /* ALLOCATION ERROR */
+ if (dev->key && dev->key->xkbInfo)
+ sli->flags= XkbSLI_HasOwnState;
+ else sli->flags= 0;
+ sli->class= KbdFeedbackClass;
+ sli->id= kf->ctrl.id;
+ sli->fb.kf= kf;
+
+ sli->autoState= 0;
+ sli->explicitState= kf->ctrl.leds;
+ sli->effectiveState= kf->ctrl.leds;
+
+ if ((kf==dev->kbdfeed) && (dev->key) && (dev->key->xkbInfo)) {
+ XkbDescPtr xkb;
+ xkb= dev->key->xkbInfo->desc;
+ sli->flags|= XkbSLI_IsDefault;
+ sli->physIndicators= xkb->indicators->phys_indicators;
+ sli->names= xkb->names->indicators;
+ sli->maps= xkb->indicators->maps;
+ checkNames= checkAccel= TRUE;
+ }
+ else {
+ sli->physIndicators= XkbAllIndicatorsMask;
+ sli->names= NULL;
+ sli->maps= NULL;
+ }
+ }
+ else if ((kf!=NULL)&&((kf->xkb_sli->flags&XkbSLI_IsDefault)!=0)) {
+ XkbDescPtr xkb;
+ xkb= dev->key->xkbInfo->desc;
+ sli->physIndicators= xkb->indicators->phys_indicators;
+ if (xkb->names->indicators!=sli->names) {
+ checkNames= TRUE;
+ sli->names= xkb->names->indicators;
+ }
+ if (xkb->indicators->maps!=sli->maps) {
+ checkAccel= TRUE;
+ sli->maps= xkb->indicators->maps;
+ }
+ }
+ else if ((lf!=NULL)&&(lf->xkb_sli==NULL)) {
+ lf->xkb_sli= sli= calloc(1, sizeof(XkbSrvLedInfoRec));
+ if (sli==NULL)
+ return NULL; /* ALLOCATION ERROR */
+ if (dev->key && dev->key->xkbInfo)
+ sli->flags= XkbSLI_HasOwnState;
+ else sli->flags= 0;
+ sli->class= LedFeedbackClass;
+ sli->id= lf->ctrl.id;
+ sli->fb.lf= lf;
+
+ sli->physIndicators= lf->ctrl.led_mask;
+ sli->autoState= 0;
+ sli->explicitState= lf->ctrl.led_values;
+ sli->effectiveState= lf->ctrl.led_values;
+ sli->maps= NULL;
+ sli->names= NULL;
+ }
+ if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
+ sli->names= calloc(XkbNumIndicators, sizeof(Atom));
+ if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
+ sli->maps= calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
+ if (checkNames) {
+ register unsigned i,bit;
+ sli->namesPresent= 0;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (sli->names[i]!=None)
+ sli->namesPresent|= bit;
+ }
+ }
+ if (checkAccel)
+ XkbCheckIndicatorMaps(dev,sli,XkbAllIndicatorsMask);
+ return sli;
+}
+
+void
+XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli)
+{
+ if ((sli->flags&XkbSLI_IsDefault)==0) {
+ if (sli->maps) free(sli->maps);
+ if (sli->names) free(sli->names);
+ }
+ sli->maps= NULL;
+ sli->names= NULL;
+ free(sli);
+ return;
+}
+
+/*
+ * XkbSrvLedInfoPtr
+ * XkbCopySrvLedInfo(dev,src,kf,lf)
+ *
+ * Takes the given XkbSrvLedInfoPtr and duplicates it. A deep copy is made,
+ * thus the new copy behaves like the original one and can be freed with
+ * XkbFreeSrvLedInfo.
+ */
+XkbSrvLedInfoPtr
+XkbCopySrvLedInfo( DeviceIntPtr from,
+ XkbSrvLedInfoPtr src,
+ KbdFeedbackPtr kf,
+ LedFeedbackPtr lf)
+{
+ XkbSrvLedInfoPtr sli_new = NULL;
+
+ if (!src)
+ goto finish;
+
+ sli_new = calloc(1, sizeof( XkbSrvLedInfoRec));
+ if (!sli_new)
+ goto finish;
+
+ memcpy(sli_new, src, sizeof(XkbSrvLedInfoRec));
+ if (sli_new->class == KbdFeedbackClass)
+ sli_new->fb.kf = kf;
+ else
+ sli_new->fb.lf = lf;
+
+ if (!(sli_new->flags & XkbSLI_IsDefault)) {
+ sli_new->names= calloc(XkbNumIndicators, sizeof(Atom));
+ sli_new->maps= calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
+ } /* else sli_new->names/maps is pointing to
+ dev->key->xkbInfo->desc->names->indicators;
+ dev->key->xkbInfo->desc->names->indicators; */
+
+finish:
+ return sli_new;
+}
+
+/***====================================================================***/
+
+ /*
+ * XkbSrvLedInfoPtr
+ * XkbFindSrvLedInfo(dev,class,id,needed_parts)
+ *
+ * Finds the XkbSrvLedInfoPtr for the specified 'class' and 'id'
+ * on the device specified by 'dev.' If the class and id specify
+ * a valid device feedback, this function returns the existing
+ * feedback or allocates a new one.
+ *
+ */
+
+XkbSrvLedInfoPtr
+XkbFindSrvLedInfo( DeviceIntPtr dev,
+ unsigned class,
+ unsigned id,
+ unsigned needed_parts)
+{
+XkbSrvLedInfoPtr sli;
+
+ /* optimization to check for most common case */
+ if (((class==XkbDfltXIClass)&&(id==XkbDfltXIId))&&(dev->kbdfeed)) {
+ XkbSrvLedInfoPtr sli;
+ sli= dev->kbdfeed->xkb_sli;
+ if (dev->kbdfeed->xkb_sli==NULL) {
+ sli= XkbAllocSrvLedInfo(dev,dev->kbdfeed,NULL,needed_parts);
+ dev->kbdfeed->xkb_sli= sli;
+ }
+ return dev->kbdfeed->xkb_sli;
+ }
+
+ sli= NULL;
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ else return NULL;
+ }
+ if (class==KbdFeedbackClass) {
+ KbdFeedbackPtr kf;
+ for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) {
+ if ((id==XkbDfltXIId)||(id==kf->ctrl.id)) {
+ if (kf->xkb_sli==NULL)
+ kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,needed_parts);
+ sli= kf->xkb_sli;
+ break;
+ }
+ }
+ }
+ else if (class==LedFeedbackClass) {
+ LedFeedbackPtr lf;
+ for (lf=dev->leds;lf!=NULL;lf=lf->next) {
+ if ((id==XkbDfltXIId)||(id==lf->ctrl.id)) {
+ if (lf->xkb_sli==NULL)
+ lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,needed_parts);
+ sli= lf->xkb_sli;
+ break;
+ }
+ }
+ }
+ if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
+ sli->names= calloc(XkbNumIndicators, sizeof(Atom));
+ if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
+ sli->maps= calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
+ return sli;
+}
+
+/***====================================================================***/
+
+void
+XkbFlushLedEvents( DeviceIntPtr dev,
+ DeviceIntPtr kbd,
+ XkbSrvLedInfoPtr sli,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+ if (changes) {
+ if (changes->indicators.state_changes)
+ XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
+ XkbSendNotification(kbd,changes,cause);
+ bzero((char *)changes,sizeof(XkbChangesRec));
+
+ if (XkbAX_NeedFeedback(kbd->key->xkbInfo->desc->ctrls, XkbAX_IndicatorFBMask)) {
+ if (sli->effectiveState)
+ /* it appears that the which parameter is not used */
+ XkbDDXAccessXBeep(dev, _BEEP_LED_ON, XkbAccessXFeedbackMask);
+ else
+ XkbDDXAccessXBeep(dev, _BEEP_LED_OFF, XkbAccessXFeedbackMask);
+ }
+ }
+ if (ed) {
+ if (ed->reason) {
+ if ((dev!=kbd)&&(ed->reason&XkbXI_IndicatorStateMask))
+ XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
+ XkbSendExtensionDeviceNotify(dev,cause->client,ed);
+ }
+ bzero((char *)ed,sizeof(XkbExtensionDeviceNotify));
+ }
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbApplyLedNameChanges( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_names,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+
+ if (changed_names==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= inputInfo.keyboard;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->names.changed|= XkbIndicatorNamesMask;
+ changes->names.changed_indicators|= changed_names;
+ }
+
+ ed->reason|= XkbXI_IndicatorNamesMask;
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported= 0;
+ ed->supported= XkbXI_AllFeaturesMask;
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbApplyLedMapChanges(dev,sli,changed_maps,changes,cause)
+ *
+ * Handles all of the secondary effects of the changes to the
+ * feedback specified by 'sli' on the device specified by 'dev.'
+ *
+ * If 'changed_maps' specifies any indicators, this function generates
+ * XkbExtensionDeviceNotify events and possibly IndicatorMapNotify
+ * events to report the changes, and recalculates the effective
+ * state of each indicator with a changed map. If any indicators
+ * change state, the server generates XkbExtensionDeviceNotify and
+ * XkbIndicatorStateNotify events as appropriate.
+ *
+ * If 'changes' is non-NULL, this function updates it to reflect
+ * any changes to the keyboard state or controls or to the 'core'
+ * indicator names, maps, or state. If 'changes' is NULL, this
+ * function generates XKB events as needed to report the changes.
+ * If 'dev' is not a keyboard device, any changes are reported
+ * for the core keyboard.
+ *
+ * The 'cause' specifies the reason for the event (key event or
+ * request) for the change, as reported in some XKB events.
+ */
+
+void
+XkbApplyLedMapChanges( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_maps,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+
+ if (changed_maps==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= inputInfo.keyboard;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->indicators.map_changes|= changed_maps;
+ }
+
+ XkbCheckIndicatorMaps(dev,sli,changed_maps);
+
+ ed->reason|= XkbXI_IndicatorMapsMask;
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported= 0;
+ ed->supported= XkbXI_AllFeaturesMask;
+
+ XkbUpdateLedAutoState(dev,sli,changed_maps,ed,changes,cause);
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbApplyLedStateChanges(DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_leds,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+XkbSrvInfoPtr xkbi;
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+register unsigned i,bit,affected;
+XkbIndicatorMapPtr map;
+unsigned oldState;
+Bool kb_changed;
+
+ if (changed_leds==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= inputInfo.keyboard;
+ xkbi= kbd->key->xkbInfo;
+
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+
+ kb_changed= FALSE;
+ affected= changed_leds;
+ oldState= sli->effectiveState;
+ for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
+ if ((affected&bit)==0)
+ continue;
+ affected&= ~bit;
+ map= &sli->maps[i];
+ if (map->flags&XkbIM_NoExplicit) {
+ sli->explicitState&= ~bit;
+ continue;
+ }
+ if (map->flags&XkbIM_LEDDrivesKB) {
+ Bool on= ((sli->explicitState&bit)!=0);
+ if (XkbApplyLEDChangeToKeyboard(xkbi,map,on,changes))
+ kb_changed= TRUE;
+ }
+ }
+ sli->effectiveState= (sli->autoState|sli->explicitState);
+ affected= sli->effectiveState^oldState;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if (affected&&(ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault))
+ changes->indicators.state_changes|= affected;
+ if (affected) {
+ ed->reason|= XkbXI_IndicatorStateMask;
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported= 0;
+ ed->supported= XkbXI_AllFeaturesMask;
+ }
+
+ if (kb_changed) {
+ XkbComputeDerivedState(kbd->key->xkbInfo);
+ XkbUpdateLedAutoState(dev,sli,sli->mapsPresent,ed,changes,cause);
+ }
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ if (kb_changed)
+ XkbUpdateAllDeviceIndicators(NULL,cause);
+ return;
+}
diff --git a/xorg-server/xkb/xkbUtils.c b/xorg-server/xkb/xkbUtils.c
index 6d0901a36..286fab073 100644
--- a/xorg-server/xkb/xkbUtils.c
+++ b/xorg-server/xkb/xkbUtils.c
@@ -1,2192 +1,2192 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-/*
-
-Copyright © 2008 Red Hat Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "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.
-
-*/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "os.h"
-#include <stdio.h>
-#include <ctype.h>
-#include <math.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#define XK_CYRILLIC
-#include <X11/keysym.h>
-#include "misc.h"
-#include "inputstr.h"
-#include "eventstr.h"
-
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-#include "xkbgeom.h"
-#include "xkb.h"
-
-/***====================================================================***/
-
-int
-_XkbLookupAnyDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
- Mask access_mode, int *xkb_err)
-{
- int rc = XkbKeyboardErrorCode;
-
- if (id == XkbUseCoreKbd)
- id = PickKeyboard(client)->id;
- else if (id == XkbUseCorePtr)
- id = PickPointer(client)->id;
-
- rc = dixLookupDevice(pDev, id, client, access_mode);
- if (rc != Success)
- *xkb_err = XkbErr_BadDevice;
-
- return rc;
-}
-
-int
-_XkbLookupKeyboard(DeviceIntPtr *pDev, int id, ClientPtr client,
- Mask access_mode, int *xkb_err)
-{
- DeviceIntPtr dev;
- int rc;
-
- if (id == XkbDfltXIId)
- id = XkbUseCoreKbd;
-
- rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
- if (rc != Success)
- return rc;
-
- dev = *pDev;
- if (!dev->key || !dev->key->xkbInfo) {
- *pDev = NULL;
- *xkb_err= XkbErr_BadClass;
- return XkbKeyboardErrorCode;
- }
- return Success;
-}
-
-int
-_XkbLookupBellDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
- Mask access_mode, int *xkb_err)
-{
- DeviceIntPtr dev;
- int rc;
-
- rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
- if (rc != Success)
- return rc;
-
- dev = *pDev;
- if (!dev->kbdfeed && !dev->bell) {
- *pDev = NULL;
- *xkb_err= XkbErr_BadClass;
- return XkbKeyboardErrorCode;
- }
- return Success;
-}
-
-int
-_XkbLookupLedDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
- Mask access_mode, int *xkb_err)
-{
- DeviceIntPtr dev;
- int rc;
-
- if (id == XkbDfltXIId)
- id = XkbUseCorePtr;
-
- rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
- if (rc != Success)
- return rc;
-
- dev = *pDev;
- if (!dev->kbdfeed && !dev->leds) {
- *pDev = NULL;
- *xkb_err= XkbErr_BadClass;
- return XkbKeyboardErrorCode;
- }
- return Success;
-}
-
-int
-_XkbLookupButtonDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
- Mask access_mode, int *xkb_err)
-{
- DeviceIntPtr dev;
- int rc;
-
- rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
- if (rc != Success)
- return rc;
-
- dev = *pDev;
- if (!dev->button) {
- *pDev = NULL;
- *xkb_err= XkbErr_BadClass;
- return XkbKeyboardErrorCode;
- }
- return Success;
-}
-
-void
-XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
-{
-register unsigned tmp;
-
- switch (act->type) {
- case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
- if (act->mods.flags&XkbSA_UseModMapMods)
- act->mods.real_mods= act->mods.mask= mods;
- if ((tmp= XkbModActionVMods(&act->mods))!=0)
- act->mods.mask|= XkbMaskForVMask(xkb,tmp);
- break;
- case XkbSA_ISOLock:
- if (act->iso.flags&XkbSA_UseModMapMods)
- act->iso.real_mods= act->iso.mask= mods;
- if ((tmp= XkbModActionVMods(&act->iso))!=0)
- act->iso.mask|= XkbMaskForVMask(xkb,tmp);
- break;
- }
- return;
-}
-
-unsigned
-XkbMaskForVMask(XkbDescPtr xkb,unsigned vmask)
-{
-register int i,bit;
-register unsigned mask;
-
- for (mask=i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (vmask&bit)
- mask|= xkb->server->vmods[i];
- }
- return mask;
-}
-
-/***====================================================================***/
-
-void
-XkbUpdateKeyTypesFromCore( DeviceIntPtr pXDev,
- KeySymsPtr pCore,
- KeyCode first,
- CARD8 num,
- XkbChangesPtr changes)
-{
-XkbDescPtr xkb;
-unsigned key,nG,explicit;
-int types[XkbNumKbdGroups];
-KeySym tsyms[XkbMaxSymsPerKey],*syms;
-XkbMapChangesPtr mc;
-
- xkb= pXDev->key->xkbInfo->desc;
- if (first+num-1>xkb->max_key_code) {
- /* 1/12/95 (ef) -- XXX! should allow XKB structures to grow */
- num= xkb->max_key_code-first+1;
- }
-
- mc= (changes?(&changes->map):NULL);
-
- syms= &pCore->map[(first - pCore->minKeyCode) * pCore->mapWidth];
- for (key=first; key<(first+num); key++,syms+= pCore->mapWidth) {
- explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
- types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
- types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
- types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
- types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
- nG= XkbKeyTypesForCoreSymbols(xkb,pCore->mapWidth,syms,explicit,types,
- tsyms);
- XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
- memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
- XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
- }
- if (changes->map.changed&XkbKeySymsMask) {
- CARD8 oldLast,newLast;
- oldLast = changes->map.first_key_sym+changes->map.num_key_syms-1;
- newLast = first+num-1;
-
- if (first<changes->map.first_key_sym)
- changes->map.first_key_sym = first;
- if (oldLast>newLast)
- newLast= oldLast;
- changes->map.num_key_syms = newLast-changes->map.first_key_sym+1;
- }
- else {
- changes->map.changed|= XkbKeySymsMask;
- changes->map.first_key_sym = first;
- changes->map.num_key_syms = num;
- }
- return;
-}
-
-void
-XkbUpdateDescActions( XkbDescPtr xkb,
- KeyCode first,
- CARD8 num,
- XkbChangesPtr changes)
-{
-register unsigned key;
-
- for (key=first;key<(first+num);key++) {
- XkbApplyCompatMapToKey(xkb,key,changes);
- }
-
- if (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask)) {
- unsigned char newVMods[XkbNumVirtualMods];
- register unsigned bit,i;
- unsigned present;
-
- bzero(newVMods,XkbNumVirtualMods);
- present= 0;
- for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
- if (xkb->server->vmodmap[key]==0)
- continue;
- for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (bit&xkb->server->vmodmap[key]) {
- present|= bit;
- newVMods[i]|= xkb->map->modmap[key];
- }
- }
- }
- for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
- changes->map.changed|= XkbVirtualModsMask;
- changes->map.vmods|= bit;
- xkb->server->vmods[i]= newVMods[i];
- }
- }
- }
- if (changes->map.changed&XkbVirtualModsMask)
- XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
-
- if (changes->map.changed&XkbKeyActionsMask) {
- CARD8 oldLast,newLast;
- oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
- newLast = first+num-1;
-
- if (first<changes->map.first_key_act)
- changes->map.first_key_act = first;
- if (newLast>oldLast)
- newLast= oldLast;
- changes->map.num_key_acts= newLast-changes->map.first_key_act+1;
- }
- else {
- changes->map.changed|= XkbKeyActionsMask;
- changes->map.first_key_act = first;
- changes->map.num_key_acts = num;
- }
- return;
-}
-
-void
-XkbUpdateActions( DeviceIntPtr pXDev,
- KeyCode first,
- CARD8 num,
- XkbChangesPtr changes,
- unsigned * needChecksRtrn,
- XkbEventCausePtr cause)
-{
-XkbSrvInfoPtr xkbi;
-XkbDescPtr xkb;
-CARD8 * repeat;
-
- if (needChecksRtrn)
- *needChecksRtrn= 0;
- xkbi= pXDev->key->xkbInfo;
- xkb= xkbi->desc;
- repeat= xkb->ctrls->per_key_repeat;
-
- if (pXDev->kbdfeed)
- memcpy(repeat,pXDev->kbdfeed->ctrl.autoRepeats,XkbPerKeyBitArraySize);
-
- XkbUpdateDescActions(xkb,first,num,changes);
-
- if ((pXDev->kbdfeed)&&
- (changes->ctrls.enabled_ctrls_changes&XkbPerKeyRepeatMask)) {
- memcpy(pXDev->kbdfeed->ctrl.autoRepeats,repeat, XkbPerKeyBitArraySize);
- (*pXDev->kbdfeed->CtrlProc)(pXDev, &pXDev->kbdfeed->ctrl);
- }
- return;
-}
-
-KeySymsPtr
-XkbGetCoreMap(DeviceIntPtr keybd)
-{
-register int key,tmp;
-int maxSymsPerKey, maxGroup1Width;
-XkbDescPtr xkb;
-KeySymsPtr syms;
-int maxNumberOfGroups;
-
- if (!keybd || !keybd->key || !keybd->key->xkbInfo)
- return NULL;
-
- xkb= keybd->key->xkbInfo->desc;
- maxSymsPerKey= maxGroup1Width= 0;
- maxNumberOfGroups = 0;
-
- /* determine sizes */
- for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
- if (XkbKeycodeInRange(xkb,key)) {
- int nGroups;
- int w;
- nGroups= XkbKeyNumGroups(xkb,key);
- tmp= 0;
- if (nGroups>0) {
- if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup1Index))<=2)
- tmp+= 2;
- else tmp+= w + 2;
- /* remember highest G1 width */
- if (w > maxGroup1Width)
- maxGroup1Width = w;
- }
- if (nGroups>1) {
- if (tmp <= 2) {
- if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))<2)
- tmp+= 2;
- else tmp+= w;
- } else {
- if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))>2)
- tmp+= w - 2;
- }
- }
- if (nGroups>2)
- tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup3Index);
- if (nGroups>3)
- tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup4Index);
- if (tmp>maxSymsPerKey)
- maxSymsPerKey= tmp;
- if (nGroups > maxNumberOfGroups)
- maxNumberOfGroups = nGroups;
- }
- }
-
- if (maxSymsPerKey <= 0)
- return NULL;
-
- syms = xcalloc(1, sizeof(*syms));
- if (!syms)
- return NULL;
-
- /* See Section 12.4 of the XKB Protocol spec. Because of the
- * single-group distribution for multi-group keyboards, we have to
- * have enough symbols for the largest group 1 to replicate across the
- * number of groups on the keyboard. e.g. a single-group key with 4
- * symbols on a keyboard that has 3 groups -> 12 syms per key */
- if (maxSymsPerKey < maxNumberOfGroups * maxGroup1Width)
- maxSymsPerKey = maxNumberOfGroups * maxGroup1Width;
-
- syms->mapWidth = maxSymsPerKey;
- syms->minKeyCode = xkb->min_key_code;
- syms->maxKeyCode = xkb->max_key_code;
-
- tmp = syms->mapWidth * (xkb->max_key_code - xkb->min_key_code + 1);
- syms->map = xcalloc(tmp, sizeof(*syms->map));
- if (!syms->map) {
- xfree(syms);
- return NULL;
- }
-
- for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
- KeySym *pCore,*pXKB;
- unsigned nGroups,groupWidth,n,nOut;
-
- nGroups= XkbKeyNumGroups(xkb,key);
- n= (key-xkb->min_key_code)*syms->mapWidth;
- pCore= &syms->map[n];
- pXKB= XkbKeySymsPtr(xkb,key);
- nOut= 2;
- if (nGroups>0) {
- groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup1Index);
- if (groupWidth>0) pCore[0]= pXKB[0];
- if (groupWidth>1) pCore[1]= pXKB[1];
- for (n=2;n<groupWidth;n++)
- pCore[2+n]= pXKB[n];
- if (groupWidth>2)
- nOut= groupWidth;
- }
-
- /* See XKB Protocol Sec, Section 12.4.
- A 1-group key with ABCDE on a 2 group keyboard must be
- duplicated across all groups as ABABCDECDE.
- */
- if (nGroups == 1)
- {
- int idx, j;
-
- groupWidth = XkbKeyGroupWidth(xkb, key, XkbGroup1Index);
-
- /* AB..CDE... -> ABABCDE... */
- if (groupWidth > 0 && syms->mapWidth >= 3)
- pCore[2] = pCore[0];
- if (groupWidth > 1 && syms->mapWidth >= 4)
- pCore[3] = pCore[1];
-
- /* ABABCDE... -> ABABCDECDE */
- idx = 2 + groupWidth;
- while (groupWidth > 2 && idx < syms->mapWidth &&
- idx < groupWidth * 2)
- {
- pCore[idx] = pCore[idx - groupWidth + 2];
- idx++;
- }
- idx = 2 * groupWidth;
- if (idx < 4)
- idx = 4;
- /* 3 or more groups: ABABCDECDEABCDEABCDE */
- for (j = 3; j <= maxNumberOfGroups; j++)
- for (n = 0; n < groupWidth && idx < maxSymsPerKey; n++)
- pCore[idx++] = pXKB[n];
- }
-
- pXKB+= XkbKeyGroupsWidth(xkb,key);
- nOut+= 2;
- if (nGroups>1) {
- groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index);
- if (groupWidth>0) pCore[2]= pXKB[0];
- if (groupWidth>1) pCore[3]= pXKB[1];
- for (n=2;n<groupWidth;n++) {
- pCore[nOut+(n-2)]= pXKB[n];
- }
- if (groupWidth>2)
- nOut+= (groupWidth-2);
- }
- pXKB+= XkbKeyGroupsWidth(xkb,key);
- for (n=XkbGroup3Index;n<nGroups;n++) {
- register int s;
- groupWidth= XkbKeyGroupWidth(xkb,key,n);
- for (s=0;s<groupWidth;s++) {
- pCore[nOut++]= pXKB[s];
- }
- pXKB+= XkbKeyGroupsWidth(xkb,key);
- }
- }
-
- return syms;
-}
-
-void
-XkbSetRepeatKeys(DeviceIntPtr pXDev,int key,int onoff)
-{
- if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
- xkbControlsNotify cn;
- XkbControlsPtr ctrls = pXDev->key->xkbInfo->desc->ctrls;
- XkbControlsRec old;
- old = *ctrls;
-
- if (key== -1) { /* global autorepeat setting changed */
- if (onoff) ctrls->enabled_ctrls |= XkbRepeatKeysMask;
- else ctrls->enabled_ctrls &= ~XkbRepeatKeysMask;
- }
- else if (pXDev->kbdfeed) {
- ctrls->per_key_repeat[key/8] =
- pXDev->kbdfeed->ctrl.autoRepeats[key/8];
- }
-
- if (XkbComputeControlsNotify(pXDev,&old,ctrls,&cn,TRUE))
- XkbSendControlsNotify(pXDev,&cn);
- }
- return;
-}
-
-/* Applies a change to a single device, does not traverse the device tree. */
-void
-XkbApplyMappingChange(DeviceIntPtr kbd, KeySymsPtr map, KeyCode first_key,
- CARD8 num_keys, CARD8 *modmap, ClientPtr client)
-{
- XkbDescPtr xkb = kbd->key->xkbInfo->desc;
- XkbEventCauseRec cause;
- XkbChangesRec changes;
- unsigned int check;
-
- memset(&changes, 0, sizeof(changes));
- memset(&cause, 0, sizeof(cause));
-
- if (map && first_key && num_keys) {
- check = 0;
- XkbSetCauseCoreReq(&cause, X_ChangeKeyboardMapping, client);
-
- XkbUpdateKeyTypesFromCore(kbd, map, first_key, num_keys, &changes);
- XkbUpdateActions(kbd, first_key, num_keys, &changes, &check, &cause);
-
- if (check)
- XkbCheckSecondaryEffects(kbd->key->xkbInfo, 1, &changes, &cause);
- }
-
- if (modmap) {
- /* A keymap change can imply a modmap change, se we prefer the
- * former. */
- if (!cause.mjr)
- XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client);
-
- check = 0;
- num_keys = xkb->max_key_code - xkb->min_key_code + 1;
- changes.map.changed |= XkbModifierMapMask;
- changes.map.first_modmap_key = xkb->min_key_code;
- changes.map.num_modmap_keys = num_keys;
- memcpy(kbd->key->xkbInfo->desc->map->modmap, modmap, MAP_LENGTH);
- XkbUpdateActions(kbd, xkb->min_key_code, num_keys, &changes, &check,
- &cause);
-
- if (check)
- XkbCheckSecondaryEffects(kbd->key->xkbInfo, 1, &changes, &cause);
- }
-
- XkbSendNotification(kbd, &changes, &cause);
-}
-
-void
-XkbDisableComputedAutoRepeats(DeviceIntPtr dev,unsigned key)
-{
-XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
-xkbMapNotify mn;
-
- xkbi->desc->server->explicit[key]|= XkbExplicitAutoRepeatMask;
- bzero(&mn,sizeof(mn));
- mn.changed= XkbExplicitComponentsMask;
- mn.firstKeyExplicit= key;
- mn.nKeyExplicit= 1;
- XkbSendMapNotify(dev,&mn);
- return;
-}
-
-unsigned
-XkbStateChangedFlags(XkbStatePtr old,XkbStatePtr new)
-{
-int changed;
-
- changed=(old->group!=new->group?XkbGroupStateMask:0);
- changed|=(old->base_group!=new->base_group?XkbGroupBaseMask:0);
- changed|=(old->latched_group!=new->latched_group?XkbGroupLatchMask:0);
- changed|=(old->locked_group!=new->locked_group?XkbGroupLockMask:0);
- changed|=(old->mods!=new->mods?XkbModifierStateMask:0);
- changed|=(old->base_mods!=new->base_mods?XkbModifierBaseMask:0);
- changed|=(old->latched_mods!=new->latched_mods?XkbModifierLatchMask:0);
- changed|=(old->locked_mods!=new->locked_mods?XkbModifierLockMask:0);
- changed|=(old->compat_state!=new->compat_state?XkbCompatStateMask:0);
- changed|=(old->grab_mods!=new->grab_mods?XkbGrabModsMask:0);
- if (old->compat_grab_mods!=new->compat_grab_mods)
- changed|= XkbCompatGrabModsMask;
- changed|=(old->lookup_mods!=new->lookup_mods?XkbLookupModsMask:0);
- if (old->compat_lookup_mods!=new->compat_lookup_mods)
- changed|= XkbCompatLookupModsMask;
- changed|=(old->ptr_buttons!=new->ptr_buttons?XkbPointerButtonMask:0);
- return changed;
-}
-
-static void
-XkbComputeCompatState(XkbSrvInfoPtr xkbi)
-{
-CARD16 grp_mask;
-XkbStatePtr state= &xkbi->state;
-XkbCompatMapPtr map;
-
- if (!state || !xkbi->desc || !xkbi->desc->ctrls || !xkbi->desc->compat)
- return;
-
- map= xkbi->desc->compat;
- grp_mask= map->groups[state->group].mask;
- state->compat_state = state->mods|grp_mask;
- state->compat_lookup_mods= state->lookup_mods|grp_mask;
-
- if (xkbi->desc->ctrls->enabled_ctrls&XkbIgnoreGroupLockMask)
- grp_mask= map->groups[state->base_group].mask;
- state->compat_grab_mods= state->grab_mods|grp_mask;
- return;
-}
-
-unsigned
-XkbAdjustGroup(int group,XkbControlsPtr ctrls)
-{
-unsigned act;
-
- act= XkbOutOfRangeGroupAction(ctrls->groups_wrap);
- if (group<0) {
- while ( group < 0 ) {
- if (act==XkbClampIntoRange) {
- group= XkbGroup1Index;
- }
- else if (act==XkbRedirectIntoRange) {
- int newGroup;
- newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
- if (newGroup>=ctrls->num_groups)
- group= XkbGroup1Index;
- else group= newGroup;
- }
- else {
- group+= ctrls->num_groups;
- }
- }
- }
- else if (group>=ctrls->num_groups) {
- if (act==XkbClampIntoRange) {
- group= ctrls->num_groups-1;
- }
- else if (act==XkbRedirectIntoRange) {
- int newGroup;
- newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
- if (newGroup>=ctrls->num_groups)
- group= XkbGroup1Index;
- else group= newGroup;
- }
- else {
- group%= ctrls->num_groups;
- }
- }
- return group;
-}
-
-void
-XkbComputeDerivedState(XkbSrvInfoPtr xkbi)
-{
-XkbStatePtr state= &xkbi->state;
-XkbControlsPtr ctrls= xkbi->desc->ctrls;
-unsigned char grp;
-
- if (!state || !ctrls)
- return;
-
- state->mods= (state->base_mods|state->latched_mods|state->locked_mods);
- state->lookup_mods= state->mods&(~ctrls->internal.mask);
- state->grab_mods= state->lookup_mods&(~ctrls->ignore_lock.mask);
- state->grab_mods|=
- ((state->base_mods|state->latched_mods)&ctrls->ignore_lock.mask);
-
-
- grp= state->locked_group;
- if (grp>=ctrls->num_groups)
- state->locked_group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
-
- grp= state->locked_group+state->base_group+state->latched_group;
- if (grp>=ctrls->num_groups)
- state->group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
- else state->group= grp;
- XkbComputeCompatState(xkbi);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbCheckSecondaryEffects( XkbSrvInfoPtr xkbi,
- unsigned which,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
- if (which&XkbStateNotifyMask) {
- XkbStateRec old;
- old= xkbi->state;
- changes->state_changes|= XkbStateChangedFlags(&old,&xkbi->state);
- XkbComputeDerivedState(xkbi);
- }
- if (which&XkbIndicatorStateNotifyMask)
- XkbUpdateIndicators(xkbi->device,XkbAllIndicatorsMask,TRUE,changes,
- cause);
- return;
-}
-
-/***====================================================================***/
-
-Bool
-XkbEnableDisableControls( XkbSrvInfoPtr xkbi,
- unsigned long change,
- unsigned long newValues,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-XkbControlsPtr ctrls;
-unsigned old;
-XkbSrvLedInfoPtr sli;
-
- ctrls= xkbi->desc->ctrls;
- old= ctrls->enabled_ctrls;
- ctrls->enabled_ctrls&= ~change;
- ctrls->enabled_ctrls|= (change&newValues);
- if (old==ctrls->enabled_ctrls)
- return FALSE;
- if (cause!=NULL) {
- xkbControlsNotify cn;
- cn.numGroups= ctrls->num_groups;
- cn.changedControls= XkbControlsEnabledMask;
- cn.enabledControls= ctrls->enabled_ctrls;
- cn.enabledControlChanges= (ctrls->enabled_ctrls^old);
- cn.keycode= cause->kc;
- cn.eventType= cause->event;
- cn.requestMajor= cause->mjr;
- cn.requestMinor= cause->mnr;
- XkbSendControlsNotify(xkbi->device,&cn);
- }
- else {
- /* Yes, this really should be an XOR. If ctrls->enabled_ctrls_changes*/
- /* is non-zero, the controls in question changed already in "this" */
- /* request and this change merely undoes the previous one. By the */
- /* same token, we have to figure out whether or not ControlsEnabled */
- /* should be set or not in the changes structure */
- changes->ctrls.enabled_ctrls_changes^= (ctrls->enabled_ctrls^old);
- if (changes->ctrls.enabled_ctrls_changes)
- changes->ctrls.changed_ctrls|= XkbControlsEnabledMask;
- else changes->ctrls.changed_ctrls&= ~XkbControlsEnabledMask;
- }
- sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
- XkbUpdateIndicators(xkbi->device,sli->usesControls,TRUE,changes,cause);
- return TRUE;
-}
-
-/***====================================================================***/
-
-#define MAX_TOC 16
-
-XkbGeometryPtr
-XkbLookupNamedGeometry(DeviceIntPtr dev,Atom name,Bool *shouldFree)
-{
-XkbSrvInfoPtr xkbi= dev->key->xkbInfo;
-XkbDescPtr xkb= xkbi->desc;
-
- *shouldFree= 0;
- if (name==None) {
- if (xkb->geom!=NULL)
- return xkb->geom;
- name= xkb->names->geometry;
- }
- if ((xkb->geom!=NULL)&&(xkb->geom->name==name))
- return xkb->geom;
- *shouldFree= 1;
- return NULL;
-}
-
-void
-XkbConvertCase(register KeySym sym, KeySym *lower, KeySym *upper)
-{
- *lower = sym;
- *upper = sym;
- switch(sym >> 8) {
- case 0: /* Latin 1 */
- if ((sym >= XK_A) && (sym <= XK_Z))
- *lower += (XK_a - XK_A);
- else if ((sym >= XK_a) && (sym <= XK_z))
- *upper -= (XK_a - XK_A);
- else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
- *lower += (XK_agrave - XK_Agrave);
- else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
- *upper -= (XK_agrave - XK_Agrave);
- else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
- *lower += (XK_oslash - XK_Ooblique);
- else if ((sym >= XK_oslash) && (sym <= XK_thorn))
- *upper -= (XK_oslash - XK_Ooblique);
- break;
- case 1: /* Latin 2 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym == XK_Aogonek)
- *lower = XK_aogonek;
- else if (sym >= XK_Lstroke && sym <= XK_Sacute)
- *lower += (XK_lstroke - XK_Lstroke);
- else if (sym >= XK_Scaron && sym <= XK_Zacute)
- *lower += (XK_scaron - XK_Scaron);
- else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
- *lower += (XK_zcaron - XK_Zcaron);
- else if (sym == XK_aogonek)
- *upper = XK_Aogonek;
- else if (sym >= XK_lstroke && sym <= XK_sacute)
- *upper -= (XK_lstroke - XK_Lstroke);
- else if (sym >= XK_scaron && sym <= XK_zacute)
- *upper -= (XK_scaron - XK_Scaron);
- else if (sym >= XK_zcaron && sym <= XK_zabovedot)
- *upper -= (XK_zcaron - XK_Zcaron);
- else if (sym >= XK_Racute && sym <= XK_Tcedilla)
- *lower += (XK_racute - XK_Racute);
- else if (sym >= XK_racute && sym <= XK_tcedilla)
- *upper -= (XK_racute - XK_Racute);
- break;
- case 2: /* Latin 3 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
- *lower += (XK_hstroke - XK_Hstroke);
- else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
- *lower += (XK_gbreve - XK_Gbreve);
- else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
- *upper -= (XK_hstroke - XK_Hstroke);
- else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
- *upper -= (XK_gbreve - XK_Gbreve);
- else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
- *lower += (XK_cabovedot - XK_Cabovedot);
- else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
- *upper -= (XK_cabovedot - XK_Cabovedot);
- break;
- case 3: /* Latin 4 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Rcedilla && sym <= XK_Tslash)
- *lower += (XK_rcedilla - XK_Rcedilla);
- else if (sym >= XK_rcedilla && sym <= XK_tslash)
- *upper -= (XK_rcedilla - XK_Rcedilla);
- else if (sym == XK_ENG)
- *lower = XK_eng;
- else if (sym == XK_eng)
- *upper = XK_ENG;
- else if (sym >= XK_Amacron && sym <= XK_Umacron)
- *lower += (XK_amacron - XK_Amacron);
- else if (sym >= XK_amacron && sym <= XK_umacron)
- *upper -= (XK_amacron - XK_Amacron);
- break;
- case 6: /* Cyrillic */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
- *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
- else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
- *upper += (XK_Serbian_DJE - XK_Serbian_dje);
- else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
- *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
- else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
- *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
- break;
- case 7: /* Greek */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
- *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
- else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
- sym != XK_Greek_iotaaccentdieresis &&
- sym != XK_Greek_upsilonaccentdieresis)
- *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
- else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
- *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
- else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
- sym != XK_Greek_finalsmallsigma)
- *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
- break;
- }
-}
-
-static Bool
-_XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
-{
- void *tmp = NULL;
- int i;
- XkbKeyTypePtr stype = NULL, dtype = NULL;
-
- /* client map */
- if (src->map) {
- if (!dst->map) {
- tmp = xcalloc(1, sizeof(XkbClientMapRec));
- if (!tmp)
- return FALSE;
- dst->map = tmp;
- }
-
- if (src->map->syms) {
- if (src->map->size_syms != dst->map->size_syms) {
- if (dst->map->syms)
- tmp = xrealloc(dst->map->syms,
- src->map->size_syms * sizeof(KeySym));
- else
- tmp = xalloc(src->map->size_syms * sizeof(KeySym));
- if (!tmp)
- return FALSE;
- dst->map->syms = tmp;
-
- }
- memcpy(dst->map->syms, src->map->syms,
- src->map->size_syms * sizeof(KeySym));
- }
- else {
- if (dst->map->syms) {
- xfree(dst->map->syms);
- dst->map->syms = NULL;
- }
- }
- dst->map->num_syms = src->map->num_syms;
- dst->map->size_syms = src->map->size_syms;
-
- if (src->map->key_sym_map) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->map->key_sym_map)
- tmp = xrealloc(dst->map->key_sym_map,
- (src->max_key_code + 1) *
- sizeof(XkbSymMapRec));
- else
- tmp = xalloc((src->max_key_code + 1) *
- sizeof(XkbSymMapRec));
- if (!tmp)
- return FALSE;
- dst->map->key_sym_map = tmp;
- }
- memcpy(dst->map->key_sym_map, src->map->key_sym_map,
- (src->max_key_code + 1) * sizeof(XkbSymMapRec));
- }
- else {
- if (dst->map->key_sym_map) {
- xfree(dst->map->key_sym_map);
- dst->map->key_sym_map = NULL;
- }
- }
-
- if (src->map->types && src->map->num_types) {
- if (src->map->num_types > dst->map->size_types ||
- !dst->map->types || !dst->map->size_types) {
- if (dst->map->types && dst->map->size_types) {
- tmp = xrealloc(dst->map->types,
- src->map->num_types * sizeof(XkbKeyTypeRec));
- if (!tmp)
- return FALSE;
- dst->map->types = tmp;
- bzero(dst->map->types + dst->map->num_types,
- (src->map->num_types - dst->map->num_types) *
- sizeof(XkbKeyTypeRec));
- }
- else {
- tmp = xcalloc(src->map->num_types, sizeof(XkbKeyTypeRec));
- if (!tmp)
- return FALSE;
- dst->map->types = tmp;
- }
- }
- else if (src->map->num_types < dst->map->num_types &&
- dst->map->types) {
- for (i = src->map->num_types, dtype = (dst->map->types + i);
- i < dst->map->num_types; i++, dtype++) {
- if (dtype->level_names)
- xfree(dtype->level_names);
- dtype->level_names = NULL;
- dtype->num_levels = 0;
- if (dtype->map_count) {
- if (dtype->map)
- xfree(dtype->map);
- if (dtype->preserve)
- xfree(dtype->preserve);
- }
- }
- }
-
- stype = src->map->types;
- dtype = dst->map->types;
- for (i = 0; i < src->map->num_types; i++, dtype++, stype++) {
- if (stype->num_levels && stype->level_names) {
- if (stype->num_levels != dtype->num_levels &&
- dtype->num_levels && dtype->level_names &&
- i < dst->map->num_types) {
- tmp = xrealloc(dtype->level_names,
- stype->num_levels * sizeof(Atom));
- if (!tmp)
- continue;
- dtype->level_names = tmp;
- }
- else if (!dtype->num_levels || !dtype->level_names ||
- i >= dst->map->num_types) {
- tmp = xalloc(stype->num_levels * sizeof(Atom));
- if (!tmp)
- continue;
- dtype->level_names = tmp;
- }
- dtype->num_levels = stype->num_levels;
- memcpy(dtype->level_names, stype->level_names,
- stype->num_levels * sizeof(Atom));
- }
- else {
- if (dtype->num_levels && dtype->level_names &&
- i < dst->map->num_types)
- xfree(dtype->level_names);
- dtype->num_levels = 0;
- dtype->level_names = NULL;
- }
-
- dtype->name = stype->name;
- memcpy(&dtype->mods, &stype->mods, sizeof(XkbModsRec));
-
- if (stype->map_count) {
- if (stype->map) {
- if (stype->map_count != dtype->map_count &&
- dtype->map_count && dtype->map &&
- i < dst->map->num_types) {
- tmp = xrealloc(dtype->map,
- stype->map_count *
- sizeof(XkbKTMapEntryRec));
- if (!tmp)
- return FALSE;
- dtype->map = tmp;
- }
- else if (!dtype->map_count || !dtype->map ||
- i >= dst->map->num_types) {
- tmp = xalloc(stype->map_count *
- sizeof(XkbKTMapEntryRec));
- if (!tmp)
- return FALSE;
- dtype->map = tmp;
- }
-
- memcpy(dtype->map, stype->map,
- stype->map_count * sizeof(XkbKTMapEntryRec));
- }
- else {
- if (dtype->map && i < dst->map->num_types)
- xfree(dtype->map);
- dtype->map = NULL;
- }
-
- if (stype->preserve) {
- if (stype->map_count != dtype->map_count &&
- dtype->map_count && dtype->preserve &&
- i < dst->map->num_types) {
- tmp = xrealloc(dtype->preserve,
- stype->map_count *
- sizeof(XkbModsRec));
- if (!tmp)
- return FALSE;
- dtype->preserve = tmp;
- }
- else if (!dtype->preserve || !dtype->map_count ||
- i >= dst->map->num_types) {
- tmp = xalloc(stype->map_count *
- sizeof(XkbModsRec));
- if (!tmp)
- return FALSE;
- dtype->preserve = tmp;
- }
-
- memcpy(dtype->preserve, stype->preserve,
- stype->map_count * sizeof(XkbModsRec));
- }
- else {
- if (dtype->preserve && i < dst->map->num_types)
- xfree(dtype->preserve);
- dtype->preserve = NULL;
- }
-
- dtype->map_count = stype->map_count;
- }
- else {
- if (dtype->map_count && i < dst->map->num_types) {
- if (dtype->map)
- xfree(dtype->map);
- if (dtype->preserve)
- xfree(dtype->preserve);
- }
- dtype->map_count = 0;
- dtype->map = NULL;
- dtype->preserve = NULL;
- }
- }
-
- dst->map->size_types = src->map->num_types;
- dst->map->num_types = src->map->num_types;
- }
- else {
- if (dst->map->types) {
- for (i = 0, dtype = dst->map->types; i < dst->map->num_types;
- i++, dtype++) {
- if (dtype->level_names)
- xfree(dtype->level_names);
- if (dtype->map && dtype->map_count)
- xfree(dtype->map);
- if (dtype->preserve && dtype->map_count)
- xfree(dtype->preserve);
- }
- xfree(dst->map->types);
- dst->map->types = NULL;
- }
- dst->map->num_types = 0;
- dst->map->size_types = 0;
- }
-
- if (src->map->modmap) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->map->modmap)
- tmp = xrealloc(dst->map->modmap, src->max_key_code + 1);
- else
- tmp = xalloc(src->max_key_code + 1);
- if (!tmp)
- return FALSE;
- dst->map->modmap = tmp;
- }
- memcpy(dst->map->modmap, src->map->modmap, src->max_key_code + 1);
- }
- else {
- if (dst->map->modmap) {
- xfree(dst->map->modmap);
- dst->map->modmap = NULL;
- }
- }
- }
- else {
- if (dst->map)
- XkbFreeClientMap(dst, XkbAllClientInfoMask, TRUE);
- }
-
- return TRUE;
-}
-
-static Bool
-_XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
-{
- void *tmp = NULL;
-
- /* server map */
- if (src->server) {
- if (!dst->server) {
- tmp = xcalloc(1, sizeof(XkbServerMapRec));
- if (!tmp)
- return FALSE;
- dst->server = tmp;
- }
-
- if (src->server->explicit) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->server->explicit)
- tmp = xrealloc(dst->server->explicit, src->max_key_code + 1);
- else
- tmp = xalloc(src->max_key_code + 1);
- if (!tmp)
- return FALSE;
- dst->server->explicit = tmp;
- }
- memcpy(dst->server->explicit, src->server->explicit,
- src->max_key_code + 1);
- }
- else {
- if (dst->server->explicit) {
- xfree(dst->server->explicit);
- dst->server->explicit = NULL;
- }
- }
-
- if (src->server->acts) {
- if (src->server->size_acts != dst->server->size_acts) {
- if (dst->server->acts)
- tmp = xrealloc(dst->server->acts,
- src->server->size_acts * sizeof(XkbAction));
- else
- tmp = xalloc(src->server->size_acts * sizeof(XkbAction));
- if (!tmp)
- return FALSE;
- dst->server->acts = tmp;
- }
- memcpy(dst->server->acts, src->server->acts,
- src->server->size_acts * sizeof(XkbAction));
- }
- else {
- if (dst->server->acts) {
- xfree(dst->server->acts);
- dst->server->acts = NULL;
- }
- }
- dst->server->size_acts = src->server->size_acts;
- dst->server->num_acts = src->server->num_acts;
-
- if (src->server->key_acts) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->server->key_acts)
- tmp = xrealloc(dst->server->key_acts,
- (src->max_key_code + 1) *
- sizeof(unsigned short));
- else
- tmp = xalloc((src->max_key_code + 1) *
- sizeof(unsigned short));
- if (!tmp)
- return FALSE;
- dst->server->key_acts = tmp;
- }
- memcpy(dst->server->key_acts, src->server->key_acts,
- (src->max_key_code + 1) * sizeof(unsigned short));
- }
- else {
- if (dst->server->key_acts) {
- xfree(dst->server->key_acts);
- dst->server->key_acts = NULL;
- }
- }
-
- if (src->server->behaviors) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->server->behaviors)
- tmp = xrealloc(dst->server->behaviors,
- (src->max_key_code + 1) *
- sizeof(XkbBehavior));
- else
- tmp = xalloc((src->max_key_code + 1) *
- sizeof(XkbBehavior));
- if (!tmp)
- return FALSE;
- dst->server->behaviors = tmp;
- }
- memcpy(dst->server->behaviors, src->server->behaviors,
- (src->max_key_code + 1) * sizeof(XkbBehavior));
- }
- else {
- if (dst->server->behaviors) {
- xfree(dst->server->behaviors);
- dst->server->behaviors = NULL;
- }
- }
-
- memcpy(dst->server->vmods, src->server->vmods, XkbNumVirtualMods);
-
- if (src->server->vmodmap) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->server->vmodmap)
- tmp = xrealloc(dst->server->vmodmap,
- (src->max_key_code + 1) *
- sizeof(unsigned short));
- else
- tmp = xalloc((src->max_key_code + 1) *
- sizeof(unsigned short));
- if (!tmp)
- return FALSE;
- dst->server->vmodmap = tmp;
- }
- memcpy(dst->server->vmodmap, src->server->vmodmap,
- (src->max_key_code + 1) * sizeof(unsigned short));
- }
- else {
- if (dst->server->vmodmap) {
- xfree(dst->server->vmodmap);
- dst->server->vmodmap = NULL;
- }
- }
- }
- else {
- if (dst->server)
- XkbFreeServerMap(dst, XkbAllServerInfoMask, TRUE);
- }
-
- return TRUE;
-}
-
-static Bool
-_XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
-{
- void *tmp = NULL;
-
- /* names */
- if (src->names) {
- if (!dst->names) {
- dst->names = xcalloc(1, sizeof(XkbNamesRec));
- if (!dst->names)
- return FALSE;
- }
-
- if (src->names->keys) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->names->keys)
- tmp = xrealloc(dst->names->keys, (src->max_key_code + 1) *
- sizeof(XkbKeyNameRec));
- else
- tmp = xalloc((src->max_key_code + 1) *
- sizeof(XkbKeyNameRec));
- if (!tmp)
- return FALSE;
- dst->names->keys = tmp;
- }
- memcpy(dst->names->keys, src->names->keys,
- (src->max_key_code + 1) * sizeof(XkbKeyNameRec));
- }
- else {
- if (dst->names->keys) {
- xfree(dst->names->keys);
- dst->names->keys = NULL;
- }
- }
-
- if (src->names->num_key_aliases) {
- if (src->names->num_key_aliases != dst->names->num_key_aliases) {
- if (dst->names->key_aliases)
- tmp = xrealloc(dst->names->key_aliases,
- src->names->num_key_aliases *
- sizeof(XkbKeyAliasRec));
- else
- tmp = xalloc(src->names->num_key_aliases *
- sizeof(XkbKeyAliasRec));
- if (!tmp)
- return FALSE;
- dst->names->key_aliases = tmp;
- }
- memcpy(dst->names->key_aliases, src->names->key_aliases,
- src->names->num_key_aliases * sizeof(XkbKeyAliasRec));
- }
- else {
- if (dst->names->key_aliases) {
- xfree(dst->names->key_aliases);
- dst->names->key_aliases = NULL;
- }
- }
- dst->names->num_key_aliases = src->names->num_key_aliases;
-
- if (src->names->num_rg) {
- if (src->names->num_rg != dst->names->num_rg) {
- if (dst->names->radio_groups)
- tmp = xrealloc(dst->names->radio_groups,
- src->names->num_rg * sizeof(Atom));
- else
- tmp = xalloc(src->names->num_rg * sizeof(Atom));
- if (!tmp)
- return FALSE;
- dst->names->radio_groups = tmp;
- }
- memcpy(dst->names->radio_groups, src->names->radio_groups,
- src->names->num_rg * sizeof(Atom));
- }
- else {
- if (dst->names->radio_groups)
- xfree(dst->names->radio_groups);
- }
- dst->names->num_rg = src->names->num_rg;
-
- dst->names->keycodes = src->names->keycodes;
- dst->names->geometry = src->names->geometry;
- dst->names->symbols = src->names->symbols;
- dst->names->types = src->names->types;
- dst->names->compat = src->names->compat;
- dst->names->phys_symbols = src->names->phys_symbols;
-
- memcpy(dst->names->vmods, src->names->vmods,
- XkbNumVirtualMods * sizeof(Atom));
- memcpy(dst->names->indicators, src->names->indicators,
- XkbNumIndicators * sizeof(Atom));
- memcpy(dst->names->groups, src->names->groups,
- XkbNumKbdGroups * sizeof(Atom));
- }
- else {
- if (dst->names)
- XkbFreeNames(dst, XkbAllNamesMask, TRUE);
- }
-
- return TRUE;
-}
-
-static Bool
-_XkbCopyCompat(XkbDescPtr src, XkbDescPtr dst)
-{
- void *tmp = NULL;
-
- /* compat */
- if (src->compat) {
- if (!dst->compat) {
- dst->compat = xcalloc(1, sizeof(XkbCompatMapRec));
- if (!dst->compat)
- return FALSE;
- }
-
- if (src->compat->sym_interpret && src->compat->num_si) {
- if (src->compat->num_si != dst->compat->size_si) {
- if (dst->compat->sym_interpret)
- tmp = xrealloc(dst->compat->sym_interpret,
- src->compat->num_si *
- sizeof(XkbSymInterpretRec));
- else
- tmp = xalloc(src->compat->num_si *
- sizeof(XkbSymInterpretRec));
- if (!tmp)
- return FALSE;
- dst->compat->sym_interpret = tmp;
- }
- memcpy(dst->compat->sym_interpret, src->compat->sym_interpret,
- src->compat->num_si * sizeof(XkbSymInterpretRec));
-
- dst->compat->num_si = src->compat->num_si;
- dst->compat->size_si = src->compat->num_si;
- }
- else {
- if (dst->compat->sym_interpret && dst->compat->size_si)
- xfree(dst->compat->sym_interpret);
-
- dst->compat->sym_interpret = NULL;
- dst->compat->num_si = 0;
- dst->compat->size_si = 0;
- }
-
- memcpy(dst->compat->groups, src->compat->groups,
- XkbNumKbdGroups * sizeof(XkbModsRec));
- }
- else {
- if (dst->compat)
- XkbFreeCompatMap(dst, XkbAllCompatMask, TRUE);
- }
-
- return TRUE;
-}
-
-static Bool
-_XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
-{
- void *tmp = NULL;
- int i = 0, j = 0, k = 0;
- XkbColorPtr scolor = NULL, dcolor = NULL;
- XkbDoodadPtr sdoodad = NULL, ddoodad = NULL;
- XkbOutlinePtr soutline = NULL, doutline = NULL;
- XkbPropertyPtr sprop = NULL, dprop = NULL;
- XkbRowPtr srow = NULL, drow = NULL;
- XkbSectionPtr ssection = NULL, dsection = NULL;
- XkbShapePtr sshape = NULL, dshape = NULL;
-
- /* geometry */
- if (src->geom) {
- if (!dst->geom) {
- dst->geom = xcalloc(sizeof(XkbGeometryRec), 1);
- if (!dst->geom)
- return FALSE;
- }
-
- /* properties */
- if (src->geom->num_properties) {
- if (src->geom->num_properties != dst->geom->sz_properties) {
- /* If we've got more properties in the destination than
- * the source, run through and free all the excess ones
- * first. */
- if (src->geom->num_properties < dst->geom->sz_properties) {
- for (i = src->geom->num_properties,
- dprop = dst->geom->properties + i;
- i < dst->geom->num_properties;
- i++, dprop++) {
- xfree(dprop->name);
- xfree(dprop->value);
- }
- }
-
- if (dst->geom->sz_properties)
- tmp = xrealloc(dst->geom->properties,
- src->geom->num_properties *
- sizeof(XkbPropertyRec));
- else
- tmp = xalloc(src->geom->num_properties *
- sizeof(XkbPropertyRec));
- if (!tmp)
- return FALSE;
- dst->geom->properties = tmp;
- }
-
- /* We don't set num_properties as we need it to try and avoid
- * too much reallocing. */
- dst->geom->sz_properties = src->geom->num_properties;
-
- if (dst->geom->sz_properties > dst->geom->num_properties) {
- bzero(dst->geom->properties + dst->geom->num_properties,
- (dst->geom->sz_properties - dst->geom->num_properties) *
- sizeof(XkbPropertyRec));
- }
-
- for (i = 0,
- sprop = src->geom->properties,
- dprop = dst->geom->properties;
- i < src->geom->num_properties;
- i++, sprop++, dprop++) {
- if (i < dst->geom->num_properties) {
- if (strlen(sprop->name) != strlen(dprop->name)) {
- tmp = xrealloc(dprop->name, strlen(sprop->name) + 1);
- if (!tmp)
- return FALSE;
- dprop->name = tmp;
- }
- if (strlen(sprop->value) != strlen(dprop->value)) {
- tmp = xrealloc(dprop->value, strlen(sprop->value) + 1);
- if (!tmp)
- return FALSE;
- dprop->value = tmp;
- }
- strcpy(dprop->name, sprop->name);
- strcpy(dprop->value, sprop->value);
- }
- else {
- dprop->name = xstrdup(sprop->name);
- dprop->value = xstrdup(sprop->value);
- }
- }
-
- /* ... which is already src->geom->num_properties. */
- dst->geom->num_properties = dst->geom->sz_properties;
- }
- else {
- if (dst->geom->sz_properties) {
- for (i = 0, dprop = dst->geom->properties;
- i < dst->geom->num_properties;
- i++, dprop++) {
- xfree(dprop->name);
- xfree(dprop->value);
- }
- xfree(dst->geom->properties);
- dst->geom->properties = NULL;
- }
-
- dst->geom->num_properties = 0;
- dst->geom->sz_properties = 0;
- }
-
- /* colors */
- if (src->geom->num_colors) {
- if (src->geom->num_colors != dst->geom->sz_colors) {
- if (src->geom->num_colors < dst->geom->sz_colors) {
- for (i = src->geom->num_colors,
- dcolor = dst->geom->colors + i;
- i < dst->geom->num_colors;
- i++, dcolor++) {
- xfree(dcolor->spec);
- }
- }
-
- if (dst->geom->sz_colors)
- tmp = xrealloc(dst->geom->colors,
- src->geom->num_colors *
- sizeof(XkbColorRec));
- else
- tmp = xalloc(src->geom->num_colors *
- sizeof(XkbColorRec));
- if (!tmp)
- return FALSE;
- dst->geom->colors = tmp;
- }
-
- dst->geom->sz_colors = src->geom->num_colors;
-
- if (dst->geom->sz_colors > dst->geom->num_colors) {
- bzero(dst->geom->colors + dst->geom->num_colors,
- (dst->geom->sz_colors - dst->geom->num_colors) *
- sizeof(XkbColorRec));
- }
-
- for (i = 0,
- scolor = src->geom->colors,
- dcolor = dst->geom->colors;
- i < src->geom->num_colors;
- i++, scolor++, dcolor++) {
- if (i < dst->geom->num_colors) {
- if (strlen(scolor->spec) != strlen(dcolor->spec)) {
- tmp = xrealloc(dcolor->spec, strlen(scolor->spec) + 1);
- if (!tmp)
- return FALSE;
- dcolor->spec = tmp;
- }
- strcpy(dcolor->spec, scolor->spec);
- }
- else {
- dcolor->spec = xstrdup(scolor->spec);
- }
- dcolor->pixel = scolor->pixel;
- }
-
- dst->geom->num_colors = dst->geom->sz_colors;
- }
- else {
- if (dst->geom->sz_colors) {
- for (i = 0, dcolor = dst->geom->colors;
- i < dst->geom->num_colors;
- i++, dcolor++) {
- xfree(dcolor->spec);
- }
- xfree(dst->geom->colors);
- dst->geom->colors = NULL;
- }
-
- dst->geom->num_colors = 0;
- dst->geom->sz_colors = 0;
- }
-
- /* shapes */
- /* shapes break down into outlines, which break down into points. */
- if (dst->geom->num_shapes) {
- for (i = 0, dshape = dst->geom->shapes;
- i < dst->geom->num_shapes;
- i++, dshape++) {
- for (j = 0, doutline = dshape->outlines;
- j < dshape->num_outlines;
- j++, doutline++) {
- if (doutline->sz_points)
- xfree(doutline->points);
- }
-
- if (dshape->sz_outlines) {
- xfree(dshape->outlines);
- dshape->outlines = NULL;
- }
-
- dshape->num_outlines = 0;
- dshape->sz_outlines = 0;
- }
- }
-
- if (src->geom->num_shapes) {
- tmp = xcalloc(src->geom->num_shapes, sizeof(XkbShapeRec));
- if (!tmp)
- return FALSE;
- dst->geom->shapes = tmp;
-
- for (i = 0, sshape = src->geom->shapes, dshape = dst->geom->shapes;
- i < src->geom->num_shapes;
- i++, sshape++, dshape++) {
- if (sshape->num_outlines) {
- tmp = xcalloc(sshape->num_outlines, sizeof(XkbOutlineRec));
- if (!tmp)
- return FALSE;
- dshape->outlines = tmp;
-
- for (j = 0,
- soutline = sshape->outlines,
- doutline = dshape->outlines;
- j < sshape->num_outlines;
- j++, soutline++, doutline++) {
- if (soutline->num_points) {
- tmp = xalloc(soutline->num_points *
- sizeof(XkbPointRec));
- if (!tmp)
- return FALSE;
- doutline->points = tmp;
-
- memcpy(doutline->points, soutline->points,
- soutline->num_points * sizeof(XkbPointRec));
-
- doutline->corner_radius = soutline->corner_radius;
- }
-
- doutline->num_points = soutline->num_points;
- doutline->sz_points = soutline->num_points;
- }
- }
-
- dshape->num_outlines = sshape->num_outlines;
- dshape->sz_outlines = sshape->num_outlines;
- dshape->name = sshape->name;
- dshape->bounds = sshape->bounds;
-
- dshape->approx = NULL;
- if (sshape->approx && sshape->num_outlines > 0) {
-
- const ptrdiff_t approx_idx =
- sshape->approx - sshape->outlines;
-
- if (approx_idx < dshape->num_outlines) {
- dshape->approx = dshape->outlines + approx_idx;
- } else {
- LogMessage(X_WARNING, "XKB: approx outline "
- "index is out of range\n");
- }
- }
-
- dshape->primary = NULL;
- if (sshape->primary && sshape->num_outlines > 0) {
-
- const ptrdiff_t primary_idx =
- sshape->primary - sshape->outlines;
-
- if (primary_idx < dshape->num_outlines) {
- dshape->primary = dshape->outlines + primary_idx;
- } else {
- LogMessage(X_WARNING, "XKB: primary outline "
- "index is out of range\n");
- }
- }
- }
-
- dst->geom->num_shapes = src->geom->num_shapes;
- dst->geom->sz_shapes = src->geom->num_shapes;
- }
- else {
- if (dst->geom->sz_shapes) {
- xfree(dst->geom->shapes);
- }
- dst->geom->shapes = NULL;
- dst->geom->num_shapes = 0;
- dst->geom->sz_shapes = 0;
- }
-
- /* sections */
- /* sections break down into doodads, and also into rows, which break
- * down into keys. */
- if (dst->geom->num_sections) {
- for (i = 0, dsection = dst->geom->sections;
- i < dst->geom->num_sections;
- i++, dsection++) {
- for (j = 0, drow = dsection->rows;
- j < dsection->num_rows;
- j++, drow++) {
- if (drow->num_keys)
- xfree(drow->keys);
- }
-
- if (dsection->num_rows)
- xfree(dsection->rows);
-
- /* cut and waste from geom/doodad below. */
- for (j = 0, ddoodad = dsection->doodads;
- j < dsection->num_doodads;
- j++, ddoodad++) {
- if (ddoodad->any.type == XkbTextDoodad) {
- if (ddoodad->text.text) {
- xfree(ddoodad->text.text);
- ddoodad->text.text = NULL;
- }
- if (ddoodad->text.font) {
- xfree(ddoodad->text.font);
- ddoodad->text.font = NULL;
- }
- }
- else if (ddoodad->any.type == XkbLogoDoodad) {
- if (ddoodad->logo.logo_name) {
- xfree(ddoodad->logo.logo_name);
- ddoodad->logo.logo_name = NULL;
- }
- }
- }
-
- if (dsection->num_doodads)
- xfree(dsection->doodads);
- }
-
- dst->geom->num_sections = 0;
- dst->geom->sections = NULL;
- }
-
- if (src->geom->num_sections) {
- if (dst->geom->sz_sections)
- tmp = xrealloc(dst->geom->sections,
- src->geom->num_sections *
- sizeof(XkbSectionRec));
- else
- tmp = xalloc(src->geom->num_sections * sizeof(XkbSectionRec));
- if (!tmp)
- return FALSE;
- memset(tmp, 0, src->geom->num_sections * sizeof(XkbSectionRec));
- dst->geom->sections = tmp;
- dst->geom->num_sections = src->geom->num_sections;
- dst->geom->sz_sections = src->geom->num_sections;
-
- for (i = 0,
- ssection = src->geom->sections,
- dsection = dst->geom->sections;
- i < src->geom->num_sections;
- i++, ssection++, dsection++) {
- *dsection = *ssection;
- if (ssection->num_rows) {
- tmp = xcalloc(ssection->num_rows, sizeof(XkbRowRec));
- if (!tmp)
- return FALSE;
- dsection->rows = tmp;
- }
- dsection->num_rows = ssection->num_rows;
- dsection->sz_rows = ssection->num_rows;
-
- for (j = 0, srow = ssection->rows, drow = dsection->rows;
- j < ssection->num_rows;
- j++, srow++, drow++) {
- if (srow->num_keys) {
- tmp = xalloc(srow->num_keys * sizeof(XkbKeyRec));
- if (!tmp)
- return FALSE;
- drow->keys = tmp;
- memcpy(drow->keys, srow->keys,
- srow->num_keys * sizeof(XkbKeyRec));
- }
- drow->num_keys = srow->num_keys;
- drow->sz_keys = srow->num_keys;
- drow->top = srow->top;
- drow->left = srow->left;
- drow->vertical = srow->vertical;
- drow->bounds = srow->bounds;
- }
-
- if (ssection->num_doodads) {
- tmp = xcalloc(ssection->num_doodads, sizeof(XkbDoodadRec));
- if (!tmp)
- return FALSE;
- dsection->doodads = tmp;
- }
- else {
- dsection->doodads = NULL;
- }
-
- dsection->sz_doodads = ssection->num_doodads;
- for (k = 0,
- sdoodad = ssection->doodads,
- ddoodad = dsection->doodads;
- k < ssection->num_doodads;
- k++, sdoodad++, ddoodad++) {
- memcpy(ddoodad , sdoodad, sizeof(XkbDoodadRec));
- if (sdoodad->any.type == XkbTextDoodad) {
- if (sdoodad->text.text)
- ddoodad->text.text =
- xstrdup(sdoodad->text.text);
- if (sdoodad->text.font)
- ddoodad->text.font =
- xstrdup(sdoodad->text.font);
- }
- else if (sdoodad->any.type == XkbLogoDoodad) {
- if (sdoodad->logo.logo_name)
- ddoodad->logo.logo_name =
- xstrdup(sdoodad->logo.logo_name);
- }
- }
- dsection->overlays = NULL;
- dsection->sz_overlays = 0;
- dsection->num_overlays = 0;
- }
- }
- else {
- if (dst->geom->sz_sections) {
- xfree(dst->geom->sections);
- }
-
- dst->geom->sections = NULL;
- dst->geom->num_sections = 0;
- dst->geom->sz_sections = 0;
- }
-
- /* doodads */
- if (dst->geom->num_doodads) {
- for (i = src->geom->num_doodads,
- ddoodad = dst->geom->doodads +
- src->geom->num_doodads;
- i < dst->geom->num_doodads;
- i++, ddoodad++) {
- if (ddoodad->any.type == XkbTextDoodad) {
- if (ddoodad->text.text) {
- xfree(ddoodad->text.text);
- ddoodad->text.text = NULL;
- }
- if (ddoodad->text.font) {
- xfree(ddoodad->text.font);
- ddoodad->text.font = NULL;
- }
- }
- else if (ddoodad->any.type == XkbLogoDoodad) {
- if (ddoodad->logo.logo_name) {
- xfree(ddoodad->logo.logo_name);
- ddoodad->logo.logo_name = NULL;
- }
- }
- }
- dst->geom->num_doodads = 0;
- dst->geom->doodads = NULL;
- }
-
- if (src->geom->num_doodads) {
- if (dst->geom->sz_doodads)
- tmp = xrealloc(dst->geom->doodads,
- src->geom->num_doodads *
- sizeof(XkbDoodadRec));
- else
- tmp = xalloc(src->geom->num_doodads *
- sizeof(XkbDoodadRec));
- if (!tmp)
- return FALSE;
- memset(tmp, 0, src->geom->num_doodads * sizeof(XkbDoodadRec));
- dst->geom->doodads = tmp;
-
- dst->geom->sz_doodads = src->geom->num_doodads;
-
- for (i = 0,
- sdoodad = src->geom->doodads,
- ddoodad = dst->geom->doodads;
- i < src->geom->num_doodads;
- i++, sdoodad++, ddoodad++) {
- memcpy(ddoodad , sdoodad, sizeof(XkbDoodadRec));
- if (sdoodad->any.type == XkbTextDoodad) {
- if (sdoodad->text.text)
- ddoodad->text.text = xstrdup(sdoodad->text.text);
- if (sdoodad->text.font)
- ddoodad->text.font = xstrdup(sdoodad->text.font);
- }
- else if (sdoodad->any.type == XkbLogoDoodad) {
- if (sdoodad->logo.logo_name)
- ddoodad->logo.logo_name =
- xstrdup(sdoodad->logo.logo_name);
- }
- }
-
- dst->geom->num_doodads = dst->geom->sz_doodads;
- }
- else {
- if (dst->geom->sz_doodads) {
- xfree(dst->geom->doodads);
- }
-
- dst->geom->doodads = NULL;
- dst->geom->num_doodads = 0;
- dst->geom->sz_doodads = 0;
- }
-
- /* key aliases */
- if (src->geom->num_key_aliases) {
- if (src->geom->num_key_aliases != dst->geom->sz_key_aliases) {
- if (dst->geom->sz_key_aliases)
- tmp = xrealloc(dst->geom->key_aliases,
- src->geom->num_key_aliases *
- 2 * XkbKeyNameLength);
- else
- tmp = xalloc(src->geom->num_key_aliases *
- 2 * XkbKeyNameLength);
- if (!tmp)
- return FALSE;
- dst->geom->key_aliases = tmp;
-
- dst->geom->sz_key_aliases = src->geom->num_key_aliases;
- }
-
- memcpy(dst->geom->key_aliases, src->geom->key_aliases,
- src->geom->num_key_aliases * 2 * XkbKeyNameLength);
-
- dst->geom->num_key_aliases = dst->geom->sz_key_aliases;
- }
- else {
- if (dst->geom->key_aliases) {
- xfree(dst->geom->key_aliases);
- }
- dst->geom->key_aliases = NULL;
- dst->geom->num_key_aliases = 0;
- dst->geom->sz_key_aliases = 0;
- }
-
- /* font */
- if (src->geom->label_font) {
- if (!dst->geom->label_font) {
- tmp = xalloc(strlen(src->geom->label_font));
- if (!tmp)
- return FALSE;
- dst->geom->label_font = tmp;
- }
- else if (strlen(src->geom->label_font) !=
- strlen(dst->geom->label_font)) {
- tmp = xrealloc(dst->geom->label_font,
- strlen(src->geom->label_font));
- if (!tmp)
- return FALSE;
- dst->geom->label_font = tmp;
- }
-
- strcpy(dst->geom->label_font, src->geom->label_font);
- i = XkbGeomColorIndex(src->geom, src->geom->label_color);
- dst->geom->label_color = &(dst->geom->colors[i]);
- i = XkbGeomColorIndex(src->geom, src->geom->base_color);
- dst->geom->base_color = &(dst->geom->colors[i]);
- }
- else {
- if (dst->geom->label_font) {
- xfree(dst->geom->label_font);
- }
- dst->geom->label_font = NULL;
- dst->geom->label_color = NULL;
- dst->geom->base_color = NULL;
- }
-
- dst->geom->name = src->geom->name;
- dst->geom->width_mm = src->geom->width_mm;
- dst->geom->height_mm = src->geom->height_mm;
- }
- else
- {
- if (dst->geom) {
- /* I LOVE THE DIFFERENT CALL SIGNATURE. REALLY, I DO. */
- XkbFreeGeometry(dst->geom, XkbGeomAllMask, TRUE);
- dst->geom = NULL;
- }
- }
-
- return TRUE;
-}
-
-static Bool
-_XkbCopyIndicators(XkbDescPtr src, XkbDescPtr dst)
-{
- /* indicators */
- if (src->indicators) {
- if (!dst->indicators) {
- dst->indicators = xalloc(sizeof(XkbIndicatorRec));
- if (!dst->indicators)
- return FALSE;
- }
- memcpy(dst->indicators, src->indicators, sizeof(XkbIndicatorRec));
- }
- else {
- if (dst->indicators) {
- xfree(dst->indicators);
- dst->indicators = NULL;
- }
- }
- return TRUE;
-}
-
-static Bool
-_XkbCopyControls(XkbDescPtr src, XkbDescPtr dst)
-{
- /* controls */
- if (src->ctrls) {
- if (!dst->ctrls) {
- dst->ctrls = xalloc(sizeof(XkbControlsRec));
- if (!dst->ctrls)
- return FALSE;
- }
- memcpy(dst->ctrls, src->ctrls, sizeof(XkbControlsRec));
- }
- else {
- if (dst->ctrls) {
- xfree(dst->ctrls);
- dst->ctrls = NULL;
- }
- }
- return TRUE;
-}
-
-/**
- * Copy an XKB map from src to dst, reallocating when necessary: if some
- * map components are present in one, but not in the other, the destination
- * components will be allocated or freed as necessary.
- *
- * Basic map consistency is assumed on both sides, so maps with random
- * uninitialised data (e.g. names->radio_grous == NULL, names->num_rg == 19)
- * _will_ cause failures. You've been warned.
- *
- * Returns TRUE on success, or FALSE on failure. If this function fails,
- * dst may be in an inconsistent state: all its pointers are guaranteed
- * to remain valid, but part of the map may be from src and part from dst.
- *
- */
-
-Bool
-XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
-{
-
- if (!src || !dst) {
- DebugF("XkbCopyKeymap: src (%p) or dst (%p) is NULL\n", src, dst);
- return FALSE;
- }
-
- if (src == dst)
- return TRUE;
-
- if (!_XkbCopyClientMap(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy client map\n");
- return FALSE;
- }
- if (!_XkbCopyServerMap(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy server map\n");
- return FALSE;
- }
- if (!_XkbCopyIndicators(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy indicators\n");
- return FALSE;
- }
- if (!_XkbCopyControls(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy controls\n");
- return FALSE;
- }
- if (!_XkbCopyNames(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy names\n");
- return FALSE;
- }
- if (!_XkbCopyCompat(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy compat map\n");
- return FALSE;
- }
- if (!_XkbCopyGeom(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy geometry\n");
- return FALSE;
- }
-
- dst->min_key_code = src->min_key_code;
- dst->max_key_code = src->max_key_code;
-
- return TRUE;
-}
-
-Bool
-XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
-{
- xkbNewKeyboardNotify nkn;
- Bool ret;
-
- if (!dst->key || !src->key)
- return FALSE;
-
- memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
- nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
- nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
- nkn.deviceID = dst->id;
- nkn.oldDeviceID = dst->id; /* maybe src->id? */
- nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
- nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
- nkn.requestMajor = XkbReqCode;
- nkn.requestMinor = X_kbSetMap; /* Near enough's good enough. */
- nkn.changed = XkbNKN_KeycodesMask;
- if (src->key->xkbInfo->desc->geom)
- nkn.changed |= XkbNKN_GeometryMask;
-
- ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
- if (ret)
- XkbSendNewKeyboardNotify(dst, &nkn);
-
- return ret;
-}
-
-int
-XkbGetEffectiveGroup(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 keycode)
-{
- XkbDescPtr xkb = xkbi->desc;
- int effectiveGroup = xkbState->group;
-
- if (!XkbKeycodeInRange(xkb, keycode))
- return -1;
-
- if (effectiveGroup == XkbGroup1Index)
- return effectiveGroup;
-
- if (XkbKeyNumGroups(xkb,keycode) > 1U) {
- if (effectiveGroup >= XkbKeyNumGroups(xkb,keycode)) {
- unsigned int gi = XkbKeyGroupInfo(xkb,keycode);
- switch (XkbOutOfRangeGroupAction(gi)) {
- default:
- case XkbWrapIntoRange:
- effectiveGroup %= XkbKeyNumGroups(xkb, keycode);
- break;
- case XkbClampIntoRange:
- effectiveGroup = XkbKeyNumGroups(xkb, keycode) - 1;
- break;
- case XkbRedirectIntoRange:
- effectiveGroup = XkbOutOfRangeGroupInfo(gi);
- if (effectiveGroup >= XkbKeyNumGroups(xkb, keycode))
- effectiveGroup = 0;
- break;
- }
- }
- }
- else effectiveGroup = XkbGroup1Index;
-
- return effectiveGroup;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+/*
+
+Copyright © 2008 Red Hat Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "os.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#define XK_CYRILLIC
+#include <X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "eventstr.h"
+
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+#include "xkb.h"
+
+/***====================================================================***/
+
+int
+_XkbLookupAnyDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
+ Mask access_mode, int *xkb_err)
+{
+ int rc = XkbKeyboardErrorCode;
+
+ if (id == XkbUseCoreKbd)
+ id = PickKeyboard(client)->id;
+ else if (id == XkbUseCorePtr)
+ id = PickPointer(client)->id;
+
+ rc = dixLookupDevice(pDev, id, client, access_mode);
+ if (rc != Success)
+ *xkb_err = XkbErr_BadDevice;
+
+ return rc;
+}
+
+int
+_XkbLookupKeyboard(DeviceIntPtr *pDev, int id, ClientPtr client,
+ Mask access_mode, int *xkb_err)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ if (id == XkbDfltXIId)
+ id = XkbUseCoreKbd;
+
+ rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
+ if (rc != Success)
+ return rc;
+
+ dev = *pDev;
+ if (!dev->key || !dev->key->xkbInfo) {
+ *pDev = NULL;
+ *xkb_err= XkbErr_BadClass;
+ return XkbKeyboardErrorCode;
+ }
+ return Success;
+}
+
+int
+_XkbLookupBellDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
+ Mask access_mode, int *xkb_err)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
+ if (rc != Success)
+ return rc;
+
+ dev = *pDev;
+ if (!dev->kbdfeed && !dev->bell) {
+ *pDev = NULL;
+ *xkb_err= XkbErr_BadClass;
+ return XkbKeyboardErrorCode;
+ }
+ return Success;
+}
+
+int
+_XkbLookupLedDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
+ Mask access_mode, int *xkb_err)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ if (id == XkbDfltXIId)
+ id = XkbUseCorePtr;
+
+ rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
+ if (rc != Success)
+ return rc;
+
+ dev = *pDev;
+ if (!dev->kbdfeed && !dev->leds) {
+ *pDev = NULL;
+ *xkb_err= XkbErr_BadClass;
+ return XkbKeyboardErrorCode;
+ }
+ return Success;
+}
+
+int
+_XkbLookupButtonDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
+ Mask access_mode, int *xkb_err)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
+ if (rc != Success)
+ return rc;
+
+ dev = *pDev;
+ if (!dev->button) {
+ *pDev = NULL;
+ *xkb_err= XkbErr_BadClass;
+ return XkbKeyboardErrorCode;
+ }
+ return Success;
+}
+
+void
+XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
+{
+register unsigned tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (act->mods.flags&XkbSA_UseModMapMods)
+ act->mods.real_mods= act->mods.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->mods))!=0)
+ act->mods.mask|= XkbMaskForVMask(xkb,tmp);
+ break;
+ case XkbSA_ISOLock:
+ if (act->iso.flags&XkbSA_UseModMapMods)
+ act->iso.real_mods= act->iso.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->iso))!=0)
+ act->iso.mask|= XkbMaskForVMask(xkb,tmp);
+ break;
+ }
+ return;
+}
+
+unsigned
+XkbMaskForVMask(XkbDescPtr xkb,unsigned vmask)
+{
+register int i,bit;
+register unsigned mask;
+
+ for (mask=i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (vmask&bit)
+ mask|= xkb->server->vmods[i];
+ }
+ return mask;
+}
+
+/***====================================================================***/
+
+void
+XkbUpdateKeyTypesFromCore( DeviceIntPtr pXDev,
+ KeySymsPtr pCore,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes)
+{
+XkbDescPtr xkb;
+unsigned key,nG,explicit;
+int types[XkbNumKbdGroups];
+KeySym tsyms[XkbMaxSymsPerKey],*syms;
+XkbMapChangesPtr mc;
+
+ xkb= pXDev->key->xkbInfo->desc;
+ if (first+num-1>xkb->max_key_code) {
+ /* 1/12/95 (ef) -- XXX! should allow XKB structures to grow */
+ num= xkb->max_key_code-first+1;
+ }
+
+ mc= (changes?(&changes->map):NULL);
+
+ syms= &pCore->map[(first - pCore->minKeyCode) * pCore->mapWidth];
+ for (key=first; key<(first+num); key++,syms+= pCore->mapWidth) {
+ explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
+ types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
+ types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
+ types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
+ types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
+ nG= XkbKeyTypesForCoreSymbols(xkb,pCore->mapWidth,syms,explicit,types,
+ tsyms);
+ XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
+ memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
+ XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
+ }
+ if (changes->map.changed&XkbKeySymsMask) {
+ CARD8 oldLast,newLast;
+ oldLast = changes->map.first_key_sym+changes->map.num_key_syms-1;
+ newLast = first+num-1;
+
+ if (first<changes->map.first_key_sym)
+ changes->map.first_key_sym = first;
+ if (oldLast>newLast)
+ newLast= oldLast;
+ changes->map.num_key_syms = newLast-changes->map.first_key_sym+1;
+ }
+ else {
+ changes->map.changed|= XkbKeySymsMask;
+ changes->map.first_key_sym = first;
+ changes->map.num_key_syms = num;
+ }
+ return;
+}
+
+void
+XkbUpdateDescActions( XkbDescPtr xkb,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes)
+{
+register unsigned key;
+
+ for (key=first;key<(first+num);key++) {
+ XkbApplyCompatMapToKey(xkb,key,changes);
+ }
+
+ if (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask)) {
+ unsigned char newVMods[XkbNumVirtualMods];
+ register unsigned bit,i;
+ unsigned present;
+
+ bzero(newVMods,XkbNumVirtualMods);
+ present= 0;
+ for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
+ if (xkb->server->vmodmap[key]==0)
+ continue;
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (bit&xkb->server->vmodmap[key]) {
+ present|= bit;
+ newVMods[i]|= xkb->map->modmap[key];
+ }
+ }
+ }
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
+ changes->map.changed|= XkbVirtualModsMask;
+ changes->map.vmods|= bit;
+ xkb->server->vmods[i]= newVMods[i];
+ }
+ }
+ }
+ if (changes->map.changed&XkbVirtualModsMask)
+ XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
+
+ if (changes->map.changed&XkbKeyActionsMask) {
+ CARD8 oldLast,newLast;
+ oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
+ newLast = first+num-1;
+
+ if (first<changes->map.first_key_act)
+ changes->map.first_key_act = first;
+ if (newLast>oldLast)
+ newLast= oldLast;
+ changes->map.num_key_acts= newLast-changes->map.first_key_act+1;
+ }
+ else {
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act = first;
+ changes->map.num_key_acts = num;
+ }
+ return;
+}
+
+void
+XkbUpdateActions( DeviceIntPtr pXDev,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes,
+ unsigned * needChecksRtrn,
+ XkbEventCausePtr cause)
+{
+XkbSrvInfoPtr xkbi;
+XkbDescPtr xkb;
+CARD8 * repeat;
+
+ if (needChecksRtrn)
+ *needChecksRtrn= 0;
+ xkbi= pXDev->key->xkbInfo;
+ xkb= xkbi->desc;
+ repeat= xkb->ctrls->per_key_repeat;
+
+ if (pXDev->kbdfeed)
+ memcpy(repeat,pXDev->kbdfeed->ctrl.autoRepeats,XkbPerKeyBitArraySize);
+
+ XkbUpdateDescActions(xkb,first,num,changes);
+
+ if ((pXDev->kbdfeed)&&
+ (changes->ctrls.enabled_ctrls_changes&XkbPerKeyRepeatMask)) {
+ memcpy(pXDev->kbdfeed->ctrl.autoRepeats,repeat, XkbPerKeyBitArraySize);
+ (*pXDev->kbdfeed->CtrlProc)(pXDev, &pXDev->kbdfeed->ctrl);
+ }
+ return;
+}
+
+KeySymsPtr
+XkbGetCoreMap(DeviceIntPtr keybd)
+{
+register int key,tmp;
+int maxSymsPerKey, maxGroup1Width;
+XkbDescPtr xkb;
+KeySymsPtr syms;
+int maxNumberOfGroups;
+
+ if (!keybd || !keybd->key || !keybd->key->xkbInfo)
+ return NULL;
+
+ xkb= keybd->key->xkbInfo->desc;
+ maxSymsPerKey= maxGroup1Width= 0;
+ maxNumberOfGroups = 0;
+
+ /* determine sizes */
+ for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
+ if (XkbKeycodeInRange(xkb,key)) {
+ int nGroups;
+ int w;
+ nGroups= XkbKeyNumGroups(xkb,key);
+ tmp= 0;
+ if (nGroups>0) {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup1Index))<=2)
+ tmp+= 2;
+ else tmp+= w + 2;
+ /* remember highest G1 width */
+ if (w > maxGroup1Width)
+ maxGroup1Width = w;
+ }
+ if (nGroups>1) {
+ if (tmp <= 2) {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))<2)
+ tmp+= 2;
+ else tmp+= w;
+ } else {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))>2)
+ tmp+= w - 2;
+ }
+ }
+ if (nGroups>2)
+ tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup3Index);
+ if (nGroups>3)
+ tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup4Index);
+ if (tmp>maxSymsPerKey)
+ maxSymsPerKey= tmp;
+ if (nGroups > maxNumberOfGroups)
+ maxNumberOfGroups = nGroups;
+ }
+ }
+
+ if (maxSymsPerKey <= 0)
+ return NULL;
+
+ syms = calloc(1, sizeof(*syms));
+ if (!syms)
+ return NULL;
+
+ /* See Section 12.4 of the XKB Protocol spec. Because of the
+ * single-group distribution for multi-group keyboards, we have to
+ * have enough symbols for the largest group 1 to replicate across the
+ * number of groups on the keyboard. e.g. a single-group key with 4
+ * symbols on a keyboard that has 3 groups -> 12 syms per key */
+ if (maxSymsPerKey < maxNumberOfGroups * maxGroup1Width)
+ maxSymsPerKey = maxNumberOfGroups * maxGroup1Width;
+
+ syms->mapWidth = maxSymsPerKey;
+ syms->minKeyCode = xkb->min_key_code;
+ syms->maxKeyCode = xkb->max_key_code;
+
+ tmp = syms->mapWidth * (xkb->max_key_code - xkb->min_key_code + 1);
+ syms->map = calloc(tmp, sizeof(*syms->map));
+ if (!syms->map) {
+ free(syms);
+ return NULL;
+ }
+
+ for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
+ KeySym *pCore,*pXKB;
+ unsigned nGroups,groupWidth,n,nOut;
+
+ nGroups= XkbKeyNumGroups(xkb,key);
+ n= (key-xkb->min_key_code)*syms->mapWidth;
+ pCore= &syms->map[n];
+ pXKB= XkbKeySymsPtr(xkb,key);
+ nOut= 2;
+ if (nGroups>0) {
+ groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup1Index);
+ if (groupWidth>0) pCore[0]= pXKB[0];
+ if (groupWidth>1) pCore[1]= pXKB[1];
+ for (n=2;n<groupWidth;n++)
+ pCore[2+n]= pXKB[n];
+ if (groupWidth>2)
+ nOut= groupWidth;
+ }
+
+ /* See XKB Protocol Sec, Section 12.4.
+ A 1-group key with ABCDE on a 2 group keyboard must be
+ duplicated across all groups as ABABCDECDE.
+ */
+ if (nGroups == 1)
+ {
+ int idx, j;
+
+ groupWidth = XkbKeyGroupWidth(xkb, key, XkbGroup1Index);
+
+ /* AB..CDE... -> ABABCDE... */
+ if (groupWidth > 0 && syms->mapWidth >= 3)
+ pCore[2] = pCore[0];
+ if (groupWidth > 1 && syms->mapWidth >= 4)
+ pCore[3] = pCore[1];
+
+ /* ABABCDE... -> ABABCDECDE */
+ idx = 2 + groupWidth;
+ while (groupWidth > 2 && idx < syms->mapWidth &&
+ idx < groupWidth * 2)
+ {
+ pCore[idx] = pCore[idx - groupWidth + 2];
+ idx++;
+ }
+ idx = 2 * groupWidth;
+ if (idx < 4)
+ idx = 4;
+ /* 3 or more groups: ABABCDECDEABCDEABCDE */
+ for (j = 3; j <= maxNumberOfGroups; j++)
+ for (n = 0; n < groupWidth && idx < maxSymsPerKey; n++)
+ pCore[idx++] = pXKB[n];
+ }
+
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ nOut+= 2;
+ if (nGroups>1) {
+ groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index);
+ if (groupWidth>0) pCore[2]= pXKB[0];
+ if (groupWidth>1) pCore[3]= pXKB[1];
+ for (n=2;n<groupWidth;n++) {
+ pCore[nOut+(n-2)]= pXKB[n];
+ }
+ if (groupWidth>2)
+ nOut+= (groupWidth-2);
+ }
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ for (n=XkbGroup3Index;n<nGroups;n++) {
+ register int s;
+ groupWidth= XkbKeyGroupWidth(xkb,key,n);
+ for (s=0;s<groupWidth;s++) {
+ pCore[nOut++]= pXKB[s];
+ }
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ }
+ }
+
+ return syms;
+}
+
+void
+XkbSetRepeatKeys(DeviceIntPtr pXDev,int key,int onoff)
+{
+ if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
+ xkbControlsNotify cn;
+ XkbControlsPtr ctrls = pXDev->key->xkbInfo->desc->ctrls;
+ XkbControlsRec old;
+ old = *ctrls;
+
+ if (key== -1) { /* global autorepeat setting changed */
+ if (onoff) ctrls->enabled_ctrls |= XkbRepeatKeysMask;
+ else ctrls->enabled_ctrls &= ~XkbRepeatKeysMask;
+ }
+ else if (pXDev->kbdfeed) {
+ ctrls->per_key_repeat[key/8] =
+ pXDev->kbdfeed->ctrl.autoRepeats[key/8];
+ }
+
+ if (XkbComputeControlsNotify(pXDev,&old,ctrls,&cn,TRUE))
+ XkbSendControlsNotify(pXDev,&cn);
+ }
+ return;
+}
+
+/* Applies a change to a single device, does not traverse the device tree. */
+void
+XkbApplyMappingChange(DeviceIntPtr kbd, KeySymsPtr map, KeyCode first_key,
+ CARD8 num_keys, CARD8 *modmap, ClientPtr client)
+{
+ XkbDescPtr xkb = kbd->key->xkbInfo->desc;
+ XkbEventCauseRec cause;
+ XkbChangesRec changes;
+ unsigned int check;
+
+ memset(&changes, 0, sizeof(changes));
+ memset(&cause, 0, sizeof(cause));
+
+ if (map && first_key && num_keys) {
+ check = 0;
+ XkbSetCauseCoreReq(&cause, X_ChangeKeyboardMapping, client);
+
+ XkbUpdateKeyTypesFromCore(kbd, map, first_key, num_keys, &changes);
+ XkbUpdateActions(kbd, first_key, num_keys, &changes, &check, &cause);
+
+ if (check)
+ XkbCheckSecondaryEffects(kbd->key->xkbInfo, 1, &changes, &cause);
+ }
+
+ if (modmap) {
+ /* A keymap change can imply a modmap change, se we prefer the
+ * former. */
+ if (!cause.mjr)
+ XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client);
+
+ check = 0;
+ num_keys = xkb->max_key_code - xkb->min_key_code + 1;
+ changes.map.changed |= XkbModifierMapMask;
+ changes.map.first_modmap_key = xkb->min_key_code;
+ changes.map.num_modmap_keys = num_keys;
+ memcpy(kbd->key->xkbInfo->desc->map->modmap, modmap, MAP_LENGTH);
+ XkbUpdateActions(kbd, xkb->min_key_code, num_keys, &changes, &check,
+ &cause);
+
+ if (check)
+ XkbCheckSecondaryEffects(kbd->key->xkbInfo, 1, &changes, &cause);
+ }
+
+ XkbSendNotification(kbd, &changes, &cause);
+}
+
+void
+XkbDisableComputedAutoRepeats(DeviceIntPtr dev,unsigned key)
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+xkbMapNotify mn;
+
+ xkbi->desc->server->explicit[key]|= XkbExplicitAutoRepeatMask;
+ bzero(&mn,sizeof(mn));
+ mn.changed= XkbExplicitComponentsMask;
+ mn.firstKeyExplicit= key;
+ mn.nKeyExplicit= 1;
+ XkbSendMapNotify(dev,&mn);
+ return;
+}
+
+unsigned
+XkbStateChangedFlags(XkbStatePtr old,XkbStatePtr new)
+{
+int changed;
+
+ changed=(old->group!=new->group?XkbGroupStateMask:0);
+ changed|=(old->base_group!=new->base_group?XkbGroupBaseMask:0);
+ changed|=(old->latched_group!=new->latched_group?XkbGroupLatchMask:0);
+ changed|=(old->locked_group!=new->locked_group?XkbGroupLockMask:0);
+ changed|=(old->mods!=new->mods?XkbModifierStateMask:0);
+ changed|=(old->base_mods!=new->base_mods?XkbModifierBaseMask:0);
+ changed|=(old->latched_mods!=new->latched_mods?XkbModifierLatchMask:0);
+ changed|=(old->locked_mods!=new->locked_mods?XkbModifierLockMask:0);
+ changed|=(old->compat_state!=new->compat_state?XkbCompatStateMask:0);
+ changed|=(old->grab_mods!=new->grab_mods?XkbGrabModsMask:0);
+ if (old->compat_grab_mods!=new->compat_grab_mods)
+ changed|= XkbCompatGrabModsMask;
+ changed|=(old->lookup_mods!=new->lookup_mods?XkbLookupModsMask:0);
+ if (old->compat_lookup_mods!=new->compat_lookup_mods)
+ changed|= XkbCompatLookupModsMask;
+ changed|=(old->ptr_buttons!=new->ptr_buttons?XkbPointerButtonMask:0);
+ return changed;
+}
+
+static void
+XkbComputeCompatState(XkbSrvInfoPtr xkbi)
+{
+CARD16 grp_mask;
+XkbStatePtr state= &xkbi->state;
+XkbCompatMapPtr map;
+
+ if (!state || !xkbi->desc || !xkbi->desc->ctrls || !xkbi->desc->compat)
+ return;
+
+ map= xkbi->desc->compat;
+ grp_mask= map->groups[state->group].mask;
+ state->compat_state = state->mods|grp_mask;
+ state->compat_lookup_mods= state->lookup_mods|grp_mask;
+
+ if (xkbi->desc->ctrls->enabled_ctrls&XkbIgnoreGroupLockMask)
+ grp_mask= map->groups[state->base_group].mask;
+ state->compat_grab_mods= state->grab_mods|grp_mask;
+ return;
+}
+
+unsigned
+XkbAdjustGroup(int group,XkbControlsPtr ctrls)
+{
+unsigned act;
+
+ act= XkbOutOfRangeGroupAction(ctrls->groups_wrap);
+ if (group<0) {
+ while ( group < 0 ) {
+ if (act==XkbClampIntoRange) {
+ group= XkbGroup1Index;
+ }
+ else if (act==XkbRedirectIntoRange) {
+ int newGroup;
+ newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
+ if (newGroup>=ctrls->num_groups)
+ group= XkbGroup1Index;
+ else group= newGroup;
+ }
+ else {
+ group+= ctrls->num_groups;
+ }
+ }
+ }
+ else if (group>=ctrls->num_groups) {
+ if (act==XkbClampIntoRange) {
+ group= ctrls->num_groups-1;
+ }
+ else if (act==XkbRedirectIntoRange) {
+ int newGroup;
+ newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
+ if (newGroup>=ctrls->num_groups)
+ group= XkbGroup1Index;
+ else group= newGroup;
+ }
+ else {
+ group%= ctrls->num_groups;
+ }
+ }
+ return group;
+}
+
+void
+XkbComputeDerivedState(XkbSrvInfoPtr xkbi)
+{
+XkbStatePtr state= &xkbi->state;
+XkbControlsPtr ctrls= xkbi->desc->ctrls;
+unsigned char grp;
+
+ if (!state || !ctrls)
+ return;
+
+ state->mods= (state->base_mods|state->latched_mods|state->locked_mods);
+ state->lookup_mods= state->mods&(~ctrls->internal.mask);
+ state->grab_mods= state->lookup_mods&(~ctrls->ignore_lock.mask);
+ state->grab_mods|=
+ ((state->base_mods|state->latched_mods)&ctrls->ignore_lock.mask);
+
+
+ grp= state->locked_group;
+ if (grp>=ctrls->num_groups)
+ state->locked_group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
+
+ grp= state->locked_group+state->base_group+state->latched_group;
+ if (grp>=ctrls->num_groups)
+ state->group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
+ else state->group= grp;
+ XkbComputeCompatState(xkbi);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbCheckSecondaryEffects( XkbSrvInfoPtr xkbi,
+ unsigned which,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+ if (which&XkbStateNotifyMask) {
+ XkbStateRec old;
+ old= xkbi->state;
+ changes->state_changes|= XkbStateChangedFlags(&old,&xkbi->state);
+ XkbComputeDerivedState(xkbi);
+ }
+ if (which&XkbIndicatorStateNotifyMask)
+ XkbUpdateIndicators(xkbi->device,XkbAllIndicatorsMask,TRUE,changes,
+ cause);
+ return;
+}
+
+/***====================================================================***/
+
+Bool
+XkbEnableDisableControls( XkbSrvInfoPtr xkbi,
+ unsigned long change,
+ unsigned long newValues,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+XkbControlsPtr ctrls;
+unsigned old;
+XkbSrvLedInfoPtr sli;
+
+ ctrls= xkbi->desc->ctrls;
+ old= ctrls->enabled_ctrls;
+ ctrls->enabled_ctrls&= ~change;
+ ctrls->enabled_ctrls|= (change&newValues);
+ if (old==ctrls->enabled_ctrls)
+ return FALSE;
+ if (cause!=NULL) {
+ xkbControlsNotify cn;
+ cn.numGroups= ctrls->num_groups;
+ cn.changedControls= XkbControlsEnabledMask;
+ cn.enabledControls= ctrls->enabled_ctrls;
+ cn.enabledControlChanges= (ctrls->enabled_ctrls^old);
+ cn.keycode= cause->kc;
+ cn.eventType= cause->event;
+ cn.requestMajor= cause->mjr;
+ cn.requestMinor= cause->mnr;
+ XkbSendControlsNotify(xkbi->device,&cn);
+ }
+ else {
+ /* Yes, this really should be an XOR. If ctrls->enabled_ctrls_changes*/
+ /* is non-zero, the controls in question changed already in "this" */
+ /* request and this change merely undoes the previous one. By the */
+ /* same token, we have to figure out whether or not ControlsEnabled */
+ /* should be set or not in the changes structure */
+ changes->ctrls.enabled_ctrls_changes^= (ctrls->enabled_ctrls^old);
+ if (changes->ctrls.enabled_ctrls_changes)
+ changes->ctrls.changed_ctrls|= XkbControlsEnabledMask;
+ else changes->ctrls.changed_ctrls&= ~XkbControlsEnabledMask;
+ }
+ sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(xkbi->device,sli->usesControls,TRUE,changes,cause);
+ return TRUE;
+}
+
+/***====================================================================***/
+
+#define MAX_TOC 16
+
+XkbGeometryPtr
+XkbLookupNamedGeometry(DeviceIntPtr dev,Atom name,Bool *shouldFree)
+{
+XkbSrvInfoPtr xkbi= dev->key->xkbInfo;
+XkbDescPtr xkb= xkbi->desc;
+
+ *shouldFree= 0;
+ if (name==None) {
+ if (xkb->geom!=NULL)
+ return xkb->geom;
+ name= xkb->names->geometry;
+ }
+ if ((xkb->geom!=NULL)&&(xkb->geom->name==name))
+ return xkb->geom;
+ *shouldFree= 1;
+ return NULL;
+}
+
+void
+XkbConvertCase(register KeySym sym, KeySym *lower, KeySym *upper)
+{
+ *lower = sym;
+ *upper = sym;
+ switch(sym >> 8) {
+ case 0: /* Latin 1 */
+ if ((sym >= XK_A) && (sym <= XK_Z))
+ *lower += (XK_a - XK_A);
+ else if ((sym >= XK_a) && (sym <= XK_z))
+ *upper -= (XK_a - XK_A);
+ else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
+ *lower += (XK_agrave - XK_Agrave);
+ else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
+ *upper -= (XK_agrave - XK_Agrave);
+ else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
+ *lower += (XK_oslash - XK_Ooblique);
+ else if ((sym >= XK_oslash) && (sym <= XK_thorn))
+ *upper -= (XK_oslash - XK_Ooblique);
+ break;
+ case 1: /* Latin 2 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym == XK_Aogonek)
+ *lower = XK_aogonek;
+ else if (sym >= XK_Lstroke && sym <= XK_Sacute)
+ *lower += (XK_lstroke - XK_Lstroke);
+ else if (sym >= XK_Scaron && sym <= XK_Zacute)
+ *lower += (XK_scaron - XK_Scaron);
+ else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
+ *lower += (XK_zcaron - XK_Zcaron);
+ else if (sym == XK_aogonek)
+ *upper = XK_Aogonek;
+ else if (sym >= XK_lstroke && sym <= XK_sacute)
+ *upper -= (XK_lstroke - XK_Lstroke);
+ else if (sym >= XK_scaron && sym <= XK_zacute)
+ *upper -= (XK_scaron - XK_Scaron);
+ else if (sym >= XK_zcaron && sym <= XK_zabovedot)
+ *upper -= (XK_zcaron - XK_Zcaron);
+ else if (sym >= XK_Racute && sym <= XK_Tcedilla)
+ *lower += (XK_racute - XK_Racute);
+ else if (sym >= XK_racute && sym <= XK_tcedilla)
+ *upper -= (XK_racute - XK_Racute);
+ break;
+ case 2: /* Latin 3 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
+ *lower += (XK_hstroke - XK_Hstroke);
+ else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
+ *lower += (XK_gbreve - XK_Gbreve);
+ else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
+ *upper -= (XK_hstroke - XK_Hstroke);
+ else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
+ *upper -= (XK_gbreve - XK_Gbreve);
+ else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
+ *lower += (XK_cabovedot - XK_Cabovedot);
+ else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
+ *upper -= (XK_cabovedot - XK_Cabovedot);
+ break;
+ case 3: /* Latin 4 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Rcedilla && sym <= XK_Tslash)
+ *lower += (XK_rcedilla - XK_Rcedilla);
+ else if (sym >= XK_rcedilla && sym <= XK_tslash)
+ *upper -= (XK_rcedilla - XK_Rcedilla);
+ else if (sym == XK_ENG)
+ *lower = XK_eng;
+ else if (sym == XK_eng)
+ *upper = XK_ENG;
+ else if (sym >= XK_Amacron && sym <= XK_Umacron)
+ *lower += (XK_amacron - XK_Amacron);
+ else if (sym >= XK_amacron && sym <= XK_umacron)
+ *upper -= (XK_amacron - XK_Amacron);
+ break;
+ case 6: /* Cyrillic */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
+ *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
+ else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
+ *upper += (XK_Serbian_DJE - XK_Serbian_dje);
+ else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
+ *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
+ else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
+ *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
+ break;
+ case 7: /* Greek */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
+ *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+ else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
+ sym != XK_Greek_iotaaccentdieresis &&
+ sym != XK_Greek_upsilonaccentdieresis)
+ *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+ else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
+ *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
+ else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
+ sym != XK_Greek_finalsmallsigma)
+ *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
+ break;
+ }
+}
+
+static Bool
+_XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+ int i;
+ XkbKeyTypePtr stype = NULL, dtype = NULL;
+
+ /* client map */
+ if (src->map) {
+ if (!dst->map) {
+ tmp = calloc(1, sizeof(XkbClientMapRec));
+ if (!tmp)
+ return FALSE;
+ dst->map = tmp;
+ }
+
+ if (src->map->syms) {
+ if (src->map->size_syms != dst->map->size_syms) {
+ if (dst->map->syms)
+ tmp = realloc(dst->map->syms,
+ src->map->size_syms * sizeof(KeySym));
+ else
+ tmp = malloc(src->map->size_syms * sizeof(KeySym));
+ if (!tmp)
+ return FALSE;
+ dst->map->syms = tmp;
+
+ }
+ memcpy(dst->map->syms, src->map->syms,
+ src->map->size_syms * sizeof(KeySym));
+ }
+ else {
+ if (dst->map->syms) {
+ free(dst->map->syms);
+ dst->map->syms = NULL;
+ }
+ }
+ dst->map->num_syms = src->map->num_syms;
+ dst->map->size_syms = src->map->size_syms;
+
+ if (src->map->key_sym_map) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->map->key_sym_map)
+ tmp = realloc(dst->map->key_sym_map,
+ (src->max_key_code + 1) *
+ sizeof(XkbSymMapRec));
+ else
+ tmp = malloc((src->max_key_code + 1) *
+ sizeof(XkbSymMapRec));
+ if (!tmp)
+ return FALSE;
+ dst->map->key_sym_map = tmp;
+ }
+ memcpy(dst->map->key_sym_map, src->map->key_sym_map,
+ (src->max_key_code + 1) * sizeof(XkbSymMapRec));
+ }
+ else {
+ if (dst->map->key_sym_map) {
+ free(dst->map->key_sym_map);
+ dst->map->key_sym_map = NULL;
+ }
+ }
+
+ if (src->map->types && src->map->num_types) {
+ if (src->map->num_types > dst->map->size_types ||
+ !dst->map->types || !dst->map->size_types) {
+ if (dst->map->types && dst->map->size_types) {
+ tmp = realloc(dst->map->types,
+ src->map->num_types * sizeof(XkbKeyTypeRec));
+ if (!tmp)
+ return FALSE;
+ dst->map->types = tmp;
+ bzero(dst->map->types + dst->map->num_types,
+ (src->map->num_types - dst->map->num_types) *
+ sizeof(XkbKeyTypeRec));
+ }
+ else {
+ tmp = calloc(src->map->num_types, sizeof(XkbKeyTypeRec));
+ if (!tmp)
+ return FALSE;
+ dst->map->types = tmp;
+ }
+ }
+ else if (src->map->num_types < dst->map->num_types &&
+ dst->map->types) {
+ for (i = src->map->num_types, dtype = (dst->map->types + i);
+ i < dst->map->num_types; i++, dtype++) {
+ if (dtype->level_names)
+ free(dtype->level_names);
+ dtype->level_names = NULL;
+ dtype->num_levels = 0;
+ if (dtype->map_count) {
+ if (dtype->map)
+ free(dtype->map);
+ if (dtype->preserve)
+ free(dtype->preserve);
+ }
+ }
+ }
+
+ stype = src->map->types;
+ dtype = dst->map->types;
+ for (i = 0; i < src->map->num_types; i++, dtype++, stype++) {
+ if (stype->num_levels && stype->level_names) {
+ if (stype->num_levels != dtype->num_levels &&
+ dtype->num_levels && dtype->level_names &&
+ i < dst->map->num_types) {
+ tmp = realloc(dtype->level_names,
+ stype->num_levels * sizeof(Atom));
+ if (!tmp)
+ continue;
+ dtype->level_names = tmp;
+ }
+ else if (!dtype->num_levels || !dtype->level_names ||
+ i >= dst->map->num_types) {
+ tmp = malloc(stype->num_levels * sizeof(Atom));
+ if (!tmp)
+ continue;
+ dtype->level_names = tmp;
+ }
+ dtype->num_levels = stype->num_levels;
+ memcpy(dtype->level_names, stype->level_names,
+ stype->num_levels * sizeof(Atom));
+ }
+ else {
+ if (dtype->num_levels && dtype->level_names &&
+ i < dst->map->num_types)
+ free(dtype->level_names);
+ dtype->num_levels = 0;
+ dtype->level_names = NULL;
+ }
+
+ dtype->name = stype->name;
+ memcpy(&dtype->mods, &stype->mods, sizeof(XkbModsRec));
+
+ if (stype->map_count) {
+ if (stype->map) {
+ if (stype->map_count != dtype->map_count &&
+ dtype->map_count && dtype->map &&
+ i < dst->map->num_types) {
+ tmp = realloc(dtype->map,
+ stype->map_count *
+ sizeof(XkbKTMapEntryRec));
+ if (!tmp)
+ return FALSE;
+ dtype->map = tmp;
+ }
+ else if (!dtype->map_count || !dtype->map ||
+ i >= dst->map->num_types) {
+ tmp = malloc(stype->map_count *
+ sizeof(XkbKTMapEntryRec));
+ if (!tmp)
+ return FALSE;
+ dtype->map = tmp;
+ }
+
+ memcpy(dtype->map, stype->map,
+ stype->map_count * sizeof(XkbKTMapEntryRec));
+ }
+ else {
+ if (dtype->map && i < dst->map->num_types)
+ free(dtype->map);
+ dtype->map = NULL;
+ }
+
+ if (stype->preserve) {
+ if (stype->map_count != dtype->map_count &&
+ dtype->map_count && dtype->preserve &&
+ i < dst->map->num_types) {
+ tmp = realloc(dtype->preserve,
+ stype->map_count *
+ sizeof(XkbModsRec));
+ if (!tmp)
+ return FALSE;
+ dtype->preserve = tmp;
+ }
+ else if (!dtype->preserve || !dtype->map_count ||
+ i >= dst->map->num_types) {
+ tmp = malloc(stype->map_count *
+ sizeof(XkbModsRec));
+ if (!tmp)
+ return FALSE;
+ dtype->preserve = tmp;
+ }
+
+ memcpy(dtype->preserve, stype->preserve,
+ stype->map_count * sizeof(XkbModsRec));
+ }
+ else {
+ if (dtype->preserve && i < dst->map->num_types)
+ free(dtype->preserve);
+ dtype->preserve = NULL;
+ }
+
+ dtype->map_count = stype->map_count;
+ }
+ else {
+ if (dtype->map_count && i < dst->map->num_types) {
+ if (dtype->map)
+ free(dtype->map);
+ if (dtype->preserve)
+ free(dtype->preserve);
+ }
+ dtype->map_count = 0;
+ dtype->map = NULL;
+ dtype->preserve = NULL;
+ }
+ }
+
+ dst->map->size_types = src->map->num_types;
+ dst->map->num_types = src->map->num_types;
+ }
+ else {
+ if (dst->map->types) {
+ for (i = 0, dtype = dst->map->types; i < dst->map->num_types;
+ i++, dtype++) {
+ if (dtype->level_names)
+ free(dtype->level_names);
+ if (dtype->map && dtype->map_count)
+ free(dtype->map);
+ if (dtype->preserve && dtype->map_count)
+ free(dtype->preserve);
+ }
+ free(dst->map->types);
+ dst->map->types = NULL;
+ }
+ dst->map->num_types = 0;
+ dst->map->size_types = 0;
+ }
+
+ if (src->map->modmap) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->map->modmap)
+ tmp = realloc(dst->map->modmap, src->max_key_code + 1);
+ else
+ tmp = malloc(src->max_key_code + 1);
+ if (!tmp)
+ return FALSE;
+ dst->map->modmap = tmp;
+ }
+ memcpy(dst->map->modmap, src->map->modmap, src->max_key_code + 1);
+ }
+ else {
+ if (dst->map->modmap) {
+ free(dst->map->modmap);
+ dst->map->modmap = NULL;
+ }
+ }
+ }
+ else {
+ if (dst->map)
+ XkbFreeClientMap(dst, XkbAllClientInfoMask, TRUE);
+ }
+
+ return TRUE;
+}
+
+static Bool
+_XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+
+ /* server map */
+ if (src->server) {
+ if (!dst->server) {
+ tmp = calloc(1, sizeof(XkbServerMapRec));
+ if (!tmp)
+ return FALSE;
+ dst->server = tmp;
+ }
+
+ if (src->server->explicit) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->server->explicit)
+ tmp = realloc(dst->server->explicit, src->max_key_code + 1);
+ else
+ tmp = malloc(src->max_key_code + 1);
+ if (!tmp)
+ return FALSE;
+ dst->server->explicit = tmp;
+ }
+ memcpy(dst->server->explicit, src->server->explicit,
+ src->max_key_code + 1);
+ }
+ else {
+ if (dst->server->explicit) {
+ free(dst->server->explicit);
+ dst->server->explicit = NULL;
+ }
+ }
+
+ if (src->server->acts) {
+ if (src->server->size_acts != dst->server->size_acts) {
+ if (dst->server->acts)
+ tmp = realloc(dst->server->acts,
+ src->server->size_acts * sizeof(XkbAction));
+ else
+ tmp = malloc(src->server->size_acts * sizeof(XkbAction));
+ if (!tmp)
+ return FALSE;
+ dst->server->acts = tmp;
+ }
+ memcpy(dst->server->acts, src->server->acts,
+ src->server->size_acts * sizeof(XkbAction));
+ }
+ else {
+ if (dst->server->acts) {
+ free(dst->server->acts);
+ dst->server->acts = NULL;
+ }
+ }
+ dst->server->size_acts = src->server->size_acts;
+ dst->server->num_acts = src->server->num_acts;
+
+ if (src->server->key_acts) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->server->key_acts)
+ tmp = realloc(dst->server->key_acts,
+ (src->max_key_code + 1) *
+ sizeof(unsigned short));
+ else
+ tmp = malloc((src->max_key_code + 1) *
+ sizeof(unsigned short));
+ if (!tmp)
+ return FALSE;
+ dst->server->key_acts = tmp;
+ }
+ memcpy(dst->server->key_acts, src->server->key_acts,
+ (src->max_key_code + 1) * sizeof(unsigned short));
+ }
+ else {
+ if (dst->server->key_acts) {
+ free(dst->server->key_acts);
+ dst->server->key_acts = NULL;
+ }
+ }
+
+ if (src->server->behaviors) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->server->behaviors)
+ tmp = realloc(dst->server->behaviors,
+ (src->max_key_code + 1) *
+ sizeof(XkbBehavior));
+ else
+ tmp = malloc((src->max_key_code + 1) *
+ sizeof(XkbBehavior));
+ if (!tmp)
+ return FALSE;
+ dst->server->behaviors = tmp;
+ }
+ memcpy(dst->server->behaviors, src->server->behaviors,
+ (src->max_key_code + 1) * sizeof(XkbBehavior));
+ }
+ else {
+ if (dst->server->behaviors) {
+ free(dst->server->behaviors);
+ dst->server->behaviors = NULL;
+ }
+ }
+
+ memcpy(dst->server->vmods, src->server->vmods, XkbNumVirtualMods);
+
+ if (src->server->vmodmap) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->server->vmodmap)
+ tmp = realloc(dst->server->vmodmap,
+ (src->max_key_code + 1) *
+ sizeof(unsigned short));
+ else
+ tmp = malloc((src->max_key_code + 1) *
+ sizeof(unsigned short));
+ if (!tmp)
+ return FALSE;
+ dst->server->vmodmap = tmp;
+ }
+ memcpy(dst->server->vmodmap, src->server->vmodmap,
+ (src->max_key_code + 1) * sizeof(unsigned short));
+ }
+ else {
+ if (dst->server->vmodmap) {
+ free(dst->server->vmodmap);
+ dst->server->vmodmap = NULL;
+ }
+ }
+ }
+ else {
+ if (dst->server)
+ XkbFreeServerMap(dst, XkbAllServerInfoMask, TRUE);
+ }
+
+ return TRUE;
+}
+
+static Bool
+_XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+
+ /* names */
+ if (src->names) {
+ if (!dst->names) {
+ dst->names = calloc(1, sizeof(XkbNamesRec));
+ if (!dst->names)
+ return FALSE;
+ }
+
+ if (src->names->keys) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->names->keys)
+ tmp = realloc(dst->names->keys, (src->max_key_code + 1) *
+ sizeof(XkbKeyNameRec));
+ else
+ tmp = malloc((src->max_key_code + 1) *
+ sizeof(XkbKeyNameRec));
+ if (!tmp)
+ return FALSE;
+ dst->names->keys = tmp;
+ }
+ memcpy(dst->names->keys, src->names->keys,
+ (src->max_key_code + 1) * sizeof(XkbKeyNameRec));
+ }
+ else {
+ if (dst->names->keys) {
+ free(dst->names->keys);
+ dst->names->keys = NULL;
+ }
+ }
+
+ if (src->names->num_key_aliases) {
+ if (src->names->num_key_aliases != dst->names->num_key_aliases) {
+ if (dst->names->key_aliases)
+ tmp = realloc(dst->names->key_aliases,
+ src->names->num_key_aliases *
+ sizeof(XkbKeyAliasRec));
+ else
+ tmp = malloc(src->names->num_key_aliases *
+ sizeof(XkbKeyAliasRec));
+ if (!tmp)
+ return FALSE;
+ dst->names->key_aliases = tmp;
+ }
+ memcpy(dst->names->key_aliases, src->names->key_aliases,
+ src->names->num_key_aliases * sizeof(XkbKeyAliasRec));
+ }
+ else {
+ if (dst->names->key_aliases) {
+ free(dst->names->key_aliases);
+ dst->names->key_aliases = NULL;
+ }
+ }
+ dst->names->num_key_aliases = src->names->num_key_aliases;
+
+ if (src->names->num_rg) {
+ if (src->names->num_rg != dst->names->num_rg) {
+ if (dst->names->radio_groups)
+ tmp = realloc(dst->names->radio_groups,
+ src->names->num_rg * sizeof(Atom));
+ else
+ tmp = malloc(src->names->num_rg * sizeof(Atom));
+ if (!tmp)
+ return FALSE;
+ dst->names->radio_groups = tmp;
+ }
+ memcpy(dst->names->radio_groups, src->names->radio_groups,
+ src->names->num_rg * sizeof(Atom));
+ }
+ else {
+ if (dst->names->radio_groups)
+ free(dst->names->radio_groups);
+ }
+ dst->names->num_rg = src->names->num_rg;
+
+ dst->names->keycodes = src->names->keycodes;
+ dst->names->geometry = src->names->geometry;
+ dst->names->symbols = src->names->symbols;
+ dst->names->types = src->names->types;
+ dst->names->compat = src->names->compat;
+ dst->names->phys_symbols = src->names->phys_symbols;
+
+ memcpy(dst->names->vmods, src->names->vmods,
+ XkbNumVirtualMods * sizeof(Atom));
+ memcpy(dst->names->indicators, src->names->indicators,
+ XkbNumIndicators * sizeof(Atom));
+ memcpy(dst->names->groups, src->names->groups,
+ XkbNumKbdGroups * sizeof(Atom));
+ }
+ else {
+ if (dst->names)
+ XkbFreeNames(dst, XkbAllNamesMask, TRUE);
+ }
+
+ return TRUE;
+}
+
+static Bool
+_XkbCopyCompat(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+
+ /* compat */
+ if (src->compat) {
+ if (!dst->compat) {
+ dst->compat = calloc(1, sizeof(XkbCompatMapRec));
+ if (!dst->compat)
+ return FALSE;
+ }
+
+ if (src->compat->sym_interpret && src->compat->num_si) {
+ if (src->compat->num_si != dst->compat->size_si) {
+ if (dst->compat->sym_interpret)
+ tmp = realloc(dst->compat->sym_interpret,
+ src->compat->num_si *
+ sizeof(XkbSymInterpretRec));
+ else
+ tmp = malloc(src->compat->num_si *
+ sizeof(XkbSymInterpretRec));
+ if (!tmp)
+ return FALSE;
+ dst->compat->sym_interpret = tmp;
+ }
+ memcpy(dst->compat->sym_interpret, src->compat->sym_interpret,
+ src->compat->num_si * sizeof(XkbSymInterpretRec));
+
+ dst->compat->num_si = src->compat->num_si;
+ dst->compat->size_si = src->compat->num_si;
+ }
+ else {
+ if (dst->compat->sym_interpret && dst->compat->size_si)
+ free(dst->compat->sym_interpret);
+
+ dst->compat->sym_interpret = NULL;
+ dst->compat->num_si = 0;
+ dst->compat->size_si = 0;
+ }
+
+ memcpy(dst->compat->groups, src->compat->groups,
+ XkbNumKbdGroups * sizeof(XkbModsRec));
+ }
+ else {
+ if (dst->compat)
+ XkbFreeCompatMap(dst, XkbAllCompatMask, TRUE);
+ }
+
+ return TRUE;
+}
+
+static Bool
+_XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+ int i = 0, j = 0, k = 0;
+ XkbColorPtr scolor = NULL, dcolor = NULL;
+ XkbDoodadPtr sdoodad = NULL, ddoodad = NULL;
+ XkbOutlinePtr soutline = NULL, doutline = NULL;
+ XkbPropertyPtr sprop = NULL, dprop = NULL;
+ XkbRowPtr srow = NULL, drow = NULL;
+ XkbSectionPtr ssection = NULL, dsection = NULL;
+ XkbShapePtr sshape = NULL, dshape = NULL;
+
+ /* geometry */
+ if (src->geom) {
+ if (!dst->geom) {
+ dst->geom = calloc(sizeof(XkbGeometryRec), 1);
+ if (!dst->geom)
+ return FALSE;
+ }
+
+ /* properties */
+ if (src->geom->num_properties) {
+ if (src->geom->num_properties != dst->geom->sz_properties) {
+ /* If we've got more properties in the destination than
+ * the source, run through and free all the excess ones
+ * first. */
+ if (src->geom->num_properties < dst->geom->sz_properties) {
+ for (i = src->geom->num_properties,
+ dprop = dst->geom->properties + i;
+ i < dst->geom->num_properties;
+ i++, dprop++) {
+ free(dprop->name);
+ free(dprop->value);
+ }
+ }
+
+ if (dst->geom->sz_properties)
+ tmp = realloc(dst->geom->properties,
+ src->geom->num_properties *
+ sizeof(XkbPropertyRec));
+ else
+ tmp = malloc(src->geom->num_properties *
+ sizeof(XkbPropertyRec));
+ if (!tmp)
+ return FALSE;
+ dst->geom->properties = tmp;
+ }
+
+ /* We don't set num_properties as we need it to try and avoid
+ * too much reallocing. */
+ dst->geom->sz_properties = src->geom->num_properties;
+
+ if (dst->geom->sz_properties > dst->geom->num_properties) {
+ bzero(dst->geom->properties + dst->geom->num_properties,
+ (dst->geom->sz_properties - dst->geom->num_properties) *
+ sizeof(XkbPropertyRec));
+ }
+
+ for (i = 0,
+ sprop = src->geom->properties,
+ dprop = dst->geom->properties;
+ i < src->geom->num_properties;
+ i++, sprop++, dprop++) {
+ if (i < dst->geom->num_properties) {
+ if (strlen(sprop->name) != strlen(dprop->name)) {
+ tmp = realloc(dprop->name, strlen(sprop->name) + 1);
+ if (!tmp)
+ return FALSE;
+ dprop->name = tmp;
+ }
+ if (strlen(sprop->value) != strlen(dprop->value)) {
+ tmp = realloc(dprop->value, strlen(sprop->value) + 1);
+ if (!tmp)
+ return FALSE;
+ dprop->value = tmp;
+ }
+ strcpy(dprop->name, sprop->name);
+ strcpy(dprop->value, sprop->value);
+ }
+ else {
+ dprop->name = xstrdup(sprop->name);
+ dprop->value = xstrdup(sprop->value);
+ }
+ }
+
+ /* ... which is already src->geom->num_properties. */
+ dst->geom->num_properties = dst->geom->sz_properties;
+ }
+ else {
+ if (dst->geom->sz_properties) {
+ for (i = 0, dprop = dst->geom->properties;
+ i < dst->geom->num_properties;
+ i++, dprop++) {
+ free(dprop->name);
+ free(dprop->value);
+ }
+ free(dst->geom->properties);
+ dst->geom->properties = NULL;
+ }
+
+ dst->geom->num_properties = 0;
+ dst->geom->sz_properties = 0;
+ }
+
+ /* colors */
+ if (src->geom->num_colors) {
+ if (src->geom->num_colors != dst->geom->sz_colors) {
+ if (src->geom->num_colors < dst->geom->sz_colors) {
+ for (i = src->geom->num_colors,
+ dcolor = dst->geom->colors + i;
+ i < dst->geom->num_colors;
+ i++, dcolor++) {
+ free(dcolor->spec);
+ }
+ }
+
+ if (dst->geom->sz_colors)
+ tmp = realloc(dst->geom->colors,
+ src->geom->num_colors *
+ sizeof(XkbColorRec));
+ else
+ tmp = malloc(src->geom->num_colors *
+ sizeof(XkbColorRec));
+ if (!tmp)
+ return FALSE;
+ dst->geom->colors = tmp;
+ }
+
+ dst->geom->sz_colors = src->geom->num_colors;
+
+ if (dst->geom->sz_colors > dst->geom->num_colors) {
+ bzero(dst->geom->colors + dst->geom->num_colors,
+ (dst->geom->sz_colors - dst->geom->num_colors) *
+ sizeof(XkbColorRec));
+ }
+
+ for (i = 0,
+ scolor = src->geom->colors,
+ dcolor = dst->geom->colors;
+ i < src->geom->num_colors;
+ i++, scolor++, dcolor++) {
+ if (i < dst->geom->num_colors) {
+ if (strlen(scolor->spec) != strlen(dcolor->spec)) {
+ tmp = realloc(dcolor->spec, strlen(scolor->spec) + 1);
+ if (!tmp)
+ return FALSE;
+ dcolor->spec = tmp;
+ }
+ strcpy(dcolor->spec, scolor->spec);
+ }
+ else {
+ dcolor->spec = xstrdup(scolor->spec);
+ }
+ dcolor->pixel = scolor->pixel;
+ }
+
+ dst->geom->num_colors = dst->geom->sz_colors;
+ }
+ else {
+ if (dst->geom->sz_colors) {
+ for (i = 0, dcolor = dst->geom->colors;
+ i < dst->geom->num_colors;
+ i++, dcolor++) {
+ free(dcolor->spec);
+ }
+ free(dst->geom->colors);
+ dst->geom->colors = NULL;
+ }
+
+ dst->geom->num_colors = 0;
+ dst->geom->sz_colors = 0;
+ }
+
+ /* shapes */
+ /* shapes break down into outlines, which break down into points. */
+ if (dst->geom->num_shapes) {
+ for (i = 0, dshape = dst->geom->shapes;
+ i < dst->geom->num_shapes;
+ i++, dshape++) {
+ for (j = 0, doutline = dshape->outlines;
+ j < dshape->num_outlines;
+ j++, doutline++) {
+ if (doutline->sz_points)
+ free(doutline->points);
+ }
+
+ if (dshape->sz_outlines) {
+ free(dshape->outlines);
+ dshape->outlines = NULL;
+ }
+
+ dshape->num_outlines = 0;
+ dshape->sz_outlines = 0;
+ }
+ }
+
+ if (src->geom->num_shapes) {
+ tmp = calloc(src->geom->num_shapes, sizeof(XkbShapeRec));
+ if (!tmp)
+ return FALSE;
+ dst->geom->shapes = tmp;
+
+ for (i = 0, sshape = src->geom->shapes, dshape = dst->geom->shapes;
+ i < src->geom->num_shapes;
+ i++, sshape++, dshape++) {
+ if (sshape->num_outlines) {
+ tmp = calloc(sshape->num_outlines, sizeof(XkbOutlineRec));
+ if (!tmp)
+ return FALSE;
+ dshape->outlines = tmp;
+
+ for (j = 0,
+ soutline = sshape->outlines,
+ doutline = dshape->outlines;
+ j < sshape->num_outlines;
+ j++, soutline++, doutline++) {
+ if (soutline->num_points) {
+ tmp = malloc(soutline->num_points *
+ sizeof(XkbPointRec));
+ if (!tmp)
+ return FALSE;
+ doutline->points = tmp;
+
+ memcpy(doutline->points, soutline->points,
+ soutline->num_points * sizeof(XkbPointRec));
+
+ doutline->corner_radius = soutline->corner_radius;
+ }
+
+ doutline->num_points = soutline->num_points;
+ doutline->sz_points = soutline->num_points;
+ }
+ }
+
+ dshape->num_outlines = sshape->num_outlines;
+ dshape->sz_outlines = sshape->num_outlines;
+ dshape->name = sshape->name;
+ dshape->bounds = sshape->bounds;
+
+ dshape->approx = NULL;
+ if (sshape->approx && sshape->num_outlines > 0) {
+
+ const ptrdiff_t approx_idx =
+ sshape->approx - sshape->outlines;
+
+ if (approx_idx < dshape->num_outlines) {
+ dshape->approx = dshape->outlines + approx_idx;
+ } else {
+ LogMessage(X_WARNING, "XKB: approx outline "
+ "index is out of range\n");
+ }
+ }
+
+ dshape->primary = NULL;
+ if (sshape->primary && sshape->num_outlines > 0) {
+
+ const ptrdiff_t primary_idx =
+ sshape->primary - sshape->outlines;
+
+ if (primary_idx < dshape->num_outlines) {
+ dshape->primary = dshape->outlines + primary_idx;
+ } else {
+ LogMessage(X_WARNING, "XKB: primary outline "
+ "index is out of range\n");
+ }
+ }
+ }
+
+ dst->geom->num_shapes = src->geom->num_shapes;
+ dst->geom->sz_shapes = src->geom->num_shapes;
+ }
+ else {
+ if (dst->geom->sz_shapes) {
+ free(dst->geom->shapes);
+ }
+ dst->geom->shapes = NULL;
+ dst->geom->num_shapes = 0;
+ dst->geom->sz_shapes = 0;
+ }
+
+ /* sections */
+ /* sections break down into doodads, and also into rows, which break
+ * down into keys. */
+ if (dst->geom->num_sections) {
+ for (i = 0, dsection = dst->geom->sections;
+ i < dst->geom->num_sections;
+ i++, dsection++) {
+ for (j = 0, drow = dsection->rows;
+ j < dsection->num_rows;
+ j++, drow++) {
+ if (drow->num_keys)
+ free(drow->keys);
+ }
+
+ if (dsection->num_rows)
+ free(dsection->rows);
+
+ /* cut and waste from geom/doodad below. */
+ for (j = 0, ddoodad = dsection->doodads;
+ j < dsection->num_doodads;
+ j++, ddoodad++) {
+ if (ddoodad->any.type == XkbTextDoodad) {
+ if (ddoodad->text.text) {
+ free(ddoodad->text.text);
+ ddoodad->text.text = NULL;
+ }
+ if (ddoodad->text.font) {
+ free(ddoodad->text.font);
+ ddoodad->text.font = NULL;
+ }
+ }
+ else if (ddoodad->any.type == XkbLogoDoodad) {
+ if (ddoodad->logo.logo_name) {
+ free(ddoodad->logo.logo_name);
+ ddoodad->logo.logo_name = NULL;
+ }
+ }
+ }
+
+ if (dsection->num_doodads)
+ free(dsection->doodads);
+ }
+
+ dst->geom->num_sections = 0;
+ dst->geom->sections = NULL;
+ }
+
+ if (src->geom->num_sections) {
+ if (dst->geom->sz_sections)
+ tmp = realloc(dst->geom->sections,
+ src->geom->num_sections *
+ sizeof(XkbSectionRec));
+ else
+ tmp = malloc(src->geom->num_sections * sizeof(XkbSectionRec));
+ if (!tmp)
+ return FALSE;
+ memset(tmp, 0, src->geom->num_sections * sizeof(XkbSectionRec));
+ dst->geom->sections = tmp;
+ dst->geom->num_sections = src->geom->num_sections;
+ dst->geom->sz_sections = src->geom->num_sections;
+
+ for (i = 0,
+ ssection = src->geom->sections,
+ dsection = dst->geom->sections;
+ i < src->geom->num_sections;
+ i++, ssection++, dsection++) {
+ *dsection = *ssection;
+ if (ssection->num_rows) {
+ tmp = calloc(ssection->num_rows, sizeof(XkbRowRec));
+ if (!tmp)
+ return FALSE;
+ dsection->rows = tmp;
+ }
+ dsection->num_rows = ssection->num_rows;
+ dsection->sz_rows = ssection->num_rows;
+
+ for (j = 0, srow = ssection->rows, drow = dsection->rows;
+ j < ssection->num_rows;
+ j++, srow++, drow++) {
+ if (srow->num_keys) {
+ tmp = malloc(srow->num_keys * sizeof(XkbKeyRec));
+ if (!tmp)
+ return FALSE;
+ drow->keys = tmp;
+ memcpy(drow->keys, srow->keys,
+ srow->num_keys * sizeof(XkbKeyRec));
+ }
+ drow->num_keys = srow->num_keys;
+ drow->sz_keys = srow->num_keys;
+ drow->top = srow->top;
+ drow->left = srow->left;
+ drow->vertical = srow->vertical;
+ drow->bounds = srow->bounds;
+ }
+
+ if (ssection->num_doodads) {
+ tmp = calloc(ssection->num_doodads, sizeof(XkbDoodadRec));
+ if (!tmp)
+ return FALSE;
+ dsection->doodads = tmp;
+ }
+ else {
+ dsection->doodads = NULL;
+ }
+
+ dsection->sz_doodads = ssection->num_doodads;
+ for (k = 0,
+ sdoodad = ssection->doodads,
+ ddoodad = dsection->doodads;
+ k < ssection->num_doodads;
+ k++, sdoodad++, ddoodad++) {
+ memcpy(ddoodad , sdoodad, sizeof(XkbDoodadRec));
+ if (sdoodad->any.type == XkbTextDoodad) {
+ if (sdoodad->text.text)
+ ddoodad->text.text =
+ xstrdup(sdoodad->text.text);
+ if (sdoodad->text.font)
+ ddoodad->text.font =
+ xstrdup(sdoodad->text.font);
+ }
+ else if (sdoodad->any.type == XkbLogoDoodad) {
+ if (sdoodad->logo.logo_name)
+ ddoodad->logo.logo_name =
+ xstrdup(sdoodad->logo.logo_name);
+ }
+ }
+ dsection->overlays = NULL;
+ dsection->sz_overlays = 0;
+ dsection->num_overlays = 0;
+ }
+ }
+ else {
+ if (dst->geom->sz_sections) {
+ free(dst->geom->sections);
+ }
+
+ dst->geom->sections = NULL;
+ dst->geom->num_sections = 0;
+ dst->geom->sz_sections = 0;
+ }
+
+ /* doodads */
+ if (dst->geom->num_doodads) {
+ for (i = src->geom->num_doodads,
+ ddoodad = dst->geom->doodads +
+ src->geom->num_doodads;
+ i < dst->geom->num_doodads;
+ i++, ddoodad++) {
+ if (ddoodad->any.type == XkbTextDoodad) {
+ if (ddoodad->text.text) {
+ free(ddoodad->text.text);
+ ddoodad->text.text = NULL;
+ }
+ if (ddoodad->text.font) {
+ free(ddoodad->text.font);
+ ddoodad->text.font = NULL;
+ }
+ }
+ else if (ddoodad->any.type == XkbLogoDoodad) {
+ if (ddoodad->logo.logo_name) {
+ free(ddoodad->logo.logo_name);
+ ddoodad->logo.logo_name = NULL;
+ }
+ }
+ }
+ dst->geom->num_doodads = 0;
+ dst->geom->doodads = NULL;
+ }
+
+ if (src->geom->num_doodads) {
+ if (dst->geom->sz_doodads)
+ tmp = realloc(dst->geom->doodads,
+ src->geom->num_doodads *
+ sizeof(XkbDoodadRec));
+ else
+ tmp = malloc(src->geom->num_doodads *
+ sizeof(XkbDoodadRec));
+ if (!tmp)
+ return FALSE;
+ memset(tmp, 0, src->geom->num_doodads * sizeof(XkbDoodadRec));
+ dst->geom->doodads = tmp;
+
+ dst->geom->sz_doodads = src->geom->num_doodads;
+
+ for (i = 0,
+ sdoodad = src->geom->doodads,
+ ddoodad = dst->geom->doodads;
+ i < src->geom->num_doodads;
+ i++, sdoodad++, ddoodad++) {
+ memcpy(ddoodad , sdoodad, sizeof(XkbDoodadRec));
+ if (sdoodad->any.type == XkbTextDoodad) {
+ if (sdoodad->text.text)
+ ddoodad->text.text = xstrdup(sdoodad->text.text);
+ if (sdoodad->text.font)
+ ddoodad->text.font = xstrdup(sdoodad->text.font);
+ }
+ else if (sdoodad->any.type == XkbLogoDoodad) {
+ if (sdoodad->logo.logo_name)
+ ddoodad->logo.logo_name =
+ xstrdup(sdoodad->logo.logo_name);
+ }
+ }
+
+ dst->geom->num_doodads = dst->geom->sz_doodads;
+ }
+ else {
+ if (dst->geom->sz_doodads) {
+ free(dst->geom->doodads);
+ }
+
+ dst->geom->doodads = NULL;
+ dst->geom->num_doodads = 0;
+ dst->geom->sz_doodads = 0;
+ }
+
+ /* key aliases */
+ if (src->geom->num_key_aliases) {
+ if (src->geom->num_key_aliases != dst->geom->sz_key_aliases) {
+ if (dst->geom->sz_key_aliases)
+ tmp = realloc(dst->geom->key_aliases,
+ src->geom->num_key_aliases *
+ 2 * XkbKeyNameLength);
+ else
+ tmp = malloc(src->geom->num_key_aliases *
+ 2 * XkbKeyNameLength);
+ if (!tmp)
+ return FALSE;
+ dst->geom->key_aliases = tmp;
+
+ dst->geom->sz_key_aliases = src->geom->num_key_aliases;
+ }
+
+ memcpy(dst->geom->key_aliases, src->geom->key_aliases,
+ src->geom->num_key_aliases * 2 * XkbKeyNameLength);
+
+ dst->geom->num_key_aliases = dst->geom->sz_key_aliases;
+ }
+ else {
+ if (dst->geom->key_aliases) {
+ free(dst->geom->key_aliases);
+ }
+ dst->geom->key_aliases = NULL;
+ dst->geom->num_key_aliases = 0;
+ dst->geom->sz_key_aliases = 0;
+ }
+
+ /* font */
+ if (src->geom->label_font) {
+ if (!dst->geom->label_font) {
+ tmp = malloc(strlen(src->geom->label_font));
+ if (!tmp)
+ return FALSE;
+ dst->geom->label_font = tmp;
+ }
+ else if (strlen(src->geom->label_font) !=
+ strlen(dst->geom->label_font)) {
+ tmp = realloc(dst->geom->label_font,
+ strlen(src->geom->label_font));
+ if (!tmp)
+ return FALSE;
+ dst->geom->label_font = tmp;
+ }
+
+ strcpy(dst->geom->label_font, src->geom->label_font);
+ i = XkbGeomColorIndex(src->geom, src->geom->label_color);
+ dst->geom->label_color = &(dst->geom->colors[i]);
+ i = XkbGeomColorIndex(src->geom, src->geom->base_color);
+ dst->geom->base_color = &(dst->geom->colors[i]);
+ }
+ else {
+ if (dst->geom->label_font) {
+ free(dst->geom->label_font);
+ }
+ dst->geom->label_font = NULL;
+ dst->geom->label_color = NULL;
+ dst->geom->base_color = NULL;
+ }
+
+ dst->geom->name = src->geom->name;
+ dst->geom->width_mm = src->geom->width_mm;
+ dst->geom->height_mm = src->geom->height_mm;
+ }
+ else
+ {
+ if (dst->geom) {
+ /* I LOVE THE DIFFERENT CALL SIGNATURE. REALLY, I DO. */
+ XkbFreeGeometry(dst->geom, XkbGeomAllMask, TRUE);
+ dst->geom = NULL;
+ }
+ }
+
+ return TRUE;
+}
+
+static Bool
+_XkbCopyIndicators(XkbDescPtr src, XkbDescPtr dst)
+{
+ /* indicators */
+ if (src->indicators) {
+ if (!dst->indicators) {
+ dst->indicators = malloc(sizeof(XkbIndicatorRec));
+ if (!dst->indicators)
+ return FALSE;
+ }
+ memcpy(dst->indicators, src->indicators, sizeof(XkbIndicatorRec));
+ }
+ else {
+ if (dst->indicators) {
+ free(dst->indicators);
+ dst->indicators = NULL;
+ }
+ }
+ return TRUE;
+}
+
+static Bool
+_XkbCopyControls(XkbDescPtr src, XkbDescPtr dst)
+{
+ /* controls */
+ if (src->ctrls) {
+ if (!dst->ctrls) {
+ dst->ctrls = malloc(sizeof(XkbControlsRec));
+ if (!dst->ctrls)
+ return FALSE;
+ }
+ memcpy(dst->ctrls, src->ctrls, sizeof(XkbControlsRec));
+ }
+ else {
+ if (dst->ctrls) {
+ free(dst->ctrls);
+ dst->ctrls = NULL;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Copy an XKB map from src to dst, reallocating when necessary: if some
+ * map components are present in one, but not in the other, the destination
+ * components will be allocated or freed as necessary.
+ *
+ * Basic map consistency is assumed on both sides, so maps with random
+ * uninitialised data (e.g. names->radio_grous == NULL, names->num_rg == 19)
+ * _will_ cause failures. You've been warned.
+ *
+ * Returns TRUE on success, or FALSE on failure. If this function fails,
+ * dst may be in an inconsistent state: all its pointers are guaranteed
+ * to remain valid, but part of the map may be from src and part from dst.
+ *
+ */
+
+Bool
+XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
+{
+
+ if (!src || !dst) {
+ DebugF("XkbCopyKeymap: src (%p) or dst (%p) is NULL\n", src, dst);
+ return FALSE;
+ }
+
+ if (src == dst)
+ return TRUE;
+
+ if (!_XkbCopyClientMap(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy client map\n");
+ return FALSE;
+ }
+ if (!_XkbCopyServerMap(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy server map\n");
+ return FALSE;
+ }
+ if (!_XkbCopyIndicators(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy indicators\n");
+ return FALSE;
+ }
+ if (!_XkbCopyControls(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy controls\n");
+ return FALSE;
+ }
+ if (!_XkbCopyNames(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy names\n");
+ return FALSE;
+ }
+ if (!_XkbCopyCompat(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy compat map\n");
+ return FALSE;
+ }
+ if (!_XkbCopyGeom(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy geometry\n");
+ return FALSE;
+ }
+
+ dst->min_key_code = src->min_key_code;
+ dst->max_key_code = src->max_key_code;
+
+ return TRUE;
+}
+
+Bool
+XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
+{
+ xkbNewKeyboardNotify nkn;
+ Bool ret;
+
+ if (!dst->key || !src->key)
+ return FALSE;
+
+ memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
+ nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
+ nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
+ nkn.deviceID = dst->id;
+ nkn.oldDeviceID = dst->id; /* maybe src->id? */
+ nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
+ nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
+ nkn.requestMajor = XkbReqCode;
+ nkn.requestMinor = X_kbSetMap; /* Near enough's good enough. */
+ nkn.changed = XkbNKN_KeycodesMask;
+ if (src->key->xkbInfo->desc->geom)
+ nkn.changed |= XkbNKN_GeometryMask;
+
+ ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
+ if (ret)
+ XkbSendNewKeyboardNotify(dst, &nkn);
+
+ return ret;
+}
+
+int
+XkbGetEffectiveGroup(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 keycode)
+{
+ XkbDescPtr xkb = xkbi->desc;
+ int effectiveGroup = xkbState->group;
+
+ if (!XkbKeycodeInRange(xkb, keycode))
+ return -1;
+
+ if (effectiveGroup == XkbGroup1Index)
+ return effectiveGroup;
+
+ if (XkbKeyNumGroups(xkb,keycode) > 1U) {
+ if (effectiveGroup >= XkbKeyNumGroups(xkb,keycode)) {
+ unsigned int gi = XkbKeyGroupInfo(xkb,keycode);
+ switch (XkbOutOfRangeGroupAction(gi)) {
+ default:
+ case XkbWrapIntoRange:
+ effectiveGroup %= XkbKeyNumGroups(xkb, keycode);
+ break;
+ case XkbClampIntoRange:
+ effectiveGroup = XkbKeyNumGroups(xkb, keycode) - 1;
+ break;
+ case XkbRedirectIntoRange:
+ effectiveGroup = XkbOutOfRangeGroupInfo(gi);
+ if (effectiveGroup >= XkbKeyNumGroups(xkb, keycode))
+ effectiveGroup = 0;
+ break;
+ }
+ }
+ }
+ else effectiveGroup = XkbGroup1Index;
+
+ return effectiveGroup;
+}
diff --git a/xorg-server/xkb/xkmread.c b/xorg-server/xkb/xkmread.c
index a201731f3..660884a7f 100644
--- a/xorg-server/xkb/xkmread.c
+++ b/xorg-server/xkb/xkmread.c
@@ -1,1238 +1,1238 @@
-/************************************************************
- Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
-
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
-
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- ********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-
-#include <X11/Xos.h>
-#include <X11/Xfuncs.h>
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include <X11/extensions/XKMformat.h>
-#include "misc.h"
-#include "inputstr.h"
-#include "xkbstr.h"
-#include "xkbsrv.h"
-#include "xkbgeom.h"
-
-Atom
-XkbInternAtom(char *str,Bool only_if_exists)
-{
- if (str==NULL)
- return None;
- return MakeAtom(str,strlen(str),!only_if_exists);
-}
-
-char *
-_XkbDupString(const char *str)
-{
-char *new;
-
- if (str==NULL)
- return NULL;
- new= xcalloc(strlen(str)+1,sizeof(char));
- if (new)
- strcpy(new,str);
- return new;
-}
-
-/***====================================================================***/
-
-static void *
-XkmInsureSize(void *oldPtr,int oldCount,int *newCountRtrn,int elemSize)
-{
-int newCount= *newCountRtrn;
-
- if (oldPtr==NULL) {
- if (newCount==0)
- return NULL;
- oldPtr= xcalloc(newCount,elemSize);
- }
- else if (oldCount<newCount) {
- oldPtr= xrealloc(oldPtr,newCount*elemSize);
- if (oldPtr!=NULL) {
- char *tmp= (char *)oldPtr;
- bzero(&tmp[oldCount*elemSize],(newCount-oldCount)*elemSize);
- }
- }
- else if (newCount<oldCount) {
- *newCountRtrn= oldCount;
- }
- return oldPtr;
-}
-
-#define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t))))
-
-static CARD8
-XkmGetCARD8(FILE *file,int *pNRead)
-{
-int tmp;
- tmp= getc(file);
- if (pNRead&&(tmp!=EOF))
- (*pNRead)+= 1;
- return tmp;
-}
-
-static CARD16
-XkmGetCARD16(FILE *file,int *pNRead)
-{
-CARD16 val;
-
- if ((fread(&val,2,1,file)==1)&&(pNRead))
- (*pNRead)+= 2;
- return val;
-}
-
-static CARD32
-XkmGetCARD32(FILE *file,int *pNRead)
-{
-CARD32 val;
-
- if ((fread(&val,4,1,file)==1)&&(pNRead))
- (*pNRead)+= 4;
- return val;
-}
-
-static int
-XkmSkipPadding(FILE *file,unsigned pad)
-{
-register int i,nRead=0;
-
- for (i=0;i<pad;i++) {
- if (getc(file)!=EOF)
- nRead++;
- }
- return nRead;
-}
-
-static int
-XkmGetCountedString(FILE *file,char *str,int max_len)
-{
-int count,nRead=0;
-
- count= XkmGetCARD16(file,&nRead);
- if (count>0) {
- int tmp;
- if (count>max_len) {
- tmp= fread(str,1,max_len,file);
- while (tmp<count) {
- if ((getc(file))!=EOF)
- tmp++;
- else break;
- }
- }
- else {
- tmp= fread(str,1,count,file);
- }
- nRead+= tmp;
- }
- if (count>=max_len) str[max_len-1]= '\0';
- else str[count]= '\0';
- count= XkbPaddedSize(nRead)-nRead;
- if (count>0)
- nRead+= XkmSkipPadding(file,count);
- return nRead;
-}
-
-/***====================================================================***/
-
-static int
-ReadXkmVirtualMods(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
-{
-register unsigned int i,bit;
-unsigned int bound,named,tmp;
-int nRead=0;
-
- if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
- return -1;
- }
- bound= XkmGetCARD16(file,&nRead);
- named= XkmGetCARD16(file,&nRead);
- for (i=tmp=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (bound&bit) {
- xkb->server->vmods[i]= XkmGetCARD8(file,&nRead);
- if (changes)
- changes->map.vmods|= bit;
- tmp++;
- }
- }
- if ((i= XkbPaddedSize(tmp)-tmp)>0)
- nRead+= XkmSkipPadding(file,i);
- if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
- return -1;
- }
- for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- char name[100];
- if (named&bit) {
- if (nRead+=XkmGetCountedString(file,name,100)) {
- xkb->names->vmods[i]= XkbInternAtom(name,FALSE);
- if (changes)
- changes->names.changed_vmods|= bit;
- }
- }
- }
- return nRead;
-}
-
-/***====================================================================***/
-
-static int
-ReadXkmKeycodes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
-{
-register int i;
-unsigned minKC,maxKC,nAl;
-int nRead=0;
-char name[100];
-XkbKeyNamePtr pN;
-
- name[0]= '\0';
- nRead+= XkmGetCountedString(file,name,100);
- minKC= XkmGetCARD8(file,&nRead);
- maxKC= XkmGetCARD8(file,&nRead);
- if (xkb->min_key_code==0) {
- xkb->min_key_code= minKC;
- xkb->max_key_code= maxKC;
- }
- else {
- if (minKC<xkb->min_key_code)
- xkb->min_key_code= minKC;
- if (maxKC>xkb->max_key_code) {
- _XkbLibError(_XkbErrBadValue,"ReadXkmKeycodes",maxKC);
- return -1;
- }
- }
- nAl= XkmGetCARD8(file,&nRead);
- nRead+= XkmSkipPadding(file,1);
-
-#define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask)
- if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
- return -1;
- }
- if (name[0]!='\0') {
- xkb->names->keycodes= XkbInternAtom(name,FALSE);
- }
-
- for (pN=&xkb->names->keys[minKC],i=minKC;i<=(int)maxKC;i++,pN++) {
- if (fread(pN,1,XkbKeyNameLength,file)!=XkbKeyNameLength) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
- return -1;
- }
- nRead+= XkbKeyNameLength;
- }
- if (nAl>0) {
- XkbKeyAliasPtr pAl;
- for (pAl= xkb->names->key_aliases,i=0;i<nAl;i++,pAl++) {
- int tmp;
- tmp= fread(pAl,1,2*XkbKeyNameLength,file);
- if (tmp!=2*XkbKeyNameLength) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
- return -1;
- }
- nRead+= 2*XkbKeyNameLength;
- }
- if (changes)
- changes->names.changed|= XkbKeyAliasesMask;
- }
- if (changes)
- changes->names.changed|= XkbKeyNamesMask;
- return nRead;
-}
-
-/***====================================================================***/
-
-static int
-ReadXkmKeyTypes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
-{
-register unsigned i,n;
-unsigned num_types;
-int nRead=0;
-int tmp;
-XkbKeyTypePtr type;
-xkmKeyTypeDesc wire;
-XkbKTMapEntryPtr entry;
-xkmKTMapEntryDesc wire_entry;
-char buf[100];
-
- if ((tmp= XkmGetCountedString(file,buf,100))<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
- return -1;
- }
- nRead+= tmp;
- if (buf[0]!='\0') {
- if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
- return -1;
- }
- xkb->names->types= XkbInternAtom(buf,FALSE);
- }
- num_types= XkmGetCARD16(file,&nRead);
- nRead+= XkmSkipPadding(file,2);
- if (num_types<1)
- return nRead;
- if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
- return nRead;
- }
- xkb->map->num_types= num_types;
- if (num_types<XkbNumRequiredTypes) {
- _XkbLibError(_XkbErrMissingReqTypes,"ReadXkmKeyTypes",0);
- return -1;
- }
- type= xkb->map->types;
- for (i=0;i<num_types;i++,type++) {
- if ((int)fread(&wire,SIZEOF(xkmKeyTypeDesc),1,file)<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
- return -1;
- }
- nRead+= SIZEOF(xkmKeyTypeDesc);
- if (((i==XkbOneLevelIndex)&&(wire.numLevels!=1))||
- (((i==XkbTwoLevelIndex)||(i==XkbAlphabeticIndex)||
- ((i)==XkbKeypadIndex))&&(wire.numLevels!=2))) {
- _XkbLibError(_XkbErrBadTypeWidth,"ReadXkmKeyTypes",i);
- return -1;
- }
- tmp= wire.nMapEntries;
- XkmInsureTypedSize(type->map,type->map_count,&tmp,XkbKTMapEntryRec);
- if ((wire.nMapEntries>0)&&(type->map==NULL)) {
- _XkbLibError(_XkbErrBadValue,"ReadXkmKeyTypes",wire.nMapEntries);
- return -1;
- }
- for (n=0,entry= type->map;n<wire.nMapEntries;n++,entry++) {
- if (fread(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file)<(int)1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
- return -1;
- }
- nRead+= SIZEOF(xkmKTMapEntryDesc);
- entry->active= (wire_entry.virtualMods==0);
- entry->level= wire_entry.level;
- entry->mods.mask= wire_entry.realMods;
- entry->mods.real_mods= wire_entry.realMods;
- entry->mods.vmods= wire_entry.virtualMods;
- }
- nRead+= XkmGetCountedString(file,buf,100);
- if (((i==XkbOneLevelIndex)&&(strcmp(buf,"ONE_LEVEL")!=0))||
- ((i==XkbTwoLevelIndex)&&(strcmp(buf,"TWO_LEVEL")!=0))||
- ((i==XkbAlphabeticIndex)&&(strcmp(buf,"ALPHABETIC")!=0))||
- ((i==XkbKeypadIndex)&&(strcmp(buf,"KEYPAD")!=0))) {
- _XkbLibError(_XkbErrBadTypeName,"ReadXkmKeyTypes",0);
- return -1;
- }
- if (buf[0]!='\0') {
- type->name= XkbInternAtom(buf,FALSE);
- }
- else type->name= None;
-
- if (wire.preserve) {
- xkmModsDesc p_entry;
- XkbModsPtr pre;
- XkmInsureTypedSize(type->preserve,type->map_count,&tmp,
- XkbModsRec);
- if (type->preserve==NULL) {
- _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
- return -1;
- }
- for (n=0,pre=type->preserve;n<wire.nMapEntries;n++,pre++) {
- if (fread(&p_entry,SIZEOF(xkmModsDesc),1,file)<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
- return -1;
- }
- nRead+= SIZEOF(xkmModsDesc);
- pre->mask= p_entry.realMods;
- pre->real_mods= p_entry.realMods;
- pre->vmods= p_entry.virtualMods;
- }
- }
- if (wire.nLevelNames>0) {
- int width= wire.numLevels;
- if (wire.nLevelNames>(unsigned)width) {
- _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
- return -1;
- }
- XkmInsureTypedSize(type->level_names,type->num_levels,&width,Atom);
- if (type->level_names!=NULL) {
- for (n=0;n<wire.nLevelNames;n++) {
- if ((tmp=XkmGetCountedString(file,buf,100))<1)
- return -1;
- nRead+= tmp;
- if (strlen(buf)==0)
- type->level_names[n]= None;
- else type->level_names[n]= XkbInternAtom(buf,0);
- }
- }
- }
- type->mods.mask= wire.realMods;
- type->mods.real_mods= wire.realMods;
- type->mods.vmods= wire.virtualMods;
- type->num_levels= wire.numLevels;
- type->map_count= wire.nMapEntries;
- }
- if (changes) {
- changes->map.changed|= XkbKeyTypesMask;
- changes->map.first_type= 0;
- changes->map.num_types= xkb->map->num_types;
- }
- return nRead;
-}
-
-/***====================================================================***/
-
-static int
-ReadXkmCompatMap(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
-{
-register int i;
-unsigned num_si,groups;
-char name[100];
-XkbSymInterpretPtr interp;
-xkmSymInterpretDesc wire;
-unsigned tmp;
-int nRead=0;
-XkbCompatMapPtr compat;
-XkbAction *act;
-
- if ((tmp= XkmGetCountedString(file,name,100))<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0);
- return -1;
- }
- nRead+= tmp;
- if (name[0]!='\0') {
- if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0);
- return -1;
- }
- xkb->names->compat= XkbInternAtom(name,FALSE);
- }
- num_si= XkmGetCARD16(file,&nRead);
- groups= XkmGetCARD8(file,&nRead);
- nRead+= XkmSkipPadding(file,1);
- if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success)
- return -1;
- compat= xkb->compat;
- compat->num_si= num_si;
- interp= compat->sym_interpret;
- for (i=0;i<num_si;i++,interp++) {
- tmp= fread(&wire,SIZEOF(xkmSymInterpretDesc),1,file);
- nRead+= tmp*SIZEOF(xkmSymInterpretDesc);
- interp->sym= wire.sym;
- interp->mods= wire.mods;
- interp->match= wire.match;
- interp->virtual_mod= wire.virtualMod;
- interp->flags= wire.flags;
- interp->act.type= wire.actionType;
- act = (XkbAction *) &interp->act;
-
- switch (interp->act.type) {
- case XkbSA_SetMods:
- case XkbSA_LatchMods:
- case XkbSA_LockMods:
- act->mods.flags = wire.actionData[0];
- act->mods.mask = wire.actionData[1];
- act->mods.real_mods = wire.actionData[2];
- act->mods.vmods1 = wire.actionData[3];
- act->mods.vmods2 = wire.actionData[4];
- break;
- case XkbSA_SetGroup:
- case XkbSA_LatchGroup:
- case XkbSA_LockGroup:
- act->group.flags = wire.actionData[0];
- act->group.group_XXX = wire.actionData[1];
- break;
- case XkbSA_MovePtr:
- act->ptr.flags = wire.actionData[0];
- act->ptr.high_XXX = wire.actionData[1];
- act->ptr.low_XXX = wire.actionData[2];
- act->ptr.high_YYY = wire.actionData[3];
- act->ptr.low_YYY = wire.actionData[4];
- break;
- case XkbSA_PtrBtn:
- case XkbSA_LockPtrBtn:
- act->btn.flags = wire.actionData[0];
- act->btn.count = wire.actionData[1];
- act->btn.button = wire.actionData[2];
- break;
- case XkbSA_DeviceBtn:
- case XkbSA_LockDeviceBtn:
- act->devbtn.flags = wire.actionData[0];
- act->devbtn.count = wire.actionData[1];
- act->devbtn.button = wire.actionData[2];
- act->devbtn.device = wire.actionData[3];
- break;
- case XkbSA_SetPtrDflt:
- act->dflt.flags = wire.actionData[0];
- act->dflt.affect = wire.actionData[1];
- act->dflt.valueXXX = wire.actionData[2];
- break;
- case XkbSA_ISOLock:
- act->iso.flags = wire.actionData[0];
- act->iso.mask = wire.actionData[1];
- act->iso.real_mods = wire.actionData[2];
- act->iso.group_XXX = wire.actionData[3];
- act->iso.affect = wire.actionData[4];
- act->iso.vmods1 = wire.actionData[5];
- act->iso.vmods2 = wire.actionData[6];
- break;
- case XkbSA_SwitchScreen:
- act->screen.flags = wire.actionData[0];
- act->screen.screenXXX = wire.actionData[1];
- break;
- case XkbSA_SetControls:
- case XkbSA_LockControls:
- act->ctrls.flags = wire.actionData[0];
- act->ctrls.ctrls3 = wire.actionData[1];
- act->ctrls.ctrls2 = wire.actionData[2];
- act->ctrls.ctrls1 = wire.actionData[3];
- act->ctrls.ctrls0 = wire.actionData[4];
- break;
- case XkbSA_RedirectKey:
- act->redirect.new_key = wire.actionData[0];
- act->redirect.mods_mask = wire.actionData[1];
- act->redirect.mods = wire.actionData[2];
- act->redirect.vmods_mask0 = wire.actionData[3];
- act->redirect.vmods_mask1 = wire.actionData[4];
- act->redirect.vmods0 = wire.actionData[4];
- act->redirect.vmods1 = wire.actionData[5];
- break;
- case XkbSA_DeviceValuator:
- act->devval.device = wire.actionData[0];
- act->devval.v1_what = wire.actionData[1];
- act->devval.v1_ndx = wire.actionData[2];
- act->devval.v1_value = wire.actionData[3];
- act->devval.v2_what = wire.actionData[4];
- act->devval.v2_ndx = wire.actionData[5];
- act->devval.v2_what = wire.actionData[6];
- break;
-
- case XkbSA_XFree86Private:
- /* copy the kind of action */
- strncpy((char*)act->any.data, (char*)wire.actionData,
- XkbAnyActionDataSize);
- break ;
-
- case XkbSA_Terminate:
- /* no args, kinda (note: untrue for xfree86). */
- break;
- case XkbSA_ActionMessage:
- /* unsupported. */
- break;
- }
- }
- if ((num_si>0)&&(changes)) {
- changes->compat.first_si= 0;
- changes->compat.num_si= num_si;
- }
- if (groups) {
- register unsigned bit;
- for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
- xkmModsDesc md;
- if (groups&bit) {
- tmp= fread(&md,SIZEOF(xkmModsDesc),1,file);
- nRead+= tmp*SIZEOF(xkmModsDesc);
- xkb->compat->groups[i].real_mods= md.realMods;
- xkb->compat->groups[i].vmods= md.virtualMods;
- if (md.virtualMods != 0) {
- unsigned mask;
- if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask))
- xkb->compat->groups[i].mask= md.realMods|mask;
- }
- else xkb->compat->groups[i].mask= md.realMods;
- }
- }
- if (changes)
- changes->compat.changed_groups|= groups;
- }
- return nRead;
-}
-
-static int
-ReadXkmIndicators(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
-{
-register unsigned nLEDs;
-xkmIndicatorMapDesc wire;
-char buf[100];
-unsigned tmp;
-int nRead=0;
-
- if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) {
- _XkbLibError(_XkbErrBadAlloc,"indicator rec",0);
- return -1;
- }
- if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"indicator names",0);
- return -1;
- }
- nLEDs= XkmGetCARD8(file,&nRead);
- nRead+= XkmSkipPadding(file,3);
- xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead);
- while (nLEDs-->0) {
- Atom name;
- XkbIndicatorMapPtr map;
-
- if ((tmp=XkmGetCountedString(file,buf,100))<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
- return -1;
- }
- nRead+= tmp;
- if (buf[0]!='\0')
- name= XkbInternAtom(buf,FALSE);
- else name= None;
- if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
- return -1;
- }
- nRead+= tmp*SIZEOF(xkmIndicatorMapDesc);
- if (xkb->names) {
- xkb->names->indicators[wire.indicator-1]= name;
- if (changes)
- changes->names.changed_indicators|= (1<<(wire.indicator-1));
- }
- map= &xkb->indicators->maps[wire.indicator-1];
- map->flags= wire.flags;
- map->which_groups= wire.which_groups;
- map->groups= wire.groups;
- map->which_mods= wire.which_mods;
- map->mods.mask= wire.real_mods;
- map->mods.real_mods= wire.real_mods;
- map->mods.vmods= wire.vmods;
- map->ctrls= wire.ctrls;
- }
- return nRead;
-}
-
-static XkbKeyTypePtr
-FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms)
-{
- if ((!xkb)||(!xkb->map))
- return NULL;
- if (name!=None) {
- register unsigned i;
- for (i=0;i<xkb->map->num_types;i++) {
- if (xkb->map->types[i].name==name) {
- if (xkb->map->types[i].num_levels!=width)
- DebugF("Group width mismatch between key and type\n");
- return &xkb->map->types[i];
- }
- }
- }
- if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol)))
- return &xkb->map->types[XkbOneLevelIndex];
- if (syms!=NULL) {
- if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1]))
- return &xkb->map->types[XkbAlphabeticIndex];
- else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1]))
- return &xkb->map->types[XkbKeypadIndex];
- }
- return &xkb->map->types[XkbTwoLevelIndex];
-}
-
-static int
-ReadXkmSymbols(FILE *file,XkbDescPtr xkb)
-{
-register int i,g,s,totalVModMaps;
-xkmKeySymMapDesc wireMap;
-char buf[100];
-unsigned minKC,maxKC,groupNames,tmp;
-int nRead=0;
-
- if ((tmp=XkmGetCountedString(file,buf,100))<1)
- return -1;
- nRead+= tmp;
- minKC= XkmGetCARD8(file,&nRead);
- maxKC= XkmGetCARD8(file,&nRead);
- groupNames= XkmGetCARD8(file,&nRead);
- totalVModMaps= XkmGetCARD8(file,&nRead);
- if (XkbAllocNames(xkb,
- XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask,
- 0,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"physical names",0);
- return -1;
- }
- if ((buf[0]!='\0')&&(xkb->names)) {
- Atom name;
- name= XkbInternAtom(buf,0);
- xkb->names->symbols= name;
- xkb->names->phys_symbols= name;
- }
- for (i=0,g=1;i<XkbNumKbdGroups;i++,g<<=1) {
- if (groupNames&g) {
- if ((tmp=XkmGetCountedString(file,buf,100))<1)
- return -1;
- nRead+= tmp;
- if ((buf[0]!='\0')&&(xkb->names)) {
- Atom name;
- name= XkbInternAtom(buf,0);
- xkb->names->groups[i]= name;
- }
- else xkb->names->groups[i]= None;
- }
- }
- if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"server map",0);
- return -1;
- }
- if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"client map",0);
- return -1;
- }
- if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"controls",0);
- return -1;
- }
- if ((xkb->map==NULL)||(xkb->server==NULL))
- return -1;
- if (xkb->min_key_code<8) xkb->min_key_code= minKC;
- if (xkb->max_key_code<8) xkb->max_key_code= maxKC;
- if ((minKC>=8)&&(minKC<xkb->min_key_code))
- xkb->min_key_code= minKC;
- if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) {
- _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC);
- return -1;
- }
- for (i=minKC;i<=(int)maxKC;i++) {
- Atom typeName[XkbNumKbdGroups];
- XkbKeyTypePtr type[XkbNumKbdGroups];
- if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0);
- return -1;
- }
- nRead+= tmp*SIZEOF(xkmKeySymMapDesc);
- bzero((char *)typeName,XkbNumKbdGroups*sizeof(Atom));
- bzero((char *)type,XkbNumKbdGroups*sizeof(XkbKeyTypePtr));
- if (wireMap.flags&XkmKeyHasTypes) {
- register int g;
- for (g=0;g<XkbNumKbdGroups;g++) {
- if ((wireMap.flags&(1<<g))&&
- ((tmp=XkmGetCountedString(file,buf,100))>0)) {
- typeName[g]= XkbInternAtom(buf,1);
- nRead+= tmp;
- }
- type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL);
- if (type[g]==NULL) {
- _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0);
- return -1;
- }
- if (typeName[g]==type[g]->name)
- xkb->server->explicit[i]|= (1<<g);
- }
- }
- if (wireMap.flags&XkmRepeatingKey) {
- xkb->ctrls->per_key_repeat[i/8]|= (1<<(i%8));
- xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
- }
- else if (wireMap.flags&XkmNonRepeatingKey) {
- xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8));
- xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
- }
- xkb->map->modmap[i]= wireMap.modifier_map;
- if (XkbNumGroups(wireMap.num_groups)>0) {
- KeySym *sym;
- int nSyms;
-
- if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups)
- xkb->ctrls->num_groups= wireMap.num_groups;
- nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width;
- sym= XkbResizeKeySyms(xkb,i,nSyms);
- if (!sym)
- return -1;
- for (s=0;s<nSyms;s++) {
- *sym++= XkmGetCARD32(file,&nRead);
- }
- if (wireMap.flags&XkmKeyHasActions) {
- XkbAction * act;
- act= XkbResizeKeyActions(xkb,i,nSyms);
- for (s=0;s<nSyms;s++,act++) {
- tmp=fread(act,SIZEOF(xkmActionDesc),1,file);
- nRead+= tmp*SIZEOF(xkmActionDesc);
- }
- xkb->server->explicit[i]|= XkbExplicitInterpretMask;
- }
- }
- for (g=0;g<XkbNumGroups(wireMap.num_groups);g++) {
- if (((xkb->server->explicit[i]&(1<<g))==0)||(type[g]==NULL)) {
- KeySym *tmpSyms;
- tmpSyms= XkbKeySymsPtr(xkb,i)+(wireMap.width*g);
- type[g]= FindTypeForKey(xkb,None,wireMap.width,tmpSyms);
- }
- xkb->map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]);
- }
- xkb->map->key_sym_map[i].group_info= wireMap.num_groups;
- xkb->map->key_sym_map[i].width= wireMap.width;
- if (wireMap.flags&XkmKeyHasBehavior) {
- xkmBehaviorDesc b;
- tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file);
- nRead+= tmp*SIZEOF(xkmBehaviorDesc);
- xkb->server->behaviors[i].type= b.type;
- xkb->server->behaviors[i].data= b.data;
- xkb->server->explicit[i]|= XkbExplicitBehaviorMask;
- }
- }
- if (totalVModMaps>0) {
- xkmVModMapDesc v;
- for (i=0;i<totalVModMaps;i++) {
- tmp= fread(&v,SIZEOF(xkmVModMapDesc),1,file);
- nRead+= tmp*SIZEOF(xkmVModMapDesc);
- if (tmp>0)
- xkb->server->vmodmap[v.key]= v.vmods;
- }
- }
- return nRead;
-}
-
-static int
-ReadXkmGeomDoodad(
- FILE * file,
- XkbGeometryPtr geom,
- XkbSectionPtr section)
-{
-XkbDoodadPtr doodad;
-xkmDoodadDesc doodadWire;
-char buf[100];
-unsigned tmp;
-int nRead=0;
-
- nRead+= XkmGetCountedString(file,buf,100);
- tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file);
- nRead+= SIZEOF(xkmDoodadDesc)*tmp;
- doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(buf,FALSE));
- if (!doodad)
- return nRead;
- doodad->any.type= doodadWire.any.type;
- doodad->any.priority= doodadWire.any.priority;
- doodad->any.top= doodadWire.any.top;
- doodad->any.left= doodadWire.any.left;
- switch (doodadWire.any.type) {
- case XkbOutlineDoodad:
- case XkbSolidDoodad:
- doodad->shape.angle= doodadWire.shape.angle;
- doodad->shape.color_ndx= doodadWire.shape.color_ndx;
- doodad->shape.shape_ndx= doodadWire.shape.shape_ndx;
- break;
- case XkbTextDoodad:
- doodad->text.angle= doodadWire.text.angle;
- doodad->text.width= doodadWire.text.width;
- doodad->text.height= doodadWire.text.height;
- doodad->text.color_ndx= doodadWire.text.color_ndx;
- nRead+= XkmGetCountedString(file,buf,100);
- doodad->text.text= _XkbDupString(buf);
- nRead+= XkmGetCountedString(file,buf,100);
- doodad->text.font= _XkbDupString(buf);
- break;
- case XkbIndicatorDoodad:
- doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx;
- doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx;
- doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx;
- break;
- case XkbLogoDoodad:
- doodad->logo.angle= doodadWire.logo.angle;
- doodad->logo.color_ndx= doodadWire.logo.color_ndx;
- doodad->logo.shape_ndx= doodadWire.logo.shape_ndx;
- nRead+= XkmGetCountedString(file,buf,100);
- doodad->logo.logo_name= _XkbDupString(buf);
- break;
- default:
- /* report error? */
- return nRead;
- }
- return nRead;
-}
-
-static int
-ReadXkmGeomOverlay( FILE * file,
- XkbGeometryPtr geom,
- XkbSectionPtr section)
-{
-char buf[100];
-unsigned tmp;
-int nRead=0;
-XkbOverlayPtr ol;
-XkbOverlayRowPtr row;
-xkmOverlayDesc olWire;
-xkmOverlayRowDesc rowWire;
-register int r;
-
- nRead+= XkmGetCountedString(file,buf,100);
- tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file);
- nRead+= tmp*SIZEOF(xkmOverlayDesc);
- ol= XkbAddGeomOverlay(section,XkbInternAtom(buf,FALSE),
- olWire.num_rows);
- if (!ol)
- return nRead;
- for (r=0;r<olWire.num_rows;r++) {
- int k;
- xkmOverlayKeyDesc keyWire;
- tmp= fread(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file);
- nRead+= tmp*SIZEOF(xkmOverlayRowDesc);
- row= XkbAddGeomOverlayRow(ol,rowWire.row_under,rowWire.num_keys);
- if (!row) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomOverlay",0);
- return nRead;
- }
- for (k=0;k<rowWire.num_keys;k++) {
- tmp= fread(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file);
- nRead+= tmp*SIZEOF(xkmOverlayKeyDesc);
- memcpy(row->keys[k].over.name,keyWire.over,XkbKeyNameLength);
- memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength);
- }
- row->num_keys= rowWire.num_keys;
- }
- return nRead;
-}
-
-static int
-ReadXkmGeomSection( FILE * file,
- XkbGeometryPtr geom)
-{
-register int i;
-XkbSectionPtr section;
-xkmSectionDesc sectionWire;
-unsigned tmp;
-int nRead= 0;
-char buf[100];
-Atom nameAtom;
-
- nRead+= XkmGetCountedString(file,buf,100);
- nameAtom= XkbInternAtom(buf,FALSE);
- tmp= fread(&sectionWire,SIZEOF(xkmSectionDesc),1,file);
- nRead+= SIZEOF(xkmSectionDesc)*tmp;
- section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows,
- sectionWire.num_doodads,
- sectionWire.num_overlays);
- if (!section) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
- return nRead;
- }
- section->top= sectionWire.top;
- section->left= sectionWire.left;
- section->width= sectionWire.width;
- section->height= sectionWire.height;
- section->angle= sectionWire.angle;
- section->priority= sectionWire.priority;
- if (sectionWire.num_rows>0) {
- register int k;
- XkbRowPtr row;
- xkmRowDesc rowWire;
- XkbKeyPtr key;
- xkmKeyDesc keyWire;
-
- for (i=0;i<sectionWire.num_rows;i++) {
- tmp= fread(&rowWire,SIZEOF(xkmRowDesc),1,file);
- nRead+= SIZEOF(xkmRowDesc)*tmp;
- row= XkbAddGeomRow(section,rowWire.num_keys);
- if (!row) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
- return nRead;
- }
- row->top= rowWire.top;
- row->left= rowWire.left;
- row->vertical= rowWire.vertical;
- for (k=0;k<rowWire.num_keys;k++) {
- tmp= fread(&keyWire,SIZEOF(xkmKeyDesc),1,file);
- nRead+= SIZEOF(xkmKeyDesc)*tmp;
- key= XkbAddGeomKey(row);
- if (!key) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
- return nRead;
- }
- memcpy(key->name.name,keyWire.name,XkbKeyNameLength);
- key->gap= keyWire.gap;
- key->shape_ndx= keyWire.shape_ndx;
- key->color_ndx= keyWire.color_ndx;
- }
- }
- }
- if (sectionWire.num_doodads>0) {
- for (i=0;i<sectionWire.num_doodads;i++) {
- tmp= ReadXkmGeomDoodad(file,geom,section);
- nRead+= tmp;
- if (tmp<1)
- return nRead;
- }
- }
- if (sectionWire.num_overlays>0) {
- for (i=0;i<sectionWire.num_overlays;i++) {
- tmp= ReadXkmGeomOverlay(file,geom,section);
- nRead+= tmp;
- if (tmp<1)
- return nRead;
- }
- }
- return nRead;
-}
-
-static int
-ReadXkmGeometry(FILE *file,XkbDescPtr xkb)
-{
-register int i;
-char buf[100];
-unsigned tmp;
-int nRead= 0;
-xkmGeometryDesc wireGeom;
-XkbGeometryPtr geom;
-XkbGeometrySizesRec sizes;
-
- nRead+= XkmGetCountedString(file,buf,100);
- tmp= fread(&wireGeom,SIZEOF(xkmGeometryDesc),1,file);
- nRead+= tmp*SIZEOF(xkmGeometryDesc);
- sizes.which= XkbGeomAllMask;
- sizes.num_properties= wireGeom.num_properties;
- sizes.num_colors= wireGeom.num_colors;
- sizes.num_shapes= wireGeom.num_shapes;
- sizes.num_sections= wireGeom.num_sections;
- sizes.num_doodads= wireGeom.num_doodads;
- sizes.num_key_aliases= wireGeom.num_key_aliases;
- if (XkbAllocGeometry(xkb,&sizes)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
- return nRead;
- }
- geom= xkb->geom;
- geom->name= XkbInternAtom(buf,FALSE);
- geom->width_mm= wireGeom.width_mm;
- geom->height_mm= wireGeom.height_mm;
- nRead+= XkmGetCountedString(file,buf,100);
- geom->label_font= _XkbDupString(buf);
- if (wireGeom.num_properties>0) {
- char val[1024];
- for (i=0;i<wireGeom.num_properties;i++) {
- nRead+= XkmGetCountedString(file,buf,100);
- nRead+= XkmGetCountedString(file,val,1024);
- if (XkbAddGeomProperty(geom,buf,val)==NULL) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
- return nRead;
- }
- }
- }
- if (wireGeom.num_colors>0) {
- for (i=0;i<wireGeom.num_colors;i++) {
- nRead+= XkmGetCountedString(file,buf,100);
- if (XkbAddGeomColor(geom,buf,i)==NULL) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
- return nRead;
- }
- }
- }
- geom->base_color= &geom->colors[wireGeom.base_color_ndx];
- geom->label_color= &geom->colors[wireGeom.label_color_ndx];
- if (wireGeom.num_shapes>0) {
- XkbShapePtr shape;
- xkmShapeDesc shapeWire;
- Atom nameAtom;
- for (i=0;i<wireGeom.num_shapes;i++) {
- register int n;
- XkbOutlinePtr ol;
- xkmOutlineDesc olWire;
- nRead+= XkmGetCountedString(file,buf,100);
- nameAtom= XkbInternAtom(buf,FALSE);
- tmp= fread(&shapeWire,SIZEOF(xkmShapeDesc),1,file);
- nRead+= tmp*SIZEOF(xkmShapeDesc);
- shape= XkbAddGeomShape(geom,nameAtom,shapeWire.num_outlines);
- if (!shape) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
- return nRead;
- }
- for (n=0;n<shapeWire.num_outlines;n++) {
- register int p;
- xkmPointDesc ptWire;
- tmp= fread(&olWire,SIZEOF(xkmOutlineDesc),1,file);
- nRead+= tmp*SIZEOF(xkmOutlineDesc);
- ol= XkbAddGeomOutline(shape,olWire.num_points);
- if (!ol) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
- return nRead;
- }
- ol->num_points= olWire.num_points;
- ol->corner_radius= olWire.corner_radius;
- for (p=0;p<olWire.num_points;p++) {
- tmp= fread(&ptWire,SIZEOF(xkmPointDesc),1,file);
- nRead+= tmp*SIZEOF(xkmPointDesc);
- ol->points[p].x= ptWire.x;
- ol->points[p].y= ptWire.y;
- if (ptWire.x<shape->bounds.x1) shape->bounds.x1= ptWire.x;
- if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x;
- if (ptWire.y<shape->bounds.y1) shape->bounds.y1= ptWire.y;
- if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y;
- }
- }
- if (shapeWire.primary_ndx!=XkbNoShape)
- shape->primary= &shape->outlines[shapeWire.primary_ndx];
- if (shapeWire.approx_ndx!=XkbNoShape)
- shape->approx= &shape->outlines[shapeWire.approx_ndx];
- }
- }
- if (wireGeom.num_sections>0) {
- for (i=0;i<wireGeom.num_sections;i++) {
- tmp= ReadXkmGeomSection(file,geom);
- nRead+= tmp;
- if (tmp==0)
- return nRead;
- }
- }
- if (wireGeom.num_doodads>0) {
- for (i=0;i<wireGeom.num_doodads;i++) {
- tmp= ReadXkmGeomDoodad(file,geom,NULL);
- nRead+= tmp;
- if (tmp==0)
- return nRead;
- }
- }
- if ((wireGeom.num_key_aliases>0)&&(geom->key_aliases)) {
- int sz= XkbKeyNameLength*2;
- int num= wireGeom.num_key_aliases;
- if (fread(geom->key_aliases,sz,num,file)!=num) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0);
- return -1;
- }
- nRead+= (num*sz);
- geom->num_key_aliases= num;
- }
- return nRead;
-}
-
-Bool
-XkmProbe(FILE *file)
-{
-unsigned hdr,tmp;
-int nRead=0;
-
- hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
- tmp= XkmGetCARD32(file,&nRead);
- if (tmp!=hdr) {
- if ((tmp&(~0xff))==(hdr&(~0xff))) {
- _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff);
- }
- return 0;
- }
- return 1;
-}
-
-static Bool
-XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc)
-{
-unsigned hdr,tmp;
-int nRead=0;
-unsigned i,size_toc;
-
- hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
- tmp= XkmGetCARD32(file,&nRead);
- if (tmp!=hdr) {
- if ((tmp&(~0xff))==(hdr&(~0xff))) {
- _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff);
- }
- else {
- _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp);
- }
- return 0;
- }
- fread(file_info,SIZEOF(xkmFileInfo),1,file);
- size_toc= file_info->num_toc;
- if (size_toc>max_toc) {
- DebugF("Warning! Too many TOC entries; last %d ignored\n",
- size_toc-max_toc);
- size_toc= max_toc;
- }
- for (i=0;i<size_toc;i++) {
- fread(&toc[i],SIZEOF(xkmSectionInfo),1,file);
- }
- return 1;
-}
-
-/***====================================================================***/
-
-#define MAX_TOC 16
-unsigned
-XkmReadFile(FILE *file,unsigned need,unsigned want,XkbDescPtr *xkb)
-{
-register unsigned i;
-xkmSectionInfo toc[MAX_TOC],tmpTOC;
-xkmFileInfo fileInfo;
-unsigned tmp,nRead=0;
-unsigned which= need|want;
-
- if (!XkmReadTOC(file,&fileInfo,MAX_TOC,toc))
- return which;
- if ((fileInfo.present&need)!=need) {
- _XkbLibError(_XkbErrIllegalContents,"XkmReadFile",
- need&(~fileInfo.present));
- return which;
- }
- if (*xkb==NULL)
- *xkb= XkbAllocKeyboard();
- for (i=0;i<fileInfo.num_toc;i++) {
- fseek(file,toc[i].offset,SEEK_SET);
- tmp= fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file);
- nRead= tmp*SIZEOF(xkmSectionInfo);
- if ((tmpTOC.type!=toc[i].type)||(tmpTOC.format!=toc[i].format)||
- (tmpTOC.size!=toc[i].size)||(tmpTOC.offset!=toc[i].offset)) {
- return which;
- }
- if ((which&(1<<tmpTOC.type))==0) {
- continue;
- }
- switch (tmpTOC.type) {
- case XkmVirtualModsIndex:
- tmp= ReadXkmVirtualMods(file,*xkb,NULL);
- break;
- case XkmTypesIndex:
- tmp= ReadXkmKeyTypes(file,*xkb,NULL);
- break;
- case XkmCompatMapIndex:
- tmp= ReadXkmCompatMap(file,*xkb,NULL);
- break;
- case XkmKeyNamesIndex:
- tmp= ReadXkmKeycodes(file,*xkb,NULL);
- break;
- case XkmIndicatorsIndex:
- tmp= ReadXkmIndicators(file,*xkb,NULL);
- break;
- case XkmSymbolsIndex:
- tmp= ReadXkmSymbols(file,*xkb);
- break;
- case XkmGeometryIndex:
- tmp= ReadXkmGeometry(file,*xkb);
- break;
- default:
- _XkbLibError(_XkbErrBadImplementation,
- XkbConfigText(tmpTOC.type,XkbMessage),0);
- tmp= 0;
- break;
- }
- if (tmp>0) {
- nRead+= tmp;
- which&= ~(1<<toc[i].type);
- (*xkb)->defined|= (1<<toc[i].type);
- }
- if (nRead!=tmpTOC.size) {
- _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage),
- nRead-tmpTOC.size);
- }
- }
- return which;
-}
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation, and that the name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+
+#include <X11/Xos.h>
+#include <X11/Xfuncs.h>
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XKMformat.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "xkbstr.h"
+#include "xkbsrv.h"
+#include "xkbgeom.h"
+
+Atom
+XkbInternAtom(char *str,Bool only_if_exists)
+{
+ if (str==NULL)
+ return None;
+ return MakeAtom(str,strlen(str),!only_if_exists);
+}
+
+char *
+_XkbDupString(const char *str)
+{
+char *new;
+
+ if (str==NULL)
+ return NULL;
+ new= calloc(strlen(str)+1,sizeof(char));
+ if (new)
+ strcpy(new,str);
+ return new;
+}
+
+/***====================================================================***/
+
+static void *
+XkmInsureSize(void *oldPtr,int oldCount,int *newCountRtrn,int elemSize)
+{
+int newCount= *newCountRtrn;
+
+ if (oldPtr==NULL) {
+ if (newCount==0)
+ return NULL;
+ oldPtr= calloc(newCount,elemSize);
+ }
+ else if (oldCount<newCount) {
+ oldPtr= realloc(oldPtr,newCount*elemSize);
+ if (oldPtr!=NULL) {
+ char *tmp= (char *)oldPtr;
+ bzero(&tmp[oldCount*elemSize],(newCount-oldCount)*elemSize);
+ }
+ }
+ else if (newCount<oldCount) {
+ *newCountRtrn= oldCount;
+ }
+ return oldPtr;
+}
+
+#define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t))))
+
+static CARD8
+XkmGetCARD8(FILE *file,int *pNRead)
+{
+int tmp;
+ tmp= getc(file);
+ if (pNRead&&(tmp!=EOF))
+ (*pNRead)+= 1;
+ return tmp;
+}
+
+static CARD16
+XkmGetCARD16(FILE *file,int *pNRead)
+{
+CARD16 val;
+
+ if ((fread(&val,2,1,file)==1)&&(pNRead))
+ (*pNRead)+= 2;
+ return val;
+}
+
+static CARD32
+XkmGetCARD32(FILE *file,int *pNRead)
+{
+CARD32 val;
+
+ if ((fread(&val,4,1,file)==1)&&(pNRead))
+ (*pNRead)+= 4;
+ return val;
+}
+
+static int
+XkmSkipPadding(FILE *file,unsigned pad)
+{
+register int i,nRead=0;
+
+ for (i=0;i<pad;i++) {
+ if (getc(file)!=EOF)
+ nRead++;
+ }
+ return nRead;
+}
+
+static int
+XkmGetCountedString(FILE *file,char *str,int max_len)
+{
+int count,nRead=0;
+
+ count= XkmGetCARD16(file,&nRead);
+ if (count>0) {
+ int tmp;
+ if (count>max_len) {
+ tmp= fread(str,1,max_len,file);
+ while (tmp<count) {
+ if ((getc(file))!=EOF)
+ tmp++;
+ else break;
+ }
+ }
+ else {
+ tmp= fread(str,1,count,file);
+ }
+ nRead+= tmp;
+ }
+ if (count>=max_len) str[max_len-1]= '\0';
+ else str[count]= '\0';
+ count= XkbPaddedSize(nRead)-nRead;
+ if (count>0)
+ nRead+= XkmSkipPadding(file,count);
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmVirtualMods(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
+{
+register unsigned int i,bit;
+unsigned int bound,named,tmp;
+int nRead=0;
+
+ if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
+ return -1;
+ }
+ bound= XkmGetCARD16(file,&nRead);
+ named= XkmGetCARD16(file,&nRead);
+ for (i=tmp=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (bound&bit) {
+ xkb->server->vmods[i]= XkmGetCARD8(file,&nRead);
+ if (changes)
+ changes->map.vmods|= bit;
+ tmp++;
+ }
+ }
+ if ((i= XkbPaddedSize(tmp)-tmp)>0)
+ nRead+= XkmSkipPadding(file,i);
+ if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
+ return -1;
+ }
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ char name[100];
+ if (named&bit) {
+ if (nRead+=XkmGetCountedString(file,name,100)) {
+ xkb->names->vmods[i]= XkbInternAtom(name,FALSE);
+ if (changes)
+ changes->names.changed_vmods|= bit;
+ }
+ }
+ }
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmKeycodes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
+{
+register int i;
+unsigned minKC,maxKC,nAl;
+int nRead=0;
+char name[100];
+XkbKeyNamePtr pN;
+
+ name[0]= '\0';
+ nRead+= XkmGetCountedString(file,name,100);
+ minKC= XkmGetCARD8(file,&nRead);
+ maxKC= XkmGetCARD8(file,&nRead);
+ if (xkb->min_key_code==0) {
+ xkb->min_key_code= minKC;
+ xkb->max_key_code= maxKC;
+ }
+ else {
+ if (minKC<xkb->min_key_code)
+ xkb->min_key_code= minKC;
+ if (maxKC>xkb->max_key_code) {
+ _XkbLibError(_XkbErrBadValue,"ReadXkmKeycodes",maxKC);
+ return -1;
+ }
+ }
+ nAl= XkmGetCARD8(file,&nRead);
+ nRead+= XkmSkipPadding(file,1);
+
+#define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask)
+ if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ if (name[0]!='\0') {
+ xkb->names->keycodes= XkbInternAtom(name,FALSE);
+ }
+
+ for (pN=&xkb->names->keys[minKC],i=minKC;i<=(int)maxKC;i++,pN++) {
+ if (fread(pN,1,XkbKeyNameLength,file)!=XkbKeyNameLength) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ nRead+= XkbKeyNameLength;
+ }
+ if (nAl>0) {
+ XkbKeyAliasPtr pAl;
+ for (pAl= xkb->names->key_aliases,i=0;i<nAl;i++,pAl++) {
+ int tmp;
+ tmp= fread(pAl,1,2*XkbKeyNameLength,file);
+ if (tmp!=2*XkbKeyNameLength) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ nRead+= 2*XkbKeyNameLength;
+ }
+ if (changes)
+ changes->names.changed|= XkbKeyAliasesMask;
+ }
+ if (changes)
+ changes->names.changed|= XkbKeyNamesMask;
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmKeyTypes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
+{
+register unsigned i,n;
+unsigned num_types;
+int nRead=0;
+int tmp;
+XkbKeyTypePtr type;
+xkmKeyTypeDesc wire;
+XkbKTMapEntryPtr entry;
+xkmKTMapEntryDesc wire_entry;
+char buf[100];
+
+ if ((tmp= XkmGetCountedString(file,buf,100))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ nRead+= tmp;
+ if (buf[0]!='\0') {
+ if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ xkb->names->types= XkbInternAtom(buf,FALSE);
+ }
+ num_types= XkmGetCARD16(file,&nRead);
+ nRead+= XkmSkipPadding(file,2);
+ if (num_types<1)
+ return nRead;
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
+ return nRead;
+ }
+ xkb->map->num_types= num_types;
+ if (num_types<XkbNumRequiredTypes) {
+ _XkbLibError(_XkbErrMissingReqTypes,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ type= xkb->map->types;
+ for (i=0;i<num_types;i++,type++) {
+ if ((int)fread(&wire,SIZEOF(xkmKeyTypeDesc),1,file)<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ nRead+= SIZEOF(xkmKeyTypeDesc);
+ if (((i==XkbOneLevelIndex)&&(wire.numLevels!=1))||
+ (((i==XkbTwoLevelIndex)||(i==XkbAlphabeticIndex)||
+ ((i)==XkbKeypadIndex))&&(wire.numLevels!=2))) {
+ _XkbLibError(_XkbErrBadTypeWidth,"ReadXkmKeyTypes",i);
+ return -1;
+ }
+ tmp= wire.nMapEntries;
+ XkmInsureTypedSize(type->map,type->map_count,&tmp,XkbKTMapEntryRec);
+ if ((wire.nMapEntries>0)&&(type->map==NULL)) {
+ _XkbLibError(_XkbErrBadValue,"ReadXkmKeyTypes",wire.nMapEntries);
+ return -1;
+ }
+ for (n=0,entry= type->map;n<wire.nMapEntries;n++,entry++) {
+ if (fread(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file)<(int)1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ nRead+= SIZEOF(xkmKTMapEntryDesc);
+ entry->active= (wire_entry.virtualMods==0);
+ entry->level= wire_entry.level;
+ entry->mods.mask= wire_entry.realMods;
+ entry->mods.real_mods= wire_entry.realMods;
+ entry->mods.vmods= wire_entry.virtualMods;
+ }
+ nRead+= XkmGetCountedString(file,buf,100);
+ if (((i==XkbOneLevelIndex)&&(strcmp(buf,"ONE_LEVEL")!=0))||
+ ((i==XkbTwoLevelIndex)&&(strcmp(buf,"TWO_LEVEL")!=0))||
+ ((i==XkbAlphabeticIndex)&&(strcmp(buf,"ALPHABETIC")!=0))||
+ ((i==XkbKeypadIndex)&&(strcmp(buf,"KEYPAD")!=0))) {
+ _XkbLibError(_XkbErrBadTypeName,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ if (buf[0]!='\0') {
+ type->name= XkbInternAtom(buf,FALSE);
+ }
+ else type->name= None;
+
+ if (wire.preserve) {
+ xkmModsDesc p_entry;
+ XkbModsPtr pre;
+ XkmInsureTypedSize(type->preserve,type->map_count,&tmp,
+ XkbModsRec);
+ if (type->preserve==NULL) {
+ _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ for (n=0,pre=type->preserve;n<wire.nMapEntries;n++,pre++) {
+ if (fread(&p_entry,SIZEOF(xkmModsDesc),1,file)<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ nRead+= SIZEOF(xkmModsDesc);
+ pre->mask= p_entry.realMods;
+ pre->real_mods= p_entry.realMods;
+ pre->vmods= p_entry.virtualMods;
+ }
+ }
+ if (wire.nLevelNames>0) {
+ int width= wire.numLevels;
+ if (wire.nLevelNames>(unsigned)width) {
+ _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ XkmInsureTypedSize(type->level_names,type->num_levels,&width,Atom);
+ if (type->level_names!=NULL) {
+ for (n=0;n<wire.nLevelNames;n++) {
+ if ((tmp=XkmGetCountedString(file,buf,100))<1)
+ return -1;
+ nRead+= tmp;
+ if (strlen(buf)==0)
+ type->level_names[n]= None;
+ else type->level_names[n]= XkbInternAtom(buf,0);
+ }
+ }
+ }
+ type->mods.mask= wire.realMods;
+ type->mods.real_mods= wire.realMods;
+ type->mods.vmods= wire.virtualMods;
+ type->num_levels= wire.numLevels;
+ type->map_count= wire.nMapEntries;
+ }
+ if (changes) {
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type= 0;
+ changes->map.num_types= xkb->map->num_types;
+ }
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmCompatMap(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
+{
+register int i;
+unsigned num_si,groups;
+char name[100];
+XkbSymInterpretPtr interp;
+xkmSymInterpretDesc wire;
+unsigned tmp;
+int nRead=0;
+XkbCompatMapPtr compat;
+XkbAction *act;
+
+ if ((tmp= XkmGetCountedString(file,name,100))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0);
+ return -1;
+ }
+ nRead+= tmp;
+ if (name[0]!='\0') {
+ if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0);
+ return -1;
+ }
+ xkb->names->compat= XkbInternAtom(name,FALSE);
+ }
+ num_si= XkmGetCARD16(file,&nRead);
+ groups= XkmGetCARD8(file,&nRead);
+ nRead+= XkmSkipPadding(file,1);
+ if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success)
+ return -1;
+ compat= xkb->compat;
+ compat->num_si= num_si;
+ interp= compat->sym_interpret;
+ for (i=0;i<num_si;i++,interp++) {
+ tmp= fread(&wire,SIZEOF(xkmSymInterpretDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmSymInterpretDesc);
+ interp->sym= wire.sym;
+ interp->mods= wire.mods;
+ interp->match= wire.match;
+ interp->virtual_mod= wire.virtualMod;
+ interp->flags= wire.flags;
+ interp->act.type= wire.actionType;
+ act = (XkbAction *) &interp->act;
+
+ switch (interp->act.type) {
+ case XkbSA_SetMods:
+ case XkbSA_LatchMods:
+ case XkbSA_LockMods:
+ act->mods.flags = wire.actionData[0];
+ act->mods.mask = wire.actionData[1];
+ act->mods.real_mods = wire.actionData[2];
+ act->mods.vmods1 = wire.actionData[3];
+ act->mods.vmods2 = wire.actionData[4];
+ break;
+ case XkbSA_SetGroup:
+ case XkbSA_LatchGroup:
+ case XkbSA_LockGroup:
+ act->group.flags = wire.actionData[0];
+ act->group.group_XXX = wire.actionData[1];
+ break;
+ case XkbSA_MovePtr:
+ act->ptr.flags = wire.actionData[0];
+ act->ptr.high_XXX = wire.actionData[1];
+ act->ptr.low_XXX = wire.actionData[2];
+ act->ptr.high_YYY = wire.actionData[3];
+ act->ptr.low_YYY = wire.actionData[4];
+ break;
+ case XkbSA_PtrBtn:
+ case XkbSA_LockPtrBtn:
+ act->btn.flags = wire.actionData[0];
+ act->btn.count = wire.actionData[1];
+ act->btn.button = wire.actionData[2];
+ break;
+ case XkbSA_DeviceBtn:
+ case XkbSA_LockDeviceBtn:
+ act->devbtn.flags = wire.actionData[0];
+ act->devbtn.count = wire.actionData[1];
+ act->devbtn.button = wire.actionData[2];
+ act->devbtn.device = wire.actionData[3];
+ break;
+ case XkbSA_SetPtrDflt:
+ act->dflt.flags = wire.actionData[0];
+ act->dflt.affect = wire.actionData[1];
+ act->dflt.valueXXX = wire.actionData[2];
+ break;
+ case XkbSA_ISOLock:
+ act->iso.flags = wire.actionData[0];
+ act->iso.mask = wire.actionData[1];
+ act->iso.real_mods = wire.actionData[2];
+ act->iso.group_XXX = wire.actionData[3];
+ act->iso.affect = wire.actionData[4];
+ act->iso.vmods1 = wire.actionData[5];
+ act->iso.vmods2 = wire.actionData[6];
+ break;
+ case XkbSA_SwitchScreen:
+ act->screen.flags = wire.actionData[0];
+ act->screen.screenXXX = wire.actionData[1];
+ break;
+ case XkbSA_SetControls:
+ case XkbSA_LockControls:
+ act->ctrls.flags = wire.actionData[0];
+ act->ctrls.ctrls3 = wire.actionData[1];
+ act->ctrls.ctrls2 = wire.actionData[2];
+ act->ctrls.ctrls1 = wire.actionData[3];
+ act->ctrls.ctrls0 = wire.actionData[4];
+ break;
+ case XkbSA_RedirectKey:
+ act->redirect.new_key = wire.actionData[0];
+ act->redirect.mods_mask = wire.actionData[1];
+ act->redirect.mods = wire.actionData[2];
+ act->redirect.vmods_mask0 = wire.actionData[3];
+ act->redirect.vmods_mask1 = wire.actionData[4];
+ act->redirect.vmods0 = wire.actionData[4];
+ act->redirect.vmods1 = wire.actionData[5];
+ break;
+ case XkbSA_DeviceValuator:
+ act->devval.device = wire.actionData[0];
+ act->devval.v1_what = wire.actionData[1];
+ act->devval.v1_ndx = wire.actionData[2];
+ act->devval.v1_value = wire.actionData[3];
+ act->devval.v2_what = wire.actionData[4];
+ act->devval.v2_ndx = wire.actionData[5];
+ act->devval.v2_what = wire.actionData[6];
+ break;
+
+ case XkbSA_XFree86Private:
+ /* copy the kind of action */
+ strncpy((char*)act->any.data, (char*)wire.actionData,
+ XkbAnyActionDataSize);
+ break ;
+
+ case XkbSA_Terminate:
+ /* no args, kinda (note: untrue for xfree86). */
+ break;
+ case XkbSA_ActionMessage:
+ /* unsupported. */
+ break;
+ }
+ }
+ if ((num_si>0)&&(changes)) {
+ changes->compat.first_si= 0;
+ changes->compat.num_si= num_si;
+ }
+ if (groups) {
+ register unsigned bit;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ xkmModsDesc md;
+ if (groups&bit) {
+ tmp= fread(&md,SIZEOF(xkmModsDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmModsDesc);
+ xkb->compat->groups[i].real_mods= md.realMods;
+ xkb->compat->groups[i].vmods= md.virtualMods;
+ if (md.virtualMods != 0) {
+ unsigned mask;
+ if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask))
+ xkb->compat->groups[i].mask= md.realMods|mask;
+ }
+ else xkb->compat->groups[i].mask= md.realMods;
+ }
+ }
+ if (changes)
+ changes->compat.changed_groups|= groups;
+ }
+ return nRead;
+}
+
+static int
+ReadXkmIndicators(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
+{
+register unsigned nLEDs;
+xkmIndicatorMapDesc wire;
+char buf[100];
+unsigned tmp;
+int nRead=0;
+
+ if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) {
+ _XkbLibError(_XkbErrBadAlloc,"indicator rec",0);
+ return -1;
+ }
+ if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"indicator names",0);
+ return -1;
+ }
+ nLEDs= XkmGetCARD8(file,&nRead);
+ nRead+= XkmSkipPadding(file,3);
+ xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead);
+ while (nLEDs-->0) {
+ Atom name;
+ XkbIndicatorMapPtr map;
+
+ if ((tmp=XkmGetCountedString(file,buf,100))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
+ return -1;
+ }
+ nRead+= tmp;
+ if (buf[0]!='\0')
+ name= XkbInternAtom(buf,FALSE);
+ else name= None;
+ if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
+ return -1;
+ }
+ nRead+= tmp*SIZEOF(xkmIndicatorMapDesc);
+ if (xkb->names) {
+ xkb->names->indicators[wire.indicator-1]= name;
+ if (changes)
+ changes->names.changed_indicators|= (1<<(wire.indicator-1));
+ }
+ map= &xkb->indicators->maps[wire.indicator-1];
+ map->flags= wire.flags;
+ map->which_groups= wire.which_groups;
+ map->groups= wire.groups;
+ map->which_mods= wire.which_mods;
+ map->mods.mask= wire.real_mods;
+ map->mods.real_mods= wire.real_mods;
+ map->mods.vmods= wire.vmods;
+ map->ctrls= wire.ctrls;
+ }
+ return nRead;
+}
+
+static XkbKeyTypePtr
+FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms)
+{
+ if ((!xkb)||(!xkb->map))
+ return NULL;
+ if (name!=None) {
+ register unsigned i;
+ for (i=0;i<xkb->map->num_types;i++) {
+ if (xkb->map->types[i].name==name) {
+ if (xkb->map->types[i].num_levels!=width)
+ DebugF("Group width mismatch between key and type\n");
+ return &xkb->map->types[i];
+ }
+ }
+ }
+ if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol)))
+ return &xkb->map->types[XkbOneLevelIndex];
+ if (syms!=NULL) {
+ if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1]))
+ return &xkb->map->types[XkbAlphabeticIndex];
+ else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1]))
+ return &xkb->map->types[XkbKeypadIndex];
+ }
+ return &xkb->map->types[XkbTwoLevelIndex];
+}
+
+static int
+ReadXkmSymbols(FILE *file,XkbDescPtr xkb)
+{
+register int i,g,s,totalVModMaps;
+xkmKeySymMapDesc wireMap;
+char buf[100];
+unsigned minKC,maxKC,groupNames,tmp;
+int nRead=0;
+
+ if ((tmp=XkmGetCountedString(file,buf,100))<1)
+ return -1;
+ nRead+= tmp;
+ minKC= XkmGetCARD8(file,&nRead);
+ maxKC= XkmGetCARD8(file,&nRead);
+ groupNames= XkmGetCARD8(file,&nRead);
+ totalVModMaps= XkmGetCARD8(file,&nRead);
+ if (XkbAllocNames(xkb,
+ XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask,
+ 0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"physical names",0);
+ return -1;
+ }
+ if ((buf[0]!='\0')&&(xkb->names)) {
+ Atom name;
+ name= XkbInternAtom(buf,0);
+ xkb->names->symbols= name;
+ xkb->names->phys_symbols= name;
+ }
+ for (i=0,g=1;i<XkbNumKbdGroups;i++,g<<=1) {
+ if (groupNames&g) {
+ if ((tmp=XkmGetCountedString(file,buf,100))<1)
+ return -1;
+ nRead+= tmp;
+ if ((buf[0]!='\0')&&(xkb->names)) {
+ Atom name;
+ name= XkbInternAtom(buf,0);
+ xkb->names->groups[i]= name;
+ }
+ else xkb->names->groups[i]= None;
+ }
+ }
+ if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"server map",0);
+ return -1;
+ }
+ if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"client map",0);
+ return -1;
+ }
+ if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"controls",0);
+ return -1;
+ }
+ if ((xkb->map==NULL)||(xkb->server==NULL))
+ return -1;
+ if (xkb->min_key_code<8) xkb->min_key_code= minKC;
+ if (xkb->max_key_code<8) xkb->max_key_code= maxKC;
+ if ((minKC>=8)&&(minKC<xkb->min_key_code))
+ xkb->min_key_code= minKC;
+ if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) {
+ _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC);
+ return -1;
+ }
+ for (i=minKC;i<=(int)maxKC;i++) {
+ Atom typeName[XkbNumKbdGroups];
+ XkbKeyTypePtr type[XkbNumKbdGroups];
+ if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0);
+ return -1;
+ }
+ nRead+= tmp*SIZEOF(xkmKeySymMapDesc);
+ bzero((char *)typeName,XkbNumKbdGroups*sizeof(Atom));
+ bzero((char *)type,XkbNumKbdGroups*sizeof(XkbKeyTypePtr));
+ if (wireMap.flags&XkmKeyHasTypes) {
+ register int g;
+ for (g=0;g<XkbNumKbdGroups;g++) {
+ if ((wireMap.flags&(1<<g))&&
+ ((tmp=XkmGetCountedString(file,buf,100))>0)) {
+ typeName[g]= XkbInternAtom(buf,1);
+ nRead+= tmp;
+ }
+ type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL);
+ if (type[g]==NULL) {
+ _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0);
+ return -1;
+ }
+ if (typeName[g]==type[g]->name)
+ xkb->server->explicit[i]|= (1<<g);
+ }
+ }
+ if (wireMap.flags&XkmRepeatingKey) {
+ xkb->ctrls->per_key_repeat[i/8]|= (1<<(i%8));
+ xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
+ }
+ else if (wireMap.flags&XkmNonRepeatingKey) {
+ xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8));
+ xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
+ }
+ xkb->map->modmap[i]= wireMap.modifier_map;
+ if (XkbNumGroups(wireMap.num_groups)>0) {
+ KeySym *sym;
+ int nSyms;
+
+ if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups)
+ xkb->ctrls->num_groups= wireMap.num_groups;
+ nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width;
+ sym= XkbResizeKeySyms(xkb,i,nSyms);
+ if (!sym)
+ return -1;
+ for (s=0;s<nSyms;s++) {
+ *sym++= XkmGetCARD32(file,&nRead);
+ }
+ if (wireMap.flags&XkmKeyHasActions) {
+ XkbAction * act;
+ act= XkbResizeKeyActions(xkb,i,nSyms);
+ for (s=0;s<nSyms;s++,act++) {
+ tmp=fread(act,SIZEOF(xkmActionDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmActionDesc);
+ }
+ xkb->server->explicit[i]|= XkbExplicitInterpretMask;
+ }
+ }
+ for (g=0;g<XkbNumGroups(wireMap.num_groups);g++) {
+ if (((xkb->server->explicit[i]&(1<<g))==0)||(type[g]==NULL)) {
+ KeySym *tmpSyms;
+ tmpSyms= XkbKeySymsPtr(xkb,i)+(wireMap.width*g);
+ type[g]= FindTypeForKey(xkb,None,wireMap.width,tmpSyms);
+ }
+ xkb->map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]);
+ }
+ xkb->map->key_sym_map[i].group_info= wireMap.num_groups;
+ xkb->map->key_sym_map[i].width= wireMap.width;
+ if (wireMap.flags&XkmKeyHasBehavior) {
+ xkmBehaviorDesc b;
+ tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmBehaviorDesc);
+ xkb->server->behaviors[i].type= b.type;
+ xkb->server->behaviors[i].data= b.data;
+ xkb->server->explicit[i]|= XkbExplicitBehaviorMask;
+ }
+ }
+ if (totalVModMaps>0) {
+ xkmVModMapDesc v;
+ for (i=0;i<totalVModMaps;i++) {
+ tmp= fread(&v,SIZEOF(xkmVModMapDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmVModMapDesc);
+ if (tmp>0)
+ xkb->server->vmodmap[v.key]= v.vmods;
+ }
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeomDoodad(
+ FILE * file,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section)
+{
+XkbDoodadPtr doodad;
+xkmDoodadDesc doodadWire;
+char buf[100];
+unsigned tmp;
+int nRead=0;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file);
+ nRead+= SIZEOF(xkmDoodadDesc)*tmp;
+ doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(buf,FALSE));
+ if (!doodad)
+ return nRead;
+ doodad->any.type= doodadWire.any.type;
+ doodad->any.priority= doodadWire.any.priority;
+ doodad->any.top= doodadWire.any.top;
+ doodad->any.left= doodadWire.any.left;
+ switch (doodadWire.any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ doodad->shape.angle= doodadWire.shape.angle;
+ doodad->shape.color_ndx= doodadWire.shape.color_ndx;
+ doodad->shape.shape_ndx= doodadWire.shape.shape_ndx;
+ break;
+ case XkbTextDoodad:
+ doodad->text.angle= doodadWire.text.angle;
+ doodad->text.width= doodadWire.text.width;
+ doodad->text.height= doodadWire.text.height;
+ doodad->text.color_ndx= doodadWire.text.color_ndx;
+ nRead+= XkmGetCountedString(file,buf,100);
+ doodad->text.text= _XkbDupString(buf);
+ nRead+= XkmGetCountedString(file,buf,100);
+ doodad->text.font= _XkbDupString(buf);
+ break;
+ case XkbIndicatorDoodad:
+ doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx;
+ doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx;
+ doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx;
+ break;
+ case XkbLogoDoodad:
+ doodad->logo.angle= doodadWire.logo.angle;
+ doodad->logo.color_ndx= doodadWire.logo.color_ndx;
+ doodad->logo.shape_ndx= doodadWire.logo.shape_ndx;
+ nRead+= XkmGetCountedString(file,buf,100);
+ doodad->logo.logo_name= _XkbDupString(buf);
+ break;
+ default:
+ /* report error? */
+ return nRead;
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeomOverlay( FILE * file,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section)
+{
+char buf[100];
+unsigned tmp;
+int nRead=0;
+XkbOverlayPtr ol;
+XkbOverlayRowPtr row;
+xkmOverlayDesc olWire;
+xkmOverlayRowDesc rowWire;
+register int r;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOverlayDesc);
+ ol= XkbAddGeomOverlay(section,XkbInternAtom(buf,FALSE),
+ olWire.num_rows);
+ if (!ol)
+ return nRead;
+ for (r=0;r<olWire.num_rows;r++) {
+ int k;
+ xkmOverlayKeyDesc keyWire;
+ tmp= fread(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOverlayRowDesc);
+ row= XkbAddGeomOverlayRow(ol,rowWire.row_under,rowWire.num_keys);
+ if (!row) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomOverlay",0);
+ return nRead;
+ }
+ for (k=0;k<rowWire.num_keys;k++) {
+ tmp= fread(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOverlayKeyDesc);
+ memcpy(row->keys[k].over.name,keyWire.over,XkbKeyNameLength);
+ memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength);
+ }
+ row->num_keys= rowWire.num_keys;
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeomSection( FILE * file,
+ XkbGeometryPtr geom)
+{
+register int i;
+XkbSectionPtr section;
+xkmSectionDesc sectionWire;
+unsigned tmp;
+int nRead= 0;
+char buf[100];
+Atom nameAtom;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ nameAtom= XkbInternAtom(buf,FALSE);
+ tmp= fread(&sectionWire,SIZEOF(xkmSectionDesc),1,file);
+ nRead+= SIZEOF(xkmSectionDesc)*tmp;
+ section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows,
+ sectionWire.num_doodads,
+ sectionWire.num_overlays);
+ if (!section) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
+ return nRead;
+ }
+ section->top= sectionWire.top;
+ section->left= sectionWire.left;
+ section->width= sectionWire.width;
+ section->height= sectionWire.height;
+ section->angle= sectionWire.angle;
+ section->priority= sectionWire.priority;
+ if (sectionWire.num_rows>0) {
+ register int k;
+ XkbRowPtr row;
+ xkmRowDesc rowWire;
+ XkbKeyPtr key;
+ xkmKeyDesc keyWire;
+
+ for (i=0;i<sectionWire.num_rows;i++) {
+ tmp= fread(&rowWire,SIZEOF(xkmRowDesc),1,file);
+ nRead+= SIZEOF(xkmRowDesc)*tmp;
+ row= XkbAddGeomRow(section,rowWire.num_keys);
+ if (!row) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
+ return nRead;
+ }
+ row->top= rowWire.top;
+ row->left= rowWire.left;
+ row->vertical= rowWire.vertical;
+ for (k=0;k<rowWire.num_keys;k++) {
+ tmp= fread(&keyWire,SIZEOF(xkmKeyDesc),1,file);
+ nRead+= SIZEOF(xkmKeyDesc)*tmp;
+ key= XkbAddGeomKey(row);
+ if (!key) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
+ return nRead;
+ }
+ memcpy(key->name.name,keyWire.name,XkbKeyNameLength);
+ key->gap= keyWire.gap;
+ key->shape_ndx= keyWire.shape_ndx;
+ key->color_ndx= keyWire.color_ndx;
+ }
+ }
+ }
+ if (sectionWire.num_doodads>0) {
+ for (i=0;i<sectionWire.num_doodads;i++) {
+ tmp= ReadXkmGeomDoodad(file,geom,section);
+ nRead+= tmp;
+ if (tmp<1)
+ return nRead;
+ }
+ }
+ if (sectionWire.num_overlays>0) {
+ for (i=0;i<sectionWire.num_overlays;i++) {
+ tmp= ReadXkmGeomOverlay(file,geom,section);
+ nRead+= tmp;
+ if (tmp<1)
+ return nRead;
+ }
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeometry(FILE *file,XkbDescPtr xkb)
+{
+register int i;
+char buf[100];
+unsigned tmp;
+int nRead= 0;
+xkmGeometryDesc wireGeom;
+XkbGeometryPtr geom;
+XkbGeometrySizesRec sizes;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ tmp= fread(&wireGeom,SIZEOF(xkmGeometryDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmGeometryDesc);
+ sizes.which= XkbGeomAllMask;
+ sizes.num_properties= wireGeom.num_properties;
+ sizes.num_colors= wireGeom.num_colors;
+ sizes.num_shapes= wireGeom.num_shapes;
+ sizes.num_sections= wireGeom.num_sections;
+ sizes.num_doodads= wireGeom.num_doodads;
+ sizes.num_key_aliases= wireGeom.num_key_aliases;
+ if (XkbAllocGeometry(xkb,&sizes)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ geom= xkb->geom;
+ geom->name= XkbInternAtom(buf,FALSE);
+ geom->width_mm= wireGeom.width_mm;
+ geom->height_mm= wireGeom.height_mm;
+ nRead+= XkmGetCountedString(file,buf,100);
+ geom->label_font= _XkbDupString(buf);
+ if (wireGeom.num_properties>0) {
+ char val[1024];
+ for (i=0;i<wireGeom.num_properties;i++) {
+ nRead+= XkmGetCountedString(file,buf,100);
+ nRead+= XkmGetCountedString(file,val,1024);
+ if (XkbAddGeomProperty(geom,buf,val)==NULL) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ }
+ }
+ if (wireGeom.num_colors>0) {
+ for (i=0;i<wireGeom.num_colors;i++) {
+ nRead+= XkmGetCountedString(file,buf,100);
+ if (XkbAddGeomColor(geom,buf,i)==NULL) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ }
+ }
+ geom->base_color= &geom->colors[wireGeom.base_color_ndx];
+ geom->label_color= &geom->colors[wireGeom.label_color_ndx];
+ if (wireGeom.num_shapes>0) {
+ XkbShapePtr shape;
+ xkmShapeDesc shapeWire;
+ Atom nameAtom;
+ for (i=0;i<wireGeom.num_shapes;i++) {
+ register int n;
+ XkbOutlinePtr ol;
+ xkmOutlineDesc olWire;
+ nRead+= XkmGetCountedString(file,buf,100);
+ nameAtom= XkbInternAtom(buf,FALSE);
+ tmp= fread(&shapeWire,SIZEOF(xkmShapeDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmShapeDesc);
+ shape= XkbAddGeomShape(geom,nameAtom,shapeWire.num_outlines);
+ if (!shape) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ for (n=0;n<shapeWire.num_outlines;n++) {
+ register int p;
+ xkmPointDesc ptWire;
+ tmp= fread(&olWire,SIZEOF(xkmOutlineDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOutlineDesc);
+ ol= XkbAddGeomOutline(shape,olWire.num_points);
+ if (!ol) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ ol->num_points= olWire.num_points;
+ ol->corner_radius= olWire.corner_radius;
+ for (p=0;p<olWire.num_points;p++) {
+ tmp= fread(&ptWire,SIZEOF(xkmPointDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmPointDesc);
+ ol->points[p].x= ptWire.x;
+ ol->points[p].y= ptWire.y;
+ if (ptWire.x<shape->bounds.x1) shape->bounds.x1= ptWire.x;
+ if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x;
+ if (ptWire.y<shape->bounds.y1) shape->bounds.y1= ptWire.y;
+ if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y;
+ }
+ }
+ if (shapeWire.primary_ndx!=XkbNoShape)
+ shape->primary= &shape->outlines[shapeWire.primary_ndx];
+ if (shapeWire.approx_ndx!=XkbNoShape)
+ shape->approx= &shape->outlines[shapeWire.approx_ndx];
+ }
+ }
+ if (wireGeom.num_sections>0) {
+ for (i=0;i<wireGeom.num_sections;i++) {
+ tmp= ReadXkmGeomSection(file,geom);
+ nRead+= tmp;
+ if (tmp==0)
+ return nRead;
+ }
+ }
+ if (wireGeom.num_doodads>0) {
+ for (i=0;i<wireGeom.num_doodads;i++) {
+ tmp= ReadXkmGeomDoodad(file,geom,NULL);
+ nRead+= tmp;
+ if (tmp==0)
+ return nRead;
+ }
+ }
+ if ((wireGeom.num_key_aliases>0)&&(geom->key_aliases)) {
+ int sz= XkbKeyNameLength*2;
+ int num= wireGeom.num_key_aliases;
+ if (fread(geom->key_aliases,sz,num,file)!=num) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0);
+ return -1;
+ }
+ nRead+= (num*sz);
+ geom->num_key_aliases= num;
+ }
+ return nRead;
+}
+
+Bool
+XkmProbe(FILE *file)
+{
+unsigned hdr,tmp;
+int nRead=0;
+
+ hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
+ tmp= XkmGetCARD32(file,&nRead);
+ if (tmp!=hdr) {
+ if ((tmp&(~0xff))==(hdr&(~0xff))) {
+ _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+static Bool
+XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc)
+{
+unsigned hdr,tmp;
+int nRead=0;
+unsigned i,size_toc;
+
+ hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
+ tmp= XkmGetCARD32(file,&nRead);
+ if (tmp!=hdr) {
+ if ((tmp&(~0xff))==(hdr&(~0xff))) {
+ _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff);
+ }
+ else {
+ _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp);
+ }
+ return 0;
+ }
+ fread(file_info,SIZEOF(xkmFileInfo),1,file);
+ size_toc= file_info->num_toc;
+ if (size_toc>max_toc) {
+ DebugF("Warning! Too many TOC entries; last %d ignored\n",
+ size_toc-max_toc);
+ size_toc= max_toc;
+ }
+ for (i=0;i<size_toc;i++) {
+ fread(&toc[i],SIZEOF(xkmSectionInfo),1,file);
+ }
+ return 1;
+}
+
+/***====================================================================***/
+
+#define MAX_TOC 16
+unsigned
+XkmReadFile(FILE *file,unsigned need,unsigned want,XkbDescPtr *xkb)
+{
+register unsigned i;
+xkmSectionInfo toc[MAX_TOC],tmpTOC;
+xkmFileInfo fileInfo;
+unsigned tmp,nRead=0;
+unsigned which= need|want;
+
+ if (!XkmReadTOC(file,&fileInfo,MAX_TOC,toc))
+ return which;
+ if ((fileInfo.present&need)!=need) {
+ _XkbLibError(_XkbErrIllegalContents,"XkmReadFile",
+ need&(~fileInfo.present));
+ return which;
+ }
+ if (*xkb==NULL)
+ *xkb= XkbAllocKeyboard();
+ for (i=0;i<fileInfo.num_toc;i++) {
+ fseek(file,toc[i].offset,SEEK_SET);
+ tmp= fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file);
+ nRead= tmp*SIZEOF(xkmSectionInfo);
+ if ((tmpTOC.type!=toc[i].type)||(tmpTOC.format!=toc[i].format)||
+ (tmpTOC.size!=toc[i].size)||(tmpTOC.offset!=toc[i].offset)) {
+ return which;
+ }
+ if ((which&(1<<tmpTOC.type))==0) {
+ continue;
+ }
+ switch (tmpTOC.type) {
+ case XkmVirtualModsIndex:
+ tmp= ReadXkmVirtualMods(file,*xkb,NULL);
+ break;
+ case XkmTypesIndex:
+ tmp= ReadXkmKeyTypes(file,*xkb,NULL);
+ break;
+ case XkmCompatMapIndex:
+ tmp= ReadXkmCompatMap(file,*xkb,NULL);
+ break;
+ case XkmKeyNamesIndex:
+ tmp= ReadXkmKeycodes(file,*xkb,NULL);
+ break;
+ case XkmIndicatorsIndex:
+ tmp= ReadXkmIndicators(file,*xkb,NULL);
+ break;
+ case XkmSymbolsIndex:
+ tmp= ReadXkmSymbols(file,*xkb);
+ break;
+ case XkmGeometryIndex:
+ tmp= ReadXkmGeometry(file,*xkb);
+ break;
+ default:
+ _XkbLibError(_XkbErrBadImplementation,
+ XkbConfigText(tmpTOC.type,XkbMessage),0);
+ tmp= 0;
+ break;
+ }
+ if (tmp>0) {
+ nRead+= tmp;
+ which&= ~(1<<toc[i].type);
+ (*xkb)->defined|= (1<<toc[i].type);
+ }
+ if (nRead!=tmpTOC.size) {
+ _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage),
+ nRead-tmpTOC.size);
+ }
+ }
+ return which;
+}