diff options
author | marha <marha@users.sourceforge.net> | 2010-05-16 20:50:58 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2010-05-16 20:50:58 +0000 |
commit | 1c94119ae26b94a60bb2c2b33494ed43c3b8a52f (patch) | |
tree | cfe0c736c95314edac7d9f1065be9c13026ed0c1 /xorg-server/xkb | |
parent | 6b29aa4559aeb6f795caee047561654bfa0a1954 (diff) | |
download | vcxsrv-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.c | 674 | ||||
-rw-r--r-- | xorg-server/xkb/XKBGAlloc.c | 1994 | ||||
-rw-r--r-- | xorg-server/xkb/XKBMAlloc.c | 1800 | ||||
-rw-r--r-- | xorg-server/xkb/XKBMisc.c | 1678 | ||||
-rw-r--r-- | xorg-server/xkb/ddxList.c | 596 | ||||
-rw-r--r-- | xorg-server/xkb/ddxLoad.c | 924 | ||||
-rw-r--r-- | xorg-server/xkb/maprules.c | 2038 | ||||
-rw-r--r-- | xorg-server/xkb/xkb.c | 120 | ||||
-rw-r--r-- | xorg-server/xkb/xkbActions.c | 6 | ||||
-rw-r--r-- | xorg-server/xkb/xkbEvents.c | 2224 | ||||
-rw-r--r-- | xorg-server/xkb/xkbInit.c | 1558 | ||||
-rw-r--r-- | xorg-server/xkb/xkbLEDs.c | 1954 | ||||
-rw-r--r-- | xorg-server/xkb/xkbUtils.c | 4384 | ||||
-rw-r--r-- | xorg-server/xkb/xkmread.c | 2476 |
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, - §ion->num_overlays,§ion->sz_overlays, - (char **)§ion->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, - §ion->num_rows,§ion->sz_rows, - (char **)§ion->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= §ion->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= §ion->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= §ion->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= §ion->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,
+ §ion->num_overlays,§ion->sz_overlays,
+ (char **)§ion->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,
+ §ion->num_rows,§ion->sz_rows,
+ (char **)§ion->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= §ion->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= §ion->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= §ion->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= §ion->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(§ionWire,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(§ionWire,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;
+}
|