aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/xkb
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2010-05-15 16:28:11 +0000
committermarha <marha@users.sourceforge.net>2010-05-15 16:28:11 +0000
commitc38dead3ea7e177728d90cd815cf4eead0c9f534 (patch)
treeb809dba1dc9013bb1e67a5ee388f2dd217dc0f88 /xorg-server/xkb
parent6083a94d68878c9ad5f59b28bd07e4738e9fb7b4 (diff)
downloadvcxsrv-c38dead3ea7e177728d90cd815cf4eead0c9f534.tar.gz
vcxsrv-c38dead3ea7e177728d90cd815cf4eead0c9f534.tar.bz2
vcxsrv-c38dead3ea7e177728d90cd815cf4eead0c9f534.zip
xserver git update 15/5/2010
Diffstat (limited to 'xorg-server/xkb')
-rw-r--r--xorg-server/xkb/XKBAlloc.c674
-rw-r--r--xorg-server/xkb/XKBGAlloc.c1994
-rw-r--r--xorg-server/xkb/XKBMAlloc.c1800
-rw-r--r--xorg-server/xkb/XKBMisc.c1678
-rw-r--r--xorg-server/xkb/ddxList.c586
-rw-r--r--xorg-server/xkb/ddxLoad.c916
-rw-r--r--xorg-server/xkb/maprules.c2038
-rw-r--r--xorg-server/xkb/xkb.c13442
-rw-r--r--xorg-server/xkb/xkbActions.c2778
-rw-r--r--xorg-server/xkb/xkbEvents.c2224
-rw-r--r--xorg-server/xkb/xkbInit.c1558
-rw-r--r--xorg-server/xkb/xkbLEDs.c1954
-rw-r--r--xorg-server/xkb/xkbUtils.c4384
-rw-r--r--xorg-server/xkb/xkmread.c2476
14 files changed, 19250 insertions, 19252 deletions
diff --git a/xorg-server/xkb/XKBAlloc.c b/xorg-server/xkb/XKBAlloc.c
index d40aa3345..4d342a0fa 100644
--- a/xorg-server/xkb/XKBAlloc.c
+++ b/xorg-server/xkb/XKBAlloc.c
@@ -1,337 +1,337 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-#include <xkbsrv.h>
-#include "xkbgeom.h"
-#include <os.h>
-#include <string.h>
-
-/***===================================================================***/
-
-/*ARGSUSED*/
-Status
-XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI)
-{
-XkbCompatMapPtr compat;
-XkbSymInterpretRec *prev_interpret;
-
- if (!xkb)
- return BadMatch;
- if (xkb->compat) {
- if (xkb->compat->size_si>=nSI)
- return Success;
- compat= xkb->compat;
- compat->size_si= nSI;
- if (compat->sym_interpret==NULL)
- compat->num_si= 0;
- prev_interpret = compat->sym_interpret;
- compat->sym_interpret= xrealloc(compat->sym_interpret,
- nSI * sizeof(XkbSymInterpretRec));
- if (compat->sym_interpret==NULL) {
- xfree(prev_interpret);
- compat->size_si= compat->num_si= 0;
- return BadAlloc;
- }
- if (compat->num_si!=0) {
- memset(&compat->sym_interpret[compat->num_si], 0,
- (compat->size_si - compat->num_si) * sizeof(XkbSymInterpretRec));
- }
- return Success;
- }
- compat= xcalloc(1, sizeof(XkbCompatMapRec));
- if (compat==NULL)
- return BadAlloc;
- if (nSI>0) {
- compat->sym_interpret= xcalloc(nSI, sizeof(XkbSymInterpretRec));
- if (!compat->sym_interpret) {
- xfree(compat);
- return BadAlloc;
- }
- }
- compat->size_si= nSI;
- compat->num_si= 0;
- bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
- xkb->compat= compat;
- return Success;
-}
-
-
-void
-XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap)
-{
-register XkbCompatMapPtr compat;
-
- if ((xkb==NULL)||(xkb->compat==NULL))
- return;
- compat= xkb->compat;
- if (freeMap)
- which= XkbAllCompatMask;
- if (which&XkbGroupCompatMask)
- bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
- if (which&XkbSymInterpMask) {
- if ((compat->sym_interpret)&&(compat->size_si>0))
- xfree(compat->sym_interpret);
- compat->size_si= compat->num_si= 0;
- compat->sym_interpret= NULL;
- }
- if (freeMap) {
- xfree(compat);
- xkb->compat= NULL;
- }
- return;
-}
-
-/***===================================================================***/
-
-Status
-XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases)
-{
-XkbNamesPtr names;
-
- if (xkb==NULL)
- return BadMatch;
- if (xkb->names==NULL) {
- xkb->names = xcalloc(1, sizeof(XkbNamesRec));
- if (xkb->names==NULL)
- return BadAlloc;
- }
- names= xkb->names;
- if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){
- register int i;
- XkbKeyTypePtr type;
-
- type= xkb->map->types;
- for (i=0;i<xkb->map->num_types;i++,type++) {
- if (type->level_names==NULL) {
- type->level_names= xcalloc(type->num_levels, sizeof(Atom));
- if (type->level_names==NULL)
- return BadAlloc;
- }
- }
- }
- if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadValue;
- names->keys= xcalloc((xkb->max_key_code+1), sizeof(XkbKeyNameRec));
- if (names->keys==NULL)
- return BadAlloc;
- }
- if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) {
- if (names->key_aliases==NULL) {
- names->key_aliases= xcalloc(nTotalAliases, sizeof(XkbKeyAliasRec));
- }
- else if (nTotalAliases>names->num_key_aliases) {
- XkbKeyAliasRec *prev_aliases = names->key_aliases;
-
- names->key_aliases= xrealloc(names->key_aliases,
- nTotalAliases * sizeof(XkbKeyAliasRec));
- if (names->key_aliases!=NULL) {
- memset(&names->key_aliases[names->num_key_aliases], 0,
- (nTotalAliases - names->num_key_aliases) * sizeof(XkbKeyAliasRec));
- } else {
- xfree(prev_aliases);
- }
- }
- if (names->key_aliases==NULL) {
- names->num_key_aliases= 0;
- return BadAlloc;
- }
- names->num_key_aliases= nTotalAliases;
- }
- if ((which&XkbRGNamesMask)&&(nTotalRG>0)) {
- if (names->radio_groups==NULL) {
- names->radio_groups= xcalloc(nTotalRG, sizeof(Atom));
- }
- else if (nTotalRG>names->num_rg) {
- Atom *prev_radio_groups = names->radio_groups;
-
- names->radio_groups= xrealloc(names->radio_groups,
- nTotalRG * sizeof(Atom));
- if (names->radio_groups!=NULL) {
- memset(&names->radio_groups[names->num_rg], 0,
- (nTotalRG - names->num_rg) * sizeof(Atom));
- } else {
- xfree(prev_radio_groups);
- }
- }
- if (names->radio_groups==NULL)
- return BadAlloc;
- names->num_rg= nTotalRG;
- }
- return Success;
-}
-
-void
-XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap)
-{
-XkbNamesPtr names;
-
- if ((xkb==NULL)||(xkb->names==NULL))
- return;
- names= xkb->names;
- if (freeMap)
- which= XkbAllNamesMask;
- if (which&XkbKTLevelNamesMask) {
- XkbClientMapPtr map= xkb->map;
- if ((map!=NULL)&&(map->types!=NULL)) {
- register int i;
- register XkbKeyTypePtr type;
- type= map->types;
- for (i=0;i<map->num_types;i++,type++) {
- if (type->level_names!=NULL) {
- xfree(type->level_names);
- type->level_names= NULL;
- }
- }
- }
- }
- if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
- xfree(names->keys);
- names->keys= NULL;
- names->num_keys= 0;
- }
- if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){
- xfree(names->key_aliases);
- names->key_aliases=NULL;
- names->num_key_aliases=0;
- }
- if ((which&XkbRGNamesMask)&&(names->radio_groups)) {
- xfree(names->radio_groups);
- names->radio_groups= NULL;
- names->num_rg= 0;
- }
- if (freeMap) {
- xfree(names);
- xkb->names= NULL;
- }
- return;
-}
-
-/***===================================================================***/
-
-/*ARGSUSED*/
-Status
-XkbAllocControls(XkbDescPtr xkb,unsigned which)
-{
- if (xkb==NULL)
- return BadMatch;
-
- if (xkb->ctrls==NULL) {
- xkb->ctrls= xcalloc(1, sizeof(XkbControlsRec));
- if (!xkb->ctrls)
- return BadAlloc;
- }
- return Success;
-}
-
-/*ARGSUSED*/
-static void
-XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap)
-{
- if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) {
- xfree(xkb->ctrls);
- xkb->ctrls= NULL;
- }
- return;
-}
-
-/***===================================================================***/
-
-Status
-XkbAllocIndicatorMaps(XkbDescPtr xkb)
-{
- if (xkb==NULL)
- return BadMatch;
- if (xkb->indicators==NULL) {
- xkb->indicators= xcalloc(1, sizeof(XkbIndicatorRec));
- if (!xkb->indicators)
- return BadAlloc;
- }
- return Success;
-}
-
-static void
-XkbFreeIndicatorMaps(XkbDescPtr xkb)
-{
- if ((xkb!=NULL)&&(xkb->indicators!=NULL)) {
- xfree(xkb->indicators);
- xkb->indicators= NULL;
- }
- return;
-}
-
-/***====================================================================***/
-
-XkbDescRec *
-XkbAllocKeyboard(void)
-{
-XkbDescRec *xkb;
-
- xkb = xcalloc(1, sizeof(XkbDescRec));
- if (xkb)
- xkb->device_spec= XkbUseCoreKbd;
- return xkb;
-}
-
-void
-XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll)
-{
- if (xkb==NULL)
- return;
- if (freeAll)
- which= XkbAllComponentsMask;
- if (which&XkbClientMapMask)
- XkbFreeClientMap(xkb,XkbAllClientInfoMask,TRUE);
- if (which&XkbServerMapMask)
- XkbFreeServerMap(xkb,XkbAllServerInfoMask,TRUE);
- if (which&XkbCompatMapMask)
- XkbFreeCompatMap(xkb,XkbAllCompatMask,TRUE);
- if (which&XkbIndicatorMapMask)
- XkbFreeIndicatorMaps(xkb);
- if (which&XkbNamesMask)
- XkbFreeNames(xkb,XkbAllNamesMask,TRUE);
- if ((which&XkbGeometryMask) && (xkb->geom!=NULL)) {
- XkbFreeGeometry(xkb->geom,XkbGeomAllMask,TRUE);
- /* PERHAPS BONGHITS etc */
- xkb->geom = NULL;
- }
- if (which&XkbControlsMask)
- XkbFreeControls(xkb,XkbAllControlsMask,TRUE);
- if (freeAll)
- xfree(xkb);
- return;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+#include <os.h>
+#include <string.h>
+
+/***===================================================================***/
+
+/*ARGSUSED*/
+Status
+XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI)
+{
+XkbCompatMapPtr compat;
+XkbSymInterpretRec *prev_interpret;
+
+ if (!xkb)
+ return BadMatch;
+ if (xkb->compat) {
+ if (xkb->compat->size_si>=nSI)
+ return Success;
+ compat= xkb->compat;
+ compat->size_si= nSI;
+ if (compat->sym_interpret==NULL)
+ compat->num_si= 0;
+ prev_interpret = compat->sym_interpret;
+ compat->sym_interpret= realloc(compat->sym_interpret,
+ nSI * sizeof(XkbSymInterpretRec));
+ if (compat->sym_interpret==NULL) {
+ free(prev_interpret);
+ compat->size_si= compat->num_si= 0;
+ return BadAlloc;
+ }
+ if (compat->num_si!=0) {
+ memset(&compat->sym_interpret[compat->num_si], 0,
+ (compat->size_si - compat->num_si) * sizeof(XkbSymInterpretRec));
+ }
+ return Success;
+ }
+ compat= calloc(1, sizeof(XkbCompatMapRec));
+ if (compat==NULL)
+ return BadAlloc;
+ if (nSI>0) {
+ compat->sym_interpret= calloc(nSI, sizeof(XkbSymInterpretRec));
+ if (!compat->sym_interpret) {
+ free(compat);
+ return BadAlloc;
+ }
+ }
+ compat->size_si= nSI;
+ compat->num_si= 0;
+ bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
+ xkb->compat= compat;
+ return Success;
+}
+
+
+void
+XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap)
+{
+register XkbCompatMapPtr compat;
+
+ if ((xkb==NULL)||(xkb->compat==NULL))
+ return;
+ compat= xkb->compat;
+ if (freeMap)
+ which= XkbAllCompatMask;
+ if (which&XkbGroupCompatMask)
+ bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
+ if (which&XkbSymInterpMask) {
+ if ((compat->sym_interpret)&&(compat->size_si>0))
+ free(compat->sym_interpret);
+ compat->size_si= compat->num_si= 0;
+ compat->sym_interpret= NULL;
+ }
+ if (freeMap) {
+ free(compat);
+ xkb->compat= NULL;
+ }
+ return;
+}
+
+/***===================================================================***/
+
+Status
+XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases)
+{
+XkbNamesPtr names;
+
+ if (xkb==NULL)
+ return BadMatch;
+ if (xkb->names==NULL) {
+ xkb->names = calloc(1, sizeof(XkbNamesRec));
+ if (xkb->names==NULL)
+ return BadAlloc;
+ }
+ names= xkb->names;
+ if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){
+ register int i;
+ XkbKeyTypePtr type;
+
+ type= xkb->map->types;
+ for (i=0;i<xkb->map->num_types;i++,type++) {
+ if (type->level_names==NULL) {
+ type->level_names= calloc(type->num_levels, sizeof(Atom));
+ if (type->level_names==NULL)
+ return BadAlloc;
+ }
+ }
+ }
+ if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadValue;
+ names->keys= calloc((xkb->max_key_code+1), sizeof(XkbKeyNameRec));
+ if (names->keys==NULL)
+ return BadAlloc;
+ }
+ if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) {
+ if (names->key_aliases==NULL) {
+ names->key_aliases= calloc(nTotalAliases, sizeof(XkbKeyAliasRec));
+ }
+ else if (nTotalAliases>names->num_key_aliases) {
+ XkbKeyAliasRec *prev_aliases = names->key_aliases;
+
+ names->key_aliases= realloc(names->key_aliases,
+ nTotalAliases * sizeof(XkbKeyAliasRec));
+ if (names->key_aliases!=NULL) {
+ memset(&names->key_aliases[names->num_key_aliases], 0,
+ (nTotalAliases - names->num_key_aliases) * sizeof(XkbKeyAliasRec));
+ } else {
+ free(prev_aliases);
+ }
+ }
+ if (names->key_aliases==NULL) {
+ names->num_key_aliases= 0;
+ return BadAlloc;
+ }
+ names->num_key_aliases= nTotalAliases;
+ }
+ if ((which&XkbRGNamesMask)&&(nTotalRG>0)) {
+ if (names->radio_groups==NULL) {
+ names->radio_groups= calloc(nTotalRG, sizeof(Atom));
+ }
+ else if (nTotalRG>names->num_rg) {
+ Atom *prev_radio_groups = names->radio_groups;
+
+ names->radio_groups= realloc(names->radio_groups,
+ nTotalRG * sizeof(Atom));
+ if (names->radio_groups!=NULL) {
+ memset(&names->radio_groups[names->num_rg], 0,
+ (nTotalRG - names->num_rg) * sizeof(Atom));
+ } else {
+ free(prev_radio_groups);
+ }
+ }
+ if (names->radio_groups==NULL)
+ return BadAlloc;
+ names->num_rg= nTotalRG;
+ }
+ return Success;
+}
+
+void
+XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap)
+{
+XkbNamesPtr names;
+
+ if ((xkb==NULL)||(xkb->names==NULL))
+ return;
+ names= xkb->names;
+ if (freeMap)
+ which= XkbAllNamesMask;
+ if (which&XkbKTLevelNamesMask) {
+ XkbClientMapPtr map= xkb->map;
+ if ((map!=NULL)&&(map->types!=NULL)) {
+ register int i;
+ register XkbKeyTypePtr type;
+ type= map->types;
+ for (i=0;i<map->num_types;i++,type++) {
+ if (type->level_names!=NULL) {
+ free(type->level_names);
+ type->level_names= NULL;
+ }
+ }
+ }
+ }
+ if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
+ free(names->keys);
+ names->keys= NULL;
+ names->num_keys= 0;
+ }
+ if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){
+ free(names->key_aliases);
+ names->key_aliases=NULL;
+ names->num_key_aliases=0;
+ }
+ if ((which&XkbRGNamesMask)&&(names->radio_groups)) {
+ free(names->radio_groups);
+ names->radio_groups= NULL;
+ names->num_rg= 0;
+ }
+ if (freeMap) {
+ free(names);
+ xkb->names= NULL;
+ }
+ return;
+}
+
+/***===================================================================***/
+
+/*ARGSUSED*/
+Status
+XkbAllocControls(XkbDescPtr xkb,unsigned which)
+{
+ if (xkb==NULL)
+ return BadMatch;
+
+ if (xkb->ctrls==NULL) {
+ xkb->ctrls= calloc(1, sizeof(XkbControlsRec));
+ if (!xkb->ctrls)
+ return BadAlloc;
+ }
+ return Success;
+}
+
+/*ARGSUSED*/
+static void
+XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap)
+{
+ if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) {
+ free(xkb->ctrls);
+ xkb->ctrls= NULL;
+ }
+ return;
+}
+
+/***===================================================================***/
+
+Status
+XkbAllocIndicatorMaps(XkbDescPtr xkb)
+{
+ if (xkb==NULL)
+ return BadMatch;
+ if (xkb->indicators==NULL) {
+ xkb->indicators= calloc(1, sizeof(XkbIndicatorRec));
+ if (!xkb->indicators)
+ return BadAlloc;
+ }
+ return Success;
+}
+
+static void
+XkbFreeIndicatorMaps(XkbDescPtr xkb)
+{
+ if ((xkb!=NULL)&&(xkb->indicators!=NULL)) {
+ free(xkb->indicators);
+ xkb->indicators= NULL;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+XkbDescRec *
+XkbAllocKeyboard(void)
+{
+XkbDescRec *xkb;
+
+ xkb = calloc(1, sizeof(XkbDescRec));
+ if (xkb)
+ xkb->device_spec= XkbUseCoreKbd;
+ return xkb;
+}
+
+void
+XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll)
+{
+ if (xkb==NULL)
+ return;
+ if (freeAll)
+ which= XkbAllComponentsMask;
+ if (which&XkbClientMapMask)
+ XkbFreeClientMap(xkb,XkbAllClientInfoMask,TRUE);
+ if (which&XkbServerMapMask)
+ XkbFreeServerMap(xkb,XkbAllServerInfoMask,TRUE);
+ if (which&XkbCompatMapMask)
+ XkbFreeCompatMap(xkb,XkbAllCompatMask,TRUE);
+ if (which&XkbIndicatorMapMask)
+ XkbFreeIndicatorMaps(xkb);
+ if (which&XkbNamesMask)
+ XkbFreeNames(xkb,XkbAllNamesMask,TRUE);
+ if ((which&XkbGeometryMask) && (xkb->geom!=NULL)) {
+ XkbFreeGeometry(xkb->geom,XkbGeomAllMask,TRUE);
+ /* PERHAPS BONGHITS etc */
+ xkb->geom = NULL;
+ }
+ if (which&XkbControlsMask)
+ XkbFreeControls(xkb,XkbAllControlsMask,TRUE);
+ if (freeAll)
+ free(xkb);
+ return;
+}
diff --git a/xorg-server/xkb/XKBGAlloc.c b/xorg-server/xkb/XKBGAlloc.c
index b01005dd0..4dc3e7017 100644
--- a/xorg-server/xkb/XKBGAlloc.c
+++ b/xorg-server/xkb/XKBGAlloc.c
@@ -1,997 +1,997 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-#include <xkbsrv.h>
-#include "xkbgeom.h"
-
-/***====================================================================***/
-
-static void
-_XkbFreeGeomLeafElems( Bool freeAll,
- int first,
- int count,
- unsigned short * num_inout,
- unsigned short * sz_inout,
- char ** elems,
- unsigned int elem_sz)
-{
- if ((freeAll)||(*elems==NULL)) {
- *num_inout= *sz_inout= 0;
- if (*elems!=NULL) {
- xfree(*elems);
- *elems= NULL;
- }
- return;
- }
-
- if ((first>=(*num_inout))||(first<0)||(count<1))
- return;
-
- if (first+count>=(*num_inout)) {
- /* truncating the array is easy */
- (*num_inout)= first;
- }
- else {
- char * ptr;
- int extra;
- ptr= *elems;
- extra= ((*num_inout)-(first+count))*elem_sz;
- if (extra>0)
- memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
- (*num_inout)-= count;
- }
- return;
-}
-
-typedef void (*ContentsClearFunc)(
- char * /* priv */
-);
-
-static void
-_XkbFreeGeomNonLeafElems( Bool freeAll,
- int first,
- int count,
- unsigned short * num_inout,
- unsigned short * sz_inout,
- char ** elems,
- unsigned int elem_sz,
- ContentsClearFunc freeFunc)
-{
-register int i;
-register char *ptr;
-
- if (freeAll) {
- first= 0;
- count= (*num_inout);
- }
- else if ((first>=(*num_inout))||(first<0)||(count<1))
- return;
- else if (first+count>(*num_inout))
- count= (*num_inout)-first;
- if (*elems==NULL)
- return;
-
- if (freeFunc) {
- ptr= *elems;
- ptr+= first*elem_sz;
- for (i=0;i<count;i++) {
- (*freeFunc)(ptr);
- ptr+= elem_sz;
- }
- }
- if (freeAll) {
- (*num_inout)= (*sz_inout)= 0;
- if (*elems) {
- xfree(*elems);
- *elems= NULL;
- }
- }
- else if (first+count>=(*num_inout))
- *num_inout= first;
- else {
- i= ((*num_inout)-(first+count))*elem_sz;
- ptr= *elems;
- memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
- (*num_inout)-= count;
- }
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearProperty(char *prop_in)
-{
-XkbPropertyPtr prop= (XkbPropertyPtr)prop_in;
-
- if (prop->name) {
- xfree(prop->name);
- prop->name= NULL;
- }
- if (prop->value) {
- xfree(prop->value);
- prop->value= NULL;
- }
- return;
-}
-
-void
-XkbFreeGeomProperties( XkbGeometryPtr geom,
- int first,
- int count,
- Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &geom->num_properties,&geom->sz_properties,
- (char **)&geom->properties,
- sizeof(XkbPropertyRec),_XkbClearProperty);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbFreeGeomKeyAliases( XkbGeometryPtr geom,
- int first,
- int count,
- Bool freeAll)
-{
- _XkbFreeGeomLeafElems(freeAll,first,count,
- &geom->num_key_aliases,&geom->sz_key_aliases,
- (char **)&geom->key_aliases,
- sizeof(XkbKeyAliasRec));
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearColor(char *color_in)
-{
-XkbColorPtr color= (XkbColorPtr)color_in;
-
- if (color->spec)
- xfree(color->spec);
- return;
-}
-
-void
-XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &geom->num_colors,&geom->sz_colors,
- (char **)&geom->colors,
- sizeof(XkbColorRec),_XkbClearColor);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomLeafElems(freeAll,first,count,
- &outline->num_points,&outline->sz_points,
- (char **)&outline->points,
- sizeof(XkbPointRec));
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearOutline(char *outline_in)
-{
-XkbOutlinePtr outline= (XkbOutlinePtr)outline_in;
-
- if (outline->points!=NULL)
- XkbFreeGeomPoints(outline,0,outline->num_points,TRUE);
- return;
-}
-
-void
-XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &shape->num_outlines,&shape->sz_outlines,
- (char **)&shape->outlines,
- sizeof(XkbOutlineRec),_XkbClearOutline);
-
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearShape(char *shape_in)
-{
-XkbShapePtr shape= (XkbShapePtr)shape_in;
-
- if (shape->outlines)
- XkbFreeGeomOutlines(shape,0,shape->num_outlines,TRUE);
- return;
-}
-
-void
-XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &geom->num_shapes,&geom->sz_shapes,
- (char **)&geom->shapes,
- sizeof(XkbShapeRec),_XkbClearShape);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomLeafElems(freeAll,first,count,
- &row->num_keys,&row->sz_keys,
- (char **)&row->keys,
- sizeof(XkbOverlayKeyRec));
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearOverlayRow(char *row_in)
-{
-XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in;
-
- if (row->keys!=NULL)
- XkbFreeGeomOverlayKeys(row,0,row->num_keys,TRUE);
- return;
-}
-
-void
-XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &overlay->num_rows,&overlay->sz_rows,
- (char **)&overlay->rows,
- sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearOverlay(char *overlay_in)
-{
-XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in;
-
- if (overlay->rows!=NULL)
- XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,TRUE);
- return;
-}
-
-void
-XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &section->num_overlays,&section->sz_overlays,
- (char **)&section->overlays,
- sizeof(XkbOverlayRec),_XkbClearOverlay);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomLeafElems(freeAll,first,count,
- &row->num_keys,&row->sz_keys,
- (char **)&row->keys,
- sizeof(XkbKeyRec));
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearRow(char *row_in)
-{
-XkbRowPtr row= (XkbRowPtr)row_in;
-
- if (row->keys!=NULL)
- XkbFreeGeomKeys(row,0,row->num_keys,TRUE);
- return;
-}
-
-void
-XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &section->num_rows,&section->sz_rows,
- (char **)&section->rows,
- sizeof(XkbRowRec),_XkbClearRow);
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearSection(char *section_in)
-{
-XkbSectionPtr section= (XkbSectionPtr)section_in;
-
- if (section->rows!=NULL)
- XkbFreeGeomRows(section,0,section->num_rows,TRUE);
- if (section->doodads!=NULL) {
- XkbFreeGeomDoodads(section->doodads,section->num_doodads,TRUE);
- section->doodads= NULL;
- }
- return;
-}
-
-void
-XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
-{
- _XkbFreeGeomNonLeafElems(freeAll,first,count,
- &geom->num_sections,&geom->sz_sections,
- (char **)&geom->sections,
- sizeof(XkbSectionRec),_XkbClearSection);
- return;
-}
-
-/***====================================================================***/
-
-static void
-_XkbClearDoodad(char *doodad_in)
-{
-XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in;
-
- switch (doodad->any.type) {
- case XkbTextDoodad:
- {
- if (doodad->text.text!=NULL) {
- xfree(doodad->text.text);
- doodad->text.text= NULL;
- }
- if (doodad->text.font!=NULL) {
- xfree(doodad->text.font);
- doodad->text.font= NULL;
- }
- }
- break;
- case XkbLogoDoodad:
- {
- if (doodad->logo.logo_name!=NULL) {
- xfree(doodad->logo.logo_name);
- doodad->logo.logo_name= NULL;
- }
- }
- break;
- }
- return;
-}
-
-void
-XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
-{
-register int i;
-register XkbDoodadPtr doodad;
-
- if (doodads) {
- for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
- _XkbClearDoodad((char *)doodad);
- }
- if (freeAll)
- xfree(doodads);
- }
- return;
-}
-
-void
-XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
-{
- if (geom==NULL)
- return;
- if (freeMap)
- which= XkbGeomAllMask;
- if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
- XkbFreeGeomProperties(geom,0,geom->num_properties,TRUE);
- if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
- XkbFreeGeomColors(geom,0,geom->num_colors,TRUE);
- if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
- XkbFreeGeomShapes(geom,0,geom->num_shapes,TRUE);
- if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
- XkbFreeGeomSections(geom,0,geom->num_sections,TRUE);
- if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
- XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,TRUE);
- geom->doodads= NULL;
- geom->num_doodads= geom->sz_doodads= 0;
- }
- if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
- XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,TRUE);
- if (freeMap) {
- if (geom->label_font!=NULL) {
- xfree(geom->label_font);
- geom->label_font= NULL;
- }
- xfree(geom);
- }
- return;
-}
-
-/***====================================================================***/
-
-static Status
-_XkbGeomAlloc( void ** old,
- unsigned short * num,
- unsigned short * total,
- int num_new,
- size_t sz_elem)
-{
- if (num_new<1)
- return Success;
- if ((*old)==NULL)
- *num= *total= 0;
-
- if ((*num)+num_new<=(*total))
- return Success;
-
- *total= (*num)+num_new;
- if ((*old)!=NULL)
- (*old)= xrealloc((*old),(*total)*sz_elem);
- else (*old)= xcalloc((*total),sz_elem);
- if ((*old)==NULL) {
- *total= *num= 0;
- return BadAlloc;
- }
-
- if (*num>0) {
- char *tmp= (char *)(*old);
- bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
- }
- return Success;
-}
-
-#define _XkbAllocProps(g,n) _XkbGeomAlloc((void *)&(g)->properties,\
- &(g)->num_properties,&(g)->sz_properties,\
- (n),sizeof(XkbPropertyRec))
-#define _XkbAllocColors(g,n) _XkbGeomAlloc((void *)&(g)->colors,\
- &(g)->num_colors,&(g)->sz_colors,\
- (n),sizeof(XkbColorRec))
-#define _XkbAllocShapes(g,n) _XkbGeomAlloc((void *)&(g)->shapes,\
- &(g)->num_shapes,&(g)->sz_shapes,\
- (n),sizeof(XkbShapeRec))
-#define _XkbAllocSections(g,n) _XkbGeomAlloc((void *)&(g)->sections,\
- &(g)->num_sections,&(g)->sz_sections,\
- (n),sizeof(XkbSectionRec))
-#define _XkbAllocDoodads(g,n) _XkbGeomAlloc((void *)&(g)->doodads,\
- &(g)->num_doodads,&(g)->sz_doodads,\
- (n),sizeof(XkbDoodadRec))
-#define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((void *)&(g)->key_aliases,\
- &(g)->num_key_aliases,&(g)->sz_key_aliases,\
- (n),sizeof(XkbKeyAliasRec))
-
-#define _XkbAllocOutlines(s,n) _XkbGeomAlloc((void *)&(s)->outlines,\
- &(s)->num_outlines,&(s)->sz_outlines,\
- (n),sizeof(XkbOutlineRec))
-#define _XkbAllocRows(s,n) _XkbGeomAlloc((void *)&(s)->rows,\
- &(s)->num_rows,&(s)->sz_rows,\
- (n),sizeof(XkbRowRec))
-#define _XkbAllocPoints(o,n) _XkbGeomAlloc((void *)&(o)->points,\
- &(o)->num_points,&(o)->sz_points,\
- (n),sizeof(XkbPointRec))
-#define _XkbAllocKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\
- &(r)->num_keys,&(r)->sz_keys,\
- (n),sizeof(XkbKeyRec))
-#define _XkbAllocOverlays(s,n) _XkbGeomAlloc((void *)&(s)->overlays,\
- &(s)->num_overlays,&(s)->sz_overlays,\
- (n),sizeof(XkbOverlayRec))
-#define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((void *)&(o)->rows,\
- &(o)->num_rows,&(o)->sz_rows,\
- (n),sizeof(XkbOverlayRowRec))
-#define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\
- &(r)->num_keys,&(r)->sz_keys,\
- (n),sizeof(XkbOverlayKeyRec))
-
-Status
-XkbAllocGeomProps(XkbGeometryPtr geom,int nProps)
-{
- return _XkbAllocProps(geom,nProps);
-}
-
-Status
-XkbAllocGeomColors(XkbGeometryPtr geom,int nColors)
-{
- return _XkbAllocColors(geom,nColors);
-}
-
-Status
-XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases)
-{
- return _XkbAllocKeyAliases(geom,nKeyAliases);
-}
-
-Status
-XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes)
-{
- return _XkbAllocShapes(geom,nShapes);
-}
-
-Status
-XkbAllocGeomSections(XkbGeometryPtr geom,int nSections)
-{
- return _XkbAllocSections(geom,nSections);
-}
-
-Status
-XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays)
-{
- return _XkbAllocOverlays(section,nOverlays);
-}
-
-Status
-XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows)
-{
- return _XkbAllocOverlayRows(overlay,nRows);
-}
-
-Status
-XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys)
-{
- return _XkbAllocOverlayKeys(row,nKeys);
-}
-
-Status
-XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads)
-{
- return _XkbAllocDoodads(geom,nDoodads);
-}
-
-Status
-XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads)
-{
- return _XkbAllocDoodads(section,nDoodads);
-}
-
-Status
-XkbAllocGeomOutlines(XkbShapePtr shape,int nOL)
-{
- return _XkbAllocOutlines(shape,nOL);
-}
-
-Status
-XkbAllocGeomRows(XkbSectionPtr section,int nRows)
-{
- return _XkbAllocRows(section,nRows);
-}
-
-Status
-XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts)
-{
- return _XkbAllocPoints(ol,nPts);
-}
-
-Status
-XkbAllocGeomKeys(XkbRowPtr row,int nKeys)
-{
- return _XkbAllocKeys(row,nKeys);
-}
-
-Status
-XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes)
-{
-XkbGeometryPtr geom;
-Status rtrn;
-
- if (xkb->geom==NULL) {
- xkb->geom= xcalloc(1, sizeof(XkbGeometryRec));
- if (!xkb->geom)
- return BadAlloc;
- }
- geom= xkb->geom;
- if ((sizes->which&XkbGeomPropertiesMask)&&
- ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
- goto BAIL;
- }
- if ((sizes->which&XkbGeomColorsMask)&&
- ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
- goto BAIL;
- }
- if ((sizes->which&XkbGeomShapesMask)&&
- ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
- goto BAIL;
- }
- if ((sizes->which&XkbGeomSectionsMask)&&
- ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
- goto BAIL;
- }
- if ((sizes->which&XkbGeomDoodadsMask)&&
- ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
- goto BAIL;
- }
- if ((sizes->which&XkbGeomKeyAliasesMask)&&
- ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
- goto BAIL;
- }
- return Success;
-BAIL:
- XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
- xkb->geom= NULL;
- return rtrn;
-}
-
-/***====================================================================***/
-
-XkbPropertyPtr
-XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value)
-{
-register int i;
-register XkbPropertyPtr prop;
-
- if ((!geom)||(!name)||(!value))
- return NULL;
- for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
- if ((prop->name)&&(strcmp(name,prop->name)==0)) {
- if (prop->value)
- xfree(prop->value);
- prop->value= xalloc(strlen(value)+1);
- if (prop->value)
- strcpy(prop->value,value);
- return prop;
- }
- }
- if ((geom->num_properties>=geom->sz_properties)&&
- (_XkbAllocProps(geom,1)!=Success)) {
- return NULL;
- }
- prop= &geom->properties[geom->num_properties];
- prop->name= xalloc(strlen(name)+1);
- if (!name)
- return NULL;
- strcpy(prop->name,name);
- prop->value= xalloc(strlen(value)+1);
- if (!value) {
- xfree(prop->name);
- prop->name= NULL;
- return NULL;
- }
- strcpy(prop->value,value);
- geom->num_properties++;
- return prop;
-}
-
-XkbKeyAliasPtr
-XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr)
-{
-register int i;
-register XkbKeyAliasPtr alias;
-
- if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0]))
- return NULL;
- for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) {
- if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) {
- bzero(alias->real,XkbKeyNameLength);
- strncpy(alias->real,realStr,XkbKeyNameLength);
- return alias;
- }
- }
- if ((geom->num_key_aliases>=geom->sz_key_aliases)&&
- (_XkbAllocKeyAliases(geom,1)!=Success)) {
- return NULL;
- }
- alias= &geom->key_aliases[geom->num_key_aliases];
- bzero(alias,sizeof(XkbKeyAliasRec));
- strncpy(alias->alias,aliasStr,XkbKeyNameLength);
- strncpy(alias->real,realStr,XkbKeyNameLength);
- geom->num_key_aliases++;
- return alias;
-}
-
-XkbColorPtr
-XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel)
-{
-register int i;
-register XkbColorPtr color;
-
- if ((!geom)||(!spec))
- return NULL;
- for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
- if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
- color->pixel= pixel;
- return color;
- }
- }
- if ((geom->num_colors>=geom->sz_colors)&&
- (_XkbAllocColors(geom,1)!=Success)) {
- return NULL;
- }
- color= &geom->colors[geom->num_colors];
- color->pixel= pixel;
- color->spec= xalloc(strlen(spec)+1);
- if (!color->spec)
- return NULL;
- strcpy(color->spec,spec);
- geom->num_colors++;
- return color;
-}
-
-XkbOutlinePtr
-XkbAddGeomOutline(XkbShapePtr shape,int sz_points)
-{
-XkbOutlinePtr outline;
-
- if ((!shape)||(sz_points<0))
- return NULL;
- if ((shape->num_outlines>=shape->sz_outlines)&&
- (_XkbAllocOutlines(shape,1)!=Success)) {
- return NULL;
- }
- outline= &shape->outlines[shape->num_outlines];
- bzero(outline,sizeof(XkbOutlineRec));
- if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
- return NULL;
- shape->num_outlines++;
- return outline;
-}
-
-XkbShapePtr
-XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines)
-{
-XkbShapePtr shape;
-register int i;
-
- if ((!geom)||(!name)||(sz_outlines<0))
- return NULL;
- if (geom->num_shapes>0) {
- for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
- if (name==shape->name)
- return shape;
- }
- }
- if ((geom->num_shapes>=geom->sz_shapes)&&
- (_XkbAllocShapes(geom,1)!=Success))
- return NULL;
- shape= &geom->shapes[geom->num_shapes];
- bzero(shape,sizeof(XkbShapeRec));
- if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
- return NULL;
- shape->name= name;
- shape->primary= shape->approx= NULL;
- geom->num_shapes++;
- return shape;
-}
-
-XkbKeyPtr
-XkbAddGeomKey(XkbRowPtr row)
-{
-XkbKeyPtr key;
- if (!row)
- return NULL;
- if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
- return NULL;
- key= &row->keys[row->num_keys++];
- bzero(key,sizeof(XkbKeyRec));
- return key;
-}
-
-XkbRowPtr
-XkbAddGeomRow(XkbSectionPtr section,int sz_keys)
-{
-XkbRowPtr row;
-
- if ((!section)||(sz_keys<0))
- return NULL;
- if ((section->num_rows>=section->sz_rows)&&
- (_XkbAllocRows(section,1)!=Success))
- return NULL;
- row= &section->rows[section->num_rows];
- bzero(row,sizeof(XkbRowRec));
- if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
- return NULL;
- section->num_rows++;
- return row;
-}
-
-XkbSectionPtr
-XkbAddGeomSection( XkbGeometryPtr geom,
- Atom name,
- int sz_rows,
- int sz_doodads,
- int sz_over)
-{
-register int i;
-XkbSectionPtr section;
-
- if ((!geom)||(name==None)||(sz_rows<0))
- return NULL;
- for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
- if (section->name!=name)
- continue;
- if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
- ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
- ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
- return NULL;
- return section;
- }
- if ((geom->num_sections>=geom->sz_sections)&&
- (_XkbAllocSections(geom,1)!=Success))
- return NULL;
- section= &geom->sections[geom->num_sections];
- if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
- return NULL;
- if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
- if (section->rows) {
- xfree(section->rows);
- section->rows= NULL;
- section->sz_rows= section->num_rows= 0;
- }
- return NULL;
- }
- section->name= name;
- geom->num_sections++;
- return section;
-}
-
-XkbDoodadPtr
-XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name)
-{
-XkbDoodadPtr old,doodad;
-register int i,nDoodads;
-
- if ((!geom)||(name==None))
- return NULL;
- if ((section!=NULL)&&(section->num_doodads>0)) {
- old= section->doodads;
- nDoodads= section->num_doodads;
- }
- else {
- old= geom->doodads;
- nDoodads= geom->num_doodads;
- }
- for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
- if (doodad->any.name==name)
- return doodad;
- }
- if (section) {
- if ((section->num_doodads>=geom->sz_doodads)&&
- (_XkbAllocDoodads(section,1)!=Success)) {
- return NULL;
- }
- doodad= &section->doodads[section->num_doodads++];
- }
- else {
- if ((geom->num_doodads>=geom->sz_doodads)&&
- (_XkbAllocDoodads(geom,1)!=Success))
- return NULL;
- doodad= &geom->doodads[geom->num_doodads++];
- }
- bzero(doodad,sizeof(XkbDoodadRec));
- doodad->any.name= name;
- return doodad;
-}
-
-XkbOverlayKeyPtr
-XkbAddGeomOverlayKey( XkbOverlayPtr overlay,
- XkbOverlayRowPtr row,
- char * over,
- char * under)
-{
-register int i;
-XkbOverlayKeyPtr key;
-XkbSectionPtr section;
-XkbRowPtr row_under;
-Bool found;
-
- if ((!overlay)||(!row)||(!over)||(!under))
- return NULL;
- section= overlay->section_under;
- if (row->row_under>=section->num_rows)
- return NULL;
- row_under= &section->rows[row->row_under];
- for (i=0,found=FALSE;i<row_under->num_keys;i++) {
- if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) {
- found= TRUE;
- break;
- }
- }
- if (!found)
- return NULL;
- if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success))
- return NULL;
- key= &row->keys[row->num_keys];
- strncpy(key->under.name,under,XkbKeyNameLength);
- strncpy(key->over.name,over,XkbKeyNameLength);
- row->num_keys++;
- return key;
-}
-
-XkbOverlayRowPtr
-XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys)
-{
-register int i;
-XkbOverlayRowPtr row;
-
- if ((!overlay)||(sz_keys<0))
- return NULL;
- if (row_under>=overlay->section_under->num_rows)
- return NULL;
- for (i=0;i<overlay->num_rows;i++) {
- if (overlay->rows[i].row_under==row_under) {
- row= &overlay->rows[i];
- if ((row->sz_keys<sz_keys)&&
- (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
- return NULL;
- }
- return &overlay->rows[i];
- }
- }
- if ((overlay->num_rows>=overlay->sz_rows)&&
- (_XkbAllocOverlayRows(overlay,1)!=Success))
- return NULL;
- row= &overlay->rows[overlay->num_rows];
- bzero(row,sizeof(XkbOverlayRowRec));
- if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
- return NULL;
- row->row_under= row_under;
- overlay->num_rows++;
- return row;
-}
-
-XkbOverlayPtr
-XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows)
-{
-register int i;
-XkbOverlayPtr overlay;
-
- if ((!section)||(name==None)||(sz_rows==0))
- return NULL;
-
- for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
- if (overlay->name==name) {
- if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
- return NULL;
- return overlay;
- }
- }
- if ((section->num_overlays>=section->sz_overlays)&&
- (_XkbAllocOverlays(section,1)!=Success))
- return NULL;
- overlay= &section->overlays[section->num_overlays];
- if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
- return NULL;
- overlay->name= name;
- overlay->section_under= section;
- section->num_overlays++;
- return overlay;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+
+/***====================================================================***/
+
+static void
+_XkbFreeGeomLeafElems( Bool freeAll,
+ int first,
+ int count,
+ unsigned short * num_inout,
+ unsigned short * sz_inout,
+ char ** elems,
+ unsigned int elem_sz)
+{
+ if ((freeAll)||(*elems==NULL)) {
+ *num_inout= *sz_inout= 0;
+ if (*elems!=NULL) {
+ free(*elems);
+ *elems= NULL;
+ }
+ return;
+ }
+
+ if ((first>=(*num_inout))||(first<0)||(count<1))
+ return;
+
+ if (first+count>=(*num_inout)) {
+ /* truncating the array is easy */
+ (*num_inout)= first;
+ }
+ else {
+ char * ptr;
+ int extra;
+ ptr= *elems;
+ extra= ((*num_inout)-(first+count))*elem_sz;
+ if (extra>0)
+ memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
+ (*num_inout)-= count;
+ }
+ return;
+}
+
+typedef void (*ContentsClearFunc)(
+ char * /* priv */
+);
+
+static void
+_XkbFreeGeomNonLeafElems( Bool freeAll,
+ int first,
+ int count,
+ unsigned short * num_inout,
+ unsigned short * sz_inout,
+ char ** elems,
+ unsigned int elem_sz,
+ ContentsClearFunc freeFunc)
+{
+register int i;
+register char *ptr;
+
+ if (freeAll) {
+ first= 0;
+ count= (*num_inout);
+ }
+ else if ((first>=(*num_inout))||(first<0)||(count<1))
+ return;
+ else if (first+count>(*num_inout))
+ count= (*num_inout)-first;
+ if (*elems==NULL)
+ return;
+
+ if (freeFunc) {
+ ptr= *elems;
+ ptr+= first*elem_sz;
+ for (i=0;i<count;i++) {
+ (*freeFunc)(ptr);
+ ptr+= elem_sz;
+ }
+ }
+ if (freeAll) {
+ (*num_inout)= (*sz_inout)= 0;
+ if (*elems) {
+ free(*elems);
+ *elems= NULL;
+ }
+ }
+ else if (first+count>=(*num_inout))
+ *num_inout= first;
+ else {
+ i= ((*num_inout)-(first+count))*elem_sz;
+ ptr= *elems;
+ memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
+ (*num_inout)-= count;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearProperty(char *prop_in)
+{
+XkbPropertyPtr prop= (XkbPropertyPtr)prop_in;
+
+ if (prop->name) {
+ free(prop->name);
+ prop->name= NULL;
+ }
+ if (prop->value) {
+ free(prop->value);
+ prop->value= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeGeomProperties( XkbGeometryPtr geom,
+ int first,
+ int count,
+ Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_properties,&geom->sz_properties,
+ (char **)&geom->properties,
+ sizeof(XkbPropertyRec),_XkbClearProperty);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomKeyAliases( XkbGeometryPtr geom,
+ int first,
+ int count,
+ Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &geom->num_key_aliases,&geom->sz_key_aliases,
+ (char **)&geom->key_aliases,
+ sizeof(XkbKeyAliasRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearColor(char *color_in)
+{
+XkbColorPtr color= (XkbColorPtr)color_in;
+
+ if (color->spec)
+ free(color->spec);
+ return;
+}
+
+void
+XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_colors,&geom->sz_colors,
+ (char **)&geom->colors,
+ sizeof(XkbColorRec),_XkbClearColor);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &outline->num_points,&outline->sz_points,
+ (char **)&outline->points,
+ sizeof(XkbPointRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOutline(char *outline_in)
+{
+XkbOutlinePtr outline= (XkbOutlinePtr)outline_in;
+
+ if (outline->points!=NULL)
+ XkbFreeGeomPoints(outline,0,outline->num_points,TRUE);
+ return;
+}
+
+void
+XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &shape->num_outlines,&shape->sz_outlines,
+ (char **)&shape->outlines,
+ sizeof(XkbOutlineRec),_XkbClearOutline);
+
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearShape(char *shape_in)
+{
+XkbShapePtr shape= (XkbShapePtr)shape_in;
+
+ if (shape->outlines)
+ XkbFreeGeomOutlines(shape,0,shape->num_outlines,TRUE);
+ return;
+}
+
+void
+XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_shapes,&geom->sz_shapes,
+ (char **)&geom->shapes,
+ sizeof(XkbShapeRec),_XkbClearShape);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &row->num_keys,&row->sz_keys,
+ (char **)&row->keys,
+ sizeof(XkbOverlayKeyRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOverlayRow(char *row_in)
+{
+XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in;
+
+ if (row->keys!=NULL)
+ XkbFreeGeomOverlayKeys(row,0,row->num_keys,TRUE);
+ return;
+}
+
+void
+XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &overlay->num_rows,&overlay->sz_rows,
+ (char **)&overlay->rows,
+ sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOverlay(char *overlay_in)
+{
+XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in;
+
+ if (overlay->rows!=NULL)
+ XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,TRUE);
+ return;
+}
+
+void
+XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &section->num_overlays,&section->sz_overlays,
+ (char **)&section->overlays,
+ sizeof(XkbOverlayRec),_XkbClearOverlay);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &row->num_keys,&row->sz_keys,
+ (char **)&row->keys,
+ sizeof(XkbKeyRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearRow(char *row_in)
+{
+XkbRowPtr row= (XkbRowPtr)row_in;
+
+ if (row->keys!=NULL)
+ XkbFreeGeomKeys(row,0,row->num_keys,TRUE);
+ return;
+}
+
+void
+XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &section->num_rows,&section->sz_rows,
+ (char **)&section->rows,
+ sizeof(XkbRowRec),_XkbClearRow);
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearSection(char *section_in)
+{
+XkbSectionPtr section= (XkbSectionPtr)section_in;
+
+ if (section->rows!=NULL)
+ XkbFreeGeomRows(section,0,section->num_rows,TRUE);
+ if (section->doodads!=NULL) {
+ XkbFreeGeomDoodads(section->doodads,section->num_doodads,TRUE);
+ section->doodads= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_sections,&geom->sz_sections,
+ (char **)&geom->sections,
+ sizeof(XkbSectionRec),_XkbClearSection);
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearDoodad(char *doodad_in)
+{
+XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in;
+
+ switch (doodad->any.type) {
+ case XkbTextDoodad:
+ {
+ if (doodad->text.text!=NULL) {
+ free(doodad->text.text);
+ doodad->text.text= NULL;
+ }
+ if (doodad->text.font!=NULL) {
+ free(doodad->text.font);
+ doodad->text.font= NULL;
+ }
+ }
+ break;
+ case XkbLogoDoodad:
+ {
+ if (doodad->logo.logo_name!=NULL) {
+ free(doodad->logo.logo_name);
+ doodad->logo.logo_name= NULL;
+ }
+ }
+ break;
+ }
+ return;
+}
+
+void
+XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
+{
+register int i;
+register XkbDoodadPtr doodad;
+
+ if (doodads) {
+ for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
+ _XkbClearDoodad((char *)doodad);
+ }
+ if (freeAll)
+ free(doodads);
+ }
+ return;
+}
+
+void
+XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
+{
+ if (geom==NULL)
+ return;
+ if (freeMap)
+ which= XkbGeomAllMask;
+ if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
+ XkbFreeGeomProperties(geom,0,geom->num_properties,TRUE);
+ if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
+ XkbFreeGeomColors(geom,0,geom->num_colors,TRUE);
+ if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
+ XkbFreeGeomShapes(geom,0,geom->num_shapes,TRUE);
+ if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
+ XkbFreeGeomSections(geom,0,geom->num_sections,TRUE);
+ if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
+ XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,TRUE);
+ geom->doodads= NULL;
+ geom->num_doodads= geom->sz_doodads= 0;
+ }
+ if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
+ XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,TRUE);
+ if (freeMap) {
+ if (geom->label_font!=NULL) {
+ free(geom->label_font);
+ geom->label_font= NULL;
+ }
+ free(geom);
+ }
+ return;
+}
+
+/***====================================================================***/
+
+static Status
+_XkbGeomAlloc( void ** old,
+ unsigned short * num,
+ unsigned short * total,
+ int num_new,
+ size_t sz_elem)
+{
+ if (num_new<1)
+ return Success;
+ if ((*old)==NULL)
+ *num= *total= 0;
+
+ if ((*num)+num_new<=(*total))
+ return Success;
+
+ *total= (*num)+num_new;
+ if ((*old)!=NULL)
+ (*old)= realloc((*old),(*total)*sz_elem);
+ else (*old)= calloc((*total),sz_elem);
+ if ((*old)==NULL) {
+ *total= *num= 0;
+ return BadAlloc;
+ }
+
+ if (*num>0) {
+ char *tmp= (char *)(*old);
+ bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
+ }
+ return Success;
+}
+
+#define _XkbAllocProps(g,n) _XkbGeomAlloc((void *)&(g)->properties,\
+ &(g)->num_properties,&(g)->sz_properties,\
+ (n),sizeof(XkbPropertyRec))
+#define _XkbAllocColors(g,n) _XkbGeomAlloc((void *)&(g)->colors,\
+ &(g)->num_colors,&(g)->sz_colors,\
+ (n),sizeof(XkbColorRec))
+#define _XkbAllocShapes(g,n) _XkbGeomAlloc((void *)&(g)->shapes,\
+ &(g)->num_shapes,&(g)->sz_shapes,\
+ (n),sizeof(XkbShapeRec))
+#define _XkbAllocSections(g,n) _XkbGeomAlloc((void *)&(g)->sections,\
+ &(g)->num_sections,&(g)->sz_sections,\
+ (n),sizeof(XkbSectionRec))
+#define _XkbAllocDoodads(g,n) _XkbGeomAlloc((void *)&(g)->doodads,\
+ &(g)->num_doodads,&(g)->sz_doodads,\
+ (n),sizeof(XkbDoodadRec))
+#define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((void *)&(g)->key_aliases,\
+ &(g)->num_key_aliases,&(g)->sz_key_aliases,\
+ (n),sizeof(XkbKeyAliasRec))
+
+#define _XkbAllocOutlines(s,n) _XkbGeomAlloc((void *)&(s)->outlines,\
+ &(s)->num_outlines,&(s)->sz_outlines,\
+ (n),sizeof(XkbOutlineRec))
+#define _XkbAllocRows(s,n) _XkbGeomAlloc((void *)&(s)->rows,\
+ &(s)->num_rows,&(s)->sz_rows,\
+ (n),sizeof(XkbRowRec))
+#define _XkbAllocPoints(o,n) _XkbGeomAlloc((void *)&(o)->points,\
+ &(o)->num_points,&(o)->sz_points,\
+ (n),sizeof(XkbPointRec))
+#define _XkbAllocKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\
+ &(r)->num_keys,&(r)->sz_keys,\
+ (n),sizeof(XkbKeyRec))
+#define _XkbAllocOverlays(s,n) _XkbGeomAlloc((void *)&(s)->overlays,\
+ &(s)->num_overlays,&(s)->sz_overlays,\
+ (n),sizeof(XkbOverlayRec))
+#define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((void *)&(o)->rows,\
+ &(o)->num_rows,&(o)->sz_rows,\
+ (n),sizeof(XkbOverlayRowRec))
+#define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((void *)&(r)->keys,\
+ &(r)->num_keys,&(r)->sz_keys,\
+ (n),sizeof(XkbOverlayKeyRec))
+
+Status
+XkbAllocGeomProps(XkbGeometryPtr geom,int nProps)
+{
+ return _XkbAllocProps(geom,nProps);
+}
+
+Status
+XkbAllocGeomColors(XkbGeometryPtr geom,int nColors)
+{
+ return _XkbAllocColors(geom,nColors);
+}
+
+Status
+XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases)
+{
+ return _XkbAllocKeyAliases(geom,nKeyAliases);
+}
+
+Status
+XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes)
+{
+ return _XkbAllocShapes(geom,nShapes);
+}
+
+Status
+XkbAllocGeomSections(XkbGeometryPtr geom,int nSections)
+{
+ return _XkbAllocSections(geom,nSections);
+}
+
+Status
+XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays)
+{
+ return _XkbAllocOverlays(section,nOverlays);
+}
+
+Status
+XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows)
+{
+ return _XkbAllocOverlayRows(overlay,nRows);
+}
+
+Status
+XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys)
+{
+ return _XkbAllocOverlayKeys(row,nKeys);
+}
+
+Status
+XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads)
+{
+ return _XkbAllocDoodads(geom,nDoodads);
+}
+
+Status
+XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads)
+{
+ return _XkbAllocDoodads(section,nDoodads);
+}
+
+Status
+XkbAllocGeomOutlines(XkbShapePtr shape,int nOL)
+{
+ return _XkbAllocOutlines(shape,nOL);
+}
+
+Status
+XkbAllocGeomRows(XkbSectionPtr section,int nRows)
+{
+ return _XkbAllocRows(section,nRows);
+}
+
+Status
+XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts)
+{
+ return _XkbAllocPoints(ol,nPts);
+}
+
+Status
+XkbAllocGeomKeys(XkbRowPtr row,int nKeys)
+{
+ return _XkbAllocKeys(row,nKeys);
+}
+
+Status
+XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes)
+{
+XkbGeometryPtr geom;
+Status rtrn;
+
+ if (xkb->geom==NULL) {
+ xkb->geom= calloc(1, sizeof(XkbGeometryRec));
+ if (!xkb->geom)
+ return BadAlloc;
+ }
+ geom= xkb->geom;
+ if ((sizes->which&XkbGeomPropertiesMask)&&
+ ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomColorsMask)&&
+ ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomShapesMask)&&
+ ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomSectionsMask)&&
+ ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomDoodadsMask)&&
+ ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomKeyAliasesMask)&&
+ ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
+ goto BAIL;
+ }
+ return Success;
+BAIL:
+ XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
+ xkb->geom= NULL;
+ return rtrn;
+}
+
+/***====================================================================***/
+
+XkbPropertyPtr
+XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value)
+{
+register int i;
+register XkbPropertyPtr prop;
+
+ if ((!geom)||(!name)||(!value))
+ return NULL;
+ for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ if ((prop->name)&&(strcmp(name,prop->name)==0)) {
+ if (prop->value)
+ free(prop->value);
+ prop->value= malloc(strlen(value)+1);
+ if (prop->value)
+ strcpy(prop->value,value);
+ return prop;
+ }
+ }
+ if ((geom->num_properties>=geom->sz_properties)&&
+ (_XkbAllocProps(geom,1)!=Success)) {
+ return NULL;
+ }
+ prop= &geom->properties[geom->num_properties];
+ prop->name= malloc(strlen(name)+1);
+ if (!name)
+ return NULL;
+ strcpy(prop->name,name);
+ prop->value= malloc(strlen(value)+1);
+ if (!value) {
+ free(prop->name);
+ prop->name= NULL;
+ return NULL;
+ }
+ strcpy(prop->value,value);
+ geom->num_properties++;
+ return prop;
+}
+
+XkbKeyAliasPtr
+XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr)
+{
+register int i;
+register XkbKeyAliasPtr alias;
+
+ if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0]))
+ return NULL;
+ for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) {
+ if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) {
+ bzero(alias->real,XkbKeyNameLength);
+ strncpy(alias->real,realStr,XkbKeyNameLength);
+ return alias;
+ }
+ }
+ if ((geom->num_key_aliases>=geom->sz_key_aliases)&&
+ (_XkbAllocKeyAliases(geom,1)!=Success)) {
+ return NULL;
+ }
+ alias= &geom->key_aliases[geom->num_key_aliases];
+ bzero(alias,sizeof(XkbKeyAliasRec));
+ strncpy(alias->alias,aliasStr,XkbKeyNameLength);
+ strncpy(alias->real,realStr,XkbKeyNameLength);
+ geom->num_key_aliases++;
+ return alias;
+}
+
+XkbColorPtr
+XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel)
+{
+register int i;
+register XkbColorPtr color;
+
+ if ((!geom)||(!spec))
+ return NULL;
+ for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
+ color->pixel= pixel;
+ return color;
+ }
+ }
+ if ((geom->num_colors>=geom->sz_colors)&&
+ (_XkbAllocColors(geom,1)!=Success)) {
+ return NULL;
+ }
+ color= &geom->colors[geom->num_colors];
+ color->pixel= pixel;
+ color->spec= malloc(strlen(spec)+1);
+ if (!color->spec)
+ return NULL;
+ strcpy(color->spec,spec);
+ geom->num_colors++;
+ return color;
+}
+
+XkbOutlinePtr
+XkbAddGeomOutline(XkbShapePtr shape,int sz_points)
+{
+XkbOutlinePtr outline;
+
+ if ((!shape)||(sz_points<0))
+ return NULL;
+ if ((shape->num_outlines>=shape->sz_outlines)&&
+ (_XkbAllocOutlines(shape,1)!=Success)) {
+ return NULL;
+ }
+ outline= &shape->outlines[shape->num_outlines];
+ bzero(outline,sizeof(XkbOutlineRec));
+ if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
+ return NULL;
+ shape->num_outlines++;
+ return outline;
+}
+
+XkbShapePtr
+XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines)
+{
+XkbShapePtr shape;
+register int i;
+
+ if ((!geom)||(!name)||(sz_outlines<0))
+ return NULL;
+ if (geom->num_shapes>0) {
+ for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
+ if (name==shape->name)
+ return shape;
+ }
+ }
+ if ((geom->num_shapes>=geom->sz_shapes)&&
+ (_XkbAllocShapes(geom,1)!=Success))
+ return NULL;
+ shape= &geom->shapes[geom->num_shapes];
+ bzero(shape,sizeof(XkbShapeRec));
+ if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
+ return NULL;
+ shape->name= name;
+ shape->primary= shape->approx= NULL;
+ geom->num_shapes++;
+ return shape;
+}
+
+XkbKeyPtr
+XkbAddGeomKey(XkbRowPtr row)
+{
+XkbKeyPtr key;
+ if (!row)
+ return NULL;
+ if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
+ return NULL;
+ key= &row->keys[row->num_keys++];
+ bzero(key,sizeof(XkbKeyRec));
+ return key;
+}
+
+XkbRowPtr
+XkbAddGeomRow(XkbSectionPtr section,int sz_keys)
+{
+XkbRowPtr row;
+
+ if ((!section)||(sz_keys<0))
+ return NULL;
+ if ((section->num_rows>=section->sz_rows)&&
+ (_XkbAllocRows(section,1)!=Success))
+ return NULL;
+ row= &section->rows[section->num_rows];
+ bzero(row,sizeof(XkbRowRec));
+ if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
+ return NULL;
+ section->num_rows++;
+ return row;
+}
+
+XkbSectionPtr
+XkbAddGeomSection( XkbGeometryPtr geom,
+ Atom name,
+ int sz_rows,
+ int sz_doodads,
+ int sz_over)
+{
+register int i;
+XkbSectionPtr section;
+
+ if ((!geom)||(name==None)||(sz_rows<0))
+ return NULL;
+ for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ if (section->name!=name)
+ continue;
+ if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
+ ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
+ ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
+ return NULL;
+ return section;
+ }
+ if ((geom->num_sections>=geom->sz_sections)&&
+ (_XkbAllocSections(geom,1)!=Success))
+ return NULL;
+ section= &geom->sections[geom->num_sections];
+ if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
+ return NULL;
+ if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
+ if (section->rows) {
+ free(section->rows);
+ section->rows= NULL;
+ section->sz_rows= section->num_rows= 0;
+ }
+ return NULL;
+ }
+ section->name= name;
+ geom->num_sections++;
+ return section;
+}
+
+XkbDoodadPtr
+XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name)
+{
+XkbDoodadPtr old,doodad;
+register int i,nDoodads;
+
+ if ((!geom)||(name==None))
+ return NULL;
+ if ((section!=NULL)&&(section->num_doodads>0)) {
+ old= section->doodads;
+ nDoodads= section->num_doodads;
+ }
+ else {
+ old= geom->doodads;
+ nDoodads= geom->num_doodads;
+ }
+ for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
+ if (doodad->any.name==name)
+ return doodad;
+ }
+ if (section) {
+ if ((section->num_doodads>=geom->sz_doodads)&&
+ (_XkbAllocDoodads(section,1)!=Success)) {
+ return NULL;
+ }
+ doodad= &section->doodads[section->num_doodads++];
+ }
+ else {
+ if ((geom->num_doodads>=geom->sz_doodads)&&
+ (_XkbAllocDoodads(geom,1)!=Success))
+ return NULL;
+ doodad= &geom->doodads[geom->num_doodads++];
+ }
+ bzero(doodad,sizeof(XkbDoodadRec));
+ doodad->any.name= name;
+ return doodad;
+}
+
+XkbOverlayKeyPtr
+XkbAddGeomOverlayKey( XkbOverlayPtr overlay,
+ XkbOverlayRowPtr row,
+ char * over,
+ char * under)
+{
+register int i;
+XkbOverlayKeyPtr key;
+XkbSectionPtr section;
+XkbRowPtr row_under;
+Bool found;
+
+ if ((!overlay)||(!row)||(!over)||(!under))
+ return NULL;
+ section= overlay->section_under;
+ if (row->row_under>=section->num_rows)
+ return NULL;
+ row_under= &section->rows[row->row_under];
+ for (i=0,found=FALSE;i<row_under->num_keys;i++) {
+ if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) {
+ found= TRUE;
+ break;
+ }
+ }
+ if (!found)
+ return NULL;
+ if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success))
+ return NULL;
+ key= &row->keys[row->num_keys];
+ strncpy(key->under.name,under,XkbKeyNameLength);
+ strncpy(key->over.name,over,XkbKeyNameLength);
+ row->num_keys++;
+ return key;
+}
+
+XkbOverlayRowPtr
+XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys)
+{
+register int i;
+XkbOverlayRowPtr row;
+
+ if ((!overlay)||(sz_keys<0))
+ return NULL;
+ if (row_under>=overlay->section_under->num_rows)
+ return NULL;
+ for (i=0;i<overlay->num_rows;i++) {
+ if (overlay->rows[i].row_under==row_under) {
+ row= &overlay->rows[i];
+ if ((row->sz_keys<sz_keys)&&
+ (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
+ return NULL;
+ }
+ return &overlay->rows[i];
+ }
+ }
+ if ((overlay->num_rows>=overlay->sz_rows)&&
+ (_XkbAllocOverlayRows(overlay,1)!=Success))
+ return NULL;
+ row= &overlay->rows[overlay->num_rows];
+ bzero(row,sizeof(XkbOverlayRowRec));
+ if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
+ return NULL;
+ row->row_under= row_under;
+ overlay->num_rows++;
+ return row;
+}
+
+XkbOverlayPtr
+XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows)
+{
+register int i;
+XkbOverlayPtr overlay;
+
+ if ((!section)||(name==None)||(sz_rows==0))
+ return NULL;
+
+ for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
+ if (overlay->name==name) {
+ if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
+ return NULL;
+ return overlay;
+ }
+ }
+ if ((section->num_overlays>=section->sz_overlays)&&
+ (_XkbAllocOverlays(section,1)!=Success))
+ return NULL;
+ overlay= &section->overlays[section->num_overlays];
+ if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
+ return NULL;
+ overlay->name= name;
+ overlay->section_under= section;
+ section->num_overlays++;
+ return overlay;
+}
diff --git a/xorg-server/xkb/XKBMAlloc.c b/xorg-server/xkb/XKBMAlloc.c
index fd12e2b6c..34e52835d 100644
--- a/xorg-server/xkb/XKBMAlloc.c
+++ b/xorg-server/xkb/XKBMAlloc.c
@@ -1,900 +1,900 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#elif defined(HAVE_CONFIG_H)
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-#include <X11/keysym.h>
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-
-/***====================================================================***/
-
-Status
-XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes)
-{
-register int i;
-XkbClientMapPtr map;
-
- if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes)))
- return BadValue;
- if ((which&XkbKeySymsMask)&&
- ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))) {
- DebugF("bad keycode (%d,%d) in XkbAllocClientMap\n",
- xkb->min_key_code,xkb->max_key_code);
- return BadValue;
- }
-
- if (xkb->map==NULL) {
- map= xcalloc(1, sizeof(XkbClientMapRec));
- if (map==NULL)
- return BadAlloc;
- xkb->map= map;
- }
- else map= xkb->map;
-
- if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) {
- if (map->types==NULL) {
- map->types= xcalloc(nTotalTypes, sizeof(XkbKeyTypeRec));
- if (map->types==NULL)
- return BadAlloc;
- map->num_types= 0;
- map->size_types= nTotalTypes;
- }
- else if (map->size_types<nTotalTypes) {
- XkbKeyTypeRec *prev_types = map->types;
-
- map->types= xrealloc(map->types,nTotalTypes * sizeof(XkbKeyTypeRec));
- if (map->types==NULL) {
- xfree(prev_types);
- map->num_types= map->size_types= 0;
- return BadAlloc;
- }
- map->size_types= nTotalTypes;
- bzero(&map->types[map->num_types],
- ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec)));
- }
- }
- if (which&XkbKeySymsMask) {
- int nKeys= XkbNumKeys(xkb);
- if (map->syms==NULL) {
- map->size_syms= (nKeys*15)/10;
- map->syms= xcalloc(map->size_syms, sizeof(KeySym));
- if (!map->syms) {
- map->size_syms= 0;
- return BadAlloc;
- }
- map->num_syms= 1;
- map->syms[0]= NoSymbol;
- }
- if (map->key_sym_map==NULL) {
- i= xkb->max_key_code+1;
- map->key_sym_map= xcalloc(i, sizeof(XkbSymMapRec));
- if (map->key_sym_map==NULL)
- return BadAlloc;
- }
- }
- if (which&XkbModifierMapMask) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadMatch;
- if (map->modmap==NULL) {
- i= xkb->max_key_code+1;
- map->modmap= xcalloc(i, sizeof(unsigned char));
- if (map->modmap==NULL)
- return BadAlloc;
- }
- }
- return Success;
-}
-
-Status
-XkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions)
-{
-register int i;
-XkbServerMapPtr map;
-
- if (xkb==NULL)
- return BadMatch;
- if (xkb->server==NULL) {
- map= xcalloc(1, sizeof(XkbServerMapRec));
- if (map==NULL)
- return BadAlloc;
- for (i=0;i<XkbNumVirtualMods;i++) {
- map->vmods[i]= XkbNoModifierMask;
- }
- xkb->server= map;
- }
- else map= xkb->server;
- if (which&XkbExplicitComponentsMask) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadMatch;
- if (map->explicit==NULL) {
- i= xkb->max_key_code+1;
- map->explicit= xcalloc(i, sizeof(unsigned char));
- if (map->explicit==NULL)
- return BadAlloc;
- }
- }
- if (which&XkbKeyActionsMask) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadMatch;
- if (nNewActions<1)
- nNewActions= 1;
- if (map->acts==NULL) {
- map->acts= xcalloc((nNewActions+1), sizeof(XkbAction));
- if (map->acts==NULL)
- return BadAlloc;
- map->num_acts= 1;
- map->size_acts= nNewActions+1;
- }
- else if ((map->size_acts-map->num_acts)<nNewActions) {
- unsigned need;
- XkbAction *prev_acts = map->acts;
- need= map->num_acts+nNewActions;
- map->acts= xrealloc(map->acts,need * sizeof(XkbAction));
- if (map->acts==NULL) {
- xfree(prev_acts);
- map->num_acts= map->size_acts= 0;
- return BadAlloc;
- }
- map->size_acts= need;
- bzero(&map->acts[map->num_acts],
- ((map->size_acts-map->num_acts)*sizeof(XkbAction)));
- }
- if (map->key_acts==NULL) {
- i= xkb->max_key_code+1;
- map->key_acts= xcalloc(i, sizeof(unsigned short));
- if (map->key_acts==NULL)
- return BadAlloc;
- }
- }
- if (which&XkbKeyBehaviorsMask) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadMatch;
- if (map->behaviors==NULL) {
- i= xkb->max_key_code+1;
- map->behaviors= xcalloc(i, sizeof(XkbBehavior));
- if (map->behaviors==NULL)
- return BadAlloc;
- }
- }
- if (which&XkbVirtualModMapMask) {
- if ((!XkbIsLegalKeycode(xkb->min_key_code))||
- (!XkbIsLegalKeycode(xkb->max_key_code))||
- (xkb->max_key_code<xkb->min_key_code))
- return BadMatch;
- if (map->vmodmap==NULL) {
- i= xkb->max_key_code+1;
- map->vmodmap= xcalloc(i, sizeof(unsigned short));
- if (map->vmodmap==NULL)
- return BadAlloc;
- }
- }
- return Success;
-}
-
-/***====================================================================***/
-
-static Status
-XkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into)
-{
- if ((!from)||(!into))
- return BadMatch;
- if (into->map) {
- xfree(into->map);
- into->map= NULL;
- }
- if (into->preserve) {
- xfree(into->preserve);
- into->preserve= NULL;
- }
- if (into->level_names) {
- xfree(into->level_names);
- into->level_names= NULL;
- }
- *into= *from;
- if ((from->map)&&(into->map_count>0)) {
- into->map= xcalloc(into->map_count, sizeof(XkbKTMapEntryRec));
- if (!into->map)
- return BadAlloc;
- memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec));
- }
- if ((from->preserve)&&(into->map_count>0)) {
- into->preserve= xcalloc(into->map_count, sizeof(XkbModsRec));
- if (!into->preserve)
- return BadAlloc;
- memcpy(into->preserve,from->preserve,
- into->map_count*sizeof(XkbModsRec));
- }
- if ((from->level_names)&&(into->num_levels>0)) {
- into->level_names= xcalloc(into->num_levels, sizeof(Atom));
- if (!into->level_names)
- return BadAlloc;
- memcpy(into->level_names,from->level_names,
- into->num_levels*sizeof(Atom));
- }
- return Success;
-}
-
-Status
-XkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types)
-{
-register int i,rtrn;
-
- if ((!from)||(!into)||(num_types<0))
- return BadMatch;
- for (i=0;i<num_types;i++) {
- if ((rtrn= XkbCopyKeyType(from++,into++))!=Success)
- return rtrn;
- }
- return Success;
-}
-
-Status
-XkbResizeKeyType( XkbDescPtr xkb,
- int type_ndx,
- int map_count,
- Bool want_preserve,
- int new_num_lvls)
-{
-XkbKeyTypePtr type;
-KeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys;
-
- if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)||
- (new_num_lvls<1))
- return BadValue;
- switch (type_ndx) {
- case XkbOneLevelIndex:
- if (new_num_lvls!=1)
- return BadMatch;
- break;
- case XkbTwoLevelIndex:
- case XkbAlphabeticIndex:
- case XkbKeypadIndex:
- if (new_num_lvls!=2)
- return BadMatch;
- break;
- }
- type= &xkb->map->types[type_ndx];
- if (map_count==0) {
- if (type->map!=NULL)
- xfree(type->map);
- type->map= NULL;
- if (type->preserve!=NULL)
- xfree(type->preserve);
- type->preserve= NULL;
- type->map_count= 0;
- }
- else {
- XkbKTMapEntryRec *prev_map = type->map;
-
- if ((map_count>type->map_count)||(type->map==NULL))
- type->map = xrealloc(type->map,map_count * sizeof(XkbKTMapEntryRec));
- if (!type->map) {
- if (prev_map)
- xfree(prev_map);
- return BadAlloc;
- }
- if (want_preserve) {
- XkbModsRec *prev_preserve = type->preserve;
-
- if ((map_count>type->map_count)||(type->preserve==NULL)) {
- type->preserve = xrealloc(type->preserve,
- map_count * sizeof(XkbModsRec));
- }
- if (!type->preserve) {
- if (prev_preserve)
- xfree(prev_preserve);
- return BadAlloc;
- }
- }
- else if (type->preserve!=NULL) {
- xfree(type->preserve);
- type->preserve= NULL;
- }
- type->map_count= map_count;
- }
-
- if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) {
- Atom * prev_level_names = type->level_names;
-
- type->level_names = xrealloc(type->level_names,
- new_num_lvls * sizeof(Atom));
- if (!type->level_names) {
- if (prev_level_names)
- xfree(prev_level_names);
- return BadAlloc;
- }
- }
- /*
- * Here's the theory:
- * If the width of the type changed, we might have to resize the symbol
- * maps for any keys that use the type for one or more groups. This is
- * expensive, so we'll try to cull out any keys that are obviously okay:
- * In any case:
- * - keys that have a group width <= the old width are okay (because
- * they could not possibly have been associated with the old type)
- * If the key type increased in size:
- * - keys that already have a group width >= to the new width are okay
- * + keys that have a group width >= the old width but < the new width
- * might have to be enlarged.
- * If the key type decreased in size:
- * - keys that have a group width > the old width don't have to be
- * resized (because they must have some other wider type associated
- * with some group).
- * + keys that have a group width == the old width might have to be
- * shrunk.
- * The possibilities marked with '+' require us to examine the key types
- * associated with each group for the key.
- */
- bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode));
- nMatchingKeys= 0;
- if (new_num_lvls>type->num_levels) {
- int nTotal;
- KeySym * newSyms;
- int width,match,nResize;
- register int i,g,nSyms;
-
- nResize= 0;
- for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- width= XkbKeyGroupsWidth(xkb,i);
- if (width<type->num_levels)
- continue;
- for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
- if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
- matchingKeys[nMatchingKeys++]= i;
- match= 1;
- }
- }
- if ((!match)||(width>=new_num_lvls))
- nTotal+= XkbKeyNumSyms(xkb,i);
- else {
- nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
- nResize++;
- }
- }
- if (nResize>0) {
- int nextMatch;
- xkb->map->size_syms= (nTotal*15)/10;
- newSyms = xcalloc(xkb->map->size_syms, sizeof(KeySym));
- if (newSyms==NULL)
- return BadAlloc;
- nextMatch= 0;
- nSyms= 1;
- for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- if (matchingKeys[nextMatch]==i) {
- KeySym *pOld;
- nextMatch++;
- width= XkbKeyGroupsWidth(xkb,i);
- pOld= XkbKeySymsPtr(xkb,i);
- for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) {
- memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g],
- width*sizeof(KeySym));
- }
- xkb->map->key_sym_map[i].offset= nSyms;
- nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
- }
- else {
- memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),
- XkbKeyNumSyms(xkb,i)*sizeof(KeySym));
- xkb->map->key_sym_map[i].offset= nSyms;
- nSyms+= XkbKeyNumSyms(xkb,i);
- }
- }
- type->num_levels= new_num_lvls;
- xfree(xkb->map->syms);
- xkb->map->syms= newSyms;
- xkb->map->num_syms= nSyms;
- return Success;
- }
- }
- else if (new_num_lvls<type->num_levels) {
- int width,match;
- register int g,i;
- for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- width= XkbKeyGroupsWidth(xkb,i);
- if (width<type->num_levels)
- continue;
- for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
- if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
- matchingKeys[nMatchingKeys++]= i;
- match= 1;
- }
- }
- }
- }
- if (nMatchingKeys>0) {
- int key,firstClear;
- register int i,g;
- if (new_num_lvls>type->num_levels)
- firstClear= type->num_levels;
- else firstClear= new_num_lvls;
- for (i=0;i<nMatchingKeys;i++) {
- KeySym * pSyms;
- int width,nClear;
-
- key= matchingKeys[i];
- width= XkbKeyGroupsWidth(xkb,key);
- nClear= width-firstClear;
- pSyms= XkbKeySymsPtr(xkb,key);
- for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) {
- if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) {
- if (nClear>0)
- bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym));
- }
- }
- }
- }
- type->num_levels= new_num_lvls;
- return Success;
-}
-
-KeySym *
-XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed)
-{
-register int i,nSyms,nKeySyms;
-unsigned nOldSyms;
-KeySym *newSyms;
-
- if (needed==0) {
- xkb->map->key_sym_map[key].offset= 0;
- return xkb->map->syms;
- }
- nOldSyms= XkbKeyNumSyms(xkb,key);
- if (nOldSyms>=(unsigned)needed) {
- return XkbKeySymsPtr(xkb,key);
- }
- if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) {
- if (nOldSyms>0) {
- memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key),
- nOldSyms*sizeof(KeySym));
- }
- if ((needed-nOldSyms)>0) {
- bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)],
- (needed-nOldSyms)*sizeof(KeySym));
- }
- xkb->map->key_sym_map[key].offset = xkb->map->num_syms;
- xkb->map->num_syms+= needed;
- return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
- }
- xkb->map->size_syms+= (needed>32?needed:32);
- newSyms = xcalloc(xkb->map->size_syms, sizeof(KeySym));
- if (newSyms==NULL)
- return NULL;
- newSyms[0]= NoSymbol;
- nSyms = 1;
- for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
- int nCopy;
-
- nCopy= nKeySyms= XkbKeyNumSyms(xkb,i);
- if ((nKeySyms==0)&&(i!=key))
- continue;
- if (i==key)
- nKeySyms= needed;
- if (nCopy!=0)
- memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym));
- if (nKeySyms>nCopy)
- bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym));
- xkb->map->key_sym_map[i].offset = nSyms;
- nSyms+= nKeySyms;
- }
- xfree(xkb->map->syms);
- xkb->map->syms = newSyms;
- xkb->map->num_syms = nSyms;
- return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
-}
-
-static unsigned
-_ExtendRange( unsigned int old_flags,
- unsigned int flag,
- KeyCode newKC,
- KeyCode * old_min,
- unsigned char * old_num)
-{
- if ((old_flags&flag)==0) {
- old_flags|= flag;
- *old_min= newKC;
- *old_num= 1;
- }
- else {
- int last= (*old_min)+(*old_num)-1;
- if (newKC<*old_min) {
- *old_min= newKC;
- *old_num= (last-newKC)+1;
- }
- else if (newKC>last) {
- *old_num= (newKC-(*old_min))+1;
- }
- }
- return old_flags;
-}
-
-Status
-XkbChangeKeycodeRange( XkbDescPtr xkb,
- int minKC,
- int maxKC,
- XkbChangesPtr changes)
-{
-int tmp;
-
- if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode))
- return BadValue;
- if (minKC>maxKC)
- return BadMatch;
- if (minKC<xkb->min_key_code) {
- if (changes)
- changes->map.min_key_code= minKC;
- tmp= xkb->min_key_code-minKC;
- if (xkb->map) {
- if (xkb->map->key_sym_map) {
- bzero((char *)&xkb->map->key_sym_map[minKC],
- tmp*sizeof(XkbSymMapRec));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeySymsMask,minKC,
- &changes->map.first_key_sym,
- &changes->map.num_key_syms);
- }
- }
- if (xkb->map->modmap) {
- bzero((char *)&xkb->map->modmap[minKC],tmp);
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbModifierMapMask,minKC,
- &changes->map.first_modmap_key,
- &changes->map.num_modmap_keys);
- }
- }
- }
- if (xkb->server) {
- if (xkb->server->behaviors) {
- bzero((char *)&xkb->server->behaviors[minKC],
- tmp*sizeof(XkbBehavior));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeyBehaviorsMask,minKC,
- &changes->map.first_key_behavior,
- &changes->map.num_key_behaviors);
- }
- }
- if (xkb->server->key_acts) {
- bzero((char *)&xkb->server->key_acts[minKC],
- tmp*sizeof(unsigned short));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeyActionsMask,minKC,
- &changes->map.first_key_act,
- &changes->map.num_key_acts);
- }
- }
- if (xkb->server->vmodmap) {
- bzero((char *)&xkb->server->vmodmap[minKC],
- tmp*sizeof(unsigned short));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbVirtualModMapMask,minKC,
- &changes->map.first_modmap_key,
- &changes->map.num_vmodmap_keys);
- }
- }
- }
- if ((xkb->names)&&(xkb->names->keys)) {
- bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec));
- if (changes) {
- changes->names.changed= _ExtendRange(changes->names.changed,
- XkbKeyNamesMask,minKC,
- &changes->names.first_key,
- &changes->names.num_keys);
- }
- }
- xkb->min_key_code= minKC;
- }
- if (maxKC>xkb->max_key_code) {
- if (changes)
- changes->map.max_key_code= maxKC;
- tmp= maxKC-xkb->max_key_code;
- if (xkb->map) {
- if (xkb->map->key_sym_map) {
- XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map;
-
- xkb->map->key_sym_map = xrealloc(xkb->map->key_sym_map,
- (maxKC+1) * sizeof(XkbSymMapRec));
- if (!xkb->map->key_sym_map) {
- xfree(prev_key_sym_map);
- return BadAlloc;
- }
- bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code],
- tmp*sizeof(XkbSymMapRec));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeySymsMask,maxKC,
- &changes->map.first_key_sym,
- &changes->map.num_key_syms);
- }
- }
- if (xkb->map->modmap) {
- unsigned char *prev_modmap = xkb->map->modmap;
-
- xkb->map->modmap = xrealloc(xkb->map->modmap,
- (maxKC+1) * sizeof(unsigned char));
- if (!xkb->map->modmap) {
- xfree(prev_modmap);
- return BadAlloc;
- }
- bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp);
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbModifierMapMask,maxKC,
- &changes->map.first_modmap_key,
- &changes->map.num_modmap_keys);
- }
- }
- }
- if (xkb->server) {
- if (xkb->server->behaviors) {
- XkbBehavior *prev_behaviors = xkb->server->behaviors;
-
- xkb->server->behaviors = xrealloc(xkb->server->behaviors,
- (maxKC+1) * sizeof(XkbBehavior));
- if (!xkb->server->behaviors) {
- xfree(prev_behaviors);
- return BadAlloc;
- }
- bzero((char *)&xkb->server->behaviors[xkb->max_key_code],
- tmp*sizeof(XkbBehavior));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeyBehaviorsMask,maxKC,
- &changes->map.first_key_behavior,
- &changes->map.num_key_behaviors);
- }
- }
- if (xkb->server->key_acts) {
- unsigned short *prev_key_acts = xkb->server->key_acts;
-
- xkb->server->key_acts= xrealloc(xkb->server->key_acts,
- (maxKC+1) * sizeof(unsigned short));
- if (!xkb->server->key_acts) {
- xfree(prev_key_acts);
- return BadAlloc;
- }
- bzero((char *)&xkb->server->key_acts[xkb->max_key_code],
- tmp*sizeof(unsigned short));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbKeyActionsMask,maxKC,
- &changes->map.first_key_act,
- &changes->map.num_key_acts);
- }
- }
- if (xkb->server->vmodmap) {
- unsigned short *prev_vmodmap = xkb->server->vmodmap;
-
- xkb->server->vmodmap= xrealloc(xkb->server->vmodmap,
- (maxKC+1) * sizeof(unsigned short));
- if (!xkb->server->vmodmap) {
- xfree(prev_vmodmap);
- return BadAlloc;
- }
- bzero((char *)&xkb->server->vmodmap[xkb->max_key_code],
- tmp*sizeof(unsigned short));
- if (changes) {
- changes->map.changed= _ExtendRange(changes->map.changed,
- XkbVirtualModMapMask,maxKC,
- &changes->map.first_modmap_key,
- &changes->map.num_vmodmap_keys);
- }
- }
- }
- if ((xkb->names)&&(xkb->names->keys)) {
- XkbKeyNameRec *prev_keys = xkb->names->keys;
-
- xkb->names->keys = xrealloc(xkb->names->keys,
- (maxKC+1) * sizeof(XkbKeyNameRec));
- if (!xkb->names->keys) {
- xfree(prev_keys);
- return BadAlloc;
- }
- bzero((char *)&xkb->names->keys[xkb->max_key_code],
- tmp*sizeof(XkbKeyNameRec));
- if (changes) {
- changes->names.changed= _ExtendRange(changes->names.changed,
- XkbKeyNamesMask,maxKC,
- &changes->names.first_key,
- &changes->names.num_keys);
- }
- }
- xkb->max_key_code= maxKC;
- }
- return Success;
-}
-
-XkbAction *
-XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed)
-{
-register int i,nActs;
-XkbAction *newActs;
-
- if (needed==0) {
- xkb->server->key_acts[key]= 0;
- return NULL;
- }
- if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed))
- return XkbKeyActionsPtr(xkb,key);
- if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) {
- xkb->server->key_acts[key]= xkb->server->num_acts;
- xkb->server->num_acts+= needed;
- return &xkb->server->acts[xkb->server->key_acts[key]];
- }
- xkb->server->size_acts= xkb->server->num_acts+needed+8;
- newActs = xcalloc(xkb->server->size_acts, sizeof(XkbAction));
- if (newActs==NULL)
- return NULL;
- newActs[0].type = XkbSA_NoAction;
- nActs = 1;
- for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
- int nKeyActs,nCopy;
-
- if ((xkb->server->key_acts[i]==0)&&(i!=key))
- continue;
-
- nCopy= nKeyActs= XkbKeyNumActions(xkb,i);
- if (i==key) {
- nKeyActs= needed;
- if (needed<nCopy)
- nCopy= needed;
- }
-
- if (nCopy>0)
- memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i),
- nCopy*sizeof(XkbAction));
- if (nCopy<nKeyActs)
- bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction));
- xkb->server->key_acts[i]= nActs;
- nActs+= nKeyActs;
- }
- xfree(xkb->server->acts);
- xkb->server->acts = newActs;
- xkb->server->num_acts= nActs;
- return &xkb->server->acts[xkb->server->key_acts[key]];
-}
-
-void
-XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
-{
-XkbClientMapPtr map;
-
- if ((xkb==NULL)||(xkb->map==NULL))
- return;
- if (freeMap)
- what= XkbAllClientInfoMask;
- map= xkb->map;
- if (what&XkbKeyTypesMask) {
- if (map->types!=NULL) {
- if (map->num_types>0) {
- register int i;
- XkbKeyTypePtr type;
- for (i=0,type=map->types;i<map->num_types;i++,type++) {
- if (type->map!=NULL) {
- xfree(type->map);
- type->map= NULL;
- }
- if (type->preserve!=NULL) {
- xfree(type->preserve);
- type->preserve= NULL;
- }
- type->map_count= 0;
- if (type->level_names!=NULL) {
- xfree(type->level_names);
- type->level_names= NULL;
- }
- }
- }
- xfree(map->types);
- map->num_types= map->size_types= 0;
- map->types= NULL;
- }
- }
- if (what&XkbKeySymsMask) {
- if (map->key_sym_map!=NULL) {
- xfree(map->key_sym_map);
- map->key_sym_map= NULL;
- }
- if (map->syms!=NULL) {
- xfree(map->syms);
- map->size_syms= map->num_syms= 0;
- map->syms= NULL;
- }
- }
- if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) {
- xfree(map->modmap);
- map->modmap= NULL;
- }
- if (freeMap) {
- xfree(xkb->map);
- xkb->map= NULL;
- }
- return;
-}
-
-void
-XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
-{
-XkbServerMapPtr map;
-
- if ((xkb==NULL)||(xkb->server==NULL))
- return;
- if (freeMap)
- what= XkbAllServerInfoMask;
- map= xkb->server;
- if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) {
- xfree(map->explicit);
- map->explicit= NULL;
- }
- if (what&XkbKeyActionsMask) {
- if (map->key_acts!=NULL) {
- xfree(map->key_acts);
- map->key_acts= NULL;
- }
- if (map->acts!=NULL) {
- xfree(map->acts);
- map->num_acts= map->size_acts= 0;
- map->acts= NULL;
- }
- }
- if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) {
- xfree(map->behaviors);
- map->behaviors= NULL;
- }
- if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) {
- xfree(map->vmodmap);
- map->vmodmap= NULL;
- }
-
- if (freeMap) {
- xfree(xkb->server);
- xkb->server= NULL;
- }
- return;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <X11/keysym.h>
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+
+/***====================================================================***/
+
+Status
+XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes)
+{
+register int i;
+XkbClientMapPtr map;
+
+ if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes)))
+ return BadValue;
+ if ((which&XkbKeySymsMask)&&
+ ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))) {
+ DebugF("bad keycode (%d,%d) in XkbAllocClientMap\n",
+ xkb->min_key_code,xkb->max_key_code);
+ return BadValue;
+ }
+
+ if (xkb->map==NULL) {
+ map= calloc(1, sizeof(XkbClientMapRec));
+ if (map==NULL)
+ return BadAlloc;
+ xkb->map= map;
+ }
+ else map= xkb->map;
+
+ if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) {
+ if (map->types==NULL) {
+ map->types= calloc(nTotalTypes, sizeof(XkbKeyTypeRec));
+ if (map->types==NULL)
+ return BadAlloc;
+ map->num_types= 0;
+ map->size_types= nTotalTypes;
+ }
+ else if (map->size_types<nTotalTypes) {
+ XkbKeyTypeRec *prev_types = map->types;
+
+ map->types= realloc(map->types,nTotalTypes * sizeof(XkbKeyTypeRec));
+ if (map->types==NULL) {
+ free(prev_types);
+ map->num_types= map->size_types= 0;
+ return BadAlloc;
+ }
+ map->size_types= nTotalTypes;
+ bzero(&map->types[map->num_types],
+ ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec)));
+ }
+ }
+ if (which&XkbKeySymsMask) {
+ int nKeys= XkbNumKeys(xkb);
+ if (map->syms==NULL) {
+ map->size_syms= (nKeys*15)/10;
+ map->syms= calloc(map->size_syms, sizeof(KeySym));
+ if (!map->syms) {
+ map->size_syms= 0;
+ return BadAlloc;
+ }
+ map->num_syms= 1;
+ map->syms[0]= NoSymbol;
+ }
+ if (map->key_sym_map==NULL) {
+ i= xkb->max_key_code+1;
+ map->key_sym_map= calloc(i, sizeof(XkbSymMapRec));
+ if (map->key_sym_map==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbModifierMapMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->modmap==NULL) {
+ i= xkb->max_key_code+1;
+ map->modmap= calloc(i, sizeof(unsigned char));
+ if (map->modmap==NULL)
+ return BadAlloc;
+ }
+ }
+ return Success;
+}
+
+Status
+XkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions)
+{
+register int i;
+XkbServerMapPtr map;
+
+ if (xkb==NULL)
+ return BadMatch;
+ if (xkb->server==NULL) {
+ map= calloc(1, sizeof(XkbServerMapRec));
+ if (map==NULL)
+ return BadAlloc;
+ for (i=0;i<XkbNumVirtualMods;i++) {
+ map->vmods[i]= XkbNoModifierMask;
+ }
+ xkb->server= map;
+ }
+ else map= xkb->server;
+ if (which&XkbExplicitComponentsMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->explicit==NULL) {
+ i= xkb->max_key_code+1;
+ map->explicit= calloc(i, sizeof(unsigned char));
+ if (map->explicit==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbKeyActionsMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (nNewActions<1)
+ nNewActions= 1;
+ if (map->acts==NULL) {
+ map->acts= calloc((nNewActions+1), sizeof(XkbAction));
+ if (map->acts==NULL)
+ return BadAlloc;
+ map->num_acts= 1;
+ map->size_acts= nNewActions+1;
+ }
+ else if ((map->size_acts-map->num_acts)<nNewActions) {
+ unsigned need;
+ XkbAction *prev_acts = map->acts;
+ need= map->num_acts+nNewActions;
+ map->acts= realloc(map->acts,need * sizeof(XkbAction));
+ if (map->acts==NULL) {
+ free(prev_acts);
+ map->num_acts= map->size_acts= 0;
+ return BadAlloc;
+ }
+ map->size_acts= need;
+ bzero(&map->acts[map->num_acts],
+ ((map->size_acts-map->num_acts)*sizeof(XkbAction)));
+ }
+ if (map->key_acts==NULL) {
+ i= xkb->max_key_code+1;
+ map->key_acts= calloc(i, sizeof(unsigned short));
+ if (map->key_acts==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbKeyBehaviorsMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->behaviors==NULL) {
+ i= xkb->max_key_code+1;
+ map->behaviors= calloc(i, sizeof(XkbBehavior));
+ if (map->behaviors==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbVirtualModMapMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->vmodmap==NULL) {
+ i= xkb->max_key_code+1;
+ map->vmodmap= calloc(i, sizeof(unsigned short));
+ if (map->vmodmap==NULL)
+ return BadAlloc;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+static Status
+XkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into)
+{
+ if ((!from)||(!into))
+ return BadMatch;
+ if (into->map) {
+ free(into->map);
+ into->map= NULL;
+ }
+ if (into->preserve) {
+ free(into->preserve);
+ into->preserve= NULL;
+ }
+ if (into->level_names) {
+ free(into->level_names);
+ into->level_names= NULL;
+ }
+ *into= *from;
+ if ((from->map)&&(into->map_count>0)) {
+ into->map= calloc(into->map_count, sizeof(XkbKTMapEntryRec));
+ if (!into->map)
+ return BadAlloc;
+ memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec));
+ }
+ if ((from->preserve)&&(into->map_count>0)) {
+ into->preserve= calloc(into->map_count, sizeof(XkbModsRec));
+ if (!into->preserve)
+ return BadAlloc;
+ memcpy(into->preserve,from->preserve,
+ into->map_count*sizeof(XkbModsRec));
+ }
+ if ((from->level_names)&&(into->num_levels>0)) {
+ into->level_names= calloc(into->num_levels, sizeof(Atom));
+ if (!into->level_names)
+ return BadAlloc;
+ memcpy(into->level_names,from->level_names,
+ into->num_levels*sizeof(Atom));
+ }
+ return Success;
+}
+
+Status
+XkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types)
+{
+register int i,rtrn;
+
+ if ((!from)||(!into)||(num_types<0))
+ return BadMatch;
+ for (i=0;i<num_types;i++) {
+ if ((rtrn= XkbCopyKeyType(from++,into++))!=Success)
+ return rtrn;
+ }
+ return Success;
+}
+
+Status
+XkbResizeKeyType( XkbDescPtr xkb,
+ int type_ndx,
+ int map_count,
+ Bool want_preserve,
+ int new_num_lvls)
+{
+XkbKeyTypePtr type;
+KeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys;
+
+ if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)||
+ (new_num_lvls<1))
+ return BadValue;
+ switch (type_ndx) {
+ case XkbOneLevelIndex:
+ if (new_num_lvls!=1)
+ return BadMatch;
+ break;
+ case XkbTwoLevelIndex:
+ case XkbAlphabeticIndex:
+ case XkbKeypadIndex:
+ if (new_num_lvls!=2)
+ return BadMatch;
+ break;
+ }
+ type= &xkb->map->types[type_ndx];
+ if (map_count==0) {
+ if (type->map!=NULL)
+ free(type->map);
+ type->map= NULL;
+ if (type->preserve!=NULL)
+ free(type->preserve);
+ type->preserve= NULL;
+ type->map_count= 0;
+ }
+ else {
+ XkbKTMapEntryRec *prev_map = type->map;
+
+ if ((map_count>type->map_count)||(type->map==NULL))
+ type->map = realloc(type->map,map_count * sizeof(XkbKTMapEntryRec));
+ if (!type->map) {
+ if (prev_map)
+ free(prev_map);
+ return BadAlloc;
+ }
+ if (want_preserve) {
+ XkbModsRec *prev_preserve = type->preserve;
+
+ if ((map_count>type->map_count)||(type->preserve==NULL)) {
+ type->preserve = realloc(type->preserve,
+ map_count * sizeof(XkbModsRec));
+ }
+ if (!type->preserve) {
+ if (prev_preserve)
+ free(prev_preserve);
+ return BadAlloc;
+ }
+ }
+ else if (type->preserve!=NULL) {
+ free(type->preserve);
+ type->preserve= NULL;
+ }
+ type->map_count= map_count;
+ }
+
+ if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) {
+ Atom * prev_level_names = type->level_names;
+
+ type->level_names = realloc(type->level_names,
+ new_num_lvls * sizeof(Atom));
+ if (!type->level_names) {
+ if (prev_level_names)
+ free(prev_level_names);
+ return BadAlloc;
+ }
+ }
+ /*
+ * Here's the theory:
+ * If the width of the type changed, we might have to resize the symbol
+ * maps for any keys that use the type for one or more groups. This is
+ * expensive, so we'll try to cull out any keys that are obviously okay:
+ * In any case:
+ * - keys that have a group width <= the old width are okay (because
+ * they could not possibly have been associated with the old type)
+ * If the key type increased in size:
+ * - keys that already have a group width >= to the new width are okay
+ * + keys that have a group width >= the old width but < the new width
+ * might have to be enlarged.
+ * If the key type decreased in size:
+ * - keys that have a group width > the old width don't have to be
+ * resized (because they must have some other wider type associated
+ * with some group).
+ * + keys that have a group width == the old width might have to be
+ * shrunk.
+ * The possibilities marked with '+' require us to examine the key types
+ * associated with each group for the key.
+ */
+ bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode));
+ nMatchingKeys= 0;
+ if (new_num_lvls>type->num_levels) {
+ int nTotal;
+ KeySym * newSyms;
+ int width,match,nResize;
+ register int i,g,nSyms;
+
+ nResize= 0;
+ for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ width= XkbKeyGroupsWidth(xkb,i);
+ if (width<type->num_levels)
+ continue;
+ for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
+ if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
+ matchingKeys[nMatchingKeys++]= i;
+ match= 1;
+ }
+ }
+ if ((!match)||(width>=new_num_lvls))
+ nTotal+= XkbKeyNumSyms(xkb,i);
+ else {
+ nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
+ nResize++;
+ }
+ }
+ if (nResize>0) {
+ int nextMatch;
+ xkb->map->size_syms= (nTotal*15)/10;
+ newSyms = calloc(xkb->map->size_syms, sizeof(KeySym));
+ if (newSyms==NULL)
+ return BadAlloc;
+ nextMatch= 0;
+ nSyms= 1;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (matchingKeys[nextMatch]==i) {
+ KeySym *pOld;
+ nextMatch++;
+ width= XkbKeyGroupsWidth(xkb,i);
+ pOld= XkbKeySymsPtr(xkb,i);
+ for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) {
+ memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g],
+ width*sizeof(KeySym));
+ }
+ xkb->map->key_sym_map[i].offset= nSyms;
+ nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
+ }
+ else {
+ memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),
+ XkbKeyNumSyms(xkb,i)*sizeof(KeySym));
+ xkb->map->key_sym_map[i].offset= nSyms;
+ nSyms+= XkbKeyNumSyms(xkb,i);
+ }
+ }
+ type->num_levels= new_num_lvls;
+ free(xkb->map->syms);
+ xkb->map->syms= newSyms;
+ xkb->map->num_syms= nSyms;
+ return Success;
+ }
+ }
+ else if (new_num_lvls<type->num_levels) {
+ int width,match;
+ register int g,i;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ width= XkbKeyGroupsWidth(xkb,i);
+ if (width<type->num_levels)
+ continue;
+ for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
+ if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
+ matchingKeys[nMatchingKeys++]= i;
+ match= 1;
+ }
+ }
+ }
+ }
+ if (nMatchingKeys>0) {
+ int key,firstClear;
+ register int i,g;
+ if (new_num_lvls>type->num_levels)
+ firstClear= type->num_levels;
+ else firstClear= new_num_lvls;
+ for (i=0;i<nMatchingKeys;i++) {
+ KeySym * pSyms;
+ int width,nClear;
+
+ key= matchingKeys[i];
+ width= XkbKeyGroupsWidth(xkb,key);
+ nClear= width-firstClear;
+ pSyms= XkbKeySymsPtr(xkb,key);
+ for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) {
+ if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) {
+ if (nClear>0)
+ bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym));
+ }
+ }
+ }
+ }
+ type->num_levels= new_num_lvls;
+ return Success;
+}
+
+KeySym *
+XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed)
+{
+register int i,nSyms,nKeySyms;
+unsigned nOldSyms;
+KeySym *newSyms;
+
+ if (needed==0) {
+ xkb->map->key_sym_map[key].offset= 0;
+ return xkb->map->syms;
+ }
+ nOldSyms= XkbKeyNumSyms(xkb,key);
+ if (nOldSyms>=(unsigned)needed) {
+ return XkbKeySymsPtr(xkb,key);
+ }
+ if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) {
+ if (nOldSyms>0) {
+ memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key),
+ nOldSyms*sizeof(KeySym));
+ }
+ if ((needed-nOldSyms)>0) {
+ bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)],
+ (needed-nOldSyms)*sizeof(KeySym));
+ }
+ xkb->map->key_sym_map[key].offset = xkb->map->num_syms;
+ xkb->map->num_syms+= needed;
+ return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
+ }
+ xkb->map->size_syms+= (needed>32?needed:32);
+ newSyms = calloc(xkb->map->size_syms, sizeof(KeySym));
+ if (newSyms==NULL)
+ return NULL;
+ newSyms[0]= NoSymbol;
+ nSyms = 1;
+ for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
+ int nCopy;
+
+ nCopy= nKeySyms= XkbKeyNumSyms(xkb,i);
+ if ((nKeySyms==0)&&(i!=key))
+ continue;
+ if (i==key)
+ nKeySyms= needed;
+ if (nCopy!=0)
+ memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym));
+ if (nKeySyms>nCopy)
+ bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym));
+ xkb->map->key_sym_map[i].offset = nSyms;
+ nSyms+= nKeySyms;
+ }
+ free(xkb->map->syms);
+ xkb->map->syms = newSyms;
+ xkb->map->num_syms = nSyms;
+ return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
+}
+
+static unsigned
+_ExtendRange( unsigned int old_flags,
+ unsigned int flag,
+ KeyCode newKC,
+ KeyCode * old_min,
+ unsigned char * old_num)
+{
+ if ((old_flags&flag)==0) {
+ old_flags|= flag;
+ *old_min= newKC;
+ *old_num= 1;
+ }
+ else {
+ int last= (*old_min)+(*old_num)-1;
+ if (newKC<*old_min) {
+ *old_min= newKC;
+ *old_num= (last-newKC)+1;
+ }
+ else if (newKC>last) {
+ *old_num= (newKC-(*old_min))+1;
+ }
+ }
+ return old_flags;
+}
+
+Status
+XkbChangeKeycodeRange( XkbDescPtr xkb,
+ int minKC,
+ int maxKC,
+ XkbChangesPtr changes)
+{
+int tmp;
+
+ if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode))
+ return BadValue;
+ if (minKC>maxKC)
+ return BadMatch;
+ if (minKC<xkb->min_key_code) {
+ if (changes)
+ changes->map.min_key_code= minKC;
+ tmp= xkb->min_key_code-minKC;
+ if (xkb->map) {
+ if (xkb->map->key_sym_map) {
+ bzero((char *)&xkb->map->key_sym_map[minKC],
+ tmp*sizeof(XkbSymMapRec));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeySymsMask,minKC,
+ &changes->map.first_key_sym,
+ &changes->map.num_key_syms);
+ }
+ }
+ if (xkb->map->modmap) {
+ bzero((char *)&xkb->map->modmap[minKC],tmp);
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbModifierMapMask,minKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_modmap_keys);
+ }
+ }
+ }
+ if (xkb->server) {
+ if (xkb->server->behaviors) {
+ bzero((char *)&xkb->server->behaviors[minKC],
+ tmp*sizeof(XkbBehavior));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyBehaviorsMask,minKC,
+ &changes->map.first_key_behavior,
+ &changes->map.num_key_behaviors);
+ }
+ }
+ if (xkb->server->key_acts) {
+ bzero((char *)&xkb->server->key_acts[minKC],
+ tmp*sizeof(unsigned short));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyActionsMask,minKC,
+ &changes->map.first_key_act,
+ &changes->map.num_key_acts);
+ }
+ }
+ if (xkb->server->vmodmap) {
+ bzero((char *)&xkb->server->vmodmap[minKC],
+ tmp*sizeof(unsigned short));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbVirtualModMapMask,minKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_vmodmap_keys);
+ }
+ }
+ }
+ if ((xkb->names)&&(xkb->names->keys)) {
+ bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec));
+ if (changes) {
+ changes->names.changed= _ExtendRange(changes->names.changed,
+ XkbKeyNamesMask,minKC,
+ &changes->names.first_key,
+ &changes->names.num_keys);
+ }
+ }
+ xkb->min_key_code= minKC;
+ }
+ if (maxKC>xkb->max_key_code) {
+ if (changes)
+ changes->map.max_key_code= maxKC;
+ tmp= maxKC-xkb->max_key_code;
+ if (xkb->map) {
+ if (xkb->map->key_sym_map) {
+ XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map;
+
+ xkb->map->key_sym_map = realloc(xkb->map->key_sym_map,
+ (maxKC+1) * sizeof(XkbSymMapRec));
+ if (!xkb->map->key_sym_map) {
+ free(prev_key_sym_map);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code],
+ tmp*sizeof(XkbSymMapRec));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeySymsMask,maxKC,
+ &changes->map.first_key_sym,
+ &changes->map.num_key_syms);
+ }
+ }
+ if (xkb->map->modmap) {
+ unsigned char *prev_modmap = xkb->map->modmap;
+
+ xkb->map->modmap = realloc(xkb->map->modmap,
+ (maxKC+1) * sizeof(unsigned char));
+ if (!xkb->map->modmap) {
+ free(prev_modmap);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp);
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbModifierMapMask,maxKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_modmap_keys);
+ }
+ }
+ }
+ if (xkb->server) {
+ if (xkb->server->behaviors) {
+ XkbBehavior *prev_behaviors = xkb->server->behaviors;
+
+ xkb->server->behaviors = realloc(xkb->server->behaviors,
+ (maxKC+1) * sizeof(XkbBehavior));
+ if (!xkb->server->behaviors) {
+ free(prev_behaviors);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->server->behaviors[xkb->max_key_code],
+ tmp*sizeof(XkbBehavior));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyBehaviorsMask,maxKC,
+ &changes->map.first_key_behavior,
+ &changes->map.num_key_behaviors);
+ }
+ }
+ if (xkb->server->key_acts) {
+ unsigned short *prev_key_acts = xkb->server->key_acts;
+
+ xkb->server->key_acts= realloc(xkb->server->key_acts,
+ (maxKC+1) * sizeof(unsigned short));
+ if (!xkb->server->key_acts) {
+ free(prev_key_acts);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->server->key_acts[xkb->max_key_code],
+ tmp*sizeof(unsigned short));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyActionsMask,maxKC,
+ &changes->map.first_key_act,
+ &changes->map.num_key_acts);
+ }
+ }
+ if (xkb->server->vmodmap) {
+ unsigned short *prev_vmodmap = xkb->server->vmodmap;
+
+ xkb->server->vmodmap= realloc(xkb->server->vmodmap,
+ (maxKC+1) * sizeof(unsigned short));
+ if (!xkb->server->vmodmap) {
+ free(prev_vmodmap);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->server->vmodmap[xkb->max_key_code],
+ tmp*sizeof(unsigned short));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbVirtualModMapMask,maxKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_vmodmap_keys);
+ }
+ }
+ }
+ if ((xkb->names)&&(xkb->names->keys)) {
+ XkbKeyNameRec *prev_keys = xkb->names->keys;
+
+ xkb->names->keys = realloc(xkb->names->keys,
+ (maxKC+1) * sizeof(XkbKeyNameRec));
+ if (!xkb->names->keys) {
+ free(prev_keys);
+ return BadAlloc;
+ }
+ bzero((char *)&xkb->names->keys[xkb->max_key_code],
+ tmp*sizeof(XkbKeyNameRec));
+ if (changes) {
+ changes->names.changed= _ExtendRange(changes->names.changed,
+ XkbKeyNamesMask,maxKC,
+ &changes->names.first_key,
+ &changes->names.num_keys);
+ }
+ }
+ xkb->max_key_code= maxKC;
+ }
+ return Success;
+}
+
+XkbAction *
+XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed)
+{
+register int i,nActs;
+XkbAction *newActs;
+
+ if (needed==0) {
+ xkb->server->key_acts[key]= 0;
+ return NULL;
+ }
+ if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed))
+ return XkbKeyActionsPtr(xkb,key);
+ if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) {
+ xkb->server->key_acts[key]= xkb->server->num_acts;
+ xkb->server->num_acts+= needed;
+ return &xkb->server->acts[xkb->server->key_acts[key]];
+ }
+ xkb->server->size_acts= xkb->server->num_acts+needed+8;
+ newActs = calloc(xkb->server->size_acts, sizeof(XkbAction));
+ if (newActs==NULL)
+ return NULL;
+ newActs[0].type = XkbSA_NoAction;
+ nActs = 1;
+ for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
+ int nKeyActs,nCopy;
+
+ if ((xkb->server->key_acts[i]==0)&&(i!=key))
+ continue;
+
+ nCopy= nKeyActs= XkbKeyNumActions(xkb,i);
+ if (i==key) {
+ nKeyActs= needed;
+ if (needed<nCopy)
+ nCopy= needed;
+ }
+
+ if (nCopy>0)
+ memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i),
+ nCopy*sizeof(XkbAction));
+ if (nCopy<nKeyActs)
+ bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction));
+ xkb->server->key_acts[i]= nActs;
+ nActs+= nKeyActs;
+ }
+ free(xkb->server->acts);
+ xkb->server->acts = newActs;
+ xkb->server->num_acts= nActs;
+ return &xkb->server->acts[xkb->server->key_acts[key]];
+}
+
+void
+XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
+{
+XkbClientMapPtr map;
+
+ if ((xkb==NULL)||(xkb->map==NULL))
+ return;
+ if (freeMap)
+ what= XkbAllClientInfoMask;
+ map= xkb->map;
+ if (what&XkbKeyTypesMask) {
+ if (map->types!=NULL) {
+ if (map->num_types>0) {
+ register int i;
+ XkbKeyTypePtr type;
+ for (i=0,type=map->types;i<map->num_types;i++,type++) {
+ if (type->map!=NULL) {
+ free(type->map);
+ type->map= NULL;
+ }
+ if (type->preserve!=NULL) {
+ free(type->preserve);
+ type->preserve= NULL;
+ }
+ type->map_count= 0;
+ if (type->level_names!=NULL) {
+ free(type->level_names);
+ type->level_names= NULL;
+ }
+ }
+ }
+ free(map->types);
+ map->num_types= map->size_types= 0;
+ map->types= NULL;
+ }
+ }
+ if (what&XkbKeySymsMask) {
+ if (map->key_sym_map!=NULL) {
+ free(map->key_sym_map);
+ map->key_sym_map= NULL;
+ }
+ if (map->syms!=NULL) {
+ free(map->syms);
+ map->size_syms= map->num_syms= 0;
+ map->syms= NULL;
+ }
+ }
+ if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) {
+ free(map->modmap);
+ map->modmap= NULL;
+ }
+ if (freeMap) {
+ free(xkb->map);
+ xkb->map= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
+{
+XkbServerMapPtr map;
+
+ if ((xkb==NULL)||(xkb->server==NULL))
+ return;
+ if (freeMap)
+ what= XkbAllServerInfoMask;
+ map= xkb->server;
+ if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) {
+ free(map->explicit);
+ map->explicit= NULL;
+ }
+ if (what&XkbKeyActionsMask) {
+ if (map->key_acts!=NULL) {
+ free(map->key_acts);
+ map->key_acts= NULL;
+ }
+ if (map->acts!=NULL) {
+ free(map->acts);
+ map->num_acts= map->size_acts= 0;
+ map->acts= NULL;
+ }
+ }
+ if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) {
+ free(map->behaviors);
+ map->behaviors= NULL;
+ }
+ if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) {
+ free(map->vmodmap);
+ map->vmodmap= NULL;
+ }
+
+ if (freeMap) {
+ free(xkb->server);
+ xkb->server= NULL;
+ }
+ return;
+}
diff --git a/xorg-server/xkb/XKBMisc.c b/xorg-server/xkb/XKBMisc.c
index 2bb4a2452..758638f4b 100644
--- a/xorg-server/xkb/XKBMisc.c
+++ b/xorg-server/xkb/XKBMisc.c
@@ -1,839 +1,839 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#elif defined(HAVE_CONFIG_H)
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-#include <X11/keysym.h>
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-
-/***====================================================================***/
-
-#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
-#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
-
-int
-XkbKeyTypesForCoreSymbols( XkbDescPtr xkb,
- int map_width,
- KeySym * core_syms,
- unsigned int protected,
- int * types_inout,
- KeySym * xkb_syms_rtrn)
-{
-register int i;
-unsigned int empty;
-int nSyms[XkbNumKbdGroups];
-int nGroups,tmp,groupsWidth;
-BOOL replicated = FALSE;
-
- /* Section 12.2 of the protocol describes this process in more detail */
- /* Step 1: find the # of symbols in the core mapping per group */
- groupsWidth= 2;
- for (i=0;i<XkbNumKbdGroups;i++) {
- if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) {
- nSyms[i]= xkb->map->types[types_inout[i]].num_levels;
- if (nSyms[i]>groupsWidth)
- groupsWidth= nSyms[i];
- }
- else {
- types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */
- nSyms[i]= 2;
- }
- }
- if (nSyms[XkbGroup1Index]<2)
- nSyms[XkbGroup1Index]= 2;
- if (nSyms[XkbGroup2Index]<2)
- nSyms[XkbGroup2Index]= 2;
- /* Step 2: Copy the symbols from the core ordering to XKB ordering */
- /* symbols in the core are in the order: */
- /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0);
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1);
- for (i=2;i<nSyms[XkbGroup1Index];i++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i);
- }
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2);
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3);
- tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */
- for (i=2;i<nSyms[XkbGroup2Index];i++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i);
- }
-
- /* Special case: if only the first group is explicit, and the symbols
- * replicate across all groups, then we have a Section 12.4 replication */
- if ((protected & ~XkbExplicitKeyType1Mask) == 0)
- {
- int j, width = nSyms[XkbGroup1Index];
-
- replicated = TRUE;
-
- /* Check ABAB in ABABCDECDEABCDE */
- if ((width > 0 && CORE_SYM(0) != CORE_SYM(2)) ||
- (width > 1 && CORE_SYM(1) != CORE_SYM(3)))
- replicated = FALSE;
-
- /* Check CDECDE in ABABCDECDEABCDE */
- for (i = 2; i < width && replicated; i++)
- {
- if (CORE_SYM(2 + i) != CORE_SYM(i + width))
- replicated = FALSE;
- }
-
- /* Check ABCDE in ABABCDECDEABCDE */
- for (j = 2; replicated &&
- j < XkbNumKbdGroups &&
- map_width >= width * (j + 1); j++)
- {
- for (i = 0; i < width && replicated; i++)
- {
- if (CORE_SYM(((i < 2) ? i : 2 + i)) != CORE_SYM(i + width * j))
- replicated = FALSE;
- }
- }
- }
-
- if (replicated)
- {
- nSyms[XkbGroup2Index]= 0;
- nSyms[XkbGroup3Index]= 0;
- nSyms[XkbGroup4Index]= 0;
- nGroups= 1;
- } else
- {
- tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index];
- if ((tmp>=map_width)&&
- ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) {
- nSyms[XkbGroup3Index]= 0;
- nSyms[XkbGroup4Index]= 0;
- nGroups= 2;
- } else
- {
- nGroups= 3;
- for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp);
- }
- if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) {
- nGroups= 4;
- for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) {
- xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp);
- }
- }
- else {
- nSyms[XkbGroup4Index]= 0;
- }
- }
- }
- /* steps 3&4: alphanumeric expansion, assign canonical types */
- empty= 0;
- for (i=0;i<nGroups;i++) {
- KeySym *syms;
- syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
- if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) {
- KeySym upper,lower;
- XkbConvertCase(syms[0],&lower,&upper);
- if (upper!=lower) {
- xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower;
- xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper;
- if ((protected&(1<<i))==0)
- types_inout[i]= XkbAlphabeticIndex;
- }
- else if ((protected&(1<<i))==0) {
- types_inout[i]= XkbOneLevelIndex;
- /* nSyms[i]= 1;*/
- }
- }
- if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) {
- if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1]))
- types_inout[i]= XkbKeypadIndex;
- else {
- KeySym upper,lower;
- XkbConvertCase(syms[0],&lower,&upper);
- if ((syms[0]==lower)&&(syms[1]==upper))
- types_inout[i]= XkbAlphabeticIndex;
- }
- }
- if (syms[0]==NoSymbol) {
- register int n;
- Bool found;
- for (n=1,found=FALSE;(!found)&&(n<nSyms[i]);n++) {
- found= (syms[n]!=NoSymbol);
- }
- if (!found)
- empty|= (1<<i);
- }
- }
- /* step 5: squoosh out empty groups */
- if (empty) {
- for (i=nGroups-1;i>=0;i--) {
- if (((empty&(1<<i))==0)||(protected&(1<<i)))
- break;
- nGroups--;
- }
- }
- if (nGroups<1)
- return 0;
-
- /* step 6: replicate group 1 into group two, if necessary */
- if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) {
- if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) {
- nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index];
- types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index];
- memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn,
- 2*sizeof(KeySym));
- }
- else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) {
- memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]],
- (char *)xkb_syms_rtrn,
- nSyms[XkbGroup1Index]*sizeof(KeySym));
- }
- }
-
- /* step 7: check for all groups identical or all width 1
- *
- * Special feature: if group 1 has an explicit type and all other groups
- * have canonical types with same symbols, we assume it's info lost from
- * the core replication.
- */
- if (nGroups>1) {
- Bool sameType,allOneLevel, canonical = TRUE;
- allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1);
- for (i=1,sameType=TRUE;(allOneLevel||sameType)&&(i<nGroups);i++) {
- sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index]));
- if (allOneLevel)
- allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
- if (types_inout[i] > XkbLastRequiredType)
- canonical = FALSE;
- }
- if (((sameType) || canonical)&&
- (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
- register int s;
- Bool identical;
- for (i=1,identical=TRUE;identical&&(i<nGroups);i++) {
- KeySym *syms;
- if (nSyms[i] != nSyms[XkbGroup1Index])
- identical = FALSE;
- syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
- for (s=0;identical&&(s<nSyms[i]);s++) {
- if (syms[s]!=xkb_syms_rtrn[s])
- identical= FALSE;
- }
- }
- if (identical)
- nGroups= 1;
- }
- if (allOneLevel && (nGroups>1)) {
- KeySym *syms;
- syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]];
- nSyms[XkbGroup1Index]= 1;
- for (i=1;i<nGroups;i++) {
- xkb_syms_rtrn[i]= syms[0];
- syms+= nSyms[i];
- nSyms[i]= 1;
- }
- }
- }
- return nGroups;
-}
-
-static XkbSymInterpretPtr
-_XkbFindMatchingInterp( XkbDescPtr xkb,
- KeySym sym,
- unsigned int real_mods,
- unsigned int level)
-{
-register unsigned i;
-XkbSymInterpretPtr interp,rtrn;
-CARD8 mods;
-
- rtrn= NULL;
- interp= xkb->compat->sym_interpret;
- for (i=0;i<xkb->compat->num_si;i++,interp++) {
- if ((interp->sym==NoSymbol)||(sym==interp->sym)) {
- int match;
- if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0))
- mods= real_mods;
- else mods= 0;
- switch (interp->match&XkbSI_OpMask) {
- case XkbSI_NoneOf:
- match= ((interp->mods&mods)==0);
- break;
- case XkbSI_AnyOfOrNone:
- match= ((mods==0)||((interp->mods&mods)!=0));
- break;
- case XkbSI_AnyOf:
- match= ((interp->mods&mods)!=0);
- break;
- case XkbSI_AllOf:
- match= ((interp->mods&mods)==interp->mods);
- break;
- case XkbSI_Exactly:
- match= (interp->mods==mods);
- break;
- default:
- match= 0;
- break;
- }
- if (match) {
- if (interp->sym!=NoSymbol) {
- return interp;
- }
- else if (rtrn==NULL) {
- rtrn= interp;
- }
- }
- }
- }
- return rtrn;
-}
-
-static void
-_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey)
-{
-KeyCode last;
-
- last= (*pFirst)+(*pNum);
- if (newKey<*pFirst) {
- *pFirst= newKey;
- *pNum= (last-newKey)+1;
- }
- else if (newKey>last) {
- *pNum= (last-*pFirst)+1;
- }
- return;
-}
-
-static void
-_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
-{
-unsigned tmp;
-
- switch (act->type) {
- case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
- if (act->mods.flags&XkbSA_UseModMapMods)
- act->mods.real_mods= act->mods.mask= mods;
- if ((tmp= XkbModActionVMods(&act->mods))!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->mods.mask|= tmp;
- }
- break;
- case XkbSA_ISOLock:
- if (act->iso.flags&XkbSA_UseModMapMods)
- act->iso.real_mods= act->iso.mask= mods;
- if ((tmp= XkbModActionVMods(&act->iso))!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->iso.mask|= tmp;
- }
- break;
- }
- return;
-}
-
-#define IBUF_SIZE 8
-
-Bool
-XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes)
-{
-KeySym * syms;
-unsigned char explicit,mods;
-XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE];
-int n,nSyms,found;
-unsigned changed,tmp;
-
- if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)||
- (!xkb->compat)||(!xkb->compat->sym_interpret)||
- (key<xkb->min_key_code)||(key>xkb->max_key_code)) {
- return FALSE;
- }
- if (((!xkb->server)||(!xkb->server->key_acts))&&
- (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) {
- return FALSE;
- }
- changed= 0; /* keeps track of what has changed in _this_ call */
- explicit= xkb->server->explicit[key];
- if (explicit&XkbExplicitInterpretMask) /* nothing to do */
- return TRUE;
- mods= (xkb->map->modmap?xkb->map->modmap[key]:0);
- nSyms= XkbKeyNumSyms(xkb,key);
- syms= XkbKeySymsPtr(xkb,key);
- if (nSyms>IBUF_SIZE) {
- interps= xcalloc(nSyms, sizeof(XkbSymInterpretPtr));
- if (interps==NULL) {
- interps= ibuf;
- nSyms= IBUF_SIZE;
- }
- }
- else {
- interps= ibuf;
- }
- found= 0;
- for (n=0;n<nSyms;n++) {
- unsigned level= (n%XkbKeyGroupsWidth(xkb,key));
- interps[n]= NULL;
- if (syms[n]!=NoSymbol) {
- interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level);
- if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction)
- found++;
- else interps[n]= NULL;
- }
- }
- /* 1/28/96 (ef) -- XXX! WORKING HERE */
- if (!found) {
- if (xkb->server->key_acts[key]!=0) {
- xkb->server->key_acts[key]= 0;
- changed|= XkbKeyActionsMask;
- }
- }
- else {
- XkbAction *pActs;
- unsigned int new_vmodmask;
- changed|= XkbKeyActionsMask;
- pActs= XkbResizeKeyActions(xkb,key,nSyms);
- if (!pActs) {
- if (nSyms > IBUF_SIZE)
- xfree(interps);
- return FALSE;
- }
- new_vmodmask= 0;
- for (n=0;n<nSyms;n++) {
- if (interps[n]) {
- unsigned effMods;
-
- pActs[n]= *((XkbAction *)&interps[n]->act);
- if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) {
- effMods= mods;
- if (interps[n]->virtual_mod!=XkbNoModifier)
- new_vmodmask|= (1<<interps[n]->virtual_mod);
- }
- else effMods= 0;
- _XkbSetActionKeyMods(xkb,&pActs[n],effMods);
- }
- else pActs[n].type= XkbSA_NoAction;
- }
- if (((explicit&XkbExplicitVModMapMask)==0)&&
- (xkb->server->vmodmap[key]!=new_vmodmask)) {
- changed|= XkbVirtualModMapMask;
- xkb->server->vmodmap[key]= new_vmodmask;
- }
- if (interps[0]) {
- if ((interps[0]->flags&XkbSI_LockingKey)&&
- ((explicit&XkbExplicitBehaviorMask)==0)) {
- xkb->server->behaviors[key].type= XkbKB_Lock;
- changed|= XkbKeyBehaviorsMask;
- }
- if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
- CARD8 old;
- old= xkb->ctrls->per_key_repeat[key/8];
- if (interps[0]->flags&XkbSI_AutoRepeat)
- xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
- else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8));
- if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
- changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
- }
- }
- }
- if ((!found)||(interps[0]==NULL)) {
- if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
- CARD8 old;
- old= xkb->ctrls->per_key_repeat[key/8];
- xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
- if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
- changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
- }
- if (((explicit&XkbExplicitBehaviorMask)==0)&&
- (xkb->server->behaviors[key].type==XkbKB_Lock)) {
- xkb->server->behaviors[key].type= XkbKB_Default;
- changed|= XkbKeyBehaviorsMask;
- }
- }
- if (changes) {
- XkbMapChangesPtr mc;
- mc= &changes->map;
- tmp= (changed&mc->changed);
- if (tmp&XkbKeyActionsMask)
- _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key);
- else if (changed&XkbKeyActionsMask) {
- mc->changed|= XkbKeyActionsMask;
- mc->first_key_act= key;
- mc->num_key_acts= 1;
- }
- if (tmp&XkbKeyBehaviorsMask) {
- _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors,
- key);
- }
- else if (changed&XkbKeyBehaviorsMask) {
- mc->changed|= XkbKeyBehaviorsMask;
- mc->first_key_behavior= key;
- mc->num_key_behaviors= 1;
- }
- if (tmp&XkbVirtualModMapMask)
- _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key);
- else if (changed&XkbVirtualModMapMask) {
- mc->changed|= XkbVirtualModMapMask;
- mc->first_vmodmap_key= key;
- mc->num_vmodmap_keys= 1;
- }
- mc->changed|= changed;
- }
- if (interps!=ibuf)
- xfree(interps);
- return TRUE;
-}
-
-Status
-XkbChangeTypesOfKey( XkbDescPtr xkb,
- int key,
- int nGroups,
- unsigned groups,
- int * newTypesIn,
- XkbMapChangesPtr changes)
-{
-XkbKeyTypePtr pOldType,pNewType;
-register int i;
-int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
-
- if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
- (!xkb->map->types)||(!newTypesIn)||((groups&XkbAllGroupsMask)==0)||
- (nGroups>XkbNumKbdGroups)) {
- return BadMatch;
- }
- if (nGroups==0) {
- for (i=0;i<XkbNumKbdGroups;i++) {
- xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex;
- }
- i= xkb->map->key_sym_map[key].group_info;
- i= XkbSetNumGroups(i,0);
- xkb->map->key_sym_map[key].group_info= i;
- XkbResizeKeySyms(xkb,key,0);
- return Success;
- }
-
- nOldGroups= XkbKeyNumGroups(xkb,key);
- oldWidth= XkbKeyGroupsWidth(xkb,key);
- for (width=i=0;i<nGroups;i++) {
- if (groups&(1<<i))
- newTypes[i]= newTypesIn[i];
- else if (i<nOldGroups)
- newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i);
- else if (nOldGroups>0)
- newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
- else newTypes[i]= XkbTwoLevelIndex;
- if (newTypes[i]>xkb->map->num_types)
- return BadMatch;
- pNewType= &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels>width)
- width= pNewType->num_levels;
- }
- if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups))
- xkb->ctrls->num_groups= nGroups;
- if ((width!=oldWidth)||(nGroups!=nOldGroups)) {
- KeySym oldSyms[XkbMaxSymsPerKey],*pSyms;
- int nCopy;
-
- if (nOldGroups==0) {
- pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
- if (pSyms!=NULL) {
- i= xkb->map->key_sym_map[key].group_info;
- i= XkbSetNumGroups(i,nGroups);
- xkb->map->key_sym_map[key].group_info= i;
- xkb->map->key_sym_map[key].width= width;
- for (i=0;i<nGroups;i++) {
- xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
- }
- return Success;
- }
- return BadAlloc;
- }
- pSyms= XkbKeySymsPtr(xkb,key);
- memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
- pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
- if (pSyms==NULL)
- return BadAlloc;
- bzero(pSyms,width*nGroups*sizeof(KeySym));
- for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
- pOldType= XkbKeyKeyType(xkb,key,i);
- pNewType= &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels>pOldType->num_levels)
- nCopy= pOldType->num_levels;
- else nCopy= pNewType->num_levels;
- memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym));
- }
- if (XkbKeyHasActions(xkb,key)) {
- XkbAction oldActs[XkbMaxSymsPerKey],*pActs;
- pActs= XkbKeyActionsPtr(xkb,key);
- memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction));
- pActs= XkbResizeKeyActions(xkb,key,width*nGroups);
- if (pActs==NULL)
- return BadAlloc;
- bzero(pActs,width*nGroups*sizeof(XkbAction));
- for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
- pOldType= XkbKeyKeyType(xkb,key,i);
- pNewType= &xkb->map->types[newTypes[i]];
- if (pNewType->num_levels>pOldType->num_levels)
- nCopy= pOldType->num_levels;
- else nCopy= pNewType->num_levels;
- memcpy(&pActs[i*width],&oldActs[i*oldWidth],
- nCopy*sizeof(XkbAction));
- }
- }
- i= xkb->map->key_sym_map[key].group_info;
- i= XkbSetNumGroups(i,nGroups);
- xkb->map->key_sym_map[key].group_info= i;
- xkb->map->key_sym_map[key].width= width;
- }
- width= 0;
- for (i=0;i<nGroups;i++) {
- xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
- if (xkb->map->types[newTypes[i]].num_levels>width)
- width= xkb->map->types[newTypes[i]].num_levels;
- }
- xkb->map->key_sym_map[key].width= width;
- if (changes!=NULL) {
- if (changes->changed&XkbKeySymsMask) {
- _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms,
- key);
- }
- else {
- changes->changed|= XkbKeySymsMask;
- changes->first_key_sym= key;
- changes->num_key_syms= 1;
- }
- }
- return Success;
-}
-
-/***====================================================================***/
-
-Bool
-XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn)
-{
-register int i,bit;
-register unsigned mask;
-
- if (xkb==NULL)
- return FALSE;
- if (virtual_mask==0) {
- *mask_rtrn= 0;
- return TRUE;
- }
- if (xkb->server==NULL)
- return FALSE;
- for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (virtual_mask&bit)
- mask|= xkb->server->vmods[i];
- }
- *mask_rtrn= mask;
- return TRUE;
-}
-
-/***====================================================================***/
-
-static Bool
-XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed)
-{
-unsigned int tmp;
-
- switch (act->type) {
- case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
- if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->mods.mask= act->mods.real_mods;
- act->mods.mask|= tmp;
- return TRUE;
- }
- break;
- case XkbSA_ISOLock:
- if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) {
- XkbVirtualModsToReal(xkb,tmp,&tmp);
- act->iso.mask= act->iso.real_mods;
- act->iso.mask|= tmp;
- return TRUE;
- }
- break;
- }
- return FALSE;
-}
-
-static void
-XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb,
- XkbKeyTypePtr type,
- unsigned int changed,
- XkbChangesPtr changes)
-{
-register unsigned int i;
-unsigned int mask;
-
- XkbVirtualModsToReal(xkb,type->mods.vmods,&mask);
- type->mods.mask= type->mods.real_mods|mask;
- if ((type->map_count>0)&&(type->mods.vmods!=0)) {
- XkbKTMapEntryPtr entry;
- for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
- if (entry->mods.vmods!=0) {
- XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask);
- entry->mods.mask=entry->mods.real_mods|mask;
- /* entry is active if vmods are bound*/
- entry->active= (mask!=0);
- }
- else entry->active= 1;
- }
- }
- if (changes) {
- int type_ndx;
- type_ndx= type-xkb->map->types;
- if ((type_ndx<0)||(type_ndx>xkb->map->num_types))
- return;
- if (changes->map.changed&XkbKeyTypesMask) {
- int last;
- last= changes->map.first_type+changes->map.num_types-1;
- if (type_ndx<changes->map.first_type) {
- changes->map.first_type= type_ndx;
- changes->map.num_types= (last-type_ndx)+1;
- }
- else if (type_ndx>last) {
- changes->map.num_types= (type_ndx-changes->map.first_type)+1;
- }
- }
- else {
- changes->map.changed|= XkbKeyTypesMask;
- changes->map.first_type= type_ndx;
- changes->map.num_types= 1;
- }
- }
- return;
-}
-
-Bool
-XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes)
-{
-register int i;
-unsigned int checkState = 0;
-
- if ((!xkb) || (!xkb->map) || (changed==0))
- return FALSE;
- for (i=0;i<xkb->map->num_types;i++) {
- if (xkb->map->types[i].mods.vmods & changed)
- XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes);
- }
- if (changed&xkb->ctrls->internal.vmods) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask);
- newMask|= xkb->ctrls->internal.real_mods;
- if (xkb->ctrls->internal.mask!=newMask) {
- xkb->ctrls->internal.mask= newMask;
- if (changes) {
- changes->ctrls.changed_ctrls|= XkbInternalModsMask;
- checkState= TRUE;
- }
- }
- }
- if (changed&xkb->ctrls->ignore_lock.vmods) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask);
- newMask|= xkb->ctrls->ignore_lock.real_mods;
- if (xkb->ctrls->ignore_lock.mask!=newMask) {
- xkb->ctrls->ignore_lock.mask= newMask;
- if (changes) {
- changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask;
- checkState= TRUE;
- }
- }
- }
- if (xkb->indicators!=NULL) {
- XkbIndicatorMapPtr map;
- map= &xkb->indicators->maps[0];
- for (i=0;i<XkbNumIndicators;i++,map++) {
- if (map->mods.vmods&changed) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask);
- newMask|= map->mods.real_mods;
- if (newMask!=map->mods.mask) {
- map->mods.mask= newMask;
- if (changes) {
- changes->indicators.map_changes|= (1<<i);
- checkState= TRUE;
- }
- }
- }
- }
- }
- if (xkb->compat!=NULL) {
- XkbCompatMapPtr compat;
- compat= xkb->compat;
- for (i=0;i<XkbNumKbdGroups;i++) {
- unsigned int newMask;
- XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask);
- newMask|= compat->groups[i].real_mods;
- if (compat->groups[i].mask!=newMask) {
- compat->groups[i].mask= newMask;
- if (changes) {
- changes->compat.changed_groups|= (1<<i);
- checkState= TRUE;
- }
- }
- }
- }
- if (xkb->map && xkb->server) {
- int highChange = 0, lowChange = -1;
- for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- if (XkbKeyHasActions(xkb,i)) {
- register XkbAction *pAct;
- register int n;
-
- pAct= XkbKeyActionsPtr(xkb,i);
- for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) {
- if ((pAct->type!=XkbSA_NoAction)&&
- XkbUpdateActionVirtualMods(xkb,pAct,changed)) {
- if (lowChange<0)
- lowChange= i;
- highChange= i;
- }
- }
- }
- }
- if (changes && (lowChange>0)) { /* something changed */
- if (changes->map.changed&XkbKeyActionsMask) {
- int last;
- if (changes->map.first_key_act<lowChange)
- lowChange= changes->map.first_key_act;
- last= changes->map.first_key_act+changes->map.num_key_acts-1;
- if (last>highChange)
- highChange= last;
- }
- changes->map.changed|= XkbKeyActionsMask;
- changes->map.first_key_act= lowChange;
- changes->map.num_key_acts= (highChange-lowChange)+1;
- }
- }
- return checkState;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <X11/keysym.h>
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+
+/***====================================================================***/
+
+#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
+#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
+
+int
+XkbKeyTypesForCoreSymbols( XkbDescPtr xkb,
+ int map_width,
+ KeySym * core_syms,
+ unsigned int protected,
+ int * types_inout,
+ KeySym * xkb_syms_rtrn)
+{
+register int i;
+unsigned int empty;
+int nSyms[XkbNumKbdGroups];
+int nGroups,tmp,groupsWidth;
+BOOL replicated = FALSE;
+
+ /* Section 12.2 of the protocol describes this process in more detail */
+ /* Step 1: find the # of symbols in the core mapping per group */
+ groupsWidth= 2;
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) {
+ nSyms[i]= xkb->map->types[types_inout[i]].num_levels;
+ if (nSyms[i]>groupsWidth)
+ groupsWidth= nSyms[i];
+ }
+ else {
+ types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */
+ nSyms[i]= 2;
+ }
+ }
+ if (nSyms[XkbGroup1Index]<2)
+ nSyms[XkbGroup1Index]= 2;
+ if (nSyms[XkbGroup2Index]<2)
+ nSyms[XkbGroup2Index]= 2;
+ /* Step 2: Copy the symbols from the core ordering to XKB ordering */
+ /* symbols in the core are in the order: */
+ /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0);
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1);
+ for (i=2;i<nSyms[XkbGroup1Index];i++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i);
+ }
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2);
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3);
+ tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */
+ for (i=2;i<nSyms[XkbGroup2Index];i++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i);
+ }
+
+ /* Special case: if only the first group is explicit, and the symbols
+ * replicate across all groups, then we have a Section 12.4 replication */
+ if ((protected & ~XkbExplicitKeyType1Mask) == 0)
+ {
+ int j, width = nSyms[XkbGroup1Index];
+
+ replicated = TRUE;
+
+ /* Check ABAB in ABABCDECDEABCDE */
+ if ((width > 0 && CORE_SYM(0) != CORE_SYM(2)) ||
+ (width > 1 && CORE_SYM(1) != CORE_SYM(3)))
+ replicated = FALSE;
+
+ /* Check CDECDE in ABABCDECDEABCDE */
+ for (i = 2; i < width && replicated; i++)
+ {
+ if (CORE_SYM(2 + i) != CORE_SYM(i + width))
+ replicated = FALSE;
+ }
+
+ /* Check ABCDE in ABABCDECDEABCDE */
+ for (j = 2; replicated &&
+ j < XkbNumKbdGroups &&
+ map_width >= width * (j + 1); j++)
+ {
+ for (i = 0; i < width && replicated; i++)
+ {
+ if (CORE_SYM(((i < 2) ? i : 2 + i)) != CORE_SYM(i + width * j))
+ replicated = FALSE;
+ }
+ }
+ }
+
+ if (replicated)
+ {
+ nSyms[XkbGroup2Index]= 0;
+ nSyms[XkbGroup3Index]= 0;
+ nSyms[XkbGroup4Index]= 0;
+ nGroups= 1;
+ } else
+ {
+ tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index];
+ if ((tmp>=map_width)&&
+ ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) {
+ nSyms[XkbGroup3Index]= 0;
+ nSyms[XkbGroup4Index]= 0;
+ nGroups= 2;
+ } else
+ {
+ nGroups= 3;
+ for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp);
+ }
+ if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) {
+ nGroups= 4;
+ for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp);
+ }
+ }
+ else {
+ nSyms[XkbGroup4Index]= 0;
+ }
+ }
+ }
+ /* steps 3&4: alphanumeric expansion, assign canonical types */
+ empty= 0;
+ for (i=0;i<nGroups;i++) {
+ KeySym *syms;
+ syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
+ if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) {
+ KeySym upper,lower;
+ XkbConvertCase(syms[0],&lower,&upper);
+ if (upper!=lower) {
+ xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower;
+ xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper;
+ if ((protected&(1<<i))==0)
+ types_inout[i]= XkbAlphabeticIndex;
+ }
+ else if ((protected&(1<<i))==0) {
+ types_inout[i]= XkbOneLevelIndex;
+ /* nSyms[i]= 1;*/
+ }
+ }
+ if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) {
+ if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1]))
+ types_inout[i]= XkbKeypadIndex;
+ else {
+ KeySym upper,lower;
+ XkbConvertCase(syms[0],&lower,&upper);
+ if ((syms[0]==lower)&&(syms[1]==upper))
+ types_inout[i]= XkbAlphabeticIndex;
+ }
+ }
+ if (syms[0]==NoSymbol) {
+ register int n;
+ Bool found;
+ for (n=1,found=FALSE;(!found)&&(n<nSyms[i]);n++) {
+ found= (syms[n]!=NoSymbol);
+ }
+ if (!found)
+ empty|= (1<<i);
+ }
+ }
+ /* step 5: squoosh out empty groups */
+ if (empty) {
+ for (i=nGroups-1;i>=0;i--) {
+ if (((empty&(1<<i))==0)||(protected&(1<<i)))
+ break;
+ nGroups--;
+ }
+ }
+ if (nGroups<1)
+ return 0;
+
+ /* step 6: replicate group 1 into group two, if necessary */
+ if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) {
+ if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) {
+ nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index];
+ types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index];
+ memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn,
+ 2*sizeof(KeySym));
+ }
+ else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) {
+ memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]],
+ (char *)xkb_syms_rtrn,
+ nSyms[XkbGroup1Index]*sizeof(KeySym));
+ }
+ }
+
+ /* step 7: check for all groups identical or all width 1
+ *
+ * Special feature: if group 1 has an explicit type and all other groups
+ * have canonical types with same symbols, we assume it's info lost from
+ * the core replication.
+ */
+ if (nGroups>1) {
+ Bool sameType,allOneLevel, canonical = TRUE;
+ allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1);
+ for (i=1,sameType=TRUE;(allOneLevel||sameType)&&(i<nGroups);i++) {
+ sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index]));
+ if (allOneLevel)
+ allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
+ if (types_inout[i] > XkbLastRequiredType)
+ canonical = FALSE;
+ }
+ if (((sameType) || canonical)&&
+ (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
+ register int s;
+ Bool identical;
+ for (i=1,identical=TRUE;identical&&(i<nGroups);i++) {
+ KeySym *syms;
+ if (nSyms[i] != nSyms[XkbGroup1Index])
+ identical = FALSE;
+ syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
+ for (s=0;identical&&(s<nSyms[i]);s++) {
+ if (syms[s]!=xkb_syms_rtrn[s])
+ identical= FALSE;
+ }
+ }
+ if (identical)
+ nGroups= 1;
+ }
+ if (allOneLevel && (nGroups>1)) {
+ KeySym *syms;
+ syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]];
+ nSyms[XkbGroup1Index]= 1;
+ for (i=1;i<nGroups;i++) {
+ xkb_syms_rtrn[i]= syms[0];
+ syms+= nSyms[i];
+ nSyms[i]= 1;
+ }
+ }
+ }
+ return nGroups;
+}
+
+static XkbSymInterpretPtr
+_XkbFindMatchingInterp( XkbDescPtr xkb,
+ KeySym sym,
+ unsigned int real_mods,
+ unsigned int level)
+{
+register unsigned i;
+XkbSymInterpretPtr interp,rtrn;
+CARD8 mods;
+
+ rtrn= NULL;
+ interp= xkb->compat->sym_interpret;
+ for (i=0;i<xkb->compat->num_si;i++,interp++) {
+ if ((interp->sym==NoSymbol)||(sym==interp->sym)) {
+ int match;
+ if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0))
+ mods= real_mods;
+ else mods= 0;
+ switch (interp->match&XkbSI_OpMask) {
+ case XkbSI_NoneOf:
+ match= ((interp->mods&mods)==0);
+ break;
+ case XkbSI_AnyOfOrNone:
+ match= ((mods==0)||((interp->mods&mods)!=0));
+ break;
+ case XkbSI_AnyOf:
+ match= ((interp->mods&mods)!=0);
+ break;
+ case XkbSI_AllOf:
+ match= ((interp->mods&mods)==interp->mods);
+ break;
+ case XkbSI_Exactly:
+ match= (interp->mods==mods);
+ break;
+ default:
+ match= 0;
+ break;
+ }
+ if (match) {
+ if (interp->sym!=NoSymbol) {
+ return interp;
+ }
+ else if (rtrn==NULL) {
+ rtrn= interp;
+ }
+ }
+ }
+ }
+ return rtrn;
+}
+
+static void
+_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey)
+{
+KeyCode last;
+
+ last= (*pFirst)+(*pNum);
+ if (newKey<*pFirst) {
+ *pFirst= newKey;
+ *pNum= (last-newKey)+1;
+ }
+ else if (newKey>last) {
+ *pNum= (last-*pFirst)+1;
+ }
+ return;
+}
+
+static void
+_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
+{
+unsigned tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (act->mods.flags&XkbSA_UseModMapMods)
+ act->mods.real_mods= act->mods.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->mods))!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->mods.mask|= tmp;
+ }
+ break;
+ case XkbSA_ISOLock:
+ if (act->iso.flags&XkbSA_UseModMapMods)
+ act->iso.real_mods= act->iso.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->iso))!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->iso.mask|= tmp;
+ }
+ break;
+ }
+ return;
+}
+
+#define IBUF_SIZE 8
+
+Bool
+XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes)
+{
+KeySym * syms;
+unsigned char explicit,mods;
+XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE];
+int n,nSyms,found;
+unsigned changed,tmp;
+
+ if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)||
+ (!xkb->compat)||(!xkb->compat->sym_interpret)||
+ (key<xkb->min_key_code)||(key>xkb->max_key_code)) {
+ return FALSE;
+ }
+ if (((!xkb->server)||(!xkb->server->key_acts))&&
+ (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) {
+ return FALSE;
+ }
+ changed= 0; /* keeps track of what has changed in _this_ call */
+ explicit= xkb->server->explicit[key];
+ if (explicit&XkbExplicitInterpretMask) /* nothing to do */
+ return TRUE;
+ mods= (xkb->map->modmap?xkb->map->modmap[key]:0);
+ nSyms= XkbKeyNumSyms(xkb,key);
+ syms= XkbKeySymsPtr(xkb,key);
+ if (nSyms>IBUF_SIZE) {
+ interps= calloc(nSyms, sizeof(XkbSymInterpretPtr));
+ if (interps==NULL) {
+ interps= ibuf;
+ nSyms= IBUF_SIZE;
+ }
+ }
+ else {
+ interps= ibuf;
+ }
+ found= 0;
+ for (n=0;n<nSyms;n++) {
+ unsigned level= (n%XkbKeyGroupsWidth(xkb,key));
+ interps[n]= NULL;
+ if (syms[n]!=NoSymbol) {
+ interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level);
+ if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction)
+ found++;
+ else interps[n]= NULL;
+ }
+ }
+ /* 1/28/96 (ef) -- XXX! WORKING HERE */
+ if (!found) {
+ if (xkb->server->key_acts[key]!=0) {
+ xkb->server->key_acts[key]= 0;
+ changed|= XkbKeyActionsMask;
+ }
+ }
+ else {
+ XkbAction *pActs;
+ unsigned int new_vmodmask;
+ changed|= XkbKeyActionsMask;
+ pActs= XkbResizeKeyActions(xkb,key,nSyms);
+ if (!pActs) {
+ if (nSyms > IBUF_SIZE)
+ free(interps);
+ return FALSE;
+ }
+ new_vmodmask= 0;
+ for (n=0;n<nSyms;n++) {
+ if (interps[n]) {
+ unsigned effMods;
+
+ pActs[n]= *((XkbAction *)&interps[n]->act);
+ if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) {
+ effMods= mods;
+ if (interps[n]->virtual_mod!=XkbNoModifier)
+ new_vmodmask|= (1<<interps[n]->virtual_mod);
+ }
+ else effMods= 0;
+ _XkbSetActionKeyMods(xkb,&pActs[n],effMods);
+ }
+ else pActs[n].type= XkbSA_NoAction;
+ }
+ if (((explicit&XkbExplicitVModMapMask)==0)&&
+ (xkb->server->vmodmap[key]!=new_vmodmask)) {
+ changed|= XkbVirtualModMapMask;
+ xkb->server->vmodmap[key]= new_vmodmask;
+ }
+ if (interps[0]) {
+ if ((interps[0]->flags&XkbSI_LockingKey)&&
+ ((explicit&XkbExplicitBehaviorMask)==0)) {
+ xkb->server->behaviors[key].type= XkbKB_Lock;
+ changed|= XkbKeyBehaviorsMask;
+ }
+ if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
+ CARD8 old;
+ old= xkb->ctrls->per_key_repeat[key/8];
+ if (interps[0]->flags&XkbSI_AutoRepeat)
+ xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
+ else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8));
+ if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
+ changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
+ }
+ }
+ }
+ if ((!found)||(interps[0]==NULL)) {
+ if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
+ CARD8 old;
+ old= xkb->ctrls->per_key_repeat[key/8];
+ xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
+ if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
+ changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
+ }
+ if (((explicit&XkbExplicitBehaviorMask)==0)&&
+ (xkb->server->behaviors[key].type==XkbKB_Lock)) {
+ xkb->server->behaviors[key].type= XkbKB_Default;
+ changed|= XkbKeyBehaviorsMask;
+ }
+ }
+ if (changes) {
+ XkbMapChangesPtr mc;
+ mc= &changes->map;
+ tmp= (changed&mc->changed);
+ if (tmp&XkbKeyActionsMask)
+ _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key);
+ else if (changed&XkbKeyActionsMask) {
+ mc->changed|= XkbKeyActionsMask;
+ mc->first_key_act= key;
+ mc->num_key_acts= 1;
+ }
+ if (tmp&XkbKeyBehaviorsMask) {
+ _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors,
+ key);
+ }
+ else if (changed&XkbKeyBehaviorsMask) {
+ mc->changed|= XkbKeyBehaviorsMask;
+ mc->first_key_behavior= key;
+ mc->num_key_behaviors= 1;
+ }
+ if (tmp&XkbVirtualModMapMask)
+ _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key);
+ else if (changed&XkbVirtualModMapMask) {
+ mc->changed|= XkbVirtualModMapMask;
+ mc->first_vmodmap_key= key;
+ mc->num_vmodmap_keys= 1;
+ }
+ mc->changed|= changed;
+ }
+ if (interps!=ibuf)
+ free(interps);
+ return TRUE;
+}
+
+Status
+XkbChangeTypesOfKey( XkbDescPtr xkb,
+ int key,
+ int nGroups,
+ unsigned groups,
+ int * newTypesIn,
+ XkbMapChangesPtr changes)
+{
+XkbKeyTypePtr pOldType,pNewType;
+register int i;
+int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
+
+ if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
+ (!xkb->map->types)||(!newTypesIn)||((groups&XkbAllGroupsMask)==0)||
+ (nGroups>XkbNumKbdGroups)) {
+ return BadMatch;
+ }
+ if (nGroups==0) {
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex;
+ }
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,0);
+ xkb->map->key_sym_map[key].group_info= i;
+ XkbResizeKeySyms(xkb,key,0);
+ return Success;
+ }
+
+ nOldGroups= XkbKeyNumGroups(xkb,key);
+ oldWidth= XkbKeyGroupsWidth(xkb,key);
+ for (width=i=0;i<nGroups;i++) {
+ if (groups&(1<<i))
+ newTypes[i]= newTypesIn[i];
+ else if (i<nOldGroups)
+ newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i);
+ else if (nOldGroups>0)
+ newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
+ else newTypes[i]= XkbTwoLevelIndex;
+ if (newTypes[i]>xkb->map->num_types)
+ return BadMatch;
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>width)
+ width= pNewType->num_levels;
+ }
+ if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups))
+ xkb->ctrls->num_groups= nGroups;
+ if ((width!=oldWidth)||(nGroups!=nOldGroups)) {
+ KeySym oldSyms[XkbMaxSymsPerKey],*pSyms;
+ int nCopy;
+
+ if (nOldGroups==0) {
+ pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
+ if (pSyms!=NULL) {
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,nGroups);
+ xkb->map->key_sym_map[key].group_info= i;
+ xkb->map->key_sym_map[key].width= width;
+ for (i=0;i<nGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
+ }
+ return Success;
+ }
+ return BadAlloc;
+ }
+ pSyms= XkbKeySymsPtr(xkb,key);
+ memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
+ pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
+ if (pSyms==NULL)
+ return BadAlloc;
+ bzero(pSyms,width*nGroups*sizeof(KeySym));
+ for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
+ pOldType= XkbKeyKeyType(xkb,key,i);
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>pOldType->num_levels)
+ nCopy= pOldType->num_levels;
+ else nCopy= pNewType->num_levels;
+ memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym));
+ }
+ if (XkbKeyHasActions(xkb,key)) {
+ XkbAction oldActs[XkbMaxSymsPerKey],*pActs;
+ pActs= XkbKeyActionsPtr(xkb,key);
+ memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction));
+ pActs= XkbResizeKeyActions(xkb,key,width*nGroups);
+ if (pActs==NULL)
+ return BadAlloc;
+ bzero(pActs,width*nGroups*sizeof(XkbAction));
+ for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
+ pOldType= XkbKeyKeyType(xkb,key,i);
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>pOldType->num_levels)
+ nCopy= pOldType->num_levels;
+ else nCopy= pNewType->num_levels;
+ memcpy(&pActs[i*width],&oldActs[i*oldWidth],
+ nCopy*sizeof(XkbAction));
+ }
+ }
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,nGroups);
+ xkb->map->key_sym_map[key].group_info= i;
+ xkb->map->key_sym_map[key].width= width;
+ }
+ width= 0;
+ for (i=0;i<nGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
+ if (xkb->map->types[newTypes[i]].num_levels>width)
+ width= xkb->map->types[newTypes[i]].num_levels;
+ }
+ xkb->map->key_sym_map[key].width= width;
+ if (changes!=NULL) {
+ if (changes->changed&XkbKeySymsMask) {
+ _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms,
+ key);
+ }
+ else {
+ changes->changed|= XkbKeySymsMask;
+ changes->first_key_sym= key;
+ changes->num_key_syms= 1;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+Bool
+XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn)
+{
+register int i,bit;
+register unsigned mask;
+
+ if (xkb==NULL)
+ return FALSE;
+ if (virtual_mask==0) {
+ *mask_rtrn= 0;
+ return TRUE;
+ }
+ if (xkb->server==NULL)
+ return FALSE;
+ for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (virtual_mask&bit)
+ mask|= xkb->server->vmods[i];
+ }
+ *mask_rtrn= mask;
+ return TRUE;
+}
+
+/***====================================================================***/
+
+static Bool
+XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed)
+{
+unsigned int tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->mods.mask= act->mods.real_mods;
+ act->mods.mask|= tmp;
+ return TRUE;
+ }
+ break;
+ case XkbSA_ISOLock:
+ if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->iso.mask= act->iso.real_mods;
+ act->iso.mask|= tmp;
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static void
+XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb,
+ XkbKeyTypePtr type,
+ unsigned int changed,
+ XkbChangesPtr changes)
+{
+register unsigned int i;
+unsigned int mask;
+
+ XkbVirtualModsToReal(xkb,type->mods.vmods,&mask);
+ type->mods.mask= type->mods.real_mods|mask;
+ if ((type->map_count>0)&&(type->mods.vmods!=0)) {
+ XkbKTMapEntryPtr entry;
+ for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
+ if (entry->mods.vmods!=0) {
+ XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask);
+ entry->mods.mask=entry->mods.real_mods|mask;
+ /* entry is active if vmods are bound*/
+ entry->active= (mask!=0);
+ }
+ else entry->active= 1;
+ }
+ }
+ if (changes) {
+ int type_ndx;
+ type_ndx= type-xkb->map->types;
+ if ((type_ndx<0)||(type_ndx>xkb->map->num_types))
+ return;
+ if (changes->map.changed&XkbKeyTypesMask) {
+ int last;
+ last= changes->map.first_type+changes->map.num_types-1;
+ if (type_ndx<changes->map.first_type) {
+ changes->map.first_type= type_ndx;
+ changes->map.num_types= (last-type_ndx)+1;
+ }
+ else if (type_ndx>last) {
+ changes->map.num_types= (type_ndx-changes->map.first_type)+1;
+ }
+ }
+ else {
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type= type_ndx;
+ changes->map.num_types= 1;
+ }
+ }
+ return;
+}
+
+Bool
+XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes)
+{
+register int i;
+unsigned int checkState = 0;
+
+ if ((!xkb) || (!xkb->map) || (changed==0))
+ return FALSE;
+ for (i=0;i<xkb->map->num_types;i++) {
+ if (xkb->map->types[i].mods.vmods & changed)
+ XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes);
+ }
+ if (changed&xkb->ctrls->internal.vmods) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask);
+ newMask|= xkb->ctrls->internal.real_mods;
+ if (xkb->ctrls->internal.mask!=newMask) {
+ xkb->ctrls->internal.mask= newMask;
+ if (changes) {
+ changes->ctrls.changed_ctrls|= XkbInternalModsMask;
+ checkState= TRUE;
+ }
+ }
+ }
+ if (changed&xkb->ctrls->ignore_lock.vmods) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask);
+ newMask|= xkb->ctrls->ignore_lock.real_mods;
+ if (xkb->ctrls->ignore_lock.mask!=newMask) {
+ xkb->ctrls->ignore_lock.mask= newMask;
+ if (changes) {
+ changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask;
+ checkState= TRUE;
+ }
+ }
+ }
+ if (xkb->indicators!=NULL) {
+ XkbIndicatorMapPtr map;
+ map= &xkb->indicators->maps[0];
+ for (i=0;i<XkbNumIndicators;i++,map++) {
+ if (map->mods.vmods&changed) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask);
+ newMask|= map->mods.real_mods;
+ if (newMask!=map->mods.mask) {
+ map->mods.mask= newMask;
+ if (changes) {
+ changes->indicators.map_changes|= (1<<i);
+ checkState= TRUE;
+ }
+ }
+ }
+ }
+ }
+ if (xkb->compat!=NULL) {
+ XkbCompatMapPtr compat;
+ compat= xkb->compat;
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ unsigned int newMask;
+ XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask);
+ newMask|= compat->groups[i].real_mods;
+ if (compat->groups[i].mask!=newMask) {
+ compat->groups[i].mask= newMask;
+ if (changes) {
+ changes->compat.changed_groups|= (1<<i);
+ checkState= TRUE;
+ }
+ }
+ }
+ }
+ if (xkb->map && xkb->server) {
+ int highChange = 0, lowChange = -1;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (XkbKeyHasActions(xkb,i)) {
+ register XkbAction *pAct;
+ register int n;
+
+ pAct= XkbKeyActionsPtr(xkb,i);
+ for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) {
+ if ((pAct->type!=XkbSA_NoAction)&&
+ XkbUpdateActionVirtualMods(xkb,pAct,changed)) {
+ if (lowChange<0)
+ lowChange= i;
+ highChange= i;
+ }
+ }
+ }
+ }
+ if (changes && (lowChange>0)) { /* something changed */
+ if (changes->map.changed&XkbKeyActionsMask) {
+ int last;
+ if (changes->map.first_key_act<lowChange)
+ lowChange= changes->map.first_key_act;
+ last= changes->map.first_key_act+changes->map.num_key_acts-1;
+ if (last>highChange)
+ highChange= last;
+ }
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act= lowChange;
+ changes->map.num_key_acts= (highChange-lowChange)+1;
+ }
+ }
+ return checkState;
+}
diff --git a/xorg-server/xkb/ddxList.c b/xorg-server/xkb/ddxList.c
index e212ea3b5..927b885fb 100644
--- a/xorg-server/xkb/ddxList.c
+++ b/xorg-server/xkb/ddxList.c
@@ -1,293 +1,293 @@
-/************************************************************
-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)
- 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)
+ 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 4ccdddaf0..32125015f 100644
--- a/xorg-server/xkb/ddxLoad.c
+++ b/xorg-server/xkb/ddxLoad.c
@@ -1,459 +1,457 @@
-/************************************************************
-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);
- 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);
+ 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 29052bf13..7d0124c25 100644
--- a/xorg-server/xkb/xkb.c
+++ b/xorg-server/xkb/xkb.c
@@ -1,6721 +1,6721 @@
-/************************************************************
-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"
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-#include "extnsionst.h"
-#include "xace.h"
-#include "xkb.h"
-#include "protocol-versions.h"
-
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XKMformat.h>
-
-int XkbEventBase;
-static int XkbErrorBase;
-int XkbReqCode;
-int XkbKeyboardErrorCode;
-CARD32 xkbDebugFlags = 0;
-static CARD32 xkbDebugCtrls = 0;
-
-static RESTYPE RT_XKBCLIENT;
-
-/***====================================================================***/
-
-#define CHK_DEVICE(dev, id, client, access_mode, lf) {\
- int why;\
- int rc = lf(&(dev), id, client, access_mode, &why);\
- if (rc != Success) {\
- client->errorValue = _XkbErrCode2(why, id);\
- return rc;\
- }\
-}
-
-#define CHK_KBD_DEVICE(dev, id, client, mode) \
- CHK_DEVICE(dev, id, client, mode, _XkbLookupKeyboard)
-#define CHK_LED_DEVICE(dev, id, client, mode) \
- CHK_DEVICE(dev, id, client, mode, _XkbLookupLedDevice)
-#define CHK_BELL_DEVICE(dev, id, client, mode) \
- CHK_DEVICE(dev, id, client, mode, _XkbLookupBellDevice)
-#define CHK_ANY_DEVICE(dev, id, client, mode) \
- CHK_DEVICE(dev, id, client, mode, _XkbLookupAnyDevice)
-
-#define CHK_ATOM_ONLY2(a,ev,er) {\
- if (((a)==None)||(!ValidAtom((a)))) {\
- (ev)= (XID)(a);\
- return er;\
- }\
-}
-#define CHK_ATOM_ONLY(a) \
- CHK_ATOM_ONLY2(a,client->errorValue,BadAtom)
-
-#define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\
- if (((a)!=None)&&(!ValidAtom((a)))) {\
- (ev)= (XID)(a);\
- (er)= BadAtom;\
- return ret;\
- }\
-}
-#define CHK_ATOM_OR_NONE2(a,ev,er) {\
- if (((a)!=None)&&(!ValidAtom((a)))) {\
- (ev)= (XID)(a);\
- return er;\
- }\
-}
-#define CHK_ATOM_OR_NONE(a) \
- CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom)
-
-#define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\
- if ((mask)&(~(legal))) { \
- (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
- (er)= BadValue;\
- return ret;\
- }\
-}
-#define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\
- if ((mask)&(~(legal))) { \
- (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
- return er;\
- }\
-}
-#define CHK_MASK_LEGAL(err,mask,legal) \
- CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue)
-
-#define CHK_MASK_MATCH(err,affect,value) {\
- if ((value)&(~(affect))) { \
- client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\
- return BadMatch;\
- }\
-}
-#define CHK_MASK_OVERLAP(err,m1,m2) {\
- if ((m1)&(m2)) { \
- client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\
- return BadMatch;\
- }\
-}
-#define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\
- if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\
- (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\
- return er;\
- }\
- else if ( (first)<(x)->min_key_code ) {\
- (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\
- return er;\
- }\
-}
-#define CHK_KEY_RANGE(err,first,num,x) \
- CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue)
-
-#define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\
- if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\
- (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\
- return er;\
- }\
- else if ( (first)<(r)->minKeyCode ) {\
- (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\
- return er;\
- }\
-}
-#define CHK_REQ_KEY_RANGE(err,first,num,r) \
- CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue)
-
-/***====================================================================***/
-
-int
-ProcXkbUseExtension(ClientPtr client)
-{
- REQUEST(xkbUseExtensionReq);
- xkbUseExtensionReply rep;
- register int n;
- int supported;
-
- REQUEST_SIZE_MATCH(xkbUseExtensionReq);
- if (stuff->wantedMajor != SERVER_XKB_MAJOR_VERSION) {
- /* pre-release version 0.65 is compatible with 1.00 */
- supported= ((SERVER_XKB_MAJOR_VERSION==1)&&
- (stuff->wantedMajor==0)&&(stuff->wantedMinor==65));
- }
- else supported = 1;
-
- if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) {
- client->xkbClientFlags= _XkbClientInitialized;
- client->vMajor= stuff->wantedMajor;
- client->vMinor= stuff->wantedMinor;
- }
- else if (xkbDebugFlags&0x1) {
- ErrorF("[xkb] Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n",
- client->index,
- (long)client->clientAsMask,
- stuff->wantedMajor,stuff->wantedMinor,
- SERVER_XKB_MAJOR_VERSION,SERVER_XKB_MINOR_VERSION);
- }
- memset(&rep, 0, sizeof(xkbUseExtensionReply));
- rep.type = X_Reply;
- rep.supported = supported;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.serverMajor = SERVER_XKB_MAJOR_VERSION;
- rep.serverMinor = SERVER_XKB_MINOR_VERSION;
- if ( client->swapped ) {
- swaps(&rep.sequenceNumber, n);
- swaps(&rep.serverMajor, n);
- swaps(&rep.serverMinor, n);
- }
- WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep);
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-int
-ProcXkbSelectEvents(ClientPtr client)
-{
- unsigned legal;
- DeviceIntPtr dev;
- XkbInterestPtr masks;
- REQUEST(xkbSelectEventsReq);
-
- REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixUseAccess);
-
- if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) {
- client->mapNotifyMask&= ~stuff->affectMap;
- client->mapNotifyMask|= (stuff->affectMap&stuff->map);
- }
- if ((stuff->affectWhich&(~XkbMapNotifyMask))==0)
- return client->noClientException;
-
- masks = XkbFindClientResource((DevicePtr)dev,client);
- if (!masks){
- XID id = FakeClientID(client->index);
- AddResource(id,RT_XKBCLIENT,dev);
- masks= XkbAddClientResource((DevicePtr)dev,client,id);
- }
- if (masks) {
- union {
- CARD8 *c8;
- CARD16 *c16;
- CARD32 *c32;
- } from,to;
- register unsigned bit,ndx,maskLeft,dataLeft,size;
-
- from.c8= (CARD8 *)&stuff[1];
- dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq);
- maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask));
- for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) {
- if ((bit&maskLeft)==0)
- continue;
- maskLeft&= ~bit;
- switch (ndx) {
- case XkbNewKeyboardNotify:
- to.c16= &client->newKeyboardNotifyMask;
- legal= XkbAllNewKeyboardEventsMask;
- size= 2;
- break;
- case XkbStateNotify:
- to.c16= &masks->stateNotifyMask;
- legal= XkbAllStateEventsMask;
- size= 2;
- break;
- case XkbControlsNotify:
- to.c32= &masks->ctrlsNotifyMask;
- legal= XkbAllControlEventsMask;
- size= 4;
- break;
- case XkbIndicatorStateNotify:
- to.c32= &masks->iStateNotifyMask;
- legal= XkbAllIndicatorEventsMask;
- size= 4;
- break;
- case XkbIndicatorMapNotify:
- to.c32= &masks->iMapNotifyMask;
- legal= XkbAllIndicatorEventsMask;
- size= 4;
- break;
- case XkbNamesNotify:
- to.c16= &masks->namesNotifyMask;
- legal= XkbAllNameEventsMask;
- size= 2;
- break;
- case XkbCompatMapNotify:
- to.c8= &masks->compatNotifyMask;
- legal= XkbAllCompatMapEventsMask;
- size= 1;
- break;
- case XkbBellNotify:
- to.c8= &masks->bellNotifyMask;
- legal= XkbAllBellEventsMask;
- size= 1;
- break;
- case XkbActionMessage:
- to.c8= &masks->actionMessageMask;
- legal= XkbAllActionMessagesMask;
- size= 1;
- break;
- case XkbAccessXNotify:
- to.c16= &masks->accessXNotifyMask;
- legal= XkbAllAccessXEventsMask;
- size= 2;
- break;
- case XkbExtensionDeviceNotify:
- to.c16= &masks->extDevNotifyMask;
- legal= XkbAllExtensionDeviceEventsMask;
- size= 2;
- break;
- default:
- client->errorValue = _XkbErrCode2(33,bit);
- return BadValue;
- }
-
- if (stuff->clear&bit) {
- if (size==2) to.c16[0]= 0;
- else if (size==4) to.c32[0]= 0;
- else to.c8[0]= 0;
- }
- else if (stuff->selectAll&bit) {
- if (size==2) to.c16[0]= ~0;
- else if (size==4) to.c32[0]= ~0;
- else to.c8[0]= ~0;
- }
- else {
- if (dataLeft<(size*2))
- return BadLength;
- if (size==2) {
- CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]);
- CHK_MASK_LEGAL(ndx,from.c16[0],legal);
- to.c16[0]&= ~from.c16[0];
- to.c16[0]|= (from.c16[0]&from.c16[1]);
- }
- else if (size==4) {
- CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]);
- CHK_MASK_LEGAL(ndx,from.c32[0],legal);
- to.c32[0]&= ~from.c32[0];
- to.c32[0]|= (from.c32[0]&from.c32[1]);
- }
- else {
- CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]);
- CHK_MASK_LEGAL(ndx,from.c8[0],legal);
- to.c8[0]&= ~from.c8[0];
- to.c8[0]|= (from.c8[0]&from.c8[1]);
- size= 2;
- }
- from.c8+= (size*2);
- dataLeft-= (size*2);
- }
- }
- if (dataLeft>2) {
- ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",dataLeft);
- return BadLength;
- }
- return client->noClientException;
- }
- return BadAlloc;
-}
-
-/***====================================================================***/
-/**
- * Ring a bell on the given device for the given client.
- */
-static int
-_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin,
- int bellClass, int bellID, int pitch, int duration,
- int percent, int forceSound, int eventOnly, Atom name)
-{
- int base;
- pointer ctrl;
- int oldPitch, oldDuration;
- int newPercent;
-
- if (bellClass == KbdFeedbackClass) {
- KbdFeedbackPtr k;
- if (bellID==XkbDfltXIId)
- k= dev->kbdfeed;
- else {
- for (k=dev->kbdfeed; k; k=k->next) {
- if (k->ctrl.id == bellID)
- break;
- }
- }
- if (!k) {
- client->errorValue = _XkbErrCode2(0x5,bellID);
- return BadValue;
- }
- base = k->ctrl.bell;
- ctrl = (pointer) &(k->ctrl);
- oldPitch= k->ctrl.bell_pitch;
- oldDuration= k->ctrl.bell_duration;
- if (pitch!=0) {
- if (pitch==-1)
- k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch;
- else k->ctrl.bell_pitch= pitch;
- }
- if (duration!=0) {
- if (duration==-1)
- k->ctrl.bell_duration= defaultKeyboardControl.bell_duration;
- else k->ctrl.bell_duration= duration;
- }
- }
- else if (bellClass == BellFeedbackClass) {
- BellFeedbackPtr b;
- if (bellID==XkbDfltXIId)
- b= dev->bell;
- else {
- for (b=dev->bell; b; b=b->next) {
- if (b->ctrl.id == bellID)
- break;
- }
- }
- if (!b) {
- client->errorValue = _XkbErrCode2(0x6,bellID);
- return BadValue;
- }
- base = b->ctrl.percent;
- ctrl = (pointer) &(b->ctrl);
- oldPitch= b->ctrl.pitch;
- oldDuration= b->ctrl.duration;
- if (pitch!=0) {
- if (pitch==-1)
- b->ctrl.pitch= defaultKeyboardControl.bell_pitch;
- else b->ctrl.pitch= pitch;
- }
- if (duration!=0) {
- if (duration==-1)
- b->ctrl.duration= defaultKeyboardControl.bell_duration;
- else b->ctrl.duration= duration;
- }
- }
- else {
- client->errorValue = _XkbErrCode2(0x7, bellClass);
- return BadValue;
- }
-
- newPercent = (base * percent)/100;
- if (percent < 0)
- newPercent = base + newPercent;
- else newPercent = base - newPercent + percent;
-
- XkbHandleBell(forceSound, eventOnly,
- dev, newPercent, ctrl, bellClass,
- name, pWin, client);
- if ((pitch!=0)||(duration!=0)) {
- if (bellClass == KbdFeedbackClass) {
- KbdFeedbackPtr k;
- k= (KbdFeedbackPtr)ctrl;
- if (pitch!=0)
- k->ctrl.bell_pitch= oldPitch;
- if (duration!=0)
- k->ctrl.bell_duration= oldDuration;
- }
- else {
- BellFeedbackPtr b;
- b= (BellFeedbackPtr)ctrl;
- if (pitch!=0)
- b->ctrl.pitch= oldPitch;
- if (duration!=0)
- b->ctrl.duration= oldDuration;
- }
- }
-
- return Success;
-}
-
-int
-ProcXkbBell(ClientPtr client)
-{
- REQUEST(xkbBellReq);
- DeviceIntPtr dev;
- WindowPtr pWin;
- int rc;
-
- REQUEST_SIZE_MATCH(xkbBellReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess);
- CHK_ATOM_OR_NONE(stuff->name);
-
- /* device-independent checks request for sane values */
- if ((stuff->forceSound)&&(stuff->eventOnly)) {
- client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly);
- return BadMatch;
- }
- if (stuff->percent < -100 || stuff->percent > 100) {
- client->errorValue = _XkbErrCode2(0x2,stuff->percent);
- return BadValue;
- }
- if (stuff->duration<-1) {
- client->errorValue = _XkbErrCode2(0x3,stuff->duration);
- return BadValue;
- }
- if (stuff->pitch<-1) {
- client->errorValue = _XkbErrCode2(0x4,stuff->pitch);
- return BadValue;
- }
-
- if (stuff->bellClass == XkbDfltXIClass) {
- if (dev->kbdfeed!=NULL)
- stuff->bellClass= KbdFeedbackClass;
- else stuff->bellClass= BellFeedbackClass;
- }
-
- if (stuff->window!=None) {
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success) {
- client->errorValue= stuff->window;
- return rc;
- }
- }
- else pWin= NULL;
-
- /* Client wants to ring a bell on the core keyboard?
- Ring the bell on the core keyboard (which does nothing, but if that
- fails the client is screwed anyway), and then on all extension devices.
- Fail if the core keyboard fails but not the extension devices. this
- may cause some keyboards to ding and others to stay silent. Fix
- your client to use explicit keyboards to avoid this.
-
- dev is the device the client requested.
- */
- rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID,
- stuff->pitch, stuff->duration, stuff->percent,
- stuff->forceSound, stuff->eventOnly, stuff->name);
-
- if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) ||
- (stuff->deviceSpec == XkbUseCorePtr)))
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
- {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess);
- if (rc == Success)
- _XkbBell(client, other, pWin, stuff->bellClass,
- stuff->bellID, stuff->pitch, stuff->duration,
- stuff->percent, stuff->forceSound,
- stuff->eventOnly, stuff->name);
- }
- }
- rc = Success; /* reset to success, that's what we got for the VCK */
- }
-
- return rc;
-}
-
-/***====================================================================***/
-
-int
-ProcXkbGetState(ClientPtr client)
-{
- REQUEST(xkbGetStateReq);
- DeviceIntPtr dev;
- xkbGetStateReply rep;
- XkbStateRec *xkb;
-
- REQUEST_SIZE_MATCH(xkbGetStateReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
-
- xkb= &dev->key->xkbInfo->state;
- bzero(&rep,sizeof(xkbGetStateReply));
- rep.type= X_Reply;
- rep.sequenceNumber= client->sequence;
- rep.length = 0;
- rep.deviceID = dev->id;
- rep.mods = XkbStateFieldFromRec(xkb) & 0xff;
- rep.baseMods = xkb->base_mods;
- rep.lockedMods = xkb->locked_mods;
- rep.latchedMods = xkb->latched_mods;
- rep.group = xkb->group;
- rep.baseGroup = xkb->base_group;
- rep.latchedGroup = xkb->latched_group;
- rep.lockedGroup = xkb->locked_group;
- rep.compatState = xkb->compat_state;
- rep.ptrBtnState = xkb->ptr_buttons;
- if (client->swapped) {
- register int n;
- swaps(&rep.sequenceNumber,n);
- swaps(&rep.ptrBtnState,n);
- }
- WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep);
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-int
-ProcXkbLatchLockState(ClientPtr client)
-{
- int status;
- DeviceIntPtr dev, tmpd;
- XkbStateRec oldState,*newState;
- CARD16 changed;
- xkbStateNotify sn;
- XkbEventCauseRec cause;
-
- REQUEST(xkbLatchLockStateReq);
- REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
-
- if (!(client->xkbClientFlags & _XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
- CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks);
- CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches);
-
- status = Success;
-
- for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
- if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
- if (!tmpd->key || !tmpd->key->xkbInfo)
- continue;
-
- oldState = tmpd->key->xkbInfo->state;
- newState = &tmpd->key->xkbInfo->state;
- if (stuff->affectModLocks) {
- newState->locked_mods &= ~stuff->affectModLocks;
- newState->locked_mods |= (stuff->affectModLocks & stuff->modLocks);
- }
- if (status == Success && stuff->lockGroup)
- newState->locked_group = stuff->groupLock;
- if (status == Success && stuff->affectModLatches)
- status = XkbLatchModifiers(tmpd, stuff->affectModLatches,
- stuff->modLatches);
- if (status == Success && stuff->latchGroup)
- status = XkbLatchGroup(tmpd, stuff->groupLatch);
-
- if (status != Success)
- return status;
-
- XkbComputeDerivedState(tmpd->key->xkbInfo);
-
- changed = XkbStateChangedFlags(&oldState, newState);
- if (changed) {
- sn.keycode = 0;
- sn.eventType = 0;
- sn.requestMajor = XkbReqCode;
- sn.requestMinor = X_kbLatchLockState;
- sn.changed = changed;
- XkbSendStateNotify(tmpd, &sn);
- changed = XkbIndicatorsToUpdate(tmpd, changed, FALSE);
- if (changed) {
- XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client);
- XkbUpdateIndicators(tmpd, changed, TRUE, NULL, &cause);
- }
- }
- }
- }
-
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-int
-ProcXkbGetControls(ClientPtr client)
-{
- xkbGetControlsReply rep;
- XkbControlsPtr xkb;
- DeviceIntPtr dev;
- register int n;
-
- REQUEST(xkbGetControlsReq);
- REQUEST_SIZE_MATCH(xkbGetControlsReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
-
- xkb = dev->key->xkbInfo->desc->ctrls;
- rep.type = X_Reply;
- rep.length = bytes_to_int32(SIZEOF(xkbGetControlsReply)-
- SIZEOF(xGenericReply));
- rep.sequenceNumber = client->sequence;
- rep.deviceID = ((DeviceIntPtr)dev)->id;
- rep.numGroups = xkb->num_groups;
- rep.groupsWrap = xkb->groups_wrap;
- rep.internalMods = xkb->internal.mask;
- rep.ignoreLockMods = xkb->ignore_lock.mask;
- rep.internalRealMods = xkb->internal.real_mods;
- rep.ignoreLockRealMods = xkb->ignore_lock.real_mods;
- rep.internalVMods = xkb->internal.vmods;
- rep.ignoreLockVMods = xkb->ignore_lock.vmods;
- rep.enabledCtrls = xkb->enabled_ctrls;
- rep.repeatDelay = xkb->repeat_delay;
- rep.repeatInterval = xkb->repeat_interval;
- rep.slowKeysDelay = xkb->slow_keys_delay;
- rep.debounceDelay = xkb->debounce_delay;
- rep.mkDelay = xkb->mk_delay;
- rep.mkInterval = xkb->mk_interval;
- rep.mkTimeToMax = xkb->mk_time_to_max;
- rep.mkMaxSpeed = xkb->mk_max_speed;
- rep.mkCurve = xkb->mk_curve;
- rep.mkDfltBtn = xkb->mk_dflt_btn;
- rep.axTimeout = xkb->ax_timeout;
- rep.axtCtrlsMask = xkb->axt_ctrls_mask;
- rep.axtCtrlsValues = xkb->axt_ctrls_values;
- rep.axtOptsMask = xkb->axt_opts_mask;
- rep.axtOptsValues = xkb->axt_opts_values;
- rep.axOptions = xkb->ax_options;
- memcpy(rep.perKeyRepeat,xkb->per_key_repeat,XkbPerKeyBitArraySize);
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length,n);
- swaps(&rep.internalVMods, n);
- swaps(&rep.ignoreLockVMods, n);
- swapl(&rep.enabledCtrls, n);
- swaps(&rep.repeatDelay, n);
- swaps(&rep.repeatInterval, n);
- swaps(&rep.slowKeysDelay, n);
- swaps(&rep.debounceDelay, n);
- swaps(&rep.mkDelay, n);
- swaps(&rep.mkInterval, n);
- swaps(&rep.mkTimeToMax, n);
- swaps(&rep.mkMaxSpeed, n);
- swaps(&rep.mkCurve, n);
- swaps(&rep.axTimeout, n);
- swapl(&rep.axtCtrlsMask, n);
- swapl(&rep.axtCtrlsValues, n);
- swaps(&rep.axtOptsMask, n);
- swaps(&rep.axtOptsValues, n);
- swaps(&rep.axOptions, n);
- }
- WriteToClient(client, SIZEOF(xkbGetControlsReply), (char *)&rep);
- return(client->noClientException);
-}
-
-int
-ProcXkbSetControls(ClientPtr client)
-{
- DeviceIntPtr dev, tmpd;
- XkbSrvInfoPtr xkbi;
- XkbControlsPtr ctrl;
- XkbControlsRec new,old;
- xkbControlsNotify cn;
- XkbEventCauseRec cause;
- XkbSrvLedInfoPtr sli;
-
- REQUEST(xkbSetControlsReq);
- REQUEST_SIZE_MATCH(xkbSetControlsReq);
-
- if (!(client->xkbClientFlags & _XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
- CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask);
-
- for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
- if (!tmpd->key || !tmpd->key->xkbInfo)
- continue;
- if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
- xkbi = tmpd->key->xkbInfo;
- ctrl = xkbi->desc->ctrls;
- new = *ctrl;
- XkbSetCauseXkbReq(&cause, X_kbSetControls, client);
-
- if (stuff->changeCtrls & XkbInternalModsMask) {
- CHK_MASK_MATCH(0x02, stuff->affectInternalMods,
- stuff->internalMods);
- CHK_MASK_MATCH(0x03, stuff->affectInternalVMods,
- stuff->internalVMods);
-
- new.internal.real_mods &= ~(stuff->affectInternalMods);
- new.internal.real_mods |= (stuff->affectInternalMods &
- stuff->internalMods);
- new.internal.vmods &= ~(stuff->affectInternalVMods);
- new.internal.vmods |= (stuff->affectInternalVMods &
- stuff->internalVMods);
- new.internal.mask = new.internal.real_mods |
- XkbMaskForVMask(xkbi->desc,
- new.internal.vmods);
- }
-
- if (stuff->changeCtrls & XkbIgnoreLockModsMask) {
- CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods,
- stuff->ignoreLockMods);
- CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods,
- stuff->ignoreLockVMods);
-
- new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods);
- new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods &
- stuff->ignoreLockMods);
- new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods);
- new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods &
- stuff->ignoreLockVMods);
- new.ignore_lock.mask = new.ignore_lock.real_mods |
- XkbMaskForVMask(xkbi->desc,
- new.ignore_lock.vmods);
- }
-
- CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls,
- stuff->enabledCtrls);
- if (stuff->affectEnabledCtrls) {
- CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls,
- XkbAllBooleanCtrlsMask);
-
- new.enabled_ctrls &= ~(stuff->affectEnabledCtrls);
- new.enabled_ctrls |= (stuff->affectEnabledCtrls &
- stuff->enabledCtrls);
- }
-
- if (stuff->changeCtrls & XkbRepeatKeysMask) {
- if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) {
- client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay,
- stuff->repeatInterval);
- return BadValue;
- }
-
- new.repeat_delay = stuff->repeatDelay;
- new.repeat_interval = stuff->repeatInterval;
- }
-
- if (stuff->changeCtrls & XkbSlowKeysMask) {
- if (stuff->slowKeysDelay < 1) {
- client->errorValue = _XkbErrCode2(0x09,
- stuff->slowKeysDelay);
- return BadValue;
- }
-
- new.slow_keys_delay = stuff->slowKeysDelay;
- }
-
- if (stuff->changeCtrls & XkbBounceKeysMask) {
- if (stuff->debounceDelay < 1) {
- client->errorValue = _XkbErrCode2(0x0A,
- stuff->debounceDelay);
- return BadValue;
- }
-
- new.debounce_delay = stuff->debounceDelay;
- }
-
- if (stuff->changeCtrls & XkbMouseKeysMask) {
- if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) {
- client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn);
- return BadValue;
- }
-
- new.mk_dflt_btn = stuff->mkDfltBtn;
- }
-
- if (stuff->changeCtrls & XkbMouseKeysAccelMask) {
- if (stuff->mkDelay < 1 || stuff->mkInterval < 1 ||
- stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 ||
- stuff->mkCurve < -1000) {
- client->errorValue = _XkbErrCode2(0x0C,0);
- return BadValue;
- }
-
- new.mk_delay = stuff->mkDelay;
- new.mk_interval = stuff->mkInterval;
- new.mk_time_to_max = stuff->mkTimeToMax;
- new.mk_max_speed = stuff->mkMaxSpeed;
- new.mk_curve = stuff->mkCurve;
- AccessXComputeCurveFactor(xkbi, &new);
- }
-
- if (stuff->changeCtrls & XkbGroupsWrapMask) {
- unsigned act, num;
-
- act = XkbOutOfRangeGroupAction(stuff->groupsWrap);
- switch (act) {
- case XkbRedirectIntoRange:
- num = XkbOutOfRangeGroupNumber(stuff->groupsWrap);
- if (num >= new.num_groups) {
- client->errorValue = _XkbErrCode3(0x0D, new.num_groups,
- num);
- return BadValue;
- }
- case XkbWrapIntoRange:
- case XkbClampIntoRange:
- break;
- default:
- client->errorValue = _XkbErrCode2(0x0E, act);
- return BadValue;
- }
-
- new.groups_wrap= stuff->groupsWrap;
- }
-
- CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask);
- if (stuff->changeCtrls & XkbAccessXKeysMask) {
- new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask;
- }
- else {
- if (stuff->changeCtrls & XkbStickyKeysMask) {
- new.ax_options &= ~(XkbAX_SKOptionsMask);
- new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask);
- }
-
- if (stuff->changeCtrls & XkbAccessXFeedbackMask) {
- new.ax_options &= ~(XkbAX_FBOptionsMask);
- new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask);
- }
- }
-
- if (stuff->changeCtrls & XkbAccessXTimeoutMask) {
- if (stuff->axTimeout < 1) {
- client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout);
- return BadValue;
- }
- CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask,
- stuff->axtCtrlsValues);
- CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask,
- XkbAllBooleanCtrlsMask);
- CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues);
- CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask);
- new.ax_timeout = stuff->axTimeout;
- new.axt_ctrls_mask = stuff->axtCtrlsMask;
- new.axt_ctrls_values = (stuff->axtCtrlsValues &
- stuff->axtCtrlsMask);
- new.axt_opts_mask = stuff->axtOptsMask;
- new.axt_opts_values = (stuff->axtOptsValues &
- stuff->axtOptsMask);
- }
-
- if (stuff->changeCtrls & XkbPerKeyRepeatMask)
- memcpy(new.per_key_repeat, stuff->perKeyRepeat,
- XkbPerKeyBitArraySize);
-
- old= *ctrl;
- *ctrl= new;
- XkbDDXChangeControls(tmpd, &old, ctrl);
-
- if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, FALSE)) {
- cn.keycode = 0;
- cn.eventType = 0;
- cn.requestMajor = XkbReqCode;
- cn.requestMinor = X_kbSetControls;
- XkbSendControlsNotify(tmpd, &cn);
- }
-
- sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0);
- if (sli)
- XkbUpdateIndicators(tmpd, sli->usesControls, TRUE, NULL,
- &cause);
-
- /* If sticky keys were disabled, clear all locks and latches */
- if ((old.enabled_ctrls & XkbStickyKeysMask) &&
- !(ctrl->enabled_ctrls & XkbStickyKeysMask))
- XkbClearAllLatchesAndLocks(tmpd, xkbi, TRUE, &cause);
- }
- }
-
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-static int
-XkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep)
-{
- XkbKeyTypeRec *type;
- unsigned i,len;
-
- len= 0;
- if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)||
- (!xkb)||(!xkb->map)||(!xkb->map->types)) {
- rep->present&= ~XkbKeyTypesMask;
- rep->firstType= rep->nTypes= 0;
- return 0;
- }
- type= &xkb->map->types[rep->firstType];
- for (i=0;i<rep->nTypes;i++,type++){
- len+= SIZEOF(xkbKeyTypeWireDesc);
- if (type->map_count>0) {
- len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc));
- if (type->preserve)
- len+= (type->map_count*SIZEOF(xkbModsWireDesc));
- }
- }
- return len;
-}
-
-static char *
-XkbWriteKeyTypes( XkbDescPtr xkb,
- xkbGetMapReply * rep,
- char * buf,
- ClientPtr client)
-{
- XkbKeyTypePtr type;
- unsigned i;
- xkbKeyTypeWireDesc *wire;
-
- type= &xkb->map->types[rep->firstType];
- for (i=0;i<rep->nTypes;i++,type++) {
- register unsigned n;
- wire= (xkbKeyTypeWireDesc *)buf;
- wire->mask = type->mods.mask;
- wire->realMods = type->mods.real_mods;
- wire->virtualMods = type->mods.vmods;
- wire->numLevels = type->num_levels;
- wire->nMapEntries = type->map_count;
- wire->preserve = (type->preserve!=NULL);
- if (client->swapped) {
- register int n;
- swaps(&wire->virtualMods,n);
- }
-
- buf= (char *)&wire[1];
- if (wire->nMapEntries>0) {
- xkbKTMapEntryWireDesc * wire;
- XkbKTMapEntryPtr entry;
- wire= (xkbKTMapEntryWireDesc *)buf;
- entry= type->map;
- for (n=0;n<type->map_count;n++,wire++,entry++) {
- wire->active= entry->active;
- wire->mask= entry->mods.mask;
- wire->level= entry->level;
- wire->realMods= entry->mods.real_mods;
- wire->virtualMods= entry->mods.vmods;
- if (client->swapped) {
- register int n;
- swaps(&wire->virtualMods,n);
- }
- }
- buf= (char *)wire;
- if (type->preserve!=NULL) {
- xkbModsWireDesc * pwire;
- XkbModsPtr preserve;
- pwire= (xkbModsWireDesc *)buf;
- preserve= type->preserve;
- for (n=0;n<type->map_count;n++,pwire++,preserve++) {
- pwire->mask= preserve->mask;
- pwire->realMods= preserve->real_mods;
- pwire->virtualMods= preserve->vmods;
- if (client->swapped) {
- register int n;
- swaps(&pwire->virtualMods,n);
- }
- }
- buf= (char *)pwire;
- }
- }
- }
- return buf;
-}
-
-static int
-XkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep)
-{
- XkbSymMapPtr symMap;
- unsigned i,len;
- unsigned nSyms,nSymsThisKey;
-
- if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)||
- (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) {
- rep->present&= ~XkbKeySymsMask;
- rep->firstKeySym= rep->nKeySyms= 0;
- rep->totalSyms= 0;
- return 0;
- }
- len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc);
- symMap = &xkb->map->key_sym_map[rep->firstKeySym];
- for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) {
- if (symMap->offset!=0) {
- nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width;
- nSyms+= nSymsThisKey;
- }
- }
- len+= nSyms*4;
- rep->totalSyms= nSyms;
- return len;
-}
-
-static int
-XkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep)
-{
-register unsigned i,nMods,bit;
-
- if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)||
- (!xkb)||(!xkb->server)) {
- rep->present&= ~XkbVirtualModsMask;
- rep->virtualMods= 0;
- return 0;
- }
- for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (rep->virtualMods&bit)
- nMods++;
- }
- return XkbPaddedSize(nMods);
-}
-
-static char *
-XkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
-{
-register KeySym * pSym;
-XkbSymMapPtr symMap;
-xkbSymMapWireDesc * outMap;
-register unsigned i;
-
- symMap = &xkb->map->key_sym_map[rep->firstKeySym];
- for (i=0;i<rep->nKeySyms;i++,symMap++) {
- outMap = (xkbSymMapWireDesc *)buf;
- outMap->ktIndex[0] = symMap->kt_index[0];
- outMap->ktIndex[1] = symMap->kt_index[1];
- outMap->ktIndex[2] = symMap->kt_index[2];
- outMap->ktIndex[3] = symMap->kt_index[3];
- outMap->groupInfo = symMap->group_info;
- outMap->width= symMap->width;
- outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info);
- buf= (char *)&outMap[1];
- if (outMap->nSyms==0)
- continue;
-
- pSym = &xkb->map->syms[symMap->offset];
- memcpy((char *)buf,(char *)pSym,outMap->nSyms*4);
- if (client->swapped) {
- register int n,nSyms= outMap->nSyms;
- swaps(&outMap->nSyms,n);
- while (nSyms-->0) {
- swapl(buf,n);
- buf+= 4;
- }
- }
- else buf+= outMap->nSyms*4;
- }
- return buf;
-}
-
-static int
-XkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep)
-{
- unsigned i,len,nActs;
- register KeyCode firstKey;
-
- if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)||
- (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) {
- rep->present&= ~XkbKeyActionsMask;
- rep->firstKeyAct= rep->nKeyActs= 0;
- rep->totalActs= 0;
- return 0;
- }
- firstKey= rep->firstKeyAct;
- for (nActs=i=0;i<rep->nKeyActs;i++) {
- if (xkb->server->key_acts[i+firstKey]!=0)
- nActs+= XkbKeyNumActions(xkb,i+firstKey);
- }
- len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc));
- rep->totalActs= nActs;
- return len;
-}
-
-static char *
-XkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
- ClientPtr client)
-{
- unsigned i;
- CARD8 * numDesc;
- XkbAnyAction * actDesc;
-
- numDesc = (CARD8 *)buf;
- for (i=0;i<rep->nKeyActs;i++) {
- if (xkb->server->key_acts[i+rep->firstKeyAct]==0)
- numDesc[i] = 0;
- else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
- }
- buf+= XkbPaddedSize(rep->nKeyActs);
-
- actDesc = (XkbAnyAction *)buf;
- for (i=0;i<rep->nKeyActs;i++) {
- if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) {
- unsigned int num;
- num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
- memcpy((char *)actDesc,
- (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)),
- num*SIZEOF(xkbActionWireDesc));
- actDesc+= num;
- }
- }
- buf = (char *)actDesc;
- return buf;
-}
-
-static int
-XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep)
-{
- unsigned i,len,nBhvr;
- XkbBehavior * bhv;
-
- if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)||
- (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) {
- rep->present&= ~XkbKeyBehaviorsMask;
- rep->firstKeyBehavior= rep->nKeyBehaviors= 0;
- rep->totalKeyBehaviors= 0;
- return 0;
- }
- bhv= &xkb->server->behaviors[rep->firstKeyBehavior];
- for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) {
- if (bhv->type!=XkbKB_Default)
- nBhvr++;
- }
- len= nBhvr*SIZEOF(xkbBehaviorWireDesc);
- rep->totalKeyBehaviors= nBhvr;
- return len;
-}
-
-static char *
-XkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
- ClientPtr client)
-{
- unsigned i;
- xkbBehaviorWireDesc *wire;
- XkbBehavior *pBhvr;
-
- wire = (xkbBehaviorWireDesc *)buf;
- pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior];
- for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) {
- if (pBhvr->type!=XkbKB_Default) {
- wire->key= i+rep->firstKeyBehavior;
- wire->type= pBhvr->type;
- wire->data= pBhvr->data;
- wire++;
- }
- }
- buf = (char *)wire;
- return buf;
-}
-
-static int
-XkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep)
-{
- unsigned i,len,nRtrn;
-
- if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)||
- (!xkb)||(!xkb->server)||(!xkb->server->explicit)) {
- rep->present&= ~XkbExplicitComponentsMask;
- rep->firstKeyExplicit= rep->nKeyExplicit= 0;
- rep->totalKeyExplicit= 0;
- return 0;
- }
- for (nRtrn=i=0;i<rep->nKeyExplicit;i++) {
- if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0)
- nRtrn++;
- }
- rep->totalKeyExplicit= nRtrn;
- len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */
- return len;
-}
-
-static char *
-XkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
-{
-unsigned i;
-char * start;
-unsigned char * pExp;
-
- start= buf;
- pExp= &xkb->server->explicit[rep->firstKeyExplicit];
- for (i=0;i<rep->nKeyExplicit;i++,pExp++) {
- if (*pExp!=0) {
- *buf++= i+rep->firstKeyExplicit;
- *buf++= *pExp;
- }
- }
- i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
- return buf+i;
-}
-
-static int
-XkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep)
-{
- unsigned i,len,nRtrn;
-
- if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)||
- (!xkb)||(!xkb->map)||(!xkb->map->modmap)) {
- rep->present&= ~XkbModifierMapMask;
- rep->firstModMapKey= rep->nModMapKeys= 0;
- rep->totalModMapKeys= 0;
- return 0;
- }
- for (nRtrn=i=0;i<rep->nModMapKeys;i++) {
- if (xkb->map->modmap[i+rep->firstModMapKey]!=0)
- nRtrn++;
- }
- rep->totalModMapKeys= nRtrn;
- len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */
- return len;
-}
-
-static char *
-XkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
- ClientPtr client)
-{
-unsigned i;
-char * start;
-unsigned char * pMap;
-
- start= buf;
- pMap= &xkb->map->modmap[rep->firstModMapKey];
- for (i=0;i<rep->nModMapKeys;i++,pMap++) {
- if (*pMap!=0) {
- *buf++= i+rep->firstModMapKey;
- *buf++= *pMap;
- }
- }
- i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
- return buf+i;
-}
-
-static int
-XkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep)
-{
- unsigned i,len,nRtrn;
-
- if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)||
- (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) {
- rep->present&= ~XkbVirtualModMapMask;
- rep->firstVModMapKey= rep->nVModMapKeys= 0;
- rep->totalVModMapKeys= 0;
- return 0;
- }
- for (nRtrn=i=0;i<rep->nVModMapKeys;i++) {
- if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0)
- nRtrn++;
- }
- rep->totalVModMapKeys= nRtrn;
- len= nRtrn*SIZEOF(xkbVModMapWireDesc);
- return len;
-}
-
-static char *
-XkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
- ClientPtr client)
-{
-unsigned i;
-xkbVModMapWireDesc * wire;
-unsigned short * pMap;
-
- wire= (xkbVModMapWireDesc *)buf;
- pMap= &xkb->server->vmodmap[rep->firstVModMapKey];
- for (i=0;i<rep->nVModMapKeys;i++,pMap++) {
- if (*pMap!=0) {
- wire->key= i+rep->firstVModMapKey;
- wire->vmods= *pMap;
- wire++;
- }
- }
- return (char *)wire;
-}
-
-static Status
-XkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep)
-{
-int len;
-
- rep->minKeyCode= xkb->min_key_code;
- rep->maxKeyCode= xkb->max_key_code;
- len= XkbSizeKeyTypes(xkb,rep);
- len+= XkbSizeKeySyms(xkb,rep);
- len+= XkbSizeKeyActions(xkb,rep);
- len+= XkbSizeKeyBehaviors(xkb,rep);
- len+= XkbSizeVirtualMods(xkb,rep);
- len+= XkbSizeExplicit(xkb,rep);
- len+= XkbSizeModifierMap(xkb,rep);
- len+= XkbSizeVirtualModMap(xkb,rep);
- rep->length+= (len/4);
- return Success;
-}
-
-static int
-XkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep)
-{
-unsigned i,len;
-char *desc,*start;
-
- len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply));
- start= desc= xcalloc(1, len);
- if (!start)
- return BadAlloc;
- if ( rep->nTypes>0 )
- desc = XkbWriteKeyTypes(xkb,rep,desc,client);
- if ( rep->nKeySyms>0 )
- desc = XkbWriteKeySyms(xkb,rep,desc,client);
- if ( rep->nKeyActs>0 )
- desc = XkbWriteKeyActions(xkb,rep,desc,client);
- if ( rep->totalKeyBehaviors>0 )
- desc = XkbWriteKeyBehaviors(xkb,rep,desc,client);
- if ( rep->virtualMods ) {
- register int sz,bit;
- for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (rep->virtualMods&bit) {
- desc[sz++]= xkb->server->vmods[i];
- }
- }
- desc+= XkbPaddedSize(sz);
- }
- if ( rep->totalKeyExplicit>0 )
- desc= XkbWriteExplicit(xkb,rep,desc,client);
- if ( rep->totalModMapKeys>0 )
- desc= XkbWriteModifierMap(xkb,rep,desc,client);
- if ( rep->totalVModMapKeys>0 )
- desc= XkbWriteVirtualModMap(xkb,rep,desc,client);
- if ((desc-start)!=(len)) {
- ErrorF("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n",
- len, (unsigned long)(desc-start));
- }
- if (client->swapped) {
- register int n;
- swaps(&rep->sequenceNumber,n);
- swapl(&rep->length,n);
- swaps(&rep->present,n);
- swaps(&rep->totalSyms,n);
- swaps(&rep->totalActs,n);
- }
- WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep);
- WriteToClient(client, len, start);
- xfree((char *)start);
- return client->noClientException;
-}
-
-int
-ProcXkbGetMap(ClientPtr client)
-{
- DeviceIntPtr dev;
- xkbGetMapReply rep;
- XkbDescRec *xkb;
- int n,status;
-
- REQUEST(xkbGetMapReq);
- REQUEST_SIZE_MATCH(xkbGetMapReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
- CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial);
- CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask);
- CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask);
-
- xkb= dev->key->xkbInfo->desc;
- bzero(&rep,sizeof(xkbGetMapReply));
- rep.type= X_Reply;
- rep.sequenceNumber= client->sequence;
- rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2;
- rep.deviceID = dev->id;
- rep.present = stuff->partial|stuff->full;
- rep.minKeyCode = xkb->min_key_code;
- rep.maxKeyCode = xkb->max_key_code;
- if ( stuff->full&XkbKeyTypesMask ) {
- rep.firstType = 0;
- rep.nTypes = xkb->map->num_types;
- }
- else if (stuff->partial&XkbKeyTypesMask) {
- if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) {
- client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types,
- stuff->firstType,stuff->nTypes);
- return BadValue;
- }
- rep.firstType = stuff->firstType;
- rep.nTypes = stuff->nTypes;
- }
- else rep.nTypes = 0;
- rep.totalTypes = xkb->map->num_types;
-
- n= XkbNumKeys(xkb);
- if ( stuff->full&XkbKeySymsMask ) {
- rep.firstKeySym = xkb->min_key_code;
- rep.nKeySyms = n;
- }
- else if (stuff->partial&XkbKeySymsMask) {
- CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb);
- rep.firstKeySym = stuff->firstKeySym;
- rep.nKeySyms = stuff->nKeySyms;
- }
- else rep.nKeySyms = 0;
- rep.totalSyms= 0;
-
- if ( stuff->full&XkbKeyActionsMask ) {
- rep.firstKeyAct= xkb->min_key_code;
- rep.nKeyActs= n;
- }
- else if (stuff->partial&XkbKeyActionsMask) {
- CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb);
- rep.firstKeyAct= stuff->firstKeyAct;
- rep.nKeyActs= stuff->nKeyActs;
- }
- else rep.nKeyActs= 0;
- rep.totalActs= 0;
-
- if ( stuff->full&XkbKeyBehaviorsMask ) {
- rep.firstKeyBehavior = xkb->min_key_code;
- rep.nKeyBehaviors = n;
- }
- else if (stuff->partial&XkbKeyBehaviorsMask) {
- CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb);
- rep.firstKeyBehavior= stuff->firstKeyBehavior;
- rep.nKeyBehaviors= stuff->nKeyBehaviors;
- }
- else rep.nKeyBehaviors = 0;
- rep.totalKeyBehaviors= 0;
-
- if (stuff->full&XkbVirtualModsMask)
- rep.virtualMods= ~0;
- else if (stuff->partial&XkbVirtualModsMask)
- rep.virtualMods= stuff->virtualMods;
-
- if (stuff->full&XkbExplicitComponentsMask) {
- rep.firstKeyExplicit= xkb->min_key_code;
- rep.nKeyExplicit= n;
- }
- else if (stuff->partial&XkbExplicitComponentsMask) {
- CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb);
- rep.firstKeyExplicit= stuff->firstKeyExplicit;
- rep.nKeyExplicit= stuff->nKeyExplicit;
- }
- else rep.nKeyExplicit = 0;
- rep.totalKeyExplicit= 0;
-
- if (stuff->full&XkbModifierMapMask) {
- rep.firstModMapKey= xkb->min_key_code;
- rep.nModMapKeys= n;
- }
- else if (stuff->partial&XkbModifierMapMask) {
- CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb);
- rep.firstModMapKey= stuff->firstModMapKey;
- rep.nModMapKeys= stuff->nModMapKeys;
- }
- else rep.nModMapKeys = 0;
- rep.totalModMapKeys= 0;
-
- if (stuff->full&XkbVirtualModMapMask) {
- rep.firstVModMapKey= xkb->min_key_code;
- rep.nVModMapKeys= n;
- }
- else if (stuff->partial&XkbVirtualModMapMask) {
- CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb);
- rep.firstVModMapKey= stuff->firstVModMapKey;
- rep.nVModMapKeys= stuff->nVModMapKeys;
- }
- else rep.nVModMapKeys = 0;
- rep.totalVModMapKeys= 0;
-
- if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success)
- return status;
- return XkbSendMap(client,xkb,&rep);
-}
-
-/***====================================================================***/
-
-static int
-CheckKeyTypes( ClientPtr client,
- XkbDescPtr xkb,
- xkbSetMapReq * req,
- xkbKeyTypeWireDesc **wireRtrn,
- int * nMapsRtrn,
- CARD8 * mapWidthRtrn)
-{
-unsigned nMaps;
-register unsigned i,n;
-register CARD8 * map;
-register xkbKeyTypeWireDesc *wire = *wireRtrn;
-
- if (req->firstType>((unsigned)xkb->map->num_types)) {
- *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types);
- return 0;
- }
- if (req->flags&XkbSetMapResizeTypes) {
- nMaps = req->firstType+req->nTypes;
- if (nMaps<XkbNumRequiredTypes) { /* canonical types must be there */
- *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4);
- return 0;
- }
- }
- else if (req->present&XkbKeyTypesMask) {
- nMaps = xkb->map->num_types;
- if ((req->firstType+req->nTypes)>nMaps) {
- *nMapsRtrn = req->firstType+req->nTypes;
- return 0;
- }
- }
- else {
- *nMapsRtrn = xkb->map->num_types;
- for (i=0;i<xkb->map->num_types;i++) {
- mapWidthRtrn[i] = xkb->map->types[i].num_levels;
- }
- return 1;
- }
-
- for (i=0;i<req->firstType;i++) {
- mapWidthRtrn[i] = xkb->map->types[i].num_levels;
- }
- for (i=0;i<req->nTypes;i++) {
- unsigned width;
- if (client->swapped) {
- register int s;
- swaps(&wire->virtualMods,s);
- }
- n= i+req->firstType;
- width= wire->numLevels;
- if (width<1) {
- *nMapsRtrn= _XkbErrCode3(0x04,n,width);
- return 0;
- }
- else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */
- *nMapsRtrn= _XkbErrCode3(0x05,n,width);
- return 0;
- }
- else if ((width!=2)&&
- ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)||
- (n==XkbAlphabeticIndex))) {
- /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */
- *nMapsRtrn= _XkbErrCode3(0x05,n,width);
- return 0;
- }
- if (wire->nMapEntries>0) {
- xkbKTSetMapEntryWireDesc * mapWire;
- xkbModsWireDesc * preWire;
- mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1];
- preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
- for (n=0;n<wire->nMapEntries;n++) {
- if (client->swapped) {
- register int s;
- swaps(&mapWire[n].virtualMods,s);
- }
- if (mapWire[n].realMods&(~wire->realMods)) {
- *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods,
- wire->realMods);
- return 0;
- }
- if (mapWire[n].virtualMods&(~wire->virtualMods)) {
- *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods);
- return 0;
- }
- if (mapWire[n].level>=wire->numLevels) {
- *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels,
- mapWire[n].level);
- return 0;
- }
- if (wire->preserve) {
- if (client->swapped) {
- register int s;
- swaps(&preWire[n].virtualMods,s);
- }
- if (preWire[n].realMods&(~mapWire[n].realMods)) {
- *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods,
- mapWire[n].realMods);
- return 0;
- }
- if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) {
- *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods);
- return 0;
- }
- }
- }
- if (wire->preserve)
- map= (CARD8 *)&preWire[wire->nMapEntries];
- else map= (CARD8 *)&mapWire[wire->nMapEntries];
- }
- else map= (CARD8 *)&wire[1];
- mapWidthRtrn[i+req->firstType] = wire->numLevels;
- wire= (xkbKeyTypeWireDesc *)map;
- }
- for (i=req->firstType+req->nTypes;i<nMaps;i++) {
- mapWidthRtrn[i] = xkb->map->types[i].num_levels;
- }
- *nMapsRtrn = nMaps;
- *wireRtrn = wire;
- return 1;
-}
-
-static int
-CheckKeySyms( ClientPtr client,
- XkbDescPtr xkb,
- xkbSetMapReq * req,
- int nTypes,
- CARD8 * mapWidths,
- CARD16 * symsPerKey,
- xkbSymMapWireDesc ** wireRtrn,
- int * errorRtrn)
-{
-register unsigned i;
-XkbSymMapPtr map;
-xkbSymMapWireDesc* wire = *wireRtrn;
-
- if (!(XkbKeySymsMask&req->present))
- return 1;
- CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0);
- map = &xkb->map->key_sym_map[xkb->min_key_code];
- for (i=xkb->min_key_code;i<(unsigned)req->firstKeySym;i++,map++) {
- register int g,ng,w;
- ng= XkbNumGroups(map->group_info);
- for (w=g=0;g<ng;g++) {
- if (map->kt_index[g]>=(unsigned)nTypes) {
- *errorRtrn = _XkbErrCode4(0x13,i,g,map->kt_index[g]);
- return 0;
- }
- if (mapWidths[map->kt_index[g]]>w)
- w= mapWidths[map->kt_index[g]];
- }
- symsPerKey[i] = w*ng;
- }
- for (i=0;i<req->nKeySyms;i++) {
- KeySym *pSyms;
- register unsigned nG;
- if (client->swapped) {
- swaps(&wire->nSyms,nG);
- }
- nG = XkbNumGroups(wire->groupInfo);
- if (nG>XkbNumKbdGroups) {
- *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG);
- return 0;
- }
- if (nG>0) {
- register int g,w;
- for (g=w=0;g<nG;g++) {
- if (wire->ktIndex[g]>=(unsigned)nTypes) {
- *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g,
- wire->ktIndex[g]);
- return 0;
- }
- if (mapWidths[wire->ktIndex[g]]>w)
- w= mapWidths[wire->ktIndex[g]];
- }
- if (wire->width!=w) {
- *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width);
- return 0;
- }
- w*= nG;
- symsPerKey[i+req->firstKeySym] = w;
- if (w!=wire->nSyms) {
- *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w);
- return 0;
- }
- }
- else if (wire->nSyms!=0) {
- *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms);
- return 0;
- }
- pSyms = (KeySym *)&wire[1];
- wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
- }
-
- map = &xkb->map->key_sym_map[i];
- for (;i<=(unsigned)xkb->max_key_code;i++,map++) {
- register int g,nG,w;
- nG= XkbKeyNumGroups(xkb,i);
- for (w=g=0;g<nG;g++) {
- if (map->kt_index[g]>=(unsigned)nTypes) {
- *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]);
- return 0;
- }
- if (mapWidths[map->kt_index[g]]>w)
- w= mapWidths[map->kt_index[g]];
- }
- symsPerKey[i] = w*nG;
- }
- *wireRtrn = wire;
- return 1;
-}
-
-static int
-CheckKeyActions( XkbDescPtr xkb,
- xkbSetMapReq * req,
- int nTypes,
- CARD8 * mapWidths,
- CARD16 * symsPerKey,
- CARD8 ** wireRtrn,
- int * nActsRtrn)
-{
-int nActs;
-CARD8 * wire = *wireRtrn;
-register unsigned i;
-
- if (!(XkbKeyActionsMask&req->present))
- return 1;
- CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0);
- for (nActs=i=0;i<req->nKeyActs;i++) {
- if (wire[0]!=0) {
- if (wire[0]==symsPerKey[i+req->firstKeyAct])
- nActs+= wire[0];
- else {
- *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]);
- return 0;
- }
- }
- wire++;
- }
- if (req->nKeyActs%4)
- wire+= 4-(req->nKeyActs%4);
- *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs);
- *nActsRtrn = nActs;
- return 1;
-}
-
-static int
-CheckKeyBehaviors( XkbDescPtr xkb,
- xkbSetMapReq * req,
- xkbBehaviorWireDesc ** wireRtrn,
- int * errorRtrn)
-{
-register xkbBehaviorWireDesc * wire = *wireRtrn;
-register XkbServerMapPtr server = xkb->server;
-register unsigned i;
-unsigned first,last;
-
- if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) {
- req->present&= ~XkbKeyBehaviorsMask;
- req->nKeyBehaviors= 0;
- return 1;
- }
- first= req->firstKeyBehavior;
- last= req->firstKeyBehavior+req->nKeyBehaviors-1;
- if (first<req->minKeyCode) {
- *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode);
- return 0;
- }
- if (last>req->maxKeyCode) {
- *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode);
- return 0;
- }
-
- for (i=0;i<req->totalKeyBehaviors;i++,wire++) {
- if ((wire->key<first)||(wire->key>last)) {
- *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key);
- return 0;
- }
- if ((wire->type&XkbKB_Permanent)&&
- ((server->behaviors[wire->key].type!=wire->type)||
- (server->behaviors[wire->key].data!=wire->data))) {
- *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type);
- return 0;
- }
- if ((wire->type==XkbKB_RadioGroup)&&
- ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) {
- *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data,
- XkbMaxRadioGroups);
- return 0;
- }
- if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) {
- CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0);
- }
- }
- *wireRtrn = wire;
- return 1;
-}
-
-static int
-CheckVirtualMods( XkbDescRec * xkb,
- xkbSetMapReq * req,
- CARD8 ** wireRtrn,
- int * errorRtrn)
-{
-register CARD8 *wire = *wireRtrn;
-register unsigned i,nMods,bit;
-
- if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
- return 1;
- for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (req->virtualMods&bit)
- nMods++;
- }
- *wireRtrn= (wire+XkbPaddedSize(nMods));
- return 1;
-}
-
-static int
-CheckKeyExplicit( XkbDescPtr xkb,
- xkbSetMapReq * req,
- CARD8 ** wireRtrn,
- int * errorRtrn)
-{
-register CARD8 * wire = *wireRtrn;
-CARD8 * start;
-register unsigned i;
-int first,last;
-
- if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) {
- req->present&= ~XkbExplicitComponentsMask;
- req->nKeyExplicit= 0;
- return 1;
- }
- first= req->firstKeyExplicit;
- last= first+req->nKeyExplicit-1;
- if (first<req->minKeyCode) {
- *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode);
- return 0;
- }
- if (last>req->maxKeyCode) {
- *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode);
- return 0;
- }
- start= wire;
- for (i=0;i<req->totalKeyExplicit;i++,wire+=2) {
- if ((wire[0]<first)||(wire[0]>last)) {
- *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]);
- return 0;
- }
- if (wire[1]&(~XkbAllExplicitMask)) {
- *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]);
- return 0;
- }
- }
- wire+= XkbPaddedSize(wire-start)-(wire-start);
- *wireRtrn= wire;
- return 1;
-}
-
-static int
-CheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn)
-{
-register CARD8 * wire = *wireRtrn;
-CARD8 * start;
-register unsigned i;
-int first,last;
-
- if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) {
- req->present&= ~XkbModifierMapMask;
- req->nModMapKeys= 0;
- return 1;
- }
- first= req->firstModMapKey;
- last= first+req->nModMapKeys-1;
- if (first<req->minKeyCode) {
- *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode);
- return 0;
- }
- if (last>req->maxKeyCode) {
- *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode);
- return 0;
- }
- start= wire;
- for (i=0;i<req->totalModMapKeys;i++,wire+=2) {
- if ((wire[0]<first)||(wire[0]>last)) {
- *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]);
- return 0;
- }
- }
- wire+= XkbPaddedSize(wire-start)-(wire-start);
- *wireRtrn= wire;
- return 1;
-}
-
-static int
-CheckVirtualModMap( XkbDescPtr xkb,
- xkbSetMapReq *req,
- xkbVModMapWireDesc **wireRtrn,
- int *errRtrn)
-{
-register xkbVModMapWireDesc * wire = *wireRtrn;
-register unsigned i;
-int first,last;
-
- if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) {
- req->present&= ~XkbVirtualModMapMask;
- req->nVModMapKeys= 0;
- return 1;
- }
- first= req->firstVModMapKey;
- last= first+req->nVModMapKeys-1;
- if (first<req->minKeyCode) {
- *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode);
- return 0;
- }
- if (last>req->maxKeyCode) {
- *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode);
- return 0;
- }
- for (i=0;i<req->totalVModMapKeys;i++,wire++) {
- if ((wire->key<first)||(wire->key>last)) {
- *errRtrn = _XkbErrCode4(0x73,first,last,wire->key);
- return 0;
- }
- }
- *wireRtrn= wire;
- return 1;
-}
-
-static char *
-SetKeyTypes( XkbDescPtr xkb,
- xkbSetMapReq * req,
- xkbKeyTypeWireDesc * wire,
- XkbChangesPtr changes)
-{
-register unsigned i;
-unsigned first,last;
-CARD8 *map;
-
- if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) {
- i= req->firstType+req->nTypes;
- if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) {
- return NULL;
- }
- }
- if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types)
- xkb->map->num_types= req->firstType+req->nTypes;
-
- for (i=0;i<req->nTypes;i++) {
- XkbKeyTypePtr pOld;
- register unsigned n;
-
- if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries,
- wire->preserve,wire->numLevels)!=Success) {
- return NULL;
- }
- pOld = &xkb->map->types[i+req->firstType];
- map = (CARD8 *)&wire[1];
-
- pOld->mods.real_mods = wire->realMods;
- pOld->mods.vmods= wire->virtualMods;
- pOld->num_levels = wire->numLevels;
- pOld->map_count= wire->nMapEntries;
-
- pOld->mods.mask= pOld->mods.real_mods|
- XkbMaskForVMask(xkb,pOld->mods.vmods);
-
- if (wire->nMapEntries) {
- xkbKTSetMapEntryWireDesc *mapWire;
- xkbModsWireDesc *preWire;
- unsigned tmp;
- mapWire= (xkbKTSetMapEntryWireDesc *)map;
- preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
- for (n=0;n<wire->nMapEntries;n++) {
- pOld->map[n].active= 1;
- pOld->map[n].mods.mask= mapWire[n].realMods;
- pOld->map[n].mods.real_mods= mapWire[n].realMods;
- pOld->map[n].mods.vmods= mapWire[n].virtualMods;
- pOld->map[n].level= mapWire[n].level;
- if (mapWire[n].virtualMods!=0) {
- tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods);
- pOld->map[n].active= (tmp!=0);
- pOld->map[n].mods.mask|= tmp;
- }
- if (wire->preserve) {
- pOld->preserve[n].real_mods= preWire[n].realMods;
- pOld->preserve[n].vmods= preWire[n].virtualMods;
- tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods);
- pOld->preserve[n].mask= preWire[n].realMods|tmp;
- }
- }
- if (wire->preserve)
- map= (CARD8 *)&preWire[wire->nMapEntries];
- else map= (CARD8 *)&mapWire[wire->nMapEntries];
- }
- else map= (CARD8 *)&wire[1];
- wire = (xkbKeyTypeWireDesc *)map;
- }
- first= req->firstType;
- last= first+req->nTypes-1; /* last changed type */
- if (changes->map.changed&XkbKeyTypesMask) {
- int oldLast;
- oldLast= changes->map.first_type+changes->map.num_types-1;
- if (changes->map.first_type<first)
- first= changes->map.first_type;
- if (oldLast>last)
- last= oldLast;
- }
- changes->map.changed|= XkbKeyTypesMask;
- changes->map.first_type = first;
- changes->map.num_types = (last-first)+1;
- return (char *)wire;
-}
-
-static char *
-SetKeySyms( ClientPtr client,
- XkbDescPtr xkb,
- xkbSetMapReq * req,
- xkbSymMapWireDesc * wire,
- XkbChangesPtr changes,
- DeviceIntPtr dev)
-{
-register unsigned i,s;
-XkbSymMapPtr oldMap;
-KeySym * newSyms;
-KeySym * pSyms;
-unsigned first,last;
-
- oldMap = &xkb->map->key_sym_map[req->firstKeySym];
- for (i=0;i<req->nKeySyms;i++,oldMap++) {
- pSyms = (KeySym *)&wire[1];
- if (wire->nSyms>0) {
- newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms);
- for (s=0;s<wire->nSyms;s++) {
- newSyms[s]= pSyms[s];
- }
- if (client->swapped) {
- int n;
- for (s=0;s<wire->nSyms;s++) {
- swapl(&newSyms[s],n);
- }
- }
- }
- oldMap->kt_index[0] = wire->ktIndex[0];
- oldMap->kt_index[1] = wire->ktIndex[1];
- oldMap->kt_index[2] = wire->ktIndex[2];
- oldMap->kt_index[3] = wire->ktIndex[3];
- oldMap->group_info = wire->groupInfo;
- oldMap->width = wire->width;
- wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
- }
- first= req->firstKeySym;
- last= first+req->nKeySyms-1;
- if (changes->map.changed&XkbKeySymsMask) {
- int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1);
- if (changes->map.first_key_sym<first)
- first= changes->map.first_key_sym;
- if (oldLast>last)
- last= oldLast;
- }
- changes->map.changed|= XkbKeySymsMask;
- changes->map.first_key_sym = first;
- changes->map.num_key_syms = (last-first+1);
-
- s= 0;
- for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- if (XkbKeyNumGroups(xkb,i)>s)
- s= XkbKeyNumGroups(xkb,i);
- }
- if (s!=xkb->ctrls->num_groups) {
- xkbControlsNotify cn;
- XkbControlsRec old;
- cn.keycode= 0;
- cn.eventType= 0;
- cn.requestMajor= XkbReqCode;
- cn.requestMinor= X_kbSetMap;
- old= *xkb->ctrls;
- xkb->ctrls->num_groups= s;
- if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,FALSE))
- XkbSendControlsNotify(dev,&cn);
- }
- return (char *)wire;
-}
-
-static char *
-SetKeyActions( XkbDescPtr xkb,
- xkbSetMapReq * req,
- CARD8 * wire,
- XkbChangesPtr changes)
-{
-register unsigned i,first,last;
-CARD8 * nActs = wire;
-XkbAction * newActs;
-
- wire+= XkbPaddedSize(req->nKeyActs);
- for (i=0;i<req->nKeyActs;i++) {
- if (nActs[i]==0)
- xkb->server->key_acts[i+req->firstKeyAct]= 0;
- else {
- newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]);
- memcpy((char *)newActs,(char *)wire,
- nActs[i]*SIZEOF(xkbActionWireDesc));
- wire+= nActs[i]*SIZEOF(xkbActionWireDesc);
- }
- }
- first= req->firstKeyAct;
- last= (first+req->nKeyActs-1);
- if (changes->map.changed&XkbKeyActionsMask) {
- int oldLast;
- oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
- if (changes->map.first_key_act<first)
- first= changes->map.first_key_act;
- if (oldLast>last)
- last= oldLast;
- }
- changes->map.changed|= XkbKeyActionsMask;
- changes->map.first_key_act= first;
- changes->map.num_key_acts= (last-first+1);
- return (char *)wire;
-}
-
-static char *
-SetKeyBehaviors( XkbSrvInfoPtr xkbi,
- xkbSetMapReq *req,
- xkbBehaviorWireDesc *wire,
- XkbChangesPtr changes)
-{
-register unsigned i;
-int maxRG = -1;
-XkbDescPtr xkb = xkbi->desc;
-XkbServerMapPtr server = xkb->server;
-unsigned first,last;
-
- first= req->firstKeyBehavior;
- last= req->firstKeyBehavior+req->nKeyBehaviors-1;
- bzero(&server->behaviors[first],req->nKeyBehaviors*sizeof(XkbBehavior));
- for (i=0;i<req->totalKeyBehaviors;i++) {
- if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) {
- server->behaviors[wire->key].type= wire->type;
- server->behaviors[wire->key].data= wire->data;
- if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG))
- maxRG= wire->data + 1;
- }
- wire++;
- }
-
- 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);
- if (xkbi->radioGroups) {
- if (xkbi->nRadioGroups)
- bzero(&xkbi->radioGroups[xkbi->nRadioGroups],
- (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec));
- xkbi->nRadioGroups= maxRG;
- }
- else xkbi->nRadioGroups= 0;
- /* should compute members here */
- }
- if (changes->map.changed&XkbKeyBehaviorsMask) {
- unsigned oldLast;
- oldLast= changes->map.first_key_behavior+
- changes->map.num_key_behaviors-1;
- if (changes->map.first_key_behavior<req->firstKeyBehavior)
- first= changes->map.first_key_behavior;
- if (oldLast>last)
- last= oldLast;
- }
- changes->map.changed|= XkbKeyBehaviorsMask;
- changes->map.first_key_behavior = first;
- changes->map.num_key_behaviors = (last-first+1);
- return (char *)wire;
-}
-
-static char *
-SetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
- XkbChangesPtr changes)
-{
-register int i,bit,nMods;
-XkbServerMapPtr srv = xkbi->desc->server;
-
- if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
- return (char *)wire;
- for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (req->virtualMods&bit) {
- if (srv->vmods[i]!=wire[nMods]) {
- changes->map.changed|= XkbVirtualModsMask;
- changes->map.vmods|= bit;
- srv->vmods[i]= wire[nMods];
- }
- nMods++;
- }
- }
- return (char *)(wire+XkbPaddedSize(nMods));
-}
-
-static char *
-SetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
- XkbChangesPtr changes)
-{
-register unsigned i,first,last;
-XkbServerMapPtr xkb = xkbi->desc->server;
-CARD8 * start;
-
- start= wire;
- first= req->firstKeyExplicit;
- last= req->firstKeyExplicit+req->nKeyExplicit-1;
- bzero(&xkb->explicit[first],req->nKeyExplicit);
- for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) {
- xkb->explicit[wire[0]]= wire[1];
- }
- if (first>0) {
- if (changes->map.changed&XkbExplicitComponentsMask) {
- int oldLast;
- oldLast= changes->map.first_key_explicit+
- changes->map.num_key_explicit-1;
- if (changes->map.first_key_explicit<first)
- first= changes->map.first_key_explicit;
- if (oldLast>last)
- last= oldLast;
- }
- changes->map.first_key_explicit= first;
- changes->map.num_key_explicit= (last-first)+1;
- }
- wire+= XkbPaddedSize(wire-start)-(wire-start);
- return (char *)wire;
-}
-
-static char *
-SetModifierMap( XkbSrvInfoPtr xkbi,
- xkbSetMapReq * req,
- CARD8 * wire,
- XkbChangesPtr changes)
-{
-register unsigned i,first,last;
-XkbClientMapPtr xkb = xkbi->desc->map;
-CARD8 * start;
-
- start= wire;
- first= req->firstModMapKey;
- last= req->firstModMapKey+req->nModMapKeys-1;
- bzero(&xkb->modmap[first],req->nModMapKeys);
- for (i=0;i<req->totalModMapKeys;i++,wire+= 2) {
- xkb->modmap[wire[0]]= wire[1];
- }
- if (first>0) {
- if (changes->map.changed&XkbModifierMapMask) {
- int oldLast;
- oldLast= changes->map.first_modmap_key+
- changes->map.num_modmap_keys-1;
- if (changes->map.first_modmap_key<first)
- first= changes->map.first_modmap_key;
- if (oldLast>last)
- last= oldLast;
- }
- changes->map.first_modmap_key= first;
- changes->map.num_modmap_keys= (last-first)+1;
- }
- wire+= XkbPaddedSize(wire-start)-(wire-start);
- return (char *)wire;
-}
-
-static char *
-SetVirtualModMap( XkbSrvInfoPtr xkbi,
- xkbSetMapReq * req,
- xkbVModMapWireDesc * wire,
- XkbChangesPtr changes)
-{
-register unsigned i,first,last;
-XkbServerMapPtr srv = xkbi->desc->server;
-
- first= req->firstVModMapKey;
- last= req->firstVModMapKey+req->nVModMapKeys-1;
- bzero(&srv->vmodmap[first],req->nVModMapKeys*sizeof(unsigned short));
- for (i=0;i<req->totalVModMapKeys;i++,wire++) {
- srv->vmodmap[wire->key]= wire->vmods;
- }
- if (first>0) {
- if (changes->map.changed&XkbVirtualModMapMask) {
- int oldLast;
- oldLast= changes->map.first_vmodmap_key+
- changes->map.num_vmodmap_keys-1;
- if (changes->map.first_vmodmap_key<first)
- first= changes->map.first_vmodmap_key;
- if (oldLast>last)
- last= oldLast;
- }
- changes->map.first_vmodmap_key= first;
- changes->map.num_vmodmap_keys= (last-first)+1;
- }
- return (char *)wire;
-}
-
-/**
- * Check if the given request can be applied to the given device but don't
- * actually do anything..
- */
-static int
-_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char* values)
-{
- XkbSrvInfoPtr xkbi;
- XkbDescPtr xkb;
- int error;
- int nTypes = 0, nActions;
- CARD8 mapWidths[XkbMaxLegalKeyCode + 1];
- CARD16 symsPerKey[XkbMaxLegalKeyCode + 1];
-
- xkbi= dev->key->xkbInfo;
- xkb = xkbi->desc;
-
- if ((xkb->min_key_code != req->minKeyCode)||
- (xkb->max_key_code != req->maxKeyCode)) {
- if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */
- req->minKeyCode= xkb->min_key_code;
- req->maxKeyCode= xkb->max_key_code;
- }
- else {
- if (!XkbIsLegalKeycode(req->minKeyCode)) {
- client->errorValue = _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode);
- return BadValue;
- }
- if (req->minKeyCode > req->maxKeyCode) {
- client->errorValue = _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode);
- return BadMatch;
- }
- }
- }
-
- if ((req->present & XkbKeyTypesMask) &&
- (!CheckKeyTypes(client,xkb,req,(xkbKeyTypeWireDesc **)&values,
- &nTypes,mapWidths))) {
- client->errorValue = nTypes;
- return BadValue;
- }
- if ((req->present & XkbKeySymsMask) &&
- (!CheckKeySyms(client,xkb,req,nTypes,mapWidths,symsPerKey,
- (xkbSymMapWireDesc **)&values,&error))) {
- client->errorValue = error;
- return BadValue;
- }
-
- if ((req->present & XkbKeyActionsMask) &&
- (!CheckKeyActions(xkb,req,nTypes,mapWidths,symsPerKey,
- (CARD8 **)&values,&nActions))) {
- client->errorValue = nActions;
- return BadValue;
- }
-
- if ((req->present & XkbKeyBehaviorsMask) &&
- (!CheckKeyBehaviors(xkb,req,(xkbBehaviorWireDesc**)&values,&error))) {
- client->errorValue = error;
- return BadValue;
- }
-
- if ((req->present & XkbVirtualModsMask) &&
- (!CheckVirtualMods(xkb,req,(CARD8 **)&values,&error))) {
- client->errorValue= error;
- return BadValue;
- }
- if ((req->present&XkbExplicitComponentsMask) &&
- (!CheckKeyExplicit(xkb,req,(CARD8 **)&values,&error))) {
- client->errorValue= error;
- return BadValue;
- }
- if ((req->present&XkbModifierMapMask) &&
- (!CheckModifierMap(xkb,req,(CARD8 **)&values,&error))) {
- client->errorValue= error;
- return BadValue;
- }
- if ((req->present&XkbVirtualModMapMask) &&
- (!CheckVirtualModMap(xkb,req,(xkbVModMapWireDesc **)&values,&error))) {
- client->errorValue= error;
- return BadValue;
- }
-
- if (((values-((char *)req))/4)!= req->length) {
- ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n");
- client->errorValue = values-((char *)&req[1]);
- return BadLength;
- }
-
- return Success;
-}
-
-/**
- * Apply the given request on the given device.
- */
-static int
-_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char *values)
-{
- XkbEventCauseRec cause;
- XkbChangesRec change;
- Bool sentNKN;
- XkbSrvInfoPtr xkbi;
- XkbDescPtr xkb;
-
- xkbi= dev->key->xkbInfo;
- xkb = xkbi->desc;
-
- XkbSetCauseXkbReq(&cause,X_kbSetMap,client);
- bzero(&change, sizeof(change));
- sentNKN = FALSE;
- if ((xkb->min_key_code!=req->minKeyCode)||
- (xkb->max_key_code!=req->maxKeyCode)) {
- Status status;
- xkbNewKeyboardNotify nkn;
- nkn.deviceID = nkn.oldDeviceID = dev->id;
- nkn.oldMinKeyCode = xkb->min_key_code;
- nkn.oldMaxKeyCode = xkb->max_key_code;
- status= XkbChangeKeycodeRange(xkb, req->minKeyCode,
- req->maxKeyCode, &change);
- if (status != Success)
- return status; /* oh-oh. what about the other keyboards? */
- nkn.minKeyCode = xkb->min_key_code;
- nkn.maxKeyCode = xkb->max_key_code;
- nkn.requestMajor = XkbReqCode;
- nkn.requestMinor = X_kbSetMap;
- nkn.changed = XkbNKN_KeycodesMask;
- XkbSendNewKeyboardNotify(dev,&nkn);
- sentNKN = TRUE;
- }
-
- if (req->present&XkbKeyTypesMask) {
- values = SetKeyTypes(xkb,req,(xkbKeyTypeWireDesc *)values,&change);
- if (!values) goto allocFailure;
- }
- if (req->present&XkbKeySymsMask) {
- values = SetKeySyms(client,xkb,req,(xkbSymMapWireDesc *)values,&change,dev);
- if (!values) goto allocFailure;
- }
- if (req->present&XkbKeyActionsMask) {
- values = SetKeyActions(xkb,req,(CARD8 *)values,&change);
- if (!values) goto allocFailure;
- }
- if (req->present&XkbKeyBehaviorsMask) {
- values= SetKeyBehaviors(xkbi,req,(xkbBehaviorWireDesc *)values,&change);
- if (!values) goto allocFailure;
- }
- if (req->present&XkbVirtualModsMask)
- values= SetVirtualMods(xkbi,req,(CARD8 *)values,&change);
- if (req->present&XkbExplicitComponentsMask)
- values= SetKeyExplicit(xkbi,req,(CARD8 *)values,&change);
- if (req->present&XkbModifierMapMask)
- values= SetModifierMap(xkbi,req,(CARD8 *)values,&change);
- if (req->present&XkbVirtualModMapMask)
- values= SetVirtualModMap(xkbi,req,(xkbVModMapWireDesc *)values,&change);
- if (((values-((char *)req))/4)!=req->length) {
- ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n");
- client->errorValue = values-((char *)&req[1]);
- return BadLength;
- }
- if (req->flags&XkbSetMapRecomputeActions) {
- KeyCode first,last,firstMM,lastMM;
- if (change.map.num_key_syms>0) {
- first= change.map.first_key_sym;
- last= first+change.map.num_key_syms-1;
- }
- else first= last= 0;
- if (change.map.num_modmap_keys>0) {
- firstMM= change.map.first_modmap_key;
- lastMM= first+change.map.num_modmap_keys-1;
- }
- else firstMM= lastMM= 0;
- if ((last>0) && (lastMM>0)) {
- if (firstMM<first)
- first= firstMM;
- if (lastMM>last)
- last= lastMM;
- }
- else if (lastMM>0) {
- first= firstMM;
- last= lastMM;
- }
- if (last>0) {
- unsigned check= 0;
- XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause);
- if (check)
- XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
- }
- }
- if (!sentNKN)
- XkbSendNotification(dev,&change,&cause);
-
- return Success;
-allocFailure:
- return BadAlloc;
-}
-
-
-int
-ProcXkbSetMap(ClientPtr client)
-{
- DeviceIntPtr dev;
- char * tmp;
- int rc;
-
- REQUEST(xkbSetMapReq);
- REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
- CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask);
-
- tmp = (char *)&stuff[1];
-
- /* Check if we can to the SetMap on the requested device. If this
- succeeds, do the same thing for all extension devices (if needed).
- If any of them fails, fail. */
- rc = _XkbSetMapChecks(client, dev, stuff, tmp);
-
- if (rc != Success)
- return rc;
-
- if (stuff->deviceSpec == XkbUseCoreKbd)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
- {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
- if (rc == Success)
- {
- rc = _XkbSetMapChecks(client, other, stuff, tmp);
- if (rc != Success)
- return rc;
- }
- }
- }
- }
-
- /* We know now that we will succed with the SetMap. In theory anyway. */
- rc = _XkbSetMap(client, dev, stuff, tmp);
- if (rc != Success)
- return rc;
-
- if (stuff->deviceSpec == XkbUseCoreKbd)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
- {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
- if (rc == Success)
- _XkbSetMap(client, other, stuff, tmp);
- /* ignore rc. if the SetMap failed although the check above
- reported true there isn't much we can do. we still need to
- set all other devices, hoping that at least they stay in
- sync. */
- }
- }
- }
-
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-static Status
-XkbComputeGetCompatMapReplySize( XkbCompatMapPtr compat,
- xkbGetCompatMapReply * rep)
-{
-unsigned size,nGroups;
-
- nGroups= 0;
- if (rep->groups!=0) {
- register int i,bit;
- for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
- if (rep->groups&bit)
- nGroups++;
- }
- }
- size= nGroups*SIZEOF(xkbModsWireDesc);
- size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc));
- rep->length= size/4;
- return Success;
-}
-
-static int
-XkbSendCompatMap( ClientPtr client,
- XkbCompatMapPtr compat,
- xkbGetCompatMapReply * rep)
-{
-char * data;
-int size;
-
- size= rep->length*4;
- if (size>0) {
- data = xalloc(size);
- if (data) {
- register unsigned i,bit;
- xkbModsWireDesc * grp;
- XkbSymInterpretPtr sym= &compat->sym_interpret[rep->firstSI];
- xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
- for (i=0;i<rep->nSI;i++,sym++,wire++) {
- wire->sym= sym->sym;
- wire->mods= sym->mods;
- wire->match= sym->match;
- wire->virtualMod= sym->virtual_mod;
- wire->flags= sym->flags;
- memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc);
- if (client->swapped) {
- register int n;
- swapl(&wire->sym,n);
- }
- }
- if (rep->groups) {
- grp = (xkbModsWireDesc *)wire;
- for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
- if (rep->groups&bit) {
- grp->mask= compat->groups[i].mask;
- grp->realMods= compat->groups[i].real_mods;
- grp->virtualMods= compat->groups[i].vmods;
- if (client->swapped) {
- register int n;
- swaps(&grp->virtualMods,n);
- }
- grp++;
- }
- }
- wire= (xkbSymInterpretWireDesc*)grp;
- }
- }
- else return BadAlloc;
- }
- else data= NULL;
-
- if (client->swapped) {
- register int n;
- swaps(&rep->sequenceNumber,n);
- swapl(&rep->length,n);
- swaps(&rep->firstSI,n);
- swaps(&rep->nSI,n);
- swaps(&rep->nTotalSI,n);
- }
-
- WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep);
- if (data) {
- WriteToClient(client, size, data);
- xfree((char *)data);
- }
- return client->noClientException;
-}
-
-int
-ProcXkbGetCompatMap(ClientPtr client)
-{
- xkbGetCompatMapReply rep;
- DeviceIntPtr dev;
- XkbDescPtr xkb;
- XkbCompatMapPtr compat;
-
- REQUEST(xkbGetCompatMapReq);
- REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
-
- xkb = dev->key->xkbInfo->desc;
- compat= xkb->compat;
-
- rep.type = X_Reply;
- rep.deviceID = dev->id;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.firstSI = stuff->firstSI;
- rep.nSI = stuff->nSI;
- if (stuff->getAllSI) {
- rep.firstSI = 0;
- rep.nSI = compat->num_si;
- }
- else if ((((unsigned)stuff->nSI)>0)&&
- ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) {
- client->errorValue = _XkbErrCode2(0x05,compat->num_si);
- return BadValue;
- }
- rep.nTotalSI = compat->num_si;
- rep.groups= stuff->groups;
- XkbComputeGetCompatMapReplySize(compat,&rep);
- return XkbSendCompatMap(client,compat,&rep);
-}
-
-/**
- * Apply the given request on the given device.
- * If dryRun is TRUE, then value checks are performed, but the device isn't
- * modified.
- */
-static int
-_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
- xkbSetCompatMapReq *req, char* data, BOOL dryRun)
-{
- XkbSrvInfoPtr xkbi;
- XkbDescPtr xkb;
- XkbCompatMapPtr compat;
- int nGroups;
- unsigned i,bit;
-
- xkbi = dev->key->xkbInfo;
- xkb = xkbi->desc;
- compat = xkb->compat;
-
- if ((req->nSI>0)||(req->truncateSI)) {
- xkbSymInterpretWireDesc *wire;
- if (req->firstSI>compat->num_si) {
- client->errorValue = _XkbErrCode2(0x02,compat->num_si);
- return BadValue;
- }
- wire= (xkbSymInterpretWireDesc *)data;
- wire+= req->nSI;
- data = (char *)wire;
- }
-
- nGroups= 0;
- if (req->groups!=0) {
- for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
- if ( req->groups&bit )
- nGroups++;
- }
- }
- data+= nGroups*SIZEOF(xkbModsWireDesc);
- if (((data-((char *)req))/4)!=req->length) {
- return BadLength;
- }
-
- /* Done all the checks we can do */
- if (dryRun)
- return Success;
-
- data = (char *)&req[1];
- if (req->nSI>0) {
- xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
- 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->num_si * sizeof(XkbSymInterpretRec));
- if (!compat->sym_interpret) {
- compat->num_si= 0;
- return BadAlloc;
- }
- }
- else if (req->truncateSI) {
- compat->num_si = req->firstSI+req->nSI;
- }
- sym = &compat->sym_interpret[req->firstSI];
- for (i=0;i<req->nSI;i++,wire++,sym++) {
- if (client->swapped) {
- int n;
- swapl(&wire->sym,n);
- }
- sym->sym= wire->sym;
- sym->mods= wire->mods;
- sym->match= wire->match;
- sym->flags= wire->flags;
- sym->virtual_mod= wire->virtualMod;
- memcpy((char *)&sym->act,(char *)&wire->act,
- SIZEOF(xkbActionWireDesc));
- }
- data = (char *)wire;
- }
- else if (req->truncateSI) {
- compat->num_si = req->firstSI;
- }
-
- if (req->groups!=0) {
- unsigned i, bit;
- xkbModsWireDesc *wire = (xkbModsWireDesc *)data;
- for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
- if (req->groups & bit) {
- if (client->swapped) {
- int n;
- swaps(&wire->virtualMods,n);
- }
- compat->groups[i].mask= wire->realMods;
- compat->groups[i].real_mods= wire->realMods;
- compat->groups[i].vmods= wire->virtualMods;
- if (wire->virtualMods!=0) {
- unsigned tmp;
- tmp= XkbMaskForVMask(xkb,wire->virtualMods);
- compat->groups[i].mask|= tmp;
- }
- data+= SIZEOF(xkbModsWireDesc);
- wire= (xkbModsWireDesc *)data;
- }
- }
- }
- i= XkbPaddedSize((data-((char *)req)));
- if ((i/4)!=req->length) {
- ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n");
- return BadLength;
- }
-
- if (dev->xkb_interest) {
- xkbCompatMapNotify ev;
- ev.deviceID = dev->id;
- ev.changedGroups = req->groups;
- ev.firstSI = req->firstSI;
- ev.nSI = req->nSI;
- ev.nTotalSI = compat->num_si;
- XkbSendCompatMapNotify(dev,&ev);
- }
-
- if (req->recomputeActions) {
- XkbChangesRec change;
- unsigned check;
- XkbEventCauseRec cause;
-
- XkbSetCauseXkbReq(&cause,X_kbSetCompatMap,client);
- bzero(&change,sizeof(XkbChangesRec));
- XkbUpdateActions(dev,xkb->min_key_code,XkbNumKeys(xkb),&change,&check,
- &cause);
- if (check)
- XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
- XkbSendNotification(dev,&change,&cause);
- }
- return Success;
-}
-
-int
-ProcXkbSetCompatMap(ClientPtr client)
-{
- DeviceIntPtr dev;
- char *data;
- int rc;
-
- REQUEST(xkbSetCompatMapReq);
- REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
-
- data = (char *)&stuff[1];
-
- /* check first using a dry-run */
- rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE);
- if (rc != Success)
- return rc;
- if (stuff->deviceSpec == XkbUseCoreKbd)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
- {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
- if (rc == Success)
- {
- /* dry-run */
- rc = _XkbSetCompatMap(client, other, stuff, data, TRUE);
- if (rc != Success)
- return rc;
- }
- }
- }
- }
-
- /* Yay, the dry-runs succeed. Let's apply */
- rc = _XkbSetCompatMap(client, dev, stuff, data, FALSE);
- if (rc != Success)
- return rc;
- if (stuff->deviceSpec == XkbUseCoreKbd)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
- {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
- if (rc == Success)
- {
- rc = _XkbSetCompatMap(client, other, stuff, data, FALSE);
- if (rc != Success)
- return rc;
- }
- }
- }
- }
-
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-int
-ProcXkbGetIndicatorState(ClientPtr client)
-{
- xkbGetIndicatorStateReply rep;
- XkbSrvLedInfoPtr sli;
- DeviceIntPtr dev;
- register int i;
-
- REQUEST(xkbGetIndicatorStateReq);
- REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess);
-
- sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
- XkbXI_IndicatorStateMask);
- if (!sli)
- return BadAlloc;
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.deviceID = dev->id;
- rep.state = sli->effectiveState;
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber,i);
- swapl(&rep.state,i);
- }
- WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), (char *)&rep);
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-static Status
-XkbComputeGetIndicatorMapReplySize(
- XkbIndicatorPtr indicators,
- xkbGetIndicatorMapReply *rep)
-{
-register int i,bit;
-int nIndicators;
-
- rep->realIndicators = indicators->phys_indicators;
- for (i=nIndicators=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
- if (rep->which&bit)
- nIndicators++;
- }
- rep->length = (nIndicators*SIZEOF(xkbIndicatorMapWireDesc))/4;
- return Success;
-}
-
-static int
-XkbSendIndicatorMap( ClientPtr client,
- XkbIndicatorPtr indicators,
- xkbGetIndicatorMapReply * rep)
-{
-int length;
-CARD8 * map;
-register int i;
-register unsigned bit;
-
- length = rep->length*4;
- if (length>0) {
- CARD8 *to;
- to= map= xalloc(length);
- if (map) {
- xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to;
- for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
- if (rep->which&bit) {
- wire->flags= indicators->maps[i].flags;
- wire->whichGroups= indicators->maps[i].which_groups;
- wire->groups= indicators->maps[i].groups;
- wire->whichMods= indicators->maps[i].which_mods;
- wire->mods= indicators->maps[i].mods.mask;
- wire->realMods= indicators->maps[i].mods.real_mods;
- wire->virtualMods= indicators->maps[i].mods.vmods;
- wire->ctrls= indicators->maps[i].ctrls;
- if (client->swapped) {
- register int n;
- swaps(&wire->virtualMods,n);
- swapl(&wire->ctrls,n);
- }
- wire++;
- }
- }
- to = (CARD8 *)wire;
- if ((to-map)!=length) {
- client->errorValue = _XkbErrCode2(0xff,length);
- return BadLength;
- }
- }
- else return BadAlloc;
- }
- else map = NULL;
- if (client->swapped) {
- swaps(&rep->sequenceNumber,i);
- swapl(&rep->length,i);
- swapl(&rep->which,i);
- swapl(&rep->realIndicators,i);
- }
- WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), (char *)rep);
- if (map) {
- WriteToClient(client, length, (char *)map);
- xfree((char *)map);
- }
- return client->noClientException;
-}
-
-int
-ProcXkbGetIndicatorMap(ClientPtr client)
-{
-xkbGetIndicatorMapReply rep;
-DeviceIntPtr dev;
-XkbDescPtr xkb;
-XkbIndicatorPtr leds;
-
- REQUEST(xkbGetIndicatorMapReq);
- REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
-
- xkb= dev->key->xkbInfo->desc;
- leds= xkb->indicators;
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.deviceID = dev->id;
- rep.which = stuff->which;
- XkbComputeGetIndicatorMapReplySize(leds,&rep);
- return XkbSendIndicatorMap(client,leds,&rep);
-}
-
-/**
- * Apply the given map to the given device. Which specifies which components
- * to apply.
- */
-static int
-_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev,
- int which, xkbIndicatorMapWireDesc *desc)
-{
- XkbSrvInfoPtr xkbi;
- XkbSrvLedInfoPtr sli;
- XkbEventCauseRec cause;
- int i, bit;
-
- xkbi = dev->key->xkbInfo;
-
- sli= XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId,
- XkbXI_IndicatorMapsMask);
- if (!sli)
- return BadAlloc;
-
- for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
- if (which & bit) {
- sli->maps[i].flags = desc->flags;
- sli->maps[i].which_groups = desc->whichGroups;
- sli->maps[i].groups = desc->groups;
- sli->maps[i].which_mods = desc->whichMods;
- sli->maps[i].mods.mask = desc->mods;
- sli->maps[i].mods.real_mods = desc->mods;
- sli->maps[i].mods.vmods= desc->virtualMods;
- sli->maps[i].ctrls = desc->ctrls;
- if (desc->virtualMods!=0) {
- unsigned tmp;
- tmp= XkbMaskForVMask(xkbi->desc,desc->virtualMods);
- sli->maps[i].mods.mask= desc->mods|tmp;
- }
- desc++;
- }
- }
-
- XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client);
- XkbApplyLedMapChanges(dev,sli,which,NULL,NULL,&cause);
-
- return Success;
-}
-
-int
-ProcXkbSetIndicatorMap(ClientPtr client)
-{
- int i, bit;
- int nIndicators;
- DeviceIntPtr dev;
- xkbIndicatorMapWireDesc *from;
- int rc;
-
- REQUEST(xkbSetIndicatorMapReq);
- REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
-
- if (stuff->which==0)
- return client->noClientException;
-
- for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
- if (stuff->which&bit)
- nIndicators++;
- }
- if (stuff->length!=((SIZEOF(xkbSetIndicatorMapReq)+
- (nIndicators*SIZEOF(xkbIndicatorMapWireDesc)))/4)) {
- return BadLength;
- }
-
- from = (xkbIndicatorMapWireDesc *)&stuff[1];
- for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
- if (stuff->which&bit) {
- if (client->swapped) {
- int n;
- swaps(&from->virtualMods,n);
- swapl(&from->ctrls,n);
- }
- CHK_MASK_LEGAL(i,from->whichGroups,XkbIM_UseAnyGroup);
- CHK_MASK_LEGAL(i,from->whichMods,XkbIM_UseAnyMods);
- from++;
- }
- }
-
- from = (xkbIndicatorMapWireDesc *)&stuff[1];
- rc = _XkbSetIndicatorMap(client, dev, stuff->which, from);
- if (rc != Success)
- return rc;
-
- if (stuff->deviceSpec == XkbUseCoreKbd)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
- {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess);
- if (rc == Success)
- _XkbSetIndicatorMap(client, other, stuff->which, from);
- }
- }
- }
-
- return Success;
-}
-
-/***====================================================================***/
-
-int
-ProcXkbGetNamedIndicator(ClientPtr client)
-{
- DeviceIntPtr dev;
- xkbGetNamedIndicatorReply rep;
- register int i = 0;
- XkbSrvLedInfoPtr sli;
- XkbIndicatorMapPtr map = NULL;
-
- REQUEST(xkbGetNamedIndicatorReq);
- REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess);
- CHK_ATOM_ONLY(stuff->indicator);
-
- sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0);
- if (!sli)
- return BadAlloc;
-
- i= 0;
- map= NULL;
- if ((sli->names)&&(sli->maps)) {
- for (i=0;i<XkbNumIndicators;i++) {
- if (stuff->indicator==sli->names[i]) {
- map= &sli->maps[i];
- break;
- }
- }
- }
-
- rep.type= X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.deviceID = dev->id;
- rep.indicator= stuff->indicator;
- if (map!=NULL) {
- rep.found= TRUE;
- rep.on= ((sli->effectiveState&(1<<i))!=0);
- rep.realIndicator= ((sli->physIndicators&(1<<i))!=0);
- rep.ndx= i;
- rep.flags= map->flags;
- rep.whichGroups= map->which_groups;
- rep.groups= map->groups;
- rep.whichMods= map->which_mods;
- rep.mods= map->mods.mask;
- rep.realMods= map->mods.real_mods;
- rep.virtualMods= map->mods.vmods;
- rep.ctrls= map->ctrls;
- rep.supported= TRUE;
- }
- else {
- rep.found= FALSE;
- rep.on= FALSE;
- rep.realIndicator= FALSE;
- rep.ndx= XkbNoIndicator;
- rep.flags= 0;
- rep.whichGroups= 0;
- rep.groups= 0;
- rep.whichMods= 0;
- rep.mods= 0;
- rep.realMods= 0;
- rep.virtualMods= 0;
- rep.ctrls= 0;
- rep.supported= TRUE;
- }
- if ( client->swapped ) {
- register int n;
- swapl(&rep.length,n);
- swaps(&rep.sequenceNumber,n);
- swapl(&rep.indicator,n);
- swaps(&rep.virtualMods,n);
- swapl(&rep.ctrls,n);
- }
-
- WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), (char *)&rep);
- return client->noClientException;
-}
-
-
-/**
- * Find the IM on the device.
- * Returns the map, or NULL if the map doesn't exist.
- * If the return value is NULL, led_return is undefined. Otherwise, led_return
- * is set to the led index of the map.
- */
-static XkbIndicatorMapPtr
-_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator,
- int *led_return)
-{
- XkbIndicatorMapPtr map;
-
- /* search for the right indicator */
- map = NULL;
- if (sli->names && sli->maps) {
- int led;
-
- for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) {
- if (sli->names[led] == indicator) {
- map= &sli->maps[led];
- *led_return = led;
- break;
- }
- }
- }
-
- return map;
-}
-
-/**
- * Creates an indicator map on the device. If dryRun is TRUE, it only checks
- * if creation is possible, but doesn't actually create it.
- */
-static int
-_XkbCreateIndicatorMap(DeviceIntPtr dev, Atom indicator,
- int ledClass, int ledID,
- XkbIndicatorMapPtr *map_return, int *led_return,
- Bool dryRun)
-{
- XkbSrvLedInfoPtr sli;
- XkbIndicatorMapPtr map;
- int led;
-
- sli = XkbFindSrvLedInfo(dev, ledClass, ledID, XkbXI_IndicatorsMask);
- if (!sli)
- return BadAlloc;
-
- map = _XkbFindNamedIndicatorMap(sli, indicator, &led);
-
- if (!map)
- {
- /* find first unused indicator maps and assign the name to it */
- for (led = 0, map = NULL; (led < XkbNumIndicators) && (map == NULL); led++) {
- if ((sli->names) && (sli->maps) && (sli->names[led] == None) &&
- (!XkbIM_InUse(&sli->maps[led])))
- {
- map = &sli->maps[led];
- if (!dryRun)
- sli->names[led] = indicator;
- break;
- }
- }
- }
-
- if (!map)
- return BadAlloc;
-
- *led_return = led;
- *map_return = map;
- return Success;
-}
-
-static int
-_XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev,
- xkbSetNamedIndicatorReq *stuff)
-{
- unsigned int extDevReason;
- unsigned int statec, namec, mapc;
- XkbSrvLedInfoPtr sli;
- int led = 0;
- XkbIndicatorMapPtr map;
- DeviceIntPtr kbd;
- XkbEventCauseRec cause;
- xkbExtensionDeviceNotify ed;
- XkbChangesRec changes;
- int rc;
-
- rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass,
- stuff->ledID, &map, &led, FALSE);
- if (rc != Success || !map) /* oh-oh */
- return rc;
-
- sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID,
- XkbXI_IndicatorsMask);
- if (!sli)
- return BadAlloc;
-
- namec = mapc = statec = 0;
- extDevReason = 0;
-
- namec |= (1<<led);
- sli->namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0);
- extDevReason |= XkbXI_IndicatorNamesMask;
-
- if (stuff->setMap) {
- map->flags = stuff->flags;
- map->which_groups = stuff->whichGroups;
- map->groups = stuff->groups;
- map->which_mods = stuff->whichMods;
- map->mods.mask = stuff->realMods;
- map->mods.real_mods = stuff->realMods;
- map->mods.vmods= stuff->virtualMods;
- map->ctrls = stuff->ctrls;
- mapc|= (1<<led);
- }
-
- if ((stuff->setState) && ((map->flags & XkbIM_NoExplicit) == 0))
- {
- if (stuff->on) sli->explicitState |= (1<<led);
- else sli->explicitState &= ~(1<<led);
- statec |= ((sli->effectiveState ^ sli->explicitState) & (1 << led));
- }
-
- bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
- bzero((char *)&changes,sizeof(XkbChangesRec));
- XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client);
- if (namec)
- XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
- if (mapc)
- XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
- if (statec)
- XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
-
- kbd = dev;
- if ((sli->flags&XkbSLI_HasOwnState)==0)
- kbd = inputInfo.keyboard;
- XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause);
-
- return Success;
-}
-
-int
-ProcXkbSetNamedIndicator(ClientPtr client)
-{
- int rc;
- DeviceIntPtr dev;
- int led = 0;
- XkbIndicatorMapPtr map;
-
- REQUEST(xkbSetNamedIndicatorReq);
- REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
- CHK_ATOM_ONLY(stuff->indicator);
- CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup);
- CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods);
-
- /* Dry-run for checks */
- rc = _XkbCreateIndicatorMap(dev, stuff->indicator,
- stuff->ledClass, stuff->ledID,
- &map, &led, TRUE);
- if (rc != Success || !map) /* couldn't be created or didn't exist */
- return rc;
-
- if (stuff->deviceSpec == XkbUseCoreKbd ||
- stuff->deviceSpec == XkbUseCorePtr)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && !IsMaster(other) && (other->u.master == dev) &&
- (other->kbdfeed || other->leds) &&
- (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success))
- {
- rc = _XkbCreateIndicatorMap(other, stuff->indicator,
- stuff->ledClass, stuff->ledID,
- &map, &led, TRUE);
- if (rc != Success || !map)
- return rc;
- }
- }
- }
-
- /* All checks passed, let's do it */
- rc = _XkbSetNamedIndicator(client, dev, stuff);
- if (rc != Success)
- return rc;
-
- if (stuff->deviceSpec == XkbUseCoreKbd ||
- stuff->deviceSpec == XkbUseCorePtr)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && !IsMaster(other) && (other->u.master == dev) &&
- (other->kbdfeed || other->leds) &&
- (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success))
- {
- _XkbSetNamedIndicator(client, other, stuff);
- }
- }
- }
-
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-static CARD32
-_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count)
-{
-register unsigned int i,bit,nAtoms;
-register CARD32 atomsPresent;
-
- for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) {
- if (atoms[i]!=None) {
- atomsPresent|= bit;
- nAtoms++;
- }
- }
- if (count)
- *count= nAtoms;
- return atomsPresent;
-}
-
-static char *
-_XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap)
-{
-register unsigned int i;
-Atom *atm;
-
- atm = (Atom *)wire;
- for (i=0;i<maxAtoms;i++) {
- if (atoms[i]!=None) {
- *atm= atoms[i];
- if (swap) {
- register int n;
- swapl(atm,n);
- }
- atm++;
- }
- }
- return (char *)atm;
-}
-
-static Status
-XkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep)
-{
-register unsigned which,length;
-register int i;
-
- rep->minKeyCode= xkb->min_key_code;
- rep->maxKeyCode= xkb->max_key_code;
- which= rep->which;
- length= 0;
- if (xkb->names!=NULL) {
- if (which&XkbKeycodesNameMask) length++;
- if (which&XkbGeometryNameMask) length++;
- if (which&XkbSymbolsNameMask) length++;
- if (which&XkbPhysSymbolsNameMask) length++;
- if (which&XkbTypesNameMask) length++;
- if (which&XkbCompatNameMask) length++;
- }
- else which&= ~XkbComponentNamesMask;
-
- if (xkb->map!=NULL) {
- if (which&XkbKeyTypeNamesMask)
- length+= xkb->map->num_types;
- rep->nTypes= xkb->map->num_types;
- if (which&XkbKTLevelNamesMask) {
- XkbKeyTypePtr pType = xkb->map->types;
- int nKTLevels = 0;
-
- length+= XkbPaddedSize(xkb->map->num_types)/4;
- for (i=0;i<xkb->map->num_types;i++,pType++) {
- if (pType->level_names!=NULL)
- nKTLevels+= pType->num_levels;
- }
- rep->nKTLevels= nKTLevels;
- length+= nKTLevels;
- }
- }
- else {
- rep->nTypes= 0;
- rep->nKTLevels= 0;
- which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask);
- }
-
- rep->minKeyCode= xkb->min_key_code;
- rep->maxKeyCode= xkb->max_key_code;
- rep->indicators= 0;
- rep->virtualMods= 0;
- rep->groupNames= 0;
- if (xkb->names!=NULL) {
- if (which&XkbIndicatorNamesMask) {
- int nLeds;
- rep->indicators=
- _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds);
- length+= nLeds;
- if (nLeds==0)
- which&= ~XkbIndicatorNamesMask;
- }
-
- if (which&XkbVirtualModNamesMask) {
- int nVMods;
- rep->virtualMods=
- _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods);
- length+= nVMods;
- if (nVMods==0)
- which&= ~XkbVirtualModNamesMask;
- }
-
- if (which&XkbGroupNamesMask) {
- int nGroups;
- rep->groupNames=
- _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups);
- length+= nGroups;
- if (nGroups==0)
- which&= ~XkbGroupNamesMask;
- }
-
- if ((which&XkbKeyNamesMask)&&(xkb->names->keys))
- length+= rep->nKeys;
- else which&= ~XkbKeyNamesMask;
-
- if ((which&XkbKeyAliasesMask)&&
- (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) {
- rep->nKeyAliases= xkb->names->num_key_aliases;
- length+= rep->nKeyAliases*2;
- }
- else {
- which&= ~XkbKeyAliasesMask;
- rep->nKeyAliases= 0;
- }
-
- if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0))
- length+= xkb->names->num_rg;
- else which&= ~XkbRGNamesMask;
- }
- else {
- which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask);
- which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask);
- which&= ~XkbRGNamesMask;
- }
-
- rep->length= length;
- rep->which= which;
- return Success;
-}
-
-static int
-XkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep)
-{
-register unsigned i,length,which;
-char * start;
-char * desc;
-register int n;
-
- length= rep->length*4;
- which= rep->which;
- if (client->swapped) {
- swaps(&rep->sequenceNumber,n);
- swapl(&rep->length,n);
- swapl(&rep->which,n);
- swaps(&rep->virtualMods,n);
- swapl(&rep->indicators,n);
- }
-
- start = desc = xalloc(length);
- if ( !start )
- return BadAlloc;
- if (xkb->names) {
- if (which&XkbKeycodesNameMask) {
- *((CARD32 *)desc)= xkb->names->keycodes;
- if (client->swapped) {
- swapl(desc,n);
- }
- desc+= 4;
- }
- if (which&XkbGeometryNameMask) {
- *((CARD32 *)desc)= xkb->names->geometry;
- if (client->swapped) {
- swapl(desc,n);
- }
- desc+= 4;
- }
- if (which&XkbSymbolsNameMask) {
- *((CARD32 *)desc)= xkb->names->symbols;
- if (client->swapped) {
- swapl(desc,n);
- }
- desc+= 4;
- }
- if (which&XkbPhysSymbolsNameMask) {
- register CARD32 *atm= (CARD32 *)desc;
- atm[0]= (CARD32)xkb->names->phys_symbols;
- if (client->swapped) {
- swapl(&atm[0],n);
- }
- desc+= 4;
- }
- if (which&XkbTypesNameMask) {
- *((CARD32 *)desc)= (CARD32)xkb->names->types;
- if (client->swapped) {
- swapl(desc,n);
- }
- desc+= 4;
- }
- if (which&XkbCompatNameMask) {
- *((CARD32 *)desc)= (CARD32)xkb->names->compat;
- if (client->swapped) {
- swapl(desc,n);
- }
- desc+= 4;
- }
- if (which&XkbKeyTypeNamesMask) {
- register CARD32 *atm= (CARD32 *)desc;
- register XkbKeyTypePtr type= xkb->map->types;
-
- for (i=0;i<xkb->map->num_types;i++,atm++,type++) {
- *atm= (CARD32)type->name;
- if (client->swapped) {
- swapl(atm,n);
- }
- }
- desc= (char *)atm;
- }
- if (which&XkbKTLevelNamesMask && xkb->map) {
- XkbKeyTypePtr type = xkb->map->types;
- register CARD32 *atm;
- for (i=0;i<rep->nTypes;i++,type++) {
- *desc++ = type->num_levels;
- }
- desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes;
-
- atm= (CARD32 *)desc;
- type = xkb->map->types;
- for (i=0;i<xkb->map->num_types;i++,type++) {
- register unsigned l;
- if (type->level_names) {
- for (l=0;l<type->num_levels;l++,atm++) {
- *atm= type->level_names[l];
- if (client->swapped) {
- swapl(atm,n);
- }
- }
- desc+= type->num_levels*4;
- }
- }
- }
- if (which&XkbIndicatorNamesMask) {
- desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators,
- client->swapped);
- }
- if (which&XkbVirtualModNamesMask) {
- desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods,
- client->swapped);
- }
- if (which&XkbGroupNamesMask) {
- desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups,
- client->swapped);
- }
- if (which&XkbKeyNamesMask) {
- for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) {
- *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey];
- }
- }
- if (which&XkbKeyAliasesMask) {
- XkbKeyAliasPtr pAl;
- pAl= xkb->names->key_aliases;
- for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) {
- *((XkbKeyAliasPtr)desc)= *pAl;
- }
- }
- if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) {
- register CARD32 *atm= (CARD32 *)desc;
- for (i=0;i<rep->nRadioGroups;i++,atm++) {
- *atm= (CARD32)xkb->names->radio_groups[i];
- if (client->swapped) {
- swapl(atm,n);
- }
- }
- desc+= rep->nRadioGroups*4;
- }
- }
-
- if ((desc-start)!=(length)) {
- ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n",
- length, (unsigned long)(desc-start));
- }
- WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep);
- WriteToClient(client, length, start);
- xfree((char *)start);
- return client->noClientException;
-}
-
-int
-ProcXkbGetNames(ClientPtr client)
-{
- DeviceIntPtr dev;
- XkbDescPtr xkb;
- xkbGetNamesReply rep;
-
- REQUEST(xkbGetNamesReq);
- REQUEST_SIZE_MATCH(xkbGetNamesReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
- CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
-
- xkb = dev->key->xkbInfo->desc;
- memset(&rep, 0, sizeof(xkbGetNamesReply));
- rep.type= X_Reply;
- rep.sequenceNumber= client->sequence;
- rep.length = 0;
- rep.deviceID = dev->id;
- rep.which = stuff->which;
- rep.nTypes = xkb->map->num_types;
- rep.firstKey = xkb->min_key_code;
- rep.nKeys = XkbNumKeys(xkb);
- if (xkb->names!=NULL) {
- rep.nKeyAliases= xkb->names->num_key_aliases;
- rep.nRadioGroups = xkb->names->num_rg;
- }
- else {
- rep.nKeyAliases= rep.nRadioGroups= 0;
- }
- XkbComputeGetNamesReplySize(xkb,&rep);
- return XkbSendNames(client,xkb,&rep);
-}
-
-/***====================================================================***/
-
-static CARD32 *
-_XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError)
-{
-register int i;
-
- for (i=0;i<nAtoms;i++,wire++) {
- if (swapped) {
- register int n;
- swapl(wire,n);
- }
- if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) {
- *pError= ((Atom)*wire);
- return NULL;
- }
- }
- return wire;
-}
-
-static CARD32 *
-_XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped,
- Atom *pError)
-{
-register unsigned i,bit;
-
- for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
- if ((present&bit)==0)
- continue;
- if (swapped) {
- register int n;
- swapl(wire,n);
- }
- if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) {
- *pError= (Atom)*wire;
- return NULL;
- }
- wire++;
- }
- return wire;
-}
-
-static Atom *
-_XkbCopyMaskedAtoms( Atom *wire,
- Atom *dest,
- int nAtoms,
- CARD32 present)
-{
-register int i,bit;
-
- for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
- if ((present&bit)==0)
- continue;
- dest[i]= *wire++;
- }
- return wire;
-}
-
-static Bool
-_XkbCheckTypeName(Atom name,int typeNdx)
-{
-const char * str;
-
- str= NameForAtom(name);
- if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)||
- (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0))
- return FALSE;
- return TRUE;
-}
-
-/**
- * Check the device-dependent data in the request against the device. Returns
- * Success, or the appropriate error code.
- */
-static int
-_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev,
- xkbSetNamesReq *stuff, CARD32 *data)
-{
- XkbDescRec *xkb;
- XkbNamesRec *names;
- CARD32 *tmp;
- Atom bad;
-
- tmp = data;
- xkb = dev->key->xkbInfo->desc;
- names = xkb->names;
-
-
- if (stuff->which & XkbKeyTypeNamesMask) {
- int i;
- CARD32 *old;
- if ( stuff->nTypes<1 ) {
- client->errorValue = _XkbErrCode2(0x02,stuff->nTypes);
- return BadValue;
- }
- if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) {
- client->errorValue = _XkbErrCode4(0x03,stuff->firstType,
- stuff->nTypes,
- xkb->map->num_types);
- return BadValue;
- }
- if (((unsigned)stuff->firstType)<=XkbLastRequiredType) {
- client->errorValue = _XkbErrCode2(0x04,stuff->firstType);
- return BadAccess;
- }
- old= tmp;
- tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad);
- if (!tmp) {
- client->errorValue= bad;
- return BadAtom;
- }
- for (i=0;i<stuff->nTypes;i++,old++) {
- if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i))
- client->errorValue= _XkbErrCode2(0x05,i);
- }
- }
- if (stuff->which&XkbKTLevelNamesMask) {
- unsigned i;
- XkbKeyTypePtr type;
- CARD8 * width;
- if ( stuff->nKTLevels<1 ) {
- client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels);
- return BadValue;
- }
- if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>=
- xkb->map->num_types) {
- client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel,
- stuff->nKTLevels,xkb->map->num_types);
- return BadValue;
- }
- width = (CARD8 *)tmp;
- tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
- type = &xkb->map->types[stuff->firstKTLevel];
- for (i=0;i<stuff->nKTLevels;i++,type++) {
- if (width[i]==0)
- continue;
- else if (width[i]!=type->num_levels) {
- client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel,
- type->num_levels,width[i]);
- return BadMatch;
- }
- tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad);
- if (!tmp) {
- client->errorValue= bad;
- return BadAtom;
- }
- }
- }
- if (stuff->which&XkbIndicatorNamesMask) {
- if (stuff->indicators==0) {
- client->errorValue= 0x08;
- return BadMatch;
- }
- tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators,
- client->swapped,&bad);
- if (!tmp) {
- client->errorValue= bad;
- return BadAtom;
- }
- }
- if (stuff->which&XkbVirtualModNamesMask) {
- if (stuff->virtualMods==0) {
- client->errorValue= 0x09;
- return BadMatch;
- }
- tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods,
- (CARD32)stuff->virtualMods,
- client->swapped,&bad);
- if (!tmp) {
- client->errorValue = bad;
- return BadAtom;
- }
- }
- if (stuff->which&XkbGroupNamesMask) {
- if (stuff->groupNames==0) {
- client->errorValue= 0x0a;
- return BadMatch;
- }
- tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups,
- (CARD32)stuff->groupNames,
- client->swapped,&bad);
- if (!tmp) {
- client->errorValue = bad;
- return BadAtom;
- }
- }
- if (stuff->which&XkbKeyNamesMask) {
- if (stuff->firstKey<(unsigned)xkb->min_key_code) {
- client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code,
- stuff->firstKey);
- return BadValue;
- }
- if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)||
- (stuff->nKeys<1)) {
- client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code,
- stuff->firstKey,stuff->nKeys);
- return BadValue;
- }
- tmp+= stuff->nKeys;
- }
- if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) {
- tmp+= stuff->nKeyAliases*2;
- }
- if (stuff->which&XkbRGNamesMask) {
- if ( stuff->nRadioGroups<1 ) {
- client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups);
- return BadValue;
- }
- tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad);
- if (!tmp) {
- client->errorValue= bad;
- return BadAtom;
- }
- }
- if ((tmp-((CARD32 *)stuff))!=stuff->length) {
- client->errorValue = stuff->length;
- return BadLength;
- }
-
-
-
- return Success;
-}
-
-static int
-_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff)
-{
- XkbDescRec *xkb;
- XkbNamesRec *names;
- CARD32 *tmp;
- xkbNamesNotify nn;
-
- tmp = (CARD32 *)&stuff[1];
- xkb = dev->key->xkbInfo->desc;
- names = xkb->names;
-
- if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups,
- stuff->nKeyAliases)!=Success) {
- return BadAlloc;
- }
-
- bzero(&nn,sizeof(xkbNamesNotify));
- nn.changed= stuff->which;
- tmp = (CARD32 *)&stuff[1];
- if (stuff->which&XkbKeycodesNameMask)
- names->keycodes= *tmp++;
- if (stuff->which&XkbGeometryNameMask)
- names->geometry= *tmp++;
- if (stuff->which&XkbSymbolsNameMask)
- names->symbols= *tmp++;
- if (stuff->which&XkbPhysSymbolsNameMask)
- names->phys_symbols= *tmp++;
- if (stuff->which&XkbTypesNameMask)
- names->types= *tmp++;
- if (stuff->which&XkbCompatNameMask)
- names->compat= *tmp++;
- if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) {
- register unsigned i;
- register XkbKeyTypePtr type;
-
- type= &xkb->map->types[stuff->firstType];
- for (i=0;i<stuff->nTypes;i++,type++) {
- type->name= *tmp++;
- }
- nn.firstType= stuff->firstType;
- nn.nTypes= stuff->nTypes;
- }
- if (stuff->which&XkbKTLevelNamesMask) {
- register XkbKeyTypePtr type;
- register unsigned i;
- CARD8 *width;
-
- width = (CARD8 *)tmp;
- tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
- type= &xkb->map->types[stuff->firstKTLevel];
- for (i=0;i<stuff->nKTLevels;i++,type++) {
- if (width[i]>0) {
- if (type->level_names) {
- register unsigned n;
- for (n=0;n<width[i];n++) {
- type->level_names[n]= tmp[n];
- }
- }
- tmp+= width[i];
- }
- }
- nn.firstLevelName= 0;
- nn.nLevelNames= stuff->nTypes;
- }
- if (stuff->which&XkbIndicatorNamesMask) {
- tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators,
- stuff->indicators);
- nn.changedIndicators= stuff->indicators;
- }
- if (stuff->which&XkbVirtualModNamesMask) {
- tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods,
- stuff->virtualMods);
- nn.changedVirtualMods= stuff->virtualMods;
- }
- if (stuff->which&XkbGroupNamesMask) {
- tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups,
- stuff->groupNames);
- nn.changedVirtualMods= stuff->groupNames;
- }
- if (stuff->which&XkbKeyNamesMask) {
- memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp,
- stuff->nKeys*XkbKeyNameLength);
- tmp+= stuff->nKeys;
- nn.firstKey= stuff->firstKey;
- nn.nKeys= stuff->nKeys;
- }
- if (stuff->which&XkbKeyAliasesMask) {
- if (stuff->nKeyAliases>0) {
- register int na= stuff->nKeyAliases;
- if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success)
- return BadAlloc;
- memcpy((char *)names->key_aliases,(char *)tmp,
- stuff->nKeyAliases*sizeof(XkbKeyAliasRec));
- tmp+= stuff->nKeyAliases*2;
- }
- else if (names->key_aliases!=NULL) {
- xfree(names->key_aliases);
- names->key_aliases= NULL;
- names->num_key_aliases= 0;
- }
- nn.nAliases= names->num_key_aliases;
- }
- if (stuff->which&XkbRGNamesMask) {
- if (stuff->nRadioGroups>0) {
- register unsigned i,nrg;
- nrg= stuff->nRadioGroups;
- if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success)
- return BadAlloc;
-
- for (i=0;i<stuff->nRadioGroups;i++) {
- names->radio_groups[i]= tmp[i];
- }
- tmp+= stuff->nRadioGroups;
- }
- else if (names->radio_groups) {
- xfree(names->radio_groups);
- names->radio_groups= NULL;
- names->num_rg= 0;
- }
- nn.nRadioGroups= names->num_rg;
- }
- if (nn.changed) {
- Bool needExtEvent;
- needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0;
- XkbSendNamesNotify(dev,&nn);
- if (needExtEvent) {
- XkbSrvLedInfoPtr sli;
- xkbExtensionDeviceNotify edev;
- register int i;
- register unsigned bit;
-
- sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
- XkbXI_IndicatorsMask);
- sli->namesPresent= 0;
- for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
- if (names->indicators[i]!=None)
- sli->namesPresent|= bit;
- }
- bzero(&edev,sizeof(xkbExtensionDeviceNotify));
- edev.reason= XkbXI_IndicatorNamesMask;
- edev.ledClass= KbdFeedbackClass;
- edev.ledID= dev->kbdfeed->ctrl.id;
- edev.ledsDefined= sli->namesPresent|sli->mapsPresent;
- edev.ledState= sli->effectiveState;
- edev.firstBtn= 0;
- edev.nBtns= 0;
- edev.supported= XkbXI_AllFeaturesMask;
- edev.unsupported= 0;
- XkbSendExtensionDeviceNotify(dev,client,&edev);
- }
- }
- return Success;
-}
-
-int
-ProcXkbSetNames(ClientPtr client)
-{
- DeviceIntPtr dev;
- CARD32 *tmp;
- Atom bad;
- int rc;
-
- REQUEST(xkbSetNamesReq);
- REQUEST_AT_LEAST_SIZE(xkbSetNamesReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
- CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
-
- /* check device-independent stuff */
- tmp = (CARD32 *)&stuff[1];
-
- if (stuff->which&XkbKeycodesNameMask) {
- tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
- if (!tmp) {
- client->errorValue = bad;
- return BadAtom;
- }
- }
- if (stuff->which&XkbGeometryNameMask) {
- tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
- if (!tmp) {
- client->errorValue = bad;
- return BadAtom;
- }
- }
- if (stuff->which&XkbSymbolsNameMask) {
- tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
- if (!tmp) {
- client->errorValue = bad;
- return BadAtom;
- }
- }
- if (stuff->which&XkbPhysSymbolsNameMask) {
- tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
- if (!tmp) {
- client->errorValue= bad;
- return BadAtom;
- }
- }
- if (stuff->which&XkbTypesNameMask) {
- tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
- if (!tmp) {
- client->errorValue = bad;
- return BadAtom;
- }
- }
- if (stuff->which&XkbCompatNameMask) {
- tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
- if (!tmp) {
- client->errorValue = bad;
- return BadAtom;
- }
- }
-
- /* start of device-dependent tests */
- rc = _XkbSetNamesCheck(client, dev, stuff, tmp);
- if (rc != Success)
- return rc;
-
- if (stuff->deviceSpec == XkbUseCoreKbd)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
- {
-
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
- if (rc == Success)
- {
- rc = _XkbSetNamesCheck(client, other, stuff, tmp);
- if (rc != Success)
- return rc;
- }
- }
- }
- }
-
- /* everything is okay -- update names */
-
- rc = _XkbSetNames(client, dev, stuff);
- if (rc != Success)
- return rc;
-
- if (stuff->deviceSpec == XkbUseCoreKbd)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
- {
-
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
- if (rc == Success)
- _XkbSetNames(client, other, stuff);
- }
- }
- }
-
- /* everything is okay -- update names */
-
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-#include "xkbgeom.h"
-
-#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4)
-
-static char *
-XkbWriteCountedString(char *wire,char *str,Bool swap)
-{
- CARD16 len,*pLen;
-
- if (!str)
- return wire;
-
- len= strlen(str);
- pLen= (CARD16 *)wire;
- *pLen= len;
- if (swap) {
- register int n;
- swaps(pLen,n);
- }
- memcpy(&wire[2],str,len);
- wire+= ((2+len+3)/4)*4;
- return wire;
-}
-
-static int
-XkbSizeGeomProperties(XkbGeometryPtr geom)
-{
-register int i,size;
-XkbPropertyPtr prop;
-
- for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
- size+= XkbSizeCountedString(prop->name);
- size+= XkbSizeCountedString(prop->value);
- }
- return size;
-}
-
-static char *
-XkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap)
-{
-register int i;
-register XkbPropertyPtr prop;
-
- for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
- wire= XkbWriteCountedString(wire,prop->name,swap);
- wire= XkbWriteCountedString(wire,prop->value,swap);
- }
- return wire;
-}
-
-static int
-XkbSizeGeomKeyAliases(XkbGeometryPtr geom)
-{
- return geom->num_key_aliases*(2*XkbKeyNameLength);
-}
-
-static char *
-XkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap)
-{
-register int sz;
-
- sz= geom->num_key_aliases*(XkbKeyNameLength*2);
- if (sz>0) {
- memcpy(wire,(char *)geom->key_aliases,sz);
- wire+= sz;
- }
- return wire;
-}
-
-static int
-XkbSizeGeomColors(XkbGeometryPtr geom)
-{
-register int i,size;
-register XkbColorPtr color;
-
- for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) {
- size+= XkbSizeCountedString(color->spec);
- }
- return size;
-}
-
-static char *
-XkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap)
-{
-register int i;
-register XkbColorPtr color;
-
- for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
- wire= XkbWriteCountedString(wire,color->spec,swap);
- }
- return wire;
-}
-
-static int
-XkbSizeGeomShapes(XkbGeometryPtr geom)
-{
-register int i,size;
-register XkbShapePtr shape;
-
- for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
- register int n;
- register XkbOutlinePtr ol;
- size+= SIZEOF(xkbShapeWireDesc);
- for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
- size+= SIZEOF(xkbOutlineWireDesc);
- size+= ol->num_points*SIZEOF(xkbPointWireDesc);
- }
- }
- return size;
-}
-
-static char *
-XkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap)
-{
-int i;
-XkbShapePtr shape;
-xkbShapeWireDesc * shapeWire;
-
- for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
- register int o;
- XkbOutlinePtr ol;
- xkbOutlineWireDesc * olWire;
- shapeWire= (xkbShapeWireDesc *)wire;
- shapeWire->name= shape->name;
- shapeWire->nOutlines= shape->num_outlines;
- if (shape->primary!=NULL)
- shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary);
- else shapeWire->primaryNdx= XkbNoShape;
- if (shape->approx!=NULL)
- shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx);
- else shapeWire->approxNdx= XkbNoShape;
- if (swap) {
- register int n;
- swapl(&shapeWire->name,n);
- }
- wire= (char *)&shapeWire[1];
- for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
- register int p;
- XkbPointPtr pt;
- xkbPointWireDesc * ptWire;
- olWire= (xkbOutlineWireDesc *)wire;
- olWire->nPoints= ol->num_points;
- olWire->cornerRadius= ol->corner_radius;
- wire= (char *)&olWire[1];
- ptWire= (xkbPointWireDesc *)wire;
- for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
- ptWire[p].x= pt->x;
- ptWire[p].y= pt->y;
- if (swap) {
- register int n;
- swaps(&ptWire[p].x,n);
- swaps(&ptWire[p].y,n);
- }
- }
- wire= (char *)&ptWire[ol->num_points];
- }
- }
- return wire;
-}
-
-static int
-XkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad)
-{
-register int i,size;
-
- for (i=size=0;i<num_doodads;i++,doodad++) {
- size+= SIZEOF(xkbAnyDoodadWireDesc);
- if (doodad->any.type==XkbTextDoodad) {
- size+= XkbSizeCountedString(doodad->text.text);
- size+= XkbSizeCountedString(doodad->text.font);
- }
- else if (doodad->any.type==XkbLogoDoodad) {
- size+= XkbSizeCountedString(doodad->logo.logo_name);
- }
- }
- return size;
-}
-
-static char *
-XkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap)
-{
-register int i;
-xkbDoodadWireDesc * doodadWire;
-
- for (i=0;i<num_doodads;i++,doodad++) {
- doodadWire= (xkbDoodadWireDesc *)wire;
- wire= (char *)&doodadWire[1];
- bzero(doodadWire,SIZEOF(xkbDoodadWireDesc));
- doodadWire->any.name= doodad->any.name;
- doodadWire->any.type= doodad->any.type;
- doodadWire->any.priority= doodad->any.priority;
- doodadWire->any.top= doodad->any.top;
- doodadWire->any.left= doodad->any.left;
- if (swap) {
- register int n;
- swapl(&doodadWire->any.name,n);
- swaps(&doodadWire->any.top,n);
- swaps(&doodadWire->any.left,n);
- }
- switch (doodad->any.type) {
- case XkbOutlineDoodad:
- case XkbSolidDoodad:
- doodadWire->shape.angle= doodad->shape.angle;
- doodadWire->shape.colorNdx= doodad->shape.color_ndx;
- doodadWire->shape.shapeNdx= doodad->shape.shape_ndx;
- if (swap) {
- register int n;
- swaps(&doodadWire->shape.angle,n);
- }
- break;
- case XkbTextDoodad:
- doodadWire->text.angle= doodad->text.angle;
- doodadWire->text.width= doodad->text.width;
- doodadWire->text.height= doodad->text.height;
- doodadWire->text.colorNdx= doodad->text.color_ndx;
- if (swap) {
- register int n;
- swaps(&doodadWire->text.angle,n);
- swaps(&doodadWire->text.width,n);
- swaps(&doodadWire->text.height,n);
- }
- wire= XkbWriteCountedString(wire,doodad->text.text,swap);
- wire= XkbWriteCountedString(wire,doodad->text.font,swap);
- break;
- case XkbIndicatorDoodad:
- doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx;
- doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx;
- doodadWire->indicator.offColorNdx=
- doodad->indicator.off_color_ndx;
- break;
- case XkbLogoDoodad:
- doodadWire->logo.angle= doodad->logo.angle;
- doodadWire->logo.colorNdx= doodad->logo.color_ndx;
- doodadWire->logo.shapeNdx= doodad->logo.shape_ndx;
- wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap);
- break;
- default:
- ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n",
- doodad->any.type);
- ErrorF("[xkb] Ignored\n");
- break;
- }
- }
- return wire;
-}
-
-static char *
-XkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap)
-{
-register int r;
-XkbOverlayRowPtr row;
-xkbOverlayWireDesc * olWire;
-
- olWire= (xkbOverlayWireDesc *)wire;
- olWire->name= ol->name;
- olWire->nRows= ol->num_rows;
- if (swap) {
- register int n;
- swapl(&olWire->name,n);
- }
- wire= (char *)&olWire[1];
- for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
- unsigned int k;
- XkbOverlayKeyPtr key;
- xkbOverlayRowWireDesc * rowWire;
- rowWire= (xkbOverlayRowWireDesc *)wire;
- rowWire->rowUnder= row->row_under;
- rowWire->nKeys= row->num_keys;
- wire= (char *)&rowWire[1];
- for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
- xkbOverlayKeyWireDesc * keyWire;
- keyWire= (xkbOverlayKeyWireDesc *)wire;
- memcpy(keyWire->over,key->over.name,XkbKeyNameLength);
- memcpy(keyWire->under,key->under.name,XkbKeyNameLength);
- wire= (char *)&keyWire[1];
- }
- }
- return wire;
-}
-
-static int
-XkbSizeGeomSections(XkbGeometryPtr geom)
-{
-register int i,size;
-XkbSectionPtr section;
-
- for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) {
- size+= SIZEOF(xkbSectionWireDesc);
- if (section->rows) {
- int r;
- XkbRowPtr row;
- for (r=0,row=section->rows;r<section->num_rows;row++,r++) {
- size+= SIZEOF(xkbRowWireDesc);
- size+= row->num_keys*SIZEOF(xkbKeyWireDesc);
- }
- }
- if (section->doodads)
- size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads);
- if (section->overlays) {
- int o;
- XkbOverlayPtr ol;
- for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
- int r;
- XkbOverlayRowPtr row;
- size+= SIZEOF(xkbOverlayWireDesc);
- for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
- size+= SIZEOF(xkbOverlayRowWireDesc);
- size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc);
- }
- }
- }
- }
- return size;
-}
-
-static char *
-XkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap)
-{
-register int i;
-XkbSectionPtr section;
-xkbSectionWireDesc * sectionWire;
-
- for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
- sectionWire= (xkbSectionWireDesc *)wire;
- sectionWire->name= section->name;
- sectionWire->top= section->top;
- sectionWire->left= section->left;
- sectionWire->width= section->width;
- sectionWire->height= section->height;
- sectionWire->angle= section->angle;
- sectionWire->priority= section->priority;
- sectionWire->nRows= section->num_rows;
- sectionWire->nDoodads= section->num_doodads;
- sectionWire->nOverlays= section->num_overlays;
- sectionWire->pad= 0;
- if (swap) {
- register int n;
- swapl(&sectionWire->name,n);
- swaps(&sectionWire->top,n);
- swaps(&sectionWire->left,n);
- swaps(&sectionWire->width,n);
- swaps(&sectionWire->height,n);
- swaps(&sectionWire->angle,n);
- }
- wire= (char *)&sectionWire[1];
- if (section->rows) {
- int r;
- XkbRowPtr row;
- xkbRowWireDesc * rowWire;
- for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
- rowWire= (xkbRowWireDesc *)wire;
- rowWire->top= row->top;
- rowWire->left= row->left;
- rowWire->nKeys= row->num_keys;
- rowWire->vertical= row->vertical;
- rowWire->pad= 0;
- if (swap) {
- register int n;
- swaps(&rowWire->top,n);
- swaps(&rowWire->left,n);
- }
- wire= (char *)&rowWire[1];
- if (row->keys) {
- int k;
- XkbKeyPtr key;
- xkbKeyWireDesc * keyWire;
- keyWire= (xkbKeyWireDesc *)wire;
- for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
- memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength);
- keyWire[k].gap= key->gap;
- keyWire[k].shapeNdx= key->shape_ndx;
- keyWire[k].colorNdx= key->color_ndx;
- if (swap) {
- register int n;
- swaps(&keyWire[k].gap,n);
- }
- }
- wire= (char *)&keyWire[row->num_keys];
- }
- }
- }
- if (section->doodads) {
- wire= XkbWriteGeomDoodads(wire,
- section->num_doodads,section->doodads,
- swap);
- }
- if (section->overlays) {
- register int o;
- for (o=0;o<section->num_overlays;o++) {
- wire= XkbWriteGeomOverlay(wire,&section->overlays[o],swap);
- }
- }
- }
- return wire;
-}
-
-static Status
-XkbComputeGetGeometryReplySize( XkbGeometryPtr geom,
- xkbGetGeometryReply * rep,
- Atom name)
-{
-int len;
-
- if (geom!=NULL) {
- len= XkbSizeCountedString(geom->label_font);
- len+= XkbSizeGeomProperties(geom);
- len+= XkbSizeGeomColors(geom);
- len+= XkbSizeGeomShapes(geom);
- len+= XkbSizeGeomSections(geom);
- len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads);
- len+= XkbSizeGeomKeyAliases(geom);
- rep->length= len/4;
- rep->found= TRUE;
- rep->name= geom->name;
- rep->widthMM= geom->width_mm;
- rep->heightMM= geom->height_mm;
- rep->nProperties= geom->num_properties;
- rep->nColors= geom->num_colors;
- rep->nShapes= geom->num_shapes;
- rep->nSections= geom->num_sections;
- rep->nDoodads= geom->num_doodads;
- rep->nKeyAliases= geom->num_key_aliases;
- rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color);
- rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color);
- }
- else {
- rep->length= 0;
- rep->found= FALSE;
- rep->name= name;
- rep->widthMM= rep->heightMM= 0;
- rep->nProperties= rep->nColors= rep->nShapes= 0;
- rep->nSections= rep->nDoodads= 0;
- rep->nKeyAliases= 0;
- rep->labelColorNdx= rep->baseColorNdx= 0;
- }
- return Success;
-}
-
-static int
-XkbSendGeometry( ClientPtr client,
- XkbGeometryPtr geom,
- xkbGetGeometryReply * rep,
- Bool freeGeom)
-{
- char *desc,*start;
- int len;
-
- if (geom!=NULL) {
- len= rep->length*4;
- start= desc= xalloc(len);
- if (!start)
- return BadAlloc;
- desc= XkbWriteCountedString(desc,geom->label_font,client->swapped);
- if ( rep->nProperties>0 )
- desc = XkbWriteGeomProperties(desc,geom,client->swapped);
- if ( rep->nColors>0 )
- desc = XkbWriteGeomColors(desc,geom,client->swapped);
- if ( rep->nShapes>0 )
- desc = XkbWriteGeomShapes(desc,geom,client->swapped);
- if ( rep->nSections>0 )
- desc = XkbWriteGeomSections(desc,geom,client->swapped);
- if ( rep->nDoodads>0 )
- desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads,
- client->swapped);
- if ( rep->nKeyAliases>0 )
- desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped);
- if ((desc-start)!=(len)) {
- ErrorF("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n",
- len, (unsigned long)(desc-start));
- }
- }
- else {
- len= 0;
- start= NULL;
- }
- if (client->swapped) {
- register int n;
- swaps(&rep->sequenceNumber,n);
- swapl(&rep->length,n);
- swapl(&rep->name,n);
- swaps(&rep->widthMM,n);
- swaps(&rep->heightMM,n);
- swaps(&rep->nProperties,n);
- swaps(&rep->nColors,n);
- swaps(&rep->nShapes,n);
- swaps(&rep->nSections,n);
- swaps(&rep->nDoodads,n);
- swaps(&rep->nKeyAliases,n);
- }
- WriteToClient(client, SIZEOF(xkbGetGeometryReply), (char *)rep);
- if (len>0)
- WriteToClient(client, len, start);
- if (start!=NULL)
- xfree((char *)start);
- if (freeGeom)
- XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
- return client->noClientException;
-}
-
-int
-ProcXkbGetGeometry(ClientPtr client)
-{
- DeviceIntPtr dev;
- xkbGetGeometryReply rep;
- XkbGeometryPtr geom;
- Bool shouldFree;
- Status status;
-
- REQUEST(xkbGetGeometryReq);
- REQUEST_SIZE_MATCH(xkbGetGeometryReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
- CHK_ATOM_OR_NONE(stuff->name);
-
- geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree);
- rep.type= X_Reply;
- rep.deviceID= dev->id;
- rep.sequenceNumber= client->sequence;
- rep.length= 0;
- status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name);
- if (status!=Success)
- return status;
- else return XkbSendGeometry(client,geom,&rep,shouldFree);
-}
-
-/***====================================================================***/
-
-static char *
-_GetCountedString(char **wire_inout,Bool swap)
-{
-char * wire,*str;
-CARD16 len,*plen;
-
- wire= *wire_inout;
- plen= (CARD16 *)wire;
- if (swap) {
- register int n;
- swaps(plen,n);
- }
- len= *plen;
- str= xalloc(len+1);
- if (str) {
- memcpy(str,&wire[2],len);
- str[len]= '\0';
- }
- wire+= XkbPaddedSize(len+2);
- *wire_inout= wire;
- return str;
-}
-
-static Status
-_CheckSetDoodad( char ** wire_inout,
- XkbGeometryPtr geom,
- XkbSectionPtr section,
- ClientPtr client)
-{
-char * wire;
-xkbDoodadWireDesc * dWire;
-XkbDoodadPtr doodad;
-
- dWire= (xkbDoodadWireDesc *)(*wire_inout);
- wire= (char *)&dWire[1];
- if (client->swapped) {
- register int n;
- swapl(&dWire->any.name,n);
- swaps(&dWire->any.top,n);
- swaps(&dWire->any.left,n);
- swaps(&dWire->any.angle,n);
- }
- CHK_ATOM_ONLY(dWire->any.name);
- doodad= XkbAddGeomDoodad(geom,section,dWire->any.name);
- if (!doodad)
- return BadAlloc;
- doodad->any.type= dWire->any.type;
- doodad->any.priority= dWire->any.priority;
- doodad->any.top= dWire->any.top;
- doodad->any.left= dWire->any.left;
- doodad->any.angle= dWire->any.angle;
- switch (doodad->any.type) {
- case XkbOutlineDoodad:
- case XkbSolidDoodad:
- if (dWire->shape.colorNdx>=geom->num_colors) {
- client->errorValue= _XkbErrCode3(0x40,geom->num_colors,
- dWire->shape.colorNdx);
- return BadMatch;
- }
- if (dWire->shape.shapeNdx>=geom->num_shapes) {
- client->errorValue= _XkbErrCode3(0x41,geom->num_shapes,
- dWire->shape.shapeNdx);
- return BadMatch;
- }
- doodad->shape.color_ndx= dWire->shape.colorNdx;
- doodad->shape.shape_ndx= dWire->shape.shapeNdx;
- break;
- case XkbTextDoodad:
- if (dWire->text.colorNdx>=geom->num_colors) {
- client->errorValue= _XkbErrCode3(0x42,geom->num_colors,
- dWire->text.colorNdx);
- return BadMatch;
- }
- if (client->swapped) {
- register int n;
- swaps(&dWire->text.width,n);
- swaps(&dWire->text.height,n);
- }
- doodad->text.width= dWire->text.width;
- doodad->text.height= dWire->text.height;
- doodad->text.color_ndx= dWire->text.colorNdx;
- doodad->text.text= _GetCountedString(&wire,client->swapped);
- doodad->text.font= _GetCountedString(&wire,client->swapped);
- break;
- case XkbIndicatorDoodad:
- if (dWire->indicator.onColorNdx>=geom->num_colors) {
- client->errorValue= _XkbErrCode3(0x43,geom->num_colors,
- dWire->indicator.onColorNdx);
- return BadMatch;
- }
- if (dWire->indicator.offColorNdx>=geom->num_colors) {
- client->errorValue= _XkbErrCode3(0x44,geom->num_colors,
- dWire->indicator.offColorNdx);
- return BadMatch;
- }
- if (dWire->indicator.shapeNdx>=geom->num_shapes) {
- client->errorValue= _XkbErrCode3(0x45,geom->num_shapes,
- dWire->indicator.shapeNdx);
- return BadMatch;
- }
- doodad->indicator.shape_ndx= dWire->indicator.shapeNdx;
- doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx;
- doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx;
- break;
- case XkbLogoDoodad:
- if (dWire->logo.colorNdx>=geom->num_colors) {
- client->errorValue= _XkbErrCode3(0x46,geom->num_colors,
- dWire->logo.colorNdx);
- return BadMatch;
- }
- if (dWire->logo.shapeNdx>=geom->num_shapes) {
- client->errorValue= _XkbErrCode3(0x47,geom->num_shapes,
- dWire->logo.shapeNdx);
- return BadMatch;
- }
- doodad->logo.color_ndx= dWire->logo.colorNdx;
- doodad->logo.shape_ndx= dWire->logo.shapeNdx;
- doodad->logo.logo_name= _GetCountedString(&wire,client->swapped);
- break;
- default:
- client->errorValue= _XkbErrCode2(0x4F,dWire->any.type);
- return BadValue;
- }
- *wire_inout= wire;
- return Success;
-}
-
-static Status
-_CheckSetOverlay( char ** wire_inout,
- XkbGeometryPtr geom,
- XkbSectionPtr section,
- ClientPtr client)
-{
-register int r;
-char * wire;
-XkbOverlayPtr ol;
-xkbOverlayWireDesc * olWire;
-xkbOverlayRowWireDesc * rWire;
-
- wire= *wire_inout;
- olWire= (xkbOverlayWireDesc *)wire;
- if (client->swapped) {
- register int n;
- swapl(&olWire->name,n);
- }
- CHK_ATOM_ONLY(olWire->name);
- ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows);
- rWire= (xkbOverlayRowWireDesc *)&olWire[1];
- for (r=0;r<olWire->nRows;r++) {
- register int k;
- xkbOverlayKeyWireDesc * kWire;
- XkbOverlayRowPtr row;
-
- if (rWire->rowUnder>section->num_rows) {
- client->errorValue= _XkbErrCode4(0x20,r,section->num_rows,
- rWire->rowUnder);
- return BadMatch;
- }
- row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys);
- kWire= (xkbOverlayKeyWireDesc *)&rWire[1];
- for (k=0;k<rWire->nKeys;k++,kWire++) {
- if (XkbAddGeomOverlayKey(ol,row,
- (char *)kWire->over,(char *)kWire->under)==NULL) {
- client->errorValue= _XkbErrCode3(0x21,r,k);
- return BadMatch;
- }
- }
- rWire= (xkbOverlayRowWireDesc *)kWire;
- }
- olWire= (xkbOverlayWireDesc *)rWire;
- wire= (char *)olWire;
- *wire_inout= wire;
- return Success;
-}
-
-static Status
-_CheckSetSections( XkbGeometryPtr geom,
- xkbSetGeometryReq * req,
- char ** wire_inout,
- ClientPtr client)
-{
-Status status;
-register int s;
-char * wire;
-xkbSectionWireDesc * sWire;
-XkbSectionPtr section;
-
- wire= *wire_inout;
- if (req->nSections<1)
- return Success;
- sWire= (xkbSectionWireDesc *)wire;
- for (s=0;s<req->nSections;s++) {
- register int r;
- xkbRowWireDesc * rWire;
- if (client->swapped) {
- register int n;
- swapl(&sWire->name,n);
- swaps(&sWire->top,n);
- swaps(&sWire->left,n);
- swaps(&sWire->width,n);
- swaps(&sWire->height,n);
- swaps(&sWire->angle,n);
- }
- CHK_ATOM_ONLY(sWire->name);
- section= XkbAddGeomSection(geom,sWire->name,sWire->nRows,
- sWire->nDoodads,sWire->nOverlays);
- if (!section)
- return BadAlloc;
- section->priority= sWire->priority;
- section->top= sWire->top;
- section->left= sWire->left;
- section->width= sWire->width;
- section->height= sWire->height;
- section->angle= sWire->angle;
- rWire= (xkbRowWireDesc *)&sWire[1];
- for (r=0;r<sWire->nRows;r++) {
- register int k;
- XkbRowPtr row;
- xkbKeyWireDesc * kWire;
- if (client->swapped) {
- register int n;
- swaps(&rWire->top,n);
- swaps(&rWire->left,n);
- }
- row= XkbAddGeomRow(section,rWire->nKeys);
- if (!row)
- return BadAlloc;
- row->top= rWire->top;
- row->left= rWire->left;
- row->vertical= rWire->vertical;
- kWire= (xkbKeyWireDesc *)&rWire[1];
- for (k=0;k<rWire->nKeys;k++) {
- XkbKeyPtr key;
- key= XkbAddGeomKey(row);
- if (!key)
- return BadAlloc;
- memcpy(key->name.name,kWire[k].name,XkbKeyNameLength);
- key->gap= kWire[k].gap;
- key->shape_ndx= kWire[k].shapeNdx;
- key->color_ndx= kWire[k].colorNdx;
- if (key->shape_ndx>=geom->num_shapes) {
- client->errorValue= _XkbErrCode3(0x10,key->shape_ndx,
- geom->num_shapes);
- return BadMatch;
- }
- if (key->color_ndx>=geom->num_colors) {
- client->errorValue= _XkbErrCode3(0x11,key->color_ndx,
- geom->num_colors);
- return BadMatch;
- }
- }
- rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys];
- }
- wire= (char *)rWire;
- if (sWire->nDoodads>0) {
- register int d;
- for (d=0;d<sWire->nDoodads;d++) {
- status=_CheckSetDoodad(&wire,geom,section,client);
- if (status!=Success)
- return status;
- }
- }
- if (sWire->nOverlays>0) {
- register int o;
- for (o=0;o<sWire->nOverlays;o++) {
- status= _CheckSetOverlay(&wire,geom,section,client);
- if (status!=Success)
- return status;
- }
- }
- sWire= (xkbSectionWireDesc *)wire;
- }
- wire= (char *)sWire;
- *wire_inout= wire;
- return Success;
-}
-
-static Status
-_CheckSetShapes( XkbGeometryPtr geom,
- xkbSetGeometryReq * req,
- char ** wire_inout,
- ClientPtr client)
-{
-register int i;
-char * wire;
-
- wire= *wire_inout;
- if (req->nShapes<1) {
- client->errorValue= _XkbErrCode2(0x06,req->nShapes);
- return BadValue;
- }
- else {
- xkbShapeWireDesc * shapeWire;
- XkbShapePtr shape;
- register int o;
- shapeWire= (xkbShapeWireDesc *)wire;
- for (i=0;i<req->nShapes;i++) {
- xkbOutlineWireDesc * olWire;
- XkbOutlinePtr ol;
- shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines);
- if (!shape)
- return BadAlloc;
- olWire= (xkbOutlineWireDesc *)(&shapeWire[1]);
- for (o=0;o<shapeWire->nOutlines;o++) {
- register int p;
- XkbPointPtr pt;
- xkbPointWireDesc * ptWire;
-
- ol= XkbAddGeomOutline(shape,olWire->nPoints);
- if (!ol)
- return BadAlloc;
- ol->corner_radius= olWire->cornerRadius;
- ptWire= (xkbPointWireDesc *)&olWire[1];
- for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) {
- pt->x= ptWire[p].x;
- pt->y= ptWire[p].y;
- if (client->swapped) {
- register int n;
- swaps(&pt->x,n);
- swaps(&pt->y,n);
- }
- }
- ol->num_points= olWire->nPoints;
- olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]);
- }
- if (shapeWire->primaryNdx!=XkbNoShape)
- shape->primary= &shape->outlines[shapeWire->primaryNdx];
- if (shapeWire->approxNdx!=XkbNoShape)
- shape->approx= &shape->outlines[shapeWire->approxNdx];
- shapeWire= (xkbShapeWireDesc *)olWire;
- }
- wire= (char *)shapeWire;
- }
- if (geom->num_shapes!=req->nShapes) {
- client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes);
- return BadMatch;
- }
-
- *wire_inout= wire;
- return Success;
-}
-
-static Status
-_CheckSetGeom( XkbGeometryPtr geom,
- xkbSetGeometryReq * req,
- ClientPtr client)
-{
-register int i;
-Status status;
-char * wire;
-
- wire= (char *)&req[1];
- geom->label_font= _GetCountedString(&wire,client->swapped);
-
- for (i=0;i<req->nProperties;i++) {
- char *name,*val;
- name= _GetCountedString(&wire,client->swapped);
- if (!name)
- return BadAlloc;
- val= _GetCountedString(&wire,client->swapped);
- if (!val) {
- xfree(name);
- return BadAlloc;
- }
- if (XkbAddGeomProperty(geom,name,val)==NULL) {
- xfree(name);
- xfree(val);
- return BadAlloc;
- }
- xfree(name);
- xfree(val);
- }
-
- if (req->nColors<2) {
- client->errorValue= _XkbErrCode3(0x01,2,req->nColors);
- return BadValue;
- }
- if (req->baseColorNdx>req->nColors) {
- client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx);
- return BadMatch;
- }
- if (req->labelColorNdx>req->nColors) {
- client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx);
- return BadMatch;
- }
- if (req->labelColorNdx==req->baseColorNdx) {
- client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx,
- req->labelColorNdx);
- return BadMatch;
- }
-
- for (i=0;i<req->nColors;i++) {
- char *name;
- name= _GetCountedString(&wire,client->swapped);
- if (!name)
- return BadAlloc;
- if (!XkbAddGeomColor(geom,name,geom->num_colors)) {
- xfree(name);
- return BadAlloc;
- }
- xfree(name);
- }
- if (req->nColors!=geom->num_colors) {
- client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors);
- return BadMatch;
- }
- geom->label_color= &geom->colors[req->labelColorNdx];
- geom->base_color= &geom->colors[req->baseColorNdx];
-
- if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success)
- return status;
-
- if ((status=_CheckSetSections(geom,req,&wire,client))!=Success)
- return status;
-
- for (i=0;i<req->nDoodads;i++) {
- status=_CheckSetDoodad(&wire,geom,NULL,client);
- if (status!=Success)
- return status;
- }
-
- for (i=0;i<req->nKeyAliases;i++) {
- if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL)
- return BadAlloc;
- wire+= 2*XkbKeyNameLength;
- }
- return Success;
-}
-
-static int
-_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq *stuff)
-{
- XkbDescPtr xkb;
- Bool new_name;
- xkbNewKeyboardNotify nkn;
- XkbGeometryPtr geom,old;
- XkbGeometrySizesRec sizes;
- Status status;
-
- xkb= dev->key->xkbInfo->desc;
- old= xkb->geom;
- xkb->geom= NULL;
-
- sizes.which= XkbGeomAllMask;
- sizes.num_properties= stuff->nProperties;
- sizes.num_colors= stuff->nColors;
- sizes.num_shapes= stuff->nShapes;
- sizes.num_sections= stuff->nSections;
- sizes.num_doodads= stuff->nDoodads;
- sizes.num_key_aliases= stuff->nKeyAliases;
- if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) {
- xkb->geom= old;
- return status;
- }
- geom= xkb->geom;
- geom->name= stuff->name;
- geom->width_mm= stuff->widthMM;
- geom->height_mm= stuff->heightMM;
- if ((status= _CheckSetGeom(geom,stuff,client))!=Success) {
- XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
- xkb->geom= old;
- return status;
- }
- new_name= (xkb->names->geometry!=geom->name);
- xkb->names->geometry= geom->name;
- if (old)
- XkbFreeGeometry(old,XkbGeomAllMask,TRUE);
- if (new_name) {
- xkbNamesNotify nn;
- bzero(&nn,sizeof(xkbNamesNotify));
- nn.changed= XkbGeometryNameMask;
- XkbSendNamesNotify(dev,&nn);
- }
- nkn.deviceID= nkn.oldDeviceID= dev->id;
- nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code;
- nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code;
- nkn.requestMajor= XkbReqCode;
- nkn.requestMinor= X_kbSetGeometry;
- nkn.changed= XkbNKN_GeometryMask;
- XkbSendNewKeyboardNotify(dev,&nkn);
- return Success;
-}
-
-int
-ProcXkbSetGeometry(ClientPtr client)
-{
- DeviceIntPtr dev;
- int rc;
-
- REQUEST(xkbSetGeometryReq);
- REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
- CHK_ATOM_OR_NONE(stuff->name);
-
- rc = _XkbSetGeometry(client, dev, stuff);
- if (rc != Success)
- return rc;
-
- if (stuff->deviceSpec == XkbUseCoreKbd)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
- {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
- if (rc == Success)
- _XkbSetGeometry(client, other, stuff);
- }
- }
- }
-
- return Success;
-}
-
-/***====================================================================***/
-
-int
-ProcXkbPerClientFlags(ClientPtr client)
-{
- DeviceIntPtr dev;
- xkbPerClientFlagsReply rep;
- XkbInterestPtr interest;
- Mask access_mode = DixGetAttrAccess | DixSetAttrAccess;
-
- REQUEST(xkbPerClientFlagsReq);
- REQUEST_SIZE_MATCH(xkbPerClientFlagsReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode);
- CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask);
- CHK_MASK_MATCH(0x02,stuff->change,stuff->value);
-
- interest = XkbFindClientResource((DevicePtr)dev,client);
- memset(&rep, 0, sizeof(xkbPerClientFlagsReply));
- rep.type= X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- if (stuff->change) {
- client->xkbClientFlags&= ~stuff->change;
- client->xkbClientFlags|= stuff->value;
- }
- if (stuff->change&XkbPCF_AutoResetControlsMask) {
- Bool want;
- want= stuff->value&XkbPCF_AutoResetControlsMask;
- if (interest && !want) {
- interest->autoCtrls= interest->autoCtrlValues= 0;
- }
- else if (want && (!interest)) {
- XID id = FakeClientID(client->index);
- AddResource(id,RT_XKBCLIENT,dev);
- interest= XkbAddClientResource((DevicePtr)dev,client,id);
- if (!interest)
- return BadAlloc;
- }
- if (interest && want ) {
- register unsigned affect;
- affect= stuff->ctrlsToChange;
-
- CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask);
- CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls);
- CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues);
-
- interest->autoCtrls&= ~affect;
- interest->autoCtrlValues&= ~affect;
- interest->autoCtrls|= stuff->autoCtrls&affect;
- interest->autoCtrlValues|= stuff->autoCtrlValues&affect;
- }
- }
- rep.supported = XkbPCF_AllFlagsMask;
- rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask;
- if (interest) {
- rep.autoCtrls= interest->autoCtrls;
- rep.autoCtrlValues= interest->autoCtrlValues;
- }
- else {
- rep.autoCtrls= rep.autoCtrlValues= 0;
- }
- if ( client->swapped ) {
- register int n;
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.supported,n);
- swapl(&rep.value,n);
- swapl(&rep.autoCtrls,n);
- swapl(&rep.autoCtrlValues,n);
- }
- WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep);
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */
-/* and wildcards */
-static unsigned char componentSpecLegal[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87,
- 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
-};
-
-/* same as above but accepts percent, plus and bar too */
-static unsigned char componentExprLegal[] = {
- 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87,
- 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
-};
-
-static char *
-GetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn)
-{
-int len;
-register int i;
-unsigned char *wire,*str,*tmp,*legal;
-
- if (allowExpr) legal= &componentExprLegal[0];
- else legal= &componentSpecLegal[0];
-
- wire= *pWire;
- len= (*(unsigned char *)wire++);
- if (len>0) {
- str= xcalloc(1, len+1);
- if (str) {
- tmp= str;
- for (i=0;i<len;i++) {
- if (legal[(*wire)/8]&(1<<((*wire)%8)))
- *tmp++= *wire++;
- else wire++;
- }
- if (tmp!=str)
- *tmp++= '\0';
- else {
- xfree(str);
- str= NULL;
- }
- }
- else {
- *errRtrn= BadAlloc;
- }
- }
- else {
- str= NULL;
- }
- *pWire= wire;
- return (char *)str;
-}
-
-/***====================================================================***/
-
-int
-ProcXkbListComponents(ClientPtr client)
-{
- DeviceIntPtr dev;
- xkbListComponentsReply rep;
- unsigned len;
- int status;
- unsigned char * str;
- XkbSrvListInfoRec list;
-
- REQUEST(xkbListComponentsReq);
- REQUEST_AT_LEAST_SIZE(xkbListComponentsReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
-
- status= Success;
- str= (unsigned char *)&stuff[1];
- bzero(&list,sizeof(XkbSrvListInfoRec));
- list.maxRtrn= stuff->maxNames;
- list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,FALSE,&status);
- list.pattern[_XkbListTypes]= GetComponentSpec(&str,FALSE,&status);
- list.pattern[_XkbListCompat]= GetComponentSpec(&str,FALSE,&status);
- list.pattern[_XkbListSymbols]= GetComponentSpec(&str,FALSE,&status);
- list.pattern[_XkbListGeometry]= GetComponentSpec(&str,FALSE,&status);
- if (status!=Success)
- return status;
- len= str-((unsigned char *)stuff);
- if ((XkbPaddedSize(len)/4)!=stuff->length)
- return BadLength;
- if ((status=XkbDDXList(dev,&list,client))!=Success) {
- if (list.pool) {
- xfree(list.pool);
- list.pool= NULL;
- }
- return status;
- }
- bzero(&rep,sizeof(xkbListComponentsReply));
- rep.type= X_Reply;
- rep.deviceID = dev->id;
- rep.sequenceNumber = client->sequence;
- rep.length = XkbPaddedSize(list.nPool)/4;
- rep.nKeymaps = 0;
- rep.nKeycodes = list.nFound[_XkbListKeycodes];
- rep.nTypes = list.nFound[_XkbListTypes];
- rep.nCompatMaps = list.nFound[_XkbListCompat];
- rep.nSymbols = list.nFound[_XkbListSymbols];
- rep.nGeometries = list.nFound[_XkbListGeometry];
- rep.extra= 0;
- if (list.nTotal>list.maxRtrn)
- rep.extra = (list.nTotal-list.maxRtrn);
- if (client->swapped) {
- register int n;
- swaps(&rep.sequenceNumber,n);
- swapl(&rep.length,n);
- swaps(&rep.nKeymaps,n);
- swaps(&rep.nKeycodes,n);
- swaps(&rep.nTypes,n);
- swaps(&rep.nCompatMaps,n);
- swaps(&rep.nSymbols,n);
- swaps(&rep.nGeometries,n);
- swaps(&rep.extra,n);
- }
- WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep);
- if (list.nPool && list.pool) {
- WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool);
- xfree(list.pool);
- list.pool= NULL;
- }
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-int
-ProcXkbGetKbdByName(ClientPtr client)
-{
- DeviceIntPtr dev;
- DeviceIntPtr tmpd;
- xkbGetKbdByNameReply rep;
- xkbGetMapReply mrep;
- xkbGetCompatMapReply crep;
- xkbGetIndicatorMapReply irep;
- xkbGetNamesReply nrep;
- xkbGetGeometryReply grep;
- XkbComponentNamesRec names;
- XkbDescPtr xkb, new;
- unsigned char * str;
- char mapFile[PATH_MAX];
- unsigned len;
- unsigned fwant,fneed,reported;
- int status;
- Bool geom_changed;
- XkbSrvLedInfoPtr old_sli;
- XkbSrvLedInfoPtr sli;
- Mask access_mode = DixGetAttrAccess | DixManageAccess;
-
- REQUEST(xkbGetKbdByNameReq);
- REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode);
-
- xkb = dev->key->xkbInfo->desc;
- status= Success;
- str= (unsigned char *)&stuff[1];
- if (GetComponentSpec(&str,TRUE,&status)) /* keymap, unsupported */
- return BadMatch;
- names.keycodes= GetComponentSpec(&str,TRUE,&status);
- names.types= GetComponentSpec(&str,TRUE,&status);
- names.compat= GetComponentSpec(&str,TRUE,&status);
- names.symbols= GetComponentSpec(&str,TRUE,&status);
- names.geometry= GetComponentSpec(&str,TRUE,&status);
- if (status!=Success)
- return status;
- len= str-((unsigned char *)stuff);
- if ((XkbPaddedSize(len)/4)!=stuff->length)
- return BadLength;
-
- CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask);
- CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask);
-
- if (stuff->load)
- fwant= XkbGBN_AllComponentsMask;
- else fwant= stuff->want|stuff->need;
- if ((!names.compat)&&
- (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) {
- names.compat= _XkbDupString("%");
- }
- if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) {
- names.types= _XkbDupString("%");
- }
- if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) {
- names.symbols= _XkbDupString("%");
- }
- geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0));
- if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) {
- names.geometry= _XkbDupString("%");
- geom_changed= FALSE;
- }
-
- bzero(mapFile,PATH_MAX);
- rep.type= X_Reply;
- rep.deviceID = dev->id;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.minKeyCode = xkb->min_key_code;
- rep.maxKeyCode = xkb->max_key_code;
- rep.loaded= FALSE;
- fwant= XkbConvertGetByNameComponents(TRUE,stuff->want)|XkmVirtualModsMask;
- fneed= XkbConvertGetByNameComponents(TRUE,stuff->need);
- rep.reported= XkbConvertGetByNameComponents(FALSE,fwant|fneed);
- if (stuff->load) {
- fneed|= XkmKeymapRequired;
- fwant|= XkmKeymapLegal;
- }
- if ((fwant|fneed)&XkmSymbolsMask) {
- fneed|= XkmKeyNamesIndex|XkmTypesIndex;
- fwant|= XkmIndicatorsIndex;
- }
-
- /* We pass dev in here so we can get the old names out if needed. */
- rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&new,
- mapFile,PATH_MAX);
- rep.newKeyboard= FALSE;
- rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0;
-
- stuff->want|= stuff->need;
- if (new==NULL)
- rep.reported= 0;
- else {
- if (stuff->load)
- rep.loaded= TRUE;
- if (stuff->load ||
- ((rep.reported&XkbGBN_SymbolsMask) && (new->compat))) {
- XkbChangesRec changes;
- bzero(&changes,sizeof(changes));
- XkbUpdateDescActions(new,
- new->min_key_code,XkbNumKeys(new),
- &changes);
- }
-
- if (new->map==NULL)
- rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask);
- else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) {
- mrep.type= X_Reply;
- mrep.deviceID = dev->id;
- mrep.sequenceNumber= client->sequence;
- mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2);
- mrep.minKeyCode = new->min_key_code;
- mrep.maxKeyCode = new->max_key_code;
- mrep.present = 0;
- mrep.totalSyms = mrep.totalActs =
- mrep.totalKeyBehaviors= mrep.totalKeyExplicit=
- mrep.totalModMapKeys= mrep.totalVModMapKeys= 0;
- if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) {
- mrep.present|= XkbKeyTypesMask;
- mrep.firstType = 0;
- mrep.nTypes = mrep.totalTypes= new->map->num_types;
- }
- else {
- mrep.firstType = mrep.nTypes= 0;
- mrep.totalTypes= 0;
- }
- if (rep.reported&XkbGBN_ClientSymbolsMask) {
- mrep.present|= (XkbKeySymsMask|XkbModifierMapMask);
- mrep.firstKeySym = mrep.firstModMapKey= new->min_key_code;
- mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(new);
- }
- else {
- mrep.firstKeySym= mrep.firstModMapKey= 0;
- mrep.nKeySyms= mrep.nModMapKeys= 0;
- }
- if (rep.reported&XkbGBN_ServerSymbolsMask) {
- mrep.present|= XkbAllServerInfoMask;
- mrep.virtualMods= ~0;
- mrep.firstKeyAct = mrep.firstKeyBehavior =
- mrep.firstKeyExplicit = new->min_key_code;
- mrep.nKeyActs = mrep.nKeyBehaviors =
- mrep.nKeyExplicit = XkbNumKeys(new);
- mrep.firstVModMapKey= new->min_key_code;
- mrep.nVModMapKeys= XkbNumKeys(new);
- }
- else {
- mrep.virtualMods= 0;
- mrep.firstKeyAct= mrep.firstKeyBehavior=
- mrep.firstKeyExplicit = 0;
- mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0;
- }
- XkbComputeGetMapReplySize(new,&mrep);
- rep.length+= SIZEOF(xGenericReply)/4+mrep.length;
- }
- if (new->compat==NULL)
- rep.reported&= ~XkbGBN_CompatMapMask;
- else if (rep.reported&XkbGBN_CompatMapMask) {
- crep.type= X_Reply;
- crep.deviceID= dev->id;
- crep.sequenceNumber= client->sequence;
- crep.length= 0;
- crep.groups= XkbAllGroupsMask;
- crep.firstSI= 0;
- crep.nSI= crep.nTotalSI= new->compat->num_si;
- XkbComputeGetCompatMapReplySize(new->compat,&crep);
- rep.length+= SIZEOF(xGenericReply)/4+crep.length;
- }
- if (new->indicators==NULL)
- rep.reported&= ~XkbGBN_IndicatorMapMask;
- else if (rep.reported&XkbGBN_IndicatorMapMask) {
- irep.type= X_Reply;
- irep.deviceID= dev->id;
- irep.sequenceNumber= client->sequence;
- irep.length= 0;
- irep.which= XkbAllIndicatorsMask;
- XkbComputeGetIndicatorMapReplySize(new->indicators,&irep);
- rep.length+= SIZEOF(xGenericReply)/4+irep.length;
- }
- if (new->names==NULL)
- rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask);
- else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) {
- nrep.type= X_Reply;
- nrep.deviceID= dev->id;
- nrep.sequenceNumber= client->sequence;
- nrep.length= 0;
- nrep.minKeyCode= new->min_key_code;
- nrep.maxKeyCode= new->max_key_code;
- if (rep.reported&XkbGBN_OtherNamesMask) {
- nrep.which= XkbAllNamesMask;
- if (new->map!=NULL)
- nrep.nTypes= new->map->num_types;
- else nrep.nTypes= 0;
- nrep.nKTLevels= 0;
- nrep.groupNames= XkbAllGroupsMask;
- nrep.virtualMods= XkbAllVirtualModsMask;
- nrep.indicators= XkbAllIndicatorsMask;
- nrep.nRadioGroups= new->names->num_rg;
- }
- else {
- nrep.which= 0;
- nrep.nTypes= 0;
- nrep.nKTLevels= 0;
- nrep.groupNames= 0;
- nrep.virtualMods= 0;
- nrep.indicators= 0;
- nrep.nRadioGroups= 0;
- }
- if (rep.reported&XkbGBN_KeyNamesMask) {
- nrep.which|= XkbKeyNamesMask;
- nrep.firstKey= new->min_key_code;
- nrep.nKeys= XkbNumKeys(new);
- nrep.nKeyAliases= new->names->num_key_aliases;
- if (nrep.nKeyAliases)
- nrep.which|= XkbKeyAliasesMask;
- }
- else {
- nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask);
- nrep.firstKey= nrep.nKeys= 0;
- nrep.nKeyAliases= 0;
- }
- XkbComputeGetNamesReplySize(new,&nrep);
- rep.length+= SIZEOF(xGenericReply)/4+nrep.length;
- }
- if (new->geom==NULL)
- rep.reported&= ~XkbGBN_GeometryMask;
- else if (rep.reported&XkbGBN_GeometryMask) {
- grep.type= X_Reply;
- grep.deviceID= dev->id;
- grep.sequenceNumber= client->sequence;
- grep.length= 0;
- grep.found= TRUE;
- grep.pad= 0;
- grep.widthMM= grep.heightMM= 0;
- grep.nProperties= grep.nColors= grep.nShapes= 0;
- grep.nSections= grep.nDoodads= 0;
- grep.baseColorNdx= grep.labelColorNdx= 0;
- XkbComputeGetGeometryReplySize(new->geom,&grep,None);
- rep.length+= SIZEOF(xGenericReply)/4+grep.length;
- }
- }
-
- reported= rep.reported;
- if ( client->swapped ) {
- register int n;
- swaps(&rep.sequenceNumber,n);
- swapl(&rep.length,n);
- swaps(&rep.found,n);
- swaps(&rep.reported,n);
- }
- WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep);
- if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask))
- XkbSendMap(client,new,&mrep);
- if (reported&XkbGBN_CompatMapMask)
- XkbSendCompatMap(client,new->compat,&crep);
- if (reported&XkbGBN_IndicatorMapMask)
- XkbSendIndicatorMap(client,new->indicators,&irep);
- if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask))
- XkbSendNames(client,new,&nrep);
- if (reported&XkbGBN_GeometryMask)
- XkbSendGeometry(client,new->geom,&grep,FALSE);
- if (rep.loaded) {
- XkbDescPtr old_xkb;
- xkbNewKeyboardNotify nkn;
- int i,nG,nTG;
- old_xkb= xkb;
- xkb= new;
- dev->key->xkbInfo->desc= xkb;
- new= old_xkb; /* so it'll get freed automatically */
-
- *xkb->ctrls= *old_xkb->ctrls;
- for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
- nG= XkbKeyNumGroups(xkb,i);
- if (nG>=XkbNumKbdGroups) {
- nTG= XkbNumKbdGroups;
- break;
- }
- if (nG>nTG) {
- nTG= nG;
- }
- }
- xkb->ctrls->num_groups= nTG;
-
- for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
- if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
- if (tmpd != dev)
- XkbCopyDeviceKeymap(tmpd, dev);
-
- if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
- old_sli = tmpd->kbdfeed->xkb_sli;
- tmpd->kbdfeed->xkb_sli = NULL;
- sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0);
- if (sli) {
- sli->explicitState = old_sli->explicitState;
- sli->effectiveState = old_sli->effectiveState;
- }
- tmpd->kbdfeed->xkb_sli = sli;
- XkbFreeSrvLedInfo(old_sli);
- }
- }
- }
-
- nkn.deviceID= nkn.oldDeviceID= dev->id;
- nkn.minKeyCode= new->min_key_code;
- nkn.maxKeyCode= new->max_key_code;
- nkn.oldMinKeyCode= xkb->min_key_code;
- nkn.oldMaxKeyCode= xkb->max_key_code;
- nkn.requestMajor= XkbReqCode;
- nkn.requestMinor= X_kbGetKbdByName;
- nkn.changed= XkbNKN_KeycodesMask;
- if (geom_changed)
- nkn.changed|= XkbNKN_GeometryMask;
- XkbSendNewKeyboardNotify(dev,&nkn);
-
- if (!IsMaster(dev) && dev->u.master)
- {
- DeviceIntPtr master = dev->u.master;
- if (master->u.lastSlave == dev)
- {
- XkbCopyDeviceKeymap(dev->u.master, dev);
- XkbSendNewKeyboardNotify(dev,&nkn);
- }
- }
- }
- if ((new!=NULL)&&(new!=xkb)) {
- 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;
-}
-
-/***====================================================================***/
-
-static int
-ComputeDeviceLedInfoSize( DeviceIntPtr dev,
- unsigned int what,
- XkbSrvLedInfoPtr sli)
-{
-int nNames,nMaps;
-register unsigned n,bit;
-
- if (sli==NULL)
- return 0;
- nNames= nMaps= 0;
- if ((what&XkbXI_IndicatorNamesMask)==0)
- sli->namesPresent= 0;
- if ((what&XkbXI_IndicatorMapsMask)==0)
- sli->mapsPresent= 0;
-
- for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
- if (sli->names && sli->names[n]!=None) {
- sli->namesPresent|= bit;
- nNames++;
- }
- if (sli->maps && XkbIM_InUse(&sli->maps[n])) {
- sli->mapsPresent|= bit;
- nMaps++;
- }
- }
- return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc));
-}
-
-static int
-CheckDeviceLedFBs( DeviceIntPtr dev,
- int class,
- int id,
- xkbGetDeviceInfoReply * rep,
- ClientPtr client)
-{
-int nFBs= 0;
-int length= 0;
-Bool classOk;
-
- if (class==XkbDfltXIClass) {
- if (dev->kbdfeed) class= KbdFeedbackClass;
- else if (dev->leds) class= LedFeedbackClass;
- else {
- client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
- return XkbKeyboardErrorCode;
- }
- }
- classOk= FALSE;
- if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
- KbdFeedbackPtr kf;
- classOk= TRUE;
- for (kf= dev->kbdfeed;(kf);kf=kf->next) {
- if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id))
- continue;
- nFBs++;
- length+= SIZEOF(xkbDeviceLedsWireDesc);
- if (!kf->xkb_sli)
- kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0);
- length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli);
- if (id!=XkbAllXIIds)
- break;
- }
- }
- if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
- LedFeedbackPtr lf;
- classOk= TRUE;
- for (lf= dev->leds;(lf);lf=lf->next) {
- if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id))
- continue;
- nFBs++;
- length+= SIZEOF(xkbDeviceLedsWireDesc);
- if (!lf->xkb_sli)
- lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0);
- length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli);
- if (id!=XkbAllXIIds)
- break;
- }
- }
- if (nFBs>0) {
- rep->nDeviceLedFBs= nFBs;
- rep->length+= (length/4);
- return Success;
- }
- if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id);
- else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
- return XkbKeyboardErrorCode;
-}
-
-static int
-SendDeviceLedInfo( XkbSrvLedInfoPtr sli,
- ClientPtr client)
-{
-xkbDeviceLedsWireDesc wire;
-int length;
-
- length= 0;
- wire.ledClass= sli->class;
- wire.ledID= sli->id;
- wire.namesPresent= sli->namesPresent;
- wire.mapsPresent= sli->mapsPresent;
- wire.physIndicators= sli->physIndicators;
- wire.state= sli->effectiveState;
- if (client->swapped) {
- register int n;
- swaps(&wire.ledClass,n);
- swaps(&wire.ledID,n);
- swapl(&wire.namesPresent,n);
- swapl(&wire.mapsPresent,n);
- swapl(&wire.physIndicators,n);
- swapl(&wire.state,n);
- }
- WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire);
- length+= SIZEOF(xkbDeviceLedsWireDesc);
- if (sli->namesPresent|sli->mapsPresent) {
- register unsigned i,bit;
- if (sli->namesPresent) {
- CARD32 awire;
- for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
- if (sli->namesPresent&bit) {
- awire= (CARD32)sli->names[i];
- if (client->swapped) {
- register int n;
- swapl(&awire,n);
- }
- WriteToClient(client,4,(char *)&awire);
- length+= 4;
- }
- }
- }
- if (sli->mapsPresent) {
- for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
- xkbIndicatorMapWireDesc iwire;
- if (sli->mapsPresent&bit) {
- iwire.flags= sli->maps[i].flags;
- iwire.whichGroups= sli->maps[i].which_groups;
- iwire.groups= sli->maps[i].groups;
- iwire.whichMods= sli->maps[i].which_mods;
- iwire.mods= sli->maps[i].mods.mask;
- iwire.realMods= sli->maps[i].mods.real_mods;
- iwire.virtualMods= sli->maps[i].mods.vmods;
- iwire.ctrls= sli->maps[i].ctrls;
- if (client->swapped) {
- register int n;
- swaps(&iwire.virtualMods,n);
- swapl(&iwire.ctrls,n);
- }
- WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc),
- (char *)&iwire);
- length+= SIZEOF(xkbIndicatorMapWireDesc);
- }
- }
- }
- }
- return length;
-}
-
-static int
-SendDeviceLedFBs( DeviceIntPtr dev,
- int class,
- int id,
- unsigned wantLength,
- ClientPtr client)
-{
-int length= 0;
-
- if (class==XkbDfltXIClass) {
- if (dev->kbdfeed) class= KbdFeedbackClass;
- else if (dev->leds) class= LedFeedbackClass;
- }
- if ((dev->kbdfeed)&&
- ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
- KbdFeedbackPtr kf;
- for (kf= dev->kbdfeed;(kf);kf=kf->next) {
- if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) {
- length+= SendDeviceLedInfo(kf->xkb_sli,client);
- if (id!=XkbAllXIIds)
- break;
- }
- }
- }
- if ((dev->leds)&&
- ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
- LedFeedbackPtr lf;
- for (lf= dev->leds;(lf);lf=lf->next) {
- if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) {
- length+= SendDeviceLedInfo(lf->xkb_sli,client);
- if (id!=XkbAllXIIds)
- break;
- }
- }
- }
- if (length==wantLength)
- return Success;
- else return BadLength;
-}
-
-int
-ProcXkbGetDeviceInfo(ClientPtr client)
-{
-DeviceIntPtr dev;
-xkbGetDeviceInfoReply rep;
-int status,nDeviceLedFBs;
-unsigned length,nameLen;
-CARD16 ledClass,ledID;
-unsigned wanted;
-char * str;
-
- REQUEST(xkbGetDeviceInfoReq);
- REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- wanted= stuff->wanted;
-
- CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
- CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask);
-
- if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns)))
- wanted&= ~XkbXI_ButtonActionsMask;
- if ((!dev->kbdfeed)&&(!dev->leds))
- wanted&= ~XkbXI_IndicatorsMask;
-
- nameLen= XkbSizeCountedString(dev->name);
- bzero((char *)&rep,SIZEOF(xkbGetDeviceInfoReply));
- rep.type = X_Reply;
- rep.deviceID= dev->id;
- rep.sequenceNumber = client->sequence;
- rep.length = nameLen/4;
- rep.present = wanted;
- rep.supported = XkbXI_AllDeviceFeaturesMask;
- rep.unsupported = 0;
- rep.firstBtnWanted = rep.nBtnsWanted = 0;
- rep.firstBtnRtrn = rep.nBtnsRtrn = 0;
- if (dev->button)
- rep.totalBtns= dev->button->numButtons;
- else rep.totalBtns= 0;
- rep.devType= dev->xinput_type;
- rep.hasOwnState= (dev->key && dev->key->xkbInfo);
- rep.nDeviceLedFBs = 0;
- if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id;
- else rep.dfltKbdFB= XkbXINone;
- if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id;
- else rep.dfltLedFB= XkbXINone;
-
- ledClass= stuff->ledClass;
- ledID= stuff->ledID;
-
- rep.firstBtnWanted= rep.nBtnsWanted= 0;
- rep.firstBtnRtrn= rep.nBtnsRtrn= 0;
- if (wanted&XkbXI_ButtonActionsMask) {
- if (stuff->allBtns) {
- stuff->firstBtn= 0;
- stuff->nBtns= dev->button->numButtons;
- }
-
- if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
- client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons,
- stuff->firstBtn,
- stuff->nBtns);
- return BadValue;
- }
- else {
- rep.firstBtnWanted= stuff->firstBtn;
- rep.nBtnsWanted= stuff->nBtns;
- if (dev->button->xkb_acts!=NULL) {
- XkbAction *act;
- register int i;
-
- rep.firstBtnRtrn= stuff->firstBtn;
- rep.nBtnsRtrn= stuff->nBtns;
- act= &dev->button->xkb_acts[rep.firstBtnWanted];
- for (i=0;i<rep.nBtnsRtrn;i++,act++) {
- if (act->type!=XkbSA_NoAction)
- break;
- }
- rep.firstBtnRtrn+= i;
- rep.nBtnsRtrn-= i;
- act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1];
- for (i=0;i<rep.nBtnsRtrn;i++,act--) {
- if (act->type!=XkbSA_NoAction)
- break;
- }
- rep.nBtnsRtrn-= i;
- }
- rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4;
- }
- }
-
- if (wanted&XkbXI_IndicatorsMask) {
- status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client);
- if (status!=Success)
- return status;
- }
- length= rep.length*4;
- nDeviceLedFBs = rep.nDeviceLedFBs;
- if (client->swapped) {
- register int n;
- swaps(&rep.sequenceNumber,n);
- swapl(&rep.length,n);
- swaps(&rep.present,n);
- swaps(&rep.supported,n);
- swaps(&rep.unsupported,n);
- swaps(&rep.nDeviceLedFBs,n);
- swapl(&rep.type,n);
- }
- WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep);
-
- str= xalloc(nameLen);
- if (!str)
- return BadAlloc;
- XkbWriteCountedString(str,dev->name,client->swapped);
- WriteToClient(client,nameLen,str);
- xfree(str);
- length-= nameLen;
-
- if (rep.nBtnsRtrn>0) {
- int sz;
- xkbActionWireDesc * awire;
- sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc);
- awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn];
- WriteToClient(client,sz,(char *)awire);
- length-= sz;
- }
- if (nDeviceLedFBs>0) {
- status= SendDeviceLedFBs(dev,ledClass,ledID,length,client);
- if (status!=Success)
- return status;
- }
- else if (length!=0) {
- ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n");
- ErrorF("[xkb] Wrote %d fewer bytes than expected\n",length);
- return BadLength;
- }
- return client->noClientException;
-}
-
-static char *
-CheckSetDeviceIndicators( char * wire,
- DeviceIntPtr dev,
- int num,
- int * status_rtrn,
- ClientPtr client)
-{
-xkbDeviceLedsWireDesc * ledWire;
-int i;
-XkbSrvLedInfoPtr sli;
-
- ledWire= (xkbDeviceLedsWireDesc *)wire;
- for (i=0;i<num;i++) {
- if (client->swapped) {
- register int n;
- swaps(&ledWire->ledClass,n);
- swaps(&ledWire->ledID,n);
- swapl(&ledWire->namesPresent,n);
- swapl(&ledWire->mapsPresent,n);
- swapl(&ledWire->physIndicators,n);
- }
-
- sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
- XkbXI_IndicatorsMask);
- if (sli!=NULL) {
- register int n;
- register unsigned bit;
- int nMaps,nNames;
- CARD32 *atomWire;
- xkbIndicatorMapWireDesc *mapWire;
-
- nMaps= nNames= 0;
- for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
- if (ledWire->namesPresent&bit)
- nNames++;
- if (ledWire->mapsPresent&bit)
- nMaps++;
- }
- atomWire= (CARD32 *)&ledWire[1];
- if (nNames>0) {
- for (n=0;n<nNames;n++) {
- if (client->swapped) {
- register int t;
- swapl(atomWire,t);
- }
- CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue,
- *status_rtrn,NULL);
- atomWire++;
- }
- }
- mapWire= (xkbIndicatorMapWireDesc *)atomWire;
- if (nMaps>0) {
- for (n=0;n<nMaps;n++) {
- if (client->swapped) {
- register int t;
- swaps(&mapWire->virtualMods,t);
- swapl(&mapWire->ctrls,t);
- }
- CHK_MASK_LEGAL3(0x21,mapWire->whichGroups,
- XkbIM_UseAnyGroup,
- client->errorValue,
- *status_rtrn,NULL);
- CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods,
- client->errorValue,
- *status_rtrn,NULL);
- mapWire++;
- }
- }
- ledWire= (xkbDeviceLedsWireDesc *)mapWire;
- }
- else {
- /* SHOULD NEVER HAPPEN */
- return (char *)ledWire;
- }
- }
- return (char *)ledWire;
-}
-
-static char *
-SetDeviceIndicators( char * wire,
- DeviceIntPtr dev,
- unsigned changed,
- int num,
- int * status_rtrn,
- ClientPtr client,
- xkbExtensionDeviceNotify *ev)
-{
-xkbDeviceLedsWireDesc * ledWire;
-int i;
-XkbEventCauseRec cause;
-unsigned namec,mapc,statec;
-xkbExtensionDeviceNotify ed;
-XkbChangesRec changes;
-DeviceIntPtr kbd;
-
- bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
- bzero((char *)&changes,sizeof(XkbChangesRec));
- XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client);
- ledWire= (xkbDeviceLedsWireDesc *)wire;
- for (i=0;i<num;i++) {
- register int n;
- register unsigned bit;
- CARD32 * atomWire;
- xkbIndicatorMapWireDesc * mapWire;
- XkbSrvLedInfoPtr sli;
-
- namec= mapc= statec= 0;
- sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
- XkbXI_IndicatorMapsMask);
- if (!sli) {
- /* SHOULD NEVER HAPPEN!! */
- return (char *)ledWire;
- }
-
- atomWire= (CARD32 *)&ledWire[1];
- if (changed&XkbXI_IndicatorNamesMask) {
- namec= sli->namesPresent|ledWire->namesPresent;
- bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
- }
- if (ledWire->namesPresent) {
- sli->namesPresent= ledWire->namesPresent;
- bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
- for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
- if (ledWire->namesPresent&bit) {
- sli->names[n]= (Atom)*atomWire;
- if (sli->names[n]==None)
- ledWire->namesPresent&= ~bit;
- atomWire++;
- }
- }
- }
- mapWire= (xkbIndicatorMapWireDesc *)atomWire;
- if (changed&XkbXI_IndicatorMapsMask) {
- mapc= sli->mapsPresent|ledWire->mapsPresent;
- sli->mapsPresent= ledWire->mapsPresent;
- bzero((char*)sli->maps,XkbNumIndicators*sizeof(XkbIndicatorMapRec));
- }
- if (ledWire->mapsPresent) {
- for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
- if (ledWire->mapsPresent&bit) {
- sli->maps[n].flags= mapWire->flags;
- sli->maps[n].which_groups= mapWire->whichGroups;
- sli->maps[n].groups= mapWire->groups;
- sli->maps[n].which_mods= mapWire->whichMods;
- sli->maps[n].mods.mask= mapWire->mods;
- sli->maps[n].mods.real_mods=mapWire->realMods;
- sli->maps[n].mods.vmods= mapWire->virtualMods;
- sli->maps[n].ctrls= mapWire->ctrls;
- mapWire++;
- }
- }
- }
- if (changed&XkbXI_IndicatorStateMask) {
- statec= sli->effectiveState^ledWire->state;
- sli->explicitState&= ~statec;
- sli->explicitState|= (ledWire->state&statec);
- }
- if (namec)
- XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
- if (mapc)
- XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
- if (statec)
- XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
-
- kbd= dev;
- if ((sli->flags&XkbSLI_HasOwnState)==0)
- kbd = inputInfo.keyboard;
-
- XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause);
- ledWire= (xkbDeviceLedsWireDesc *)mapWire;
- }
- return (char *)ledWire;
-}
-
-
-static int
-_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev,
- xkbSetDeviceInfoReq *stuff)
-{
- char *wire;
-
- wire= (char *)&stuff[1];
- if (stuff->change&XkbXI_ButtonActionsMask) {
- if (!dev->button) {
- client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass);
- return XkbKeyboardErrorCode;
- }
- if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
- client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns,
- dev->button->numButtons);
- return BadMatch;
- }
- wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc));
- }
- if (stuff->change&XkbXI_IndicatorsMask) {
- int status= Success;
- wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs,
- &status,client);
- if (status!=Success)
- return status;
- }
- if (((wire-((char *)stuff))/4)!=stuff->length)
- return BadLength;
-
- return Success;
-}
-
-static int
-_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
- xkbSetDeviceInfoReq *stuff)
-{
- char *wire;
- xkbExtensionDeviceNotify ed;
-
- bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
- ed.deviceID= dev->id;
- wire= (char *)&stuff[1];
- if (stuff->change&XkbXI_ButtonActionsMask) {
- int nBtns,sz,i;
- XkbAction * acts;
- DeviceIntPtr kbd;
-
- nBtns= dev->button->numButtons;
- acts= dev->button->xkb_acts;
- if (acts==NULL) {
- acts= xcalloc(nBtns, sizeof(XkbAction));
- if (!acts)
- return BadAlloc;
- dev->button->xkb_acts= acts;
- }
- sz= stuff->nBtns*SIZEOF(xkbActionWireDesc);
- memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz);
- wire+= sz;
- ed.reason|= XkbXI_ButtonActionsMask;
- ed.firstBtn= stuff->firstBtn;
- ed.nBtns= stuff->nBtns;
-
- if (dev->key) kbd= dev;
- else kbd= inputInfo.keyboard;
- acts= &dev->button->xkb_acts[stuff->firstBtn];
- for (i=0;i<stuff->nBtns;i++,acts++) {
- if (acts->type!=XkbSA_NoAction)
- XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0);
- }
- }
- if (stuff->change&XkbXI_IndicatorsMask) {
- int status= Success;
- wire= SetDeviceIndicators(wire,dev,stuff->change,
- stuff->nDeviceLedFBs, &status,client,&ed);
- if (status!=Success)
- return status;
- }
- if ((stuff->change)&&(ed.reason))
- XkbSendExtensionDeviceNotify(dev,client,&ed);
- return Success;
-}
-
-int
-ProcXkbSetDeviceInfo(ClientPtr client)
-{
- DeviceIntPtr dev;
- int rc;
-
- REQUEST(xkbSetDeviceInfoReq);
- REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
-
- CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
- CHK_MASK_LEGAL(0x01,stuff->change,XkbXI_AllFeaturesMask);
-
- rc = _XkbSetDeviceInfoCheck(client, dev, stuff);
-
- if (rc != Success)
- return rc;
-
- if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if (((other != dev) && !IsMaster(other) && (other->u.master == dev)) &&
- ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
- (stuff->deviceSpec == XkbUseCorePtr && other->button)))
- {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
- if (rc == Success)
- {
- rc = _XkbSetDeviceInfoCheck(client, other, stuff);
- if (rc != Success)
- return rc;
- }
- }
- }
- }
-
- /* checks done, apply */
- rc = _XkbSetDeviceInfo(client, dev, stuff);
- if (rc != Success)
- return rc;
-
- if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr)
- {
- DeviceIntPtr other;
- for (other = inputInfo.devices; other; other = other->next)
- {
- if (((other != dev) && !IsMaster(other) && (other->u.master == dev)) &&
- ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
- (stuff->deviceSpec == XkbUseCorePtr && other->button)))
- {
- rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
- if (rc == Success)
- {
- rc = _XkbSetDeviceInfo(client, other, stuff);
- if (rc != Success)
- return rc;
- }
- }
- }
- }
-
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-int
-ProcXkbSetDebuggingFlags(ClientPtr client)
-{
-CARD32 newFlags,newCtrls,extraLength;
-xkbSetDebuggingFlagsReply rep;
-int rc;
-
- REQUEST(xkbSetDebuggingFlagsReq);
- REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq);
-
- rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess);
- if (rc != Success)
- return rc;
-
- newFlags= xkbDebugFlags&(~stuff->affectFlags);
- newFlags|= (stuff->flags&stuff->affectFlags);
- newCtrls= xkbDebugCtrls&(~stuff->affectCtrls);
- newCtrls|= (stuff->ctrls&stuff->affectCtrls);
- if (xkbDebugFlags || newFlags || stuff->msgLength) {
- ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags);
- if (newCtrls!=xkbDebugCtrls)
- ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls);
- }
- extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq;
- if (stuff->msgLength>0) {
- char *msg;
- if (extraLength<XkbPaddedSize(stuff->msgLength)) {
- ErrorF("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n",
- stuff->msgLength,(long)extraLength,
- XkbPaddedSize(stuff->msgLength));
- return BadLength;
- }
- msg= (char *)&stuff[1];
- if (msg[stuff->msgLength-1]!='\0') {
- ErrorF("[xkb] XkbDebug: message not null-terminated\n");
- return BadValue;
- }
- ErrorF("[xkb] XkbDebug: %s\n",msg);
- }
- xkbDebugFlags = newFlags;
- xkbDebugCtrls = newCtrls;
-
- rep.type= X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.currentFlags = newFlags;
- rep.currentCtrls = newCtrls;
- rep.supportedFlags = ~0;
- rep.supportedCtrls = ~0;
- if ( client->swapped ) {
- register int n;
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.currentFlags, n);
- swapl(&rep.currentCtrls, n);
- swapl(&rep.supportedFlags, n);
- swapl(&rep.supportedCtrls, n);
- }
- WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep);
- return client->noClientException;
-}
-
-/***====================================================================***/
-
-static int
-ProcXkbDispatch (ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data)
- {
- case X_kbUseExtension:
- return ProcXkbUseExtension(client);
- case X_kbSelectEvents:
- return ProcXkbSelectEvents(client);
- case X_kbBell:
- return ProcXkbBell(client);
- case X_kbGetState:
- return ProcXkbGetState(client);
- case X_kbLatchLockState:
- return ProcXkbLatchLockState(client);
- case X_kbGetControls:
- return ProcXkbGetControls(client);
- case X_kbSetControls:
- return ProcXkbSetControls(client);
- case X_kbGetMap:
- return ProcXkbGetMap(client);
- case X_kbSetMap:
- return ProcXkbSetMap(client);
- case X_kbGetCompatMap:
- return ProcXkbGetCompatMap(client);
- case X_kbSetCompatMap:
- return ProcXkbSetCompatMap(client);
- case X_kbGetIndicatorState:
- return ProcXkbGetIndicatorState(client);
- case X_kbGetIndicatorMap:
- return ProcXkbGetIndicatorMap(client);
- case X_kbSetIndicatorMap:
- return ProcXkbSetIndicatorMap(client);
- case X_kbGetNamedIndicator:
- return ProcXkbGetNamedIndicator(client);
- case X_kbSetNamedIndicator:
- return ProcXkbSetNamedIndicator(client);
- case X_kbGetNames:
- return ProcXkbGetNames(client);
- case X_kbSetNames:
- return ProcXkbSetNames(client);
- case X_kbGetGeometry:
- return ProcXkbGetGeometry(client);
- case X_kbSetGeometry:
- return ProcXkbSetGeometry(client);
- case X_kbPerClientFlags:
- return ProcXkbPerClientFlags(client);
- case X_kbListComponents:
- return ProcXkbListComponents(client);
- case X_kbGetKbdByName:
- return ProcXkbGetKbdByName(client);
- case X_kbGetDeviceInfo:
- return ProcXkbGetDeviceInfo(client);
- case X_kbSetDeviceInfo:
- return ProcXkbSetDeviceInfo(client);
- case X_kbSetDebuggingFlags:
- return ProcXkbSetDebuggingFlags(client);
- default:
- return BadRequest;
- }
-}
-
-static int
-XkbClientGone(pointer data,XID id)
-{
- DevicePtr pXDev = (DevicePtr)data;
-
- if (!XkbRemoveResourceClient(pXDev,id)) {
- ErrorF("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n");
- }
- return 1;
-}
-
-void
-XkbExtensionInit(void)
-{
- ExtensionEntry *extEntry;
-
- RT_XKBCLIENT = CreateNewResourceType(XkbClientGone, "XkbClient");
- if (!RT_XKBCLIENT)
- return;
-
- if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors,
- ProcXkbDispatch, SProcXkbDispatch,
- NULL, StandardMinorOpcode))) {
- XkbReqCode = (unsigned char)extEntry->base;
- XkbEventBase = (unsigned char)extEntry->eventBase;
- XkbErrorBase = (unsigned char)extEntry->errorBase;
- XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard;
- }
- 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"
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+#include "extnsionst.h"
+#include "xace.h"
+#include "xkb.h"
+#include "protocol-versions.h"
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XKMformat.h>
+
+int XkbEventBase;
+static int XkbErrorBase;
+int XkbReqCode;
+int XkbKeyboardErrorCode;
+CARD32 xkbDebugFlags = 0;
+static CARD32 xkbDebugCtrls = 0;
+
+static RESTYPE RT_XKBCLIENT;
+
+/***====================================================================***/
+
+#define CHK_DEVICE(dev, id, client, access_mode, lf) {\
+ int why;\
+ int rc = lf(&(dev), id, client, access_mode, &why);\
+ if (rc != Success) {\
+ client->errorValue = _XkbErrCode2(why, id);\
+ return rc;\
+ }\
+}
+
+#define CHK_KBD_DEVICE(dev, id, client, mode) \
+ CHK_DEVICE(dev, id, client, mode, _XkbLookupKeyboard)
+#define CHK_LED_DEVICE(dev, id, client, mode) \
+ CHK_DEVICE(dev, id, client, mode, _XkbLookupLedDevice)
+#define CHK_BELL_DEVICE(dev, id, client, mode) \
+ CHK_DEVICE(dev, id, client, mode, _XkbLookupBellDevice)
+#define CHK_ANY_DEVICE(dev, id, client, mode) \
+ CHK_DEVICE(dev, id, client, mode, _XkbLookupAnyDevice)
+
+#define CHK_ATOM_ONLY2(a,ev,er) {\
+ if (((a)==None)||(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ return er;\
+ }\
+}
+#define CHK_ATOM_ONLY(a) \
+ CHK_ATOM_ONLY2(a,client->errorValue,BadAtom)
+
+#define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\
+ if (((a)!=None)&&(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ (er)= BadAtom;\
+ return ret;\
+ }\
+}
+#define CHK_ATOM_OR_NONE2(a,ev,er) {\
+ if (((a)!=None)&&(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ return er;\
+ }\
+}
+#define CHK_ATOM_OR_NONE(a) \
+ CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom)
+
+#define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\
+ if ((mask)&(~(legal))) { \
+ (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
+ (er)= BadValue;\
+ return ret;\
+ }\
+}
+#define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\
+ if ((mask)&(~(legal))) { \
+ (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
+ return er;\
+ }\
+}
+#define CHK_MASK_LEGAL(err,mask,legal) \
+ CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue)
+
+#define CHK_MASK_MATCH(err,affect,value) {\
+ if ((value)&(~(affect))) { \
+ client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\
+ return BadMatch;\
+ }\
+}
+#define CHK_MASK_OVERLAP(err,m1,m2) {\
+ if ((m1)&(m2)) { \
+ client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\
+ return BadMatch;\
+ }\
+}
+#define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\
+ if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\
+ (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\
+ return er;\
+ }\
+ else if ( (first)<(x)->min_key_code ) {\
+ (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\
+ return er;\
+ }\
+}
+#define CHK_KEY_RANGE(err,first,num,x) \
+ CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue)
+
+#define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\
+ if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\
+ (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\
+ return er;\
+ }\
+ else if ( (first)<(r)->minKeyCode ) {\
+ (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\
+ return er;\
+ }\
+}
+#define CHK_REQ_KEY_RANGE(err,first,num,r) \
+ CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue)
+
+/***====================================================================***/
+
+int
+ProcXkbUseExtension(ClientPtr client)
+{
+ REQUEST(xkbUseExtensionReq);
+ xkbUseExtensionReply rep;
+ register int n;
+ int supported;
+
+ REQUEST_SIZE_MATCH(xkbUseExtensionReq);
+ if (stuff->wantedMajor != SERVER_XKB_MAJOR_VERSION) {
+ /* pre-release version 0.65 is compatible with 1.00 */
+ supported= ((SERVER_XKB_MAJOR_VERSION==1)&&
+ (stuff->wantedMajor==0)&&(stuff->wantedMinor==65));
+ }
+ else supported = 1;
+
+ if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) {
+ client->xkbClientFlags= _XkbClientInitialized;
+ client->vMajor= stuff->wantedMajor;
+ client->vMinor= stuff->wantedMinor;
+ }
+ else if (xkbDebugFlags&0x1) {
+ ErrorF("[xkb] Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n",
+ client->index,
+ (long)client->clientAsMask,
+ stuff->wantedMajor,stuff->wantedMinor,
+ SERVER_XKB_MAJOR_VERSION,SERVER_XKB_MINOR_VERSION);
+ }
+ memset(&rep, 0, sizeof(xkbUseExtensionReply));
+ rep.type = X_Reply;
+ rep.supported = supported;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.serverMajor = SERVER_XKB_MAJOR_VERSION;
+ rep.serverMinor = SERVER_XKB_MINOR_VERSION;
+ if ( client->swapped ) {
+ swaps(&rep.sequenceNumber, n);
+ swaps(&rep.serverMajor, n);
+ swaps(&rep.serverMinor, n);
+ }
+ WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep);
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbSelectEvents(ClientPtr client)
+{
+ unsigned legal;
+ DeviceIntPtr dev;
+ XkbInterestPtr masks;
+ REQUEST(xkbSelectEventsReq);
+
+ REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixUseAccess);
+
+ if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) {
+ client->mapNotifyMask&= ~stuff->affectMap;
+ client->mapNotifyMask|= (stuff->affectMap&stuff->map);
+ }
+ if ((stuff->affectWhich&(~XkbMapNotifyMask))==0)
+ return Success;
+
+ masks = XkbFindClientResource((DevicePtr)dev,client);
+ if (!masks){
+ XID id = FakeClientID(client->index);
+ AddResource(id,RT_XKBCLIENT,dev);
+ masks= XkbAddClientResource((DevicePtr)dev,client,id);
+ }
+ if (masks) {
+ union {
+ CARD8 *c8;
+ CARD16 *c16;
+ CARD32 *c32;
+ } from,to;
+ register unsigned bit,ndx,maskLeft,dataLeft,size;
+
+ from.c8= (CARD8 *)&stuff[1];
+ dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq);
+ maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask));
+ for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) {
+ if ((bit&maskLeft)==0)
+ continue;
+ maskLeft&= ~bit;
+ switch (ndx) {
+ case XkbNewKeyboardNotify:
+ to.c16= &client->newKeyboardNotifyMask;
+ legal= XkbAllNewKeyboardEventsMask;
+ size= 2;
+ break;
+ case XkbStateNotify:
+ to.c16= &masks->stateNotifyMask;
+ legal= XkbAllStateEventsMask;
+ size= 2;
+ break;
+ case XkbControlsNotify:
+ to.c32= &masks->ctrlsNotifyMask;
+ legal= XkbAllControlEventsMask;
+ size= 4;
+ break;
+ case XkbIndicatorStateNotify:
+ to.c32= &masks->iStateNotifyMask;
+ legal= XkbAllIndicatorEventsMask;
+ size= 4;
+ break;
+ case XkbIndicatorMapNotify:
+ to.c32= &masks->iMapNotifyMask;
+ legal= XkbAllIndicatorEventsMask;
+ size= 4;
+ break;
+ case XkbNamesNotify:
+ to.c16= &masks->namesNotifyMask;
+ legal= XkbAllNameEventsMask;
+ size= 2;
+ break;
+ case XkbCompatMapNotify:
+ to.c8= &masks->compatNotifyMask;
+ legal= XkbAllCompatMapEventsMask;
+ size= 1;
+ break;
+ case XkbBellNotify:
+ to.c8= &masks->bellNotifyMask;
+ legal= XkbAllBellEventsMask;
+ size= 1;
+ break;
+ case XkbActionMessage:
+ to.c8= &masks->actionMessageMask;
+ legal= XkbAllActionMessagesMask;
+ size= 1;
+ break;
+ case XkbAccessXNotify:
+ to.c16= &masks->accessXNotifyMask;
+ legal= XkbAllAccessXEventsMask;
+ size= 2;
+ break;
+ case XkbExtensionDeviceNotify:
+ to.c16= &masks->extDevNotifyMask;
+ legal= XkbAllExtensionDeviceEventsMask;
+ size= 2;
+ break;
+ default:
+ client->errorValue = _XkbErrCode2(33,bit);
+ return BadValue;
+ }
+
+ if (stuff->clear&bit) {
+ if (size==2) to.c16[0]= 0;
+ else if (size==4) to.c32[0]= 0;
+ else to.c8[0]= 0;
+ }
+ else if (stuff->selectAll&bit) {
+ if (size==2) to.c16[0]= ~0;
+ else if (size==4) to.c32[0]= ~0;
+ else to.c8[0]= ~0;
+ }
+ else {
+ if (dataLeft<(size*2))
+ return BadLength;
+ if (size==2) {
+ CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]);
+ CHK_MASK_LEGAL(ndx,from.c16[0],legal);
+ to.c16[0]&= ~from.c16[0];
+ to.c16[0]|= (from.c16[0]&from.c16[1]);
+ }
+ else if (size==4) {
+ CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]);
+ CHK_MASK_LEGAL(ndx,from.c32[0],legal);
+ to.c32[0]&= ~from.c32[0];
+ to.c32[0]|= (from.c32[0]&from.c32[1]);
+ }
+ else {
+ CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]);
+ CHK_MASK_LEGAL(ndx,from.c8[0],legal);
+ to.c8[0]&= ~from.c8[0];
+ to.c8[0]|= (from.c8[0]&from.c8[1]);
+ size= 2;
+ }
+ from.c8+= (size*2);
+ dataLeft-= (size*2);
+ }
+ }
+ if (dataLeft>2) {
+ ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",dataLeft);
+ return BadLength;
+ }
+ return Success;
+ }
+ return BadAlloc;
+}
+
+/***====================================================================***/
+/**
+ * Ring a bell on the given device for the given client.
+ */
+static int
+_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin,
+ int bellClass, int bellID, int pitch, int duration,
+ int percent, int forceSound, int eventOnly, Atom name)
+{
+ int base;
+ pointer ctrl;
+ int oldPitch, oldDuration;
+ int newPercent;
+
+ if (bellClass == KbdFeedbackClass) {
+ KbdFeedbackPtr k;
+ if (bellID==XkbDfltXIId)
+ k= dev->kbdfeed;
+ else {
+ for (k=dev->kbdfeed; k; k=k->next) {
+ if (k->ctrl.id == bellID)
+ break;
+ }
+ }
+ if (!k) {
+ client->errorValue = _XkbErrCode2(0x5,bellID);
+ return BadValue;
+ }
+ base = k->ctrl.bell;
+ ctrl = (pointer) &(k->ctrl);
+ oldPitch= k->ctrl.bell_pitch;
+ oldDuration= k->ctrl.bell_duration;
+ if (pitch!=0) {
+ if (pitch==-1)
+ k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch;
+ else k->ctrl.bell_pitch= pitch;
+ }
+ if (duration!=0) {
+ if (duration==-1)
+ k->ctrl.bell_duration= defaultKeyboardControl.bell_duration;
+ else k->ctrl.bell_duration= duration;
+ }
+ }
+ else if (bellClass == BellFeedbackClass) {
+ BellFeedbackPtr b;
+ if (bellID==XkbDfltXIId)
+ b= dev->bell;
+ else {
+ for (b=dev->bell; b; b=b->next) {
+ if (b->ctrl.id == bellID)
+ break;
+ }
+ }
+ if (!b) {
+ client->errorValue = _XkbErrCode2(0x6,bellID);
+ return BadValue;
+ }
+ base = b->ctrl.percent;
+ ctrl = (pointer) &(b->ctrl);
+ oldPitch= b->ctrl.pitch;
+ oldDuration= b->ctrl.duration;
+ if (pitch!=0) {
+ if (pitch==-1)
+ b->ctrl.pitch= defaultKeyboardControl.bell_pitch;
+ else b->ctrl.pitch= pitch;
+ }
+ if (duration!=0) {
+ if (duration==-1)
+ b->ctrl.duration= defaultKeyboardControl.bell_duration;
+ else b->ctrl.duration= duration;
+ }
+ }
+ else {
+ client->errorValue = _XkbErrCode2(0x7, bellClass);
+ return BadValue;
+ }
+
+ newPercent = (base * percent)/100;
+ if (percent < 0)
+ newPercent = base + newPercent;
+ else newPercent = base - newPercent + percent;
+
+ XkbHandleBell(forceSound, eventOnly,
+ dev, newPercent, ctrl, bellClass,
+ name, pWin, client);
+ if ((pitch!=0)||(duration!=0)) {
+ if (bellClass == KbdFeedbackClass) {
+ KbdFeedbackPtr k;
+ k= (KbdFeedbackPtr)ctrl;
+ if (pitch!=0)
+ k->ctrl.bell_pitch= oldPitch;
+ if (duration!=0)
+ k->ctrl.bell_duration= oldDuration;
+ }
+ else {
+ BellFeedbackPtr b;
+ b= (BellFeedbackPtr)ctrl;
+ if (pitch!=0)
+ b->ctrl.pitch= oldPitch;
+ if (duration!=0)
+ b->ctrl.duration= oldDuration;
+ }
+ }
+
+ return Success;
+}
+
+int
+ProcXkbBell(ClientPtr client)
+{
+ REQUEST(xkbBellReq);
+ DeviceIntPtr dev;
+ WindowPtr pWin;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xkbBellReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ /* device-independent checks request for sane values */
+ if ((stuff->forceSound)&&(stuff->eventOnly)) {
+ client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly);
+ return BadMatch;
+ }
+ if (stuff->percent < -100 || stuff->percent > 100) {
+ client->errorValue = _XkbErrCode2(0x2,stuff->percent);
+ return BadValue;
+ }
+ if (stuff->duration<-1) {
+ client->errorValue = _XkbErrCode2(0x3,stuff->duration);
+ return BadValue;
+ }
+ if (stuff->pitch<-1) {
+ client->errorValue = _XkbErrCode2(0x4,stuff->pitch);
+ return BadValue;
+ }
+
+ if (stuff->bellClass == XkbDfltXIClass) {
+ if (dev->kbdfeed!=NULL)
+ stuff->bellClass= KbdFeedbackClass;
+ else stuff->bellClass= BellFeedbackClass;
+ }
+
+ if (stuff->window!=None) {
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success) {
+ client->errorValue= stuff->window;
+ return rc;
+ }
+ }
+ else pWin= NULL;
+
+ /* Client wants to ring a bell on the core keyboard?
+ Ring the bell on the core keyboard (which does nothing, but if that
+ fails the client is screwed anyway), and then on all extension devices.
+ Fail if the core keyboard fails but not the extension devices. this
+ may cause some keyboards to ding and others to stay silent. Fix
+ your client to use explicit keyboards to avoid this.
+
+ dev is the device the client requested.
+ */
+ rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID,
+ stuff->pitch, stuff->duration, stuff->percent,
+ stuff->forceSound, stuff->eventOnly, stuff->name);
+
+ if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) ||
+ (stuff->deviceSpec == XkbUseCorePtr)))
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess);
+ if (rc == Success)
+ _XkbBell(client, other, pWin, stuff->bellClass,
+ stuff->bellID, stuff->pitch, stuff->duration,
+ stuff->percent, stuff->forceSound,
+ stuff->eventOnly, stuff->name);
+ }
+ }
+ rc = Success; /* reset to success, that's what we got for the VCK */
+ }
+
+ return rc;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetState(ClientPtr client)
+{
+ REQUEST(xkbGetStateReq);
+ DeviceIntPtr dev;
+ xkbGetStateReply rep;
+ XkbStateRec *xkb;
+
+ REQUEST_SIZE_MATCH(xkbGetStateReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+
+ xkb= &dev->key->xkbInfo->state;
+ bzero(&rep,sizeof(xkbGetStateReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.mods = XkbStateFieldFromRec(xkb) & 0xff;
+ rep.baseMods = xkb->base_mods;
+ rep.lockedMods = xkb->locked_mods;
+ rep.latchedMods = xkb->latched_mods;
+ rep.group = xkb->group;
+ rep.baseGroup = xkb->base_group;
+ rep.latchedGroup = xkb->latched_group;
+ rep.lockedGroup = xkb->locked_group;
+ rep.compatState = xkb->compat_state;
+ rep.ptrBtnState = xkb->ptr_buttons;
+ if (client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swaps(&rep.ptrBtnState,n);
+ }
+ WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep);
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbLatchLockState(ClientPtr client)
+{
+ int status;
+ DeviceIntPtr dev, tmpd;
+ XkbStateRec oldState,*newState;
+ CARD16 changed;
+ xkbStateNotify sn;
+ XkbEventCauseRec cause;
+
+ REQUEST(xkbLatchLockStateReq);
+ REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
+
+ if (!(client->xkbClientFlags & _XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
+ CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks);
+ CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches);
+
+ status = Success;
+
+ for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
+ if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
+ if (!tmpd->key || !tmpd->key->xkbInfo)
+ continue;
+
+ oldState = tmpd->key->xkbInfo->state;
+ newState = &tmpd->key->xkbInfo->state;
+ if (stuff->affectModLocks) {
+ newState->locked_mods &= ~stuff->affectModLocks;
+ newState->locked_mods |= (stuff->affectModLocks & stuff->modLocks);
+ }
+ if (status == Success && stuff->lockGroup)
+ newState->locked_group = stuff->groupLock;
+ if (status == Success && stuff->affectModLatches)
+ status = XkbLatchModifiers(tmpd, stuff->affectModLatches,
+ stuff->modLatches);
+ if (status == Success && stuff->latchGroup)
+ status = XkbLatchGroup(tmpd, stuff->groupLatch);
+
+ if (status != Success)
+ return status;
+
+ XkbComputeDerivedState(tmpd->key->xkbInfo);
+
+ changed = XkbStateChangedFlags(&oldState, newState);
+ if (changed) {
+ sn.keycode = 0;
+ sn.eventType = 0;
+ sn.requestMajor = XkbReqCode;
+ sn.requestMinor = X_kbLatchLockState;
+ sn.changed = changed;
+ XkbSendStateNotify(tmpd, &sn);
+ changed = XkbIndicatorsToUpdate(tmpd, changed, FALSE);
+ if (changed) {
+ XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client);
+ XkbUpdateIndicators(tmpd, changed, TRUE, NULL, &cause);
+ }
+ }
+ }
+ }
+
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetControls(ClientPtr client)
+{
+ xkbGetControlsReply rep;
+ XkbControlsPtr xkb;
+ DeviceIntPtr dev;
+ register int n;
+
+ REQUEST(xkbGetControlsReq);
+ REQUEST_SIZE_MATCH(xkbGetControlsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+
+ xkb = dev->key->xkbInfo->desc->ctrls;
+ rep.type = X_Reply;
+ rep.length = bytes_to_int32(SIZEOF(xkbGetControlsReply)-
+ SIZEOF(xGenericReply));
+ rep.sequenceNumber = client->sequence;
+ rep.deviceID = ((DeviceIntPtr)dev)->id;
+ rep.numGroups = xkb->num_groups;
+ rep.groupsWrap = xkb->groups_wrap;
+ rep.internalMods = xkb->internal.mask;
+ rep.ignoreLockMods = xkb->ignore_lock.mask;
+ rep.internalRealMods = xkb->internal.real_mods;
+ rep.ignoreLockRealMods = xkb->ignore_lock.real_mods;
+ rep.internalVMods = xkb->internal.vmods;
+ rep.ignoreLockVMods = xkb->ignore_lock.vmods;
+ rep.enabledCtrls = xkb->enabled_ctrls;
+ rep.repeatDelay = xkb->repeat_delay;
+ rep.repeatInterval = xkb->repeat_interval;
+ rep.slowKeysDelay = xkb->slow_keys_delay;
+ rep.debounceDelay = xkb->debounce_delay;
+ rep.mkDelay = xkb->mk_delay;
+ rep.mkInterval = xkb->mk_interval;
+ rep.mkTimeToMax = xkb->mk_time_to_max;
+ rep.mkMaxSpeed = xkb->mk_max_speed;
+ rep.mkCurve = xkb->mk_curve;
+ rep.mkDfltBtn = xkb->mk_dflt_btn;
+ rep.axTimeout = xkb->ax_timeout;
+ rep.axtCtrlsMask = xkb->axt_ctrls_mask;
+ rep.axtCtrlsValues = xkb->axt_ctrls_values;
+ rep.axtOptsMask = xkb->axt_opts_mask;
+ rep.axtOptsValues = xkb->axt_opts_values;
+ rep.axOptions = xkb->ax_options;
+ memcpy(rep.perKeyRepeat,xkb->per_key_repeat,XkbPerKeyBitArraySize);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length,n);
+ swaps(&rep.internalVMods, n);
+ swaps(&rep.ignoreLockVMods, n);
+ swapl(&rep.enabledCtrls, n);
+ swaps(&rep.repeatDelay, n);
+ swaps(&rep.repeatInterval, n);
+ swaps(&rep.slowKeysDelay, n);
+ swaps(&rep.debounceDelay, n);
+ swaps(&rep.mkDelay, n);
+ swaps(&rep.mkInterval, n);
+ swaps(&rep.mkTimeToMax, n);
+ swaps(&rep.mkMaxSpeed, n);
+ swaps(&rep.mkCurve, n);
+ swaps(&rep.axTimeout, n);
+ swapl(&rep.axtCtrlsMask, n);
+ swapl(&rep.axtCtrlsValues, n);
+ swaps(&rep.axtOptsMask, n);
+ swaps(&rep.axtOptsValues, n);
+ swaps(&rep.axOptions, n);
+ }
+ WriteToClient(client, SIZEOF(xkbGetControlsReply), (char *)&rep);
+ return Success;
+}
+
+int
+ProcXkbSetControls(ClientPtr client)
+{
+ DeviceIntPtr dev, tmpd;
+ XkbSrvInfoPtr xkbi;
+ XkbControlsPtr ctrl;
+ XkbControlsRec new,old;
+ xkbControlsNotify cn;
+ XkbEventCauseRec cause;
+ XkbSrvLedInfoPtr sli;
+
+ REQUEST(xkbSetControlsReq);
+ REQUEST_SIZE_MATCH(xkbSetControlsReq);
+
+ if (!(client->xkbClientFlags & _XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask);
+
+ for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
+ if (!tmpd->key || !tmpd->key->xkbInfo)
+ continue;
+ if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
+ xkbi = tmpd->key->xkbInfo;
+ ctrl = xkbi->desc->ctrls;
+ new = *ctrl;
+ XkbSetCauseXkbReq(&cause, X_kbSetControls, client);
+
+ if (stuff->changeCtrls & XkbInternalModsMask) {
+ CHK_MASK_MATCH(0x02, stuff->affectInternalMods,
+ stuff->internalMods);
+ CHK_MASK_MATCH(0x03, stuff->affectInternalVMods,
+ stuff->internalVMods);
+
+ new.internal.real_mods &= ~(stuff->affectInternalMods);
+ new.internal.real_mods |= (stuff->affectInternalMods &
+ stuff->internalMods);
+ new.internal.vmods &= ~(stuff->affectInternalVMods);
+ new.internal.vmods |= (stuff->affectInternalVMods &
+ stuff->internalVMods);
+ new.internal.mask = new.internal.real_mods |
+ XkbMaskForVMask(xkbi->desc,
+ new.internal.vmods);
+ }
+
+ if (stuff->changeCtrls & XkbIgnoreLockModsMask) {
+ CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods,
+ stuff->ignoreLockMods);
+ CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods,
+ stuff->ignoreLockVMods);
+
+ new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods);
+ new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods &
+ stuff->ignoreLockMods);
+ new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods);
+ new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods &
+ stuff->ignoreLockVMods);
+ new.ignore_lock.mask = new.ignore_lock.real_mods |
+ XkbMaskForVMask(xkbi->desc,
+ new.ignore_lock.vmods);
+ }
+
+ CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls,
+ stuff->enabledCtrls);
+ if (stuff->affectEnabledCtrls) {
+ CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls,
+ XkbAllBooleanCtrlsMask);
+
+ new.enabled_ctrls &= ~(stuff->affectEnabledCtrls);
+ new.enabled_ctrls |= (stuff->affectEnabledCtrls &
+ stuff->enabledCtrls);
+ }
+
+ if (stuff->changeCtrls & XkbRepeatKeysMask) {
+ if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) {
+ client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay,
+ stuff->repeatInterval);
+ return BadValue;
+ }
+
+ new.repeat_delay = stuff->repeatDelay;
+ new.repeat_interval = stuff->repeatInterval;
+ }
+
+ if (stuff->changeCtrls & XkbSlowKeysMask) {
+ if (stuff->slowKeysDelay < 1) {
+ client->errorValue = _XkbErrCode2(0x09,
+ stuff->slowKeysDelay);
+ return BadValue;
+ }
+
+ new.slow_keys_delay = stuff->slowKeysDelay;
+ }
+
+ if (stuff->changeCtrls & XkbBounceKeysMask) {
+ if (stuff->debounceDelay < 1) {
+ client->errorValue = _XkbErrCode2(0x0A,
+ stuff->debounceDelay);
+ return BadValue;
+ }
+
+ new.debounce_delay = stuff->debounceDelay;
+ }
+
+ if (stuff->changeCtrls & XkbMouseKeysMask) {
+ if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) {
+ client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn);
+ return BadValue;
+ }
+
+ new.mk_dflt_btn = stuff->mkDfltBtn;
+ }
+
+ if (stuff->changeCtrls & XkbMouseKeysAccelMask) {
+ if (stuff->mkDelay < 1 || stuff->mkInterval < 1 ||
+ stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 ||
+ stuff->mkCurve < -1000) {
+ client->errorValue = _XkbErrCode2(0x0C,0);
+ return BadValue;
+ }
+
+ new.mk_delay = stuff->mkDelay;
+ new.mk_interval = stuff->mkInterval;
+ new.mk_time_to_max = stuff->mkTimeToMax;
+ new.mk_max_speed = stuff->mkMaxSpeed;
+ new.mk_curve = stuff->mkCurve;
+ AccessXComputeCurveFactor(xkbi, &new);
+ }
+
+ if (stuff->changeCtrls & XkbGroupsWrapMask) {
+ unsigned act, num;
+
+ act = XkbOutOfRangeGroupAction(stuff->groupsWrap);
+ switch (act) {
+ case XkbRedirectIntoRange:
+ num = XkbOutOfRangeGroupNumber(stuff->groupsWrap);
+ if (num >= new.num_groups) {
+ client->errorValue = _XkbErrCode3(0x0D, new.num_groups,
+ num);
+ return BadValue;
+ }
+ case XkbWrapIntoRange:
+ case XkbClampIntoRange:
+ break;
+ default:
+ client->errorValue = _XkbErrCode2(0x0E, act);
+ return BadValue;
+ }
+
+ new.groups_wrap= stuff->groupsWrap;
+ }
+
+ CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask);
+ if (stuff->changeCtrls & XkbAccessXKeysMask) {
+ new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask;
+ }
+ else {
+ if (stuff->changeCtrls & XkbStickyKeysMask) {
+ new.ax_options &= ~(XkbAX_SKOptionsMask);
+ new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask);
+ }
+
+ if (stuff->changeCtrls & XkbAccessXFeedbackMask) {
+ new.ax_options &= ~(XkbAX_FBOptionsMask);
+ new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask);
+ }
+ }
+
+ if (stuff->changeCtrls & XkbAccessXTimeoutMask) {
+ if (stuff->axTimeout < 1) {
+ client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout);
+ return BadValue;
+ }
+ CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask,
+ stuff->axtCtrlsValues);
+ CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask,
+ XkbAllBooleanCtrlsMask);
+ CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues);
+ CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask);
+ new.ax_timeout = stuff->axTimeout;
+ new.axt_ctrls_mask = stuff->axtCtrlsMask;
+ new.axt_ctrls_values = (stuff->axtCtrlsValues &
+ stuff->axtCtrlsMask);
+ new.axt_opts_mask = stuff->axtOptsMask;
+ new.axt_opts_values = (stuff->axtOptsValues &
+ stuff->axtOptsMask);
+ }
+
+ if (stuff->changeCtrls & XkbPerKeyRepeatMask)
+ memcpy(new.per_key_repeat, stuff->perKeyRepeat,
+ XkbPerKeyBitArraySize);
+
+ old= *ctrl;
+ *ctrl= new;
+ XkbDDXChangeControls(tmpd, &old, ctrl);
+
+ if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, FALSE)) {
+ cn.keycode = 0;
+ cn.eventType = 0;
+ cn.requestMajor = XkbReqCode;
+ cn.requestMinor = X_kbSetControls;
+ XkbSendControlsNotify(tmpd, &cn);
+ }
+
+ sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0);
+ if (sli)
+ XkbUpdateIndicators(tmpd, sli->usesControls, TRUE, NULL,
+ &cause);
+
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls & XkbStickyKeysMask) &&
+ !(ctrl->enabled_ctrls & XkbStickyKeysMask))
+ XkbClearAllLatchesAndLocks(tmpd, xkbi, TRUE, &cause);
+ }
+ }
+
+ return Success;
+}
+
+/***====================================================================***/
+
+static int
+XkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ XkbKeyTypeRec *type;
+ unsigned i,len;
+
+ len= 0;
+ if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->types)) {
+ rep->present&= ~XkbKeyTypesMask;
+ rep->firstType= rep->nTypes= 0;
+ return 0;
+ }
+ type= &xkb->map->types[rep->firstType];
+ for (i=0;i<rep->nTypes;i++,type++){
+ len+= SIZEOF(xkbKeyTypeWireDesc);
+ if (type->map_count>0) {
+ len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc));
+ if (type->preserve)
+ len+= (type->map_count*SIZEOF(xkbModsWireDesc));
+ }
+ }
+ return len;
+}
+
+static char *
+XkbWriteKeyTypes( XkbDescPtr xkb,
+ xkbGetMapReply * rep,
+ char * buf,
+ ClientPtr client)
+{
+ XkbKeyTypePtr type;
+ unsigned i;
+ xkbKeyTypeWireDesc *wire;
+
+ type= &xkb->map->types[rep->firstType];
+ for (i=0;i<rep->nTypes;i++,type++) {
+ register unsigned n;
+ wire= (xkbKeyTypeWireDesc *)buf;
+ wire->mask = type->mods.mask;
+ wire->realMods = type->mods.real_mods;
+ wire->virtualMods = type->mods.vmods;
+ wire->numLevels = type->num_levels;
+ wire->nMapEntries = type->map_count;
+ wire->preserve = (type->preserve!=NULL);
+ if (client->swapped) {
+ register int n;
+ swaps(&wire->virtualMods,n);
+ }
+
+ buf= (char *)&wire[1];
+ if (wire->nMapEntries>0) {
+ xkbKTMapEntryWireDesc * wire;
+ XkbKTMapEntryPtr entry;
+ wire= (xkbKTMapEntryWireDesc *)buf;
+ entry= type->map;
+ for (n=0;n<type->map_count;n++,wire++,entry++) {
+ wire->active= entry->active;
+ wire->mask= entry->mods.mask;
+ wire->level= entry->level;
+ wire->realMods= entry->mods.real_mods;
+ wire->virtualMods= entry->mods.vmods;
+ if (client->swapped) {
+ register int n;
+ swaps(&wire->virtualMods,n);
+ }
+ }
+ buf= (char *)wire;
+ if (type->preserve!=NULL) {
+ xkbModsWireDesc * pwire;
+ XkbModsPtr preserve;
+ pwire= (xkbModsWireDesc *)buf;
+ preserve= type->preserve;
+ for (n=0;n<type->map_count;n++,pwire++,preserve++) {
+ pwire->mask= preserve->mask;
+ pwire->realMods= preserve->real_mods;
+ pwire->virtualMods= preserve->vmods;
+ if (client->swapped) {
+ register int n;
+ swaps(&pwire->virtualMods,n);
+ }
+ }
+ buf= (char *)pwire;
+ }
+ }
+ }
+ return buf;
+}
+
+static int
+XkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ XkbSymMapPtr symMap;
+ unsigned i,len;
+ unsigned nSyms,nSymsThisKey;
+
+ if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) {
+ rep->present&= ~XkbKeySymsMask;
+ rep->firstKeySym= rep->nKeySyms= 0;
+ rep->totalSyms= 0;
+ return 0;
+ }
+ len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc);
+ symMap = &xkb->map->key_sym_map[rep->firstKeySym];
+ for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) {
+ if (symMap->offset!=0) {
+ nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width;
+ nSyms+= nSymsThisKey;
+ }
+ }
+ len+= nSyms*4;
+ rep->totalSyms= nSyms;
+ return len;
+}
+
+static int
+XkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+register unsigned i,nMods,bit;
+
+ if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)||
+ (!xkb)||(!xkb->server)) {
+ rep->present&= ~XkbVirtualModsMask;
+ rep->virtualMods= 0;
+ return 0;
+ }
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (rep->virtualMods&bit)
+ nMods++;
+ }
+ return XkbPaddedSize(nMods);
+}
+
+static char *
+XkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
+{
+register KeySym * pSym;
+XkbSymMapPtr symMap;
+xkbSymMapWireDesc * outMap;
+register unsigned i;
+
+ symMap = &xkb->map->key_sym_map[rep->firstKeySym];
+ for (i=0;i<rep->nKeySyms;i++,symMap++) {
+ outMap = (xkbSymMapWireDesc *)buf;
+ outMap->ktIndex[0] = symMap->kt_index[0];
+ outMap->ktIndex[1] = symMap->kt_index[1];
+ outMap->ktIndex[2] = symMap->kt_index[2];
+ outMap->ktIndex[3] = symMap->kt_index[3];
+ outMap->groupInfo = symMap->group_info;
+ outMap->width= symMap->width;
+ outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info);
+ buf= (char *)&outMap[1];
+ if (outMap->nSyms==0)
+ continue;
+
+ pSym = &xkb->map->syms[symMap->offset];
+ memcpy((char *)buf,(char *)pSym,outMap->nSyms*4);
+ if (client->swapped) {
+ register int n,nSyms= outMap->nSyms;
+ swaps(&outMap->nSyms,n);
+ while (nSyms-->0) {
+ swapl(buf,n);
+ buf+= 4;
+ }
+ }
+ else buf+= outMap->nSyms*4;
+ }
+ return buf;
+}
+
+static int
+XkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nActs;
+ register KeyCode firstKey;
+
+ if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) {
+ rep->present&= ~XkbKeyActionsMask;
+ rep->firstKeyAct= rep->nKeyActs= 0;
+ rep->totalActs= 0;
+ return 0;
+ }
+ firstKey= rep->firstKeyAct;
+ for (nActs=i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+firstKey]!=0)
+ nActs+= XkbKeyNumActions(xkb,i+firstKey);
+ }
+ len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc));
+ rep->totalActs= nActs;
+ return len;
+}
+
+static char *
+XkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+ unsigned i;
+ CARD8 * numDesc;
+ XkbAnyAction * actDesc;
+
+ numDesc = (CARD8 *)buf;
+ for (i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+rep->firstKeyAct]==0)
+ numDesc[i] = 0;
+ else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
+ }
+ buf+= XkbPaddedSize(rep->nKeyActs);
+
+ actDesc = (XkbAnyAction *)buf;
+ for (i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) {
+ unsigned int num;
+ num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
+ memcpy((char *)actDesc,
+ (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)),
+ num*SIZEOF(xkbActionWireDesc));
+ actDesc+= num;
+ }
+ }
+ buf = (char *)actDesc;
+ return buf;
+}
+
+static int
+XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nBhvr;
+ XkbBehavior * bhv;
+
+ if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) {
+ rep->present&= ~XkbKeyBehaviorsMask;
+ rep->firstKeyBehavior= rep->nKeyBehaviors= 0;
+ rep->totalKeyBehaviors= 0;
+ return 0;
+ }
+ bhv= &xkb->server->behaviors[rep->firstKeyBehavior];
+ for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) {
+ if (bhv->type!=XkbKB_Default)
+ nBhvr++;
+ }
+ len= nBhvr*SIZEOF(xkbBehaviorWireDesc);
+ rep->totalKeyBehaviors= nBhvr;
+ return len;
+}
+
+static char *
+XkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+ unsigned i;
+ xkbBehaviorWireDesc *wire;
+ XkbBehavior *pBhvr;
+
+ wire = (xkbBehaviorWireDesc *)buf;
+ pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior];
+ for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) {
+ if (pBhvr->type!=XkbKB_Default) {
+ wire->key= i+rep->firstKeyBehavior;
+ wire->type= pBhvr->type;
+ wire->data= pBhvr->data;
+ wire++;
+ }
+ }
+ buf = (char *)wire;
+ return buf;
+}
+
+static int
+XkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->explicit)) {
+ rep->present&= ~XkbExplicitComponentsMask;
+ rep->firstKeyExplicit= rep->nKeyExplicit= 0;
+ rep->totalKeyExplicit= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nKeyExplicit;i++) {
+ if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0)
+ nRtrn++;
+ }
+ rep->totalKeyExplicit= nRtrn;
+ len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */
+ return len;
+}
+
+static char *
+XkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
+{
+unsigned i;
+char * start;
+unsigned char * pExp;
+
+ start= buf;
+ pExp= &xkb->server->explicit[rep->firstKeyExplicit];
+ for (i=0;i<rep->nKeyExplicit;i++,pExp++) {
+ if (*pExp!=0) {
+ *buf++= i+rep->firstKeyExplicit;
+ *buf++= *pExp;
+ }
+ }
+ i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
+ return buf+i;
+}
+
+static int
+XkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->modmap)) {
+ rep->present&= ~XkbModifierMapMask;
+ rep->firstModMapKey= rep->nModMapKeys= 0;
+ rep->totalModMapKeys= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nModMapKeys;i++) {
+ if (xkb->map->modmap[i+rep->firstModMapKey]!=0)
+ nRtrn++;
+ }
+ rep->totalModMapKeys= nRtrn;
+ len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */
+ return len;
+}
+
+static char *
+XkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+unsigned i;
+char * start;
+unsigned char * pMap;
+
+ start= buf;
+ pMap= &xkb->map->modmap[rep->firstModMapKey];
+ for (i=0;i<rep->nModMapKeys;i++,pMap++) {
+ if (*pMap!=0) {
+ *buf++= i+rep->firstModMapKey;
+ *buf++= *pMap;
+ }
+ }
+ i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
+ return buf+i;
+}
+
+static int
+XkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) {
+ rep->present&= ~XkbVirtualModMapMask;
+ rep->firstVModMapKey= rep->nVModMapKeys= 0;
+ rep->totalVModMapKeys= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nVModMapKeys;i++) {
+ if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0)
+ nRtrn++;
+ }
+ rep->totalVModMapKeys= nRtrn;
+ len= nRtrn*SIZEOF(xkbVModMapWireDesc);
+ return len;
+}
+
+static char *
+XkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+unsigned i;
+xkbVModMapWireDesc * wire;
+unsigned short * pMap;
+
+ wire= (xkbVModMapWireDesc *)buf;
+ pMap= &xkb->server->vmodmap[rep->firstVModMapKey];
+ for (i=0;i<rep->nVModMapKeys;i++,pMap++) {
+ if (*pMap!=0) {
+ wire->key= i+rep->firstVModMapKey;
+ wire->vmods= *pMap;
+ wire++;
+ }
+ }
+ return (char *)wire;
+}
+
+static Status
+XkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+int len;
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ len= XkbSizeKeyTypes(xkb,rep);
+ len+= XkbSizeKeySyms(xkb,rep);
+ len+= XkbSizeKeyActions(xkb,rep);
+ len+= XkbSizeKeyBehaviors(xkb,rep);
+ len+= XkbSizeVirtualMods(xkb,rep);
+ len+= XkbSizeExplicit(xkb,rep);
+ len+= XkbSizeModifierMap(xkb,rep);
+ len+= XkbSizeVirtualModMap(xkb,rep);
+ rep->length+= (len/4);
+ return Success;
+}
+
+static int
+XkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+unsigned i,len;
+char *desc,*start;
+
+ len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply));
+ start= desc= calloc(1, len);
+ if (!start)
+ return BadAlloc;
+ if ( rep->nTypes>0 )
+ desc = XkbWriteKeyTypes(xkb,rep,desc,client);
+ if ( rep->nKeySyms>0 )
+ desc = XkbWriteKeySyms(xkb,rep,desc,client);
+ if ( rep->nKeyActs>0 )
+ desc = XkbWriteKeyActions(xkb,rep,desc,client);
+ if ( rep->totalKeyBehaviors>0 )
+ desc = XkbWriteKeyBehaviors(xkb,rep,desc,client);
+ if ( rep->virtualMods ) {
+ register int sz,bit;
+ for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (rep->virtualMods&bit) {
+ desc[sz++]= xkb->server->vmods[i];
+ }
+ }
+ desc+= XkbPaddedSize(sz);
+ }
+ if ( rep->totalKeyExplicit>0 )
+ desc= XkbWriteExplicit(xkb,rep,desc,client);
+ if ( rep->totalModMapKeys>0 )
+ desc= XkbWriteModifierMap(xkb,rep,desc,client);
+ if ( rep->totalVModMapKeys>0 )
+ desc= XkbWriteVirtualModMap(xkb,rep,desc,client);
+ if ((desc-start)!=(len)) {
+ ErrorF("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n",
+ len, (unsigned long)(desc-start));
+ }
+ if (client->swapped) {
+ register int n;
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swaps(&rep->present,n);
+ swaps(&rep->totalSyms,n);
+ swaps(&rep->totalActs,n);
+ }
+ WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep);
+ WriteToClient(client, len, start);
+ free((char *)start);
+ return Success;
+}
+
+int
+ProcXkbGetMap(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbGetMapReply rep;
+ XkbDescRec *xkb;
+ int n,status;
+
+ REQUEST(xkbGetMapReq);
+ REQUEST_SIZE_MATCH(xkbGetMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+ CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial);
+ CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask);
+ CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask);
+
+ xkb= dev->key->xkbInfo->desc;
+ bzero(&rep,sizeof(xkbGetMapReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2;
+ rep.deviceID = dev->id;
+ rep.present = stuff->partial|stuff->full;
+ rep.minKeyCode = xkb->min_key_code;
+ rep.maxKeyCode = xkb->max_key_code;
+ if ( stuff->full&XkbKeyTypesMask ) {
+ rep.firstType = 0;
+ rep.nTypes = xkb->map->num_types;
+ }
+ else if (stuff->partial&XkbKeyTypesMask) {
+ if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types,
+ stuff->firstType,stuff->nTypes);
+ return BadValue;
+ }
+ rep.firstType = stuff->firstType;
+ rep.nTypes = stuff->nTypes;
+ }
+ else rep.nTypes = 0;
+ rep.totalTypes = xkb->map->num_types;
+
+ n= XkbNumKeys(xkb);
+ if ( stuff->full&XkbKeySymsMask ) {
+ rep.firstKeySym = xkb->min_key_code;
+ rep.nKeySyms = n;
+ }
+ else if (stuff->partial&XkbKeySymsMask) {
+ CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb);
+ rep.firstKeySym = stuff->firstKeySym;
+ rep.nKeySyms = stuff->nKeySyms;
+ }
+ else rep.nKeySyms = 0;
+ rep.totalSyms= 0;
+
+ if ( stuff->full&XkbKeyActionsMask ) {
+ rep.firstKeyAct= xkb->min_key_code;
+ rep.nKeyActs= n;
+ }
+ else if (stuff->partial&XkbKeyActionsMask) {
+ CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb);
+ rep.firstKeyAct= stuff->firstKeyAct;
+ rep.nKeyActs= stuff->nKeyActs;
+ }
+ else rep.nKeyActs= 0;
+ rep.totalActs= 0;
+
+ if ( stuff->full&XkbKeyBehaviorsMask ) {
+ rep.firstKeyBehavior = xkb->min_key_code;
+ rep.nKeyBehaviors = n;
+ }
+ else if (stuff->partial&XkbKeyBehaviorsMask) {
+ CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb);
+ rep.firstKeyBehavior= stuff->firstKeyBehavior;
+ rep.nKeyBehaviors= stuff->nKeyBehaviors;
+ }
+ else rep.nKeyBehaviors = 0;
+ rep.totalKeyBehaviors= 0;
+
+ if (stuff->full&XkbVirtualModsMask)
+ rep.virtualMods= ~0;
+ else if (stuff->partial&XkbVirtualModsMask)
+ rep.virtualMods= stuff->virtualMods;
+
+ if (stuff->full&XkbExplicitComponentsMask) {
+ rep.firstKeyExplicit= xkb->min_key_code;
+ rep.nKeyExplicit= n;
+ }
+ else if (stuff->partial&XkbExplicitComponentsMask) {
+ CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb);
+ rep.firstKeyExplicit= stuff->firstKeyExplicit;
+ rep.nKeyExplicit= stuff->nKeyExplicit;
+ }
+ else rep.nKeyExplicit = 0;
+ rep.totalKeyExplicit= 0;
+
+ if (stuff->full&XkbModifierMapMask) {
+ rep.firstModMapKey= xkb->min_key_code;
+ rep.nModMapKeys= n;
+ }
+ else if (stuff->partial&XkbModifierMapMask) {
+ CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb);
+ rep.firstModMapKey= stuff->firstModMapKey;
+ rep.nModMapKeys= stuff->nModMapKeys;
+ }
+ else rep.nModMapKeys = 0;
+ rep.totalModMapKeys= 0;
+
+ if (stuff->full&XkbVirtualModMapMask) {
+ rep.firstVModMapKey= xkb->min_key_code;
+ rep.nVModMapKeys= n;
+ }
+ else if (stuff->partial&XkbVirtualModMapMask) {
+ CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb);
+ rep.firstVModMapKey= stuff->firstVModMapKey;
+ rep.nVModMapKeys= stuff->nVModMapKeys;
+ }
+ else rep.nVModMapKeys = 0;
+ rep.totalVModMapKeys= 0;
+
+ if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success)
+ return status;
+ return XkbSendMap(client,xkb,&rep);
+}
+
+/***====================================================================***/
+
+static int
+CheckKeyTypes( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbKeyTypeWireDesc **wireRtrn,
+ int * nMapsRtrn,
+ CARD8 * mapWidthRtrn)
+{
+unsigned nMaps;
+register unsigned i,n;
+register CARD8 * map;
+register xkbKeyTypeWireDesc *wire = *wireRtrn;
+
+ if (req->firstType>((unsigned)xkb->map->num_types)) {
+ *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types);
+ return 0;
+ }
+ if (req->flags&XkbSetMapResizeTypes) {
+ nMaps = req->firstType+req->nTypes;
+ if (nMaps<XkbNumRequiredTypes) { /* canonical types must be there */
+ *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4);
+ return 0;
+ }
+ }
+ else if (req->present&XkbKeyTypesMask) {
+ nMaps = xkb->map->num_types;
+ if ((req->firstType+req->nTypes)>nMaps) {
+ *nMapsRtrn = req->firstType+req->nTypes;
+ return 0;
+ }
+ }
+ else {
+ *nMapsRtrn = xkb->map->num_types;
+ for (i=0;i<xkb->map->num_types;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ return 1;
+ }
+
+ for (i=0;i<req->firstType;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ for (i=0;i<req->nTypes;i++) {
+ unsigned width;
+ if (client->swapped) {
+ register int s;
+ swaps(&wire->virtualMods,s);
+ }
+ n= i+req->firstType;
+ width= wire->numLevels;
+ if (width<1) {
+ *nMapsRtrn= _XkbErrCode3(0x04,n,width);
+ return 0;
+ }
+ else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */
+ *nMapsRtrn= _XkbErrCode3(0x05,n,width);
+ return 0;
+ }
+ else if ((width!=2)&&
+ ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)||
+ (n==XkbAlphabeticIndex))) {
+ /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */
+ *nMapsRtrn= _XkbErrCode3(0x05,n,width);
+ return 0;
+ }
+ if (wire->nMapEntries>0) {
+ xkbKTSetMapEntryWireDesc * mapWire;
+ xkbModsWireDesc * preWire;
+ mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1];
+ preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
+ for (n=0;n<wire->nMapEntries;n++) {
+ if (client->swapped) {
+ register int s;
+ swaps(&mapWire[n].virtualMods,s);
+ }
+ if (mapWire[n].realMods&(~wire->realMods)) {
+ *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods,
+ wire->realMods);
+ return 0;
+ }
+ if (mapWire[n].virtualMods&(~wire->virtualMods)) {
+ *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods);
+ return 0;
+ }
+ if (mapWire[n].level>=wire->numLevels) {
+ *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels,
+ mapWire[n].level);
+ return 0;
+ }
+ if (wire->preserve) {
+ if (client->swapped) {
+ register int s;
+ swaps(&preWire[n].virtualMods,s);
+ }
+ if (preWire[n].realMods&(~mapWire[n].realMods)) {
+ *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods,
+ mapWire[n].realMods);
+ return 0;
+ }
+ if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) {
+ *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods);
+ return 0;
+ }
+ }
+ }
+ if (wire->preserve)
+ map= (CARD8 *)&preWire[wire->nMapEntries];
+ else map= (CARD8 *)&mapWire[wire->nMapEntries];
+ }
+ else map= (CARD8 *)&wire[1];
+ mapWidthRtrn[i+req->firstType] = wire->numLevels;
+ wire= (xkbKeyTypeWireDesc *)map;
+ }
+ for (i=req->firstType+req->nTypes;i<nMaps;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ *nMapsRtrn = nMaps;
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+CheckKeySyms( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ int nTypes,
+ CARD8 * mapWidths,
+ CARD16 * symsPerKey,
+ xkbSymMapWireDesc ** wireRtrn,
+ int * errorRtrn)
+{
+register unsigned i;
+XkbSymMapPtr map;
+xkbSymMapWireDesc* wire = *wireRtrn;
+
+ if (!(XkbKeySymsMask&req->present))
+ return 1;
+ CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0);
+ map = &xkb->map->key_sym_map[xkb->min_key_code];
+ for (i=xkb->min_key_code;i<(unsigned)req->firstKeySym;i++,map++) {
+ register int g,ng,w;
+ ng= XkbNumGroups(map->group_info);
+ for (w=g=0;g<ng;g++) {
+ if (map->kt_index[g]>=(unsigned)nTypes) {
+ *errorRtrn = _XkbErrCode4(0x13,i,g,map->kt_index[g]);
+ return 0;
+ }
+ if (mapWidths[map->kt_index[g]]>w)
+ w= mapWidths[map->kt_index[g]];
+ }
+ symsPerKey[i] = w*ng;
+ }
+ for (i=0;i<req->nKeySyms;i++) {
+ KeySym *pSyms;
+ register unsigned nG;
+ if (client->swapped) {
+ swaps(&wire->nSyms,nG);
+ }
+ nG = XkbNumGroups(wire->groupInfo);
+ if (nG>XkbNumKbdGroups) {
+ *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG);
+ return 0;
+ }
+ if (nG>0) {
+ register int g,w;
+ for (g=w=0;g<nG;g++) {
+ if (wire->ktIndex[g]>=(unsigned)nTypes) {
+ *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g,
+ wire->ktIndex[g]);
+ return 0;
+ }
+ if (mapWidths[wire->ktIndex[g]]>w)
+ w= mapWidths[wire->ktIndex[g]];
+ }
+ if (wire->width!=w) {
+ *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width);
+ return 0;
+ }
+ w*= nG;
+ symsPerKey[i+req->firstKeySym] = w;
+ if (w!=wire->nSyms) {
+ *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w);
+ return 0;
+ }
+ }
+ else if (wire->nSyms!=0) {
+ *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms);
+ return 0;
+ }
+ pSyms = (KeySym *)&wire[1];
+ wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
+ }
+
+ map = &xkb->map->key_sym_map[i];
+ for (;i<=(unsigned)xkb->max_key_code;i++,map++) {
+ register int g,nG,w;
+ nG= XkbKeyNumGroups(xkb,i);
+ for (w=g=0;g<nG;g++) {
+ if (map->kt_index[g]>=(unsigned)nTypes) {
+ *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]);
+ return 0;
+ }
+ if (mapWidths[map->kt_index[g]]>w)
+ w= mapWidths[map->kt_index[g]];
+ }
+ symsPerKey[i] = w*nG;
+ }
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+CheckKeyActions( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ int nTypes,
+ CARD8 * mapWidths,
+ CARD16 * symsPerKey,
+ CARD8 ** wireRtrn,
+ int * nActsRtrn)
+{
+int nActs;
+CARD8 * wire = *wireRtrn;
+register unsigned i;
+
+ if (!(XkbKeyActionsMask&req->present))
+ return 1;
+ CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0);
+ for (nActs=i=0;i<req->nKeyActs;i++) {
+ if (wire[0]!=0) {
+ if (wire[0]==symsPerKey[i+req->firstKeyAct])
+ nActs+= wire[0];
+ else {
+ *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]);
+ return 0;
+ }
+ }
+ wire++;
+ }
+ if (req->nKeyActs%4)
+ wire+= 4-(req->nKeyActs%4);
+ *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs);
+ *nActsRtrn = nActs;
+ return 1;
+}
+
+static int
+CheckKeyBehaviors( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbBehaviorWireDesc ** wireRtrn,
+ int * errorRtrn)
+{
+register xkbBehaviorWireDesc * wire = *wireRtrn;
+register XkbServerMapPtr server = xkb->server;
+register unsigned i;
+unsigned first,last;
+
+ if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) {
+ req->present&= ~XkbKeyBehaviorsMask;
+ req->nKeyBehaviors= 0;
+ return 1;
+ }
+ first= req->firstKeyBehavior;
+ last= req->firstKeyBehavior+req->nKeyBehaviors-1;
+ if (first<req->minKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode);
+ return 0;
+ }
+
+ for (i=0;i<req->totalKeyBehaviors;i++,wire++) {
+ if ((wire->key<first)||(wire->key>last)) {
+ *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key);
+ return 0;
+ }
+ if ((wire->type&XkbKB_Permanent)&&
+ ((server->behaviors[wire->key].type!=wire->type)||
+ (server->behaviors[wire->key].data!=wire->data))) {
+ *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type);
+ return 0;
+ }
+ if ((wire->type==XkbKB_RadioGroup)&&
+ ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) {
+ *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data,
+ XkbMaxRadioGroups);
+ return 0;
+ }
+ if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) {
+ CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0);
+ }
+ }
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+CheckVirtualMods( XkbDescRec * xkb,
+ xkbSetMapReq * req,
+ CARD8 ** wireRtrn,
+ int * errorRtrn)
+{
+register CARD8 *wire = *wireRtrn;
+register unsigned i,nMods,bit;
+
+ if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
+ return 1;
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (req->virtualMods&bit)
+ nMods++;
+ }
+ *wireRtrn= (wire+XkbPaddedSize(nMods));
+ return 1;
+}
+
+static int
+CheckKeyExplicit( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ CARD8 ** wireRtrn,
+ int * errorRtrn)
+{
+register CARD8 * wire = *wireRtrn;
+CARD8 * start;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) {
+ req->present&= ~XkbExplicitComponentsMask;
+ req->nKeyExplicit= 0;
+ return 1;
+ }
+ first= req->firstKeyExplicit;
+ last= first+req->nKeyExplicit-1;
+ if (first<req->minKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode);
+ return 0;
+ }
+ start= wire;
+ for (i=0;i<req->totalKeyExplicit;i++,wire+=2) {
+ if ((wire[0]<first)||(wire[0]>last)) {
+ *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]);
+ return 0;
+ }
+ if (wire[1]&(~XkbAllExplicitMask)) {
+ *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]);
+ return 0;
+ }
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ *wireRtrn= wire;
+ return 1;
+}
+
+static int
+CheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn)
+{
+register CARD8 * wire = *wireRtrn;
+CARD8 * start;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) {
+ req->present&= ~XkbModifierMapMask;
+ req->nModMapKeys= 0;
+ return 1;
+ }
+ first= req->firstModMapKey;
+ last= first+req->nModMapKeys-1;
+ if (first<req->minKeyCode) {
+ *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode);
+ return 0;
+ }
+ start= wire;
+ for (i=0;i<req->totalModMapKeys;i++,wire+=2) {
+ if ((wire[0]<first)||(wire[0]>last)) {
+ *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]);
+ return 0;
+ }
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ *wireRtrn= wire;
+ return 1;
+}
+
+static int
+CheckVirtualModMap( XkbDescPtr xkb,
+ xkbSetMapReq *req,
+ xkbVModMapWireDesc **wireRtrn,
+ int *errRtrn)
+{
+register xkbVModMapWireDesc * wire = *wireRtrn;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) {
+ req->present&= ~XkbVirtualModMapMask;
+ req->nVModMapKeys= 0;
+ return 1;
+ }
+ first= req->firstVModMapKey;
+ last= first+req->nVModMapKeys-1;
+ if (first<req->minKeyCode) {
+ *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode);
+ return 0;
+ }
+ for (i=0;i<req->totalVModMapKeys;i++,wire++) {
+ if ((wire->key<first)||(wire->key>last)) {
+ *errRtrn = _XkbErrCode4(0x73,first,last,wire->key);
+ return 0;
+ }
+ }
+ *wireRtrn= wire;
+ return 1;
+}
+
+static char *
+SetKeyTypes( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbKeyTypeWireDesc * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i;
+unsigned first,last;
+CARD8 *map;
+
+ if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) {
+ i= req->firstType+req->nTypes;
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) {
+ return NULL;
+ }
+ }
+ if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types)
+ xkb->map->num_types= req->firstType+req->nTypes;
+
+ for (i=0;i<req->nTypes;i++) {
+ XkbKeyTypePtr pOld;
+ register unsigned n;
+
+ if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries,
+ wire->preserve,wire->numLevels)!=Success) {
+ return NULL;
+ }
+ pOld = &xkb->map->types[i+req->firstType];
+ map = (CARD8 *)&wire[1];
+
+ pOld->mods.real_mods = wire->realMods;
+ pOld->mods.vmods= wire->virtualMods;
+ pOld->num_levels = wire->numLevels;
+ pOld->map_count= wire->nMapEntries;
+
+ pOld->mods.mask= pOld->mods.real_mods|
+ XkbMaskForVMask(xkb,pOld->mods.vmods);
+
+ if (wire->nMapEntries) {
+ xkbKTSetMapEntryWireDesc *mapWire;
+ xkbModsWireDesc *preWire;
+ unsigned tmp;
+ mapWire= (xkbKTSetMapEntryWireDesc *)map;
+ preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
+ for (n=0;n<wire->nMapEntries;n++) {
+ pOld->map[n].active= 1;
+ pOld->map[n].mods.mask= mapWire[n].realMods;
+ pOld->map[n].mods.real_mods= mapWire[n].realMods;
+ pOld->map[n].mods.vmods= mapWire[n].virtualMods;
+ pOld->map[n].level= mapWire[n].level;
+ if (mapWire[n].virtualMods!=0) {
+ tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods);
+ pOld->map[n].active= (tmp!=0);
+ pOld->map[n].mods.mask|= tmp;
+ }
+ if (wire->preserve) {
+ pOld->preserve[n].real_mods= preWire[n].realMods;
+ pOld->preserve[n].vmods= preWire[n].virtualMods;
+ tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods);
+ pOld->preserve[n].mask= preWire[n].realMods|tmp;
+ }
+ }
+ if (wire->preserve)
+ map= (CARD8 *)&preWire[wire->nMapEntries];
+ else map= (CARD8 *)&mapWire[wire->nMapEntries];
+ }
+ else map= (CARD8 *)&wire[1];
+ wire = (xkbKeyTypeWireDesc *)map;
+ }
+ first= req->firstType;
+ last= first+req->nTypes-1; /* last changed type */
+ if (changes->map.changed&XkbKeyTypesMask) {
+ int oldLast;
+ oldLast= changes->map.first_type+changes->map.num_types-1;
+ if (changes->map.first_type<first)
+ first= changes->map.first_type;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type = first;
+ changes->map.num_types = (last-first)+1;
+ return (char *)wire;
+}
+
+static char *
+SetKeySyms( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbSymMapWireDesc * wire,
+ XkbChangesPtr changes,
+ DeviceIntPtr dev)
+{
+register unsigned i,s;
+XkbSymMapPtr oldMap;
+KeySym * newSyms;
+KeySym * pSyms;
+unsigned first,last;
+
+ oldMap = &xkb->map->key_sym_map[req->firstKeySym];
+ for (i=0;i<req->nKeySyms;i++,oldMap++) {
+ pSyms = (KeySym *)&wire[1];
+ if (wire->nSyms>0) {
+ newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms);
+ for (s=0;s<wire->nSyms;s++) {
+ newSyms[s]= pSyms[s];
+ }
+ if (client->swapped) {
+ int n;
+ for (s=0;s<wire->nSyms;s++) {
+ swapl(&newSyms[s],n);
+ }
+ }
+ }
+ oldMap->kt_index[0] = wire->ktIndex[0];
+ oldMap->kt_index[1] = wire->ktIndex[1];
+ oldMap->kt_index[2] = wire->ktIndex[2];
+ oldMap->kt_index[3] = wire->ktIndex[3];
+ oldMap->group_info = wire->groupInfo;
+ oldMap->width = wire->width;
+ wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
+ }
+ first= req->firstKeySym;
+ last= first+req->nKeySyms-1;
+ if (changes->map.changed&XkbKeySymsMask) {
+ int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1);
+ if (changes->map.first_key_sym<first)
+ first= changes->map.first_key_sym;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeySymsMask;
+ changes->map.first_key_sym = first;
+ changes->map.num_key_syms = (last-first+1);
+
+ s= 0;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (XkbKeyNumGroups(xkb,i)>s)
+ s= XkbKeyNumGroups(xkb,i);
+ }
+ if (s!=xkb->ctrls->num_groups) {
+ xkbControlsNotify cn;
+ XkbControlsRec old;
+ cn.keycode= 0;
+ cn.eventType= 0;
+ cn.requestMajor= XkbReqCode;
+ cn.requestMinor= X_kbSetMap;
+ old= *xkb->ctrls;
+ xkb->ctrls->num_groups= s;
+ if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,FALSE))
+ XkbSendControlsNotify(dev,&cn);
+ }
+ return (char *)wire;
+}
+
+static char *
+SetKeyActions( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ CARD8 * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+CARD8 * nActs = wire;
+XkbAction * newActs;
+
+ wire+= XkbPaddedSize(req->nKeyActs);
+ for (i=0;i<req->nKeyActs;i++) {
+ if (nActs[i]==0)
+ xkb->server->key_acts[i+req->firstKeyAct]= 0;
+ else {
+ newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]);
+ memcpy((char *)newActs,(char *)wire,
+ nActs[i]*SIZEOF(xkbActionWireDesc));
+ wire+= nActs[i]*SIZEOF(xkbActionWireDesc);
+ }
+ }
+ first= req->firstKeyAct;
+ last= (first+req->nKeyActs-1);
+ if (changes->map.changed&XkbKeyActionsMask) {
+ int oldLast;
+ oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
+ if (changes->map.first_key_act<first)
+ first= changes->map.first_key_act;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act= first;
+ changes->map.num_key_acts= (last-first+1);
+ return (char *)wire;
+}
+
+static char *
+SetKeyBehaviors( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq *req,
+ xkbBehaviorWireDesc *wire,
+ XkbChangesPtr changes)
+{
+register unsigned i;
+int maxRG = -1;
+XkbDescPtr xkb = xkbi->desc;
+XkbServerMapPtr server = xkb->server;
+unsigned first,last;
+
+ first= req->firstKeyBehavior;
+ last= req->firstKeyBehavior+req->nKeyBehaviors-1;
+ bzero(&server->behaviors[first],req->nKeyBehaviors*sizeof(XkbBehavior));
+ for (i=0;i<req->totalKeyBehaviors;i++) {
+ if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) {
+ server->behaviors[wire->key].type= wire->type;
+ server->behaviors[wire->key].data= wire->data;
+ if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG))
+ maxRG= wire->data + 1;
+ }
+ wire++;
+ }
+
+ if (maxRG>(int)xkbi->nRadioGroups) {
+ int sz = maxRG*sizeof(XkbRadioGroupRec);
+ if (xkbi->radioGroups)
+ xkbi->radioGroups= realloc(xkbi->radioGroups,sz);
+ else xkbi->radioGroups= calloc(1, sz);
+ if (xkbi->radioGroups) {
+ if (xkbi->nRadioGroups)
+ bzero(&xkbi->radioGroups[xkbi->nRadioGroups],
+ (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec));
+ xkbi->nRadioGroups= maxRG;
+ }
+ else xkbi->nRadioGroups= 0;
+ /* should compute members here */
+ }
+ if (changes->map.changed&XkbKeyBehaviorsMask) {
+ unsigned oldLast;
+ oldLast= changes->map.first_key_behavior+
+ changes->map.num_key_behaviors-1;
+ if (changes->map.first_key_behavior<req->firstKeyBehavior)
+ first= changes->map.first_key_behavior;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyBehaviorsMask;
+ changes->map.first_key_behavior = first;
+ changes->map.num_key_behaviors = (last-first+1);
+ return (char *)wire;
+}
+
+static char *
+SetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
+ XkbChangesPtr changes)
+{
+register int i,bit,nMods;
+XkbServerMapPtr srv = xkbi->desc->server;
+
+ if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
+ return (char *)wire;
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (req->virtualMods&bit) {
+ if (srv->vmods[i]!=wire[nMods]) {
+ changes->map.changed|= XkbVirtualModsMask;
+ changes->map.vmods|= bit;
+ srv->vmods[i]= wire[nMods];
+ }
+ nMods++;
+ }
+ }
+ return (char *)(wire+XkbPaddedSize(nMods));
+}
+
+static char *
+SetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+XkbServerMapPtr xkb = xkbi->desc->server;
+CARD8 * start;
+
+ start= wire;
+ first= req->firstKeyExplicit;
+ last= req->firstKeyExplicit+req->nKeyExplicit-1;
+ bzero(&xkb->explicit[first],req->nKeyExplicit);
+ for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) {
+ xkb->explicit[wire[0]]= wire[1];
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbExplicitComponentsMask) {
+ int oldLast;
+ oldLast= changes->map.first_key_explicit+
+ changes->map.num_key_explicit-1;
+ if (changes->map.first_key_explicit<first)
+ first= changes->map.first_key_explicit;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_key_explicit= first;
+ changes->map.num_key_explicit= (last-first)+1;
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ return (char *)wire;
+}
+
+static char *
+SetModifierMap( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq * req,
+ CARD8 * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+XkbClientMapPtr xkb = xkbi->desc->map;
+CARD8 * start;
+
+ start= wire;
+ first= req->firstModMapKey;
+ last= req->firstModMapKey+req->nModMapKeys-1;
+ bzero(&xkb->modmap[first],req->nModMapKeys);
+ for (i=0;i<req->totalModMapKeys;i++,wire+= 2) {
+ xkb->modmap[wire[0]]= wire[1];
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbModifierMapMask) {
+ int oldLast;
+ oldLast= changes->map.first_modmap_key+
+ changes->map.num_modmap_keys-1;
+ if (changes->map.first_modmap_key<first)
+ first= changes->map.first_modmap_key;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_modmap_key= first;
+ changes->map.num_modmap_keys= (last-first)+1;
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ return (char *)wire;
+}
+
+static char *
+SetVirtualModMap( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq * req,
+ xkbVModMapWireDesc * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+XkbServerMapPtr srv = xkbi->desc->server;
+
+ first= req->firstVModMapKey;
+ last= req->firstVModMapKey+req->nVModMapKeys-1;
+ bzero(&srv->vmodmap[first],req->nVModMapKeys*sizeof(unsigned short));
+ for (i=0;i<req->totalVModMapKeys;i++,wire++) {
+ srv->vmodmap[wire->key]= wire->vmods;
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbVirtualModMapMask) {
+ int oldLast;
+ oldLast= changes->map.first_vmodmap_key+
+ changes->map.num_vmodmap_keys-1;
+ if (changes->map.first_vmodmap_key<first)
+ first= changes->map.first_vmodmap_key;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_vmodmap_key= first;
+ changes->map.num_vmodmap_keys= (last-first)+1;
+ }
+ return (char *)wire;
+}
+
+/**
+ * Check if the given request can be applied to the given device but don't
+ * actually do anything..
+ */
+static int
+_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char* values)
+{
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ int error;
+ int nTypes = 0, nActions;
+ CARD8 mapWidths[XkbMaxLegalKeyCode + 1];
+ CARD16 symsPerKey[XkbMaxLegalKeyCode + 1];
+
+ xkbi= dev->key->xkbInfo;
+ xkb = xkbi->desc;
+
+ if ((xkb->min_key_code != req->minKeyCode)||
+ (xkb->max_key_code != req->maxKeyCode)) {
+ if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */
+ req->minKeyCode= xkb->min_key_code;
+ req->maxKeyCode= xkb->max_key_code;
+ }
+ else {
+ if (!XkbIsLegalKeycode(req->minKeyCode)) {
+ client->errorValue = _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode);
+ return BadValue;
+ }
+ if (req->minKeyCode > req->maxKeyCode) {
+ client->errorValue = _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode);
+ return BadMatch;
+ }
+ }
+ }
+
+ if ((req->present & XkbKeyTypesMask) &&
+ (!CheckKeyTypes(client,xkb,req,(xkbKeyTypeWireDesc **)&values,
+ &nTypes,mapWidths))) {
+ client->errorValue = nTypes;
+ return BadValue;
+ }
+ if ((req->present & XkbKeySymsMask) &&
+ (!CheckKeySyms(client,xkb,req,nTypes,mapWidths,symsPerKey,
+ (xkbSymMapWireDesc **)&values,&error))) {
+ client->errorValue = error;
+ return BadValue;
+ }
+
+ if ((req->present & XkbKeyActionsMask) &&
+ (!CheckKeyActions(xkb,req,nTypes,mapWidths,symsPerKey,
+ (CARD8 **)&values,&nActions))) {
+ client->errorValue = nActions;
+ return BadValue;
+ }
+
+ if ((req->present & XkbKeyBehaviorsMask) &&
+ (!CheckKeyBehaviors(xkb,req,(xkbBehaviorWireDesc**)&values,&error))) {
+ client->errorValue = error;
+ return BadValue;
+ }
+
+ if ((req->present & XkbVirtualModsMask) &&
+ (!CheckVirtualMods(xkb,req,(CARD8 **)&values,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((req->present&XkbExplicitComponentsMask) &&
+ (!CheckKeyExplicit(xkb,req,(CARD8 **)&values,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((req->present&XkbModifierMapMask) &&
+ (!CheckModifierMap(xkb,req,(CARD8 **)&values,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((req->present&XkbVirtualModMapMask) &&
+ (!CheckVirtualModMap(xkb,req,(xkbVModMapWireDesc **)&values,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+
+ if (((values-((char *)req))/4)!= req->length) {
+ ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n");
+ client->errorValue = values-((char *)&req[1]);
+ return BadLength;
+ }
+
+ return Success;
+}
+
+/**
+ * Apply the given request on the given device.
+ */
+static int
+_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char *values)
+{
+ XkbEventCauseRec cause;
+ XkbChangesRec change;
+ Bool sentNKN;
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+
+ xkbi= dev->key->xkbInfo;
+ xkb = xkbi->desc;
+
+ XkbSetCauseXkbReq(&cause,X_kbSetMap,client);
+ bzero(&change, sizeof(change));
+ sentNKN = FALSE;
+ if ((xkb->min_key_code!=req->minKeyCode)||
+ (xkb->max_key_code!=req->maxKeyCode)) {
+ Status status;
+ xkbNewKeyboardNotify nkn;
+ nkn.deviceID = nkn.oldDeviceID = dev->id;
+ nkn.oldMinKeyCode = xkb->min_key_code;
+ nkn.oldMaxKeyCode = xkb->max_key_code;
+ status= XkbChangeKeycodeRange(xkb, req->minKeyCode,
+ req->maxKeyCode, &change);
+ if (status != Success)
+ return status; /* oh-oh. what about the other keyboards? */
+ nkn.minKeyCode = xkb->min_key_code;
+ nkn.maxKeyCode = xkb->max_key_code;
+ nkn.requestMajor = XkbReqCode;
+ nkn.requestMinor = X_kbSetMap;
+ nkn.changed = XkbNKN_KeycodesMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ sentNKN = TRUE;
+ }
+
+ if (req->present&XkbKeyTypesMask) {
+ values = SetKeyTypes(xkb,req,(xkbKeyTypeWireDesc *)values,&change);
+ if (!values) goto allocFailure;
+ }
+ if (req->present&XkbKeySymsMask) {
+ values = SetKeySyms(client,xkb,req,(xkbSymMapWireDesc *)values,&change,dev);
+ if (!values) goto allocFailure;
+ }
+ if (req->present&XkbKeyActionsMask) {
+ values = SetKeyActions(xkb,req,(CARD8 *)values,&change);
+ if (!values) goto allocFailure;
+ }
+ if (req->present&XkbKeyBehaviorsMask) {
+ values= SetKeyBehaviors(xkbi,req,(xkbBehaviorWireDesc *)values,&change);
+ if (!values) goto allocFailure;
+ }
+ if (req->present&XkbVirtualModsMask)
+ values= SetVirtualMods(xkbi,req,(CARD8 *)values,&change);
+ if (req->present&XkbExplicitComponentsMask)
+ values= SetKeyExplicit(xkbi,req,(CARD8 *)values,&change);
+ if (req->present&XkbModifierMapMask)
+ values= SetModifierMap(xkbi,req,(CARD8 *)values,&change);
+ if (req->present&XkbVirtualModMapMask)
+ values= SetVirtualModMap(xkbi,req,(xkbVModMapWireDesc *)values,&change);
+ if (((values-((char *)req))/4)!=req->length) {
+ ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n");
+ client->errorValue = values-((char *)&req[1]);
+ return BadLength;
+ }
+ if (req->flags&XkbSetMapRecomputeActions) {
+ KeyCode first,last,firstMM,lastMM;
+ if (change.map.num_key_syms>0) {
+ first= change.map.first_key_sym;
+ last= first+change.map.num_key_syms-1;
+ }
+ else first= last= 0;
+ if (change.map.num_modmap_keys>0) {
+ firstMM= change.map.first_modmap_key;
+ lastMM= first+change.map.num_modmap_keys-1;
+ }
+ else firstMM= lastMM= 0;
+ if ((last>0) && (lastMM>0)) {
+ if (firstMM<first)
+ first= firstMM;
+ if (lastMM>last)
+ last= lastMM;
+ }
+ else if (lastMM>0) {
+ first= firstMM;
+ last= lastMM;
+ }
+ if (last>0) {
+ unsigned check= 0;
+ XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause);
+ if (check)
+ XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
+ }
+ }
+ if (!sentNKN)
+ XkbSendNotification(dev,&change,&cause);
+
+ return Success;
+allocFailure:
+ return BadAlloc;
+}
+
+
+int
+ProcXkbSetMap(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ char * tmp;
+ int rc;
+
+ REQUEST(xkbSetMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask);
+
+ tmp = (char *)&stuff[1];
+
+ /* Check if we can to the SetMap on the requested device. If this
+ succeeds, do the same thing for all extension devices (if needed).
+ If any of them fails, fail. */
+ rc = _XkbSetMapChecks(client, dev, stuff, tmp);
+
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetMapChecks(client, other, stuff, tmp);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ /* We know now that we will succed with the SetMap. In theory anyway. */
+ rc = _XkbSetMap(client, dev, stuff, tmp);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ _XkbSetMap(client, other, stuff, tmp);
+ /* ignore rc. if the SetMap failed although the check above
+ reported true there isn't much we can do. we still need to
+ set all other devices, hoping that at least they stay in
+ sync. */
+ }
+ }
+ }
+
+ return Success;
+}
+
+/***====================================================================***/
+
+static Status
+XkbComputeGetCompatMapReplySize( XkbCompatMapPtr compat,
+ xkbGetCompatMapReply * rep)
+{
+unsigned size,nGroups;
+
+ nGroups= 0;
+ if (rep->groups!=0) {
+ register int i,bit;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (rep->groups&bit)
+ nGroups++;
+ }
+ }
+ size= nGroups*SIZEOF(xkbModsWireDesc);
+ size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc));
+ rep->length= size/4;
+ return Success;
+}
+
+static int
+XkbSendCompatMap( ClientPtr client,
+ XkbCompatMapPtr compat,
+ xkbGetCompatMapReply * rep)
+{
+char * data;
+int size;
+
+ size= rep->length*4;
+ if (size>0) {
+ data = malloc(size);
+ if (data) {
+ register unsigned i,bit;
+ xkbModsWireDesc * grp;
+ XkbSymInterpretPtr sym= &compat->sym_interpret[rep->firstSI];
+ xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
+ for (i=0;i<rep->nSI;i++,sym++,wire++) {
+ wire->sym= sym->sym;
+ wire->mods= sym->mods;
+ wire->match= sym->match;
+ wire->virtualMod= sym->virtual_mod;
+ wire->flags= sym->flags;
+ memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc);
+ if (client->swapped) {
+ register int n;
+ swapl(&wire->sym,n);
+ }
+ }
+ if (rep->groups) {
+ grp = (xkbModsWireDesc *)wire;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (rep->groups&bit) {
+ grp->mask= compat->groups[i].mask;
+ grp->realMods= compat->groups[i].real_mods;
+ grp->virtualMods= compat->groups[i].vmods;
+ if (client->swapped) {
+ register int n;
+ swaps(&grp->virtualMods,n);
+ }
+ grp++;
+ }
+ }
+ wire= (xkbSymInterpretWireDesc*)grp;
+ }
+ }
+ else return BadAlloc;
+ }
+ else data= NULL;
+
+ if (client->swapped) {
+ register int n;
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swaps(&rep->firstSI,n);
+ swaps(&rep->nSI,n);
+ swaps(&rep->nTotalSI,n);
+ }
+
+ WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep);
+ if (data) {
+ WriteToClient(client, size, data);
+ free((char *)data);
+ }
+ return Success;
+}
+
+int
+ProcXkbGetCompatMap(ClientPtr client)
+{
+ xkbGetCompatMapReply rep;
+ DeviceIntPtr dev;
+ XkbDescPtr xkb;
+ XkbCompatMapPtr compat;
+
+ REQUEST(xkbGetCompatMapReq);
+ REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+
+ xkb = dev->key->xkbInfo->desc;
+ compat= xkb->compat;
+
+ rep.type = X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.firstSI = stuff->firstSI;
+ rep.nSI = stuff->nSI;
+ if (stuff->getAllSI) {
+ rep.firstSI = 0;
+ rep.nSI = compat->num_si;
+ }
+ else if ((((unsigned)stuff->nSI)>0)&&
+ ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) {
+ client->errorValue = _XkbErrCode2(0x05,compat->num_si);
+ return BadValue;
+ }
+ rep.nTotalSI = compat->num_si;
+ rep.groups= stuff->groups;
+ XkbComputeGetCompatMapReplySize(compat,&rep);
+ return XkbSendCompatMap(client,compat,&rep);
+}
+
+/**
+ * Apply the given request on the given device.
+ * If dryRun is TRUE, then value checks are performed, but the device isn't
+ * modified.
+ */
+static int
+_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
+ xkbSetCompatMapReq *req, char* data, BOOL dryRun)
+{
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ XkbCompatMapPtr compat;
+ int nGroups;
+ unsigned i,bit;
+
+ xkbi = dev->key->xkbInfo;
+ xkb = xkbi->desc;
+ compat = xkb->compat;
+
+ if ((req->nSI>0)||(req->truncateSI)) {
+ xkbSymInterpretWireDesc *wire;
+ if (req->firstSI>compat->num_si) {
+ client->errorValue = _XkbErrCode2(0x02,compat->num_si);
+ return BadValue;
+ }
+ wire= (xkbSymInterpretWireDesc *)data;
+ wire+= req->nSI;
+ data = (char *)wire;
+ }
+
+ nGroups= 0;
+ if (req->groups!=0) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if ( req->groups&bit )
+ nGroups++;
+ }
+ }
+ data+= nGroups*SIZEOF(xkbModsWireDesc);
+ if (((data-((char *)req))/4)!=req->length) {
+ return BadLength;
+ }
+
+ /* Done all the checks we can do */
+ if (dryRun)
+ return Success;
+
+ data = (char *)&req[1];
+ if (req->nSI>0) {
+ xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
+ XkbSymInterpretPtr sym;
+ if ((unsigned)(req->firstSI+req->nSI)>compat->num_si) {
+ compat->num_si= req->firstSI+req->nSI;
+ compat->sym_interpret= realloc(compat->sym_interpret,
+ compat->num_si * sizeof(XkbSymInterpretRec));
+ if (!compat->sym_interpret) {
+ compat->num_si= 0;
+ return BadAlloc;
+ }
+ }
+ else if (req->truncateSI) {
+ compat->num_si = req->firstSI+req->nSI;
+ }
+ sym = &compat->sym_interpret[req->firstSI];
+ for (i=0;i<req->nSI;i++,wire++,sym++) {
+ if (client->swapped) {
+ int n;
+ swapl(&wire->sym,n);
+ }
+ sym->sym= wire->sym;
+ sym->mods= wire->mods;
+ sym->match= wire->match;
+ sym->flags= wire->flags;
+ sym->virtual_mod= wire->virtualMod;
+ memcpy((char *)&sym->act,(char *)&wire->act,
+ SIZEOF(xkbActionWireDesc));
+ }
+ data = (char *)wire;
+ }
+ else if (req->truncateSI) {
+ compat->num_si = req->firstSI;
+ }
+
+ if (req->groups!=0) {
+ unsigned i, bit;
+ xkbModsWireDesc *wire = (xkbModsWireDesc *)data;
+ for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
+ if (req->groups & bit) {
+ if (client->swapped) {
+ int n;
+ swaps(&wire->virtualMods,n);
+ }
+ compat->groups[i].mask= wire->realMods;
+ compat->groups[i].real_mods= wire->realMods;
+ compat->groups[i].vmods= wire->virtualMods;
+ if (wire->virtualMods!=0) {
+ unsigned tmp;
+ tmp= XkbMaskForVMask(xkb,wire->virtualMods);
+ compat->groups[i].mask|= tmp;
+ }
+ data+= SIZEOF(xkbModsWireDesc);
+ wire= (xkbModsWireDesc *)data;
+ }
+ }
+ }
+ i= XkbPaddedSize((data-((char *)req)));
+ if ((i/4)!=req->length) {
+ ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n");
+ return BadLength;
+ }
+
+ if (dev->xkb_interest) {
+ xkbCompatMapNotify ev;
+ ev.deviceID = dev->id;
+ ev.changedGroups = req->groups;
+ ev.firstSI = req->firstSI;
+ ev.nSI = req->nSI;
+ ev.nTotalSI = compat->num_si;
+ XkbSendCompatMapNotify(dev,&ev);
+ }
+
+ if (req->recomputeActions) {
+ XkbChangesRec change;
+ unsigned check;
+ XkbEventCauseRec cause;
+
+ XkbSetCauseXkbReq(&cause,X_kbSetCompatMap,client);
+ bzero(&change,sizeof(XkbChangesRec));
+ XkbUpdateActions(dev,xkb->min_key_code,XkbNumKeys(xkb),&change,&check,
+ &cause);
+ if (check)
+ XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
+ XkbSendNotification(dev,&change,&cause);
+ }
+ return Success;
+}
+
+int
+ProcXkbSetCompatMap(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ char *data;
+ int rc;
+
+ REQUEST(xkbSetCompatMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+
+ data = (char *)&stuff[1];
+
+ /* check first using a dry-run */
+ rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE);
+ if (rc != Success)
+ return rc;
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ /* dry-run */
+ rc = _XkbSetCompatMap(client, other, stuff, data, TRUE);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ /* Yay, the dry-runs succeed. Let's apply */
+ rc = _XkbSetCompatMap(client, dev, stuff, data, FALSE);
+ if (rc != Success)
+ return rc;
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetCompatMap(client, other, stuff, data, FALSE);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetIndicatorState(ClientPtr client)
+{
+ xkbGetIndicatorStateReply rep;
+ XkbSrvLedInfoPtr sli;
+ DeviceIntPtr dev;
+ register int i;
+
+ REQUEST(xkbGetIndicatorStateReq);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess);
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
+ XkbXI_IndicatorStateMask);
+ if (!sli)
+ return BadAlloc;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.state = sli->effectiveState;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber,i);
+ swapl(&rep.state,i);
+ }
+ WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), (char *)&rep);
+ return Success;
+}
+
+/***====================================================================***/
+
+static Status
+XkbComputeGetIndicatorMapReplySize(
+ XkbIndicatorPtr indicators,
+ xkbGetIndicatorMapReply *rep)
+{
+register int i,bit;
+int nIndicators;
+
+ rep->realIndicators = indicators->phys_indicators;
+ for (i=nIndicators=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (rep->which&bit)
+ nIndicators++;
+ }
+ rep->length = (nIndicators*SIZEOF(xkbIndicatorMapWireDesc))/4;
+ return Success;
+}
+
+static int
+XkbSendIndicatorMap( ClientPtr client,
+ XkbIndicatorPtr indicators,
+ xkbGetIndicatorMapReply * rep)
+{
+int length;
+CARD8 * map;
+register int i;
+register unsigned bit;
+
+ length = rep->length*4;
+ if (length>0) {
+ CARD8 *to;
+ to= map= malloc(length);
+ if (map) {
+ xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (rep->which&bit) {
+ wire->flags= indicators->maps[i].flags;
+ wire->whichGroups= indicators->maps[i].which_groups;
+ wire->groups= indicators->maps[i].groups;
+ wire->whichMods= indicators->maps[i].which_mods;
+ wire->mods= indicators->maps[i].mods.mask;
+ wire->realMods= indicators->maps[i].mods.real_mods;
+ wire->virtualMods= indicators->maps[i].mods.vmods;
+ wire->ctrls= indicators->maps[i].ctrls;
+ if (client->swapped) {
+ register int n;
+ swaps(&wire->virtualMods,n);
+ swapl(&wire->ctrls,n);
+ }
+ wire++;
+ }
+ }
+ to = (CARD8 *)wire;
+ if ((to-map)!=length) {
+ client->errorValue = _XkbErrCode2(0xff,length);
+ return BadLength;
+ }
+ }
+ else return BadAlloc;
+ }
+ else map = NULL;
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber,i);
+ swapl(&rep->length,i);
+ swapl(&rep->which,i);
+ swapl(&rep->realIndicators,i);
+ }
+ WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), (char *)rep);
+ if (map) {
+ WriteToClient(client, length, (char *)map);
+ free((char *)map);
+ }
+ return Success;
+}
+
+int
+ProcXkbGetIndicatorMap(ClientPtr client)
+{
+xkbGetIndicatorMapReply rep;
+DeviceIntPtr dev;
+XkbDescPtr xkb;
+XkbIndicatorPtr leds;
+
+ REQUEST(xkbGetIndicatorMapReq);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+
+ xkb= dev->key->xkbInfo->desc;
+ leds= xkb->indicators;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.which = stuff->which;
+ XkbComputeGetIndicatorMapReplySize(leds,&rep);
+ return XkbSendIndicatorMap(client,leds,&rep);
+}
+
+/**
+ * Apply the given map to the given device. Which specifies which components
+ * to apply.
+ */
+static int
+_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev,
+ int which, xkbIndicatorMapWireDesc *desc)
+{
+ XkbSrvInfoPtr xkbi;
+ XkbSrvLedInfoPtr sli;
+ XkbEventCauseRec cause;
+ int i, bit;
+
+ xkbi = dev->key->xkbInfo;
+
+ sli= XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId,
+ XkbXI_IndicatorMapsMask);
+ if (!sli)
+ return BadAlloc;
+
+ for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
+ if (which & bit) {
+ sli->maps[i].flags = desc->flags;
+ sli->maps[i].which_groups = desc->whichGroups;
+ sli->maps[i].groups = desc->groups;
+ sli->maps[i].which_mods = desc->whichMods;
+ sli->maps[i].mods.mask = desc->mods;
+ sli->maps[i].mods.real_mods = desc->mods;
+ sli->maps[i].mods.vmods= desc->virtualMods;
+ sli->maps[i].ctrls = desc->ctrls;
+ if (desc->virtualMods!=0) {
+ unsigned tmp;
+ tmp= XkbMaskForVMask(xkbi->desc,desc->virtualMods);
+ sli->maps[i].mods.mask= desc->mods|tmp;
+ }
+ desc++;
+ }
+ }
+
+ XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client);
+ XkbApplyLedMapChanges(dev,sli,which,NULL,NULL,&cause);
+
+ return Success;
+}
+
+int
+ProcXkbSetIndicatorMap(ClientPtr client)
+{
+ int i, bit;
+ int nIndicators;
+ DeviceIntPtr dev;
+ xkbIndicatorMapWireDesc *from;
+ int rc;
+
+ REQUEST(xkbSetIndicatorMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
+
+ if (stuff->which==0)
+ return Success;
+
+ for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (stuff->which&bit)
+ nIndicators++;
+ }
+ if (stuff->length!=((SIZEOF(xkbSetIndicatorMapReq)+
+ (nIndicators*SIZEOF(xkbIndicatorMapWireDesc)))/4)) {
+ return BadLength;
+ }
+
+ from = (xkbIndicatorMapWireDesc *)&stuff[1];
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (stuff->which&bit) {
+ if (client->swapped) {
+ int n;
+ swaps(&from->virtualMods,n);
+ swapl(&from->ctrls,n);
+ }
+ CHK_MASK_LEGAL(i,from->whichGroups,XkbIM_UseAnyGroup);
+ CHK_MASK_LEGAL(i,from->whichMods,XkbIM_UseAnyMods);
+ from++;
+ }
+ }
+
+ from = (xkbIndicatorMapWireDesc *)&stuff[1];
+ rc = _XkbSetIndicatorMap(client, dev, stuff->which, from);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess);
+ if (rc == Success)
+ _XkbSetIndicatorMap(client, other, stuff->which, from);
+ }
+ }
+ }
+
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetNamedIndicator(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbGetNamedIndicatorReply rep;
+ register int i = 0;
+ XkbSrvLedInfoPtr sli;
+ XkbIndicatorMapPtr map = NULL;
+
+ REQUEST(xkbGetNamedIndicatorReq);
+ REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess);
+ CHK_ATOM_ONLY(stuff->indicator);
+
+ sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0);
+ if (!sli)
+ return BadAlloc;
+
+ i= 0;
+ map= NULL;
+ if ((sli->names)&&(sli->maps)) {
+ for (i=0;i<XkbNumIndicators;i++) {
+ if (stuff->indicator==sli->names[i]) {
+ map= &sli->maps[i];
+ break;
+ }
+ }
+ }
+
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.deviceID = dev->id;
+ rep.indicator= stuff->indicator;
+ if (map!=NULL) {
+ rep.found= TRUE;
+ rep.on= ((sli->effectiveState&(1<<i))!=0);
+ rep.realIndicator= ((sli->physIndicators&(1<<i))!=0);
+ rep.ndx= i;
+ rep.flags= map->flags;
+ rep.whichGroups= map->which_groups;
+ rep.groups= map->groups;
+ rep.whichMods= map->which_mods;
+ rep.mods= map->mods.mask;
+ rep.realMods= map->mods.real_mods;
+ rep.virtualMods= map->mods.vmods;
+ rep.ctrls= map->ctrls;
+ rep.supported= TRUE;
+ }
+ else {
+ rep.found= FALSE;
+ rep.on= FALSE;
+ rep.realIndicator= FALSE;
+ rep.ndx= XkbNoIndicator;
+ rep.flags= 0;
+ rep.whichGroups= 0;
+ rep.groups= 0;
+ rep.whichMods= 0;
+ rep.mods= 0;
+ rep.realMods= 0;
+ rep.virtualMods= 0;
+ rep.ctrls= 0;
+ rep.supported= TRUE;
+ }
+ if ( client->swapped ) {
+ register int n;
+ swapl(&rep.length,n);
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.indicator,n);
+ swaps(&rep.virtualMods,n);
+ swapl(&rep.ctrls,n);
+ }
+
+ WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), (char *)&rep);
+ return Success;
+}
+
+
+/**
+ * Find the IM on the device.
+ * Returns the map, or NULL if the map doesn't exist.
+ * If the return value is NULL, led_return is undefined. Otherwise, led_return
+ * is set to the led index of the map.
+ */
+static XkbIndicatorMapPtr
+_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator,
+ int *led_return)
+{
+ XkbIndicatorMapPtr map;
+
+ /* search for the right indicator */
+ map = NULL;
+ if (sli->names && sli->maps) {
+ int led;
+
+ for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) {
+ if (sli->names[led] == indicator) {
+ map= &sli->maps[led];
+ *led_return = led;
+ break;
+ }
+ }
+ }
+
+ return map;
+}
+
+/**
+ * Creates an indicator map on the device. If dryRun is TRUE, it only checks
+ * if creation is possible, but doesn't actually create it.
+ */
+static int
+_XkbCreateIndicatorMap(DeviceIntPtr dev, Atom indicator,
+ int ledClass, int ledID,
+ XkbIndicatorMapPtr *map_return, int *led_return,
+ Bool dryRun)
+{
+ XkbSrvLedInfoPtr sli;
+ XkbIndicatorMapPtr map;
+ int led;
+
+ sli = XkbFindSrvLedInfo(dev, ledClass, ledID, XkbXI_IndicatorsMask);
+ if (!sli)
+ return BadAlloc;
+
+ map = _XkbFindNamedIndicatorMap(sli, indicator, &led);
+
+ if (!map)
+ {
+ /* find first unused indicator maps and assign the name to it */
+ for (led = 0, map = NULL; (led < XkbNumIndicators) && (map == NULL); led++) {
+ if ((sli->names) && (sli->maps) && (sli->names[led] == None) &&
+ (!XkbIM_InUse(&sli->maps[led])))
+ {
+ map = &sli->maps[led];
+ if (!dryRun)
+ sli->names[led] = indicator;
+ break;
+ }
+ }
+ }
+
+ if (!map)
+ return BadAlloc;
+
+ *led_return = led;
+ *map_return = map;
+ return Success;
+}
+
+static int
+_XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev,
+ xkbSetNamedIndicatorReq *stuff)
+{
+ unsigned int extDevReason;
+ unsigned int statec, namec, mapc;
+ XkbSrvLedInfoPtr sli;
+ int led = 0;
+ XkbIndicatorMapPtr map;
+ DeviceIntPtr kbd;
+ XkbEventCauseRec cause;
+ xkbExtensionDeviceNotify ed;
+ XkbChangesRec changes;
+ int rc;
+
+ rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass,
+ stuff->ledID, &map, &led, FALSE);
+ if (rc != Success || !map) /* oh-oh */
+ return rc;
+
+ sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID,
+ XkbXI_IndicatorsMask);
+ if (!sli)
+ return BadAlloc;
+
+ namec = mapc = statec = 0;
+ extDevReason = 0;
+
+ namec |= (1<<led);
+ sli->namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0);
+ extDevReason |= XkbXI_IndicatorNamesMask;
+
+ if (stuff->setMap) {
+ map->flags = stuff->flags;
+ map->which_groups = stuff->whichGroups;
+ map->groups = stuff->groups;
+ map->which_mods = stuff->whichMods;
+ map->mods.mask = stuff->realMods;
+ map->mods.real_mods = stuff->realMods;
+ map->mods.vmods= stuff->virtualMods;
+ map->ctrls = stuff->ctrls;
+ mapc|= (1<<led);
+ }
+
+ if ((stuff->setState) && ((map->flags & XkbIM_NoExplicit) == 0))
+ {
+ if (stuff->on) sli->explicitState |= (1<<led);
+ else sli->explicitState &= ~(1<<led);
+ statec |= ((sli->effectiveState ^ sli->explicitState) & (1 << led));
+ }
+
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client);
+ if (namec)
+ XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
+ if (mapc)
+ XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
+ if (statec)
+ XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
+
+ kbd = dev;
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ kbd = inputInfo.keyboard;
+ XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause);
+
+ return Success;
+}
+
+int
+ProcXkbSetNamedIndicator(ClientPtr client)
+{
+ int rc;
+ DeviceIntPtr dev;
+ int led = 0;
+ XkbIndicatorMapPtr map;
+
+ REQUEST(xkbSetNamedIndicatorReq);
+ REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
+ CHK_ATOM_ONLY(stuff->indicator);
+ CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup);
+ CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods);
+
+ /* Dry-run for checks */
+ rc = _XkbCreateIndicatorMap(dev, stuff->indicator,
+ stuff->ledClass, stuff->ledID,
+ &map, &led, TRUE);
+ if (rc != Success || !map) /* couldn't be created or didn't exist */
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd ||
+ stuff->deviceSpec == XkbUseCorePtr)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && !IsMaster(other) && (other->u.master == dev) &&
+ (other->kbdfeed || other->leds) &&
+ (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success))
+ {
+ rc = _XkbCreateIndicatorMap(other, stuff->indicator,
+ stuff->ledClass, stuff->ledID,
+ &map, &led, TRUE);
+ if (rc != Success || !map)
+ return rc;
+ }
+ }
+ }
+
+ /* All checks passed, let's do it */
+ rc = _XkbSetNamedIndicator(client, dev, stuff);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd ||
+ stuff->deviceSpec == XkbUseCorePtr)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && !IsMaster(other) && (other->u.master == dev) &&
+ (other->kbdfeed || other->leds) &&
+ (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success))
+ {
+ _XkbSetNamedIndicator(client, other, stuff);
+ }
+ }
+ }
+
+ return Success;
+}
+
+/***====================================================================***/
+
+static CARD32
+_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count)
+{
+register unsigned int i,bit,nAtoms;
+register CARD32 atomsPresent;
+
+ for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) {
+ if (atoms[i]!=None) {
+ atomsPresent|= bit;
+ nAtoms++;
+ }
+ }
+ if (count)
+ *count= nAtoms;
+ return atomsPresent;
+}
+
+static char *
+_XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap)
+{
+register unsigned int i;
+Atom *atm;
+
+ atm = (Atom *)wire;
+ for (i=0;i<maxAtoms;i++) {
+ if (atoms[i]!=None) {
+ *atm= atoms[i];
+ if (swap) {
+ register int n;
+ swapl(atm,n);
+ }
+ atm++;
+ }
+ }
+ return (char *)atm;
+}
+
+static Status
+XkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep)
+{
+register unsigned which,length;
+register int i;
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ which= rep->which;
+ length= 0;
+ if (xkb->names!=NULL) {
+ if (which&XkbKeycodesNameMask) length++;
+ if (which&XkbGeometryNameMask) length++;
+ if (which&XkbSymbolsNameMask) length++;
+ if (which&XkbPhysSymbolsNameMask) length++;
+ if (which&XkbTypesNameMask) length++;
+ if (which&XkbCompatNameMask) length++;
+ }
+ else which&= ~XkbComponentNamesMask;
+
+ if (xkb->map!=NULL) {
+ if (which&XkbKeyTypeNamesMask)
+ length+= xkb->map->num_types;
+ rep->nTypes= xkb->map->num_types;
+ if (which&XkbKTLevelNamesMask) {
+ XkbKeyTypePtr pType = xkb->map->types;
+ int nKTLevels = 0;
+
+ length+= XkbPaddedSize(xkb->map->num_types)/4;
+ for (i=0;i<xkb->map->num_types;i++,pType++) {
+ if (pType->level_names!=NULL)
+ nKTLevels+= pType->num_levels;
+ }
+ rep->nKTLevels= nKTLevels;
+ length+= nKTLevels;
+ }
+ }
+ else {
+ rep->nTypes= 0;
+ rep->nKTLevels= 0;
+ which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask);
+ }
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ rep->indicators= 0;
+ rep->virtualMods= 0;
+ rep->groupNames= 0;
+ if (xkb->names!=NULL) {
+ if (which&XkbIndicatorNamesMask) {
+ int nLeds;
+ rep->indicators=
+ _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds);
+ length+= nLeds;
+ if (nLeds==0)
+ which&= ~XkbIndicatorNamesMask;
+ }
+
+ if (which&XkbVirtualModNamesMask) {
+ int nVMods;
+ rep->virtualMods=
+ _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods);
+ length+= nVMods;
+ if (nVMods==0)
+ which&= ~XkbVirtualModNamesMask;
+ }
+
+ if (which&XkbGroupNamesMask) {
+ int nGroups;
+ rep->groupNames=
+ _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups);
+ length+= nGroups;
+ if (nGroups==0)
+ which&= ~XkbGroupNamesMask;
+ }
+
+ if ((which&XkbKeyNamesMask)&&(xkb->names->keys))
+ length+= rep->nKeys;
+ else which&= ~XkbKeyNamesMask;
+
+ if ((which&XkbKeyAliasesMask)&&
+ (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) {
+ rep->nKeyAliases= xkb->names->num_key_aliases;
+ length+= rep->nKeyAliases*2;
+ }
+ else {
+ which&= ~XkbKeyAliasesMask;
+ rep->nKeyAliases= 0;
+ }
+
+ if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0))
+ length+= xkb->names->num_rg;
+ else which&= ~XkbRGNamesMask;
+ }
+ else {
+ which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask);
+ which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask);
+ which&= ~XkbRGNamesMask;
+ }
+
+ rep->length= length;
+ rep->which= which;
+ return Success;
+}
+
+static int
+XkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep)
+{
+register unsigned i,length,which;
+char * start;
+char * desc;
+register int n;
+
+ length= rep->length*4;
+ which= rep->which;
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swapl(&rep->which,n);
+ swaps(&rep->virtualMods,n);
+ swapl(&rep->indicators,n);
+ }
+
+ start = desc = malloc(length);
+ if ( !start )
+ return BadAlloc;
+ if (xkb->names) {
+ if (which&XkbKeycodesNameMask) {
+ *((CARD32 *)desc)= xkb->names->keycodes;
+ if (client->swapped) {
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbGeometryNameMask) {
+ *((CARD32 *)desc)= xkb->names->geometry;
+ if (client->swapped) {
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbSymbolsNameMask) {
+ *((CARD32 *)desc)= xkb->names->symbols;
+ if (client->swapped) {
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbPhysSymbolsNameMask) {
+ register CARD32 *atm= (CARD32 *)desc;
+ atm[0]= (CARD32)xkb->names->phys_symbols;
+ if (client->swapped) {
+ swapl(&atm[0],n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbTypesNameMask) {
+ *((CARD32 *)desc)= (CARD32)xkb->names->types;
+ if (client->swapped) {
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbCompatNameMask) {
+ *((CARD32 *)desc)= (CARD32)xkb->names->compat;
+ if (client->swapped) {
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbKeyTypeNamesMask) {
+ register CARD32 *atm= (CARD32 *)desc;
+ register XkbKeyTypePtr type= xkb->map->types;
+
+ for (i=0;i<xkb->map->num_types;i++,atm++,type++) {
+ *atm= (CARD32)type->name;
+ if (client->swapped) {
+ swapl(atm,n);
+ }
+ }
+ desc= (char *)atm;
+ }
+ if (which&XkbKTLevelNamesMask && xkb->map) {
+ XkbKeyTypePtr type = xkb->map->types;
+ register CARD32 *atm;
+ for (i=0;i<rep->nTypes;i++,type++) {
+ *desc++ = type->num_levels;
+ }
+ desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes;
+
+ atm= (CARD32 *)desc;
+ type = xkb->map->types;
+ for (i=0;i<xkb->map->num_types;i++,type++) {
+ register unsigned l;
+ if (type->level_names) {
+ for (l=0;l<type->num_levels;l++,atm++) {
+ *atm= type->level_names[l];
+ if (client->swapped) {
+ swapl(atm,n);
+ }
+ }
+ desc+= type->num_levels*4;
+ }
+ }
+ }
+ if (which&XkbIndicatorNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators,
+ client->swapped);
+ }
+ if (which&XkbVirtualModNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods,
+ client->swapped);
+ }
+ if (which&XkbGroupNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups,
+ client->swapped);
+ }
+ if (which&XkbKeyNamesMask) {
+ for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) {
+ *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey];
+ }
+ }
+ if (which&XkbKeyAliasesMask) {
+ XkbKeyAliasPtr pAl;
+ pAl= xkb->names->key_aliases;
+ for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) {
+ *((XkbKeyAliasPtr)desc)= *pAl;
+ }
+ }
+ if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) {
+ register CARD32 *atm= (CARD32 *)desc;
+ for (i=0;i<rep->nRadioGroups;i++,atm++) {
+ *atm= (CARD32)xkb->names->radio_groups[i];
+ if (client->swapped) {
+ swapl(atm,n);
+ }
+ }
+ desc+= rep->nRadioGroups*4;
+ }
+ }
+
+ if ((desc-start)!=(length)) {
+ ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n",
+ length, (unsigned long)(desc-start));
+ }
+ WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep);
+ WriteToClient(client, length, start);
+ free((char *)start);
+ return Success;
+}
+
+int
+ProcXkbGetNames(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ XkbDescPtr xkb;
+ xkbGetNamesReply rep;
+
+ REQUEST(xkbGetNamesReq);
+ REQUEST_SIZE_MATCH(xkbGetNamesReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+ CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
+
+ xkb = dev->key->xkbInfo->desc;
+ memset(&rep, 0, sizeof(xkbGetNamesReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.which = stuff->which;
+ rep.nTypes = xkb->map->num_types;
+ rep.firstKey = xkb->min_key_code;
+ rep.nKeys = XkbNumKeys(xkb);
+ if (xkb->names!=NULL) {
+ rep.nKeyAliases= xkb->names->num_key_aliases;
+ rep.nRadioGroups = xkb->names->num_rg;
+ }
+ else {
+ rep.nKeyAliases= rep.nRadioGroups= 0;
+ }
+ XkbComputeGetNamesReplySize(xkb,&rep);
+ return XkbSendNames(client,xkb,&rep);
+}
+
+/***====================================================================***/
+
+static CARD32 *
+_XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError)
+{
+register int i;
+
+ for (i=0;i<nAtoms;i++,wire++) {
+ if (swapped) {
+ register int n;
+ swapl(wire,n);
+ }
+ if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) {
+ *pError= ((Atom)*wire);
+ return NULL;
+ }
+ }
+ return wire;
+}
+
+static CARD32 *
+_XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped,
+ Atom *pError)
+{
+register unsigned i,bit;
+
+ for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
+ if ((present&bit)==0)
+ continue;
+ if (swapped) {
+ register int n;
+ swapl(wire,n);
+ }
+ if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) {
+ *pError= (Atom)*wire;
+ return NULL;
+ }
+ wire++;
+ }
+ return wire;
+}
+
+static Atom *
+_XkbCopyMaskedAtoms( Atom *wire,
+ Atom *dest,
+ int nAtoms,
+ CARD32 present)
+{
+register int i,bit;
+
+ for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
+ if ((present&bit)==0)
+ continue;
+ dest[i]= *wire++;
+ }
+ return wire;
+}
+
+static Bool
+_XkbCheckTypeName(Atom name,int typeNdx)
+{
+const char * str;
+
+ str= NameForAtom(name);
+ if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)||
+ (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0))
+ return FALSE;
+ return TRUE;
+}
+
+/**
+ * Check the device-dependent data in the request against the device. Returns
+ * Success, or the appropriate error code.
+ */
+static int
+_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev,
+ xkbSetNamesReq *stuff, CARD32 *data)
+{
+ XkbDescRec *xkb;
+ XkbNamesRec *names;
+ CARD32 *tmp;
+ Atom bad;
+
+ tmp = data;
+ xkb = dev->key->xkbInfo->desc;
+ names = xkb->names;
+
+
+ if (stuff->which & XkbKeyTypeNamesMask) {
+ int i;
+ CARD32 *old;
+ if ( stuff->nTypes<1 ) {
+ client->errorValue = _XkbErrCode2(0x02,stuff->nTypes);
+ return BadValue;
+ }
+ if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x03,stuff->firstType,
+ stuff->nTypes,
+ xkb->map->num_types);
+ return BadValue;
+ }
+ if (((unsigned)stuff->firstType)<=XkbLastRequiredType) {
+ client->errorValue = _XkbErrCode2(0x04,stuff->firstType);
+ return BadAccess;
+ }
+ old= tmp;
+ tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ for (i=0;i<stuff->nTypes;i++,old++) {
+ if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i))
+ client->errorValue= _XkbErrCode2(0x05,i);
+ }
+ }
+ if (stuff->which&XkbKTLevelNamesMask) {
+ unsigned i;
+ XkbKeyTypePtr type;
+ CARD8 * width;
+ if ( stuff->nKTLevels<1 ) {
+ client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels);
+ return BadValue;
+ }
+ if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>=
+ xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel,
+ stuff->nKTLevels,xkb->map->num_types);
+ return BadValue;
+ }
+ width = (CARD8 *)tmp;
+ tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
+ type = &xkb->map->types[stuff->firstKTLevel];
+ for (i=0;i<stuff->nKTLevels;i++,type++) {
+ if (width[i]==0)
+ continue;
+ else if (width[i]!=type->num_levels) {
+ client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel,
+ type->num_levels,width[i]);
+ return BadMatch;
+ }
+ tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ }
+ if (stuff->which&XkbIndicatorNamesMask) {
+ if (stuff->indicators==0) {
+ client->errorValue= 0x08;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbVirtualModNamesMask) {
+ if (stuff->virtualMods==0) {
+ client->errorValue= 0x09;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods,
+ (CARD32)stuff->virtualMods,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbGroupNamesMask) {
+ if (stuff->groupNames==0) {
+ client->errorValue= 0x0a;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups,
+ (CARD32)stuff->groupNames,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbKeyNamesMask) {
+ if (stuff->firstKey<(unsigned)xkb->min_key_code) {
+ client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code,
+ stuff->firstKey);
+ return BadValue;
+ }
+ if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)||
+ (stuff->nKeys<1)) {
+ client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code,
+ stuff->firstKey,stuff->nKeys);
+ return BadValue;
+ }
+ tmp+= stuff->nKeys;
+ }
+ if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) {
+ tmp+= stuff->nKeyAliases*2;
+ }
+ if (stuff->which&XkbRGNamesMask) {
+ if ( stuff->nRadioGroups<1 ) {
+ client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups);
+ return BadValue;
+ }
+ tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if ((tmp-((CARD32 *)stuff))!=stuff->length) {
+ client->errorValue = stuff->length;
+ return BadLength;
+ }
+
+
+
+ return Success;
+}
+
+static int
+_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff)
+{
+ XkbDescRec *xkb;
+ XkbNamesRec *names;
+ CARD32 *tmp;
+ xkbNamesNotify nn;
+
+ tmp = (CARD32 *)&stuff[1];
+ xkb = dev->key->xkbInfo->desc;
+ names = xkb->names;
+
+ if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups,
+ stuff->nKeyAliases)!=Success) {
+ return BadAlloc;
+ }
+
+ bzero(&nn,sizeof(xkbNamesNotify));
+ nn.changed= stuff->which;
+ tmp = (CARD32 *)&stuff[1];
+ if (stuff->which&XkbKeycodesNameMask)
+ names->keycodes= *tmp++;
+ if (stuff->which&XkbGeometryNameMask)
+ names->geometry= *tmp++;
+ if (stuff->which&XkbSymbolsNameMask)
+ names->symbols= *tmp++;
+ if (stuff->which&XkbPhysSymbolsNameMask)
+ names->phys_symbols= *tmp++;
+ if (stuff->which&XkbTypesNameMask)
+ names->types= *tmp++;
+ if (stuff->which&XkbCompatNameMask)
+ names->compat= *tmp++;
+ if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) {
+ register unsigned i;
+ register XkbKeyTypePtr type;
+
+ type= &xkb->map->types[stuff->firstType];
+ for (i=0;i<stuff->nTypes;i++,type++) {
+ type->name= *tmp++;
+ }
+ nn.firstType= stuff->firstType;
+ nn.nTypes= stuff->nTypes;
+ }
+ if (stuff->which&XkbKTLevelNamesMask) {
+ register XkbKeyTypePtr type;
+ register unsigned i;
+ CARD8 *width;
+
+ width = (CARD8 *)tmp;
+ tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
+ type= &xkb->map->types[stuff->firstKTLevel];
+ for (i=0;i<stuff->nKTLevels;i++,type++) {
+ if (width[i]>0) {
+ if (type->level_names) {
+ register unsigned n;
+ for (n=0;n<width[i];n++) {
+ type->level_names[n]= tmp[n];
+ }
+ }
+ tmp+= width[i];
+ }
+ }
+ nn.firstLevelName= 0;
+ nn.nLevelNames= stuff->nTypes;
+ }
+ if (stuff->which&XkbIndicatorNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators,
+ stuff->indicators);
+ nn.changedIndicators= stuff->indicators;
+ }
+ if (stuff->which&XkbVirtualModNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods,
+ stuff->virtualMods);
+ nn.changedVirtualMods= stuff->virtualMods;
+ }
+ if (stuff->which&XkbGroupNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups,
+ stuff->groupNames);
+ nn.changedVirtualMods= stuff->groupNames;
+ }
+ if (stuff->which&XkbKeyNamesMask) {
+ memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp,
+ stuff->nKeys*XkbKeyNameLength);
+ tmp+= stuff->nKeys;
+ nn.firstKey= stuff->firstKey;
+ nn.nKeys= stuff->nKeys;
+ }
+ if (stuff->which&XkbKeyAliasesMask) {
+ if (stuff->nKeyAliases>0) {
+ register int na= stuff->nKeyAliases;
+ if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success)
+ return BadAlloc;
+ memcpy((char *)names->key_aliases,(char *)tmp,
+ stuff->nKeyAliases*sizeof(XkbKeyAliasRec));
+ tmp+= stuff->nKeyAliases*2;
+ }
+ else if (names->key_aliases!=NULL) {
+ free(names->key_aliases);
+ names->key_aliases= NULL;
+ names->num_key_aliases= 0;
+ }
+ nn.nAliases= names->num_key_aliases;
+ }
+ if (stuff->which&XkbRGNamesMask) {
+ if (stuff->nRadioGroups>0) {
+ register unsigned i,nrg;
+ nrg= stuff->nRadioGroups;
+ if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success)
+ return BadAlloc;
+
+ for (i=0;i<stuff->nRadioGroups;i++) {
+ names->radio_groups[i]= tmp[i];
+ }
+ tmp+= stuff->nRadioGroups;
+ }
+ else if (names->radio_groups) {
+ free(names->radio_groups);
+ names->radio_groups= NULL;
+ names->num_rg= 0;
+ }
+ nn.nRadioGroups= names->num_rg;
+ }
+ if (nn.changed) {
+ Bool needExtEvent;
+ needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0;
+ XkbSendNamesNotify(dev,&nn);
+ if (needExtEvent) {
+ XkbSrvLedInfoPtr sli;
+ xkbExtensionDeviceNotify edev;
+ register int i;
+ register unsigned bit;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
+ XkbXI_IndicatorsMask);
+ sli->namesPresent= 0;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (names->indicators[i]!=None)
+ sli->namesPresent|= bit;
+ }
+ bzero(&edev,sizeof(xkbExtensionDeviceNotify));
+ edev.reason= XkbXI_IndicatorNamesMask;
+ edev.ledClass= KbdFeedbackClass;
+ edev.ledID= dev->kbdfeed->ctrl.id;
+ edev.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ edev.ledState= sli->effectiveState;
+ edev.firstBtn= 0;
+ edev.nBtns= 0;
+ edev.supported= XkbXI_AllFeaturesMask;
+ edev.unsupported= 0;
+ XkbSendExtensionDeviceNotify(dev,client,&edev);
+ }
+ }
+ return Success;
+}
+
+int
+ProcXkbSetNames(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ CARD32 *tmp;
+ Atom bad;
+ int rc;
+
+ REQUEST(xkbSetNamesReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetNamesReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
+
+ /* check device-independent stuff */
+ tmp = (CARD32 *)&stuff[1];
+
+ if (stuff->which&XkbKeycodesNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbGeometryNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbSymbolsNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbPhysSymbolsNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbTypesNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbCompatNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+
+ /* start of device-dependent tests */
+ rc = _XkbSetNamesCheck(client, dev, stuff, tmp);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetNamesCheck(client, other, stuff, tmp);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ /* everything is okay -- update names */
+
+ rc = _XkbSetNames(client, dev, stuff);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ _XkbSetNames(client, other, stuff);
+ }
+ }
+ }
+
+ /* everything is okay -- update names */
+
+ return Success;
+}
+
+/***====================================================================***/
+
+#include "xkbgeom.h"
+
+#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4)
+
+static char *
+XkbWriteCountedString(char *wire,char *str,Bool swap)
+{
+ CARD16 len,*pLen;
+
+ if (!str)
+ return wire;
+
+ len= strlen(str);
+ pLen= (CARD16 *)wire;
+ *pLen= len;
+ if (swap) {
+ register int n;
+ swaps(pLen,n);
+ }
+ memcpy(&wire[2],str,len);
+ wire+= ((2+len+3)/4)*4;
+ return wire;
+}
+
+static int
+XkbSizeGeomProperties(XkbGeometryPtr geom)
+{
+register int i,size;
+XkbPropertyPtr prop;
+
+ for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ size+= XkbSizeCountedString(prop->name);
+ size+= XkbSizeCountedString(prop->value);
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int i;
+register XkbPropertyPtr prop;
+
+ for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ wire= XkbWriteCountedString(wire,prop->name,swap);
+ wire= XkbWriteCountedString(wire,prop->value,swap);
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomKeyAliases(XkbGeometryPtr geom)
+{
+ return geom->num_key_aliases*(2*XkbKeyNameLength);
+}
+
+static char *
+XkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int sz;
+
+ sz= geom->num_key_aliases*(XkbKeyNameLength*2);
+ if (sz>0) {
+ memcpy(wire,(char *)geom->key_aliases,sz);
+ wire+= sz;
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomColors(XkbGeometryPtr geom)
+{
+register int i,size;
+register XkbColorPtr color;
+
+ for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ size+= XkbSizeCountedString(color->spec);
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int i;
+register XkbColorPtr color;
+
+ for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ wire= XkbWriteCountedString(wire,color->spec,swap);
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomShapes(XkbGeometryPtr geom)
+{
+register int i,size;
+register XkbShapePtr shape;
+
+ for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
+ register int n;
+ register XkbOutlinePtr ol;
+ size+= SIZEOF(xkbShapeWireDesc);
+ for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
+ size+= SIZEOF(xkbOutlineWireDesc);
+ size+= ol->num_points*SIZEOF(xkbPointWireDesc);
+ }
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+int i;
+XkbShapePtr shape;
+xkbShapeWireDesc * shapeWire;
+
+ for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
+ register int o;
+ XkbOutlinePtr ol;
+ xkbOutlineWireDesc * olWire;
+ shapeWire= (xkbShapeWireDesc *)wire;
+ shapeWire->name= shape->name;
+ shapeWire->nOutlines= shape->num_outlines;
+ if (shape->primary!=NULL)
+ shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary);
+ else shapeWire->primaryNdx= XkbNoShape;
+ if (shape->approx!=NULL)
+ shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx);
+ else shapeWire->approxNdx= XkbNoShape;
+ if (swap) {
+ register int n;
+ swapl(&shapeWire->name,n);
+ }
+ wire= (char *)&shapeWire[1];
+ for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
+ register int p;
+ XkbPointPtr pt;
+ xkbPointWireDesc * ptWire;
+ olWire= (xkbOutlineWireDesc *)wire;
+ olWire->nPoints= ol->num_points;
+ olWire->cornerRadius= ol->corner_radius;
+ wire= (char *)&olWire[1];
+ ptWire= (xkbPointWireDesc *)wire;
+ for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
+ ptWire[p].x= pt->x;
+ ptWire[p].y= pt->y;
+ if (swap) {
+ register int n;
+ swaps(&ptWire[p].x,n);
+ swaps(&ptWire[p].y,n);
+ }
+ }
+ wire= (char *)&ptWire[ol->num_points];
+ }
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad)
+{
+register int i,size;
+
+ for (i=size=0;i<num_doodads;i++,doodad++) {
+ size+= SIZEOF(xkbAnyDoodadWireDesc);
+ if (doodad->any.type==XkbTextDoodad) {
+ size+= XkbSizeCountedString(doodad->text.text);
+ size+= XkbSizeCountedString(doodad->text.font);
+ }
+ else if (doodad->any.type==XkbLogoDoodad) {
+ size+= XkbSizeCountedString(doodad->logo.logo_name);
+ }
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap)
+{
+register int i;
+xkbDoodadWireDesc * doodadWire;
+
+ for (i=0;i<num_doodads;i++,doodad++) {
+ doodadWire= (xkbDoodadWireDesc *)wire;
+ wire= (char *)&doodadWire[1];
+ bzero(doodadWire,SIZEOF(xkbDoodadWireDesc));
+ doodadWire->any.name= doodad->any.name;
+ doodadWire->any.type= doodad->any.type;
+ doodadWire->any.priority= doodad->any.priority;
+ doodadWire->any.top= doodad->any.top;
+ doodadWire->any.left= doodad->any.left;
+ if (swap) {
+ register int n;
+ swapl(&doodadWire->any.name,n);
+ swaps(&doodadWire->any.top,n);
+ swaps(&doodadWire->any.left,n);
+ }
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ doodadWire->shape.angle= doodad->shape.angle;
+ doodadWire->shape.colorNdx= doodad->shape.color_ndx;
+ doodadWire->shape.shapeNdx= doodad->shape.shape_ndx;
+ if (swap) {
+ register int n;
+ swaps(&doodadWire->shape.angle,n);
+ }
+ break;
+ case XkbTextDoodad:
+ doodadWire->text.angle= doodad->text.angle;
+ doodadWire->text.width= doodad->text.width;
+ doodadWire->text.height= doodad->text.height;
+ doodadWire->text.colorNdx= doodad->text.color_ndx;
+ if (swap) {
+ register int n;
+ swaps(&doodadWire->text.angle,n);
+ swaps(&doodadWire->text.width,n);
+ swaps(&doodadWire->text.height,n);
+ }
+ wire= XkbWriteCountedString(wire,doodad->text.text,swap);
+ wire= XkbWriteCountedString(wire,doodad->text.font,swap);
+ break;
+ case XkbIndicatorDoodad:
+ doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx;
+ doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx;
+ doodadWire->indicator.offColorNdx=
+ doodad->indicator.off_color_ndx;
+ break;
+ case XkbLogoDoodad:
+ doodadWire->logo.angle= doodad->logo.angle;
+ doodadWire->logo.colorNdx= doodad->logo.color_ndx;
+ doodadWire->logo.shapeNdx= doodad->logo.shape_ndx;
+ wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap);
+ break;
+ default:
+ ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n",
+ doodad->any.type);
+ ErrorF("[xkb] Ignored\n");
+ break;
+ }
+ }
+ return wire;
+}
+
+static char *
+XkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap)
+{
+register int r;
+XkbOverlayRowPtr row;
+xkbOverlayWireDesc * olWire;
+
+ olWire= (xkbOverlayWireDesc *)wire;
+ olWire->name= ol->name;
+ olWire->nRows= ol->num_rows;
+ if (swap) {
+ register int n;
+ swapl(&olWire->name,n);
+ }
+ wire= (char *)&olWire[1];
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ unsigned int k;
+ XkbOverlayKeyPtr key;
+ xkbOverlayRowWireDesc * rowWire;
+ rowWire= (xkbOverlayRowWireDesc *)wire;
+ rowWire->rowUnder= row->row_under;
+ rowWire->nKeys= row->num_keys;
+ wire= (char *)&rowWire[1];
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ xkbOverlayKeyWireDesc * keyWire;
+ keyWire= (xkbOverlayKeyWireDesc *)wire;
+ memcpy(keyWire->over,key->over.name,XkbKeyNameLength);
+ memcpy(keyWire->under,key->under.name,XkbKeyNameLength);
+ wire= (char *)&keyWire[1];
+ }
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomSections(XkbGeometryPtr geom)
+{
+register int i,size;
+XkbSectionPtr section;
+
+ for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ size+= SIZEOF(xkbSectionWireDesc);
+ if (section->rows) {
+ int r;
+ XkbRowPtr row;
+ for (r=0,row=section->rows;r<section->num_rows;row++,r++) {
+ size+= SIZEOF(xkbRowWireDesc);
+ size+= row->num_keys*SIZEOF(xkbKeyWireDesc);
+ }
+ }
+ if (section->doodads)
+ size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads);
+ if (section->overlays) {
+ int o;
+ XkbOverlayPtr ol;
+ for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
+ int r;
+ XkbOverlayRowPtr row;
+ size+= SIZEOF(xkbOverlayWireDesc);
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ size+= SIZEOF(xkbOverlayRowWireDesc);
+ size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc);
+ }
+ }
+ }
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int i;
+XkbSectionPtr section;
+xkbSectionWireDesc * sectionWire;
+
+ for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ sectionWire= (xkbSectionWireDesc *)wire;
+ sectionWire->name= section->name;
+ sectionWire->top= section->top;
+ sectionWire->left= section->left;
+ sectionWire->width= section->width;
+ sectionWire->height= section->height;
+ sectionWire->angle= section->angle;
+ sectionWire->priority= section->priority;
+ sectionWire->nRows= section->num_rows;
+ sectionWire->nDoodads= section->num_doodads;
+ sectionWire->nOverlays= section->num_overlays;
+ sectionWire->pad= 0;
+ if (swap) {
+ register int n;
+ swapl(&sectionWire->name,n);
+ swaps(&sectionWire->top,n);
+ swaps(&sectionWire->left,n);
+ swaps(&sectionWire->width,n);
+ swaps(&sectionWire->height,n);
+ swaps(&sectionWire->angle,n);
+ }
+ wire= (char *)&sectionWire[1];
+ if (section->rows) {
+ int r;
+ XkbRowPtr row;
+ xkbRowWireDesc * rowWire;
+ for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
+ rowWire= (xkbRowWireDesc *)wire;
+ rowWire->top= row->top;
+ rowWire->left= row->left;
+ rowWire->nKeys= row->num_keys;
+ rowWire->vertical= row->vertical;
+ rowWire->pad= 0;
+ if (swap) {
+ register int n;
+ swaps(&rowWire->top,n);
+ swaps(&rowWire->left,n);
+ }
+ wire= (char *)&rowWire[1];
+ if (row->keys) {
+ int k;
+ XkbKeyPtr key;
+ xkbKeyWireDesc * keyWire;
+ keyWire= (xkbKeyWireDesc *)wire;
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength);
+ keyWire[k].gap= key->gap;
+ keyWire[k].shapeNdx= key->shape_ndx;
+ keyWire[k].colorNdx= key->color_ndx;
+ if (swap) {
+ register int n;
+ swaps(&keyWire[k].gap,n);
+ }
+ }
+ wire= (char *)&keyWire[row->num_keys];
+ }
+ }
+ }
+ if (section->doodads) {
+ wire= XkbWriteGeomDoodads(wire,
+ section->num_doodads,section->doodads,
+ swap);
+ }
+ if (section->overlays) {
+ register int o;
+ for (o=0;o<section->num_overlays;o++) {
+ wire= XkbWriteGeomOverlay(wire,&section->overlays[o],swap);
+ }
+ }
+ }
+ return wire;
+}
+
+static Status
+XkbComputeGetGeometryReplySize( XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep,
+ Atom name)
+{
+int len;
+
+ if (geom!=NULL) {
+ len= XkbSizeCountedString(geom->label_font);
+ len+= XkbSizeGeomProperties(geom);
+ len+= XkbSizeGeomColors(geom);
+ len+= XkbSizeGeomShapes(geom);
+ len+= XkbSizeGeomSections(geom);
+ len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads);
+ len+= XkbSizeGeomKeyAliases(geom);
+ rep->length= len/4;
+ rep->found= TRUE;
+ rep->name= geom->name;
+ rep->widthMM= geom->width_mm;
+ rep->heightMM= geom->height_mm;
+ rep->nProperties= geom->num_properties;
+ rep->nColors= geom->num_colors;
+ rep->nShapes= geom->num_shapes;
+ rep->nSections= geom->num_sections;
+ rep->nDoodads= geom->num_doodads;
+ rep->nKeyAliases= geom->num_key_aliases;
+ rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color);
+ rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color);
+ }
+ else {
+ rep->length= 0;
+ rep->found= FALSE;
+ rep->name= name;
+ rep->widthMM= rep->heightMM= 0;
+ rep->nProperties= rep->nColors= rep->nShapes= 0;
+ rep->nSections= rep->nDoodads= 0;
+ rep->nKeyAliases= 0;
+ rep->labelColorNdx= rep->baseColorNdx= 0;
+ }
+ return Success;
+}
+
+static int
+XkbSendGeometry( ClientPtr client,
+ XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep,
+ Bool freeGeom)
+{
+ char *desc,*start;
+ int len;
+
+ if (geom!=NULL) {
+ len= rep->length*4;
+ start= desc= malloc(len);
+ if (!start)
+ return BadAlloc;
+ desc= XkbWriteCountedString(desc,geom->label_font,client->swapped);
+ if ( rep->nProperties>0 )
+ desc = XkbWriteGeomProperties(desc,geom,client->swapped);
+ if ( rep->nColors>0 )
+ desc = XkbWriteGeomColors(desc,geom,client->swapped);
+ if ( rep->nShapes>0 )
+ desc = XkbWriteGeomShapes(desc,geom,client->swapped);
+ if ( rep->nSections>0 )
+ desc = XkbWriteGeomSections(desc,geom,client->swapped);
+ if ( rep->nDoodads>0 )
+ desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads,
+ client->swapped);
+ if ( rep->nKeyAliases>0 )
+ desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped);
+ if ((desc-start)!=(len)) {
+ ErrorF("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n",
+ len, (unsigned long)(desc-start));
+ }
+ }
+ else {
+ len= 0;
+ start= NULL;
+ }
+ if (client->swapped) {
+ register int n;
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swapl(&rep->name,n);
+ swaps(&rep->widthMM,n);
+ swaps(&rep->heightMM,n);
+ swaps(&rep->nProperties,n);
+ swaps(&rep->nColors,n);
+ swaps(&rep->nShapes,n);
+ swaps(&rep->nSections,n);
+ swaps(&rep->nDoodads,n);
+ swaps(&rep->nKeyAliases,n);
+ }
+ WriteToClient(client, SIZEOF(xkbGetGeometryReply), (char *)rep);
+ if (len>0)
+ WriteToClient(client, len, start);
+ if (start!=NULL)
+ free((char *)start);
+ if (freeGeom)
+ XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
+ return Success;
+}
+
+int
+ProcXkbGetGeometry(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbGetGeometryReply rep;
+ XkbGeometryPtr geom;
+ Bool shouldFree;
+ Status status;
+
+ REQUEST(xkbGetGeometryReq);
+ REQUEST_SIZE_MATCH(xkbGetGeometryReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree);
+ rep.type= X_Reply;
+ rep.deviceID= dev->id;
+ rep.sequenceNumber= client->sequence;
+ rep.length= 0;
+ status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name);
+ if (status!=Success)
+ return status;
+ else return XkbSendGeometry(client,geom,&rep,shouldFree);
+}
+
+/***====================================================================***/
+
+static char *
+_GetCountedString(char **wire_inout,Bool swap)
+{
+char * wire,*str;
+CARD16 len,*plen;
+
+ wire= *wire_inout;
+ plen= (CARD16 *)wire;
+ if (swap) {
+ register int n;
+ swaps(plen,n);
+ }
+ len= *plen;
+ str= malloc(len+1);
+ if (str) {
+ memcpy(str,&wire[2],len);
+ str[len]= '\0';
+ }
+ wire+= XkbPaddedSize(len+2);
+ *wire_inout= wire;
+ return str;
+}
+
+static Status
+_CheckSetDoodad( char ** wire_inout,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section,
+ ClientPtr client)
+{
+char * wire;
+xkbDoodadWireDesc * dWire;
+XkbDoodadPtr doodad;
+
+ dWire= (xkbDoodadWireDesc *)(*wire_inout);
+ wire= (char *)&dWire[1];
+ if (client->swapped) {
+ register int n;
+ swapl(&dWire->any.name,n);
+ swaps(&dWire->any.top,n);
+ swaps(&dWire->any.left,n);
+ swaps(&dWire->any.angle,n);
+ }
+ CHK_ATOM_ONLY(dWire->any.name);
+ doodad= XkbAddGeomDoodad(geom,section,dWire->any.name);
+ if (!doodad)
+ return BadAlloc;
+ doodad->any.type= dWire->any.type;
+ doodad->any.priority= dWire->any.priority;
+ doodad->any.top= dWire->any.top;
+ doodad->any.left= dWire->any.left;
+ doodad->any.angle= dWire->any.angle;
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ if (dWire->shape.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x40,geom->num_colors,
+ dWire->shape.colorNdx);
+ return BadMatch;
+ }
+ if (dWire->shape.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x41,geom->num_shapes,
+ dWire->shape.shapeNdx);
+ return BadMatch;
+ }
+ doodad->shape.color_ndx= dWire->shape.colorNdx;
+ doodad->shape.shape_ndx= dWire->shape.shapeNdx;
+ break;
+ case XkbTextDoodad:
+ if (dWire->text.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x42,geom->num_colors,
+ dWire->text.colorNdx);
+ return BadMatch;
+ }
+ if (client->swapped) {
+ register int n;
+ swaps(&dWire->text.width,n);
+ swaps(&dWire->text.height,n);
+ }
+ doodad->text.width= dWire->text.width;
+ doodad->text.height= dWire->text.height;
+ doodad->text.color_ndx= dWire->text.colorNdx;
+ doodad->text.text= _GetCountedString(&wire,client->swapped);
+ doodad->text.font= _GetCountedString(&wire,client->swapped);
+ break;
+ case XkbIndicatorDoodad:
+ if (dWire->indicator.onColorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x43,geom->num_colors,
+ dWire->indicator.onColorNdx);
+ return BadMatch;
+ }
+ if (dWire->indicator.offColorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x44,geom->num_colors,
+ dWire->indicator.offColorNdx);
+ return BadMatch;
+ }
+ if (dWire->indicator.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x45,geom->num_shapes,
+ dWire->indicator.shapeNdx);
+ return BadMatch;
+ }
+ doodad->indicator.shape_ndx= dWire->indicator.shapeNdx;
+ doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx;
+ doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx;
+ break;
+ case XkbLogoDoodad:
+ if (dWire->logo.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x46,geom->num_colors,
+ dWire->logo.colorNdx);
+ return BadMatch;
+ }
+ if (dWire->logo.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x47,geom->num_shapes,
+ dWire->logo.shapeNdx);
+ return BadMatch;
+ }
+ doodad->logo.color_ndx= dWire->logo.colorNdx;
+ doodad->logo.shape_ndx= dWire->logo.shapeNdx;
+ doodad->logo.logo_name= _GetCountedString(&wire,client->swapped);
+ break;
+ default:
+ client->errorValue= _XkbErrCode2(0x4F,dWire->any.type);
+ return BadValue;
+ }
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetOverlay( char ** wire_inout,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section,
+ ClientPtr client)
+{
+register int r;
+char * wire;
+XkbOverlayPtr ol;
+xkbOverlayWireDesc * olWire;
+xkbOverlayRowWireDesc * rWire;
+
+ wire= *wire_inout;
+ olWire= (xkbOverlayWireDesc *)wire;
+ if (client->swapped) {
+ register int n;
+ swapl(&olWire->name,n);
+ }
+ CHK_ATOM_ONLY(olWire->name);
+ ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows);
+ rWire= (xkbOverlayRowWireDesc *)&olWire[1];
+ for (r=0;r<olWire->nRows;r++) {
+ register int k;
+ xkbOverlayKeyWireDesc * kWire;
+ XkbOverlayRowPtr row;
+
+ if (rWire->rowUnder>section->num_rows) {
+ client->errorValue= _XkbErrCode4(0x20,r,section->num_rows,
+ rWire->rowUnder);
+ return BadMatch;
+ }
+ row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys);
+ kWire= (xkbOverlayKeyWireDesc *)&rWire[1];
+ for (k=0;k<rWire->nKeys;k++,kWire++) {
+ if (XkbAddGeomOverlayKey(ol,row,
+ (char *)kWire->over,(char *)kWire->under)==NULL) {
+ client->errorValue= _XkbErrCode3(0x21,r,k);
+ return BadMatch;
+ }
+ }
+ rWire= (xkbOverlayRowWireDesc *)kWire;
+ }
+ olWire= (xkbOverlayWireDesc *)rWire;
+ wire= (char *)olWire;
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetSections( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ char ** wire_inout,
+ ClientPtr client)
+{
+Status status;
+register int s;
+char * wire;
+xkbSectionWireDesc * sWire;
+XkbSectionPtr section;
+
+ wire= *wire_inout;
+ if (req->nSections<1)
+ return Success;
+ sWire= (xkbSectionWireDesc *)wire;
+ for (s=0;s<req->nSections;s++) {
+ register int r;
+ xkbRowWireDesc * rWire;
+ if (client->swapped) {
+ register int n;
+ swapl(&sWire->name,n);
+ swaps(&sWire->top,n);
+ swaps(&sWire->left,n);
+ swaps(&sWire->width,n);
+ swaps(&sWire->height,n);
+ swaps(&sWire->angle,n);
+ }
+ CHK_ATOM_ONLY(sWire->name);
+ section= XkbAddGeomSection(geom,sWire->name,sWire->nRows,
+ sWire->nDoodads,sWire->nOverlays);
+ if (!section)
+ return BadAlloc;
+ section->priority= sWire->priority;
+ section->top= sWire->top;
+ section->left= sWire->left;
+ section->width= sWire->width;
+ section->height= sWire->height;
+ section->angle= sWire->angle;
+ rWire= (xkbRowWireDesc *)&sWire[1];
+ for (r=0;r<sWire->nRows;r++) {
+ register int k;
+ XkbRowPtr row;
+ xkbKeyWireDesc * kWire;
+ if (client->swapped) {
+ register int n;
+ swaps(&rWire->top,n);
+ swaps(&rWire->left,n);
+ }
+ row= XkbAddGeomRow(section,rWire->nKeys);
+ if (!row)
+ return BadAlloc;
+ row->top= rWire->top;
+ row->left= rWire->left;
+ row->vertical= rWire->vertical;
+ kWire= (xkbKeyWireDesc *)&rWire[1];
+ for (k=0;k<rWire->nKeys;k++) {
+ XkbKeyPtr key;
+ key= XkbAddGeomKey(row);
+ if (!key)
+ return BadAlloc;
+ memcpy(key->name.name,kWire[k].name,XkbKeyNameLength);
+ key->gap= kWire[k].gap;
+ key->shape_ndx= kWire[k].shapeNdx;
+ key->color_ndx= kWire[k].colorNdx;
+ if (key->shape_ndx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x10,key->shape_ndx,
+ geom->num_shapes);
+ return BadMatch;
+ }
+ if (key->color_ndx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x11,key->color_ndx,
+ geom->num_colors);
+ return BadMatch;
+ }
+ }
+ rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys];
+ }
+ wire= (char *)rWire;
+ if (sWire->nDoodads>0) {
+ register int d;
+ for (d=0;d<sWire->nDoodads;d++) {
+ status=_CheckSetDoodad(&wire,geom,section,client);
+ if (status!=Success)
+ return status;
+ }
+ }
+ if (sWire->nOverlays>0) {
+ register int o;
+ for (o=0;o<sWire->nOverlays;o++) {
+ status= _CheckSetOverlay(&wire,geom,section,client);
+ if (status!=Success)
+ return status;
+ }
+ }
+ sWire= (xkbSectionWireDesc *)wire;
+ }
+ wire= (char *)sWire;
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetShapes( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ char ** wire_inout,
+ ClientPtr client)
+{
+register int i;
+char * wire;
+
+ wire= *wire_inout;
+ if (req->nShapes<1) {
+ client->errorValue= _XkbErrCode2(0x06,req->nShapes);
+ return BadValue;
+ }
+ else {
+ xkbShapeWireDesc * shapeWire;
+ XkbShapePtr shape;
+ register int o;
+ shapeWire= (xkbShapeWireDesc *)wire;
+ for (i=0;i<req->nShapes;i++) {
+ xkbOutlineWireDesc * olWire;
+ XkbOutlinePtr ol;
+ shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines);
+ if (!shape)
+ return BadAlloc;
+ olWire= (xkbOutlineWireDesc *)(&shapeWire[1]);
+ for (o=0;o<shapeWire->nOutlines;o++) {
+ register int p;
+ XkbPointPtr pt;
+ xkbPointWireDesc * ptWire;
+
+ ol= XkbAddGeomOutline(shape,olWire->nPoints);
+ if (!ol)
+ return BadAlloc;
+ ol->corner_radius= olWire->cornerRadius;
+ ptWire= (xkbPointWireDesc *)&olWire[1];
+ for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) {
+ pt->x= ptWire[p].x;
+ pt->y= ptWire[p].y;
+ if (client->swapped) {
+ register int n;
+ swaps(&pt->x,n);
+ swaps(&pt->y,n);
+ }
+ }
+ ol->num_points= olWire->nPoints;
+ olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]);
+ }
+ if (shapeWire->primaryNdx!=XkbNoShape)
+ shape->primary= &shape->outlines[shapeWire->primaryNdx];
+ if (shapeWire->approxNdx!=XkbNoShape)
+ shape->approx= &shape->outlines[shapeWire->approxNdx];
+ shapeWire= (xkbShapeWireDesc *)olWire;
+ }
+ wire= (char *)shapeWire;
+ }
+ if (geom->num_shapes!=req->nShapes) {
+ client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes);
+ return BadMatch;
+ }
+
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetGeom( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ ClientPtr client)
+{
+register int i;
+Status status;
+char * wire;
+
+ wire= (char *)&req[1];
+ geom->label_font= _GetCountedString(&wire,client->swapped);
+
+ for (i=0;i<req->nProperties;i++) {
+ char *name,*val;
+ name= _GetCountedString(&wire,client->swapped);
+ if (!name)
+ return BadAlloc;
+ val= _GetCountedString(&wire,client->swapped);
+ if (!val) {
+ free(name);
+ return BadAlloc;
+ }
+ if (XkbAddGeomProperty(geom,name,val)==NULL) {
+ free(name);
+ free(val);
+ return BadAlloc;
+ }
+ free(name);
+ free(val);
+ }
+
+ if (req->nColors<2) {
+ client->errorValue= _XkbErrCode3(0x01,2,req->nColors);
+ return BadValue;
+ }
+ if (req->baseColorNdx>req->nColors) {
+ client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx);
+ return BadMatch;
+ }
+ if (req->labelColorNdx>req->nColors) {
+ client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx);
+ return BadMatch;
+ }
+ if (req->labelColorNdx==req->baseColorNdx) {
+ client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx,
+ req->labelColorNdx);
+ return BadMatch;
+ }
+
+ for (i=0;i<req->nColors;i++) {
+ char *name;
+ name= _GetCountedString(&wire,client->swapped);
+ if (!name)
+ return BadAlloc;
+ if (!XkbAddGeomColor(geom,name,geom->num_colors)) {
+ free(name);
+ return BadAlloc;
+ }
+ free(name);
+ }
+ if (req->nColors!=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors);
+ return BadMatch;
+ }
+ geom->label_color= &geom->colors[req->labelColorNdx];
+ geom->base_color= &geom->colors[req->baseColorNdx];
+
+ if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success)
+ return status;
+
+ if ((status=_CheckSetSections(geom,req,&wire,client))!=Success)
+ return status;
+
+ for (i=0;i<req->nDoodads;i++) {
+ status=_CheckSetDoodad(&wire,geom,NULL,client);
+ if (status!=Success)
+ return status;
+ }
+
+ for (i=0;i<req->nKeyAliases;i++) {
+ if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL)
+ return BadAlloc;
+ wire+= 2*XkbKeyNameLength;
+ }
+ return Success;
+}
+
+static int
+_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq *stuff)
+{
+ XkbDescPtr xkb;
+ Bool new_name;
+ xkbNewKeyboardNotify nkn;
+ XkbGeometryPtr geom,old;
+ XkbGeometrySizesRec sizes;
+ Status status;
+
+ xkb= dev->key->xkbInfo->desc;
+ old= xkb->geom;
+ xkb->geom= NULL;
+
+ sizes.which= XkbGeomAllMask;
+ sizes.num_properties= stuff->nProperties;
+ sizes.num_colors= stuff->nColors;
+ sizes.num_shapes= stuff->nShapes;
+ sizes.num_sections= stuff->nSections;
+ sizes.num_doodads= stuff->nDoodads;
+ sizes.num_key_aliases= stuff->nKeyAliases;
+ if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) {
+ xkb->geom= old;
+ return status;
+ }
+ geom= xkb->geom;
+ geom->name= stuff->name;
+ geom->width_mm= stuff->widthMM;
+ geom->height_mm= stuff->heightMM;
+ if ((status= _CheckSetGeom(geom,stuff,client))!=Success) {
+ XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
+ xkb->geom= old;
+ return status;
+ }
+ new_name= (xkb->names->geometry!=geom->name);
+ xkb->names->geometry= geom->name;
+ if (old)
+ XkbFreeGeometry(old,XkbGeomAllMask,TRUE);
+ if (new_name) {
+ xkbNamesNotify nn;
+ bzero(&nn,sizeof(xkbNamesNotify));
+ nn.changed= XkbGeometryNameMask;
+ XkbSendNamesNotify(dev,&nn);
+ }
+ nkn.deviceID= nkn.oldDeviceID= dev->id;
+ nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code;
+ nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code;
+ nkn.requestMajor= XkbReqCode;
+ nkn.requestMinor= X_kbSetGeometry;
+ nkn.changed= XkbNKN_GeometryMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ return Success;
+}
+
+int
+ProcXkbSetGeometry(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ REQUEST(xkbSetGeometryReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ rc = _XkbSetGeometry(client, dev, stuff);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ _XkbSetGeometry(client, other, stuff);
+ }
+ }
+ }
+
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbPerClientFlags(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbPerClientFlagsReply rep;
+ XkbInterestPtr interest;
+ Mask access_mode = DixGetAttrAccess | DixSetAttrAccess;
+
+ REQUEST(xkbPerClientFlagsReq);
+ REQUEST_SIZE_MATCH(xkbPerClientFlagsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode);
+ CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask);
+ CHK_MASK_MATCH(0x02,stuff->change,stuff->value);
+
+ interest = XkbFindClientResource((DevicePtr)dev,client);
+ memset(&rep, 0, sizeof(xkbPerClientFlagsReply));
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (stuff->change) {
+ client->xkbClientFlags&= ~stuff->change;
+ client->xkbClientFlags|= stuff->value;
+ }
+ if (stuff->change&XkbPCF_AutoResetControlsMask) {
+ Bool want;
+ want= stuff->value&XkbPCF_AutoResetControlsMask;
+ if (interest && !want) {
+ interest->autoCtrls= interest->autoCtrlValues= 0;
+ }
+ else if (want && (!interest)) {
+ XID id = FakeClientID(client->index);
+ AddResource(id,RT_XKBCLIENT,dev);
+ interest= XkbAddClientResource((DevicePtr)dev,client,id);
+ if (!interest)
+ return BadAlloc;
+ }
+ if (interest && want ) {
+ register unsigned affect;
+ affect= stuff->ctrlsToChange;
+
+ CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask);
+ CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls);
+ CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues);
+
+ interest->autoCtrls&= ~affect;
+ interest->autoCtrlValues&= ~affect;
+ interest->autoCtrls|= stuff->autoCtrls&affect;
+ interest->autoCtrlValues|= stuff->autoCtrlValues&affect;
+ }
+ }
+ rep.supported = XkbPCF_AllFlagsMask;
+ rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask;
+ if (interest) {
+ rep.autoCtrls= interest->autoCtrls;
+ rep.autoCtrlValues= interest->autoCtrlValues;
+ }
+ else {
+ rep.autoCtrls= rep.autoCtrlValues= 0;
+ }
+ if ( client->swapped ) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.supported,n);
+ swapl(&rep.value,n);
+ swapl(&rep.autoCtrls,n);
+ swapl(&rep.autoCtrlValues,n);
+ }
+ WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep);
+ return Success;
+}
+
+/***====================================================================***/
+
+/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */
+/* and wildcards */
+static unsigned char componentSpecLegal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+};
+
+/* same as above but accepts percent, plus and bar too */
+static unsigned char componentExprLegal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+};
+
+static char *
+GetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn)
+{
+int len;
+register int i;
+unsigned char *wire,*str,*tmp,*legal;
+
+ if (allowExpr) legal= &componentExprLegal[0];
+ else legal= &componentSpecLegal[0];
+
+ wire= *pWire;
+ len= (*(unsigned char *)wire++);
+ if (len>0) {
+ str= calloc(1, len+1);
+ if (str) {
+ tmp= str;
+ for (i=0;i<len;i++) {
+ if (legal[(*wire)/8]&(1<<((*wire)%8)))
+ *tmp++= *wire++;
+ else wire++;
+ }
+ if (tmp!=str)
+ *tmp++= '\0';
+ else {
+ free(str);
+ str= NULL;
+ }
+ }
+ else {
+ *errRtrn= BadAlloc;
+ }
+ }
+ else {
+ str= NULL;
+ }
+ *pWire= wire;
+ return (char *)str;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbListComponents(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbListComponentsReply rep;
+ unsigned len;
+ int status;
+ unsigned char * str;
+ XkbSrvListInfoRec list;
+
+ REQUEST(xkbListComponentsReq);
+ REQUEST_AT_LEAST_SIZE(xkbListComponentsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+
+ status= Success;
+ str= (unsigned char *)&stuff[1];
+ bzero(&list,sizeof(XkbSrvListInfoRec));
+ list.maxRtrn= stuff->maxNames;
+ list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,FALSE,&status);
+ list.pattern[_XkbListTypes]= GetComponentSpec(&str,FALSE,&status);
+ list.pattern[_XkbListCompat]= GetComponentSpec(&str,FALSE,&status);
+ list.pattern[_XkbListSymbols]= GetComponentSpec(&str,FALSE,&status);
+ list.pattern[_XkbListGeometry]= GetComponentSpec(&str,FALSE,&status);
+ if (status!=Success)
+ return status;
+ len= str-((unsigned char *)stuff);
+ if ((XkbPaddedSize(len)/4)!=stuff->length)
+ return BadLength;
+ if ((status=XkbDDXList(dev,&list,client))!=Success) {
+ if (list.pool) {
+ free(list.pool);
+ list.pool= NULL;
+ }
+ return status;
+ }
+ bzero(&rep,sizeof(xkbListComponentsReply));
+ rep.type= X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = XkbPaddedSize(list.nPool)/4;
+ rep.nKeymaps = 0;
+ rep.nKeycodes = list.nFound[_XkbListKeycodes];
+ rep.nTypes = list.nFound[_XkbListTypes];
+ rep.nCompatMaps = list.nFound[_XkbListCompat];
+ rep.nSymbols = list.nFound[_XkbListSymbols];
+ rep.nGeometries = list.nFound[_XkbListGeometry];
+ rep.extra= 0;
+ if (list.nTotal>list.maxRtrn)
+ rep.extra = (list.nTotal-list.maxRtrn);
+ if (client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.length,n);
+ swaps(&rep.nKeymaps,n);
+ swaps(&rep.nKeycodes,n);
+ swaps(&rep.nTypes,n);
+ swaps(&rep.nCompatMaps,n);
+ swaps(&rep.nSymbols,n);
+ swaps(&rep.nGeometries,n);
+ swaps(&rep.extra,n);
+ }
+ WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep);
+ if (list.nPool && list.pool) {
+ WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool);
+ free(list.pool);
+ list.pool= NULL;
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetKbdByName(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ DeviceIntPtr tmpd;
+ xkbGetKbdByNameReply rep;
+ xkbGetMapReply mrep;
+ xkbGetCompatMapReply crep;
+ xkbGetIndicatorMapReply irep;
+ xkbGetNamesReply nrep;
+ xkbGetGeometryReply grep;
+ XkbComponentNamesRec names;
+ XkbDescPtr xkb, new;
+ unsigned char * str;
+ char mapFile[PATH_MAX];
+ unsigned len;
+ unsigned fwant,fneed,reported;
+ int status;
+ Bool geom_changed;
+ XkbSrvLedInfoPtr old_sli;
+ XkbSrvLedInfoPtr sli;
+ Mask access_mode = DixGetAttrAccess | DixManageAccess;
+
+ REQUEST(xkbGetKbdByNameReq);
+ REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode);
+
+ xkb = dev->key->xkbInfo->desc;
+ status= Success;
+ str= (unsigned char *)&stuff[1];
+ if (GetComponentSpec(&str,TRUE,&status)) /* keymap, unsupported */
+ return BadMatch;
+ names.keycodes= GetComponentSpec(&str,TRUE,&status);
+ names.types= GetComponentSpec(&str,TRUE,&status);
+ names.compat= GetComponentSpec(&str,TRUE,&status);
+ names.symbols= GetComponentSpec(&str,TRUE,&status);
+ names.geometry= GetComponentSpec(&str,TRUE,&status);
+ if (status!=Success)
+ return status;
+ len= str-((unsigned char *)stuff);
+ if ((XkbPaddedSize(len)/4)!=stuff->length)
+ return BadLength;
+
+ CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask);
+ CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask);
+
+ if (stuff->load)
+ fwant= XkbGBN_AllComponentsMask;
+ else fwant= stuff->want|stuff->need;
+ if ((!names.compat)&&
+ (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) {
+ names.compat= _XkbDupString("%");
+ }
+ if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) {
+ names.types= _XkbDupString("%");
+ }
+ if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) {
+ names.symbols= _XkbDupString("%");
+ }
+ geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0));
+ if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) {
+ names.geometry= _XkbDupString("%");
+ geom_changed= FALSE;
+ }
+
+ bzero(mapFile,PATH_MAX);
+ rep.type= X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.minKeyCode = xkb->min_key_code;
+ rep.maxKeyCode = xkb->max_key_code;
+ rep.loaded= FALSE;
+ fwant= XkbConvertGetByNameComponents(TRUE,stuff->want)|XkmVirtualModsMask;
+ fneed= XkbConvertGetByNameComponents(TRUE,stuff->need);
+ rep.reported= XkbConvertGetByNameComponents(FALSE,fwant|fneed);
+ if (stuff->load) {
+ fneed|= XkmKeymapRequired;
+ fwant|= XkmKeymapLegal;
+ }
+ if ((fwant|fneed)&XkmSymbolsMask) {
+ fneed|= XkmKeyNamesIndex|XkmTypesIndex;
+ fwant|= XkmIndicatorsIndex;
+ }
+
+ /* We pass dev in here so we can get the old names out if needed. */
+ rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&new,
+ mapFile,PATH_MAX);
+ rep.newKeyboard= FALSE;
+ rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0;
+
+ stuff->want|= stuff->need;
+ if (new==NULL)
+ rep.reported= 0;
+ else {
+ if (stuff->load)
+ rep.loaded= TRUE;
+ if (stuff->load ||
+ ((rep.reported&XkbGBN_SymbolsMask) && (new->compat))) {
+ XkbChangesRec changes;
+ bzero(&changes,sizeof(changes));
+ XkbUpdateDescActions(new,
+ new->min_key_code,XkbNumKeys(new),
+ &changes);
+ }
+
+ if (new->map==NULL)
+ rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask);
+ else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) {
+ mrep.type= X_Reply;
+ mrep.deviceID = dev->id;
+ mrep.sequenceNumber= client->sequence;
+ mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2);
+ mrep.minKeyCode = new->min_key_code;
+ mrep.maxKeyCode = new->max_key_code;
+ mrep.present = 0;
+ mrep.totalSyms = mrep.totalActs =
+ mrep.totalKeyBehaviors= mrep.totalKeyExplicit=
+ mrep.totalModMapKeys= mrep.totalVModMapKeys= 0;
+ if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) {
+ mrep.present|= XkbKeyTypesMask;
+ mrep.firstType = 0;
+ mrep.nTypes = mrep.totalTypes= new->map->num_types;
+ }
+ else {
+ mrep.firstType = mrep.nTypes= 0;
+ mrep.totalTypes= 0;
+ }
+ if (rep.reported&XkbGBN_ClientSymbolsMask) {
+ mrep.present|= (XkbKeySymsMask|XkbModifierMapMask);
+ mrep.firstKeySym = mrep.firstModMapKey= new->min_key_code;
+ mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(new);
+ }
+ else {
+ mrep.firstKeySym= mrep.firstModMapKey= 0;
+ mrep.nKeySyms= mrep.nModMapKeys= 0;
+ }
+ if (rep.reported&XkbGBN_ServerSymbolsMask) {
+ mrep.present|= XkbAllServerInfoMask;
+ mrep.virtualMods= ~0;
+ mrep.firstKeyAct = mrep.firstKeyBehavior =
+ mrep.firstKeyExplicit = new->min_key_code;
+ mrep.nKeyActs = mrep.nKeyBehaviors =
+ mrep.nKeyExplicit = XkbNumKeys(new);
+ mrep.firstVModMapKey= new->min_key_code;
+ mrep.nVModMapKeys= XkbNumKeys(new);
+ }
+ else {
+ mrep.virtualMods= 0;
+ mrep.firstKeyAct= mrep.firstKeyBehavior=
+ mrep.firstKeyExplicit = 0;
+ mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0;
+ }
+ XkbComputeGetMapReplySize(new,&mrep);
+ rep.length+= SIZEOF(xGenericReply)/4+mrep.length;
+ }
+ if (new->compat==NULL)
+ rep.reported&= ~XkbGBN_CompatMapMask;
+ else if (rep.reported&XkbGBN_CompatMapMask) {
+ crep.type= X_Reply;
+ crep.deviceID= dev->id;
+ crep.sequenceNumber= client->sequence;
+ crep.length= 0;
+ crep.groups= XkbAllGroupsMask;
+ crep.firstSI= 0;
+ crep.nSI= crep.nTotalSI= new->compat->num_si;
+ XkbComputeGetCompatMapReplySize(new->compat,&crep);
+ rep.length+= SIZEOF(xGenericReply)/4+crep.length;
+ }
+ if (new->indicators==NULL)
+ rep.reported&= ~XkbGBN_IndicatorMapMask;
+ else if (rep.reported&XkbGBN_IndicatorMapMask) {
+ irep.type= X_Reply;
+ irep.deviceID= dev->id;
+ irep.sequenceNumber= client->sequence;
+ irep.length= 0;
+ irep.which= XkbAllIndicatorsMask;
+ XkbComputeGetIndicatorMapReplySize(new->indicators,&irep);
+ rep.length+= SIZEOF(xGenericReply)/4+irep.length;
+ }
+ if (new->names==NULL)
+ rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask);
+ else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) {
+ nrep.type= X_Reply;
+ nrep.deviceID= dev->id;
+ nrep.sequenceNumber= client->sequence;
+ nrep.length= 0;
+ nrep.minKeyCode= new->min_key_code;
+ nrep.maxKeyCode= new->max_key_code;
+ if (rep.reported&XkbGBN_OtherNamesMask) {
+ nrep.which= XkbAllNamesMask;
+ if (new->map!=NULL)
+ nrep.nTypes= new->map->num_types;
+ else nrep.nTypes= 0;
+ nrep.nKTLevels= 0;
+ nrep.groupNames= XkbAllGroupsMask;
+ nrep.virtualMods= XkbAllVirtualModsMask;
+ nrep.indicators= XkbAllIndicatorsMask;
+ nrep.nRadioGroups= new->names->num_rg;
+ }
+ else {
+ nrep.which= 0;
+ nrep.nTypes= 0;
+ nrep.nKTLevels= 0;
+ nrep.groupNames= 0;
+ nrep.virtualMods= 0;
+ nrep.indicators= 0;
+ nrep.nRadioGroups= 0;
+ }
+ if (rep.reported&XkbGBN_KeyNamesMask) {
+ nrep.which|= XkbKeyNamesMask;
+ nrep.firstKey= new->min_key_code;
+ nrep.nKeys= XkbNumKeys(new);
+ nrep.nKeyAliases= new->names->num_key_aliases;
+ if (nrep.nKeyAliases)
+ nrep.which|= XkbKeyAliasesMask;
+ }
+ else {
+ nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask);
+ nrep.firstKey= nrep.nKeys= 0;
+ nrep.nKeyAliases= 0;
+ }
+ XkbComputeGetNamesReplySize(new,&nrep);
+ rep.length+= SIZEOF(xGenericReply)/4+nrep.length;
+ }
+ if (new->geom==NULL)
+ rep.reported&= ~XkbGBN_GeometryMask;
+ else if (rep.reported&XkbGBN_GeometryMask) {
+ grep.type= X_Reply;
+ grep.deviceID= dev->id;
+ grep.sequenceNumber= client->sequence;
+ grep.length= 0;
+ grep.found= TRUE;
+ grep.pad= 0;
+ grep.widthMM= grep.heightMM= 0;
+ grep.nProperties= grep.nColors= grep.nShapes= 0;
+ grep.nSections= grep.nDoodads= 0;
+ grep.baseColorNdx= grep.labelColorNdx= 0;
+ XkbComputeGetGeometryReplySize(new->geom,&grep,None);
+ rep.length+= SIZEOF(xGenericReply)/4+grep.length;
+ }
+ }
+
+ reported= rep.reported;
+ if ( client->swapped ) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.length,n);
+ swaps(&rep.found,n);
+ swaps(&rep.reported,n);
+ }
+ WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep);
+ if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask))
+ XkbSendMap(client,new,&mrep);
+ if (reported&XkbGBN_CompatMapMask)
+ XkbSendCompatMap(client,new->compat,&crep);
+ if (reported&XkbGBN_IndicatorMapMask)
+ XkbSendIndicatorMap(client,new->indicators,&irep);
+ if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask))
+ XkbSendNames(client,new,&nrep);
+ if (reported&XkbGBN_GeometryMask)
+ XkbSendGeometry(client,new->geom,&grep,FALSE);
+ if (rep.loaded) {
+ XkbDescPtr old_xkb;
+ xkbNewKeyboardNotify nkn;
+ int i,nG,nTG;
+ old_xkb= xkb;
+ xkb= new;
+ dev->key->xkbInfo->desc= xkb;
+ new= old_xkb; /* so it'll get freed automatically */
+
+ *xkb->ctrls= *old_xkb->ctrls;
+ for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ nG= XkbKeyNumGroups(xkb,i);
+ if (nG>=XkbNumKbdGroups) {
+ nTG= XkbNumKbdGroups;
+ break;
+ }
+ if (nG>nTG) {
+ nTG= nG;
+ }
+ }
+ xkb->ctrls->num_groups= nTG;
+
+ for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
+ if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
+ if (tmpd != dev)
+ XkbCopyDeviceKeymap(tmpd, dev);
+
+ if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
+ old_sli = tmpd->kbdfeed->xkb_sli;
+ tmpd->kbdfeed->xkb_sli = NULL;
+ sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0);
+ if (sli) {
+ sli->explicitState = old_sli->explicitState;
+ sli->effectiveState = old_sli->effectiveState;
+ }
+ tmpd->kbdfeed->xkb_sli = sli;
+ XkbFreeSrvLedInfo(old_sli);
+ }
+ }
+ }
+
+ nkn.deviceID= nkn.oldDeviceID= dev->id;
+ nkn.minKeyCode= new->min_key_code;
+ nkn.maxKeyCode= new->max_key_code;
+ nkn.oldMinKeyCode= xkb->min_key_code;
+ nkn.oldMaxKeyCode= xkb->max_key_code;
+ nkn.requestMajor= XkbReqCode;
+ nkn.requestMinor= X_kbGetKbdByName;
+ nkn.changed= XkbNKN_KeycodesMask;
+ if (geom_changed)
+ nkn.changed|= XkbNKN_GeometryMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+
+ if (!IsMaster(dev) && dev->u.master)
+ {
+ DeviceIntPtr master = dev->u.master;
+ if (master->u.lastSlave == dev)
+ {
+ XkbCopyDeviceKeymap(dev->u.master, dev);
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ }
+ }
+ }
+ if ((new!=NULL)&&(new!=xkb)) {
+ XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE);
+ new= NULL;
+ }
+ 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;
+}
+
+/***====================================================================***/
+
+static int
+ComputeDeviceLedInfoSize( DeviceIntPtr dev,
+ unsigned int what,
+ XkbSrvLedInfoPtr sli)
+{
+int nNames,nMaps;
+register unsigned n,bit;
+
+ if (sli==NULL)
+ return 0;
+ nNames= nMaps= 0;
+ if ((what&XkbXI_IndicatorNamesMask)==0)
+ sli->namesPresent= 0;
+ if ((what&XkbXI_IndicatorMapsMask)==0)
+ sli->mapsPresent= 0;
+
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (sli->names && sli->names[n]!=None) {
+ sli->namesPresent|= bit;
+ nNames++;
+ }
+ if (sli->maps && XkbIM_InUse(&sli->maps[n])) {
+ sli->mapsPresent|= bit;
+ nMaps++;
+ }
+ }
+ return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc));
+}
+
+static int
+CheckDeviceLedFBs( DeviceIntPtr dev,
+ int class,
+ int id,
+ xkbGetDeviceInfoReply * rep,
+ ClientPtr client)
+{
+int nFBs= 0;
+int length= 0;
+Bool classOk;
+
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ else {
+ client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
+ return XkbKeyboardErrorCode;
+ }
+ }
+ classOk= FALSE;
+ if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
+ KbdFeedbackPtr kf;
+ classOk= TRUE;
+ for (kf= dev->kbdfeed;(kf);kf=kf->next) {
+ if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id))
+ continue;
+ nFBs++;
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (!kf->xkb_sli)
+ kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0);
+ length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
+ LedFeedbackPtr lf;
+ classOk= TRUE;
+ for (lf= dev->leds;(lf);lf=lf->next) {
+ if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id))
+ continue;
+ nFBs++;
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (!lf->xkb_sli)
+ lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0);
+ length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ if (nFBs>0) {
+ rep->nDeviceLedFBs= nFBs;
+ rep->length+= (length/4);
+ return Success;
+ }
+ if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id);
+ else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
+ return XkbKeyboardErrorCode;
+}
+
+static int
+SendDeviceLedInfo( XkbSrvLedInfoPtr sli,
+ ClientPtr client)
+{
+xkbDeviceLedsWireDesc wire;
+int length;
+
+ length= 0;
+ wire.ledClass= sli->class;
+ wire.ledID= sli->id;
+ wire.namesPresent= sli->namesPresent;
+ wire.mapsPresent= sli->mapsPresent;
+ wire.physIndicators= sli->physIndicators;
+ wire.state= sli->effectiveState;
+ if (client->swapped) {
+ register int n;
+ swaps(&wire.ledClass,n);
+ swaps(&wire.ledID,n);
+ swapl(&wire.namesPresent,n);
+ swapl(&wire.mapsPresent,n);
+ swapl(&wire.physIndicators,n);
+ swapl(&wire.state,n);
+ }
+ WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire);
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (sli->namesPresent|sli->mapsPresent) {
+ register unsigned i,bit;
+ if (sli->namesPresent) {
+ CARD32 awire;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (sli->namesPresent&bit) {
+ awire= (CARD32)sli->names[i];
+ if (client->swapped) {
+ register int n;
+ swapl(&awire,n);
+ }
+ WriteToClient(client,4,(char *)&awire);
+ length+= 4;
+ }
+ }
+ }
+ if (sli->mapsPresent) {
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ xkbIndicatorMapWireDesc iwire;
+ if (sli->mapsPresent&bit) {
+ iwire.flags= sli->maps[i].flags;
+ iwire.whichGroups= sli->maps[i].which_groups;
+ iwire.groups= sli->maps[i].groups;
+ iwire.whichMods= sli->maps[i].which_mods;
+ iwire.mods= sli->maps[i].mods.mask;
+ iwire.realMods= sli->maps[i].mods.real_mods;
+ iwire.virtualMods= sli->maps[i].mods.vmods;
+ iwire.ctrls= sli->maps[i].ctrls;
+ if (client->swapped) {
+ register int n;
+ swaps(&iwire.virtualMods,n);
+ swapl(&iwire.ctrls,n);
+ }
+ WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc),
+ (char *)&iwire);
+ length+= SIZEOF(xkbIndicatorMapWireDesc);
+ }
+ }
+ }
+ }
+ return length;
+}
+
+static int
+SendDeviceLedFBs( DeviceIntPtr dev,
+ int class,
+ int id,
+ unsigned wantLength,
+ ClientPtr client)
+{
+int length= 0;
+
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ }
+ if ((dev->kbdfeed)&&
+ ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
+ KbdFeedbackPtr kf;
+ for (kf= dev->kbdfeed;(kf);kf=kf->next) {
+ if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) {
+ length+= SendDeviceLedInfo(kf->xkb_sli,client);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ }
+ if ((dev->leds)&&
+ ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
+ LedFeedbackPtr lf;
+ for (lf= dev->leds;(lf);lf=lf->next) {
+ if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) {
+ length+= SendDeviceLedInfo(lf->xkb_sli,client);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ }
+ if (length==wantLength)
+ return Success;
+ else return BadLength;
+}
+
+int
+ProcXkbGetDeviceInfo(ClientPtr client)
+{
+DeviceIntPtr dev;
+xkbGetDeviceInfoReply rep;
+int status,nDeviceLedFBs;
+unsigned length,nameLen;
+CARD16 ledClass,ledID;
+unsigned wanted;
+char * str;
+
+ REQUEST(xkbGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ wanted= stuff->wanted;
+
+ CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+ CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask);
+
+ if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns)))
+ wanted&= ~XkbXI_ButtonActionsMask;
+ if ((!dev->kbdfeed)&&(!dev->leds))
+ wanted&= ~XkbXI_IndicatorsMask;
+
+ nameLen= XkbSizeCountedString(dev->name);
+ bzero((char *)&rep,SIZEOF(xkbGetDeviceInfoReply));
+ rep.type = X_Reply;
+ rep.deviceID= dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = nameLen/4;
+ rep.present = wanted;
+ rep.supported = XkbXI_AllDeviceFeaturesMask;
+ rep.unsupported = 0;
+ rep.firstBtnWanted = rep.nBtnsWanted = 0;
+ rep.firstBtnRtrn = rep.nBtnsRtrn = 0;
+ if (dev->button)
+ rep.totalBtns= dev->button->numButtons;
+ else rep.totalBtns= 0;
+ rep.devType= dev->xinput_type;
+ rep.hasOwnState= (dev->key && dev->key->xkbInfo);
+ rep.nDeviceLedFBs = 0;
+ if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id;
+ else rep.dfltKbdFB= XkbXINone;
+ if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id;
+ else rep.dfltLedFB= XkbXINone;
+
+ ledClass= stuff->ledClass;
+ ledID= stuff->ledID;
+
+ rep.firstBtnWanted= rep.nBtnsWanted= 0;
+ rep.firstBtnRtrn= rep.nBtnsRtrn= 0;
+ if (wanted&XkbXI_ButtonActionsMask) {
+ if (stuff->allBtns) {
+ stuff->firstBtn= 0;
+ stuff->nBtns= dev->button->numButtons;
+ }
+
+ if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
+ client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons,
+ stuff->firstBtn,
+ stuff->nBtns);
+ return BadValue;
+ }
+ else {
+ rep.firstBtnWanted= stuff->firstBtn;
+ rep.nBtnsWanted= stuff->nBtns;
+ if (dev->button->xkb_acts!=NULL) {
+ XkbAction *act;
+ register int i;
+
+ rep.firstBtnRtrn= stuff->firstBtn;
+ rep.nBtnsRtrn= stuff->nBtns;
+ act= &dev->button->xkb_acts[rep.firstBtnWanted];
+ for (i=0;i<rep.nBtnsRtrn;i++,act++) {
+ if (act->type!=XkbSA_NoAction)
+ break;
+ }
+ rep.firstBtnRtrn+= i;
+ rep.nBtnsRtrn-= i;
+ act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1];
+ for (i=0;i<rep.nBtnsRtrn;i++,act--) {
+ if (act->type!=XkbSA_NoAction)
+ break;
+ }
+ rep.nBtnsRtrn-= i;
+ }
+ rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4;
+ }
+ }
+
+ if (wanted&XkbXI_IndicatorsMask) {
+ status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client);
+ if (status!=Success)
+ return status;
+ }
+ length= rep.length*4;
+ nDeviceLedFBs = rep.nDeviceLedFBs;
+ if (client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.length,n);
+ swaps(&rep.present,n);
+ swaps(&rep.supported,n);
+ swaps(&rep.unsupported,n);
+ swaps(&rep.nDeviceLedFBs,n);
+ swapl(&rep.type,n);
+ }
+ WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep);
+
+ str= malloc(nameLen);
+ if (!str)
+ return BadAlloc;
+ XkbWriteCountedString(str,dev->name,client->swapped);
+ WriteToClient(client,nameLen,str);
+ free(str);
+ length-= nameLen;
+
+ if (rep.nBtnsRtrn>0) {
+ int sz;
+ xkbActionWireDesc * awire;
+ sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc);
+ awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn];
+ WriteToClient(client,sz,(char *)awire);
+ length-= sz;
+ }
+ if (nDeviceLedFBs>0) {
+ status= SendDeviceLedFBs(dev,ledClass,ledID,length,client);
+ if (status!=Success)
+ return status;
+ }
+ else if (length!=0) {
+ ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n");
+ ErrorF("[xkb] Wrote %d fewer bytes than expected\n",length);
+ return BadLength;
+ }
+ return Success;
+}
+
+static char *
+CheckSetDeviceIndicators( char * wire,
+ DeviceIntPtr dev,
+ int num,
+ int * status_rtrn,
+ ClientPtr client)
+{
+xkbDeviceLedsWireDesc * ledWire;
+int i;
+XkbSrvLedInfoPtr sli;
+
+ ledWire= (xkbDeviceLedsWireDesc *)wire;
+ for (i=0;i<num;i++) {
+ if (client->swapped) {
+ register int n;
+ swaps(&ledWire->ledClass,n);
+ swaps(&ledWire->ledID,n);
+ swapl(&ledWire->namesPresent,n);
+ swapl(&ledWire->mapsPresent,n);
+ swapl(&ledWire->physIndicators,n);
+ }
+
+ sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
+ XkbXI_IndicatorsMask);
+ if (sli!=NULL) {
+ register int n;
+ register unsigned bit;
+ int nMaps,nNames;
+ CARD32 *atomWire;
+ xkbIndicatorMapWireDesc *mapWire;
+
+ nMaps= nNames= 0;
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->namesPresent&bit)
+ nNames++;
+ if (ledWire->mapsPresent&bit)
+ nMaps++;
+ }
+ atomWire= (CARD32 *)&ledWire[1];
+ if (nNames>0) {
+ for (n=0;n<nNames;n++) {
+ if (client->swapped) {
+ register int t;
+ swapl(atomWire,t);
+ }
+ CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue,
+ *status_rtrn,NULL);
+ atomWire++;
+ }
+ }
+ mapWire= (xkbIndicatorMapWireDesc *)atomWire;
+ if (nMaps>0) {
+ for (n=0;n<nMaps;n++) {
+ if (client->swapped) {
+ register int t;
+ swaps(&mapWire->virtualMods,t);
+ swapl(&mapWire->ctrls,t);
+ }
+ CHK_MASK_LEGAL3(0x21,mapWire->whichGroups,
+ XkbIM_UseAnyGroup,
+ client->errorValue,
+ *status_rtrn,NULL);
+ CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods,
+ client->errorValue,
+ *status_rtrn,NULL);
+ mapWire++;
+ }
+ }
+ ledWire= (xkbDeviceLedsWireDesc *)mapWire;
+ }
+ else {
+ /* SHOULD NEVER HAPPEN */
+ return (char *)ledWire;
+ }
+ }
+ return (char *)ledWire;
+}
+
+static char *
+SetDeviceIndicators( char * wire,
+ DeviceIntPtr dev,
+ unsigned changed,
+ int num,
+ int * status_rtrn,
+ ClientPtr client,
+ xkbExtensionDeviceNotify *ev)
+{
+xkbDeviceLedsWireDesc * ledWire;
+int i;
+XkbEventCauseRec cause;
+unsigned namec,mapc,statec;
+xkbExtensionDeviceNotify ed;
+XkbChangesRec changes;
+DeviceIntPtr kbd;
+
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client);
+ ledWire= (xkbDeviceLedsWireDesc *)wire;
+ for (i=0;i<num;i++) {
+ register int n;
+ register unsigned bit;
+ CARD32 * atomWire;
+ xkbIndicatorMapWireDesc * mapWire;
+ XkbSrvLedInfoPtr sli;
+
+ namec= mapc= statec= 0;
+ sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
+ XkbXI_IndicatorMapsMask);
+ if (!sli) {
+ /* SHOULD NEVER HAPPEN!! */
+ return (char *)ledWire;
+ }
+
+ atomWire= (CARD32 *)&ledWire[1];
+ if (changed&XkbXI_IndicatorNamesMask) {
+ namec= sli->namesPresent|ledWire->namesPresent;
+ bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
+ }
+ if (ledWire->namesPresent) {
+ sli->namesPresent= ledWire->namesPresent;
+ bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->namesPresent&bit) {
+ sli->names[n]= (Atom)*atomWire;
+ if (sli->names[n]==None)
+ ledWire->namesPresent&= ~bit;
+ atomWire++;
+ }
+ }
+ }
+ mapWire= (xkbIndicatorMapWireDesc *)atomWire;
+ if (changed&XkbXI_IndicatorMapsMask) {
+ mapc= sli->mapsPresent|ledWire->mapsPresent;
+ sli->mapsPresent= ledWire->mapsPresent;
+ bzero((char*)sli->maps,XkbNumIndicators*sizeof(XkbIndicatorMapRec));
+ }
+ if (ledWire->mapsPresent) {
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->mapsPresent&bit) {
+ sli->maps[n].flags= mapWire->flags;
+ sli->maps[n].which_groups= mapWire->whichGroups;
+ sli->maps[n].groups= mapWire->groups;
+ sli->maps[n].which_mods= mapWire->whichMods;
+ sli->maps[n].mods.mask= mapWire->mods;
+ sli->maps[n].mods.real_mods=mapWire->realMods;
+ sli->maps[n].mods.vmods= mapWire->virtualMods;
+ sli->maps[n].ctrls= mapWire->ctrls;
+ mapWire++;
+ }
+ }
+ }
+ if (changed&XkbXI_IndicatorStateMask) {
+ statec= sli->effectiveState^ledWire->state;
+ sli->explicitState&= ~statec;
+ sli->explicitState|= (ledWire->state&statec);
+ }
+ if (namec)
+ XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
+ if (mapc)
+ XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
+ if (statec)
+ XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
+
+ kbd= dev;
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ kbd = inputInfo.keyboard;
+
+ XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause);
+ ledWire= (xkbDeviceLedsWireDesc *)mapWire;
+ }
+ return (char *)ledWire;
+}
+
+
+static int
+_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev,
+ xkbSetDeviceInfoReq *stuff)
+{
+ char *wire;
+
+ wire= (char *)&stuff[1];
+ if (stuff->change&XkbXI_ButtonActionsMask) {
+ if (!dev->button) {
+ client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass);
+ return XkbKeyboardErrorCode;
+ }
+ if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
+ client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns,
+ dev->button->numButtons);
+ return BadMatch;
+ }
+ wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc));
+ }
+ if (stuff->change&XkbXI_IndicatorsMask) {
+ int status= Success;
+ wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs,
+ &status,client);
+ if (status!=Success)
+ return status;
+ }
+ if (((wire-((char *)stuff))/4)!=stuff->length)
+ return BadLength;
+
+ return Success;
+}
+
+static int
+_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
+ xkbSetDeviceInfoReq *stuff)
+{
+ char *wire;
+ xkbExtensionDeviceNotify ed;
+
+ bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
+ ed.deviceID= dev->id;
+ wire= (char *)&stuff[1];
+ if (stuff->change&XkbXI_ButtonActionsMask) {
+ int nBtns,sz,i;
+ XkbAction * acts;
+ DeviceIntPtr kbd;
+
+ nBtns= dev->button->numButtons;
+ acts= dev->button->xkb_acts;
+ if (acts==NULL) {
+ acts= calloc(nBtns, sizeof(XkbAction));
+ if (!acts)
+ return BadAlloc;
+ dev->button->xkb_acts= acts;
+ }
+ sz= stuff->nBtns*SIZEOF(xkbActionWireDesc);
+ memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz);
+ wire+= sz;
+ ed.reason|= XkbXI_ButtonActionsMask;
+ ed.firstBtn= stuff->firstBtn;
+ ed.nBtns= stuff->nBtns;
+
+ if (dev->key) kbd= dev;
+ else kbd= inputInfo.keyboard;
+ acts= &dev->button->xkb_acts[stuff->firstBtn];
+ for (i=0;i<stuff->nBtns;i++,acts++) {
+ if (acts->type!=XkbSA_NoAction)
+ XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0);
+ }
+ }
+ if (stuff->change&XkbXI_IndicatorsMask) {
+ int status= Success;
+ wire= SetDeviceIndicators(wire,dev,stuff->change,
+ stuff->nDeviceLedFBs, &status,client,&ed);
+ if (status!=Success)
+ return status;
+ }
+ if ((stuff->change)&&(ed.reason))
+ XkbSendExtensionDeviceNotify(dev,client,&ed);
+ return Success;
+}
+
+int
+ProcXkbSetDeviceInfo(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ REQUEST(xkbSetDeviceInfoReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_MASK_LEGAL(0x01,stuff->change,XkbXI_AllFeaturesMask);
+
+ rc = _XkbSetDeviceInfoCheck(client, dev, stuff);
+
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (((other != dev) && !IsMaster(other) && (other->u.master == dev)) &&
+ ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
+ (stuff->deviceSpec == XkbUseCorePtr && other->button)))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetDeviceInfoCheck(client, other, stuff);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ /* checks done, apply */
+ rc = _XkbSetDeviceInfo(client, dev, stuff);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (((other != dev) && !IsMaster(other) && (other->u.master == dev)) &&
+ ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
+ (stuff->deviceSpec == XkbUseCorePtr && other->button)))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetDeviceInfo(client, other, stuff);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbSetDebuggingFlags(ClientPtr client)
+{
+CARD32 newFlags,newCtrls,extraLength;
+xkbSetDebuggingFlagsReply rep;
+int rc;
+
+ REQUEST(xkbSetDebuggingFlagsReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq);
+
+ rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess);
+ if (rc != Success)
+ return rc;
+
+ newFlags= xkbDebugFlags&(~stuff->affectFlags);
+ newFlags|= (stuff->flags&stuff->affectFlags);
+ newCtrls= xkbDebugCtrls&(~stuff->affectCtrls);
+ newCtrls|= (stuff->ctrls&stuff->affectCtrls);
+ if (xkbDebugFlags || newFlags || stuff->msgLength) {
+ ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags);
+ if (newCtrls!=xkbDebugCtrls)
+ ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls);
+ }
+ extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq;
+ if (stuff->msgLength>0) {
+ char *msg;
+ if (extraLength<XkbPaddedSize(stuff->msgLength)) {
+ ErrorF("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n",
+ stuff->msgLength,(long)extraLength,
+ XkbPaddedSize(stuff->msgLength));
+ return BadLength;
+ }
+ msg= (char *)&stuff[1];
+ if (msg[stuff->msgLength-1]!='\0') {
+ ErrorF("[xkb] XkbDebug: message not null-terminated\n");
+ return BadValue;
+ }
+ ErrorF("[xkb] XkbDebug: %s\n",msg);
+ }
+ xkbDebugFlags = newFlags;
+ xkbDebugCtrls = newCtrls;
+
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.currentFlags = newFlags;
+ rep.currentCtrls = newCtrls;
+ rep.supportedFlags = ~0;
+ rep.supportedCtrls = ~0;
+ if ( client->swapped ) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.currentFlags, n);
+ swapl(&rep.currentCtrls, n);
+ swapl(&rep.supportedFlags, n);
+ swapl(&rep.supportedCtrls, n);
+ }
+ WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep);
+ return Success;
+}
+
+/***====================================================================***/
+
+static int
+ProcXkbDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_kbUseExtension:
+ return ProcXkbUseExtension(client);
+ case X_kbSelectEvents:
+ return ProcXkbSelectEvents(client);
+ case X_kbBell:
+ return ProcXkbBell(client);
+ case X_kbGetState:
+ return ProcXkbGetState(client);
+ case X_kbLatchLockState:
+ return ProcXkbLatchLockState(client);
+ case X_kbGetControls:
+ return ProcXkbGetControls(client);
+ case X_kbSetControls:
+ return ProcXkbSetControls(client);
+ case X_kbGetMap:
+ return ProcXkbGetMap(client);
+ case X_kbSetMap:
+ return ProcXkbSetMap(client);
+ case X_kbGetCompatMap:
+ return ProcXkbGetCompatMap(client);
+ case X_kbSetCompatMap:
+ return ProcXkbSetCompatMap(client);
+ case X_kbGetIndicatorState:
+ return ProcXkbGetIndicatorState(client);
+ case X_kbGetIndicatorMap:
+ return ProcXkbGetIndicatorMap(client);
+ case X_kbSetIndicatorMap:
+ return ProcXkbSetIndicatorMap(client);
+ case X_kbGetNamedIndicator:
+ return ProcXkbGetNamedIndicator(client);
+ case X_kbSetNamedIndicator:
+ return ProcXkbSetNamedIndicator(client);
+ case X_kbGetNames:
+ return ProcXkbGetNames(client);
+ case X_kbSetNames:
+ return ProcXkbSetNames(client);
+ case X_kbGetGeometry:
+ return ProcXkbGetGeometry(client);
+ case X_kbSetGeometry:
+ return ProcXkbSetGeometry(client);
+ case X_kbPerClientFlags:
+ return ProcXkbPerClientFlags(client);
+ case X_kbListComponents:
+ return ProcXkbListComponents(client);
+ case X_kbGetKbdByName:
+ return ProcXkbGetKbdByName(client);
+ case X_kbGetDeviceInfo:
+ return ProcXkbGetDeviceInfo(client);
+ case X_kbSetDeviceInfo:
+ return ProcXkbSetDeviceInfo(client);
+ case X_kbSetDebuggingFlags:
+ return ProcXkbSetDebuggingFlags(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+XkbClientGone(pointer data,XID id)
+{
+ DevicePtr pXDev = (DevicePtr)data;
+
+ if (!XkbRemoveResourceClient(pXDev,id)) {
+ ErrorF("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n");
+ }
+ return 1;
+}
+
+void
+XkbExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ RT_XKBCLIENT = CreateNewResourceType(XkbClientGone, "XkbClient");
+ if (!RT_XKBCLIENT)
+ return;
+
+ if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors,
+ ProcXkbDispatch, SProcXkbDispatch,
+ NULL, StandardMinorOpcode))) {
+ XkbReqCode = (unsigned char)extEntry->base;
+ XkbEventBase = (unsigned char)extEntry->eventBase;
+ XkbErrorBase = (unsigned char)extEntry->errorBase;
+ XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard;
+ }
+ return;
+}
+
+
diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c
index 6a9943fbc..747f945bb 100644
--- a/xorg-server/xkb/xkbActions.c
+++ b/xorg-server/xkb/xkbActions.c
@@ -1,1389 +1,1389 @@
-/************************************************************
-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 <math.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include "misc.h"
-#include "inputstr.h"
-#include "exevents.h"
-#include "eventstr.h"
-#include <xkbsrv.h>
-#include "xkb.h"
-#include <ctype.h>
-#include "mi.h"
-#define EXTENSION_EVENT_BASE 64
-
-static int xkbDevicePrivateKeyIndex;
-DevPrivateKey xkbDevicePrivateKey = &xkbDevicePrivateKeyIndex;
-
-static void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
-static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y);
-
-void
-xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
- pointer data)
-{
- xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
- ProcessInputProc backupproc;
- if(xkbPrivPtr->unwrapProc)
- xkbPrivPtr->unwrapProc = NULL;
-
- UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc);
- proc(device,data);
- COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
- backupproc,xkbUnwrapProc);
-}
-
-
-void
-XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
-{
- xkbDeviceInfoPtr xkbPrivPtr;
-
- xkbPrivPtr = (xkbDeviceInfoPtr) xcalloc(1, sizeof(xkbDeviceInfoRec));
- if (!xkbPrivPtr)
- return;
- xkbPrivPtr->unwrapProc = NULL;
-
- dixSetPrivate(&device->devPrivates, xkbDevicePrivateKey, xkbPrivPtr);
- WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
-}
-
-/***====================================================================***/
-
-static XkbAction
-_FixUpAction(XkbDescPtr xkb,XkbAction *act)
-{
-static XkbAction fake;
-
- if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
- fake.type = XkbSA_NoAction;
- return fake;
- }
- if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) {
- if (act->any.type==XkbSA_SetMods) {
- fake.mods.type = XkbSA_LatchMods;
- fake.mods.mask = act->mods.mask;
- if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
- fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
- else fake.mods.flags= XkbSA_ClearLocks;
- return fake;
- }
- if (act->any.type==XkbSA_SetGroup) {
- fake.group.type = XkbSA_LatchGroup;
- if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
- fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
- else fake.group.flags= XkbSA_ClearLocks;
- XkbSASetGroup(&fake.group,XkbSAGroup(&act->group));
- return fake;
- }
- }
- return *act;
-}
-
-static XkbAction
-XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
-{
-int effectiveGroup;
-int col;
-XkbDescPtr xkb;
-XkbKeyTypePtr type;
-XkbAction * pActs;
-static XkbAction fake;
-
- xkb= xkbi->desc;
- if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) {
- fake.type = XkbSA_NoAction;
- return fake;
- }
- pActs= XkbKeyActionsPtr(xkb,key);
- col= 0;
-
- effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
- if (effectiveGroup != XkbGroup1Index)
- col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
-
- type= XkbKeyKeyType(xkb,key,effectiveGroup);
- if (type->map!=NULL) {
- register unsigned i,mods;
- register XkbKTMapEntryPtr entry;
- mods= xkbState->mods&type->mods.mask;
- for (entry= type->map,i=0;i<type->map_count;i++,entry++) {
- if ((entry->active)&&(entry->mods.mask==mods)) {
- col+= entry->level;
- break;
- }
- }
- }
- if (pActs[col].any.type==XkbSA_NoAction)
- return pActs[col];
- fake= _FixUpAction(xkb,&pActs[col]);
- return fake;
-}
-
-static XkbAction
-XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
-{
-XkbAction fake;
- if ((dev->button)&&(dev->button->xkb_acts)) {
- if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) {
- fake= _FixUpAction(kbd->key->xkbInfo->desc,
- &dev->button->xkb_acts[button-1]);
- return fake;
- }
- }
- fake.any.type= XkbSA_NoAction;
- return fake;
-}
-
-/***====================================================================***/
-
-#define SYNTHETIC_KEYCODE 1
-#define BTN_ACT_FLAG 0x100
-
-static int
-_XkbFilterSetState( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction *pAction)
-{
- if (filter->keycode==0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
- filter->priv = 0;
- filter->filter = _XkbFilterSetState;
- if (pAction->type==XkbSA_SetMods) {
- filter->upAction = *pAction;
- xkbi->setMods= pAction->mods.mask;
- }
- else {
- xkbi->groupChange = XkbSAGroup(&pAction->group);
- if (pAction->group.flags&XkbSA_GroupAbsolute)
- xkbi->groupChange-= xkbi->state.base_group;
- filter->upAction= *pAction;
- XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
- }
- }
- else if (filter->keycode==keycode) {
- if (filter->upAction.type==XkbSA_SetMods) {
- xkbi->clearMods = filter->upAction.mods.mask;
- if (filter->upAction.mods.flags&XkbSA_ClearLocks) {
- xkbi->state.locked_mods&= ~filter->upAction.mods.mask;
- }
- }
- else {
- if (filter->upAction.group.flags&XkbSA_ClearLocks) {
- xkbi->state.locked_group = 0;
- }
- xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
- }
- filter->active = 0;
- }
- else {
- filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
- filter->filterOthers = 0;
- }
- return 1;
-}
-
-#define LATCH_KEY_DOWN 1
-#define LATCH_PENDING 2
-#define NO_LATCH 3
-
-static int
-_XkbFilterLatchState( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
-
- if (filter->keycode==0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 1;
- filter->priv = LATCH_KEY_DOWN;
- filter->filter = _XkbFilterLatchState;
- if (pAction->type==XkbSA_LatchMods) {
- filter->upAction = *pAction;
- xkbi->setMods = pAction->mods.mask;
- }
- else {
- xkbi->groupChange = XkbSAGroup(&pAction->group);
- if (pAction->group.flags&XkbSA_GroupAbsolute)
- xkbi->groupChange-= xkbi->state.base_group;
- filter->upAction= *pAction;
- XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
- }
- }
- else if ( pAction && (filter->priv==LATCH_PENDING) ) {
- if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) {
- filter->active = 0;
- if (filter->upAction.type==XkbSA_LatchMods)
- xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
- else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
- }
- else if ((pAction->type==filter->upAction.type)&&
- (pAction->mods.flags==filter->upAction.mods.flags)&&
- (pAction->mods.mask==filter->upAction.mods.mask)) {
- if (filter->upAction.mods.flags&XkbSA_LatchToLock) {
- XkbControlsPtr ctrls= xkbi->desc->ctrls;
- if (filter->upAction.type==XkbSA_LatchMods)
- pAction->mods.type= XkbSA_LockMods;
- else pAction->group.type= XkbSA_LockGroup;
- if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&&
- (ctrls->enabled_ctrls&XkbStickyKeysMask)) {
- XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK,
- XkbStickyKeysMask);
- }
- }
- else {
- if (filter->upAction.type==XkbSA_LatchMods)
- pAction->mods.type= XkbSA_SetMods;
- else pAction->group.type= XkbSA_SetGroup;
- }
- if (filter->upAction.type==XkbSA_LatchMods)
- xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
- else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
- filter->active = 0;
- }
- }
- else if (filter->keycode==keycode) { /* release */
- XkbControlsPtr ctrls= xkbi->desc->ctrls;
- int needBeep;
- int beepType= _BEEP_NONE;
-
- needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&&
- XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask));
- if (filter->upAction.type==XkbSA_LatchMods) {
- xkbi->clearMods = filter->upAction.mods.mask;
- if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&&
- (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) {
- xkbi->state.locked_mods&= ~xkbi->clearMods;
- filter->priv= NO_LATCH;
- beepType= _BEEP_STICKY_UNLOCK;
- }
- }
- else {
- xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
- if ((filter->upAction.group.flags&XkbSA_ClearLocks)&&
- (xkbi->state.locked_group)) {
- xkbi->state.locked_group = 0;
- filter->priv = NO_LATCH;
- beepType= _BEEP_STICKY_UNLOCK;
- }
- }
- if (filter->priv==NO_LATCH) {
- filter->active= 0;
- }
- else {
- filter->priv= LATCH_PENDING;
- if (filter->upAction.type==XkbSA_LatchMods) {
- xkbi->state.latched_mods |= filter->upAction.mods.mask;
- needBeep = xkbi->state.latched_mods ? needBeep : 0;
- xkbi->state.latched_mods |= filter->upAction.mods.mask;
- }
- else {
- xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
- }
- if (needBeep && (beepType==_BEEP_NONE))
- beepType= _BEEP_STICKY_LATCH;
- }
- if (needBeep && (beepType!=_BEEP_NONE))
- XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
- }
- else if (filter->priv==LATCH_KEY_DOWN) {
- filter->priv= NO_LATCH;
- filter->filterOthers = 0;
- }
- return 1;
-}
-
-static int
-_XkbFilterLockState( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
- if (pAction&&(pAction->type==XkbSA_LockGroup)) {
- if (pAction->group.flags&XkbSA_GroupAbsolute)
- xkbi->state.locked_group= XkbSAGroup(&pAction->group);
- else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
- return 1;
- }
- if (filter->keycode==0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv = 0;
- filter->filter = _XkbFilterLockState;
- filter->upAction = *pAction;
- xkbi->state.locked_mods^= pAction->mods.mask;
- xkbi->setMods = pAction->mods.mask;
- }
- else if (filter->keycode==keycode) {
- filter->active = 0;
- xkbi->clearMods = filter->upAction.mods.mask;
- }
- return 1;
-}
-
-#define ISO_KEY_DOWN 0
-#define NO_ISO_LOCK 1
-
-static int
-_XkbFilterISOLock( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
-
- if (filter->keycode==0) { /* initial press */
- CARD8 flags= pAction->iso.flags;
-
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 1;
- filter->priv = ISO_KEY_DOWN;
- filter->upAction = *pAction;
- filter->filter = _XkbFilterISOLock;
- if (flags&XkbSA_ISODfltIsGroup) {
- xkbi->groupChange = XkbSAGroup(&pAction->iso);
- xkbi->setMods = 0;
- }
- else {
- xkbi->setMods = pAction->iso.mask;
- xkbi->groupChange = 0;
- }
- if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
- filter->priv= NO_ISO_LOCK;
- xkbi->state.locked_mods^= xkbi->state.base_mods;
- }
- if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
-/* 6/22/93 (ef) -- lock groups if group key is down first */
- }
- if (!(flags&XkbSA_ISONoAffectPtr)) {
-/* 6/22/93 (ef) -- lock mouse buttons if they're down */
- }
- }
- else if (filter->keycode==keycode) {
- CARD8 flags= filter->upAction.iso.flags;
-
- if (flags&XkbSA_ISODfltIsGroup) {
- xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
- xkbi->clearMods = 0;
- if (filter->priv==ISO_KEY_DOWN)
- xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
- }
- else {
- xkbi->clearMods= filter->upAction.iso.mask;
- xkbi->groupChange= 0;
- if (filter->priv==ISO_KEY_DOWN)
- xkbi->state.locked_mods^= filter->upAction.iso.mask;
- }
- filter->active = 0;
- }
- else if (pAction) {
- CARD8 flags= filter->upAction.iso.flags;
-
- switch (pAction->type) {
- case XkbSA_SetMods: case XkbSA_LatchMods:
- if (!(flags&XkbSA_ISONoAffectMods)) {
- pAction->type= XkbSA_LockMods;
- filter->priv= NO_ISO_LOCK;
- }
- break;
- case XkbSA_SetGroup: case XkbSA_LatchGroup:
- if (!(flags&XkbSA_ISONoAffectGroup)) {
- pAction->type= XkbSA_LockGroup;
- filter->priv= NO_ISO_LOCK;
- }
- break;
- case XkbSA_PtrBtn:
- if (!(flags&XkbSA_ISONoAffectPtr)) {
- pAction->type= XkbSA_LockPtrBtn;
- filter->priv= NO_ISO_LOCK;
- }
- break;
- case XkbSA_SetControls:
- if (!(flags&XkbSA_ISONoAffectCtrls)) {
- pAction->type= XkbSA_LockControls;
- filter->priv= NO_ISO_LOCK;
- }
- break;
- }
- }
- return 1;
-}
-
-
-static CARD32
-_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg)
-{
-XkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg;
-XkbControlsPtr ctrls= xkbi->desc->ctrls;
-int dx,dy;
-
- if (xkbi->mouseKey==0)
- return 0;
-
- if (xkbi->mouseKeysAccel) {
- if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
- double step;
- xkbi->mouseKeysCounter++;
- step= xkbi->mouseKeysCurveFactor*
- pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve);
- if (xkbi->mouseKeysDX<0)
- dx= floor( ((double)xkbi->mouseKeysDX)*step );
- else dx= ceil( ((double)xkbi->mouseKeysDX)*step );
- if (xkbi->mouseKeysDY<0)
- dy= floor( ((double)xkbi->mouseKeysDY)*step );
- else dy= ceil( ((double)xkbi->mouseKeysDY)*step );
- }
- else {
- dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
- dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
- }
- if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
- dx= xkbi->mouseKeysDX;
- if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
- dy= xkbi->mouseKeysDY;
- }
- else {
- dx= xkbi->mouseKeysDX;
- dy= xkbi->mouseKeysDY;
- }
- XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
- return xkbi->desc->ctrls->mk_interval;
-}
-
-static int
-_XkbFilterPointerMove( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
-int x,y;
-Bool accel;
-
- if (xkbi->device == inputInfo.keyboard)
- return 0;
-
- if (filter->keycode==0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv=0;
- filter->filter = _XkbFilterPointerMove;
- filter->upAction= *pAction;
- xkbi->mouseKeysCounter= 0;
- xkbi->mouseKey= keycode;
- accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
- x= XkbPtrActionX(&pAction->ptr);
- y= XkbPtrActionY(&pAction->ptr);
- XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y);
- AccessXCancelRepeatKey(xkbi,keycode);
- xkbi->mouseKeysAccel= accel&&
- (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
- xkbi->mouseKeysFlags= pAction->ptr.flags;
- xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr);
- xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr);
- xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0,
- xkbi->desc->ctrls->mk_delay,
- _XkbPtrAccelExpire,(pointer)xkbi);
- }
- else if (filter->keycode==keycode) {
- filter->active = 0;
- if (xkbi->mouseKey==keycode) {
- xkbi->mouseKey= 0;
- xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
- NULL, NULL);
- }
- }
- return 0;
-}
-
-static int
-_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
- if (filter->keycode==0) { /* initial press */
- int button= pAction->btn.button;
-
- if (button==XkbSA_UseDfltButton)
- button = xkbi->desc->ctrls->mk_dflt_btn;
-
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv=0;
- filter->filter = _XkbFilterPointerBtn;
- filter->upAction= *pAction;
- filter->upAction.btn.button= button;
- switch (pAction->type) {
- case XkbSA_LockPtrBtn:
- if (((xkbi->lockedPtrButtons&(1<<button))==0)&&
- ((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
- xkbi->lockedPtrButtons|= (1<<button);
- AccessXCancelRepeatKey(xkbi,keycode);
- XkbFakeDeviceButton(xkbi->device, 1, button);
- filter->upAction.type= XkbSA_NoAction;
- }
- break;
- case XkbSA_PtrBtn:
- {
- register int i,nClicks;
- AccessXCancelRepeatKey(xkbi,keycode);
- if (pAction->btn.count>0) {
- nClicks= pAction->btn.count;
- for (i=0;i<nClicks;i++) {
- XkbFakeDeviceButton(xkbi->device, 1, button);
- XkbFakeDeviceButton(xkbi->device, 0, button);
- }
- filter->upAction.type= XkbSA_NoAction;
- }
- else XkbFakeDeviceButton(xkbi->device, 1, button);
- }
- break;
- case XkbSA_SetPtrDflt:
- {
- XkbControlsPtr ctrls= xkbi->desc->ctrls;
- XkbControlsRec old;
- xkbControlsNotify cn;
-
- old= *ctrls;
- AccessXCancelRepeatKey(xkbi,keycode);
- switch (pAction->dflt.affect) {
- case XkbSA_AffectDfltBtn:
- if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
- ctrls->mk_dflt_btn=
- XkbSAPtrDfltValue(&pAction->dflt);
- else {
- ctrls->mk_dflt_btn+=
- XkbSAPtrDfltValue(&pAction->dflt);
- if (ctrls->mk_dflt_btn>5)
- ctrls->mk_dflt_btn= 5;
- else if (ctrls->mk_dflt_btn<1)
- ctrls->mk_dflt_btn= 1;
- }
- break;
- default:
- ErrorF(
- "Attempt to change unknown pointer default (%d) ignored\n",
- pAction->dflt.affect);
- break;
- }
- if (XkbComputeControlsNotify(xkbi->device,
- &old,xkbi->desc->ctrls,
- &cn,FALSE)) {
- cn.keycode = keycode;
- /* XXX: what about DeviceKeyPress? */
- cn.eventType = KeyPress;
- cn.requestMajor = 0;
- cn.requestMinor = 0;
- XkbSendControlsNotify(xkbi->device,&cn);
- }
- }
- break;
- }
- }
- else if (filter->keycode==keycode) {
- int button= filter->upAction.btn.button;
-
- switch (filter->upAction.type) {
- case XkbSA_LockPtrBtn:
- if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
- ((xkbi->lockedPtrButtons&(1<<button))==0)) {
- break;
- }
- xkbi->lockedPtrButtons&= ~(1<<button);
- case XkbSA_PtrBtn:
- XkbFakeDeviceButton(xkbi->device, 0, button);
- break;
- }
- filter->active = 0;
- }
- return 0;
-}
-
-static int
-_XkbFilterControls( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
-XkbControlsRec old;
-XkbControlsPtr ctrls;
-DeviceIntPtr kbd;
-unsigned int change;
-XkbEventCauseRec cause;
-
- kbd= xkbi->device;
- ctrls= xkbi->desc->ctrls;
- old= *ctrls;
- if (filter->keycode==0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- change= XkbActionCtrls(&pAction->ctrls);
- filter->priv = change;
- filter->filter = _XkbFilterControls;
- filter->upAction = *pAction;
-
- if (pAction->type==XkbSA_LockControls) {
- filter->priv= (ctrls->enabled_ctrls&change);
- change&= ~ctrls->enabled_ctrls;
- }
-
- if (change) {
- xkbControlsNotify cn;
- XkbSrvLedInfoPtr sli;
-
- ctrls->enabled_ctrls|= change;
- if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
- cn.keycode = keycode;
- /* XXX: what about DeviceKeyPress? */
- cn.eventType = KeyPress;
- cn.requestMajor = 0;
- cn.requestMinor = 0;
- XkbSendControlsNotify(kbd,&cn);
- }
-
- XkbSetCauseKey(&cause,keycode,KeyPress);
-
- /* If sticky keys were disabled, clear all locks and latches */
- if ((old.enabled_ctrls&XkbStickyKeysMask)&&
- (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
- XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
- }
- sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
- XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
- if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
- XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change);
- }
- }
- else if (filter->keycode==keycode) {
- change= filter->priv;
- if (change) {
- xkbControlsNotify cn;
- XkbSrvLedInfoPtr sli;
-
- ctrls->enabled_ctrls&= ~change;
- if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
- cn.keycode = keycode;
- cn.eventType = KeyRelease;
- cn.requestMajor = 0;
- cn.requestMinor = 0;
- XkbSendControlsNotify(kbd,&cn);
- }
-
- XkbSetCauseKey(&cause,keycode,KeyRelease);
- /* If sticky keys were disabled, clear all locks and latches */
- if ((old.enabled_ctrls&XkbStickyKeysMask)&&
- (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
- XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
- }
- sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
- XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
- if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
- XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change);
- }
- filter->keycode= 0;
- filter->active= 0;
- }
- return 1;
-}
-
-static int
-_XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
-XkbMessageAction * pMsg;
-DeviceIntPtr kbd;
-
- kbd= xkbi->device;
- if (filter->keycode==0) { /* initial press */
- pMsg= &pAction->msg;
- if ((pMsg->flags&XkbSA_MessageOnRelease)||
- ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv = 0;
- filter->filter = _XkbFilterActionMessage;
- filter->upAction = *pAction;
- }
- if (pMsg->flags&XkbSA_MessageOnPress) {
- xkbActionMessage msg;
-
- msg.keycode= keycode;
- msg.press= 1;
- msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
- memcpy((char *)msg.message,
- (char *)pMsg->message,XkbActionMessageLength);
- XkbSendActionMessage(kbd,&msg);
- }
- return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
- }
- else if (filter->keycode==keycode) {
- pMsg= &filter->upAction.msg;
- if (pMsg->flags&XkbSA_MessageOnRelease) {
- xkbActionMessage msg;
-
- msg.keycode= keycode;
- msg.press= 0;
- msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
- memcpy((char *)msg.message,(char *)pMsg->message,
- XkbActionMessageLength);
- XkbSendActionMessage(kbd,&msg);
- }
- filter->keycode= 0;
- filter->active= 0;
- return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
- }
- return 0;
-}
-
-static int
-_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
-DeviceEvent ev;
-int x,y;
-XkbStateRec old;
-unsigned mods,mask;
-xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
-ProcessInputProc backupproc;
-
- /* never actually used uninitialised, but gcc isn't smart enough
- * to work that out. */
- memset(&old, 0, sizeof(old));
-
- if ((filter->keycode!=0)&&(filter->keycode!=keycode))
- return 1;
-
- GetSpritePosition(xkbi->device, &x,&y);
- ev.header = ET_Internal;
- ev.length = sizeof(DeviceEvent);
- ev.time = GetTimeInMillis();
- ev.root_x = x;
- ev.root_y = y;
-
- if (filter->keycode==0) { /* initial press */
- if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
- (pAction->redirect.new_key>xkbi->desc->max_key_code)) {
- return 1;
- }
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv = 0;
- filter->filter = _XkbFilterRedirectKey;
- filter->upAction = *pAction;
-
- ev.type = ET_KeyPress;
- ev.detail.key = pAction->redirect.new_key;
-
- mask= XkbSARedirectVModsMask(&pAction->redirect);
- mods= XkbSARedirectVMods(&pAction->redirect);
- if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
- if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
- mask|= pAction->redirect.mods_mask;
- mods|= pAction->redirect.mods;
-
- if ( mask || mods ) {
- old= xkbi->state;
- xkbi->state.base_mods&= ~mask;
- xkbi->state.base_mods|= (mods&mask);
- xkbi->state.latched_mods&= ~mask;
- xkbi->state.latched_mods|= (mods&mask);
- xkbi->state.locked_mods&= ~mask;
- xkbi->state.locked_mods|= (mods&mask);
- XkbComputeDerivedState(xkbi);
- }
-
- UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
- xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
- COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
- backupproc,xkbUnwrapProc);
-
- if ( mask || mods )
- xkbi->state= old;
- }
- else if (filter->keycode==keycode) {
-
- ev.type = ET_KeyRelease;
- ev.detail.key = filter->upAction.redirect.new_key;
-
- mask= XkbSARedirectVModsMask(&filter->upAction.redirect);
- mods= XkbSARedirectVMods(&filter->upAction.redirect);
- if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
- if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
- mask|= filter->upAction.redirect.mods_mask;
- mods|= filter->upAction.redirect.mods;
-
- if ( mask || mods ) {
- old= xkbi->state;
- xkbi->state.base_mods&= ~mask;
- xkbi->state.base_mods|= (mods&mask);
- xkbi->state.latched_mods&= ~mask;
- xkbi->state.latched_mods|= (mods&mask);
- xkbi->state.locked_mods&= ~mask;
- xkbi->state.locked_mods|= (mods&mask);
- XkbComputeDerivedState(xkbi);
- }
-
- UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
- xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
- COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
- backupproc,xkbUnwrapProc);
-
- if ( mask || mods )
- xkbi->state= old;
-
- filter->keycode= 0;
- filter->active= 0;
- }
- return 0;
-}
-
-static int
-_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
- DeviceIntPtr dev = xkbi->device;
- if (dev == inputInfo.keyboard)
- return 0;
-
- if (filter->keycode==0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->filter = _XkbFilterSwitchScreen;
- AccessXCancelRepeatKey(xkbi, keycode);
- XkbDDXSwitchScreen(dev,keycode,pAction);
- return 0;
- }
- else if (filter->keycode==keycode) {
- filter->active= 0;
- return 0;
- }
- return 1;
-}
-
-static int
-_XkbFilterXF86Private( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
- DeviceIntPtr dev = xkbi->device;
- if (dev == inputInfo.keyboard)
- return 0;
-
- if (filter->keycode==0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->filter = _XkbFilterXF86Private;
- XkbDDXPrivate(dev,keycode,pAction);
- return 0;
- }
- else if (filter->keycode==keycode) {
- filter->active= 0;
- return 0;
- }
- return 1;
-}
-
-
-static int
-_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode,
- XkbAction * pAction)
-{
-DeviceIntPtr dev;
-int button;
-
- if (xkbi->device == inputInfo.keyboard)
- return 0;
-
- if (filter->keycode==0) { /* initial press */
- _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
- DixUnknownAccess, &button);
- if (!dev || !dev->public.on)
- return 1;
-
- button= pAction->devbtn.button;
- if ((button<1)||(button>dev->button->numButtons))
- return 1;
-
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv=0;
- filter->filter = _XkbFilterDeviceBtn;
- filter->upAction= *pAction;
- switch (pAction->type) {
- case XkbSA_LockDeviceBtn:
- if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
- BitIsOn(dev->button->down, button))
- return 0;
- XkbFakeDeviceButton(dev,TRUE,button);
- filter->upAction.type= XkbSA_NoAction;
- break;
- case XkbSA_DeviceBtn:
- if (pAction->devbtn.count>0) {
- int nClicks,i;
- nClicks= pAction->btn.count;
- for (i=0;i<nClicks;i++) {
- XkbFakeDeviceButton(dev,TRUE,button);
- XkbFakeDeviceButton(dev,FALSE,button);
- }
- filter->upAction.type= XkbSA_NoAction;
- }
- else XkbFakeDeviceButton(dev,TRUE,button);
- break;
- }
- }
- else if (filter->keycode==keycode) {
- int button;
-
- filter->active= 0;
- _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
- serverClient, DixUnknownAccess, &button);
- if (!dev || !dev->public.on)
- return 1;
-
- button= filter->upAction.btn.button;
- switch (filter->upAction.type) {
- case XkbSA_LockDeviceBtn:
- if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
- !BitIsOn(dev->button->down, button))
- return 0;
- XkbFakeDeviceButton(dev,FALSE,button);
- break;
- case XkbSA_DeviceBtn:
- XkbFakeDeviceButton(dev,FALSE,button);
- break;
- }
- filter->active = 0;
- }
- return 0;
-}
-
-static XkbFilterPtr
-_XkbNextFreeFilter(
- XkbSrvInfoPtr xkbi
-)
-{
-register int i;
-
- if (xkbi->szFilters==0) {
- xkbi->szFilters = 4;
- xkbi->filters = xcalloc(xkbi->szFilters, sizeof(XkbFilterRec));
- /* 6/21/93 (ef) -- XXX! deal with allocation failure */
- }
- for (i=0;i<xkbi->szFilters;i++) {
- if (!xkbi->filters[i].active) {
- xkbi->filters[i].keycode = 0;
- return &xkbi->filters[i];
- }
- }
- xkbi->szFilters*=2;
- xkbi->filters= xrealloc(xkbi->filters,
- xkbi->szFilters * sizeof(XkbFilterRec));
- /* 6/21/93 (ef) -- XXX! deal with allocation failure */
- bzero(&xkbi->filters[xkbi->szFilters/2],
- (xkbi->szFilters/2)*sizeof(XkbFilterRec));
- return &xkbi->filters[xkbi->szFilters/2];
-}
-
-static int
-_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
-{
-register int i,send;
-
- send= 1;
- for (i=0;i<xkbi->szFilters;i++) {
- if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter))
- send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction)
- && send);
- }
- return send;
-}
-
-void
-XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event)
-{
-int key,bit,i;
-XkbSrvInfoPtr xkbi;
-KeyClassPtr keyc;
-int changed,sendEvent;
-Bool genStateNotify;
-XkbAction act;
-XkbFilterPtr filter;
-Bool keyEvent;
-Bool pressEvent;
-ProcessInputProc backupproc;
-
-xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
-
- keyc= kbd->key;
- xkbi= keyc->xkbInfo;
- key= event->detail.key;
- /* The state may change, so if we're not in the middle of sending a state
- * notify, prepare for it */
- if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
- xkbi->prev_state = xkbi->state;
- xkbi->flags|= _XkbStateNotifyInProgress;
- genStateNotify= TRUE;
- }
- else genStateNotify= FALSE;
-
- xkbi->clearMods = xkbi->setMods = 0;
- xkbi->groupChange = 0;
-
- sendEvent = 1;
- keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
- pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress));
-
- if (pressEvent) {
- if (keyEvent)
- act = XkbGetKeyAction(xkbi,&xkbi->state,key);
- else {
- act = XkbGetButtonAction(kbd,dev,key);
- key|= BTN_ACT_FLAG;
- }
- sendEvent = _XkbApplyFilters(xkbi,key,&act);
- if (sendEvent) {
- switch (act.type) {
- case XkbSA_SetMods:
- case XkbSA_SetGroup:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
- break;
- case XkbSA_LatchMods:
- case XkbSA_LatchGroup:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
- break;
- case XkbSA_LockMods:
- case XkbSA_LockGroup:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
- break;
- case XkbSA_ISOLock:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
- break;
- case XkbSA_MovePtr:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
- break;
- case XkbSA_PtrBtn:
- case XkbSA_LockPtrBtn:
- case XkbSA_SetPtrDflt:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
- break;
- case XkbSA_Terminate:
- sendEvent= XkbDDXTerminateServer(dev,key,&act);
- break;
- case XkbSA_SwitchScreen:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
- break;
- case XkbSA_SetControls:
- case XkbSA_LockControls:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
- break;
- case XkbSA_ActionMessage:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
- break;
- case XkbSA_RedirectKey:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
- break;
- case XkbSA_DeviceBtn:
- case XkbSA_LockDeviceBtn:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
- break;
- case XkbSA_XFree86Private:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
- break;
- }
- }
- }
- else {
- if (!keyEvent)
- key|= BTN_ACT_FLAG;
- sendEvent = _XkbApplyFilters(xkbi,key,NULL);
- }
-
- if (xkbi->groupChange!=0)
- xkbi->state.base_group+= xkbi->groupChange;
- if (xkbi->setMods) {
- for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) {
- if (xkbi->setMods&bit) {
- keyc->modifierKeyCount[i]++;
- xkbi->state.base_mods|= bit;
- xkbi->setMods&= ~bit;
- }
- }
- }
- if (xkbi->clearMods) {
- for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) {
- if (xkbi->clearMods&bit) {
- keyc->modifierKeyCount[i]--;
- if (keyc->modifierKeyCount[i]<=0) {
- xkbi->state.base_mods&= ~bit;
- keyc->modifierKeyCount[i] = 0;
- }
- xkbi->clearMods&= ~bit;
- }
- }
- }
-
- if (sendEvent) {
- DeviceIntPtr tmpdev;
- if (keyEvent)
- tmpdev = dev;
- else
- tmpdev = GetPairedDevice(dev);
-
- UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc);
- dev->public.processInputProc((InternalEvent*)event, tmpdev);
- COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
- backupproc,xkbUnwrapProc);
- }
- else if (keyEvent) {
- FixKeyState(event, dev);
- }
-
- XkbComputeDerivedState(xkbi);
- changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state);
- if (genStateNotify) {
- if (changed) {
- xkbStateNotify sn;
- sn.keycode= key;
- sn.eventType= event->type;
- sn.requestMajor = sn.requestMinor = 0;
- sn.changed= changed;
- XkbSendStateNotify(dev,&sn);
- }
- xkbi->flags&= ~_XkbStateNotifyInProgress;
- }
- changed= XkbIndicatorsToUpdate(dev,changed,FALSE);
- if (changed) {
- XkbEventCauseRec cause;
- XkbSetCauseKey(&cause, key, event->type);
- XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause);
- }
- return;
-}
-
-int
-XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
-{
-XkbSrvInfoPtr xkbi;
-XkbFilterPtr filter;
-XkbAction act;
-unsigned clear;
-
- if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
- xkbi = pXDev->key->xkbInfo;
- clear= (mask&(~latches));
- xkbi->state.latched_mods&= ~clear;
- /* Clear any pending latch to locks.
- */
- act.type = XkbSA_NoAction;
- _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
- act.type = XkbSA_LatchMods;
- act.mods.flags = 0;
- act.mods.mask = mask&latches;
- filter = _XkbNextFreeFilter(xkbi);
- _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
- _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
- return Success;
- }
- return BadValue;
-}
-
-int
-XkbLatchGroup(DeviceIntPtr pXDev,int group)
-{
-XkbSrvInfoPtr xkbi;
-XkbFilterPtr filter;
-XkbAction act;
-
- if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
- xkbi = pXDev->key->xkbInfo;
- act.type = XkbSA_LatchGroup;
- act.group.flags = 0;
- XkbSASetGroup(&act.group,group);
- filter = _XkbNextFreeFilter(xkbi);
- _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
- _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
- return Success;
- }
- return BadValue;
-}
-
-/***====================================================================***/
-
-void
-XkbClearAllLatchesAndLocks( DeviceIntPtr dev,
- XkbSrvInfoPtr xkbi,
- Bool genEv,
- XkbEventCausePtr cause)
-{
-XkbStateRec os;
-xkbStateNotify sn;
-
- sn.changed= 0;
- os= xkbi->state;
- if (os.latched_mods) { /* clear all latches */
- XkbLatchModifiers(dev,~0,0);
- sn.changed|= XkbModifierLatchMask;
- }
- if (os.latched_group) {
- XkbLatchGroup(dev,0);
- sn.changed|= XkbGroupLatchMask;
- }
- if (os.locked_mods) {
- xkbi->state.locked_mods= 0;
- sn.changed|= XkbModifierLockMask;
- }
- if (os.locked_group) {
- xkbi->state.locked_group= 0;
- sn.changed|= XkbGroupLockMask;
- }
- if ( genEv && sn.changed) {
- CARD32 changed;
-
- XkbComputeDerivedState(xkbi);
- sn.keycode= cause->kc;
- sn.eventType= cause->event;
- sn.requestMajor= cause->mjr;
- sn.requestMinor= cause->mnr;
- sn.changed= XkbStateChangedFlags(&os,&xkbi->state);
- XkbSendStateNotify(dev,&sn);
- changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE);
- if (changed) {
- XkbUpdateIndicators(dev,changed,TRUE,NULL,cause);
- }
- }
- return;
-}
-
-static void
-XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
-{
- EventListPtr events;
- int nevents, i;
- DeviceIntPtr ptr;
- int gpe_flags = 0;
-
- if (!dev->u.master)
- ptr = dev;
- else
- ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
-
- if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
- gpe_flags = POINTER_ABSOLUTE;
- else
- gpe_flags = POINTER_RELATIVE;
-
- events = InitEventList(GetMaximumEventsNum());
- OsBlockSignals();
- nevents = GetPointerEvents(events, ptr,
- MotionNotify, 0,
- gpe_flags, 0, 2, (int[]){x, y});
- OsReleaseSignals();
-
- for (i = 0; i < nevents; i++)
- mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
-
- FreeEventList(events, GetMaximumEventsNum());
-}
-
-static void
-XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
-{
- EventListPtr events;
- int nevents, i;
- DeviceIntPtr ptr;
-
- /* If dev is a slave device, and the SD is attached, do nothing. If we'd
- * post through the attached master pointer we'd get duplicate events.
- *
- * if dev is a master keyboard, post through the XTEST device
- *
- * if dev is a floating slave, post through the device itself.
- */
-
- if (IsMaster(dev))
- ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
- else if (!dev->u.master)
- ptr = dev;
- else
- return;
-
- events = InitEventList(GetMaximumEventsNum());
- OsBlockSignals();
- nevents = GetPointerEvents(events, ptr,
- press ? ButtonPress : ButtonRelease, button,
- 0 /* flags */, 0 /* first */,
- 0 /* num_val */, NULL);
- OsReleaseSignals();
-
-
- for (i = 0; i < nevents; i++)
- mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
-
- FreeEventList(events, GetMaximumEventsNum());
-}
+/************************************************************
+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 <math.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "exevents.h"
+#include "eventstr.h"
+#include <xkbsrv.h>
+#include "xkb.h"
+#include <ctype.h>
+#include "mi.h"
+#define EXTENSION_EVENT_BASE 64
+
+static int xkbDevicePrivateKeyIndex;
+DevPrivateKey xkbDevicePrivateKey = &xkbDevicePrivateKeyIndex;
+
+static void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
+static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y);
+
+void
+xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
+ pointer data)
+{
+ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
+ ProcessInputProc backupproc;
+ if(xkbPrivPtr->unwrapProc)
+ xkbPrivPtr->unwrapProc = NULL;
+
+ UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc);
+ proc(device,data);
+ COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
+ backupproc,xkbUnwrapProc);
+}
+
+
+void
+XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
+{
+ xkbDeviceInfoPtr xkbPrivPtr;
+
+ xkbPrivPtr = (xkbDeviceInfoPtr) calloc(1, sizeof(xkbDeviceInfoRec));
+ if (!xkbPrivPtr)
+ return;
+ xkbPrivPtr->unwrapProc = NULL;
+
+ dixSetPrivate(&device->devPrivates, xkbDevicePrivateKey, xkbPrivPtr);
+ WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
+}
+
+/***====================================================================***/
+
+static XkbAction
+_FixUpAction(XkbDescPtr xkb,XkbAction *act)
+{
+static XkbAction fake;
+
+ if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
+ fake.type = XkbSA_NoAction;
+ return fake;
+ }
+ if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) {
+ if (act->any.type==XkbSA_SetMods) {
+ fake.mods.type = XkbSA_LatchMods;
+ fake.mods.mask = act->mods.mask;
+ if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
+ fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
+ else fake.mods.flags= XkbSA_ClearLocks;
+ return fake;
+ }
+ if (act->any.type==XkbSA_SetGroup) {
+ fake.group.type = XkbSA_LatchGroup;
+ if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
+ fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
+ else fake.group.flags= XkbSA_ClearLocks;
+ XkbSASetGroup(&fake.group,XkbSAGroup(&act->group));
+ return fake;
+ }
+ }
+ return *act;
+}
+
+static XkbAction
+XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
+{
+int effectiveGroup;
+int col;
+XkbDescPtr xkb;
+XkbKeyTypePtr type;
+XkbAction * pActs;
+static XkbAction fake;
+
+ xkb= xkbi->desc;
+ if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) {
+ fake.type = XkbSA_NoAction;
+ return fake;
+ }
+ pActs= XkbKeyActionsPtr(xkb,key);
+ col= 0;
+
+ effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
+ if (effectiveGroup != XkbGroup1Index)
+ col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
+
+ type= XkbKeyKeyType(xkb,key,effectiveGroup);
+ if (type->map!=NULL) {
+ register unsigned i,mods;
+ register XkbKTMapEntryPtr entry;
+ mods= xkbState->mods&type->mods.mask;
+ for (entry= type->map,i=0;i<type->map_count;i++,entry++) {
+ if ((entry->active)&&(entry->mods.mask==mods)) {
+ col+= entry->level;
+ break;
+ }
+ }
+ }
+ if (pActs[col].any.type==XkbSA_NoAction)
+ return pActs[col];
+ fake= _FixUpAction(xkb,&pActs[col]);
+ return fake;
+}
+
+static XkbAction
+XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
+{
+XkbAction fake;
+ if ((dev->button)&&(dev->button->xkb_acts)) {
+ if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) {
+ fake= _FixUpAction(kbd->key->xkbInfo->desc,
+ &dev->button->xkb_acts[button-1]);
+ return fake;
+ }
+ }
+ fake.any.type= XkbSA_NoAction;
+ return fake;
+}
+
+/***====================================================================***/
+
+#define SYNTHETIC_KEYCODE 1
+#define BTN_ACT_FLAG 0x100
+
+static int
+_XkbFilterSetState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction *pAction)
+{
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
+ filter->priv = 0;
+ filter->filter = _XkbFilterSetState;
+ if (pAction->type==XkbSA_SetMods) {
+ filter->upAction = *pAction;
+ xkbi->setMods= pAction->mods.mask;
+ }
+ else {
+ xkbi->groupChange = XkbSAGroup(&pAction->group);
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->groupChange-= xkbi->state.base_group;
+ filter->upAction= *pAction;
+ XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
+ }
+ }
+ else if (filter->keycode==keycode) {
+ if (filter->upAction.type==XkbSA_SetMods) {
+ xkbi->clearMods = filter->upAction.mods.mask;
+ if (filter->upAction.mods.flags&XkbSA_ClearLocks) {
+ xkbi->state.locked_mods&= ~filter->upAction.mods.mask;
+ }
+ }
+ else {
+ if (filter->upAction.group.flags&XkbSA_ClearLocks) {
+ xkbi->state.locked_group = 0;
+ }
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+ }
+ filter->active = 0;
+ }
+ else {
+ filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
+ filter->filterOthers = 0;
+ }
+ return 1;
+}
+
+#define LATCH_KEY_DOWN 1
+#define LATCH_PENDING 2
+#define NO_LATCH 3
+
+static int
+_XkbFilterLatchState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 1;
+ filter->priv = LATCH_KEY_DOWN;
+ filter->filter = _XkbFilterLatchState;
+ if (pAction->type==XkbSA_LatchMods) {
+ filter->upAction = *pAction;
+ xkbi->setMods = pAction->mods.mask;
+ }
+ else {
+ xkbi->groupChange = XkbSAGroup(&pAction->group);
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->groupChange-= xkbi->state.base_group;
+ filter->upAction= *pAction;
+ XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
+ }
+ }
+ else if ( pAction && (filter->priv==LATCH_PENDING) ) {
+ if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) {
+ filter->active = 0;
+ if (filter->upAction.type==XkbSA_LatchMods)
+ xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
+ else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
+ }
+ else if ((pAction->type==filter->upAction.type)&&
+ (pAction->mods.flags==filter->upAction.mods.flags)&&
+ (pAction->mods.mask==filter->upAction.mods.mask)) {
+ if (filter->upAction.mods.flags&XkbSA_LatchToLock) {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ if (filter->upAction.type==XkbSA_LatchMods)
+ pAction->mods.type= XkbSA_LockMods;
+ else pAction->group.type= XkbSA_LockGroup;
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&&
+ (ctrls->enabled_ctrls&XkbStickyKeysMask)) {
+ XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK,
+ XkbStickyKeysMask);
+ }
+ }
+ else {
+ if (filter->upAction.type==XkbSA_LatchMods)
+ pAction->mods.type= XkbSA_SetMods;
+ else pAction->group.type= XkbSA_SetGroup;
+ }
+ if (filter->upAction.type==XkbSA_LatchMods)
+ xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
+ else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
+ filter->active = 0;
+ }
+ }
+ else if (filter->keycode==keycode) { /* release */
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ int needBeep;
+ int beepType= _BEEP_NONE;
+
+ needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&&
+ XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask));
+ if (filter->upAction.type==XkbSA_LatchMods) {
+ xkbi->clearMods = filter->upAction.mods.mask;
+ if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&&
+ (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) {
+ xkbi->state.locked_mods&= ~xkbi->clearMods;
+ filter->priv= NO_LATCH;
+ beepType= _BEEP_STICKY_UNLOCK;
+ }
+ }
+ else {
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+ if ((filter->upAction.group.flags&XkbSA_ClearLocks)&&
+ (xkbi->state.locked_group)) {
+ xkbi->state.locked_group = 0;
+ filter->priv = NO_LATCH;
+ beepType= _BEEP_STICKY_UNLOCK;
+ }
+ }
+ if (filter->priv==NO_LATCH) {
+ filter->active= 0;
+ }
+ else {
+ filter->priv= LATCH_PENDING;
+ if (filter->upAction.type==XkbSA_LatchMods) {
+ xkbi->state.latched_mods |= filter->upAction.mods.mask;
+ needBeep = xkbi->state.latched_mods ? needBeep : 0;
+ xkbi->state.latched_mods |= filter->upAction.mods.mask;
+ }
+ else {
+ xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
+ }
+ if (needBeep && (beepType==_BEEP_NONE))
+ beepType= _BEEP_STICKY_LATCH;
+ }
+ if (needBeep && (beepType!=_BEEP_NONE))
+ XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
+ }
+ else if (filter->priv==LATCH_KEY_DOWN) {
+ filter->priv= NO_LATCH;
+ filter->filterOthers = 0;
+ }
+ return 1;
+}
+
+static int
+_XkbFilterLockState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ if (pAction&&(pAction->type==XkbSA_LockGroup)) {
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->state.locked_group= XkbSAGroup(&pAction->group);
+ else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
+ return 1;
+ }
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterLockState;
+ filter->upAction = *pAction;
+ xkbi->state.locked_mods^= pAction->mods.mask;
+ xkbi->setMods = pAction->mods.mask;
+ }
+ else if (filter->keycode==keycode) {
+ filter->active = 0;
+ xkbi->clearMods = filter->upAction.mods.mask;
+ }
+ return 1;
+}
+
+#define ISO_KEY_DOWN 0
+#define NO_ISO_LOCK 1
+
+static int
+_XkbFilterISOLock( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+
+ if (filter->keycode==0) { /* initial press */
+ CARD8 flags= pAction->iso.flags;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 1;
+ filter->priv = ISO_KEY_DOWN;
+ filter->upAction = *pAction;
+ filter->filter = _XkbFilterISOLock;
+ if (flags&XkbSA_ISODfltIsGroup) {
+ xkbi->groupChange = XkbSAGroup(&pAction->iso);
+ xkbi->setMods = 0;
+ }
+ else {
+ xkbi->setMods = pAction->iso.mask;
+ xkbi->groupChange = 0;
+ }
+ if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
+ filter->priv= NO_ISO_LOCK;
+ xkbi->state.locked_mods^= xkbi->state.base_mods;
+ }
+ if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
+/* 6/22/93 (ef) -- lock groups if group key is down first */
+ }
+ if (!(flags&XkbSA_ISONoAffectPtr)) {
+/* 6/22/93 (ef) -- lock mouse buttons if they're down */
+ }
+ }
+ else if (filter->keycode==keycode) {
+ CARD8 flags= filter->upAction.iso.flags;
+
+ if (flags&XkbSA_ISODfltIsGroup) {
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
+ xkbi->clearMods = 0;
+ if (filter->priv==ISO_KEY_DOWN)
+ xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
+ }
+ else {
+ xkbi->clearMods= filter->upAction.iso.mask;
+ xkbi->groupChange= 0;
+ if (filter->priv==ISO_KEY_DOWN)
+ xkbi->state.locked_mods^= filter->upAction.iso.mask;
+ }
+ filter->active = 0;
+ }
+ else if (pAction) {
+ CARD8 flags= filter->upAction.iso.flags;
+
+ switch (pAction->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods:
+ if (!(flags&XkbSA_ISONoAffectMods)) {
+ pAction->type= XkbSA_LockMods;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_SetGroup: case XkbSA_LatchGroup:
+ if (!(flags&XkbSA_ISONoAffectGroup)) {
+ pAction->type= XkbSA_LockGroup;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_PtrBtn:
+ if (!(flags&XkbSA_ISONoAffectPtr)) {
+ pAction->type= XkbSA_LockPtrBtn;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_SetControls:
+ if (!(flags&XkbSA_ISONoAffectCtrls)) {
+ pAction->type= XkbSA_LockControls;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ }
+ }
+ return 1;
+}
+
+
+static CARD32
+_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+{
+XkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg;
+XkbControlsPtr ctrls= xkbi->desc->ctrls;
+int dx,dy;
+
+ if (xkbi->mouseKey==0)
+ return 0;
+
+ if (xkbi->mouseKeysAccel) {
+ if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
+ double step;
+ xkbi->mouseKeysCounter++;
+ step= xkbi->mouseKeysCurveFactor*
+ pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve);
+ if (xkbi->mouseKeysDX<0)
+ dx= floor( ((double)xkbi->mouseKeysDX)*step );
+ else dx= ceil( ((double)xkbi->mouseKeysDX)*step );
+ if (xkbi->mouseKeysDY<0)
+ dy= floor( ((double)xkbi->mouseKeysDY)*step );
+ else dy= ceil( ((double)xkbi->mouseKeysDY)*step );
+ }
+ else {
+ dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
+ dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
+ }
+ if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
+ dx= xkbi->mouseKeysDX;
+ if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
+ dy= xkbi->mouseKeysDY;
+ }
+ else {
+ dx= xkbi->mouseKeysDX;
+ dy= xkbi->mouseKeysDY;
+ }
+ XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
+ return xkbi->desc->ctrls->mk_interval;
+}
+
+static int
+_XkbFilterPointerMove( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+int x,y;
+Bool accel;
+
+ if (xkbi->device == inputInfo.keyboard)
+ return 0;
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterPointerMove;
+ filter->upAction= *pAction;
+ xkbi->mouseKeysCounter= 0;
+ xkbi->mouseKey= keycode;
+ accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
+ x= XkbPtrActionX(&pAction->ptr);
+ y= XkbPtrActionY(&pAction->ptr);
+ XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y);
+ AccessXCancelRepeatKey(xkbi,keycode);
+ xkbi->mouseKeysAccel= accel&&
+ (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
+ xkbi->mouseKeysFlags= pAction->ptr.flags;
+ xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr);
+ xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr);
+ xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0,
+ xkbi->desc->ctrls->mk_delay,
+ _XkbPtrAccelExpire,(pointer)xkbi);
+ }
+ else if (filter->keycode==keycode) {
+ filter->active = 0;
+ if (xkbi->mouseKey==keycode) {
+ xkbi->mouseKey= 0;
+ xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
+ NULL, NULL);
+ }
+ }
+ return 0;
+}
+
+static int
+_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ if (filter->keycode==0) { /* initial press */
+ int button= pAction->btn.button;
+
+ if (button==XkbSA_UseDfltButton)
+ button = xkbi->desc->ctrls->mk_dflt_btn;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterPointerBtn;
+ filter->upAction= *pAction;
+ filter->upAction.btn.button= button;
+ switch (pAction->type) {
+ case XkbSA_LockPtrBtn:
+ if (((xkbi->lockedPtrButtons&(1<<button))==0)&&
+ ((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
+ xkbi->lockedPtrButtons|= (1<<button);
+ AccessXCancelRepeatKey(xkbi,keycode);
+ XkbFakeDeviceButton(xkbi->device, 1, button);
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ break;
+ case XkbSA_PtrBtn:
+ {
+ register int i,nClicks;
+ AccessXCancelRepeatKey(xkbi,keycode);
+ if (pAction->btn.count>0) {
+ nClicks= pAction->btn.count;
+ for (i=0;i<nClicks;i++) {
+ XkbFakeDeviceButton(xkbi->device, 1, button);
+ XkbFakeDeviceButton(xkbi->device, 0, button);
+ }
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ else XkbFakeDeviceButton(xkbi->device, 1, button);
+ }
+ break;
+ case XkbSA_SetPtrDflt:
+ {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ XkbControlsRec old;
+ xkbControlsNotify cn;
+
+ old= *ctrls;
+ AccessXCancelRepeatKey(xkbi,keycode);
+ switch (pAction->dflt.affect) {
+ case XkbSA_AffectDfltBtn:
+ if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
+ ctrls->mk_dflt_btn=
+ XkbSAPtrDfltValue(&pAction->dflt);
+ else {
+ ctrls->mk_dflt_btn+=
+ XkbSAPtrDfltValue(&pAction->dflt);
+ if (ctrls->mk_dflt_btn>5)
+ ctrls->mk_dflt_btn= 5;
+ else if (ctrls->mk_dflt_btn<1)
+ ctrls->mk_dflt_btn= 1;
+ }
+ break;
+ default:
+ ErrorF(
+ "Attempt to change unknown pointer default (%d) ignored\n",
+ pAction->dflt.affect);
+ break;
+ }
+ if (XkbComputeControlsNotify(xkbi->device,
+ &old,xkbi->desc->ctrls,
+ &cn,FALSE)) {
+ cn.keycode = keycode;
+ /* XXX: what about DeviceKeyPress? */
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(xkbi->device,&cn);
+ }
+ }
+ break;
+ }
+ }
+ else if (filter->keycode==keycode) {
+ int button= filter->upAction.btn.button;
+
+ switch (filter->upAction.type) {
+ case XkbSA_LockPtrBtn:
+ if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
+ ((xkbi->lockedPtrButtons&(1<<button))==0)) {
+ break;
+ }
+ xkbi->lockedPtrButtons&= ~(1<<button);
+ case XkbSA_PtrBtn:
+ XkbFakeDeviceButton(xkbi->device, 0, button);
+ break;
+ }
+ filter->active = 0;
+ }
+ return 0;
+}
+
+static int
+_XkbFilterControls( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+XkbControlsRec old;
+XkbControlsPtr ctrls;
+DeviceIntPtr kbd;
+unsigned int change;
+XkbEventCauseRec cause;
+
+ kbd= xkbi->device;
+ ctrls= xkbi->desc->ctrls;
+ old= *ctrls;
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ change= XkbActionCtrls(&pAction->ctrls);
+ filter->priv = change;
+ filter->filter = _XkbFilterControls;
+ filter->upAction = *pAction;
+
+ if (pAction->type==XkbSA_LockControls) {
+ filter->priv= (ctrls->enabled_ctrls&change);
+ change&= ~ctrls->enabled_ctrls;
+ }
+
+ if (change) {
+ xkbControlsNotify cn;
+ XkbSrvLedInfoPtr sli;
+
+ ctrls->enabled_ctrls|= change;
+ if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
+ cn.keycode = keycode;
+ /* XXX: what about DeviceKeyPress? */
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+
+ XkbSetCauseKey(&cause,keycode,KeyPress);
+
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+ (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
+ XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
+ }
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+ XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change);
+ }
+ }
+ else if (filter->keycode==keycode) {
+ change= filter->priv;
+ if (change) {
+ xkbControlsNotify cn;
+ XkbSrvLedInfoPtr sli;
+
+ ctrls->enabled_ctrls&= ~change;
+ if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
+ cn.keycode = keycode;
+ cn.eventType = KeyRelease;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+
+ XkbSetCauseKey(&cause,keycode,KeyRelease);
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+ (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
+ XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
+ }
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+ XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change);
+ }
+ filter->keycode= 0;
+ filter->active= 0;
+ }
+ return 1;
+}
+
+static int
+_XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+XkbMessageAction * pMsg;
+DeviceIntPtr kbd;
+
+ kbd= xkbi->device;
+ if (filter->keycode==0) { /* initial press */
+ pMsg= &pAction->msg;
+ if ((pMsg->flags&XkbSA_MessageOnRelease)||
+ ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterActionMessage;
+ filter->upAction = *pAction;
+ }
+ if (pMsg->flags&XkbSA_MessageOnPress) {
+ xkbActionMessage msg;
+
+ msg.keycode= keycode;
+ msg.press= 1;
+ msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ memcpy((char *)msg.message,
+ (char *)pMsg->message,XkbActionMessageLength);
+ XkbSendActionMessage(kbd,&msg);
+ }
+ return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
+ }
+ else if (filter->keycode==keycode) {
+ pMsg= &filter->upAction.msg;
+ if (pMsg->flags&XkbSA_MessageOnRelease) {
+ xkbActionMessage msg;
+
+ msg.keycode= keycode;
+ msg.press= 0;
+ msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ memcpy((char *)msg.message,(char *)pMsg->message,
+ XkbActionMessageLength);
+ XkbSendActionMessage(kbd,&msg);
+ }
+ filter->keycode= 0;
+ filter->active= 0;
+ return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ }
+ return 0;
+}
+
+static int
+_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+DeviceEvent ev;
+int x,y;
+XkbStateRec old;
+unsigned mods,mask;
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
+ProcessInputProc backupproc;
+
+ /* never actually used uninitialised, but gcc isn't smart enough
+ * to work that out. */
+ memset(&old, 0, sizeof(old));
+
+ if ((filter->keycode!=0)&&(filter->keycode!=keycode))
+ return 1;
+
+ GetSpritePosition(xkbi->device, &x,&y);
+ ev.header = ET_Internal;
+ ev.length = sizeof(DeviceEvent);
+ ev.time = GetTimeInMillis();
+ ev.root_x = x;
+ ev.root_y = y;
+
+ if (filter->keycode==0) { /* initial press */
+ if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
+ (pAction->redirect.new_key>xkbi->desc->max_key_code)) {
+ return 1;
+ }
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterRedirectKey;
+ filter->upAction = *pAction;
+
+ ev.type = ET_KeyPress;
+ ev.detail.key = pAction->redirect.new_key;
+
+ mask= XkbSARedirectVModsMask(&pAction->redirect);
+ mods= XkbSARedirectVMods(&pAction->redirect);
+ if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
+ if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
+ mask|= pAction->redirect.mods_mask;
+ mods|= pAction->redirect.mods;
+
+ if ( mask || mods ) {
+ old= xkbi->state;
+ xkbi->state.base_mods&= ~mask;
+ xkbi->state.base_mods|= (mods&mask);
+ xkbi->state.latched_mods&= ~mask;
+ xkbi->state.latched_mods|= (mods&mask);
+ xkbi->state.locked_mods&= ~mask;
+ xkbi->state.locked_mods|= (mods&mask);
+ XkbComputeDerivedState(xkbi);
+ }
+
+ UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
+ xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
+ COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
+ backupproc,xkbUnwrapProc);
+
+ if ( mask || mods )
+ xkbi->state= old;
+ }
+ else if (filter->keycode==keycode) {
+
+ ev.type = ET_KeyRelease;
+ ev.detail.key = filter->upAction.redirect.new_key;
+
+ mask= XkbSARedirectVModsMask(&filter->upAction.redirect);
+ mods= XkbSARedirectVMods(&filter->upAction.redirect);
+ if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
+ if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
+ mask|= filter->upAction.redirect.mods_mask;
+ mods|= filter->upAction.redirect.mods;
+
+ if ( mask || mods ) {
+ old= xkbi->state;
+ xkbi->state.base_mods&= ~mask;
+ xkbi->state.base_mods|= (mods&mask);
+ xkbi->state.latched_mods&= ~mask;
+ xkbi->state.latched_mods|= (mods&mask);
+ xkbi->state.locked_mods&= ~mask;
+ xkbi->state.locked_mods|= (mods&mask);
+ XkbComputeDerivedState(xkbi);
+ }
+
+ UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
+ xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
+ COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
+ backupproc,xkbUnwrapProc);
+
+ if ( mask || mods )
+ xkbi->state= old;
+
+ filter->keycode= 0;
+ filter->active= 0;
+ }
+ return 0;
+}
+
+static int
+_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ DeviceIntPtr dev = xkbi->device;
+ if (dev == inputInfo.keyboard)
+ return 0;
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->filter = _XkbFilterSwitchScreen;
+ AccessXCancelRepeatKey(xkbi, keycode);
+ XkbDDXSwitchScreen(dev,keycode,pAction);
+ return 0;
+ }
+ else if (filter->keycode==keycode) {
+ filter->active= 0;
+ return 0;
+ }
+ return 1;
+}
+
+static int
+_XkbFilterXF86Private( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ DeviceIntPtr dev = xkbi->device;
+ if (dev == inputInfo.keyboard)
+ return 0;
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->filter = _XkbFilterXF86Private;
+ XkbDDXPrivate(dev,keycode,pAction);
+ return 0;
+ }
+ else if (filter->keycode==keycode) {
+ filter->active= 0;
+ return 0;
+ }
+ return 1;
+}
+
+
+static int
+_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+DeviceIntPtr dev;
+int button;
+
+ if (xkbi->device == inputInfo.keyboard)
+ return 0;
+
+ if (filter->keycode==0) { /* initial press */
+ _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
+ DixUnknownAccess, &button);
+ if (!dev || !dev->public.on)
+ return 1;
+
+ button= pAction->devbtn.button;
+ if ((button<1)||(button>dev->button->numButtons))
+ return 1;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterDeviceBtn;
+ filter->upAction= *pAction;
+ switch (pAction->type) {
+ case XkbSA_LockDeviceBtn:
+ if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
+ BitIsOn(dev->button->down, button))
+ return 0;
+ XkbFakeDeviceButton(dev,TRUE,button);
+ filter->upAction.type= XkbSA_NoAction;
+ break;
+ case XkbSA_DeviceBtn:
+ if (pAction->devbtn.count>0) {
+ int nClicks,i;
+ nClicks= pAction->btn.count;
+ for (i=0;i<nClicks;i++) {
+ XkbFakeDeviceButton(dev,TRUE,button);
+ XkbFakeDeviceButton(dev,FALSE,button);
+ }
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ else XkbFakeDeviceButton(dev,TRUE,button);
+ break;
+ }
+ }
+ else if (filter->keycode==keycode) {
+ int button;
+
+ filter->active= 0;
+ _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
+ serverClient, DixUnknownAccess, &button);
+ if (!dev || !dev->public.on)
+ return 1;
+
+ button= filter->upAction.btn.button;
+ switch (filter->upAction.type) {
+ case XkbSA_LockDeviceBtn:
+ if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
+ !BitIsOn(dev->button->down, button))
+ return 0;
+ XkbFakeDeviceButton(dev,FALSE,button);
+ break;
+ case XkbSA_DeviceBtn:
+ XkbFakeDeviceButton(dev,FALSE,button);
+ break;
+ }
+ filter->active = 0;
+ }
+ return 0;
+}
+
+static XkbFilterPtr
+_XkbNextFreeFilter(
+ XkbSrvInfoPtr xkbi
+)
+{
+register int i;
+
+ if (xkbi->szFilters==0) {
+ xkbi->szFilters = 4;
+ xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
+ /* 6/21/93 (ef) -- XXX! deal with allocation failure */
+ }
+ for (i=0;i<xkbi->szFilters;i++) {
+ if (!xkbi->filters[i].active) {
+ xkbi->filters[i].keycode = 0;
+ return &xkbi->filters[i];
+ }
+ }
+ xkbi->szFilters*=2;
+ xkbi->filters= realloc(xkbi->filters,
+ xkbi->szFilters * sizeof(XkbFilterRec));
+ /* 6/21/93 (ef) -- XXX! deal with allocation failure */
+ bzero(&xkbi->filters[xkbi->szFilters/2],
+ (xkbi->szFilters/2)*sizeof(XkbFilterRec));
+ return &xkbi->filters[xkbi->szFilters/2];
+}
+
+static int
+_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
+{
+register int i,send;
+
+ send= 1;
+ for (i=0;i<xkbi->szFilters;i++) {
+ if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter))
+ send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction)
+ && send);
+ }
+ return send;
+}
+
+void
+XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event)
+{
+int key,bit,i;
+XkbSrvInfoPtr xkbi;
+KeyClassPtr keyc;
+int changed,sendEvent;
+Bool genStateNotify;
+XkbAction act;
+XkbFilterPtr filter;
+Bool keyEvent;
+Bool pressEvent;
+ProcessInputProc backupproc;
+
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
+
+ keyc= kbd->key;
+ xkbi= keyc->xkbInfo;
+ key= event->detail.key;
+ /* The state may change, so if we're not in the middle of sending a state
+ * notify, prepare for it */
+ if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
+ xkbi->prev_state = xkbi->state;
+ xkbi->flags|= _XkbStateNotifyInProgress;
+ genStateNotify= TRUE;
+ }
+ else genStateNotify= FALSE;
+
+ xkbi->clearMods = xkbi->setMods = 0;
+ xkbi->groupChange = 0;
+
+ sendEvent = 1;
+ keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
+ pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress));
+
+ if (pressEvent) {
+ if (keyEvent)
+ act = XkbGetKeyAction(xkbi,&xkbi->state,key);
+ else {
+ act = XkbGetButtonAction(kbd,dev,key);
+ key|= BTN_ACT_FLAG;
+ }
+ sendEvent = _XkbApplyFilters(xkbi,key,&act);
+ if (sendEvent) {
+ switch (act.type) {
+ case XkbSA_SetMods:
+ case XkbSA_SetGroup:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_LatchMods:
+ case XkbSA_LatchGroup:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_LockMods:
+ case XkbSA_LockGroup:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_ISOLock:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
+ break;
+ case XkbSA_MovePtr:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
+ break;
+ case XkbSA_PtrBtn:
+ case XkbSA_LockPtrBtn:
+ case XkbSA_SetPtrDflt:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
+ break;
+ case XkbSA_Terminate:
+ sendEvent= XkbDDXTerminateServer(dev,key,&act);
+ break;
+ case XkbSA_SwitchScreen:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
+ break;
+ case XkbSA_SetControls:
+ case XkbSA_LockControls:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
+ break;
+ case XkbSA_ActionMessage:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
+ break;
+ case XkbSA_RedirectKey:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
+ break;
+ case XkbSA_DeviceBtn:
+ case XkbSA_LockDeviceBtn:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
+ break;
+ case XkbSA_XFree86Private:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
+ break;
+ }
+ }
+ }
+ else {
+ if (!keyEvent)
+ key|= BTN_ACT_FLAG;
+ sendEvent = _XkbApplyFilters(xkbi,key,NULL);
+ }
+
+ if (xkbi->groupChange!=0)
+ xkbi->state.base_group+= xkbi->groupChange;
+ if (xkbi->setMods) {
+ for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) {
+ if (xkbi->setMods&bit) {
+ keyc->modifierKeyCount[i]++;
+ xkbi->state.base_mods|= bit;
+ xkbi->setMods&= ~bit;
+ }
+ }
+ }
+ if (xkbi->clearMods) {
+ for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) {
+ if (xkbi->clearMods&bit) {
+ keyc->modifierKeyCount[i]--;
+ if (keyc->modifierKeyCount[i]<=0) {
+ xkbi->state.base_mods&= ~bit;
+ keyc->modifierKeyCount[i] = 0;
+ }
+ xkbi->clearMods&= ~bit;
+ }
+ }
+ }
+
+ if (sendEvent) {
+ DeviceIntPtr tmpdev;
+ if (keyEvent)
+ tmpdev = dev;
+ else
+ tmpdev = GetPairedDevice(dev);
+
+ UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc);
+ dev->public.processInputProc((InternalEvent*)event, tmpdev);
+ COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
+ backupproc,xkbUnwrapProc);
+ }
+ else if (keyEvent) {
+ FixKeyState(event, dev);
+ }
+
+ XkbComputeDerivedState(xkbi);
+ changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state);
+ if (genStateNotify) {
+ if (changed) {
+ xkbStateNotify sn;
+ sn.keycode= key;
+ sn.eventType= event->type;
+ sn.requestMajor = sn.requestMinor = 0;
+ sn.changed= changed;
+ XkbSendStateNotify(dev,&sn);
+ }
+ xkbi->flags&= ~_XkbStateNotifyInProgress;
+ }
+ changed= XkbIndicatorsToUpdate(dev,changed,FALSE);
+ if (changed) {
+ XkbEventCauseRec cause;
+ XkbSetCauseKey(&cause, key, event->type);
+ XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause);
+ }
+ return;
+}
+
+int
+XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
+{
+XkbSrvInfoPtr xkbi;
+XkbFilterPtr filter;
+XkbAction act;
+unsigned clear;
+
+ if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
+ xkbi = pXDev->key->xkbInfo;
+ clear= (mask&(~latches));
+ xkbi->state.latched_mods&= ~clear;
+ /* Clear any pending latch to locks.
+ */
+ act.type = XkbSA_NoAction;
+ _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
+ act.type = XkbSA_LatchMods;
+ act.mods.flags = 0;
+ act.mods.mask = mask&latches;
+ filter = _XkbNextFreeFilter(xkbi);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
+ return Success;
+ }
+ return BadValue;
+}
+
+int
+XkbLatchGroup(DeviceIntPtr pXDev,int group)
+{
+XkbSrvInfoPtr xkbi;
+XkbFilterPtr filter;
+XkbAction act;
+
+ if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
+ xkbi = pXDev->key->xkbInfo;
+ act.type = XkbSA_LatchGroup;
+ act.group.flags = 0;
+ XkbSASetGroup(&act.group,group);
+ filter = _XkbNextFreeFilter(xkbi);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
+ return Success;
+ }
+ return BadValue;
+}
+
+/***====================================================================***/
+
+void
+XkbClearAllLatchesAndLocks( DeviceIntPtr dev,
+ XkbSrvInfoPtr xkbi,
+ Bool genEv,
+ XkbEventCausePtr cause)
+{
+XkbStateRec os;
+xkbStateNotify sn;
+
+ sn.changed= 0;
+ os= xkbi->state;
+ if (os.latched_mods) { /* clear all latches */
+ XkbLatchModifiers(dev,~0,0);
+ sn.changed|= XkbModifierLatchMask;
+ }
+ if (os.latched_group) {
+ XkbLatchGroup(dev,0);
+ sn.changed|= XkbGroupLatchMask;
+ }
+ if (os.locked_mods) {
+ xkbi->state.locked_mods= 0;
+ sn.changed|= XkbModifierLockMask;
+ }
+ if (os.locked_group) {
+ xkbi->state.locked_group= 0;
+ sn.changed|= XkbGroupLockMask;
+ }
+ if ( genEv && sn.changed) {
+ CARD32 changed;
+
+ XkbComputeDerivedState(xkbi);
+ sn.keycode= cause->kc;
+ sn.eventType= cause->event;
+ sn.requestMajor= cause->mjr;
+ sn.requestMinor= cause->mnr;
+ sn.changed= XkbStateChangedFlags(&os,&xkbi->state);
+ XkbSendStateNotify(dev,&sn);
+ changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE);
+ if (changed) {
+ XkbUpdateIndicators(dev,changed,TRUE,NULL,cause);
+ }
+ }
+ return;
+}
+
+static void
+XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
+{
+ EventListPtr events;
+ int nevents, i;
+ DeviceIntPtr ptr;
+ int gpe_flags = 0;
+
+ if (!dev->u.master)
+ ptr = dev;
+ else
+ ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
+
+ if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
+ gpe_flags = POINTER_ABSOLUTE;
+ else
+ gpe_flags = POINTER_RELATIVE;
+
+ events = InitEventList(GetMaximumEventsNum());
+ OsBlockSignals();
+ nevents = GetPointerEvents(events, ptr,
+ MotionNotify, 0,
+ gpe_flags, 0, 2, (int[]){x, y});
+ OsReleaseSignals();
+
+ for (i = 0; i < nevents; i++)
+ mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
+
+ FreeEventList(events, GetMaximumEventsNum());
+}
+
+static void
+XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
+{
+ EventListPtr events;
+ int nevents, i;
+ DeviceIntPtr ptr;
+
+ /* If dev is a slave device, and the SD is attached, do nothing. If we'd
+ * post through the attached master pointer we'd get duplicate events.
+ *
+ * if dev is a master keyboard, post through the XTEST device
+ *
+ * if dev is a floating slave, post through the device itself.
+ */
+
+ if (IsMaster(dev))
+ ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
+ else if (!dev->u.master)
+ ptr = dev;
+ else
+ return;
+
+ events = InitEventList(GetMaximumEventsNum());
+ OsBlockSignals();
+ nevents = GetPointerEvents(events, ptr,
+ press ? ButtonPress : ButtonRelease, button,
+ 0 /* flags */, 0 /* first */,
+ 0 /* num_val */, NULL);
+ OsReleaseSignals();
+
+
+ for (i = 0; i < nevents; i++)
+ mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
+
+ FreeEventList(events, GetMaximumEventsNum());
+}
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 4a3219e2a..0bb232f5a 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
-
-char * XkbBaseDirectory= XKB_BASE_DIRECTORY;
-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
+
+char * XkbBaseDirectory= XKB_BASE_DIRECTORY;
+char * XkbBinDirectory= XKB_BIN_DIRECTORY;
+static int XkbWantAccessX= 0;
+
+static char * XkbRulesDflt= NULL;
+static char * XkbModelDflt= NULL;
+static char * XkbLayoutDflt= NULL;
+static char * XkbVariantDflt= NULL;
+static char * XkbOptionsDflt= NULL;
+
+static char * XkbRulesUsed= NULL;
+static char * XkbModelUsed= NULL;
+static char * XkbLayoutUsed= NULL;
+static char * XkbVariantUsed= NULL;
+static char * XkbOptionsUsed= NULL;
+
+static XkbDescPtr xkb_cached_map = NULL;
+
+static Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP;
+
+/***====================================================================***/
+
+/**
+ * Get the current default XKB rules.
+ * Caller must free the data in rmlvo.
+ */
+void
+XkbGetRulesDflts(XkbRMLVOSet *rmlvo)
+{
+ if (XkbRulesDflt) rmlvo->rules = XkbRulesDflt;
+ else rmlvo->rules = XKB_DFLT_RULES;
+ if (XkbModelDflt) rmlvo->model= XkbModelDflt;
+ else rmlvo->model= XKB_DFLT_MODEL;
+ if (XkbLayoutDflt) rmlvo->layout= XkbLayoutDflt;
+ else rmlvo->layout= XKB_DFLT_LAYOUT;
+ if (XkbVariantDflt) rmlvo->variant= XkbVariantDflt;
+ else rmlvo->variant= XKB_DFLT_VARIANT;
+ if (XkbOptionsDflt) rmlvo->options= XkbOptionsDflt;
+ else rmlvo->options= XKB_DFLT_OPTIONS;
+
+ rmlvo->rules = strdup(rmlvo->rules);
+ rmlvo->model = strdup(rmlvo->model);
+ rmlvo->layout = strdup(rmlvo->layout);
+ rmlvo->variant = strdup(rmlvo->variant);
+ rmlvo->options = strdup(rmlvo->options);
+}
+
+void
+XkbFreeRMLVOSet(XkbRMLVOSet *rmlvo, Bool freeRMLVO)
+{
+ if (!rmlvo)
+ return;
+
+ free(rmlvo->rules);
+ free(rmlvo->model);
+ free(rmlvo->layout);
+ free(rmlvo->variant);
+ free(rmlvo->options);
+
+ if (freeRMLVO)
+ free(rmlvo);
+ else
+ memset(rmlvo, 0, sizeof(XkbRMLVOSet));
+}
+
+static Bool
+XkbWriteRulesProp(ClientPtr client, pointer closure)
+{
+int len,out;
+Atom name;
+char * pval;
+
+ len= (XkbRulesUsed?strlen(XkbRulesUsed):0);
+ len+= (XkbModelUsed?strlen(XkbModelUsed):0);
+ len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0);
+ len+= (XkbVariantUsed?strlen(XkbVariantUsed):0);
+ len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0);
+ if (len<1)
+ return TRUE;
+
+ len+= 5; /* trailing NULs */
+
+ name= MakeAtom(_XKB_RF_NAMES_PROP_ATOM,strlen(_XKB_RF_NAMES_PROP_ATOM),1);
+ if (name==None) {
+ ErrorF("[xkb] Atom error: %s not created\n",_XKB_RF_NAMES_PROP_ATOM);
+ return TRUE;
+ }
+ pval= (char*) malloc(len);
+ if (!pval) {
+ ErrorF("[xkb] Allocation error: %s proprerty not created\n",
+ _XKB_RF_NAMES_PROP_ATOM);
+ return TRUE;
+ }
+ out= 0;
+ if (XkbRulesUsed) {
+ strcpy(&pval[out],XkbRulesUsed);
+ out+= strlen(XkbRulesUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbModelUsed) {
+ strcpy(&pval[out],XkbModelUsed);
+ out+= strlen(XkbModelUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbLayoutUsed) {
+ strcpy(&pval[out],XkbLayoutUsed);
+ out+= strlen(XkbLayoutUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbVariantUsed) {
+ strcpy(&pval[out],XkbVariantUsed);
+ out+= strlen(XkbVariantUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbOptionsUsed) {
+ strcpy(&pval[out],XkbOptionsUsed);
+ out+= strlen(XkbOptionsUsed);
+ }
+ pval[out++]= '\0';
+ if (out!=len) {
+ ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
+ out,len);
+ }
+ dixChangeWindowProperty(serverClient, WindowTable[0], name, XA_STRING, 8,
+ PropModeReplace, len, pval, TRUE);
+ free(pval);
+ return TRUE;
+}
+
+static void
+XkbSetRulesUsed(XkbRMLVOSet *rmlvo)
+{
+ if (XkbRulesUsed)
+ free(XkbRulesUsed);
+ XkbRulesUsed= (rmlvo->rules?_XkbDupString(rmlvo->rules):NULL);
+ if (XkbModelUsed)
+ free(XkbModelUsed);
+ XkbModelUsed= (rmlvo->model?_XkbDupString(rmlvo->model):NULL);
+ if (XkbLayoutUsed)
+ free(XkbLayoutUsed);
+ XkbLayoutUsed= (rmlvo->layout?_XkbDupString(rmlvo->layout):NULL);
+ if (XkbVariantUsed)
+ free(XkbVariantUsed);
+ XkbVariantUsed= (rmlvo->variant?_XkbDupString(rmlvo->variant):NULL);
+ if (XkbOptionsUsed)
+ free(XkbOptionsUsed);
+ XkbOptionsUsed= (rmlvo->options?_XkbDupString(rmlvo->options):NULL);
+ if (XkbWantRulesProp)
+ QueueWorkProc(XkbWriteRulesProp,NULL,NULL);
+ return;
+}
+
+void
+XkbSetRulesDflts(XkbRMLVOSet *rmlvo)
+{
+ if (rmlvo->rules) {
+ if (XkbRulesDflt)
+ free(XkbRulesDflt);
+ XkbRulesDflt= _XkbDupString(rmlvo->rules);
+ }
+ if (rmlvo->model) {
+ if (XkbModelDflt)
+ free(XkbModelDflt);
+ XkbModelDflt= _XkbDupString(rmlvo->model);
+ }
+ if (rmlvo->layout) {
+ if (XkbLayoutDflt)
+ free(XkbLayoutDflt);
+ XkbLayoutDflt= _XkbDupString(rmlvo->layout);
+ }
+ if (rmlvo->variant) {
+ if (XkbVariantDflt)
+ free(XkbVariantDflt);
+ XkbVariantDflt= _XkbDupString(rmlvo->variant);
+ }
+ if (rmlvo->options) {
+ if (XkbOptionsDflt)
+ free(XkbOptionsDflt);
+ XkbOptionsDflt= _XkbDupString(rmlvo->options);
+ }
+ return;
+}
+
+void
+XkbDeleteRulesDflts(void)
+{
+ free(XkbRulesDflt);
+ XkbRulesDflt = NULL;
+ free(XkbModelDflt);
+ XkbModelDflt = NULL;
+ free(XkbLayoutDflt);
+ XkbLayoutDflt = NULL;
+ free(XkbVariantDflt);
+ XkbVariantDflt = NULL;
+ free(XkbOptionsDflt);
+ XkbOptionsDflt = NULL;
+
+ XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
+ xkb_cached_map = NULL;
+}
+
+#define DIFFERS(a, b) (strcmp((a) ? (a) : "", (b) ? (b) : "") != 0)
+
+static Bool
+XkbCompareUsedRMLVO(XkbRMLVOSet *rmlvo)
+{
+ if (DIFFERS(rmlvo->rules, XkbRulesUsed) ||
+ DIFFERS(rmlvo->model, XkbModelUsed) ||
+ DIFFERS(rmlvo->layout, XkbLayoutUsed) ||
+ DIFFERS(rmlvo->variant, XkbVariantUsed) ||
+ DIFFERS(rmlvo->options, XkbOptionsUsed))
+ return FALSE;
+ return TRUE;
+}
+
+#undef DIFFERS
+
+/***====================================================================***/
+
+#include "xkbDflts.h"
+
+static Bool
+XkbInitKeyTypes(XkbDescPtr xkb)
+{
+ if (xkb->defined & XkmTypesMask)
+ return TRUE;
+
+ initTypeNames(NULL);
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_dflt_types)!=Success)
+ return FALSE;
+ if (XkbCopyKeyTypes(dflt_types,xkb->map->types,num_dflt_types)!=
+ Success) {
+ return FALSE;
+ }
+ xkb->map->size_types= xkb->map->num_types= num_dflt_types;
+ return TRUE;
+}
+
+static void
+XkbInitRadioGroups(XkbSrvInfoPtr xkbi)
+{
+ xkbi->nRadioGroups = 0;
+ xkbi->radioGroups = NULL;
+ return;
+}
+
+
+static Status
+XkbInitCompatStructs(XkbDescPtr xkb)
+{
+register int i;
+XkbCompatMapPtr compat;
+
+ if (xkb->defined & XkmCompatMapMask)
+ return TRUE;
+
+ if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_dfltSI)!=Success)
+ return BadAlloc;
+ compat = xkb->compat;
+ if (compat->sym_interpret) {
+ compat->num_si = num_dfltSI;
+ memcpy((char *)compat->sym_interpret,(char *)dfltSI,sizeof(dfltSI));
+ }
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ compat->groups[i]= compatMap.groups[i];
+ if (compat->groups[i].vmods!=0) {
+ unsigned mask;
+ mask= XkbMaskForVMask(xkb,compat->groups[i].vmods);
+ compat->groups[i].mask= compat->groups[i].real_mods|mask;
+ }
+ else compat->groups[i].mask= compat->groups[i].real_mods;
+ }
+ return Success;
+}
+
+static void
+XkbInitSemantics(XkbDescPtr xkb)
+{
+ XkbInitKeyTypes(xkb);
+ XkbInitCompatStructs(xkb);
+ return;
+}
+
+/***====================================================================***/
+
+static Status
+XkbInitNames(XkbSrvInfoPtr xkbi)
+{
+XkbDescPtr xkb;
+XkbNamesPtr names;
+Status rtrn;
+Atom unknown;
+
+ xkb= xkbi->desc;
+ if ((rtrn=XkbAllocNames(xkb,XkbAllNamesMask,0,0))!=Success)
+ return rtrn;
+ unknown= CREATE_ATOM("unknown");
+ names = xkb->names;
+ if (names->keycodes==None) names->keycodes= unknown;
+ if (names->geometry==None) names->geometry= unknown;
+ if (names->phys_symbols==None) names->phys_symbols= unknown;
+ if (names->symbols==None) names->symbols= unknown;
+ if (names->types==None) names->types= unknown;
+ if (names->compat==None) names->compat= unknown;
+ if (!(xkb->defined & XkmVirtualModsMask)) {
+ if (names->vmods[vmod_NumLock]==None)
+ names->vmods[vmod_NumLock]= CREATE_ATOM("NumLock");
+ if (names->vmods[vmod_Alt]==None)
+ names->vmods[vmod_Alt]= CREATE_ATOM("Alt");
+ if (names->vmods[vmod_AltGr]==None)
+ names->vmods[vmod_AltGr]= CREATE_ATOM("ModeSwitch");
+ }
+
+ if (!(xkb->defined & XkmIndicatorsMask) ||
+ !(xkb->defined & XkmGeometryMask)) {
+ initIndicatorNames(NULL,xkb);
+ if (names->indicators[LED_CAPS-1]==None)
+ names->indicators[LED_CAPS-1] = CREATE_ATOM("Caps Lock");
+ if (names->indicators[LED_NUM-1]==None)
+ names->indicators[LED_NUM-1] = CREATE_ATOM("Num Lock");
+ if (names->indicators[LED_SCROLL-1]==None)
+ names->indicators[LED_SCROLL-1] = CREATE_ATOM("Scroll Lock");
+#ifdef LED_COMPOSE
+ if (names->indicators[LED_COMPOSE-1]==None)
+ names->indicators[LED_COMPOSE-1] = CREATE_ATOM("Compose");
+#endif
+ }
+
+ if (xkb->geom!=NULL)
+ names->geometry= xkb->geom->name;
+ else names->geometry= unknown;
+
+ return Success;
+}
+
+static Status
+XkbInitIndicatorMap(XkbSrvInfoPtr xkbi)
+{
+XkbDescPtr xkb;
+XkbIndicatorPtr map;
+XkbSrvLedInfoPtr sli;
+
+ xkb= xkbi->desc;
+ if (XkbAllocIndicatorMaps(xkb)!=Success)
+ return BadAlloc;
+
+ if (!(xkb->defined & XkmIndicatorsMask)) {
+ map= xkb->indicators;
+ map->phys_indicators = PHYS_LEDS;
+ map->maps[LED_CAPS-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_CAPS-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_CAPS-1].mods.mask= LockMask;
+ map->maps[LED_CAPS-1].mods.real_mods= LockMask;
+
+ map->maps[LED_NUM-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_NUM-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_NUM-1].mods.mask= 0;
+ map->maps[LED_NUM-1].mods.real_mods= 0;
+ map->maps[LED_NUM-1].mods.vmods= vmod_NumLockMask;
+
+ map->maps[LED_SCROLL-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_SCROLL-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_SCROLL-1].mods.mask= Mod3Mask;
+ map->maps[LED_SCROLL-1].mods.real_mods= Mod3Mask;
+ }
+
+ sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
+ if (sli)
+ XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask);
+
+ return Success;
+}
+
+static Status
+XkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi)
+{
+XkbDescPtr xkb;
+XkbControlsPtr ctrls;
+
+ xkb= xkbi->desc;
+ /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */
+ if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success)
+ FatalError("Couldn't allocate keyboard controls\n");
+ ctrls= xkb->ctrls;
+ if (!(xkb->defined & XkmSymbolsMask))
+ ctrls->num_groups = 1;
+ ctrls->groups_wrap = XkbSetGroupInfo(1,XkbWrapIntoRange,0);
+ ctrls->internal.mask = 0;
+ ctrls->internal.real_mods = 0;
+ ctrls->internal.vmods = 0;
+ ctrls->ignore_lock.mask = 0;
+ ctrls->ignore_lock.real_mods = 0;
+ ctrls->ignore_lock.vmods = 0;
+ ctrls->enabled_ctrls = XkbAccessXTimeoutMask|XkbRepeatKeysMask|
+ XkbMouseKeysAccelMask|XkbAudibleBellMask|
+ XkbIgnoreGroupLockMask;
+ if (XkbWantAccessX)
+ ctrls->enabled_ctrls|= XkbAccessXKeysMask;
+ AccessXInit(pXDev);
+ return Success;
+}
+
+_X_EXPORT Bool
+InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo,
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+ int i;
+ unsigned int check;
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ XkbSrvLedInfoPtr sli;
+ XkbChangesRec changes;
+ XkbEventCauseRec cause;
+ XkbRMLVOSet rmlvo_dflts = { NULL };
+
+ if (dev->key || dev->kbdfeed)
+ return FALSE;
+
+ if (!rmlvo)
+ {
+ rmlvo = &rmlvo_dflts;
+ XkbGetRulesDflts(rmlvo);
+ }
+
+
+ memset(&changes, 0, sizeof(changes));
+ XkbSetCauseUnknown(&cause);
+
+ dev->key = calloc(1, sizeof(*dev->key));
+ if (!dev->key) {
+ ErrorF("XKB: Failed to allocate key class\n");
+ return FALSE;
+ }
+ dev->key->sourceid = dev->id;
+
+ dev->kbdfeed = calloc(1, sizeof(*dev->kbdfeed));
+ if (!dev->kbdfeed) {
+ ErrorF("XKB: Failed to allocate key feedback class\n");
+ goto unwind_key;
+ }
+
+ xkbi = calloc(1, sizeof(*xkbi));
+ if (!xkbi) {
+ ErrorF("XKB: Failed to allocate XKB info\n");
+ goto unwind_kbdfeed;
+ }
+ dev->key->xkbInfo = xkbi;
+
+ if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
+ XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
+ xkb_cached_map = NULL;
+ }
+
+ if (xkb_cached_map)
+ LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
+ else {
+ xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
+ if (!xkb_cached_map) {
+ ErrorF("XKB: Failed to compile keymap\n");
+ goto unwind_info;
+ }
+ }
+
+ xkb = XkbAllocKeyboard();
+ if (!xkb) {
+ ErrorF("XKB: Failed to allocate keyboard description\n");
+ goto unwind_info;
+ }
+
+ if (!XkbCopyKeymap(xkb, xkb_cached_map)) {
+ ErrorF("XKB: Failed to copy keymap\n");
+ goto unwind_desc;
+ }
+ xkb->defined = xkb_cached_map->defined;
+ xkb->flags = xkb_cached_map->flags;
+ xkb->device_spec = xkb_cached_map->device_spec;
+ xkbi->desc = xkb;
+
+ if (xkb->min_key_code == 0)
+ xkb->min_key_code = 8;
+ if (xkb->max_key_code == 0)
+ xkb->max_key_code = 255;
+
+ i = XkbNumKeys(xkb) / 3 + 1;
+ if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success)
+ goto unwind_desc;
+ if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success)
+ goto unwind_desc;
+
+ xkbi->dfltPtrDelta = 1;
+ xkbi->device = dev;
+
+ XkbInitSemantics(xkb);
+ XkbInitNames(xkbi);
+ XkbInitRadioGroups(xkbi);
+
+ XkbInitControls(dev, xkbi);
+
+ XkbInitIndicatorMap(xkbi);
+
+ XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
+ &check, &cause);
+
+ InitFocusClassDeviceStruct(dev);
+
+ xkbi->kbdProc = ctrl_func;
+ dev->kbdfeed->BellProc = bell_func;
+ dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc;
+
+ dev->kbdfeed->ctrl = defaultKeyboardControl;
+ if (dev->kbdfeed->ctrl.autoRepeat)
+ xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask;
+
+ memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat,
+ XkbPerKeyBitArraySize);
+
+ sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
+ if (sli)
+ XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask);
+ else
+ DebugF("XKB: No indicator feedback in XkbFinishInit!\n");
+
+ dev->kbdfeed->CtrlProc(dev,&dev->kbdfeed->ctrl);
+
+ XkbSetRulesDflts(rmlvo);
+ XkbSetRulesUsed(rmlvo);
+ XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
+
+ return TRUE;
+
+unwind_desc:
+ XkbFreeKeyboard(xkb, 0, TRUE);
+unwind_info:
+ free(xkbi);
+ dev->key->xkbInfo = NULL;
+unwind_kbdfeed:
+ free(dev->kbdfeed);
+ dev->kbdfeed = NULL;
+unwind_key:
+ free(dev->key);
+ dev->key = NULL;
+ return FALSE;
+}
+
+
+/***====================================================================***/
+
+ /*
+ * Be very careful about what does and doesn't get freed by this
+ * function. To reduce fragmentation, XkbInitDevice allocates a
+ * single huge block per device and divides it up into most of the
+ * fixed-size structures for the device. Don't free anything that
+ * is part of this larger block.
+ */
+void
+XkbFreeInfo(XkbSrvInfoPtr xkbi)
+{
+ if (xkbi->radioGroups) {
+ free(xkbi->radioGroups);
+ xkbi->radioGroups= NULL;
+ }
+ if (xkbi->mouseKeyTimer) {
+ TimerFree(xkbi->mouseKeyTimer);
+ xkbi->mouseKeyTimer= NULL;
+ }
+ if (xkbi->slowKeysTimer) {
+ TimerFree(xkbi->slowKeysTimer);
+ xkbi->slowKeysTimer= NULL;
+ }
+ if (xkbi->bounceKeysTimer) {
+ TimerFree(xkbi->bounceKeysTimer);
+ xkbi->bounceKeysTimer= NULL;
+ }
+ if (xkbi->repeatKeyTimer) {
+ TimerFree(xkbi->repeatKeyTimer);
+ xkbi->repeatKeyTimer= NULL;
+ }
+ if (xkbi->krgTimer) {
+ TimerFree(xkbi->krgTimer);
+ xkbi->krgTimer= NULL;
+ }
+ xkbi->beepType= _BEEP_NONE;
+ if (xkbi->beepTimer) {
+ TimerFree(xkbi->beepTimer);
+ xkbi->beepTimer= NULL;
+ }
+ if (xkbi->desc) {
+ XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,TRUE);
+ xkbi->desc= NULL;
+ }
+ free(xkbi);
+ return;
+}
+
+/***====================================================================***/
+
+extern int XkbDfltRepeatDelay;
+extern int XkbDfltRepeatInterval;
+
+extern unsigned short XkbDfltAccessXTimeout;
+extern unsigned int XkbDfltAccessXTimeoutMask;
+extern unsigned int XkbDfltAccessXFeedback;
+extern unsigned char XkbDfltAccessXOptions;
+
+int
+XkbProcessArguments(int argc,char *argv[],int i)
+{
+ if (strncmp(argv[i], "-xkbdir", 7) == 0) {
+ if(++i < argc) {
+#if !defined(WIN32) && !defined(__CYGWIN__)
+ if (getuid() != geteuid()) {
+ LogMessage(X_WARNING, "-xkbdir is not available for setuid X servers\n");
+ return -1;
+ } else
+#endif
+ {
+ if (strlen(argv[i]) < PATH_MAX) {
+ XkbBaseDirectory= argv[i];
+ return 2;
+ } else {
+ LogMessage(X_ERROR, "-xkbdir pathname too long\n");
+ return -1;
+ }
+ }
+ }
+ else {
+ return -1;
+ }
+ }
+ else if ((strncmp(argv[i],"-accessx",8)==0)||
+ (strncmp(argv[i],"+accessx",8)==0)) {
+ int j=1;
+ if (argv[i][0]=='-')
+ XkbWantAccessX= 0;
+ else {
+ XkbWantAccessX= 1;
+
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ XkbDfltAccessXTimeout = atoi(argv[++i]);
+ j++;
+
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ /*
+ * presumption that the reasonably useful range of
+ * values fits in 0..MAXINT since SunOS 4 doesn't
+ * have strtoul.
+ */
+ XkbDfltAccessXTimeoutMask=(unsigned int)
+ strtol(argv[++i],NULL,16);
+ j++;
+ }
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ if (argv[++i][0] == '1' )
+ XkbDfltAccessXFeedback=XkbAccessXFeedbackMask;
+ else
+ XkbDfltAccessXFeedback=0;
+ j++;
+ }
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ XkbDfltAccessXOptions=(unsigned char)
+ strtol(argv[++i],NULL,16);
+ j++;
+ }
+ }
+ }
+ return j;
+ }
+ if ((strcmp(argv[i], "-ardelay") == 0) ||
+ (strcmp (argv[i], "-ar1") == 0)) { /* -ardelay int */
+ if (++i >= argc) UseMsg ();
+ XkbDfltRepeatDelay = (long)atoi(argv[i]);
+ return 2;
+ }
+ if ((strcmp(argv[i], "-arinterval") == 0) ||
+ (strcmp (argv[i], "-ar2") == 0)) { /* -arinterval int */
+ if (++i >= argc) UseMsg ();
+ XkbDfltRepeatInterval = (long)atoi(argv[i]);
+ return 2;
+ }
+ return 0;
+}
+
+void
+XkbUseMsg(void)
+{
+ ErrorF("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n");
+ ErrorF(" enable/disable accessx key sequences\n");
+ ErrorF("-ardelay set XKB autorepeat delay\n");
+ ErrorF("-arinterval set XKB autorepeat interval\n");
+}
diff --git a/xorg-server/xkb/xkbLEDs.c b/xorg-server/xkb/xkbLEDs.c
index 8c28513ec..a0a037fd7 100644
--- a/xorg-server/xkb/xkbLEDs.c
+++ b/xorg-server/xkb/xkbLEDs.c
@@ -1,977 +1,977 @@
-/************************************************************
-Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-#include <math.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "inputstr.h"
-
-#include <X11/extensions/XI.h>
-#include <xkbsrv.h>
-#include "xkb.h"
-
-/***====================================================================***/
-
- /*
- * unsigned
- * XkbIndicatorsToUpdate(dev,changed,check_devs_rtrn)
- *
- * Given a keyboard and a set of state components that have changed,
- * this function returns the indicators on the default keyboard
- * feedback that might be affected. It also reports whether or not
- * any extension devices might be affected in check_devs_rtrn.
- */
-
-unsigned
-XkbIndicatorsToUpdate( DeviceIntPtr dev,
- unsigned long state_changes,
- Bool enable_changes)
-{
-register unsigned update= 0;
-XkbSrvLedInfoPtr sli;
-
- sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
-
- if (!sli)
- return update;
-
- if (state_changes&(XkbModifierStateMask|XkbGroupStateMask))
- update|= sli->usesEffective;
- if (state_changes&(XkbModifierBaseMask|XkbGroupBaseMask))
- update|= sli->usesBase;
- if (state_changes&(XkbModifierLatchMask|XkbGroupLatchMask))
- update|= sli->usesLatched;
- if (state_changes&(XkbModifierLockMask|XkbGroupLockMask))
- update|= sli->usesLocked;
- if (state_changes&XkbCompatStateMask)
- update|= sli->usesCompat;
- if (enable_changes)
- update|= sli->usesControls;
- return update;
-}
-
-/***====================================================================***/
-
- /*
- * Bool
- *XkbApplyLEDChangeToKeyboard(xkbi,map,on,change)
- *
- * Some indicators "drive" the keyboard when their state is explicitly
- * changed, as described in section 9.2.1 of the XKB protocol spec.
- * This function updates the state and controls for the keyboard
- * specified by 'xkbi' to reflect any changes that are required
- * when the indicator described by 'map' is turned on or off. The
- * extent of the changes is reported in change, which must be defined.
- */
-static Bool
-XkbApplyLEDChangeToKeyboard( XkbSrvInfoPtr xkbi,
- XkbIndicatorMapPtr map,
- Bool on,
- XkbChangesPtr change)
-{
-Bool ctrlChange,stateChange;
-XkbStatePtr state;
-
- if ((map->flags&XkbIM_NoExplicit)||((map->flags&XkbIM_LEDDrivesKB)==0))
- return FALSE;
- ctrlChange= stateChange= FALSE;
- if (map->ctrls) {
- XkbControlsPtr ctrls= xkbi->desc->ctrls;
- unsigned old;
-
- old= ctrls->enabled_ctrls;
- if (on) ctrls->enabled_ctrls|= map->ctrls;
- else ctrls->enabled_ctrls&= ~map->ctrls;
- if (old!=ctrls->enabled_ctrls) {
- change->ctrls.changed_ctrls= XkbControlsEnabledMask;
- change->ctrls.enabled_ctrls_changes= old^ctrls->enabled_ctrls;
- ctrlChange= TRUE;
- }
- }
- state= &xkbi->state;
- if ((map->groups)&&((map->which_groups&(~XkbIM_UseBase))!=0)) {
- register int i;
- register unsigned bit,match;
-
- if (on) match= (map->groups)&XkbAllGroupsMask;
- else match= (~map->groups)&XkbAllGroupsMask;
- if (map->which_groups&(XkbIM_UseLocked|XkbIM_UseEffective)) {
- for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
- if (bit&match)
- break;
- }
- if (map->which_groups&XkbIM_UseLatched)
- XkbLatchGroup(xkbi->device,0); /* unlatch group */
- state->locked_group= i;
- stateChange= TRUE;
- }
- else if (map->which_groups&(XkbIM_UseLatched|XkbIM_UseEffective)) {
- for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
- if (bit&match)
- break;
- }
- state->locked_group= 0;
- XkbLatchGroup(xkbi->device,i);
- stateChange= TRUE;
- }
- }
- if ((map->mods.mask)&&((map->which_mods&(~XkbIM_UseBase))!=0)) {
- if (map->which_mods&(XkbIM_UseLocked|XkbIM_UseEffective)) {
- register unsigned long old;
- old= state->locked_mods;
- if (on) state->locked_mods|= map->mods.mask;
- else state->locked_mods&= ~map->mods.mask;
- if (state->locked_mods!=old)
- stateChange= TRUE;
- }
- if (map->which_mods&(XkbIM_UseLatched|XkbIM_UseEffective)) {
- register unsigned long newmods;
- newmods= state->latched_mods;
- if (on) newmods|= map->mods.mask;
- else newmods&= ~map->mods.mask;
- if (newmods!=state->locked_mods) {
- newmods&= map->mods.mask;
- XkbLatchModifiers(xkbi->device,map->mods.mask,newmods);
- stateChange= TRUE;
- }
- }
- }
- return (stateChange || ctrlChange);
-}
-
- /*
- * Bool
- * ComputeAutoState(map,state,ctrls)
- *
- * This function reports the effect of applying the specified
- * indicator map given the specified state and controls, as
- * described in section 9.2 of the XKB protocol specification.
- */
-
-static Bool
-ComputeAutoState( XkbIndicatorMapPtr map,
- XkbStatePtr state,
- XkbControlsPtr ctrls)
-{
-Bool on;
-CARD8 mods,group;
-
- on= FALSE;
- mods= group= 0;
- if (map->which_mods&XkbIM_UseAnyMods) {
- if (map->which_mods&XkbIM_UseBase)
- mods|= state->base_mods;
- if (map->which_mods&XkbIM_UseLatched)
- mods|= state->latched_mods;
- if (map->which_mods&XkbIM_UseLocked)
- mods|= state->locked_mods;
- if (map->which_mods&XkbIM_UseEffective)
- mods|= state->mods;
- if (map->which_mods&XkbIM_UseCompat)
- mods|= state->compat_state;
- on = ((map->mods.mask&mods)!=0);
- on = on||((mods==0)&&(map->mods.mask==0)&&(map->mods.vmods==0));
- }
- if (map->which_groups&XkbIM_UseAnyGroup) {
- if (map->which_groups&XkbIM_UseBase)
- group|= (1L << state->base_group);
- if (map->which_groups&XkbIM_UseLatched)
- group|= (1L << state->latched_group);
- if (map->which_groups&XkbIM_UseLocked)
- group|= (1L << state->locked_group);
- if (map->which_groups&XkbIM_UseEffective)
- group|= (1L << state->group);
- on = on||(((map->groups&group)!=0)||(map->groups==0));
- }
- if (map->ctrls)
- on = on||(ctrls->enabled_ctrls&map->ctrls);
- return on;
-}
-
-
-static void
-XkbUpdateLedAutoState( DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned maps_to_check,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-DeviceIntPtr kbd;
-XkbStatePtr state;
-XkbControlsPtr ctrls;
-XkbChangesRec my_changes;
-xkbExtensionDeviceNotify my_ed;
-register unsigned i,bit,affected;
-register XkbIndicatorMapPtr map;
-unsigned oldState;
-
- if ((maps_to_check==0)||(sli->maps==NULL)||(sli->mapsPresent==0))
- return;
-
- if (dev->key && dev->key->xkbInfo)
- kbd= dev;
- else kbd= inputInfo.keyboard;
-
- state= &kbd->key->xkbInfo->state;
- ctrls= kbd->key->xkbInfo->desc->ctrls;
- affected= maps_to_check;
- oldState= sli->effectiveState;
- sli->autoState&= ~affected;
- for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
- if ((affected&bit)==0)
- continue;
- affected&= ~bit;
- map= &sli->maps[i];
- if((!(map->flags&XkbIM_NoAutomatic))&&ComputeAutoState(map,state,ctrls))
- sli->autoState|= bit;
- }
- sli->effectiveState= (sli->autoState|sli->explicitState);
- affected= sli->effectiveState^oldState;
- if (affected==0)
- return;
-
- if (ed==NULL) {
- ed= &my_ed;
- bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
- }
- else if ((ed->reason&XkbXI_IndicatorsMask)&&
- ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- }
-
- if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
- if (changes==NULL) {
- changes= &my_changes;
- bzero((char *)changes,sizeof(XkbChangesRec));
- }
- changes->indicators.state_changes|= affected;
- }
-
- ed->reason|= XkbXI_IndicatorStateMask;
- ed->ledClass= sli->class;
- ed->ledID= sli->id;
- ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
- ed->ledState= sli->effectiveState;
- ed->unsupported= 0;
- ed->supported= XkbXI_AllFeaturesMask;
-
- if (changes!=&my_changes) changes= NULL;
- if (ed!=&my_ed) ed= NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- return;
-}
-
-static void
-XkbUpdateAllDeviceIndicators(XkbChangesPtr changes,XkbEventCausePtr cause)
-{
-DeviceIntPtr edev;
-XkbSrvLedInfoPtr sli;
-
- for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) {
- if (edev->kbdfeed) {
- KbdFeedbackPtr kf;
- for (kf=edev->kbdfeed;kf!=NULL;kf=kf->next) {
- if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL))
- continue;
- sli= kf->xkb_sli;
- XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
- changes,cause);
-
- }
- }
- if (edev->leds) {
- LedFeedbackPtr lf;
- for (lf=edev->leds;lf!=NULL;lf=lf->next) {
- if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL))
- continue;
- sli= lf->xkb_sli;
- XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
- changes,cause);
-
- }
- }
- }
- return;
-}
-
-
-/***====================================================================***/
-
- /*
- * void
- * XkbSetIndicators(dev,affect,values,cause)
- *
- * Attempts to change the indicators specified in 'affect' to the
- * states specified in 'values' for the default keyboard feedback
- * on the keyboard specified by 'dev.' Attempts to change indicator
- * state might be ignored or have no affect, depending on the XKB
- * indicator map for any affected indicators, as described in section
- * 9.2 of the XKB protocol specification.
- *
- * If 'changes' is non-NULL, this function notes any changes to the
- * keyboard state, controls, or indicator state that result from this
- * attempted change. If 'changes' is NULL, this function generates
- * XKB events to report any such changes to interested clients.
- *
- * If 'cause' is non-NULL, it specifies the reason for the change,
- * as reported in some XKB events. If it is NULL, this function
- * assumes that the change is the result of a core protocol
- * ChangeKeyboardMapping request.
- */
-
-void
-XkbSetIndicators( DeviceIntPtr dev,
- CARD32 affect,
- CARD32 values,
- XkbEventCausePtr cause)
-{
-XkbSrvLedInfoPtr sli;
-XkbChangesRec changes;
-xkbExtensionDeviceNotify ed;
-unsigned side_affected;
-
- bzero((char *)&changes,sizeof(XkbChangesRec));
- bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
- sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
- sli->explicitState&= ~affect;
- sli->explicitState|= (affect&values);
- XkbApplyLedStateChanges(dev,sli,affect,&ed,&changes,cause);
-
- side_affected= 0;
- if (changes.state_changes!=0)
- side_affected|= XkbIndicatorsToUpdate(dev,changes.state_changes,FALSE);
- if (changes.ctrls.enabled_ctrls_changes)
- side_affected|= sli->usesControls;
-
- if (side_affected) {
- XkbUpdateLedAutoState(dev,sli,side_affected,&ed,&changes,cause);
- affect|= side_affected;
- }
- if (changes.state_changes || changes.ctrls.enabled_ctrls_changes)
- XkbUpdateAllDeviceIndicators(NULL,cause);
-
- XkbFlushLedEvents(dev,dev,sli,&ed,&changes,cause);
- return;
-}
-
-/***====================================================================***/
-
-/***====================================================================***/
-
- /*
- * void
- * XkbUpdateIndicators(dev,update,check_edevs,changes,cause)
- *
- * Applies the indicator maps for any indicators specified in
- * 'update' from the default keyboard feedback on the device
- * specified by 'dev.'
- *
- * If 'changes' is NULL, this function generates and XKB events
- * required to report the necessary changes, otherwise it simply
- * notes the indicators with changed state.
- *
- * If 'check_edevs' is TRUE, this function also checks the indicator
- * maps for any open extension devices that have them, and updates
- * the state of any extension device indicators as necessary.
- */
-
-void
-XkbUpdateIndicators( DeviceIntPtr dev,
- register CARD32 update,
- Bool check_edevs,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-XkbSrvLedInfoPtr sli;
-
- sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
- XkbUpdateLedAutoState(dev,sli,update,NULL,changes,cause);
- if (check_edevs)
- XkbUpdateAllDeviceIndicators(changes,cause);
- return;
-}
-
-/***====================================================================***/
-
-/***====================================================================***/
-
- /*
- * void
- * XkbCheckIndicatorMaps(dev,sli,which)
- *
- * Updates the 'indicator accelerators' for the indicators specified
- * by 'which' in the feedback specified by 'sli.' The indicator
- * accelerators are internal to the server and are used to simplify
- * and speed up the process of figuring out which indicators might
- * be affected by a particular change in keyboard state or controls.
- */
-
-void
-XkbCheckIndicatorMaps(DeviceIntPtr dev,XkbSrvLedInfoPtr sli,unsigned which)
-{
-register unsigned i,bit;
-XkbIndicatorMapPtr map;
-XkbDescPtr xkb;
-
- if ((sli->flags&XkbSLI_HasOwnState)==0)
- return;
-
- sli->usesBase&= ~which;
- sli->usesLatched&= ~which;
- sli->usesLocked&= ~which;
- sli->usesEffective&= ~which;
- sli->usesCompat&= ~which;
- sli->usesControls&= ~which;
- sli->mapsPresent&= ~which;
-
- xkb= dev->key->xkbInfo->desc;
- for (i=0,bit=1,map=sli->maps;i<XkbNumIndicators;i++,bit<<=1,map++) {
- if (which&bit) {
- CARD8 what;
-
- if (!map || !XkbIM_InUse(map))
- continue;
- sli->mapsPresent|= bit;
-
- what= (map->which_mods|map->which_groups);
- if (what&XkbIM_UseBase)
- sli->usesBase|= bit;
- if (what&XkbIM_UseLatched)
- sli->usesLatched|= bit;
- if (what&XkbIM_UseLocked)
- sli->usesLocked|= bit;
- if (what&XkbIM_UseEffective)
- sli->usesEffective|= bit;
- if (what&XkbIM_UseCompat)
- sli->usesCompat|= bit;
- if (map->ctrls)
- sli->usesControls|= bit;
-
- map->mods.mask= map->mods.real_mods;
- if (map->mods.vmods!=0) {
- map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods);
- }
- }
- }
- sli->usedComponents= 0;
- if (sli->usesBase)
- sli->usedComponents|= XkbModifierBaseMask|XkbGroupBaseMask;
- if (sli->usesLatched)
- sli->usedComponents|= XkbModifierLatchMask|XkbGroupLatchMask;
- if (sli->usesLocked)
- sli->usedComponents|= XkbModifierLockMask|XkbGroupLockMask;
- if (sli->usesEffective)
- sli->usedComponents|= XkbModifierStateMask|XkbGroupStateMask;
- if (sli->usesCompat)
- sli->usedComponents|= XkbCompatStateMask;
- return;
-}
-
-/***====================================================================***/
-
- /*
- * XkbSrvLedInfoPtr
- * XkbAllocSrvLedInfo(dev,kf,lf,needed_parts)
- *
- * Allocates an XkbSrvLedInfoPtr for the feedback specified by either
- * 'kf' or 'lf' on the keyboard specified by 'dev.'
- *
- * If 'needed_parts' is non-zero, this function makes sure that any
- * of the parts speicified therein are allocated.
- */
-XkbSrvLedInfoPtr
-XkbAllocSrvLedInfo( DeviceIntPtr dev,
- KbdFeedbackPtr kf,
- LedFeedbackPtr lf,
- unsigned needed_parts)
-{
-XkbSrvLedInfoPtr sli;
-Bool checkAccel;
-Bool checkNames;
-
- sli= NULL;
- checkAccel= checkNames= FALSE;
- if ((kf!=NULL)&&(kf->xkb_sli==NULL)) {
- kf->xkb_sli= sli= xcalloc(1, sizeof(XkbSrvLedInfoRec));
- if (sli==NULL)
- return NULL; /* ALLOCATION ERROR */
- if (dev->key && dev->key->xkbInfo)
- sli->flags= XkbSLI_HasOwnState;
- else sli->flags= 0;
- sli->class= KbdFeedbackClass;
- sli->id= kf->ctrl.id;
- sli->fb.kf= kf;
-
- sli->autoState= 0;
- sli->explicitState= kf->ctrl.leds;
- sli->effectiveState= kf->ctrl.leds;
-
- if ((kf==dev->kbdfeed) && (dev->key) && (dev->key->xkbInfo)) {
- XkbDescPtr xkb;
- xkb= dev->key->xkbInfo->desc;
- sli->flags|= XkbSLI_IsDefault;
- sli->physIndicators= xkb->indicators->phys_indicators;
- sli->names= xkb->names->indicators;
- sli->maps= xkb->indicators->maps;
- checkNames= checkAccel= TRUE;
- }
- else {
- sli->physIndicators= XkbAllIndicatorsMask;
- sli->names= NULL;
- sli->maps= NULL;
- }
- }
- else if ((kf!=NULL)&&((kf->xkb_sli->flags&XkbSLI_IsDefault)!=0)) {
- XkbDescPtr xkb;
- xkb= dev->key->xkbInfo->desc;
- sli->physIndicators= xkb->indicators->phys_indicators;
- if (xkb->names->indicators!=sli->names) {
- checkNames= TRUE;
- sli->names= xkb->names->indicators;
- }
- if (xkb->indicators->maps!=sli->maps) {
- checkAccel= TRUE;
- sli->maps= xkb->indicators->maps;
- }
- }
- else if ((lf!=NULL)&&(lf->xkb_sli==NULL)) {
- lf->xkb_sli= sli= xcalloc(1, sizeof(XkbSrvLedInfoRec));
- if (sli==NULL)
- return NULL; /* ALLOCATION ERROR */
- if (dev->key && dev->key->xkbInfo)
- sli->flags= XkbSLI_HasOwnState;
- else sli->flags= 0;
- sli->class= LedFeedbackClass;
- sli->id= lf->ctrl.id;
- sli->fb.lf= lf;
-
- sli->physIndicators= lf->ctrl.led_mask;
- sli->autoState= 0;
- sli->explicitState= lf->ctrl.led_values;
- sli->effectiveState= lf->ctrl.led_values;
- sli->maps= NULL;
- sli->names= NULL;
- }
- if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
- sli->names= xcalloc(XkbNumIndicators, sizeof(Atom));
- if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
- sli->maps= xcalloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
- if (checkNames) {
- register unsigned i,bit;
- sli->namesPresent= 0;
- for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
- if (sli->names[i]!=None)
- sli->namesPresent|= bit;
- }
- }
- if (checkAccel)
- XkbCheckIndicatorMaps(dev,sli,XkbAllIndicatorsMask);
- return sli;
-}
-
-void
-XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli)
-{
- if ((sli->flags&XkbSLI_IsDefault)==0) {
- if (sli->maps) xfree(sli->maps);
- if (sli->names) xfree(sli->names);
- }
- sli->maps= NULL;
- sli->names= NULL;
- xfree(sli);
- return;
-}
-
-/*
- * XkbSrvLedInfoPtr
- * XkbCopySrvLedInfo(dev,src,kf,lf)
- *
- * Takes the given XkbSrvLedInfoPtr and duplicates it. A deep copy is made,
- * thus the new copy behaves like the original one and can be freed with
- * XkbFreeSrvLedInfo.
- */
-XkbSrvLedInfoPtr
-XkbCopySrvLedInfo( DeviceIntPtr from,
- XkbSrvLedInfoPtr src,
- KbdFeedbackPtr kf,
- LedFeedbackPtr lf)
-{
- XkbSrvLedInfoPtr sli_new = NULL;
-
- if (!src)
- goto finish;
-
- sli_new = xcalloc(1, sizeof( XkbSrvLedInfoRec));
- if (!sli_new)
- goto finish;
-
- memcpy(sli_new, src, sizeof(XkbSrvLedInfoRec));
- if (sli_new->class == KbdFeedbackClass)
- sli_new->fb.kf = kf;
- else
- sli_new->fb.lf = lf;
-
- if (!(sli_new->flags & XkbSLI_IsDefault)) {
- sli_new->names= xcalloc(XkbNumIndicators, sizeof(Atom));
- sli_new->maps= xcalloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
- } /* else sli_new->names/maps is pointing to
- dev->key->xkbInfo->desc->names->indicators;
- dev->key->xkbInfo->desc->names->indicators; */
-
-finish:
- return sli_new;
-}
-
-/***====================================================================***/
-
- /*
- * XkbSrvLedInfoPtr
- * XkbFindSrvLedInfo(dev,class,id,needed_parts)
- *
- * Finds the XkbSrvLedInfoPtr for the specified 'class' and 'id'
- * on the device specified by 'dev.' If the class and id specify
- * a valid device feedback, this function returns the existing
- * feedback or allocates a new one.
- *
- */
-
-XkbSrvLedInfoPtr
-XkbFindSrvLedInfo( DeviceIntPtr dev,
- unsigned class,
- unsigned id,
- unsigned needed_parts)
-{
-XkbSrvLedInfoPtr sli;
-
- /* optimization to check for most common case */
- if (((class==XkbDfltXIClass)&&(id==XkbDfltXIId))&&(dev->kbdfeed)) {
- XkbSrvLedInfoPtr sli;
- sli= dev->kbdfeed->xkb_sli;
- if (dev->kbdfeed->xkb_sli==NULL) {
- sli= XkbAllocSrvLedInfo(dev,dev->kbdfeed,NULL,needed_parts);
- dev->kbdfeed->xkb_sli= sli;
- }
- return dev->kbdfeed->xkb_sli;
- }
-
- sli= NULL;
- if (class==XkbDfltXIClass) {
- if (dev->kbdfeed) class= KbdFeedbackClass;
- else if (dev->leds) class= LedFeedbackClass;
- else return NULL;
- }
- if (class==KbdFeedbackClass) {
- KbdFeedbackPtr kf;
- for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) {
- if ((id==XkbDfltXIId)||(id==kf->ctrl.id)) {
- if (kf->xkb_sli==NULL)
- kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,needed_parts);
- sli= kf->xkb_sli;
- break;
- }
- }
- }
- else if (class==LedFeedbackClass) {
- LedFeedbackPtr lf;
- for (lf=dev->leds;lf!=NULL;lf=lf->next) {
- if ((id==XkbDfltXIId)||(id==lf->ctrl.id)) {
- if (lf->xkb_sli==NULL)
- lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,needed_parts);
- sli= lf->xkb_sli;
- break;
- }
- }
- }
- if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
- sli->names= xcalloc(XkbNumIndicators, sizeof(Atom));
- if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
- sli->maps= xcalloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
- return sli;
-}
-
-/***====================================================================***/
-
-void
-XkbFlushLedEvents( DeviceIntPtr dev,
- DeviceIntPtr kbd,
- XkbSrvLedInfoPtr sli,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
- if (changes) {
- if (changes->indicators.state_changes)
- XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
- XkbSendNotification(kbd,changes,cause);
- bzero((char *)changes,sizeof(XkbChangesRec));
-
- if (XkbAX_NeedFeedback(kbd->key->xkbInfo->desc->ctrls, XkbAX_IndicatorFBMask)) {
- if (sli->effectiveState)
- /* it appears that the which parameter is not used */
- XkbDDXAccessXBeep(dev, _BEEP_LED_ON, XkbAccessXFeedbackMask);
- else
- XkbDDXAccessXBeep(dev, _BEEP_LED_OFF, XkbAccessXFeedbackMask);
- }
- }
- if (ed) {
- if (ed->reason) {
- if ((dev!=kbd)&&(ed->reason&XkbXI_IndicatorStateMask))
- XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
- XkbSendExtensionDeviceNotify(dev,cause->client,ed);
- }
- bzero((char *)ed,sizeof(XkbExtensionDeviceNotify));
- }
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbApplyLedNameChanges( DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned changed_names,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-DeviceIntPtr kbd;
-XkbChangesRec my_changes;
-xkbExtensionDeviceNotify my_ed;
-
- if (changed_names==0)
- return;
- if (dev->key && dev->key->xkbInfo)
- kbd= dev;
- else kbd= inputInfo.keyboard;
-
- if (ed==NULL) {
- ed= &my_ed;
- bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
- }
- else if ((ed->reason&XkbXI_IndicatorsMask)&&
- ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- }
-
- if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
- if (changes==NULL) {
- changes= &my_changes;
- bzero((char *)changes,sizeof(XkbChangesRec));
- }
- changes->names.changed|= XkbIndicatorNamesMask;
- changes->names.changed_indicators|= changed_names;
- }
-
- ed->reason|= XkbXI_IndicatorNamesMask;
- ed->ledClass= sli->class;
- ed->ledID= sli->id;
- ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
- ed->ledState= sli->effectiveState;
- ed->unsupported= 0;
- ed->supported= XkbXI_AllFeaturesMask;
-
- if (changes!=&my_changes) changes= NULL;
- if (ed!=&my_ed) ed= NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- return;
-}
-/***====================================================================***/
-
- /*
- * void
- * XkbApplyLedMapChanges(dev,sli,changed_maps,changes,cause)
- *
- * Handles all of the secondary effects of the changes to the
- * feedback specified by 'sli' on the device specified by 'dev.'
- *
- * If 'changed_maps' specifies any indicators, this function generates
- * XkbExtensionDeviceNotify events and possibly IndicatorMapNotify
- * events to report the changes, and recalculates the effective
- * state of each indicator with a changed map. If any indicators
- * change state, the server generates XkbExtensionDeviceNotify and
- * XkbIndicatorStateNotify events as appropriate.
- *
- * If 'changes' is non-NULL, this function updates it to reflect
- * any changes to the keyboard state or controls or to the 'core'
- * indicator names, maps, or state. If 'changes' is NULL, this
- * function generates XKB events as needed to report the changes.
- * If 'dev' is not a keyboard device, any changes are reported
- * for the core keyboard.
- *
- * The 'cause' specifies the reason for the event (key event or
- * request) for the change, as reported in some XKB events.
- */
-
-void
-XkbApplyLedMapChanges( DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned changed_maps,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-DeviceIntPtr kbd;
-XkbChangesRec my_changes;
-xkbExtensionDeviceNotify my_ed;
-
- if (changed_maps==0)
- return;
- if (dev->key && dev->key->xkbInfo)
- kbd= dev;
- else kbd= inputInfo.keyboard;
-
- if (ed==NULL) {
- ed= &my_ed;
- bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
- }
- else if ((ed->reason&XkbXI_IndicatorsMask)&&
- ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- }
-
- if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
- if (changes==NULL) {
- changes= &my_changes;
- bzero((char *)changes,sizeof(XkbChangesRec));
- }
- changes->indicators.map_changes|= changed_maps;
- }
-
- XkbCheckIndicatorMaps(dev,sli,changed_maps);
-
- ed->reason|= XkbXI_IndicatorMapsMask;
- ed->ledClass= sli->class;
- ed->ledID= sli->id;
- ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
- ed->ledState= sli->effectiveState;
- ed->unsupported= 0;
- ed->supported= XkbXI_AllFeaturesMask;
-
- XkbUpdateLedAutoState(dev,sli,changed_maps,ed,changes,cause);
-
- if (changes!=&my_changes) changes= NULL;
- if (ed!=&my_ed) ed= NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbApplyLedStateChanges(DeviceIntPtr dev,
- XkbSrvLedInfoPtr sli,
- unsigned changed_leds,
- xkbExtensionDeviceNotify * ed,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-XkbSrvInfoPtr xkbi;
-DeviceIntPtr kbd;
-XkbChangesRec my_changes;
-xkbExtensionDeviceNotify my_ed;
-register unsigned i,bit,affected;
-XkbIndicatorMapPtr map;
-unsigned oldState;
-Bool kb_changed;
-
- if (changed_leds==0)
- return;
- if (dev->key && dev->key->xkbInfo)
- kbd= dev;
- else kbd= inputInfo.keyboard;
- xkbi= kbd->key->xkbInfo;
-
- if (changes==NULL) {
- changes= &my_changes;
- bzero((char *)changes,sizeof(XkbChangesRec));
- }
-
- kb_changed= FALSE;
- affected= changed_leds;
- oldState= sli->effectiveState;
- for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
- if ((affected&bit)==0)
- continue;
- affected&= ~bit;
- map= &sli->maps[i];
- if (map->flags&XkbIM_NoExplicit) {
- sli->explicitState&= ~bit;
- continue;
- }
- if (map->flags&XkbIM_LEDDrivesKB) {
- Bool on= ((sli->explicitState&bit)!=0);
- if (XkbApplyLEDChangeToKeyboard(xkbi,map,on,changes))
- kb_changed= TRUE;
- }
- }
- sli->effectiveState= (sli->autoState|sli->explicitState);
- affected= sli->effectiveState^oldState;
-
- if (ed==NULL) {
- ed= &my_ed;
- bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
- }
- else if (affected&&(ed->reason&XkbXI_IndicatorsMask)&&
- ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- }
-
- if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault))
- changes->indicators.state_changes|= affected;
- if (affected) {
- ed->reason|= XkbXI_IndicatorStateMask;
- ed->ledClass= sli->class;
- ed->ledID= sli->id;
- ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
- ed->ledState= sli->effectiveState;
- ed->unsupported= 0;
- ed->supported= XkbXI_AllFeaturesMask;
- }
-
- if (kb_changed) {
- XkbComputeDerivedState(kbd->key->xkbInfo);
- XkbUpdateLedAutoState(dev,sli,sli->mapsPresent,ed,changes,cause);
- }
-
- if (changes!=&my_changes) changes= NULL;
- if (ed!=&my_ed) ed= NULL;
- if (changes || ed)
- XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
- if (kb_changed)
- XkbUpdateAllDeviceIndicators(NULL,cause);
- return;
-}
+/************************************************************
+Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+
+#include <X11/extensions/XI.h>
+#include <xkbsrv.h>
+#include "xkb.h"
+
+/***====================================================================***/
+
+ /*
+ * unsigned
+ * XkbIndicatorsToUpdate(dev,changed,check_devs_rtrn)
+ *
+ * Given a keyboard and a set of state components that have changed,
+ * this function returns the indicators on the default keyboard
+ * feedback that might be affected. It also reports whether or not
+ * any extension devices might be affected in check_devs_rtrn.
+ */
+
+unsigned
+XkbIndicatorsToUpdate( DeviceIntPtr dev,
+ unsigned long state_changes,
+ Bool enable_changes)
+{
+register unsigned update= 0;
+XkbSrvLedInfoPtr sli;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+
+ if (!sli)
+ return update;
+
+ if (state_changes&(XkbModifierStateMask|XkbGroupStateMask))
+ update|= sli->usesEffective;
+ if (state_changes&(XkbModifierBaseMask|XkbGroupBaseMask))
+ update|= sli->usesBase;
+ if (state_changes&(XkbModifierLatchMask|XkbGroupLatchMask))
+ update|= sli->usesLatched;
+ if (state_changes&(XkbModifierLockMask|XkbGroupLockMask))
+ update|= sli->usesLocked;
+ if (state_changes&XkbCompatStateMask)
+ update|= sli->usesCompat;
+ if (enable_changes)
+ update|= sli->usesControls;
+ return update;
+}
+
+/***====================================================================***/
+
+ /*
+ * Bool
+ *XkbApplyLEDChangeToKeyboard(xkbi,map,on,change)
+ *
+ * Some indicators "drive" the keyboard when their state is explicitly
+ * changed, as described in section 9.2.1 of the XKB protocol spec.
+ * This function updates the state and controls for the keyboard
+ * specified by 'xkbi' to reflect any changes that are required
+ * when the indicator described by 'map' is turned on or off. The
+ * extent of the changes is reported in change, which must be defined.
+ */
+static Bool
+XkbApplyLEDChangeToKeyboard( XkbSrvInfoPtr xkbi,
+ XkbIndicatorMapPtr map,
+ Bool on,
+ XkbChangesPtr change)
+{
+Bool ctrlChange,stateChange;
+XkbStatePtr state;
+
+ if ((map->flags&XkbIM_NoExplicit)||((map->flags&XkbIM_LEDDrivesKB)==0))
+ return FALSE;
+ ctrlChange= stateChange= FALSE;
+ if (map->ctrls) {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ unsigned old;
+
+ old= ctrls->enabled_ctrls;
+ if (on) ctrls->enabled_ctrls|= map->ctrls;
+ else ctrls->enabled_ctrls&= ~map->ctrls;
+ if (old!=ctrls->enabled_ctrls) {
+ change->ctrls.changed_ctrls= XkbControlsEnabledMask;
+ change->ctrls.enabled_ctrls_changes= old^ctrls->enabled_ctrls;
+ ctrlChange= TRUE;
+ }
+ }
+ state= &xkbi->state;
+ if ((map->groups)&&((map->which_groups&(~XkbIM_UseBase))!=0)) {
+ register int i;
+ register unsigned bit,match;
+
+ if (on) match= (map->groups)&XkbAllGroupsMask;
+ else match= (~map->groups)&XkbAllGroupsMask;
+ if (map->which_groups&(XkbIM_UseLocked|XkbIM_UseEffective)) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (bit&match)
+ break;
+ }
+ if (map->which_groups&XkbIM_UseLatched)
+ XkbLatchGroup(xkbi->device,0); /* unlatch group */
+ state->locked_group= i;
+ stateChange= TRUE;
+ }
+ else if (map->which_groups&(XkbIM_UseLatched|XkbIM_UseEffective)) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (bit&match)
+ break;
+ }
+ state->locked_group= 0;
+ XkbLatchGroup(xkbi->device,i);
+ stateChange= TRUE;
+ }
+ }
+ if ((map->mods.mask)&&((map->which_mods&(~XkbIM_UseBase))!=0)) {
+ if (map->which_mods&(XkbIM_UseLocked|XkbIM_UseEffective)) {
+ register unsigned long old;
+ old= state->locked_mods;
+ if (on) state->locked_mods|= map->mods.mask;
+ else state->locked_mods&= ~map->mods.mask;
+ if (state->locked_mods!=old)
+ stateChange= TRUE;
+ }
+ if (map->which_mods&(XkbIM_UseLatched|XkbIM_UseEffective)) {
+ register unsigned long newmods;
+ newmods= state->latched_mods;
+ if (on) newmods|= map->mods.mask;
+ else newmods&= ~map->mods.mask;
+ if (newmods!=state->locked_mods) {
+ newmods&= map->mods.mask;
+ XkbLatchModifiers(xkbi->device,map->mods.mask,newmods);
+ stateChange= TRUE;
+ }
+ }
+ }
+ return (stateChange || ctrlChange);
+}
+
+ /*
+ * Bool
+ * ComputeAutoState(map,state,ctrls)
+ *
+ * This function reports the effect of applying the specified
+ * indicator map given the specified state and controls, as
+ * described in section 9.2 of the XKB protocol specification.
+ */
+
+static Bool
+ComputeAutoState( XkbIndicatorMapPtr map,
+ XkbStatePtr state,
+ XkbControlsPtr ctrls)
+{
+Bool on;
+CARD8 mods,group;
+
+ on= FALSE;
+ mods= group= 0;
+ if (map->which_mods&XkbIM_UseAnyMods) {
+ if (map->which_mods&XkbIM_UseBase)
+ mods|= state->base_mods;
+ if (map->which_mods&XkbIM_UseLatched)
+ mods|= state->latched_mods;
+ if (map->which_mods&XkbIM_UseLocked)
+ mods|= state->locked_mods;
+ if (map->which_mods&XkbIM_UseEffective)
+ mods|= state->mods;
+ if (map->which_mods&XkbIM_UseCompat)
+ mods|= state->compat_state;
+ on = ((map->mods.mask&mods)!=0);
+ on = on||((mods==0)&&(map->mods.mask==0)&&(map->mods.vmods==0));
+ }
+ if (map->which_groups&XkbIM_UseAnyGroup) {
+ if (map->which_groups&XkbIM_UseBase)
+ group|= (1L << state->base_group);
+ if (map->which_groups&XkbIM_UseLatched)
+ group|= (1L << state->latched_group);
+ if (map->which_groups&XkbIM_UseLocked)
+ group|= (1L << state->locked_group);
+ if (map->which_groups&XkbIM_UseEffective)
+ group|= (1L << state->group);
+ on = on||(((map->groups&group)!=0)||(map->groups==0));
+ }
+ if (map->ctrls)
+ on = on||(ctrls->enabled_ctrls&map->ctrls);
+ return on;
+}
+
+
+static void
+XkbUpdateLedAutoState( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned maps_to_check,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+DeviceIntPtr kbd;
+XkbStatePtr state;
+XkbControlsPtr ctrls;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+register unsigned i,bit,affected;
+register XkbIndicatorMapPtr map;
+unsigned oldState;
+
+ if ((maps_to_check==0)||(sli->maps==NULL)||(sli->mapsPresent==0))
+ return;
+
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= inputInfo.keyboard;
+
+ state= &kbd->key->xkbInfo->state;
+ ctrls= kbd->key->xkbInfo->desc->ctrls;
+ affected= maps_to_check;
+ oldState= sli->effectiveState;
+ sli->autoState&= ~affected;
+ for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
+ if ((affected&bit)==0)
+ continue;
+ affected&= ~bit;
+ map= &sli->maps[i];
+ if((!(map->flags&XkbIM_NoAutomatic))&&ComputeAutoState(map,state,ctrls))
+ sli->autoState|= bit;
+ }
+ sli->effectiveState= (sli->autoState|sli->explicitState);
+ affected= sli->effectiveState^oldState;
+ if (affected==0)
+ return;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->indicators.state_changes|= affected;
+ }
+
+ ed->reason|= XkbXI_IndicatorStateMask;
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported= 0;
+ ed->supported= XkbXI_AllFeaturesMask;
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+
+static void
+XkbUpdateAllDeviceIndicators(XkbChangesPtr changes,XkbEventCausePtr cause)
+{
+DeviceIntPtr edev;
+XkbSrvLedInfoPtr sli;
+
+ for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) {
+ if (edev->kbdfeed) {
+ KbdFeedbackPtr kf;
+ for (kf=edev->kbdfeed;kf!=NULL;kf=kf->next) {
+ if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL))
+ continue;
+ sli= kf->xkb_sli;
+ XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
+ changes,cause);
+
+ }
+ }
+ if (edev->leds) {
+ LedFeedbackPtr lf;
+ for (lf=edev->leds;lf!=NULL;lf=lf->next) {
+ if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL))
+ continue;
+ sli= lf->xkb_sli;
+ XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
+ changes,cause);
+
+ }
+ }
+ }
+ return;
+}
+
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbSetIndicators(dev,affect,values,cause)
+ *
+ * Attempts to change the indicators specified in 'affect' to the
+ * states specified in 'values' for the default keyboard feedback
+ * on the keyboard specified by 'dev.' Attempts to change indicator
+ * state might be ignored or have no affect, depending on the XKB
+ * indicator map for any affected indicators, as described in section
+ * 9.2 of the XKB protocol specification.
+ *
+ * If 'changes' is non-NULL, this function notes any changes to the
+ * keyboard state, controls, or indicator state that result from this
+ * attempted change. If 'changes' is NULL, this function generates
+ * XKB events to report any such changes to interested clients.
+ *
+ * If 'cause' is non-NULL, it specifies the reason for the change,
+ * as reported in some XKB events. If it is NULL, this function
+ * assumes that the change is the result of a core protocol
+ * ChangeKeyboardMapping request.
+ */
+
+void
+XkbSetIndicators( DeviceIntPtr dev,
+ CARD32 affect,
+ CARD32 values,
+ XkbEventCausePtr cause)
+{
+XkbSrvLedInfoPtr sli;
+XkbChangesRec changes;
+xkbExtensionDeviceNotify ed;
+unsigned side_affected;
+
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ sli->explicitState&= ~affect;
+ sli->explicitState|= (affect&values);
+ XkbApplyLedStateChanges(dev,sli,affect,&ed,&changes,cause);
+
+ side_affected= 0;
+ if (changes.state_changes!=0)
+ side_affected|= XkbIndicatorsToUpdate(dev,changes.state_changes,FALSE);
+ if (changes.ctrls.enabled_ctrls_changes)
+ side_affected|= sli->usesControls;
+
+ if (side_affected) {
+ XkbUpdateLedAutoState(dev,sli,side_affected,&ed,&changes,cause);
+ affect|= side_affected;
+ }
+ if (changes.state_changes || changes.ctrls.enabled_ctrls_changes)
+ XkbUpdateAllDeviceIndicators(NULL,cause);
+
+ XkbFlushLedEvents(dev,dev,sli,&ed,&changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbUpdateIndicators(dev,update,check_edevs,changes,cause)
+ *
+ * Applies the indicator maps for any indicators specified in
+ * 'update' from the default keyboard feedback on the device
+ * specified by 'dev.'
+ *
+ * If 'changes' is NULL, this function generates and XKB events
+ * required to report the necessary changes, otherwise it simply
+ * notes the indicators with changed state.
+ *
+ * If 'check_edevs' is TRUE, this function also checks the indicator
+ * maps for any open extension devices that have them, and updates
+ * the state of any extension device indicators as necessary.
+ */
+
+void
+XkbUpdateIndicators( DeviceIntPtr dev,
+ register CARD32 update,
+ Bool check_edevs,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+XkbSrvLedInfoPtr sli;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateLedAutoState(dev,sli,update,NULL,changes,cause);
+ if (check_edevs)
+ XkbUpdateAllDeviceIndicators(changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbCheckIndicatorMaps(dev,sli,which)
+ *
+ * Updates the 'indicator accelerators' for the indicators specified
+ * by 'which' in the feedback specified by 'sli.' The indicator
+ * accelerators are internal to the server and are used to simplify
+ * and speed up the process of figuring out which indicators might
+ * be affected by a particular change in keyboard state or controls.
+ */
+
+void
+XkbCheckIndicatorMaps(DeviceIntPtr dev,XkbSrvLedInfoPtr sli,unsigned which)
+{
+register unsigned i,bit;
+XkbIndicatorMapPtr map;
+XkbDescPtr xkb;
+
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ return;
+
+ sli->usesBase&= ~which;
+ sli->usesLatched&= ~which;
+ sli->usesLocked&= ~which;
+ sli->usesEffective&= ~which;
+ sli->usesCompat&= ~which;
+ sli->usesControls&= ~which;
+ sli->mapsPresent&= ~which;
+
+ xkb= dev->key->xkbInfo->desc;
+ for (i=0,bit=1,map=sli->maps;i<XkbNumIndicators;i++,bit<<=1,map++) {
+ if (which&bit) {
+ CARD8 what;
+
+ if (!map || !XkbIM_InUse(map))
+ continue;
+ sli->mapsPresent|= bit;
+
+ what= (map->which_mods|map->which_groups);
+ if (what&XkbIM_UseBase)
+ sli->usesBase|= bit;
+ if (what&XkbIM_UseLatched)
+ sli->usesLatched|= bit;
+ if (what&XkbIM_UseLocked)
+ sli->usesLocked|= bit;
+ if (what&XkbIM_UseEffective)
+ sli->usesEffective|= bit;
+ if (what&XkbIM_UseCompat)
+ sli->usesCompat|= bit;
+ if (map->ctrls)
+ sli->usesControls|= bit;
+
+ map->mods.mask= map->mods.real_mods;
+ if (map->mods.vmods!=0) {
+ map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods);
+ }
+ }
+ }
+ sli->usedComponents= 0;
+ if (sli->usesBase)
+ sli->usedComponents|= XkbModifierBaseMask|XkbGroupBaseMask;
+ if (sli->usesLatched)
+ sli->usedComponents|= XkbModifierLatchMask|XkbGroupLatchMask;
+ if (sli->usesLocked)
+ sli->usedComponents|= XkbModifierLockMask|XkbGroupLockMask;
+ if (sli->usesEffective)
+ sli->usedComponents|= XkbModifierStateMask|XkbGroupStateMask;
+ if (sli->usesCompat)
+ sli->usedComponents|= XkbCompatStateMask;
+ return;
+}
+
+/***====================================================================***/
+
+ /*
+ * XkbSrvLedInfoPtr
+ * XkbAllocSrvLedInfo(dev,kf,lf,needed_parts)
+ *
+ * Allocates an XkbSrvLedInfoPtr for the feedback specified by either
+ * 'kf' or 'lf' on the keyboard specified by 'dev.'
+ *
+ * If 'needed_parts' is non-zero, this function makes sure that any
+ * of the parts speicified therein are allocated.
+ */
+XkbSrvLedInfoPtr
+XkbAllocSrvLedInfo( DeviceIntPtr dev,
+ KbdFeedbackPtr kf,
+ LedFeedbackPtr lf,
+ unsigned needed_parts)
+{
+XkbSrvLedInfoPtr sli;
+Bool checkAccel;
+Bool checkNames;
+
+ sli= NULL;
+ checkAccel= checkNames= FALSE;
+ if ((kf!=NULL)&&(kf->xkb_sli==NULL)) {
+ kf->xkb_sli= sli= calloc(1, sizeof(XkbSrvLedInfoRec));
+ if (sli==NULL)
+ return NULL; /* ALLOCATION ERROR */
+ if (dev->key && dev->key->xkbInfo)
+ sli->flags= XkbSLI_HasOwnState;
+ else sli->flags= 0;
+ sli->class= KbdFeedbackClass;
+ sli->id= kf->ctrl.id;
+ sli->fb.kf= kf;
+
+ sli->autoState= 0;
+ sli->explicitState= kf->ctrl.leds;
+ sli->effectiveState= kf->ctrl.leds;
+
+ if ((kf==dev->kbdfeed) && (dev->key) && (dev->key->xkbInfo)) {
+ XkbDescPtr xkb;
+ xkb= dev->key->xkbInfo->desc;
+ sli->flags|= XkbSLI_IsDefault;
+ sli->physIndicators= xkb->indicators->phys_indicators;
+ sli->names= xkb->names->indicators;
+ sli->maps= xkb->indicators->maps;
+ checkNames= checkAccel= TRUE;
+ }
+ else {
+ sli->physIndicators= XkbAllIndicatorsMask;
+ sli->names= NULL;
+ sli->maps= NULL;
+ }
+ }
+ else if ((kf!=NULL)&&((kf->xkb_sli->flags&XkbSLI_IsDefault)!=0)) {
+ XkbDescPtr xkb;
+ xkb= dev->key->xkbInfo->desc;
+ sli->physIndicators= xkb->indicators->phys_indicators;
+ if (xkb->names->indicators!=sli->names) {
+ checkNames= TRUE;
+ sli->names= xkb->names->indicators;
+ }
+ if (xkb->indicators->maps!=sli->maps) {
+ checkAccel= TRUE;
+ sli->maps= xkb->indicators->maps;
+ }
+ }
+ else if ((lf!=NULL)&&(lf->xkb_sli==NULL)) {
+ lf->xkb_sli= sli= calloc(1, sizeof(XkbSrvLedInfoRec));
+ if (sli==NULL)
+ return NULL; /* ALLOCATION ERROR */
+ if (dev->key && dev->key->xkbInfo)
+ sli->flags= XkbSLI_HasOwnState;
+ else sli->flags= 0;
+ sli->class= LedFeedbackClass;
+ sli->id= lf->ctrl.id;
+ sli->fb.lf= lf;
+
+ sli->physIndicators= lf->ctrl.led_mask;
+ sli->autoState= 0;
+ sli->explicitState= lf->ctrl.led_values;
+ sli->effectiveState= lf->ctrl.led_values;
+ sli->maps= NULL;
+ sli->names= NULL;
+ }
+ if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
+ sli->names= calloc(XkbNumIndicators, sizeof(Atom));
+ if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
+ sli->maps= calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
+ if (checkNames) {
+ register unsigned i,bit;
+ sli->namesPresent= 0;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (sli->names[i]!=None)
+ sli->namesPresent|= bit;
+ }
+ }
+ if (checkAccel)
+ XkbCheckIndicatorMaps(dev,sli,XkbAllIndicatorsMask);
+ return sli;
+}
+
+void
+XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli)
+{
+ if ((sli->flags&XkbSLI_IsDefault)==0) {
+ if (sli->maps) free(sli->maps);
+ if (sli->names) free(sli->names);
+ }
+ sli->maps= NULL;
+ sli->names= NULL;
+ free(sli);
+ return;
+}
+
+/*
+ * XkbSrvLedInfoPtr
+ * XkbCopySrvLedInfo(dev,src,kf,lf)
+ *
+ * Takes the given XkbSrvLedInfoPtr and duplicates it. A deep copy is made,
+ * thus the new copy behaves like the original one and can be freed with
+ * XkbFreeSrvLedInfo.
+ */
+XkbSrvLedInfoPtr
+XkbCopySrvLedInfo( DeviceIntPtr from,
+ XkbSrvLedInfoPtr src,
+ KbdFeedbackPtr kf,
+ LedFeedbackPtr lf)
+{
+ XkbSrvLedInfoPtr sli_new = NULL;
+
+ if (!src)
+ goto finish;
+
+ sli_new = calloc(1, sizeof( XkbSrvLedInfoRec));
+ if (!sli_new)
+ goto finish;
+
+ memcpy(sli_new, src, sizeof(XkbSrvLedInfoRec));
+ if (sli_new->class == KbdFeedbackClass)
+ sli_new->fb.kf = kf;
+ else
+ sli_new->fb.lf = lf;
+
+ if (!(sli_new->flags & XkbSLI_IsDefault)) {
+ sli_new->names= calloc(XkbNumIndicators, sizeof(Atom));
+ sli_new->maps= calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
+ } /* else sli_new->names/maps is pointing to
+ dev->key->xkbInfo->desc->names->indicators;
+ dev->key->xkbInfo->desc->names->indicators; */
+
+finish:
+ return sli_new;
+}
+
+/***====================================================================***/
+
+ /*
+ * XkbSrvLedInfoPtr
+ * XkbFindSrvLedInfo(dev,class,id,needed_parts)
+ *
+ * Finds the XkbSrvLedInfoPtr for the specified 'class' and 'id'
+ * on the device specified by 'dev.' If the class and id specify
+ * a valid device feedback, this function returns the existing
+ * feedback or allocates a new one.
+ *
+ */
+
+XkbSrvLedInfoPtr
+XkbFindSrvLedInfo( DeviceIntPtr dev,
+ unsigned class,
+ unsigned id,
+ unsigned needed_parts)
+{
+XkbSrvLedInfoPtr sli;
+
+ /* optimization to check for most common case */
+ if (((class==XkbDfltXIClass)&&(id==XkbDfltXIId))&&(dev->kbdfeed)) {
+ XkbSrvLedInfoPtr sli;
+ sli= dev->kbdfeed->xkb_sli;
+ if (dev->kbdfeed->xkb_sli==NULL) {
+ sli= XkbAllocSrvLedInfo(dev,dev->kbdfeed,NULL,needed_parts);
+ dev->kbdfeed->xkb_sli= sli;
+ }
+ return dev->kbdfeed->xkb_sli;
+ }
+
+ sli= NULL;
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ else return NULL;
+ }
+ if (class==KbdFeedbackClass) {
+ KbdFeedbackPtr kf;
+ for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) {
+ if ((id==XkbDfltXIId)||(id==kf->ctrl.id)) {
+ if (kf->xkb_sli==NULL)
+ kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,needed_parts);
+ sli= kf->xkb_sli;
+ break;
+ }
+ }
+ }
+ else if (class==LedFeedbackClass) {
+ LedFeedbackPtr lf;
+ for (lf=dev->leds;lf!=NULL;lf=lf->next) {
+ if ((id==XkbDfltXIId)||(id==lf->ctrl.id)) {
+ if (lf->xkb_sli==NULL)
+ lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,needed_parts);
+ sli= lf->xkb_sli;
+ break;
+ }
+ }
+ }
+ if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
+ sli->names= calloc(XkbNumIndicators, sizeof(Atom));
+ if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
+ sli->maps= calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec));
+ return sli;
+}
+
+/***====================================================================***/
+
+void
+XkbFlushLedEvents( DeviceIntPtr dev,
+ DeviceIntPtr kbd,
+ XkbSrvLedInfoPtr sli,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+ if (changes) {
+ if (changes->indicators.state_changes)
+ XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
+ XkbSendNotification(kbd,changes,cause);
+ bzero((char *)changes,sizeof(XkbChangesRec));
+
+ if (XkbAX_NeedFeedback(kbd->key->xkbInfo->desc->ctrls, XkbAX_IndicatorFBMask)) {
+ if (sli->effectiveState)
+ /* it appears that the which parameter is not used */
+ XkbDDXAccessXBeep(dev, _BEEP_LED_ON, XkbAccessXFeedbackMask);
+ else
+ XkbDDXAccessXBeep(dev, _BEEP_LED_OFF, XkbAccessXFeedbackMask);
+ }
+ }
+ if (ed) {
+ if (ed->reason) {
+ if ((dev!=kbd)&&(ed->reason&XkbXI_IndicatorStateMask))
+ XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
+ XkbSendExtensionDeviceNotify(dev,cause->client,ed);
+ }
+ bzero((char *)ed,sizeof(XkbExtensionDeviceNotify));
+ }
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbApplyLedNameChanges( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_names,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+
+ if (changed_names==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= inputInfo.keyboard;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->names.changed|= XkbIndicatorNamesMask;
+ changes->names.changed_indicators|= changed_names;
+ }
+
+ ed->reason|= XkbXI_IndicatorNamesMask;
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported= 0;
+ ed->supported= XkbXI_AllFeaturesMask;
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbApplyLedMapChanges(dev,sli,changed_maps,changes,cause)
+ *
+ * Handles all of the secondary effects of the changes to the
+ * feedback specified by 'sli' on the device specified by 'dev.'
+ *
+ * If 'changed_maps' specifies any indicators, this function generates
+ * XkbExtensionDeviceNotify events and possibly IndicatorMapNotify
+ * events to report the changes, and recalculates the effective
+ * state of each indicator with a changed map. If any indicators
+ * change state, the server generates XkbExtensionDeviceNotify and
+ * XkbIndicatorStateNotify events as appropriate.
+ *
+ * If 'changes' is non-NULL, this function updates it to reflect
+ * any changes to the keyboard state or controls or to the 'core'
+ * indicator names, maps, or state. If 'changes' is NULL, this
+ * function generates XKB events as needed to report the changes.
+ * If 'dev' is not a keyboard device, any changes are reported
+ * for the core keyboard.
+ *
+ * The 'cause' specifies the reason for the event (key event or
+ * request) for the change, as reported in some XKB events.
+ */
+
+void
+XkbApplyLedMapChanges( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_maps,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+
+ if (changed_maps==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= inputInfo.keyboard;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->indicators.map_changes|= changed_maps;
+ }
+
+ XkbCheckIndicatorMaps(dev,sli,changed_maps);
+
+ ed->reason|= XkbXI_IndicatorMapsMask;
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported= 0;
+ ed->supported= XkbXI_AllFeaturesMask;
+
+ XkbUpdateLedAutoState(dev,sli,changed_maps,ed,changes,cause);
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbApplyLedStateChanges(DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_leds,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+XkbSrvInfoPtr xkbi;
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+register unsigned i,bit,affected;
+XkbIndicatorMapPtr map;
+unsigned oldState;
+Bool kb_changed;
+
+ if (changed_leds==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= inputInfo.keyboard;
+ xkbi= kbd->key->xkbInfo;
+
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+
+ kb_changed= FALSE;
+ affected= changed_leds;
+ oldState= sli->effectiveState;
+ for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
+ if ((affected&bit)==0)
+ continue;
+ affected&= ~bit;
+ map= &sli->maps[i];
+ if (map->flags&XkbIM_NoExplicit) {
+ sli->explicitState&= ~bit;
+ continue;
+ }
+ if (map->flags&XkbIM_LEDDrivesKB) {
+ Bool on= ((sli->explicitState&bit)!=0);
+ if (XkbApplyLEDChangeToKeyboard(xkbi,map,on,changes))
+ kb_changed= TRUE;
+ }
+ }
+ sli->effectiveState= (sli->autoState|sli->explicitState);
+ affected= sli->effectiveState^oldState;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if (affected&&(ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault))
+ changes->indicators.state_changes|= affected;
+ if (affected) {
+ ed->reason|= XkbXI_IndicatorStateMask;
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported= 0;
+ ed->supported= XkbXI_AllFeaturesMask;
+ }
+
+ if (kb_changed) {
+ XkbComputeDerivedState(kbd->key->xkbInfo);
+ XkbUpdateLedAutoState(dev,sli,sli->mapsPresent,ed,changes,cause);
+ }
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ if (kb_changed)
+ XkbUpdateAllDeviceIndicators(NULL,cause);
+ return;
+}
diff --git a/xorg-server/xkb/xkbUtils.c b/xorg-server/xkb/xkbUtils.c
index 6d0901a36..286fab073 100644
--- a/xorg-server/xkb/xkbUtils.c
+++ b/xorg-server/xkb/xkbUtils.c
@@ -1,2192 +1,2192 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be
-used in advertising or publicity pertaining to distribution
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-/*
-
-Copyright © 2008 Red Hat Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
-*/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "os.h"
-#include <stdio.h>
-#include <ctype.h>
-#include <math.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#define XK_CYRILLIC
-#include <X11/keysym.h>
-#include "misc.h"
-#include "inputstr.h"
-#include "eventstr.h"
-
-#define XKBSRV_NEED_FILE_FUNCS
-#include <xkbsrv.h>
-#include "xkbgeom.h"
-#include "xkb.h"
-
-/***====================================================================***/
-
-int
-_XkbLookupAnyDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
- Mask access_mode, int *xkb_err)
-{
- int rc = XkbKeyboardErrorCode;
-
- if (id == XkbUseCoreKbd)
- id = PickKeyboard(client)->id;
- else if (id == XkbUseCorePtr)
- id = PickPointer(client)->id;
-
- rc = dixLookupDevice(pDev, id, client, access_mode);
- if (rc != Success)
- *xkb_err = XkbErr_BadDevice;
-
- return rc;
-}
-
-int
-_XkbLookupKeyboard(DeviceIntPtr *pDev, int id, ClientPtr client,
- Mask access_mode, int *xkb_err)
-{
- DeviceIntPtr dev;
- int rc;
-
- if (id == XkbDfltXIId)
- id = XkbUseCoreKbd;
-
- rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
- if (rc != Success)
- return rc;
-
- dev = *pDev;
- if (!dev->key || !dev->key->xkbInfo) {
- *pDev = NULL;
- *xkb_err= XkbErr_BadClass;
- return XkbKeyboardErrorCode;
- }
- return Success;
-}
-
-int
-_XkbLookupBellDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
- Mask access_mode, int *xkb_err)
-{
- DeviceIntPtr dev;
- int rc;
-
- rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
- if (rc != Success)
- return rc;
-
- dev = *pDev;
- if (!dev->kbdfeed && !dev->bell) {
- *pDev = NULL;
- *xkb_err= XkbErr_BadClass;
- return XkbKeyboardErrorCode;
- }
- return Success;
-}
-
-int
-_XkbLookupLedDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
- Mask access_mode, int *xkb_err)
-{
- DeviceIntPtr dev;
- int rc;
-
- if (id == XkbDfltXIId)
- id = XkbUseCorePtr;
-
- rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
- if (rc != Success)
- return rc;
-
- dev = *pDev;
- if (!dev->kbdfeed && !dev->leds) {
- *pDev = NULL;
- *xkb_err= XkbErr_BadClass;
- return XkbKeyboardErrorCode;
- }
- return Success;
-}
-
-int
-_XkbLookupButtonDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
- Mask access_mode, int *xkb_err)
-{
- DeviceIntPtr dev;
- int rc;
-
- rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
- if (rc != Success)
- return rc;
-
- dev = *pDev;
- if (!dev->button) {
- *pDev = NULL;
- *xkb_err= XkbErr_BadClass;
- return XkbKeyboardErrorCode;
- }
- return Success;
-}
-
-void
-XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
-{
-register unsigned tmp;
-
- switch (act->type) {
- case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
- if (act->mods.flags&XkbSA_UseModMapMods)
- act->mods.real_mods= act->mods.mask= mods;
- if ((tmp= XkbModActionVMods(&act->mods))!=0)
- act->mods.mask|= XkbMaskForVMask(xkb,tmp);
- break;
- case XkbSA_ISOLock:
- if (act->iso.flags&XkbSA_UseModMapMods)
- act->iso.real_mods= act->iso.mask= mods;
- if ((tmp= XkbModActionVMods(&act->iso))!=0)
- act->iso.mask|= XkbMaskForVMask(xkb,tmp);
- break;
- }
- return;
-}
-
-unsigned
-XkbMaskForVMask(XkbDescPtr xkb,unsigned vmask)
-{
-register int i,bit;
-register unsigned mask;
-
- for (mask=i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (vmask&bit)
- mask|= xkb->server->vmods[i];
- }
- return mask;
-}
-
-/***====================================================================***/
-
-void
-XkbUpdateKeyTypesFromCore( DeviceIntPtr pXDev,
- KeySymsPtr pCore,
- KeyCode first,
- CARD8 num,
- XkbChangesPtr changes)
-{
-XkbDescPtr xkb;
-unsigned key,nG,explicit;
-int types[XkbNumKbdGroups];
-KeySym tsyms[XkbMaxSymsPerKey],*syms;
-XkbMapChangesPtr mc;
-
- xkb= pXDev->key->xkbInfo->desc;
- if (first+num-1>xkb->max_key_code) {
- /* 1/12/95 (ef) -- XXX! should allow XKB structures to grow */
- num= xkb->max_key_code-first+1;
- }
-
- mc= (changes?(&changes->map):NULL);
-
- syms= &pCore->map[(first - pCore->minKeyCode) * pCore->mapWidth];
- for (key=first; key<(first+num); key++,syms+= pCore->mapWidth) {
- explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
- types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
- types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
- types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
- types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
- nG= XkbKeyTypesForCoreSymbols(xkb,pCore->mapWidth,syms,explicit,types,
- tsyms);
- XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
- memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
- XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
- }
- if (changes->map.changed&XkbKeySymsMask) {
- CARD8 oldLast,newLast;
- oldLast = changes->map.first_key_sym+changes->map.num_key_syms-1;
- newLast = first+num-1;
-
- if (first<changes->map.first_key_sym)
- changes->map.first_key_sym = first;
- if (oldLast>newLast)
- newLast= oldLast;
- changes->map.num_key_syms = newLast-changes->map.first_key_sym+1;
- }
- else {
- changes->map.changed|= XkbKeySymsMask;
- changes->map.first_key_sym = first;
- changes->map.num_key_syms = num;
- }
- return;
-}
-
-void
-XkbUpdateDescActions( XkbDescPtr xkb,
- KeyCode first,
- CARD8 num,
- XkbChangesPtr changes)
-{
-register unsigned key;
-
- for (key=first;key<(first+num);key++) {
- XkbApplyCompatMapToKey(xkb,key,changes);
- }
-
- if (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask)) {
- unsigned char newVMods[XkbNumVirtualMods];
- register unsigned bit,i;
- unsigned present;
-
- bzero(newVMods,XkbNumVirtualMods);
- present= 0;
- for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
- if (xkb->server->vmodmap[key]==0)
- continue;
- for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (bit&xkb->server->vmodmap[key]) {
- present|= bit;
- newVMods[i]|= xkb->map->modmap[key];
- }
- }
- }
- for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
- changes->map.changed|= XkbVirtualModsMask;
- changes->map.vmods|= bit;
- xkb->server->vmods[i]= newVMods[i];
- }
- }
- }
- if (changes->map.changed&XkbVirtualModsMask)
- XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
-
- if (changes->map.changed&XkbKeyActionsMask) {
- CARD8 oldLast,newLast;
- oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
- newLast = first+num-1;
-
- if (first<changes->map.first_key_act)
- changes->map.first_key_act = first;
- if (newLast>oldLast)
- newLast= oldLast;
- changes->map.num_key_acts= newLast-changes->map.first_key_act+1;
- }
- else {
- changes->map.changed|= XkbKeyActionsMask;
- changes->map.first_key_act = first;
- changes->map.num_key_acts = num;
- }
- return;
-}
-
-void
-XkbUpdateActions( DeviceIntPtr pXDev,
- KeyCode first,
- CARD8 num,
- XkbChangesPtr changes,
- unsigned * needChecksRtrn,
- XkbEventCausePtr cause)
-{
-XkbSrvInfoPtr xkbi;
-XkbDescPtr xkb;
-CARD8 * repeat;
-
- if (needChecksRtrn)
- *needChecksRtrn= 0;
- xkbi= pXDev->key->xkbInfo;
- xkb= xkbi->desc;
- repeat= xkb->ctrls->per_key_repeat;
-
- if (pXDev->kbdfeed)
- memcpy(repeat,pXDev->kbdfeed->ctrl.autoRepeats,XkbPerKeyBitArraySize);
-
- XkbUpdateDescActions(xkb,first,num,changes);
-
- if ((pXDev->kbdfeed)&&
- (changes->ctrls.enabled_ctrls_changes&XkbPerKeyRepeatMask)) {
- memcpy(pXDev->kbdfeed->ctrl.autoRepeats,repeat, XkbPerKeyBitArraySize);
- (*pXDev->kbdfeed->CtrlProc)(pXDev, &pXDev->kbdfeed->ctrl);
- }
- return;
-}
-
-KeySymsPtr
-XkbGetCoreMap(DeviceIntPtr keybd)
-{
-register int key,tmp;
-int maxSymsPerKey, maxGroup1Width;
-XkbDescPtr xkb;
-KeySymsPtr syms;
-int maxNumberOfGroups;
-
- if (!keybd || !keybd->key || !keybd->key->xkbInfo)
- return NULL;
-
- xkb= keybd->key->xkbInfo->desc;
- maxSymsPerKey= maxGroup1Width= 0;
- maxNumberOfGroups = 0;
-
- /* determine sizes */
- for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
- if (XkbKeycodeInRange(xkb,key)) {
- int nGroups;
- int w;
- nGroups= XkbKeyNumGroups(xkb,key);
- tmp= 0;
- if (nGroups>0) {
- if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup1Index))<=2)
- tmp+= 2;
- else tmp+= w + 2;
- /* remember highest G1 width */
- if (w > maxGroup1Width)
- maxGroup1Width = w;
- }
- if (nGroups>1) {
- if (tmp <= 2) {
- if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))<2)
- tmp+= 2;
- else tmp+= w;
- } else {
- if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))>2)
- tmp+= w - 2;
- }
- }
- if (nGroups>2)
- tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup3Index);
- if (nGroups>3)
- tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup4Index);
- if (tmp>maxSymsPerKey)
- maxSymsPerKey= tmp;
- if (nGroups > maxNumberOfGroups)
- maxNumberOfGroups = nGroups;
- }
- }
-
- if (maxSymsPerKey <= 0)
- return NULL;
-
- syms = xcalloc(1, sizeof(*syms));
- if (!syms)
- return NULL;
-
- /* See Section 12.4 of the XKB Protocol spec. Because of the
- * single-group distribution for multi-group keyboards, we have to
- * have enough symbols for the largest group 1 to replicate across the
- * number of groups on the keyboard. e.g. a single-group key with 4
- * symbols on a keyboard that has 3 groups -> 12 syms per key */
- if (maxSymsPerKey < maxNumberOfGroups * maxGroup1Width)
- maxSymsPerKey = maxNumberOfGroups * maxGroup1Width;
-
- syms->mapWidth = maxSymsPerKey;
- syms->minKeyCode = xkb->min_key_code;
- syms->maxKeyCode = xkb->max_key_code;
-
- tmp = syms->mapWidth * (xkb->max_key_code - xkb->min_key_code + 1);
- syms->map = xcalloc(tmp, sizeof(*syms->map));
- if (!syms->map) {
- xfree(syms);
- return NULL;
- }
-
- for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
- KeySym *pCore,*pXKB;
- unsigned nGroups,groupWidth,n,nOut;
-
- nGroups= XkbKeyNumGroups(xkb,key);
- n= (key-xkb->min_key_code)*syms->mapWidth;
- pCore= &syms->map[n];
- pXKB= XkbKeySymsPtr(xkb,key);
- nOut= 2;
- if (nGroups>0) {
- groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup1Index);
- if (groupWidth>0) pCore[0]= pXKB[0];
- if (groupWidth>1) pCore[1]= pXKB[1];
- for (n=2;n<groupWidth;n++)
- pCore[2+n]= pXKB[n];
- if (groupWidth>2)
- nOut= groupWidth;
- }
-
- /* See XKB Protocol Sec, Section 12.4.
- A 1-group key with ABCDE on a 2 group keyboard must be
- duplicated across all groups as ABABCDECDE.
- */
- if (nGroups == 1)
- {
- int idx, j;
-
- groupWidth = XkbKeyGroupWidth(xkb, key, XkbGroup1Index);
-
- /* AB..CDE... -> ABABCDE... */
- if (groupWidth > 0 && syms->mapWidth >= 3)
- pCore[2] = pCore[0];
- if (groupWidth > 1 && syms->mapWidth >= 4)
- pCore[3] = pCore[1];
-
- /* ABABCDE... -> ABABCDECDE */
- idx = 2 + groupWidth;
- while (groupWidth > 2 && idx < syms->mapWidth &&
- idx < groupWidth * 2)
- {
- pCore[idx] = pCore[idx - groupWidth + 2];
- idx++;
- }
- idx = 2 * groupWidth;
- if (idx < 4)
- idx = 4;
- /* 3 or more groups: ABABCDECDEABCDEABCDE */
- for (j = 3; j <= maxNumberOfGroups; j++)
- for (n = 0; n < groupWidth && idx < maxSymsPerKey; n++)
- pCore[idx++] = pXKB[n];
- }
-
- pXKB+= XkbKeyGroupsWidth(xkb,key);
- nOut+= 2;
- if (nGroups>1) {
- groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index);
- if (groupWidth>0) pCore[2]= pXKB[0];
- if (groupWidth>1) pCore[3]= pXKB[1];
- for (n=2;n<groupWidth;n++) {
- pCore[nOut+(n-2)]= pXKB[n];
- }
- if (groupWidth>2)
- nOut+= (groupWidth-2);
- }
- pXKB+= XkbKeyGroupsWidth(xkb,key);
- for (n=XkbGroup3Index;n<nGroups;n++) {
- register int s;
- groupWidth= XkbKeyGroupWidth(xkb,key,n);
- for (s=0;s<groupWidth;s++) {
- pCore[nOut++]= pXKB[s];
- }
- pXKB+= XkbKeyGroupsWidth(xkb,key);
- }
- }
-
- return syms;
-}
-
-void
-XkbSetRepeatKeys(DeviceIntPtr pXDev,int key,int onoff)
-{
- if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
- xkbControlsNotify cn;
- XkbControlsPtr ctrls = pXDev->key->xkbInfo->desc->ctrls;
- XkbControlsRec old;
- old = *ctrls;
-
- if (key== -1) { /* global autorepeat setting changed */
- if (onoff) ctrls->enabled_ctrls |= XkbRepeatKeysMask;
- else ctrls->enabled_ctrls &= ~XkbRepeatKeysMask;
- }
- else if (pXDev->kbdfeed) {
- ctrls->per_key_repeat[key/8] =
- pXDev->kbdfeed->ctrl.autoRepeats[key/8];
- }
-
- if (XkbComputeControlsNotify(pXDev,&old,ctrls,&cn,TRUE))
- XkbSendControlsNotify(pXDev,&cn);
- }
- return;
-}
-
-/* Applies a change to a single device, does not traverse the device tree. */
-void
-XkbApplyMappingChange(DeviceIntPtr kbd, KeySymsPtr map, KeyCode first_key,
- CARD8 num_keys, CARD8 *modmap, ClientPtr client)
-{
- XkbDescPtr xkb = kbd->key->xkbInfo->desc;
- XkbEventCauseRec cause;
- XkbChangesRec changes;
- unsigned int check;
-
- memset(&changes, 0, sizeof(changes));
- memset(&cause, 0, sizeof(cause));
-
- if (map && first_key && num_keys) {
- check = 0;
- XkbSetCauseCoreReq(&cause, X_ChangeKeyboardMapping, client);
-
- XkbUpdateKeyTypesFromCore(kbd, map, first_key, num_keys, &changes);
- XkbUpdateActions(kbd, first_key, num_keys, &changes, &check, &cause);
-
- if (check)
- XkbCheckSecondaryEffects(kbd->key->xkbInfo, 1, &changes, &cause);
- }
-
- if (modmap) {
- /* A keymap change can imply a modmap change, se we prefer the
- * former. */
- if (!cause.mjr)
- XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client);
-
- check = 0;
- num_keys = xkb->max_key_code - xkb->min_key_code + 1;
- changes.map.changed |= XkbModifierMapMask;
- changes.map.first_modmap_key = xkb->min_key_code;
- changes.map.num_modmap_keys = num_keys;
- memcpy(kbd->key->xkbInfo->desc->map->modmap, modmap, MAP_LENGTH);
- XkbUpdateActions(kbd, xkb->min_key_code, num_keys, &changes, &check,
- &cause);
-
- if (check)
- XkbCheckSecondaryEffects(kbd->key->xkbInfo, 1, &changes, &cause);
- }
-
- XkbSendNotification(kbd, &changes, &cause);
-}
-
-void
-XkbDisableComputedAutoRepeats(DeviceIntPtr dev,unsigned key)
-{
-XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
-xkbMapNotify mn;
-
- xkbi->desc->server->explicit[key]|= XkbExplicitAutoRepeatMask;
- bzero(&mn,sizeof(mn));
- mn.changed= XkbExplicitComponentsMask;
- mn.firstKeyExplicit= key;
- mn.nKeyExplicit= 1;
- XkbSendMapNotify(dev,&mn);
- return;
-}
-
-unsigned
-XkbStateChangedFlags(XkbStatePtr old,XkbStatePtr new)
-{
-int changed;
-
- changed=(old->group!=new->group?XkbGroupStateMask:0);
- changed|=(old->base_group!=new->base_group?XkbGroupBaseMask:0);
- changed|=(old->latched_group!=new->latched_group?XkbGroupLatchMask:0);
- changed|=(old->locked_group!=new->locked_group?XkbGroupLockMask:0);
- changed|=(old->mods!=new->mods?XkbModifierStateMask:0);
- changed|=(old->base_mods!=new->base_mods?XkbModifierBaseMask:0);
- changed|=(old->latched_mods!=new->latched_mods?XkbModifierLatchMask:0);
- changed|=(old->locked_mods!=new->locked_mods?XkbModifierLockMask:0);
- changed|=(old->compat_state!=new->compat_state?XkbCompatStateMask:0);
- changed|=(old->grab_mods!=new->grab_mods?XkbGrabModsMask:0);
- if (old->compat_grab_mods!=new->compat_grab_mods)
- changed|= XkbCompatGrabModsMask;
- changed|=(old->lookup_mods!=new->lookup_mods?XkbLookupModsMask:0);
- if (old->compat_lookup_mods!=new->compat_lookup_mods)
- changed|= XkbCompatLookupModsMask;
- changed|=(old->ptr_buttons!=new->ptr_buttons?XkbPointerButtonMask:0);
- return changed;
-}
-
-static void
-XkbComputeCompatState(XkbSrvInfoPtr xkbi)
-{
-CARD16 grp_mask;
-XkbStatePtr state= &xkbi->state;
-XkbCompatMapPtr map;
-
- if (!state || !xkbi->desc || !xkbi->desc->ctrls || !xkbi->desc->compat)
- return;
-
- map= xkbi->desc->compat;
- grp_mask= map->groups[state->group].mask;
- state->compat_state = state->mods|grp_mask;
- state->compat_lookup_mods= state->lookup_mods|grp_mask;
-
- if (xkbi->desc->ctrls->enabled_ctrls&XkbIgnoreGroupLockMask)
- grp_mask= map->groups[state->base_group].mask;
- state->compat_grab_mods= state->grab_mods|grp_mask;
- return;
-}
-
-unsigned
-XkbAdjustGroup(int group,XkbControlsPtr ctrls)
-{
-unsigned act;
-
- act= XkbOutOfRangeGroupAction(ctrls->groups_wrap);
- if (group<0) {
- while ( group < 0 ) {
- if (act==XkbClampIntoRange) {
- group= XkbGroup1Index;
- }
- else if (act==XkbRedirectIntoRange) {
- int newGroup;
- newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
- if (newGroup>=ctrls->num_groups)
- group= XkbGroup1Index;
- else group= newGroup;
- }
- else {
- group+= ctrls->num_groups;
- }
- }
- }
- else if (group>=ctrls->num_groups) {
- if (act==XkbClampIntoRange) {
- group= ctrls->num_groups-1;
- }
- else if (act==XkbRedirectIntoRange) {
- int newGroup;
- newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
- if (newGroup>=ctrls->num_groups)
- group= XkbGroup1Index;
- else group= newGroup;
- }
- else {
- group%= ctrls->num_groups;
- }
- }
- return group;
-}
-
-void
-XkbComputeDerivedState(XkbSrvInfoPtr xkbi)
-{
-XkbStatePtr state= &xkbi->state;
-XkbControlsPtr ctrls= xkbi->desc->ctrls;
-unsigned char grp;
-
- if (!state || !ctrls)
- return;
-
- state->mods= (state->base_mods|state->latched_mods|state->locked_mods);
- state->lookup_mods= state->mods&(~ctrls->internal.mask);
- state->grab_mods= state->lookup_mods&(~ctrls->ignore_lock.mask);
- state->grab_mods|=
- ((state->base_mods|state->latched_mods)&ctrls->ignore_lock.mask);
-
-
- grp= state->locked_group;
- if (grp>=ctrls->num_groups)
- state->locked_group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
-
- grp= state->locked_group+state->base_group+state->latched_group;
- if (grp>=ctrls->num_groups)
- state->group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
- else state->group= grp;
- XkbComputeCompatState(xkbi);
- return;
-}
-
-/***====================================================================***/
-
-void
-XkbCheckSecondaryEffects( XkbSrvInfoPtr xkbi,
- unsigned which,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
- if (which&XkbStateNotifyMask) {
- XkbStateRec old;
- old= xkbi->state;
- changes->state_changes|= XkbStateChangedFlags(&old,&xkbi->state);
- XkbComputeDerivedState(xkbi);
- }
- if (which&XkbIndicatorStateNotifyMask)
- XkbUpdateIndicators(xkbi->device,XkbAllIndicatorsMask,TRUE,changes,
- cause);
- return;
-}
-
-/***====================================================================***/
-
-Bool
-XkbEnableDisableControls( XkbSrvInfoPtr xkbi,
- unsigned long change,
- unsigned long newValues,
- XkbChangesPtr changes,
- XkbEventCausePtr cause)
-{
-XkbControlsPtr ctrls;
-unsigned old;
-XkbSrvLedInfoPtr sli;
-
- ctrls= xkbi->desc->ctrls;
- old= ctrls->enabled_ctrls;
- ctrls->enabled_ctrls&= ~change;
- ctrls->enabled_ctrls|= (change&newValues);
- if (old==ctrls->enabled_ctrls)
- return FALSE;
- if (cause!=NULL) {
- xkbControlsNotify cn;
- cn.numGroups= ctrls->num_groups;
- cn.changedControls= XkbControlsEnabledMask;
- cn.enabledControls= ctrls->enabled_ctrls;
- cn.enabledControlChanges= (ctrls->enabled_ctrls^old);
- cn.keycode= cause->kc;
- cn.eventType= cause->event;
- cn.requestMajor= cause->mjr;
- cn.requestMinor= cause->mnr;
- XkbSendControlsNotify(xkbi->device,&cn);
- }
- else {
- /* Yes, this really should be an XOR. If ctrls->enabled_ctrls_changes*/
- /* is non-zero, the controls in question changed already in "this" */
- /* request and this change merely undoes the previous one. By the */
- /* same token, we have to figure out whether or not ControlsEnabled */
- /* should be set or not in the changes structure */
- changes->ctrls.enabled_ctrls_changes^= (ctrls->enabled_ctrls^old);
- if (changes->ctrls.enabled_ctrls_changes)
- changes->ctrls.changed_ctrls|= XkbControlsEnabledMask;
- else changes->ctrls.changed_ctrls&= ~XkbControlsEnabledMask;
- }
- sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
- XkbUpdateIndicators(xkbi->device,sli->usesControls,TRUE,changes,cause);
- return TRUE;
-}
-
-/***====================================================================***/
-
-#define MAX_TOC 16
-
-XkbGeometryPtr
-XkbLookupNamedGeometry(DeviceIntPtr dev,Atom name,Bool *shouldFree)
-{
-XkbSrvInfoPtr xkbi= dev->key->xkbInfo;
-XkbDescPtr xkb= xkbi->desc;
-
- *shouldFree= 0;
- if (name==None) {
- if (xkb->geom!=NULL)
- return xkb->geom;
- name= xkb->names->geometry;
- }
- if ((xkb->geom!=NULL)&&(xkb->geom->name==name))
- return xkb->geom;
- *shouldFree= 1;
- return NULL;
-}
-
-void
-XkbConvertCase(register KeySym sym, KeySym *lower, KeySym *upper)
-{
- *lower = sym;
- *upper = sym;
- switch(sym >> 8) {
- case 0: /* Latin 1 */
- if ((sym >= XK_A) && (sym <= XK_Z))
- *lower += (XK_a - XK_A);
- else if ((sym >= XK_a) && (sym <= XK_z))
- *upper -= (XK_a - XK_A);
- else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
- *lower += (XK_agrave - XK_Agrave);
- else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
- *upper -= (XK_agrave - XK_Agrave);
- else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
- *lower += (XK_oslash - XK_Ooblique);
- else if ((sym >= XK_oslash) && (sym <= XK_thorn))
- *upper -= (XK_oslash - XK_Ooblique);
- break;
- case 1: /* Latin 2 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym == XK_Aogonek)
- *lower = XK_aogonek;
- else if (sym >= XK_Lstroke && sym <= XK_Sacute)
- *lower += (XK_lstroke - XK_Lstroke);
- else if (sym >= XK_Scaron && sym <= XK_Zacute)
- *lower += (XK_scaron - XK_Scaron);
- else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
- *lower += (XK_zcaron - XK_Zcaron);
- else if (sym == XK_aogonek)
- *upper = XK_Aogonek;
- else if (sym >= XK_lstroke && sym <= XK_sacute)
- *upper -= (XK_lstroke - XK_Lstroke);
- else if (sym >= XK_scaron && sym <= XK_zacute)
- *upper -= (XK_scaron - XK_Scaron);
- else if (sym >= XK_zcaron && sym <= XK_zabovedot)
- *upper -= (XK_zcaron - XK_Zcaron);
- else if (sym >= XK_Racute && sym <= XK_Tcedilla)
- *lower += (XK_racute - XK_Racute);
- else if (sym >= XK_racute && sym <= XK_tcedilla)
- *upper -= (XK_racute - XK_Racute);
- break;
- case 2: /* Latin 3 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
- *lower += (XK_hstroke - XK_Hstroke);
- else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
- *lower += (XK_gbreve - XK_Gbreve);
- else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
- *upper -= (XK_hstroke - XK_Hstroke);
- else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
- *upper -= (XK_gbreve - XK_Gbreve);
- else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
- *lower += (XK_cabovedot - XK_Cabovedot);
- else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
- *upper -= (XK_cabovedot - XK_Cabovedot);
- break;
- case 3: /* Latin 4 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Rcedilla && sym <= XK_Tslash)
- *lower += (XK_rcedilla - XK_Rcedilla);
- else if (sym >= XK_rcedilla && sym <= XK_tslash)
- *upper -= (XK_rcedilla - XK_Rcedilla);
- else if (sym == XK_ENG)
- *lower = XK_eng;
- else if (sym == XK_eng)
- *upper = XK_ENG;
- else if (sym >= XK_Amacron && sym <= XK_Umacron)
- *lower += (XK_amacron - XK_Amacron);
- else if (sym >= XK_amacron && sym <= XK_umacron)
- *upper -= (XK_amacron - XK_Amacron);
- break;
- case 6: /* Cyrillic */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
- *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
- else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
- *upper += (XK_Serbian_DJE - XK_Serbian_dje);
- else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
- *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
- else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
- *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
- break;
- case 7: /* Greek */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
- *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
- else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
- sym != XK_Greek_iotaaccentdieresis &&
- sym != XK_Greek_upsilonaccentdieresis)
- *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
- else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
- *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
- else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
- sym != XK_Greek_finalsmallsigma)
- *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
- break;
- }
-}
-
-static Bool
-_XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
-{
- void *tmp = NULL;
- int i;
- XkbKeyTypePtr stype = NULL, dtype = NULL;
-
- /* client map */
- if (src->map) {
- if (!dst->map) {
- tmp = xcalloc(1, sizeof(XkbClientMapRec));
- if (!tmp)
- return FALSE;
- dst->map = tmp;
- }
-
- if (src->map->syms) {
- if (src->map->size_syms != dst->map->size_syms) {
- if (dst->map->syms)
- tmp = xrealloc(dst->map->syms,
- src->map->size_syms * sizeof(KeySym));
- else
- tmp = xalloc(src->map->size_syms * sizeof(KeySym));
- if (!tmp)
- return FALSE;
- dst->map->syms = tmp;
-
- }
- memcpy(dst->map->syms, src->map->syms,
- src->map->size_syms * sizeof(KeySym));
- }
- else {
- if (dst->map->syms) {
- xfree(dst->map->syms);
- dst->map->syms = NULL;
- }
- }
- dst->map->num_syms = src->map->num_syms;
- dst->map->size_syms = src->map->size_syms;
-
- if (src->map->key_sym_map) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->map->key_sym_map)
- tmp = xrealloc(dst->map->key_sym_map,
- (src->max_key_code + 1) *
- sizeof(XkbSymMapRec));
- else
- tmp = xalloc((src->max_key_code + 1) *
- sizeof(XkbSymMapRec));
- if (!tmp)
- return FALSE;
- dst->map->key_sym_map = tmp;
- }
- memcpy(dst->map->key_sym_map, src->map->key_sym_map,
- (src->max_key_code + 1) * sizeof(XkbSymMapRec));
- }
- else {
- if (dst->map->key_sym_map) {
- xfree(dst->map->key_sym_map);
- dst->map->key_sym_map = NULL;
- }
- }
-
- if (src->map->types && src->map->num_types) {
- if (src->map->num_types > dst->map->size_types ||
- !dst->map->types || !dst->map->size_types) {
- if (dst->map->types && dst->map->size_types) {
- tmp = xrealloc(dst->map->types,
- src->map->num_types * sizeof(XkbKeyTypeRec));
- if (!tmp)
- return FALSE;
- dst->map->types = tmp;
- bzero(dst->map->types + dst->map->num_types,
- (src->map->num_types - dst->map->num_types) *
- sizeof(XkbKeyTypeRec));
- }
- else {
- tmp = xcalloc(src->map->num_types, sizeof(XkbKeyTypeRec));
- if (!tmp)
- return FALSE;
- dst->map->types = tmp;
- }
- }
- else if (src->map->num_types < dst->map->num_types &&
- dst->map->types) {
- for (i = src->map->num_types, dtype = (dst->map->types + i);
- i < dst->map->num_types; i++, dtype++) {
- if (dtype->level_names)
- xfree(dtype->level_names);
- dtype->level_names = NULL;
- dtype->num_levels = 0;
- if (dtype->map_count) {
- if (dtype->map)
- xfree(dtype->map);
- if (dtype->preserve)
- xfree(dtype->preserve);
- }
- }
- }
-
- stype = src->map->types;
- dtype = dst->map->types;
- for (i = 0; i < src->map->num_types; i++, dtype++, stype++) {
- if (stype->num_levels && stype->level_names) {
- if (stype->num_levels != dtype->num_levels &&
- dtype->num_levels && dtype->level_names &&
- i < dst->map->num_types) {
- tmp = xrealloc(dtype->level_names,
- stype->num_levels * sizeof(Atom));
- if (!tmp)
- continue;
- dtype->level_names = tmp;
- }
- else if (!dtype->num_levels || !dtype->level_names ||
- i >= dst->map->num_types) {
- tmp = xalloc(stype->num_levels * sizeof(Atom));
- if (!tmp)
- continue;
- dtype->level_names = tmp;
- }
- dtype->num_levels = stype->num_levels;
- memcpy(dtype->level_names, stype->level_names,
- stype->num_levels * sizeof(Atom));
- }
- else {
- if (dtype->num_levels && dtype->level_names &&
- i < dst->map->num_types)
- xfree(dtype->level_names);
- dtype->num_levels = 0;
- dtype->level_names = NULL;
- }
-
- dtype->name = stype->name;
- memcpy(&dtype->mods, &stype->mods, sizeof(XkbModsRec));
-
- if (stype->map_count) {
- if (stype->map) {
- if (stype->map_count != dtype->map_count &&
- dtype->map_count && dtype->map &&
- i < dst->map->num_types) {
- tmp = xrealloc(dtype->map,
- stype->map_count *
- sizeof(XkbKTMapEntryRec));
- if (!tmp)
- return FALSE;
- dtype->map = tmp;
- }
- else if (!dtype->map_count || !dtype->map ||
- i >= dst->map->num_types) {
- tmp = xalloc(stype->map_count *
- sizeof(XkbKTMapEntryRec));
- if (!tmp)
- return FALSE;
- dtype->map = tmp;
- }
-
- memcpy(dtype->map, stype->map,
- stype->map_count * sizeof(XkbKTMapEntryRec));
- }
- else {
- if (dtype->map && i < dst->map->num_types)
- xfree(dtype->map);
- dtype->map = NULL;
- }
-
- if (stype->preserve) {
- if (stype->map_count != dtype->map_count &&
- dtype->map_count && dtype->preserve &&
- i < dst->map->num_types) {
- tmp = xrealloc(dtype->preserve,
- stype->map_count *
- sizeof(XkbModsRec));
- if (!tmp)
- return FALSE;
- dtype->preserve = tmp;
- }
- else if (!dtype->preserve || !dtype->map_count ||
- i >= dst->map->num_types) {
- tmp = xalloc(stype->map_count *
- sizeof(XkbModsRec));
- if (!tmp)
- return FALSE;
- dtype->preserve = tmp;
- }
-
- memcpy(dtype->preserve, stype->preserve,
- stype->map_count * sizeof(XkbModsRec));
- }
- else {
- if (dtype->preserve && i < dst->map->num_types)
- xfree(dtype->preserve);
- dtype->preserve = NULL;
- }
-
- dtype->map_count = stype->map_count;
- }
- else {
- if (dtype->map_count && i < dst->map->num_types) {
- if (dtype->map)
- xfree(dtype->map);
- if (dtype->preserve)
- xfree(dtype->preserve);
- }
- dtype->map_count = 0;
- dtype->map = NULL;
- dtype->preserve = NULL;
- }
- }
-
- dst->map->size_types = src->map->num_types;
- dst->map->num_types = src->map->num_types;
- }
- else {
- if (dst->map->types) {
- for (i = 0, dtype = dst->map->types; i < dst->map->num_types;
- i++, dtype++) {
- if (dtype->level_names)
- xfree(dtype->level_names);
- if (dtype->map && dtype->map_count)
- xfree(dtype->map);
- if (dtype->preserve && dtype->map_count)
- xfree(dtype->preserve);
- }
- xfree(dst->map->types);
- dst->map->types = NULL;
- }
- dst->map->num_types = 0;
- dst->map->size_types = 0;
- }
-
- if (src->map->modmap) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->map->modmap)
- tmp = xrealloc(dst->map->modmap, src->max_key_code + 1);
- else
- tmp = xalloc(src->max_key_code + 1);
- if (!tmp)
- return FALSE;
- dst->map->modmap = tmp;
- }
- memcpy(dst->map->modmap, src->map->modmap, src->max_key_code + 1);
- }
- else {
- if (dst->map->modmap) {
- xfree(dst->map->modmap);
- dst->map->modmap = NULL;
- }
- }
- }
- else {
- if (dst->map)
- XkbFreeClientMap(dst, XkbAllClientInfoMask, TRUE);
- }
-
- return TRUE;
-}
-
-static Bool
-_XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
-{
- void *tmp = NULL;
-
- /* server map */
- if (src->server) {
- if (!dst->server) {
- tmp = xcalloc(1, sizeof(XkbServerMapRec));
- if (!tmp)
- return FALSE;
- dst->server = tmp;
- }
-
- if (src->server->explicit) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->server->explicit)
- tmp = xrealloc(dst->server->explicit, src->max_key_code + 1);
- else
- tmp = xalloc(src->max_key_code + 1);
- if (!tmp)
- return FALSE;
- dst->server->explicit = tmp;
- }
- memcpy(dst->server->explicit, src->server->explicit,
- src->max_key_code + 1);
- }
- else {
- if (dst->server->explicit) {
- xfree(dst->server->explicit);
- dst->server->explicit = NULL;
- }
- }
-
- if (src->server->acts) {
- if (src->server->size_acts != dst->server->size_acts) {
- if (dst->server->acts)
- tmp = xrealloc(dst->server->acts,
- src->server->size_acts * sizeof(XkbAction));
- else
- tmp = xalloc(src->server->size_acts * sizeof(XkbAction));
- if (!tmp)
- return FALSE;
- dst->server->acts = tmp;
- }
- memcpy(dst->server->acts, src->server->acts,
- src->server->size_acts * sizeof(XkbAction));
- }
- else {
- if (dst->server->acts) {
- xfree(dst->server->acts);
- dst->server->acts = NULL;
- }
- }
- dst->server->size_acts = src->server->size_acts;
- dst->server->num_acts = src->server->num_acts;
-
- if (src->server->key_acts) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->server->key_acts)
- tmp = xrealloc(dst->server->key_acts,
- (src->max_key_code + 1) *
- sizeof(unsigned short));
- else
- tmp = xalloc((src->max_key_code + 1) *
- sizeof(unsigned short));
- if (!tmp)
- return FALSE;
- dst->server->key_acts = tmp;
- }
- memcpy(dst->server->key_acts, src->server->key_acts,
- (src->max_key_code + 1) * sizeof(unsigned short));
- }
- else {
- if (dst->server->key_acts) {
- xfree(dst->server->key_acts);
- dst->server->key_acts = NULL;
- }
- }
-
- if (src->server->behaviors) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->server->behaviors)
- tmp = xrealloc(dst->server->behaviors,
- (src->max_key_code + 1) *
- sizeof(XkbBehavior));
- else
- tmp = xalloc((src->max_key_code + 1) *
- sizeof(XkbBehavior));
- if (!tmp)
- return FALSE;
- dst->server->behaviors = tmp;
- }
- memcpy(dst->server->behaviors, src->server->behaviors,
- (src->max_key_code + 1) * sizeof(XkbBehavior));
- }
- else {
- if (dst->server->behaviors) {
- xfree(dst->server->behaviors);
- dst->server->behaviors = NULL;
- }
- }
-
- memcpy(dst->server->vmods, src->server->vmods, XkbNumVirtualMods);
-
- if (src->server->vmodmap) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->server->vmodmap)
- tmp = xrealloc(dst->server->vmodmap,
- (src->max_key_code + 1) *
- sizeof(unsigned short));
- else
- tmp = xalloc((src->max_key_code + 1) *
- sizeof(unsigned short));
- if (!tmp)
- return FALSE;
- dst->server->vmodmap = tmp;
- }
- memcpy(dst->server->vmodmap, src->server->vmodmap,
- (src->max_key_code + 1) * sizeof(unsigned short));
- }
- else {
- if (dst->server->vmodmap) {
- xfree(dst->server->vmodmap);
- dst->server->vmodmap = NULL;
- }
- }
- }
- else {
- if (dst->server)
- XkbFreeServerMap(dst, XkbAllServerInfoMask, TRUE);
- }
-
- return TRUE;
-}
-
-static Bool
-_XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
-{
- void *tmp = NULL;
-
- /* names */
- if (src->names) {
- if (!dst->names) {
- dst->names = xcalloc(1, sizeof(XkbNamesRec));
- if (!dst->names)
- return FALSE;
- }
-
- if (src->names->keys) {
- if (src->max_key_code != dst->max_key_code) {
- if (dst->names->keys)
- tmp = xrealloc(dst->names->keys, (src->max_key_code + 1) *
- sizeof(XkbKeyNameRec));
- else
- tmp = xalloc((src->max_key_code + 1) *
- sizeof(XkbKeyNameRec));
- if (!tmp)
- return FALSE;
- dst->names->keys = tmp;
- }
- memcpy(dst->names->keys, src->names->keys,
- (src->max_key_code + 1) * sizeof(XkbKeyNameRec));
- }
- else {
- if (dst->names->keys) {
- xfree(dst->names->keys);
- dst->names->keys = NULL;
- }
- }
-
- if (src->names->num_key_aliases) {
- if (src->names->num_key_aliases != dst->names->num_key_aliases) {
- if (dst->names->key_aliases)
- tmp = xrealloc(dst->names->key_aliases,
- src->names->num_key_aliases *
- sizeof(XkbKeyAliasRec));
- else
- tmp = xalloc(src->names->num_key_aliases *
- sizeof(XkbKeyAliasRec));
- if (!tmp)
- return FALSE;
- dst->names->key_aliases = tmp;
- }
- memcpy(dst->names->key_aliases, src->names->key_aliases,
- src->names->num_key_aliases * sizeof(XkbKeyAliasRec));
- }
- else {
- if (dst->names->key_aliases) {
- xfree(dst->names->key_aliases);
- dst->names->key_aliases = NULL;
- }
- }
- dst->names->num_key_aliases = src->names->num_key_aliases;
-
- if (src->names->num_rg) {
- if (src->names->num_rg != dst->names->num_rg) {
- if (dst->names->radio_groups)
- tmp = xrealloc(dst->names->radio_groups,
- src->names->num_rg * sizeof(Atom));
- else
- tmp = xalloc(src->names->num_rg * sizeof(Atom));
- if (!tmp)
- return FALSE;
- dst->names->radio_groups = tmp;
- }
- memcpy(dst->names->radio_groups, src->names->radio_groups,
- src->names->num_rg * sizeof(Atom));
- }
- else {
- if (dst->names->radio_groups)
- xfree(dst->names->radio_groups);
- }
- dst->names->num_rg = src->names->num_rg;
-
- dst->names->keycodes = src->names->keycodes;
- dst->names->geometry = src->names->geometry;
- dst->names->symbols = src->names->symbols;
- dst->names->types = src->names->types;
- dst->names->compat = src->names->compat;
- dst->names->phys_symbols = src->names->phys_symbols;
-
- memcpy(dst->names->vmods, src->names->vmods,
- XkbNumVirtualMods * sizeof(Atom));
- memcpy(dst->names->indicators, src->names->indicators,
- XkbNumIndicators * sizeof(Atom));
- memcpy(dst->names->groups, src->names->groups,
- XkbNumKbdGroups * sizeof(Atom));
- }
- else {
- if (dst->names)
- XkbFreeNames(dst, XkbAllNamesMask, TRUE);
- }
-
- return TRUE;
-}
-
-static Bool
-_XkbCopyCompat(XkbDescPtr src, XkbDescPtr dst)
-{
- void *tmp = NULL;
-
- /* compat */
- if (src->compat) {
- if (!dst->compat) {
- dst->compat = xcalloc(1, sizeof(XkbCompatMapRec));
- if (!dst->compat)
- return FALSE;
- }
-
- if (src->compat->sym_interpret && src->compat->num_si) {
- if (src->compat->num_si != dst->compat->size_si) {
- if (dst->compat->sym_interpret)
- tmp = xrealloc(dst->compat->sym_interpret,
- src->compat->num_si *
- sizeof(XkbSymInterpretRec));
- else
- tmp = xalloc(src->compat->num_si *
- sizeof(XkbSymInterpretRec));
- if (!tmp)
- return FALSE;
- dst->compat->sym_interpret = tmp;
- }
- memcpy(dst->compat->sym_interpret, src->compat->sym_interpret,
- src->compat->num_si * sizeof(XkbSymInterpretRec));
-
- dst->compat->num_si = src->compat->num_si;
- dst->compat->size_si = src->compat->num_si;
- }
- else {
- if (dst->compat->sym_interpret && dst->compat->size_si)
- xfree(dst->compat->sym_interpret);
-
- dst->compat->sym_interpret = NULL;
- dst->compat->num_si = 0;
- dst->compat->size_si = 0;
- }
-
- memcpy(dst->compat->groups, src->compat->groups,
- XkbNumKbdGroups * sizeof(XkbModsRec));
- }
- else {
- if (dst->compat)
- XkbFreeCompatMap(dst, XkbAllCompatMask, TRUE);
- }
-
- return TRUE;
-}
-
-static Bool
-_XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
-{
- void *tmp = NULL;
- int i = 0, j = 0, k = 0;
- XkbColorPtr scolor = NULL, dcolor = NULL;
- XkbDoodadPtr sdoodad = NULL, ddoodad = NULL;
- XkbOutlinePtr soutline = NULL, doutline = NULL;
- XkbPropertyPtr sprop = NULL, dprop = NULL;
- XkbRowPtr srow = NULL, drow = NULL;
- XkbSectionPtr ssection = NULL, dsection = NULL;
- XkbShapePtr sshape = NULL, dshape = NULL;
-
- /* geometry */
- if (src->geom) {
- if (!dst->geom) {
- dst->geom = xcalloc(sizeof(XkbGeometryRec), 1);
- if (!dst->geom)
- return FALSE;
- }
-
- /* properties */
- if (src->geom->num_properties) {
- if (src->geom->num_properties != dst->geom->sz_properties) {
- /* If we've got more properties in the destination than
- * the source, run through and free all the excess ones
- * first. */
- if (src->geom->num_properties < dst->geom->sz_properties) {
- for (i = src->geom->num_properties,
- dprop = dst->geom->properties + i;
- i < dst->geom->num_properties;
- i++, dprop++) {
- xfree(dprop->name);
- xfree(dprop->value);
- }
- }
-
- if (dst->geom->sz_properties)
- tmp = xrealloc(dst->geom->properties,
- src->geom->num_properties *
- sizeof(XkbPropertyRec));
- else
- tmp = xalloc(src->geom->num_properties *
- sizeof(XkbPropertyRec));
- if (!tmp)
- return FALSE;
- dst->geom->properties = tmp;
- }
-
- /* We don't set num_properties as we need it to try and avoid
- * too much reallocing. */
- dst->geom->sz_properties = src->geom->num_properties;
-
- if (dst->geom->sz_properties > dst->geom->num_properties) {
- bzero(dst->geom->properties + dst->geom->num_properties,
- (dst->geom->sz_properties - dst->geom->num_properties) *
- sizeof(XkbPropertyRec));
- }
-
- for (i = 0,
- sprop = src->geom->properties,
- dprop = dst->geom->properties;
- i < src->geom->num_properties;
- i++, sprop++, dprop++) {
- if (i < dst->geom->num_properties) {
- if (strlen(sprop->name) != strlen(dprop->name)) {
- tmp = xrealloc(dprop->name, strlen(sprop->name) + 1);
- if (!tmp)
- return FALSE;
- dprop->name = tmp;
- }
- if (strlen(sprop->value) != strlen(dprop->value)) {
- tmp = xrealloc(dprop->value, strlen(sprop->value) + 1);
- if (!tmp)
- return FALSE;
- dprop->value = tmp;
- }
- strcpy(dprop->name, sprop->name);
- strcpy(dprop->value, sprop->value);
- }
- else {
- dprop->name = xstrdup(sprop->name);
- dprop->value = xstrdup(sprop->value);
- }
- }
-
- /* ... which is already src->geom->num_properties. */
- dst->geom->num_properties = dst->geom->sz_properties;
- }
- else {
- if (dst->geom->sz_properties) {
- for (i = 0, dprop = dst->geom->properties;
- i < dst->geom->num_properties;
- i++, dprop++) {
- xfree(dprop->name);
- xfree(dprop->value);
- }
- xfree(dst->geom->properties);
- dst->geom->properties = NULL;
- }
-
- dst->geom->num_properties = 0;
- dst->geom->sz_properties = 0;
- }
-
- /* colors */
- if (src->geom->num_colors) {
- if (src->geom->num_colors != dst->geom->sz_colors) {
- if (src->geom->num_colors < dst->geom->sz_colors) {
- for (i = src->geom->num_colors,
- dcolor = dst->geom->colors + i;
- i < dst->geom->num_colors;
- i++, dcolor++) {
- xfree(dcolor->spec);
- }
- }
-
- if (dst->geom->sz_colors)
- tmp = xrealloc(dst->geom->colors,
- src->geom->num_colors *
- sizeof(XkbColorRec));
- else
- tmp = xalloc(src->geom->num_colors *
- sizeof(XkbColorRec));
- if (!tmp)
- return FALSE;
- dst->geom->colors = tmp;
- }
-
- dst->geom->sz_colors = src->geom->num_colors;
-
- if (dst->geom->sz_colors > dst->geom->num_colors) {
- bzero(dst->geom->colors + dst->geom->num_colors,
- (dst->geom->sz_colors - dst->geom->num_colors) *
- sizeof(XkbColorRec));
- }
-
- for (i = 0,
- scolor = src->geom->colors,
- dcolor = dst->geom->colors;
- i < src->geom->num_colors;
- i++, scolor++, dcolor++) {
- if (i < dst->geom->num_colors) {
- if (strlen(scolor->spec) != strlen(dcolor->spec)) {
- tmp = xrealloc(dcolor->spec, strlen(scolor->spec) + 1);
- if (!tmp)
- return FALSE;
- dcolor->spec = tmp;
- }
- strcpy(dcolor->spec, scolor->spec);
- }
- else {
- dcolor->spec = xstrdup(scolor->spec);
- }
- dcolor->pixel = scolor->pixel;
- }
-
- dst->geom->num_colors = dst->geom->sz_colors;
- }
- else {
- if (dst->geom->sz_colors) {
- for (i = 0, dcolor = dst->geom->colors;
- i < dst->geom->num_colors;
- i++, dcolor++) {
- xfree(dcolor->spec);
- }
- xfree(dst->geom->colors);
- dst->geom->colors = NULL;
- }
-
- dst->geom->num_colors = 0;
- dst->geom->sz_colors = 0;
- }
-
- /* shapes */
- /* shapes break down into outlines, which break down into points. */
- if (dst->geom->num_shapes) {
- for (i = 0, dshape = dst->geom->shapes;
- i < dst->geom->num_shapes;
- i++, dshape++) {
- for (j = 0, doutline = dshape->outlines;
- j < dshape->num_outlines;
- j++, doutline++) {
- if (doutline->sz_points)
- xfree(doutline->points);
- }
-
- if (dshape->sz_outlines) {
- xfree(dshape->outlines);
- dshape->outlines = NULL;
- }
-
- dshape->num_outlines = 0;
- dshape->sz_outlines = 0;
- }
- }
-
- if (src->geom->num_shapes) {
- tmp = xcalloc(src->geom->num_shapes, sizeof(XkbShapeRec));
- if (!tmp)
- return FALSE;
- dst->geom->shapes = tmp;
-
- for (i = 0, sshape = src->geom->shapes, dshape = dst->geom->shapes;
- i < src->geom->num_shapes;
- i++, sshape++, dshape++) {
- if (sshape->num_outlines) {
- tmp = xcalloc(sshape->num_outlines, sizeof(XkbOutlineRec));
- if (!tmp)
- return FALSE;
- dshape->outlines = tmp;
-
- for (j = 0,
- soutline = sshape->outlines,
- doutline = dshape->outlines;
- j < sshape->num_outlines;
- j++, soutline++, doutline++) {
- if (soutline->num_points) {
- tmp = xalloc(soutline->num_points *
- sizeof(XkbPointRec));
- if (!tmp)
- return FALSE;
- doutline->points = tmp;
-
- memcpy(doutline->points, soutline->points,
- soutline->num_points * sizeof(XkbPointRec));
-
- doutline->corner_radius = soutline->corner_radius;
- }
-
- doutline->num_points = soutline->num_points;
- doutline->sz_points = soutline->num_points;
- }
- }
-
- dshape->num_outlines = sshape->num_outlines;
- dshape->sz_outlines = sshape->num_outlines;
- dshape->name = sshape->name;
- dshape->bounds = sshape->bounds;
-
- dshape->approx = NULL;
- if (sshape->approx && sshape->num_outlines > 0) {
-
- const ptrdiff_t approx_idx =
- sshape->approx - sshape->outlines;
-
- if (approx_idx < dshape->num_outlines) {
- dshape->approx = dshape->outlines + approx_idx;
- } else {
- LogMessage(X_WARNING, "XKB: approx outline "
- "index is out of range\n");
- }
- }
-
- dshape->primary = NULL;
- if (sshape->primary && sshape->num_outlines > 0) {
-
- const ptrdiff_t primary_idx =
- sshape->primary - sshape->outlines;
-
- if (primary_idx < dshape->num_outlines) {
- dshape->primary = dshape->outlines + primary_idx;
- } else {
- LogMessage(X_WARNING, "XKB: primary outline "
- "index is out of range\n");
- }
- }
- }
-
- dst->geom->num_shapes = src->geom->num_shapes;
- dst->geom->sz_shapes = src->geom->num_shapes;
- }
- else {
- if (dst->geom->sz_shapes) {
- xfree(dst->geom->shapes);
- }
- dst->geom->shapes = NULL;
- dst->geom->num_shapes = 0;
- dst->geom->sz_shapes = 0;
- }
-
- /* sections */
- /* sections break down into doodads, and also into rows, which break
- * down into keys. */
- if (dst->geom->num_sections) {
- for (i = 0, dsection = dst->geom->sections;
- i < dst->geom->num_sections;
- i++, dsection++) {
- for (j = 0, drow = dsection->rows;
- j < dsection->num_rows;
- j++, drow++) {
- if (drow->num_keys)
- xfree(drow->keys);
- }
-
- if (dsection->num_rows)
- xfree(dsection->rows);
-
- /* cut and waste from geom/doodad below. */
- for (j = 0, ddoodad = dsection->doodads;
- j < dsection->num_doodads;
- j++, ddoodad++) {
- if (ddoodad->any.type == XkbTextDoodad) {
- if (ddoodad->text.text) {
- xfree(ddoodad->text.text);
- ddoodad->text.text = NULL;
- }
- if (ddoodad->text.font) {
- xfree(ddoodad->text.font);
- ddoodad->text.font = NULL;
- }
- }
- else if (ddoodad->any.type == XkbLogoDoodad) {
- if (ddoodad->logo.logo_name) {
- xfree(ddoodad->logo.logo_name);
- ddoodad->logo.logo_name = NULL;
- }
- }
- }
-
- if (dsection->num_doodads)
- xfree(dsection->doodads);
- }
-
- dst->geom->num_sections = 0;
- dst->geom->sections = NULL;
- }
-
- if (src->geom->num_sections) {
- if (dst->geom->sz_sections)
- tmp = xrealloc(dst->geom->sections,
- src->geom->num_sections *
- sizeof(XkbSectionRec));
- else
- tmp = xalloc(src->geom->num_sections * sizeof(XkbSectionRec));
- if (!tmp)
- return FALSE;
- memset(tmp, 0, src->geom->num_sections * sizeof(XkbSectionRec));
- dst->geom->sections = tmp;
- dst->geom->num_sections = src->geom->num_sections;
- dst->geom->sz_sections = src->geom->num_sections;
-
- for (i = 0,
- ssection = src->geom->sections,
- dsection = dst->geom->sections;
- i < src->geom->num_sections;
- i++, ssection++, dsection++) {
- *dsection = *ssection;
- if (ssection->num_rows) {
- tmp = xcalloc(ssection->num_rows, sizeof(XkbRowRec));
- if (!tmp)
- return FALSE;
- dsection->rows = tmp;
- }
- dsection->num_rows = ssection->num_rows;
- dsection->sz_rows = ssection->num_rows;
-
- for (j = 0, srow = ssection->rows, drow = dsection->rows;
- j < ssection->num_rows;
- j++, srow++, drow++) {
- if (srow->num_keys) {
- tmp = xalloc(srow->num_keys * sizeof(XkbKeyRec));
- if (!tmp)
- return FALSE;
- drow->keys = tmp;
- memcpy(drow->keys, srow->keys,
- srow->num_keys * sizeof(XkbKeyRec));
- }
- drow->num_keys = srow->num_keys;
- drow->sz_keys = srow->num_keys;
- drow->top = srow->top;
- drow->left = srow->left;
- drow->vertical = srow->vertical;
- drow->bounds = srow->bounds;
- }
-
- if (ssection->num_doodads) {
- tmp = xcalloc(ssection->num_doodads, sizeof(XkbDoodadRec));
- if (!tmp)
- return FALSE;
- dsection->doodads = tmp;
- }
- else {
- dsection->doodads = NULL;
- }
-
- dsection->sz_doodads = ssection->num_doodads;
- for (k = 0,
- sdoodad = ssection->doodads,
- ddoodad = dsection->doodads;
- k < ssection->num_doodads;
- k++, sdoodad++, ddoodad++) {
- memcpy(ddoodad , sdoodad, sizeof(XkbDoodadRec));
- if (sdoodad->any.type == XkbTextDoodad) {
- if (sdoodad->text.text)
- ddoodad->text.text =
- xstrdup(sdoodad->text.text);
- if (sdoodad->text.font)
- ddoodad->text.font =
- xstrdup(sdoodad->text.font);
- }
- else if (sdoodad->any.type == XkbLogoDoodad) {
- if (sdoodad->logo.logo_name)
- ddoodad->logo.logo_name =
- xstrdup(sdoodad->logo.logo_name);
- }
- }
- dsection->overlays = NULL;
- dsection->sz_overlays = 0;
- dsection->num_overlays = 0;
- }
- }
- else {
- if (dst->geom->sz_sections) {
- xfree(dst->geom->sections);
- }
-
- dst->geom->sections = NULL;
- dst->geom->num_sections = 0;
- dst->geom->sz_sections = 0;
- }
-
- /* doodads */
- if (dst->geom->num_doodads) {
- for (i = src->geom->num_doodads,
- ddoodad = dst->geom->doodads +
- src->geom->num_doodads;
- i < dst->geom->num_doodads;
- i++, ddoodad++) {
- if (ddoodad->any.type == XkbTextDoodad) {
- if (ddoodad->text.text) {
- xfree(ddoodad->text.text);
- ddoodad->text.text = NULL;
- }
- if (ddoodad->text.font) {
- xfree(ddoodad->text.font);
- ddoodad->text.font = NULL;
- }
- }
- else if (ddoodad->any.type == XkbLogoDoodad) {
- if (ddoodad->logo.logo_name) {
- xfree(ddoodad->logo.logo_name);
- ddoodad->logo.logo_name = NULL;
- }
- }
- }
- dst->geom->num_doodads = 0;
- dst->geom->doodads = NULL;
- }
-
- if (src->geom->num_doodads) {
- if (dst->geom->sz_doodads)
- tmp = xrealloc(dst->geom->doodads,
- src->geom->num_doodads *
- sizeof(XkbDoodadRec));
- else
- tmp = xalloc(src->geom->num_doodads *
- sizeof(XkbDoodadRec));
- if (!tmp)
- return FALSE;
- memset(tmp, 0, src->geom->num_doodads * sizeof(XkbDoodadRec));
- dst->geom->doodads = tmp;
-
- dst->geom->sz_doodads = src->geom->num_doodads;
-
- for (i = 0,
- sdoodad = src->geom->doodads,
- ddoodad = dst->geom->doodads;
- i < src->geom->num_doodads;
- i++, sdoodad++, ddoodad++) {
- memcpy(ddoodad , sdoodad, sizeof(XkbDoodadRec));
- if (sdoodad->any.type == XkbTextDoodad) {
- if (sdoodad->text.text)
- ddoodad->text.text = xstrdup(sdoodad->text.text);
- if (sdoodad->text.font)
- ddoodad->text.font = xstrdup(sdoodad->text.font);
- }
- else if (sdoodad->any.type == XkbLogoDoodad) {
- if (sdoodad->logo.logo_name)
- ddoodad->logo.logo_name =
- xstrdup(sdoodad->logo.logo_name);
- }
- }
-
- dst->geom->num_doodads = dst->geom->sz_doodads;
- }
- else {
- if (dst->geom->sz_doodads) {
- xfree(dst->geom->doodads);
- }
-
- dst->geom->doodads = NULL;
- dst->geom->num_doodads = 0;
- dst->geom->sz_doodads = 0;
- }
-
- /* key aliases */
- if (src->geom->num_key_aliases) {
- if (src->geom->num_key_aliases != dst->geom->sz_key_aliases) {
- if (dst->geom->sz_key_aliases)
- tmp = xrealloc(dst->geom->key_aliases,
- src->geom->num_key_aliases *
- 2 * XkbKeyNameLength);
- else
- tmp = xalloc(src->geom->num_key_aliases *
- 2 * XkbKeyNameLength);
- if (!tmp)
- return FALSE;
- dst->geom->key_aliases = tmp;
-
- dst->geom->sz_key_aliases = src->geom->num_key_aliases;
- }
-
- memcpy(dst->geom->key_aliases, src->geom->key_aliases,
- src->geom->num_key_aliases * 2 * XkbKeyNameLength);
-
- dst->geom->num_key_aliases = dst->geom->sz_key_aliases;
- }
- else {
- if (dst->geom->key_aliases) {
- xfree(dst->geom->key_aliases);
- }
- dst->geom->key_aliases = NULL;
- dst->geom->num_key_aliases = 0;
- dst->geom->sz_key_aliases = 0;
- }
-
- /* font */
- if (src->geom->label_font) {
- if (!dst->geom->label_font) {
- tmp = xalloc(strlen(src->geom->label_font));
- if (!tmp)
- return FALSE;
- dst->geom->label_font = tmp;
- }
- else if (strlen(src->geom->label_font) !=
- strlen(dst->geom->label_font)) {
- tmp = xrealloc(dst->geom->label_font,
- strlen(src->geom->label_font));
- if (!tmp)
- return FALSE;
- dst->geom->label_font = tmp;
- }
-
- strcpy(dst->geom->label_font, src->geom->label_font);
- i = XkbGeomColorIndex(src->geom, src->geom->label_color);
- dst->geom->label_color = &(dst->geom->colors[i]);
- i = XkbGeomColorIndex(src->geom, src->geom->base_color);
- dst->geom->base_color = &(dst->geom->colors[i]);
- }
- else {
- if (dst->geom->label_font) {
- xfree(dst->geom->label_font);
- }
- dst->geom->label_font = NULL;
- dst->geom->label_color = NULL;
- dst->geom->base_color = NULL;
- }
-
- dst->geom->name = src->geom->name;
- dst->geom->width_mm = src->geom->width_mm;
- dst->geom->height_mm = src->geom->height_mm;
- }
- else
- {
- if (dst->geom) {
- /* I LOVE THE DIFFERENT CALL SIGNATURE. REALLY, I DO. */
- XkbFreeGeometry(dst->geom, XkbGeomAllMask, TRUE);
- dst->geom = NULL;
- }
- }
-
- return TRUE;
-}
-
-static Bool
-_XkbCopyIndicators(XkbDescPtr src, XkbDescPtr dst)
-{
- /* indicators */
- if (src->indicators) {
- if (!dst->indicators) {
- dst->indicators = xalloc(sizeof(XkbIndicatorRec));
- if (!dst->indicators)
- return FALSE;
- }
- memcpy(dst->indicators, src->indicators, sizeof(XkbIndicatorRec));
- }
- else {
- if (dst->indicators) {
- xfree(dst->indicators);
- dst->indicators = NULL;
- }
- }
- return TRUE;
-}
-
-static Bool
-_XkbCopyControls(XkbDescPtr src, XkbDescPtr dst)
-{
- /* controls */
- if (src->ctrls) {
- if (!dst->ctrls) {
- dst->ctrls = xalloc(sizeof(XkbControlsRec));
- if (!dst->ctrls)
- return FALSE;
- }
- memcpy(dst->ctrls, src->ctrls, sizeof(XkbControlsRec));
- }
- else {
- if (dst->ctrls) {
- xfree(dst->ctrls);
- dst->ctrls = NULL;
- }
- }
- return TRUE;
-}
-
-/**
- * Copy an XKB map from src to dst, reallocating when necessary: if some
- * map components are present in one, but not in the other, the destination
- * components will be allocated or freed as necessary.
- *
- * Basic map consistency is assumed on both sides, so maps with random
- * uninitialised data (e.g. names->radio_grous == NULL, names->num_rg == 19)
- * _will_ cause failures. You've been warned.
- *
- * Returns TRUE on success, or FALSE on failure. If this function fails,
- * dst may be in an inconsistent state: all its pointers are guaranteed
- * to remain valid, but part of the map may be from src and part from dst.
- *
- */
-
-Bool
-XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
-{
-
- if (!src || !dst) {
- DebugF("XkbCopyKeymap: src (%p) or dst (%p) is NULL\n", src, dst);
- return FALSE;
- }
-
- if (src == dst)
- return TRUE;
-
- if (!_XkbCopyClientMap(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy client map\n");
- return FALSE;
- }
- if (!_XkbCopyServerMap(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy server map\n");
- return FALSE;
- }
- if (!_XkbCopyIndicators(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy indicators\n");
- return FALSE;
- }
- if (!_XkbCopyControls(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy controls\n");
- return FALSE;
- }
- if (!_XkbCopyNames(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy names\n");
- return FALSE;
- }
- if (!_XkbCopyCompat(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy compat map\n");
- return FALSE;
- }
- if (!_XkbCopyGeom(src, dst)) {
- DebugF("XkbCopyKeymap: failed to copy geometry\n");
- return FALSE;
- }
-
- dst->min_key_code = src->min_key_code;
- dst->max_key_code = src->max_key_code;
-
- return TRUE;
-}
-
-Bool
-XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
-{
- xkbNewKeyboardNotify nkn;
- Bool ret;
-
- if (!dst->key || !src->key)
- return FALSE;
-
- memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
- nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
- nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
- nkn.deviceID = dst->id;
- nkn.oldDeviceID = dst->id; /* maybe src->id? */
- nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
- nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
- nkn.requestMajor = XkbReqCode;
- nkn.requestMinor = X_kbSetMap; /* Near enough's good enough. */
- nkn.changed = XkbNKN_KeycodesMask;
- if (src->key->xkbInfo->desc->geom)
- nkn.changed |= XkbNKN_GeometryMask;
-
- ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
- if (ret)
- XkbSendNewKeyboardNotify(dst, &nkn);
-
- return ret;
-}
-
-int
-XkbGetEffectiveGroup(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 keycode)
-{
- XkbDescPtr xkb = xkbi->desc;
- int effectiveGroup = xkbState->group;
-
- if (!XkbKeycodeInRange(xkb, keycode))
- return -1;
-
- if (effectiveGroup == XkbGroup1Index)
- return effectiveGroup;
-
- if (XkbKeyNumGroups(xkb,keycode) > 1U) {
- if (effectiveGroup >= XkbKeyNumGroups(xkb,keycode)) {
- unsigned int gi = XkbKeyGroupInfo(xkb,keycode);
- switch (XkbOutOfRangeGroupAction(gi)) {
- default:
- case XkbWrapIntoRange:
- effectiveGroup %= XkbKeyNumGroups(xkb, keycode);
- break;
- case XkbClampIntoRange:
- effectiveGroup = XkbKeyNumGroups(xkb, keycode) - 1;
- break;
- case XkbRedirectIntoRange:
- effectiveGroup = XkbOutOfRangeGroupInfo(gi);
- if (effectiveGroup >= XkbKeyNumGroups(xkb, keycode))
- effectiveGroup = 0;
- break;
- }
- }
- }
- else effectiveGroup = XkbGroup1Index;
-
- return effectiveGroup;
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+/*
+
+Copyright © 2008 Red Hat Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "os.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#define XK_CYRILLIC
+#include <X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "eventstr.h"
+
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+#include "xkb.h"
+
+/***====================================================================***/
+
+int
+_XkbLookupAnyDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
+ Mask access_mode, int *xkb_err)
+{
+ int rc = XkbKeyboardErrorCode;
+
+ if (id == XkbUseCoreKbd)
+ id = PickKeyboard(client)->id;
+ else if (id == XkbUseCorePtr)
+ id = PickPointer(client)->id;
+
+ rc = dixLookupDevice(pDev, id, client, access_mode);
+ if (rc != Success)
+ *xkb_err = XkbErr_BadDevice;
+
+ return rc;
+}
+
+int
+_XkbLookupKeyboard(DeviceIntPtr *pDev, int id, ClientPtr client,
+ Mask access_mode, int *xkb_err)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ if (id == XkbDfltXIId)
+ id = XkbUseCoreKbd;
+
+ rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
+ if (rc != Success)
+ return rc;
+
+ dev = *pDev;
+ if (!dev->key || !dev->key->xkbInfo) {
+ *pDev = NULL;
+ *xkb_err= XkbErr_BadClass;
+ return XkbKeyboardErrorCode;
+ }
+ return Success;
+}
+
+int
+_XkbLookupBellDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
+ Mask access_mode, int *xkb_err)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
+ if (rc != Success)
+ return rc;
+
+ dev = *pDev;
+ if (!dev->kbdfeed && !dev->bell) {
+ *pDev = NULL;
+ *xkb_err= XkbErr_BadClass;
+ return XkbKeyboardErrorCode;
+ }
+ return Success;
+}
+
+int
+_XkbLookupLedDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
+ Mask access_mode, int *xkb_err)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ if (id == XkbDfltXIId)
+ id = XkbUseCorePtr;
+
+ rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
+ if (rc != Success)
+ return rc;
+
+ dev = *pDev;
+ if (!dev->kbdfeed && !dev->leds) {
+ *pDev = NULL;
+ *xkb_err= XkbErr_BadClass;
+ return XkbKeyboardErrorCode;
+ }
+ return Success;
+}
+
+int
+_XkbLookupButtonDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
+ Mask access_mode, int *xkb_err)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ rc = _XkbLookupAnyDevice(pDev, id, client, access_mode, xkb_err);
+ if (rc != Success)
+ return rc;
+
+ dev = *pDev;
+ if (!dev->button) {
+ *pDev = NULL;
+ *xkb_err= XkbErr_BadClass;
+ return XkbKeyboardErrorCode;
+ }
+ return Success;
+}
+
+void
+XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
+{
+register unsigned tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (act->mods.flags&XkbSA_UseModMapMods)
+ act->mods.real_mods= act->mods.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->mods))!=0)
+ act->mods.mask|= XkbMaskForVMask(xkb,tmp);
+ break;
+ case XkbSA_ISOLock:
+ if (act->iso.flags&XkbSA_UseModMapMods)
+ act->iso.real_mods= act->iso.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->iso))!=0)
+ act->iso.mask|= XkbMaskForVMask(xkb,tmp);
+ break;
+ }
+ return;
+}
+
+unsigned
+XkbMaskForVMask(XkbDescPtr xkb,unsigned vmask)
+{
+register int i,bit;
+register unsigned mask;
+
+ for (mask=i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (vmask&bit)
+ mask|= xkb->server->vmods[i];
+ }
+ return mask;
+}
+
+/***====================================================================***/
+
+void
+XkbUpdateKeyTypesFromCore( DeviceIntPtr pXDev,
+ KeySymsPtr pCore,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes)
+{
+XkbDescPtr xkb;
+unsigned key,nG,explicit;
+int types[XkbNumKbdGroups];
+KeySym tsyms[XkbMaxSymsPerKey],*syms;
+XkbMapChangesPtr mc;
+
+ xkb= pXDev->key->xkbInfo->desc;
+ if (first+num-1>xkb->max_key_code) {
+ /* 1/12/95 (ef) -- XXX! should allow XKB structures to grow */
+ num= xkb->max_key_code-first+1;
+ }
+
+ mc= (changes?(&changes->map):NULL);
+
+ syms= &pCore->map[(first - pCore->minKeyCode) * pCore->mapWidth];
+ for (key=first; key<(first+num); key++,syms+= pCore->mapWidth) {
+ explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
+ types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
+ types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
+ types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
+ types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
+ nG= XkbKeyTypesForCoreSymbols(xkb,pCore->mapWidth,syms,explicit,types,
+ tsyms);
+ XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
+ memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
+ XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
+ }
+ if (changes->map.changed&XkbKeySymsMask) {
+ CARD8 oldLast,newLast;
+ oldLast = changes->map.first_key_sym+changes->map.num_key_syms-1;
+ newLast = first+num-1;
+
+ if (first<changes->map.first_key_sym)
+ changes->map.first_key_sym = first;
+ if (oldLast>newLast)
+ newLast= oldLast;
+ changes->map.num_key_syms = newLast-changes->map.first_key_sym+1;
+ }
+ else {
+ changes->map.changed|= XkbKeySymsMask;
+ changes->map.first_key_sym = first;
+ changes->map.num_key_syms = num;
+ }
+ return;
+}
+
+void
+XkbUpdateDescActions( XkbDescPtr xkb,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes)
+{
+register unsigned key;
+
+ for (key=first;key<(first+num);key++) {
+ XkbApplyCompatMapToKey(xkb,key,changes);
+ }
+
+ if (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask)) {
+ unsigned char newVMods[XkbNumVirtualMods];
+ register unsigned bit,i;
+ unsigned present;
+
+ bzero(newVMods,XkbNumVirtualMods);
+ present= 0;
+ for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
+ if (xkb->server->vmodmap[key]==0)
+ continue;
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (bit&xkb->server->vmodmap[key]) {
+ present|= bit;
+ newVMods[i]|= xkb->map->modmap[key];
+ }
+ }
+ }
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
+ changes->map.changed|= XkbVirtualModsMask;
+ changes->map.vmods|= bit;
+ xkb->server->vmods[i]= newVMods[i];
+ }
+ }
+ }
+ if (changes->map.changed&XkbVirtualModsMask)
+ XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
+
+ if (changes->map.changed&XkbKeyActionsMask) {
+ CARD8 oldLast,newLast;
+ oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
+ newLast = first+num-1;
+
+ if (first<changes->map.first_key_act)
+ changes->map.first_key_act = first;
+ if (newLast>oldLast)
+ newLast= oldLast;
+ changes->map.num_key_acts= newLast-changes->map.first_key_act+1;
+ }
+ else {
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act = first;
+ changes->map.num_key_acts = num;
+ }
+ return;
+}
+
+void
+XkbUpdateActions( DeviceIntPtr pXDev,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes,
+ unsigned * needChecksRtrn,
+ XkbEventCausePtr cause)
+{
+XkbSrvInfoPtr xkbi;
+XkbDescPtr xkb;
+CARD8 * repeat;
+
+ if (needChecksRtrn)
+ *needChecksRtrn= 0;
+ xkbi= pXDev->key->xkbInfo;
+ xkb= xkbi->desc;
+ repeat= xkb->ctrls->per_key_repeat;
+
+ if (pXDev->kbdfeed)
+ memcpy(repeat,pXDev->kbdfeed->ctrl.autoRepeats,XkbPerKeyBitArraySize);
+
+ XkbUpdateDescActions(xkb,first,num,changes);
+
+ if ((pXDev->kbdfeed)&&
+ (changes->ctrls.enabled_ctrls_changes&XkbPerKeyRepeatMask)) {
+ memcpy(pXDev->kbdfeed->ctrl.autoRepeats,repeat, XkbPerKeyBitArraySize);
+ (*pXDev->kbdfeed->CtrlProc)(pXDev, &pXDev->kbdfeed->ctrl);
+ }
+ return;
+}
+
+KeySymsPtr
+XkbGetCoreMap(DeviceIntPtr keybd)
+{
+register int key,tmp;
+int maxSymsPerKey, maxGroup1Width;
+XkbDescPtr xkb;
+KeySymsPtr syms;
+int maxNumberOfGroups;
+
+ if (!keybd || !keybd->key || !keybd->key->xkbInfo)
+ return NULL;
+
+ xkb= keybd->key->xkbInfo->desc;
+ maxSymsPerKey= maxGroup1Width= 0;
+ maxNumberOfGroups = 0;
+
+ /* determine sizes */
+ for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
+ if (XkbKeycodeInRange(xkb,key)) {
+ int nGroups;
+ int w;
+ nGroups= XkbKeyNumGroups(xkb,key);
+ tmp= 0;
+ if (nGroups>0) {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup1Index))<=2)
+ tmp+= 2;
+ else tmp+= w + 2;
+ /* remember highest G1 width */
+ if (w > maxGroup1Width)
+ maxGroup1Width = w;
+ }
+ if (nGroups>1) {
+ if (tmp <= 2) {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))<2)
+ tmp+= 2;
+ else tmp+= w;
+ } else {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))>2)
+ tmp+= w - 2;
+ }
+ }
+ if (nGroups>2)
+ tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup3Index);
+ if (nGroups>3)
+ tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup4Index);
+ if (tmp>maxSymsPerKey)
+ maxSymsPerKey= tmp;
+ if (nGroups > maxNumberOfGroups)
+ maxNumberOfGroups = nGroups;
+ }
+ }
+
+ if (maxSymsPerKey <= 0)
+ return NULL;
+
+ syms = calloc(1, sizeof(*syms));
+ if (!syms)
+ return NULL;
+
+ /* See Section 12.4 of the XKB Protocol spec. Because of the
+ * single-group distribution for multi-group keyboards, we have to
+ * have enough symbols for the largest group 1 to replicate across the
+ * number of groups on the keyboard. e.g. a single-group key with 4
+ * symbols on a keyboard that has 3 groups -> 12 syms per key */
+ if (maxSymsPerKey < maxNumberOfGroups * maxGroup1Width)
+ maxSymsPerKey = maxNumberOfGroups * maxGroup1Width;
+
+ syms->mapWidth = maxSymsPerKey;
+ syms->minKeyCode = xkb->min_key_code;
+ syms->maxKeyCode = xkb->max_key_code;
+
+ tmp = syms->mapWidth * (xkb->max_key_code - xkb->min_key_code + 1);
+ syms->map = calloc(tmp, sizeof(*syms->map));
+ if (!syms->map) {
+ free(syms);
+ return NULL;
+ }
+
+ for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
+ KeySym *pCore,*pXKB;
+ unsigned nGroups,groupWidth,n,nOut;
+
+ nGroups= XkbKeyNumGroups(xkb,key);
+ n= (key-xkb->min_key_code)*syms->mapWidth;
+ pCore= &syms->map[n];
+ pXKB= XkbKeySymsPtr(xkb,key);
+ nOut= 2;
+ if (nGroups>0) {
+ groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup1Index);
+ if (groupWidth>0) pCore[0]= pXKB[0];
+ if (groupWidth>1) pCore[1]= pXKB[1];
+ for (n=2;n<groupWidth;n++)
+ pCore[2+n]= pXKB[n];
+ if (groupWidth>2)
+ nOut= groupWidth;
+ }
+
+ /* See XKB Protocol Sec, Section 12.4.
+ A 1-group key with ABCDE on a 2 group keyboard must be
+ duplicated across all groups as ABABCDECDE.
+ */
+ if (nGroups == 1)
+ {
+ int idx, j;
+
+ groupWidth = XkbKeyGroupWidth(xkb, key, XkbGroup1Index);
+
+ /* AB..CDE... -> ABABCDE... */
+ if (groupWidth > 0 && syms->mapWidth >= 3)
+ pCore[2] = pCore[0];
+ if (groupWidth > 1 && syms->mapWidth >= 4)
+ pCore[3] = pCore[1];
+
+ /* ABABCDE... -> ABABCDECDE */
+ idx = 2 + groupWidth;
+ while (groupWidth > 2 && idx < syms->mapWidth &&
+ idx < groupWidth * 2)
+ {
+ pCore[idx] = pCore[idx - groupWidth + 2];
+ idx++;
+ }
+ idx = 2 * groupWidth;
+ if (idx < 4)
+ idx = 4;
+ /* 3 or more groups: ABABCDECDEABCDEABCDE */
+ for (j = 3; j <= maxNumberOfGroups; j++)
+ for (n = 0; n < groupWidth && idx < maxSymsPerKey; n++)
+ pCore[idx++] = pXKB[n];
+ }
+
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ nOut+= 2;
+ if (nGroups>1) {
+ groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index);
+ if (groupWidth>0) pCore[2]= pXKB[0];
+ if (groupWidth>1) pCore[3]= pXKB[1];
+ for (n=2;n<groupWidth;n++) {
+ pCore[nOut+(n-2)]= pXKB[n];
+ }
+ if (groupWidth>2)
+ nOut+= (groupWidth-2);
+ }
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ for (n=XkbGroup3Index;n<nGroups;n++) {
+ register int s;
+ groupWidth= XkbKeyGroupWidth(xkb,key,n);
+ for (s=0;s<groupWidth;s++) {
+ pCore[nOut++]= pXKB[s];
+ }
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ }
+ }
+
+ return syms;
+}
+
+void
+XkbSetRepeatKeys(DeviceIntPtr pXDev,int key,int onoff)
+{
+ if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
+ xkbControlsNotify cn;
+ XkbControlsPtr ctrls = pXDev->key->xkbInfo->desc->ctrls;
+ XkbControlsRec old;
+ old = *ctrls;
+
+ if (key== -1) { /* global autorepeat setting changed */
+ if (onoff) ctrls->enabled_ctrls |= XkbRepeatKeysMask;
+ else ctrls->enabled_ctrls &= ~XkbRepeatKeysMask;
+ }
+ else if (pXDev->kbdfeed) {
+ ctrls->per_key_repeat[key/8] =
+ pXDev->kbdfeed->ctrl.autoRepeats[key/8];
+ }
+
+ if (XkbComputeControlsNotify(pXDev,&old,ctrls,&cn,TRUE))
+ XkbSendControlsNotify(pXDev,&cn);
+ }
+ return;
+}
+
+/* Applies a change to a single device, does not traverse the device tree. */
+void
+XkbApplyMappingChange(DeviceIntPtr kbd, KeySymsPtr map, KeyCode first_key,
+ CARD8 num_keys, CARD8 *modmap, ClientPtr client)
+{
+ XkbDescPtr xkb = kbd->key->xkbInfo->desc;
+ XkbEventCauseRec cause;
+ XkbChangesRec changes;
+ unsigned int check;
+
+ memset(&changes, 0, sizeof(changes));
+ memset(&cause, 0, sizeof(cause));
+
+ if (map && first_key && num_keys) {
+ check = 0;
+ XkbSetCauseCoreReq(&cause, X_ChangeKeyboardMapping, client);
+
+ XkbUpdateKeyTypesFromCore(kbd, map, first_key, num_keys, &changes);
+ XkbUpdateActions(kbd, first_key, num_keys, &changes, &check, &cause);
+
+ if (check)
+ XkbCheckSecondaryEffects(kbd->key->xkbInfo, 1, &changes, &cause);
+ }
+
+ if (modmap) {
+ /* A keymap change can imply a modmap change, se we prefer the
+ * former. */
+ if (!cause.mjr)
+ XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client);
+
+ check = 0;
+ num_keys = xkb->max_key_code - xkb->min_key_code + 1;
+ changes.map.changed |= XkbModifierMapMask;
+ changes.map.first_modmap_key = xkb->min_key_code;
+ changes.map.num_modmap_keys = num_keys;
+ memcpy(kbd->key->xkbInfo->desc->map->modmap, modmap, MAP_LENGTH);
+ XkbUpdateActions(kbd, xkb->min_key_code, num_keys, &changes, &check,
+ &cause);
+
+ if (check)
+ XkbCheckSecondaryEffects(kbd->key->xkbInfo, 1, &changes, &cause);
+ }
+
+ XkbSendNotification(kbd, &changes, &cause);
+}
+
+void
+XkbDisableComputedAutoRepeats(DeviceIntPtr dev,unsigned key)
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+xkbMapNotify mn;
+
+ xkbi->desc->server->explicit[key]|= XkbExplicitAutoRepeatMask;
+ bzero(&mn,sizeof(mn));
+ mn.changed= XkbExplicitComponentsMask;
+ mn.firstKeyExplicit= key;
+ mn.nKeyExplicit= 1;
+ XkbSendMapNotify(dev,&mn);
+ return;
+}
+
+unsigned
+XkbStateChangedFlags(XkbStatePtr old,XkbStatePtr new)
+{
+int changed;
+
+ changed=(old->group!=new->group?XkbGroupStateMask:0);
+ changed|=(old->base_group!=new->base_group?XkbGroupBaseMask:0);
+ changed|=(old->latched_group!=new->latched_group?XkbGroupLatchMask:0);
+ changed|=(old->locked_group!=new->locked_group?XkbGroupLockMask:0);
+ changed|=(old->mods!=new->mods?XkbModifierStateMask:0);
+ changed|=(old->base_mods!=new->base_mods?XkbModifierBaseMask:0);
+ changed|=(old->latched_mods!=new->latched_mods?XkbModifierLatchMask:0);
+ changed|=(old->locked_mods!=new->locked_mods?XkbModifierLockMask:0);
+ changed|=(old->compat_state!=new->compat_state?XkbCompatStateMask:0);
+ changed|=(old->grab_mods!=new->grab_mods?XkbGrabModsMask:0);
+ if (old->compat_grab_mods!=new->compat_grab_mods)
+ changed|= XkbCompatGrabModsMask;
+ changed|=(old->lookup_mods!=new->lookup_mods?XkbLookupModsMask:0);
+ if (old->compat_lookup_mods!=new->compat_lookup_mods)
+ changed|= XkbCompatLookupModsMask;
+ changed|=(old->ptr_buttons!=new->ptr_buttons?XkbPointerButtonMask:0);
+ return changed;
+}
+
+static void
+XkbComputeCompatState(XkbSrvInfoPtr xkbi)
+{
+CARD16 grp_mask;
+XkbStatePtr state= &xkbi->state;
+XkbCompatMapPtr map;
+
+ if (!state || !xkbi->desc || !xkbi->desc->ctrls || !xkbi->desc->compat)
+ return;
+
+ map= xkbi->desc->compat;
+ grp_mask= map->groups[state->group].mask;
+ state->compat_state = state->mods|grp_mask;
+ state->compat_lookup_mods= state->lookup_mods|grp_mask;
+
+ if (xkbi->desc->ctrls->enabled_ctrls&XkbIgnoreGroupLockMask)
+ grp_mask= map->groups[state->base_group].mask;
+ state->compat_grab_mods= state->grab_mods|grp_mask;
+ return;
+}
+
+unsigned
+XkbAdjustGroup(int group,XkbControlsPtr ctrls)
+{
+unsigned act;
+
+ act= XkbOutOfRangeGroupAction(ctrls->groups_wrap);
+ if (group<0) {
+ while ( group < 0 ) {
+ if (act==XkbClampIntoRange) {
+ group= XkbGroup1Index;
+ }
+ else if (act==XkbRedirectIntoRange) {
+ int newGroup;
+ newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
+ if (newGroup>=ctrls->num_groups)
+ group= XkbGroup1Index;
+ else group= newGroup;
+ }
+ else {
+ group+= ctrls->num_groups;
+ }
+ }
+ }
+ else if (group>=ctrls->num_groups) {
+ if (act==XkbClampIntoRange) {
+ group= ctrls->num_groups-1;
+ }
+ else if (act==XkbRedirectIntoRange) {
+ int newGroup;
+ newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
+ if (newGroup>=ctrls->num_groups)
+ group= XkbGroup1Index;
+ else group= newGroup;
+ }
+ else {
+ group%= ctrls->num_groups;
+ }
+ }
+ return group;
+}
+
+void
+XkbComputeDerivedState(XkbSrvInfoPtr xkbi)
+{
+XkbStatePtr state= &xkbi->state;
+XkbControlsPtr ctrls= xkbi->desc->ctrls;
+unsigned char grp;
+
+ if (!state || !ctrls)
+ return;
+
+ state->mods= (state->base_mods|state->latched_mods|state->locked_mods);
+ state->lookup_mods= state->mods&(~ctrls->internal.mask);
+ state->grab_mods= state->lookup_mods&(~ctrls->ignore_lock.mask);
+ state->grab_mods|=
+ ((state->base_mods|state->latched_mods)&ctrls->ignore_lock.mask);
+
+
+ grp= state->locked_group;
+ if (grp>=ctrls->num_groups)
+ state->locked_group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
+
+ grp= state->locked_group+state->base_group+state->latched_group;
+ if (grp>=ctrls->num_groups)
+ state->group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
+ else state->group= grp;
+ XkbComputeCompatState(xkbi);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbCheckSecondaryEffects( XkbSrvInfoPtr xkbi,
+ unsigned which,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+ if (which&XkbStateNotifyMask) {
+ XkbStateRec old;
+ old= xkbi->state;
+ changes->state_changes|= XkbStateChangedFlags(&old,&xkbi->state);
+ XkbComputeDerivedState(xkbi);
+ }
+ if (which&XkbIndicatorStateNotifyMask)
+ XkbUpdateIndicators(xkbi->device,XkbAllIndicatorsMask,TRUE,changes,
+ cause);
+ return;
+}
+
+/***====================================================================***/
+
+Bool
+XkbEnableDisableControls( XkbSrvInfoPtr xkbi,
+ unsigned long change,
+ unsigned long newValues,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+XkbControlsPtr ctrls;
+unsigned old;
+XkbSrvLedInfoPtr sli;
+
+ ctrls= xkbi->desc->ctrls;
+ old= ctrls->enabled_ctrls;
+ ctrls->enabled_ctrls&= ~change;
+ ctrls->enabled_ctrls|= (change&newValues);
+ if (old==ctrls->enabled_ctrls)
+ return FALSE;
+ if (cause!=NULL) {
+ xkbControlsNotify cn;
+ cn.numGroups= ctrls->num_groups;
+ cn.changedControls= XkbControlsEnabledMask;
+ cn.enabledControls= ctrls->enabled_ctrls;
+ cn.enabledControlChanges= (ctrls->enabled_ctrls^old);
+ cn.keycode= cause->kc;
+ cn.eventType= cause->event;
+ cn.requestMajor= cause->mjr;
+ cn.requestMinor= cause->mnr;
+ XkbSendControlsNotify(xkbi->device,&cn);
+ }
+ else {
+ /* Yes, this really should be an XOR. If ctrls->enabled_ctrls_changes*/
+ /* is non-zero, the controls in question changed already in "this" */
+ /* request and this change merely undoes the previous one. By the */
+ /* same token, we have to figure out whether or not ControlsEnabled */
+ /* should be set or not in the changes structure */
+ changes->ctrls.enabled_ctrls_changes^= (ctrls->enabled_ctrls^old);
+ if (changes->ctrls.enabled_ctrls_changes)
+ changes->ctrls.changed_ctrls|= XkbControlsEnabledMask;
+ else changes->ctrls.changed_ctrls&= ~XkbControlsEnabledMask;
+ }
+ sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(xkbi->device,sli->usesControls,TRUE,changes,cause);
+ return TRUE;
+}
+
+/***====================================================================***/
+
+#define MAX_TOC 16
+
+XkbGeometryPtr
+XkbLookupNamedGeometry(DeviceIntPtr dev,Atom name,Bool *shouldFree)
+{
+XkbSrvInfoPtr xkbi= dev->key->xkbInfo;
+XkbDescPtr xkb= xkbi->desc;
+
+ *shouldFree= 0;
+ if (name==None) {
+ if (xkb->geom!=NULL)
+ return xkb->geom;
+ name= xkb->names->geometry;
+ }
+ if ((xkb->geom!=NULL)&&(xkb->geom->name==name))
+ return xkb->geom;
+ *shouldFree= 1;
+ return NULL;
+}
+
+void
+XkbConvertCase(register KeySym sym, KeySym *lower, KeySym *upper)
+{
+ *lower = sym;
+ *upper = sym;
+ switch(sym >> 8) {
+ case 0: /* Latin 1 */
+ if ((sym >= XK_A) && (sym <= XK_Z))
+ *lower += (XK_a - XK_A);
+ else if ((sym >= XK_a) && (sym <= XK_z))
+ *upper -= (XK_a - XK_A);
+ else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
+ *lower += (XK_agrave - XK_Agrave);
+ else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
+ *upper -= (XK_agrave - XK_Agrave);
+ else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
+ *lower += (XK_oslash - XK_Ooblique);
+ else if ((sym >= XK_oslash) && (sym <= XK_thorn))
+ *upper -= (XK_oslash - XK_Ooblique);
+ break;
+ case 1: /* Latin 2 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym == XK_Aogonek)
+ *lower = XK_aogonek;
+ else if (sym >= XK_Lstroke && sym <= XK_Sacute)
+ *lower += (XK_lstroke - XK_Lstroke);
+ else if (sym >= XK_Scaron && sym <= XK_Zacute)
+ *lower += (XK_scaron - XK_Scaron);
+ else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
+ *lower += (XK_zcaron - XK_Zcaron);
+ else if (sym == XK_aogonek)
+ *upper = XK_Aogonek;
+ else if (sym >= XK_lstroke && sym <= XK_sacute)
+ *upper -= (XK_lstroke - XK_Lstroke);
+ else if (sym >= XK_scaron && sym <= XK_zacute)
+ *upper -= (XK_scaron - XK_Scaron);
+ else if (sym >= XK_zcaron && sym <= XK_zabovedot)
+ *upper -= (XK_zcaron - XK_Zcaron);
+ else if (sym >= XK_Racute && sym <= XK_Tcedilla)
+ *lower += (XK_racute - XK_Racute);
+ else if (sym >= XK_racute && sym <= XK_tcedilla)
+ *upper -= (XK_racute - XK_Racute);
+ break;
+ case 2: /* Latin 3 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
+ *lower += (XK_hstroke - XK_Hstroke);
+ else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
+ *lower += (XK_gbreve - XK_Gbreve);
+ else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
+ *upper -= (XK_hstroke - XK_Hstroke);
+ else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
+ *upper -= (XK_gbreve - XK_Gbreve);
+ else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
+ *lower += (XK_cabovedot - XK_Cabovedot);
+ else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
+ *upper -= (XK_cabovedot - XK_Cabovedot);
+ break;
+ case 3: /* Latin 4 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Rcedilla && sym <= XK_Tslash)
+ *lower += (XK_rcedilla - XK_Rcedilla);
+ else if (sym >= XK_rcedilla && sym <= XK_tslash)
+ *upper -= (XK_rcedilla - XK_Rcedilla);
+ else if (sym == XK_ENG)
+ *lower = XK_eng;
+ else if (sym == XK_eng)
+ *upper = XK_ENG;
+ else if (sym >= XK_Amacron && sym <= XK_Umacron)
+ *lower += (XK_amacron - XK_Amacron);
+ else if (sym >= XK_amacron && sym <= XK_umacron)
+ *upper -= (XK_amacron - XK_Amacron);
+ break;
+ case 6: /* Cyrillic */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
+ *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
+ else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
+ *upper += (XK_Serbian_DJE - XK_Serbian_dje);
+ else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
+ *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
+ else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
+ *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
+ break;
+ case 7: /* Greek */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
+ *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+ else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
+ sym != XK_Greek_iotaaccentdieresis &&
+ sym != XK_Greek_upsilonaccentdieresis)
+ *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+ else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
+ *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
+ else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
+ sym != XK_Greek_finalsmallsigma)
+ *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
+ break;
+ }
+}
+
+static Bool
+_XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+ int i;
+ XkbKeyTypePtr stype = NULL, dtype = NULL;
+
+ /* client map */
+ if (src->map) {
+ if (!dst->map) {
+ tmp = calloc(1, sizeof(XkbClientMapRec));
+ if (!tmp)
+ return FALSE;
+ dst->map = tmp;
+ }
+
+ if (src->map->syms) {
+ if (src->map->size_syms != dst->map->size_syms) {
+ if (dst->map->syms)
+ tmp = realloc(dst->map->syms,
+ src->map->size_syms * sizeof(KeySym));
+ else
+ tmp = malloc(src->map->size_syms * sizeof(KeySym));
+ if (!tmp)
+ return FALSE;
+ dst->map->syms = tmp;
+
+ }
+ memcpy(dst->map->syms, src->map->syms,
+ src->map->size_syms * sizeof(KeySym));
+ }
+ else {
+ if (dst->map->syms) {
+ free(dst->map->syms);
+ dst->map->syms = NULL;
+ }
+ }
+ dst->map->num_syms = src->map->num_syms;
+ dst->map->size_syms = src->map->size_syms;
+
+ if (src->map->key_sym_map) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->map->key_sym_map)
+ tmp = realloc(dst->map->key_sym_map,
+ (src->max_key_code + 1) *
+ sizeof(XkbSymMapRec));
+ else
+ tmp = malloc((src->max_key_code + 1) *
+ sizeof(XkbSymMapRec));
+ if (!tmp)
+ return FALSE;
+ dst->map->key_sym_map = tmp;
+ }
+ memcpy(dst->map->key_sym_map, src->map->key_sym_map,
+ (src->max_key_code + 1) * sizeof(XkbSymMapRec));
+ }
+ else {
+ if (dst->map->key_sym_map) {
+ free(dst->map->key_sym_map);
+ dst->map->key_sym_map = NULL;
+ }
+ }
+
+ if (src->map->types && src->map->num_types) {
+ if (src->map->num_types > dst->map->size_types ||
+ !dst->map->types || !dst->map->size_types) {
+ if (dst->map->types && dst->map->size_types) {
+ tmp = realloc(dst->map->types,
+ src->map->num_types * sizeof(XkbKeyTypeRec));
+ if (!tmp)
+ return FALSE;
+ dst->map->types = tmp;
+ bzero(dst->map->types + dst->map->num_types,
+ (src->map->num_types - dst->map->num_types) *
+ sizeof(XkbKeyTypeRec));
+ }
+ else {
+ tmp = calloc(src->map->num_types, sizeof(XkbKeyTypeRec));
+ if (!tmp)
+ return FALSE;
+ dst->map->types = tmp;
+ }
+ }
+ else if (src->map->num_types < dst->map->num_types &&
+ dst->map->types) {
+ for (i = src->map->num_types, dtype = (dst->map->types + i);
+ i < dst->map->num_types; i++, dtype++) {
+ if (dtype->level_names)
+ free(dtype->level_names);
+ dtype->level_names = NULL;
+ dtype->num_levels = 0;
+ if (dtype->map_count) {
+ if (dtype->map)
+ free(dtype->map);
+ if (dtype->preserve)
+ free(dtype->preserve);
+ }
+ }
+ }
+
+ stype = src->map->types;
+ dtype = dst->map->types;
+ for (i = 0; i < src->map->num_types; i++, dtype++, stype++) {
+ if (stype->num_levels && stype->level_names) {
+ if (stype->num_levels != dtype->num_levels &&
+ dtype->num_levels && dtype->level_names &&
+ i < dst->map->num_types) {
+ tmp = realloc(dtype->level_names,
+ stype->num_levels * sizeof(Atom));
+ if (!tmp)
+ continue;
+ dtype->level_names = tmp;
+ }
+ else if (!dtype->num_levels || !dtype->level_names ||
+ i >= dst->map->num_types) {
+ tmp = malloc(stype->num_levels * sizeof(Atom));
+ if (!tmp)
+ continue;
+ dtype->level_names = tmp;
+ }
+ dtype->num_levels = stype->num_levels;
+ memcpy(dtype->level_names, stype->level_names,
+ stype->num_levels * sizeof(Atom));
+ }
+ else {
+ if (dtype->num_levels && dtype->level_names &&
+ i < dst->map->num_types)
+ free(dtype->level_names);
+ dtype->num_levels = 0;
+ dtype->level_names = NULL;
+ }
+
+ dtype->name = stype->name;
+ memcpy(&dtype->mods, &stype->mods, sizeof(XkbModsRec));
+
+ if (stype->map_count) {
+ if (stype->map) {
+ if (stype->map_count != dtype->map_count &&
+ dtype->map_count && dtype->map &&
+ i < dst->map->num_types) {
+ tmp = realloc(dtype->map,
+ stype->map_count *
+ sizeof(XkbKTMapEntryRec));
+ if (!tmp)
+ return FALSE;
+ dtype->map = tmp;
+ }
+ else if (!dtype->map_count || !dtype->map ||
+ i >= dst->map->num_types) {
+ tmp = malloc(stype->map_count *
+ sizeof(XkbKTMapEntryRec));
+ if (!tmp)
+ return FALSE;
+ dtype->map = tmp;
+ }
+
+ memcpy(dtype->map, stype->map,
+ stype->map_count * sizeof(XkbKTMapEntryRec));
+ }
+ else {
+ if (dtype->map && i < dst->map->num_types)
+ free(dtype->map);
+ dtype->map = NULL;
+ }
+
+ if (stype->preserve) {
+ if (stype->map_count != dtype->map_count &&
+ dtype->map_count && dtype->preserve &&
+ i < dst->map->num_types) {
+ tmp = realloc(dtype->preserve,
+ stype->map_count *
+ sizeof(XkbModsRec));
+ if (!tmp)
+ return FALSE;
+ dtype->preserve = tmp;
+ }
+ else if (!dtype->preserve || !dtype->map_count ||
+ i >= dst->map->num_types) {
+ tmp = malloc(stype->map_count *
+ sizeof(XkbModsRec));
+ if (!tmp)
+ return FALSE;
+ dtype->preserve = tmp;
+ }
+
+ memcpy(dtype->preserve, stype->preserve,
+ stype->map_count * sizeof(XkbModsRec));
+ }
+ else {
+ if (dtype->preserve && i < dst->map->num_types)
+ free(dtype->preserve);
+ dtype->preserve = NULL;
+ }
+
+ dtype->map_count = stype->map_count;
+ }
+ else {
+ if (dtype->map_count && i < dst->map->num_types) {
+ if (dtype->map)
+ free(dtype->map);
+ if (dtype->preserve)
+ free(dtype->preserve);
+ }
+ dtype->map_count = 0;
+ dtype->map = NULL;
+ dtype->preserve = NULL;
+ }
+ }
+
+ dst->map->size_types = src->map->num_types;
+ dst->map->num_types = src->map->num_types;
+ }
+ else {
+ if (dst->map->types) {
+ for (i = 0, dtype = dst->map->types; i < dst->map->num_types;
+ i++, dtype++) {
+ if (dtype->level_names)
+ free(dtype->level_names);
+ if (dtype->map && dtype->map_count)
+ free(dtype->map);
+ if (dtype->preserve && dtype->map_count)
+ free(dtype->preserve);
+ }
+ free(dst->map->types);
+ dst->map->types = NULL;
+ }
+ dst->map->num_types = 0;
+ dst->map->size_types = 0;
+ }
+
+ if (src->map->modmap) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->map->modmap)
+ tmp = realloc(dst->map->modmap, src->max_key_code + 1);
+ else
+ tmp = malloc(src->max_key_code + 1);
+ if (!tmp)
+ return FALSE;
+ dst->map->modmap = tmp;
+ }
+ memcpy(dst->map->modmap, src->map->modmap, src->max_key_code + 1);
+ }
+ else {
+ if (dst->map->modmap) {
+ free(dst->map->modmap);
+ dst->map->modmap = NULL;
+ }
+ }
+ }
+ else {
+ if (dst->map)
+ XkbFreeClientMap(dst, XkbAllClientInfoMask, TRUE);
+ }
+
+ return TRUE;
+}
+
+static Bool
+_XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+
+ /* server map */
+ if (src->server) {
+ if (!dst->server) {
+ tmp = calloc(1, sizeof(XkbServerMapRec));
+ if (!tmp)
+ return FALSE;
+ dst->server = tmp;
+ }
+
+ if (src->server->explicit) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->server->explicit)
+ tmp = realloc(dst->server->explicit, src->max_key_code + 1);
+ else
+ tmp = malloc(src->max_key_code + 1);
+ if (!tmp)
+ return FALSE;
+ dst->server->explicit = tmp;
+ }
+ memcpy(dst->server->explicit, src->server->explicit,
+ src->max_key_code + 1);
+ }
+ else {
+ if (dst->server->explicit) {
+ free(dst->server->explicit);
+ dst->server->explicit = NULL;
+ }
+ }
+
+ if (src->server->acts) {
+ if (src->server->size_acts != dst->server->size_acts) {
+ if (dst->server->acts)
+ tmp = realloc(dst->server->acts,
+ src->server->size_acts * sizeof(XkbAction));
+ else
+ tmp = malloc(src->server->size_acts * sizeof(XkbAction));
+ if (!tmp)
+ return FALSE;
+ dst->server->acts = tmp;
+ }
+ memcpy(dst->server->acts, src->server->acts,
+ src->server->size_acts * sizeof(XkbAction));
+ }
+ else {
+ if (dst->server->acts) {
+ free(dst->server->acts);
+ dst->server->acts = NULL;
+ }
+ }
+ dst->server->size_acts = src->server->size_acts;
+ dst->server->num_acts = src->server->num_acts;
+
+ if (src->server->key_acts) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->server->key_acts)
+ tmp = realloc(dst->server->key_acts,
+ (src->max_key_code + 1) *
+ sizeof(unsigned short));
+ else
+ tmp = malloc((src->max_key_code + 1) *
+ sizeof(unsigned short));
+ if (!tmp)
+ return FALSE;
+ dst->server->key_acts = tmp;
+ }
+ memcpy(dst->server->key_acts, src->server->key_acts,
+ (src->max_key_code + 1) * sizeof(unsigned short));
+ }
+ else {
+ if (dst->server->key_acts) {
+ free(dst->server->key_acts);
+ dst->server->key_acts = NULL;
+ }
+ }
+
+ if (src->server->behaviors) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->server->behaviors)
+ tmp = realloc(dst->server->behaviors,
+ (src->max_key_code + 1) *
+ sizeof(XkbBehavior));
+ else
+ tmp = malloc((src->max_key_code + 1) *
+ sizeof(XkbBehavior));
+ if (!tmp)
+ return FALSE;
+ dst->server->behaviors = tmp;
+ }
+ memcpy(dst->server->behaviors, src->server->behaviors,
+ (src->max_key_code + 1) * sizeof(XkbBehavior));
+ }
+ else {
+ if (dst->server->behaviors) {
+ free(dst->server->behaviors);
+ dst->server->behaviors = NULL;
+ }
+ }
+
+ memcpy(dst->server->vmods, src->server->vmods, XkbNumVirtualMods);
+
+ if (src->server->vmodmap) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->server->vmodmap)
+ tmp = realloc(dst->server->vmodmap,
+ (src->max_key_code + 1) *
+ sizeof(unsigned short));
+ else
+ tmp = malloc((src->max_key_code + 1) *
+ sizeof(unsigned short));
+ if (!tmp)
+ return FALSE;
+ dst->server->vmodmap = tmp;
+ }
+ memcpy(dst->server->vmodmap, src->server->vmodmap,
+ (src->max_key_code + 1) * sizeof(unsigned short));
+ }
+ else {
+ if (dst->server->vmodmap) {
+ free(dst->server->vmodmap);
+ dst->server->vmodmap = NULL;
+ }
+ }
+ }
+ else {
+ if (dst->server)
+ XkbFreeServerMap(dst, XkbAllServerInfoMask, TRUE);
+ }
+
+ return TRUE;
+}
+
+static Bool
+_XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+
+ /* names */
+ if (src->names) {
+ if (!dst->names) {
+ dst->names = calloc(1, sizeof(XkbNamesRec));
+ if (!dst->names)
+ return FALSE;
+ }
+
+ if (src->names->keys) {
+ if (src->max_key_code != dst->max_key_code) {
+ if (dst->names->keys)
+ tmp = realloc(dst->names->keys, (src->max_key_code + 1) *
+ sizeof(XkbKeyNameRec));
+ else
+ tmp = malloc((src->max_key_code + 1) *
+ sizeof(XkbKeyNameRec));
+ if (!tmp)
+ return FALSE;
+ dst->names->keys = tmp;
+ }
+ memcpy(dst->names->keys, src->names->keys,
+ (src->max_key_code + 1) * sizeof(XkbKeyNameRec));
+ }
+ else {
+ if (dst->names->keys) {
+ free(dst->names->keys);
+ dst->names->keys = NULL;
+ }
+ }
+
+ if (src->names->num_key_aliases) {
+ if (src->names->num_key_aliases != dst->names->num_key_aliases) {
+ if (dst->names->key_aliases)
+ tmp = realloc(dst->names->key_aliases,
+ src->names->num_key_aliases *
+ sizeof(XkbKeyAliasRec));
+ else
+ tmp = malloc(src->names->num_key_aliases *
+ sizeof(XkbKeyAliasRec));
+ if (!tmp)
+ return FALSE;
+ dst->names->key_aliases = tmp;
+ }
+ memcpy(dst->names->key_aliases, src->names->key_aliases,
+ src->names->num_key_aliases * sizeof(XkbKeyAliasRec));
+ }
+ else {
+ if (dst->names->key_aliases) {
+ free(dst->names->key_aliases);
+ dst->names->key_aliases = NULL;
+ }
+ }
+ dst->names->num_key_aliases = src->names->num_key_aliases;
+
+ if (src->names->num_rg) {
+ if (src->names->num_rg != dst->names->num_rg) {
+ if (dst->names->radio_groups)
+ tmp = realloc(dst->names->radio_groups,
+ src->names->num_rg * sizeof(Atom));
+ else
+ tmp = malloc(src->names->num_rg * sizeof(Atom));
+ if (!tmp)
+ return FALSE;
+ dst->names->radio_groups = tmp;
+ }
+ memcpy(dst->names->radio_groups, src->names->radio_groups,
+ src->names->num_rg * sizeof(Atom));
+ }
+ else {
+ if (dst->names->radio_groups)
+ free(dst->names->radio_groups);
+ }
+ dst->names->num_rg = src->names->num_rg;
+
+ dst->names->keycodes = src->names->keycodes;
+ dst->names->geometry = src->names->geometry;
+ dst->names->symbols = src->names->symbols;
+ dst->names->types = src->names->types;
+ dst->names->compat = src->names->compat;
+ dst->names->phys_symbols = src->names->phys_symbols;
+
+ memcpy(dst->names->vmods, src->names->vmods,
+ XkbNumVirtualMods * sizeof(Atom));
+ memcpy(dst->names->indicators, src->names->indicators,
+ XkbNumIndicators * sizeof(Atom));
+ memcpy(dst->names->groups, src->names->groups,
+ XkbNumKbdGroups * sizeof(Atom));
+ }
+ else {
+ if (dst->names)
+ XkbFreeNames(dst, XkbAllNamesMask, TRUE);
+ }
+
+ return TRUE;
+}
+
+static Bool
+_XkbCopyCompat(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+
+ /* compat */
+ if (src->compat) {
+ if (!dst->compat) {
+ dst->compat = calloc(1, sizeof(XkbCompatMapRec));
+ if (!dst->compat)
+ return FALSE;
+ }
+
+ if (src->compat->sym_interpret && src->compat->num_si) {
+ if (src->compat->num_si != dst->compat->size_si) {
+ if (dst->compat->sym_interpret)
+ tmp = realloc(dst->compat->sym_interpret,
+ src->compat->num_si *
+ sizeof(XkbSymInterpretRec));
+ else
+ tmp = malloc(src->compat->num_si *
+ sizeof(XkbSymInterpretRec));
+ if (!tmp)
+ return FALSE;
+ dst->compat->sym_interpret = tmp;
+ }
+ memcpy(dst->compat->sym_interpret, src->compat->sym_interpret,
+ src->compat->num_si * sizeof(XkbSymInterpretRec));
+
+ dst->compat->num_si = src->compat->num_si;
+ dst->compat->size_si = src->compat->num_si;
+ }
+ else {
+ if (dst->compat->sym_interpret && dst->compat->size_si)
+ free(dst->compat->sym_interpret);
+
+ dst->compat->sym_interpret = NULL;
+ dst->compat->num_si = 0;
+ dst->compat->size_si = 0;
+ }
+
+ memcpy(dst->compat->groups, src->compat->groups,
+ XkbNumKbdGroups * sizeof(XkbModsRec));
+ }
+ else {
+ if (dst->compat)
+ XkbFreeCompatMap(dst, XkbAllCompatMask, TRUE);
+ }
+
+ return TRUE;
+}
+
+static Bool
+_XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+ int i = 0, j = 0, k = 0;
+ XkbColorPtr scolor = NULL, dcolor = NULL;
+ XkbDoodadPtr sdoodad = NULL, ddoodad = NULL;
+ XkbOutlinePtr soutline = NULL, doutline = NULL;
+ XkbPropertyPtr sprop = NULL, dprop = NULL;
+ XkbRowPtr srow = NULL, drow = NULL;
+ XkbSectionPtr ssection = NULL, dsection = NULL;
+ XkbShapePtr sshape = NULL, dshape = NULL;
+
+ /* geometry */
+ if (src->geom) {
+ if (!dst->geom) {
+ dst->geom = calloc(sizeof(XkbGeometryRec), 1);
+ if (!dst->geom)
+ return FALSE;
+ }
+
+ /* properties */
+ if (src->geom->num_properties) {
+ if (src->geom->num_properties != dst->geom->sz_properties) {
+ /* If we've got more properties in the destination than
+ * the source, run through and free all the excess ones
+ * first. */
+ if (src->geom->num_properties < dst->geom->sz_properties) {
+ for (i = src->geom->num_properties,
+ dprop = dst->geom->properties + i;
+ i < dst->geom->num_properties;
+ i++, dprop++) {
+ free(dprop->name);
+ free(dprop->value);
+ }
+ }
+
+ if (dst->geom->sz_properties)
+ tmp = realloc(dst->geom->properties,
+ src->geom->num_properties *
+ sizeof(XkbPropertyRec));
+ else
+ tmp = malloc(src->geom->num_properties *
+ sizeof(XkbPropertyRec));
+ if (!tmp)
+ return FALSE;
+ dst->geom->properties = tmp;
+ }
+
+ /* We don't set num_properties as we need it to try and avoid
+ * too much reallocing. */
+ dst->geom->sz_properties = src->geom->num_properties;
+
+ if (dst->geom->sz_properties > dst->geom->num_properties) {
+ bzero(dst->geom->properties + dst->geom->num_properties,
+ (dst->geom->sz_properties - dst->geom->num_properties) *
+ sizeof(XkbPropertyRec));
+ }
+
+ for (i = 0,
+ sprop = src->geom->properties,
+ dprop = dst->geom->properties;
+ i < src->geom->num_properties;
+ i++, sprop++, dprop++) {
+ if (i < dst->geom->num_properties) {
+ if (strlen(sprop->name) != strlen(dprop->name)) {
+ tmp = realloc(dprop->name, strlen(sprop->name) + 1);
+ if (!tmp)
+ return FALSE;
+ dprop->name = tmp;
+ }
+ if (strlen(sprop->value) != strlen(dprop->value)) {
+ tmp = realloc(dprop->value, strlen(sprop->value) + 1);
+ if (!tmp)
+ return FALSE;
+ dprop->value = tmp;
+ }
+ strcpy(dprop->name, sprop->name);
+ strcpy(dprop->value, sprop->value);
+ }
+ else {
+ dprop->name = xstrdup(sprop->name);
+ dprop->value = xstrdup(sprop->value);
+ }
+ }
+
+ /* ... which is already src->geom->num_properties. */
+ dst->geom->num_properties = dst->geom->sz_properties;
+ }
+ else {
+ if (dst->geom->sz_properties) {
+ for (i = 0, dprop = dst->geom->properties;
+ i < dst->geom->num_properties;
+ i++, dprop++) {
+ free(dprop->name);
+ free(dprop->value);
+ }
+ free(dst->geom->properties);
+ dst->geom->properties = NULL;
+ }
+
+ dst->geom->num_properties = 0;
+ dst->geom->sz_properties = 0;
+ }
+
+ /* colors */
+ if (src->geom->num_colors) {
+ if (src->geom->num_colors != dst->geom->sz_colors) {
+ if (src->geom->num_colors < dst->geom->sz_colors) {
+ for (i = src->geom->num_colors,
+ dcolor = dst->geom->colors + i;
+ i < dst->geom->num_colors;
+ i++, dcolor++) {
+ free(dcolor->spec);
+ }
+ }
+
+ if (dst->geom->sz_colors)
+ tmp = realloc(dst->geom->colors,
+ src->geom->num_colors *
+ sizeof(XkbColorRec));
+ else
+ tmp = malloc(src->geom->num_colors *
+ sizeof(XkbColorRec));
+ if (!tmp)
+ return FALSE;
+ dst->geom->colors = tmp;
+ }
+
+ dst->geom->sz_colors = src->geom->num_colors;
+
+ if (dst->geom->sz_colors > dst->geom->num_colors) {
+ bzero(dst->geom->colors + dst->geom->num_colors,
+ (dst->geom->sz_colors - dst->geom->num_colors) *
+ sizeof(XkbColorRec));
+ }
+
+ for (i = 0,
+ scolor = src->geom->colors,
+ dcolor = dst->geom->colors;
+ i < src->geom->num_colors;
+ i++, scolor++, dcolor++) {
+ if (i < dst->geom->num_colors) {
+ if (strlen(scolor->spec) != strlen(dcolor->spec)) {
+ tmp = realloc(dcolor->spec, strlen(scolor->spec) + 1);
+ if (!tmp)
+ return FALSE;
+ dcolor->spec = tmp;
+ }
+ strcpy(dcolor->spec, scolor->spec);
+ }
+ else {
+ dcolor->spec = xstrdup(scolor->spec);
+ }
+ dcolor->pixel = scolor->pixel;
+ }
+
+ dst->geom->num_colors = dst->geom->sz_colors;
+ }
+ else {
+ if (dst->geom->sz_colors) {
+ for (i = 0, dcolor = dst->geom->colors;
+ i < dst->geom->num_colors;
+ i++, dcolor++) {
+ free(dcolor->spec);
+ }
+ free(dst->geom->colors);
+ dst->geom->colors = NULL;
+ }
+
+ dst->geom->num_colors = 0;
+ dst->geom->sz_colors = 0;
+ }
+
+ /* shapes */
+ /* shapes break down into outlines, which break down into points. */
+ if (dst->geom->num_shapes) {
+ for (i = 0, dshape = dst->geom->shapes;
+ i < dst->geom->num_shapes;
+ i++, dshape++) {
+ for (j = 0, doutline = dshape->outlines;
+ j < dshape->num_outlines;
+ j++, doutline++) {
+ if (doutline->sz_points)
+ free(doutline->points);
+ }
+
+ if (dshape->sz_outlines) {
+ free(dshape->outlines);
+ dshape->outlines = NULL;
+ }
+
+ dshape->num_outlines = 0;
+ dshape->sz_outlines = 0;
+ }
+ }
+
+ if (src->geom->num_shapes) {
+ tmp = calloc(src->geom->num_shapes, sizeof(XkbShapeRec));
+ if (!tmp)
+ return FALSE;
+ dst->geom->shapes = tmp;
+
+ for (i = 0, sshape = src->geom->shapes, dshape = dst->geom->shapes;
+ i < src->geom->num_shapes;
+ i++, sshape++, dshape++) {
+ if (sshape->num_outlines) {
+ tmp = calloc(sshape->num_outlines, sizeof(XkbOutlineRec));
+ if (!tmp)
+ return FALSE;
+ dshape->outlines = tmp;
+
+ for (j = 0,
+ soutline = sshape->outlines,
+ doutline = dshape->outlines;
+ j < sshape->num_outlines;
+ j++, soutline++, doutline++) {
+ if (soutline->num_points) {
+ tmp = malloc(soutline->num_points *
+ sizeof(XkbPointRec));
+ if (!tmp)
+ return FALSE;
+ doutline->points = tmp;
+
+ memcpy(doutline->points, soutline->points,
+ soutline->num_points * sizeof(XkbPointRec));
+
+ doutline->corner_radius = soutline->corner_radius;
+ }
+
+ doutline->num_points = soutline->num_points;
+ doutline->sz_points = soutline->num_points;
+ }
+ }
+
+ dshape->num_outlines = sshape->num_outlines;
+ dshape->sz_outlines = sshape->num_outlines;
+ dshape->name = sshape->name;
+ dshape->bounds = sshape->bounds;
+
+ dshape->approx = NULL;
+ if (sshape->approx && sshape->num_outlines > 0) {
+
+ const ptrdiff_t approx_idx =
+ sshape->approx - sshape->outlines;
+
+ if (approx_idx < dshape->num_outlines) {
+ dshape->approx = dshape->outlines + approx_idx;
+ } else {
+ LogMessage(X_WARNING, "XKB: approx outline "
+ "index is out of range\n");
+ }
+ }
+
+ dshape->primary = NULL;
+ if (sshape->primary && sshape->num_outlines > 0) {
+
+ const ptrdiff_t primary_idx =
+ sshape->primary - sshape->outlines;
+
+ if (primary_idx < dshape->num_outlines) {
+ dshape->primary = dshape->outlines + primary_idx;
+ } else {
+ LogMessage(X_WARNING, "XKB: primary outline "
+ "index is out of range\n");
+ }
+ }
+ }
+
+ dst->geom->num_shapes = src->geom->num_shapes;
+ dst->geom->sz_shapes = src->geom->num_shapes;
+ }
+ else {
+ if (dst->geom->sz_shapes) {
+ free(dst->geom->shapes);
+ }
+ dst->geom->shapes = NULL;
+ dst->geom->num_shapes = 0;
+ dst->geom->sz_shapes = 0;
+ }
+
+ /* sections */
+ /* sections break down into doodads, and also into rows, which break
+ * down into keys. */
+ if (dst->geom->num_sections) {
+ for (i = 0, dsection = dst->geom->sections;
+ i < dst->geom->num_sections;
+ i++, dsection++) {
+ for (j = 0, drow = dsection->rows;
+ j < dsection->num_rows;
+ j++, drow++) {
+ if (drow->num_keys)
+ free(drow->keys);
+ }
+
+ if (dsection->num_rows)
+ free(dsection->rows);
+
+ /* cut and waste from geom/doodad below. */
+ for (j = 0, ddoodad = dsection->doodads;
+ j < dsection->num_doodads;
+ j++, ddoodad++) {
+ if (ddoodad->any.type == XkbTextDoodad) {
+ if (ddoodad->text.text) {
+ free(ddoodad->text.text);
+ ddoodad->text.text = NULL;
+ }
+ if (ddoodad->text.font) {
+ free(ddoodad->text.font);
+ ddoodad->text.font = NULL;
+ }
+ }
+ else if (ddoodad->any.type == XkbLogoDoodad) {
+ if (ddoodad->logo.logo_name) {
+ free(ddoodad->logo.logo_name);
+ ddoodad->logo.logo_name = NULL;
+ }
+ }
+ }
+
+ if (dsection->num_doodads)
+ free(dsection->doodads);
+ }
+
+ dst->geom->num_sections = 0;
+ dst->geom->sections = NULL;
+ }
+
+ if (src->geom->num_sections) {
+ if (dst->geom->sz_sections)
+ tmp = realloc(dst->geom->sections,
+ src->geom->num_sections *
+ sizeof(XkbSectionRec));
+ else
+ tmp = malloc(src->geom->num_sections * sizeof(XkbSectionRec));
+ if (!tmp)
+ return FALSE;
+ memset(tmp, 0, src->geom->num_sections * sizeof(XkbSectionRec));
+ dst->geom->sections = tmp;
+ dst->geom->num_sections = src->geom->num_sections;
+ dst->geom->sz_sections = src->geom->num_sections;
+
+ for (i = 0,
+ ssection = src->geom->sections,
+ dsection = dst->geom->sections;
+ i < src->geom->num_sections;
+ i++, ssection++, dsection++) {
+ *dsection = *ssection;
+ if (ssection->num_rows) {
+ tmp = calloc(ssection->num_rows, sizeof(XkbRowRec));
+ if (!tmp)
+ return FALSE;
+ dsection->rows = tmp;
+ }
+ dsection->num_rows = ssection->num_rows;
+ dsection->sz_rows = ssection->num_rows;
+
+ for (j = 0, srow = ssection->rows, drow = dsection->rows;
+ j < ssection->num_rows;
+ j++, srow++, drow++) {
+ if (srow->num_keys) {
+ tmp = malloc(srow->num_keys * sizeof(XkbKeyRec));
+ if (!tmp)
+ return FALSE;
+ drow->keys = tmp;
+ memcpy(drow->keys, srow->keys,
+ srow->num_keys * sizeof(XkbKeyRec));
+ }
+ drow->num_keys = srow->num_keys;
+ drow->sz_keys = srow->num_keys;
+ drow->top = srow->top;
+ drow->left = srow->left;
+ drow->vertical = srow->vertical;
+ drow->bounds = srow->bounds;
+ }
+
+ if (ssection->num_doodads) {
+ tmp = calloc(ssection->num_doodads, sizeof(XkbDoodadRec));
+ if (!tmp)
+ return FALSE;
+ dsection->doodads = tmp;
+ }
+ else {
+ dsection->doodads = NULL;
+ }
+
+ dsection->sz_doodads = ssection->num_doodads;
+ for (k = 0,
+ sdoodad = ssection->doodads,
+ ddoodad = dsection->doodads;
+ k < ssection->num_doodads;
+ k++, sdoodad++, ddoodad++) {
+ memcpy(ddoodad , sdoodad, sizeof(XkbDoodadRec));
+ if (sdoodad->any.type == XkbTextDoodad) {
+ if (sdoodad->text.text)
+ ddoodad->text.text =
+ xstrdup(sdoodad->text.text);
+ if (sdoodad->text.font)
+ ddoodad->text.font =
+ xstrdup(sdoodad->text.font);
+ }
+ else if (sdoodad->any.type == XkbLogoDoodad) {
+ if (sdoodad->logo.logo_name)
+ ddoodad->logo.logo_name =
+ xstrdup(sdoodad->logo.logo_name);
+ }
+ }
+ dsection->overlays = NULL;
+ dsection->sz_overlays = 0;
+ dsection->num_overlays = 0;
+ }
+ }
+ else {
+ if (dst->geom->sz_sections) {
+ free(dst->geom->sections);
+ }
+
+ dst->geom->sections = NULL;
+ dst->geom->num_sections = 0;
+ dst->geom->sz_sections = 0;
+ }
+
+ /* doodads */
+ if (dst->geom->num_doodads) {
+ for (i = src->geom->num_doodads,
+ ddoodad = dst->geom->doodads +
+ src->geom->num_doodads;
+ i < dst->geom->num_doodads;
+ i++, ddoodad++) {
+ if (ddoodad->any.type == XkbTextDoodad) {
+ if (ddoodad->text.text) {
+ free(ddoodad->text.text);
+ ddoodad->text.text = NULL;
+ }
+ if (ddoodad->text.font) {
+ free(ddoodad->text.font);
+ ddoodad->text.font = NULL;
+ }
+ }
+ else if (ddoodad->any.type == XkbLogoDoodad) {
+ if (ddoodad->logo.logo_name) {
+ free(ddoodad->logo.logo_name);
+ ddoodad->logo.logo_name = NULL;
+ }
+ }
+ }
+ dst->geom->num_doodads = 0;
+ dst->geom->doodads = NULL;
+ }
+
+ if (src->geom->num_doodads) {
+ if (dst->geom->sz_doodads)
+ tmp = realloc(dst->geom->doodads,
+ src->geom->num_doodads *
+ sizeof(XkbDoodadRec));
+ else
+ tmp = malloc(src->geom->num_doodads *
+ sizeof(XkbDoodadRec));
+ if (!tmp)
+ return FALSE;
+ memset(tmp, 0, src->geom->num_doodads * sizeof(XkbDoodadRec));
+ dst->geom->doodads = tmp;
+
+ dst->geom->sz_doodads = src->geom->num_doodads;
+
+ for (i = 0,
+ sdoodad = src->geom->doodads,
+ ddoodad = dst->geom->doodads;
+ i < src->geom->num_doodads;
+ i++, sdoodad++, ddoodad++) {
+ memcpy(ddoodad , sdoodad, sizeof(XkbDoodadRec));
+ if (sdoodad->any.type == XkbTextDoodad) {
+ if (sdoodad->text.text)
+ ddoodad->text.text = xstrdup(sdoodad->text.text);
+ if (sdoodad->text.font)
+ ddoodad->text.font = xstrdup(sdoodad->text.font);
+ }
+ else if (sdoodad->any.type == XkbLogoDoodad) {
+ if (sdoodad->logo.logo_name)
+ ddoodad->logo.logo_name =
+ xstrdup(sdoodad->logo.logo_name);
+ }
+ }
+
+ dst->geom->num_doodads = dst->geom->sz_doodads;
+ }
+ else {
+ if (dst->geom->sz_doodads) {
+ free(dst->geom->doodads);
+ }
+
+ dst->geom->doodads = NULL;
+ dst->geom->num_doodads = 0;
+ dst->geom->sz_doodads = 0;
+ }
+
+ /* key aliases */
+ if (src->geom->num_key_aliases) {
+ if (src->geom->num_key_aliases != dst->geom->sz_key_aliases) {
+ if (dst->geom->sz_key_aliases)
+ tmp = realloc(dst->geom->key_aliases,
+ src->geom->num_key_aliases *
+ 2 * XkbKeyNameLength);
+ else
+ tmp = malloc(src->geom->num_key_aliases *
+ 2 * XkbKeyNameLength);
+ if (!tmp)
+ return FALSE;
+ dst->geom->key_aliases = tmp;
+
+ dst->geom->sz_key_aliases = src->geom->num_key_aliases;
+ }
+
+ memcpy(dst->geom->key_aliases, src->geom->key_aliases,
+ src->geom->num_key_aliases * 2 * XkbKeyNameLength);
+
+ dst->geom->num_key_aliases = dst->geom->sz_key_aliases;
+ }
+ else {
+ if (dst->geom->key_aliases) {
+ free(dst->geom->key_aliases);
+ }
+ dst->geom->key_aliases = NULL;
+ dst->geom->num_key_aliases = 0;
+ dst->geom->sz_key_aliases = 0;
+ }
+
+ /* font */
+ if (src->geom->label_font) {
+ if (!dst->geom->label_font) {
+ tmp = malloc(strlen(src->geom->label_font));
+ if (!tmp)
+ return FALSE;
+ dst->geom->label_font = tmp;
+ }
+ else if (strlen(src->geom->label_font) !=
+ strlen(dst->geom->label_font)) {
+ tmp = realloc(dst->geom->label_font,
+ strlen(src->geom->label_font));
+ if (!tmp)
+ return FALSE;
+ dst->geom->label_font = tmp;
+ }
+
+ strcpy(dst->geom->label_font, src->geom->label_font);
+ i = XkbGeomColorIndex(src->geom, src->geom->label_color);
+ dst->geom->label_color = &(dst->geom->colors[i]);
+ i = XkbGeomColorIndex(src->geom, src->geom->base_color);
+ dst->geom->base_color = &(dst->geom->colors[i]);
+ }
+ else {
+ if (dst->geom->label_font) {
+ free(dst->geom->label_font);
+ }
+ dst->geom->label_font = NULL;
+ dst->geom->label_color = NULL;
+ dst->geom->base_color = NULL;
+ }
+
+ dst->geom->name = src->geom->name;
+ dst->geom->width_mm = src->geom->width_mm;
+ dst->geom->height_mm = src->geom->height_mm;
+ }
+ else
+ {
+ if (dst->geom) {
+ /* I LOVE THE DIFFERENT CALL SIGNATURE. REALLY, I DO. */
+ XkbFreeGeometry(dst->geom, XkbGeomAllMask, TRUE);
+ dst->geom = NULL;
+ }
+ }
+
+ return TRUE;
+}
+
+static Bool
+_XkbCopyIndicators(XkbDescPtr src, XkbDescPtr dst)
+{
+ /* indicators */
+ if (src->indicators) {
+ if (!dst->indicators) {
+ dst->indicators = malloc(sizeof(XkbIndicatorRec));
+ if (!dst->indicators)
+ return FALSE;
+ }
+ memcpy(dst->indicators, src->indicators, sizeof(XkbIndicatorRec));
+ }
+ else {
+ if (dst->indicators) {
+ free(dst->indicators);
+ dst->indicators = NULL;
+ }
+ }
+ return TRUE;
+}
+
+static Bool
+_XkbCopyControls(XkbDescPtr src, XkbDescPtr dst)
+{
+ /* controls */
+ if (src->ctrls) {
+ if (!dst->ctrls) {
+ dst->ctrls = malloc(sizeof(XkbControlsRec));
+ if (!dst->ctrls)
+ return FALSE;
+ }
+ memcpy(dst->ctrls, src->ctrls, sizeof(XkbControlsRec));
+ }
+ else {
+ if (dst->ctrls) {
+ free(dst->ctrls);
+ dst->ctrls = NULL;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Copy an XKB map from src to dst, reallocating when necessary: if some
+ * map components are present in one, but not in the other, the destination
+ * components will be allocated or freed as necessary.
+ *
+ * Basic map consistency is assumed on both sides, so maps with random
+ * uninitialised data (e.g. names->radio_grous == NULL, names->num_rg == 19)
+ * _will_ cause failures. You've been warned.
+ *
+ * Returns TRUE on success, or FALSE on failure. If this function fails,
+ * dst may be in an inconsistent state: all its pointers are guaranteed
+ * to remain valid, but part of the map may be from src and part from dst.
+ *
+ */
+
+Bool
+XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
+{
+
+ if (!src || !dst) {
+ DebugF("XkbCopyKeymap: src (%p) or dst (%p) is NULL\n", src, dst);
+ return FALSE;
+ }
+
+ if (src == dst)
+ return TRUE;
+
+ if (!_XkbCopyClientMap(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy client map\n");
+ return FALSE;
+ }
+ if (!_XkbCopyServerMap(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy server map\n");
+ return FALSE;
+ }
+ if (!_XkbCopyIndicators(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy indicators\n");
+ return FALSE;
+ }
+ if (!_XkbCopyControls(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy controls\n");
+ return FALSE;
+ }
+ if (!_XkbCopyNames(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy names\n");
+ return FALSE;
+ }
+ if (!_XkbCopyCompat(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy compat map\n");
+ return FALSE;
+ }
+ if (!_XkbCopyGeom(src, dst)) {
+ DebugF("XkbCopyKeymap: failed to copy geometry\n");
+ return FALSE;
+ }
+
+ dst->min_key_code = src->min_key_code;
+ dst->max_key_code = src->max_key_code;
+
+ return TRUE;
+}
+
+Bool
+XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
+{
+ xkbNewKeyboardNotify nkn;
+ Bool ret;
+
+ if (!dst->key || !src->key)
+ return FALSE;
+
+ memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
+ nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
+ nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
+ nkn.deviceID = dst->id;
+ nkn.oldDeviceID = dst->id; /* maybe src->id? */
+ nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
+ nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
+ nkn.requestMajor = XkbReqCode;
+ nkn.requestMinor = X_kbSetMap; /* Near enough's good enough. */
+ nkn.changed = XkbNKN_KeycodesMask;
+ if (src->key->xkbInfo->desc->geom)
+ nkn.changed |= XkbNKN_GeometryMask;
+
+ ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
+ if (ret)
+ XkbSendNewKeyboardNotify(dst, &nkn);
+
+ return ret;
+}
+
+int
+XkbGetEffectiveGroup(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 keycode)
+{
+ XkbDescPtr xkb = xkbi->desc;
+ int effectiveGroup = xkbState->group;
+
+ if (!XkbKeycodeInRange(xkb, keycode))
+ return -1;
+
+ if (effectiveGroup == XkbGroup1Index)
+ return effectiveGroup;
+
+ if (XkbKeyNumGroups(xkb,keycode) > 1U) {
+ if (effectiveGroup >= XkbKeyNumGroups(xkb,keycode)) {
+ unsigned int gi = XkbKeyGroupInfo(xkb,keycode);
+ switch (XkbOutOfRangeGroupAction(gi)) {
+ default:
+ case XkbWrapIntoRange:
+ effectiveGroup %= XkbKeyNumGroups(xkb, keycode);
+ break;
+ case XkbClampIntoRange:
+ effectiveGroup = XkbKeyNumGroups(xkb, keycode) - 1;
+ break;
+ case XkbRedirectIntoRange:
+ effectiveGroup = XkbOutOfRangeGroupInfo(gi);
+ if (effectiveGroup >= XkbKeyNumGroups(xkb, keycode))
+ effectiveGroup = 0;
+ break;
+ }
+ }
+ }
+ else effectiveGroup = XkbGroup1Index;
+
+ return effectiveGroup;
+}
diff --git a/xorg-server/xkb/xkmread.c b/xorg-server/xkb/xkmread.c
index a201731f3..660884a7f 100644
--- a/xorg-server/xkb/xkmread.c
+++ b/xorg-server/xkb/xkmread.c
@@ -1,1238 +1,1238 @@
-/************************************************************
- Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
-
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
-
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- ********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-
-#include <X11/Xos.h>
-#include <X11/Xfuncs.h>
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include <X11/extensions/XKMformat.h>
-#include "misc.h"
-#include "inputstr.h"
-#include "xkbstr.h"
-#include "xkbsrv.h"
-#include "xkbgeom.h"
-
-Atom
-XkbInternAtom(char *str,Bool only_if_exists)
-{
- if (str==NULL)
- return None;
- return MakeAtom(str,strlen(str),!only_if_exists);
-}
-
-char *
-_XkbDupString(const char *str)
-{
-char *new;
-
- if (str==NULL)
- return NULL;
- new= xcalloc(strlen(str)+1,sizeof(char));
- if (new)
- strcpy(new,str);
- return new;
-}
-
-/***====================================================================***/
-
-static void *
-XkmInsureSize(void *oldPtr,int oldCount,int *newCountRtrn,int elemSize)
-{
-int newCount= *newCountRtrn;
-
- if (oldPtr==NULL) {
- if (newCount==0)
- return NULL;
- oldPtr= xcalloc(newCount,elemSize);
- }
- else if (oldCount<newCount) {
- oldPtr= xrealloc(oldPtr,newCount*elemSize);
- if (oldPtr!=NULL) {
- char *tmp= (char *)oldPtr;
- bzero(&tmp[oldCount*elemSize],(newCount-oldCount)*elemSize);
- }
- }
- else if (newCount<oldCount) {
- *newCountRtrn= oldCount;
- }
- return oldPtr;
-}
-
-#define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t))))
-
-static CARD8
-XkmGetCARD8(FILE *file,int *pNRead)
-{
-int tmp;
- tmp= getc(file);
- if (pNRead&&(tmp!=EOF))
- (*pNRead)+= 1;
- return tmp;
-}
-
-static CARD16
-XkmGetCARD16(FILE *file,int *pNRead)
-{
-CARD16 val;
-
- if ((fread(&val,2,1,file)==1)&&(pNRead))
- (*pNRead)+= 2;
- return val;
-}
-
-static CARD32
-XkmGetCARD32(FILE *file,int *pNRead)
-{
-CARD32 val;
-
- if ((fread(&val,4,1,file)==1)&&(pNRead))
- (*pNRead)+= 4;
- return val;
-}
-
-static int
-XkmSkipPadding(FILE *file,unsigned pad)
-{
-register int i,nRead=0;
-
- for (i=0;i<pad;i++) {
- if (getc(file)!=EOF)
- nRead++;
- }
- return nRead;
-}
-
-static int
-XkmGetCountedString(FILE *file,char *str,int max_len)
-{
-int count,nRead=0;
-
- count= XkmGetCARD16(file,&nRead);
- if (count>0) {
- int tmp;
- if (count>max_len) {
- tmp= fread(str,1,max_len,file);
- while (tmp<count) {
- if ((getc(file))!=EOF)
- tmp++;
- else break;
- }
- }
- else {
- tmp= fread(str,1,count,file);
- }
- nRead+= tmp;
- }
- if (count>=max_len) str[max_len-1]= '\0';
- else str[count]= '\0';
- count= XkbPaddedSize(nRead)-nRead;
- if (count>0)
- nRead+= XkmSkipPadding(file,count);
- return nRead;
-}
-
-/***====================================================================***/
-
-static int
-ReadXkmVirtualMods(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
-{
-register unsigned int i,bit;
-unsigned int bound,named,tmp;
-int nRead=0;
-
- if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
- return -1;
- }
- bound= XkmGetCARD16(file,&nRead);
- named= XkmGetCARD16(file,&nRead);
- for (i=tmp=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- if (bound&bit) {
- xkb->server->vmods[i]= XkmGetCARD8(file,&nRead);
- if (changes)
- changes->map.vmods|= bit;
- tmp++;
- }
- }
- if ((i= XkbPaddedSize(tmp)-tmp)>0)
- nRead+= XkmSkipPadding(file,i);
- if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
- return -1;
- }
- for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
- char name[100];
- if (named&bit) {
- if (nRead+=XkmGetCountedString(file,name,100)) {
- xkb->names->vmods[i]= XkbInternAtom(name,FALSE);
- if (changes)
- changes->names.changed_vmods|= bit;
- }
- }
- }
- return nRead;
-}
-
-/***====================================================================***/
-
-static int
-ReadXkmKeycodes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
-{
-register int i;
-unsigned minKC,maxKC,nAl;
-int nRead=0;
-char name[100];
-XkbKeyNamePtr pN;
-
- name[0]= '\0';
- nRead+= XkmGetCountedString(file,name,100);
- minKC= XkmGetCARD8(file,&nRead);
- maxKC= XkmGetCARD8(file,&nRead);
- if (xkb->min_key_code==0) {
- xkb->min_key_code= minKC;
- xkb->max_key_code= maxKC;
- }
- else {
- if (minKC<xkb->min_key_code)
- xkb->min_key_code= minKC;
- if (maxKC>xkb->max_key_code) {
- _XkbLibError(_XkbErrBadValue,"ReadXkmKeycodes",maxKC);
- return -1;
- }
- }
- nAl= XkmGetCARD8(file,&nRead);
- nRead+= XkmSkipPadding(file,1);
-
-#define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask)
- if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
- return -1;
- }
- if (name[0]!='\0') {
- xkb->names->keycodes= XkbInternAtom(name,FALSE);
- }
-
- for (pN=&xkb->names->keys[minKC],i=minKC;i<=(int)maxKC;i++,pN++) {
- if (fread(pN,1,XkbKeyNameLength,file)!=XkbKeyNameLength) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
- return -1;
- }
- nRead+= XkbKeyNameLength;
- }
- if (nAl>0) {
- XkbKeyAliasPtr pAl;
- for (pAl= xkb->names->key_aliases,i=0;i<nAl;i++,pAl++) {
- int tmp;
- tmp= fread(pAl,1,2*XkbKeyNameLength,file);
- if (tmp!=2*XkbKeyNameLength) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
- return -1;
- }
- nRead+= 2*XkbKeyNameLength;
- }
- if (changes)
- changes->names.changed|= XkbKeyAliasesMask;
- }
- if (changes)
- changes->names.changed|= XkbKeyNamesMask;
- return nRead;
-}
-
-/***====================================================================***/
-
-static int
-ReadXkmKeyTypes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
-{
-register unsigned i,n;
-unsigned num_types;
-int nRead=0;
-int tmp;
-XkbKeyTypePtr type;
-xkmKeyTypeDesc wire;
-XkbKTMapEntryPtr entry;
-xkmKTMapEntryDesc wire_entry;
-char buf[100];
-
- if ((tmp= XkmGetCountedString(file,buf,100))<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
- return -1;
- }
- nRead+= tmp;
- if (buf[0]!='\0') {
- if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
- return -1;
- }
- xkb->names->types= XkbInternAtom(buf,FALSE);
- }
- num_types= XkmGetCARD16(file,&nRead);
- nRead+= XkmSkipPadding(file,2);
- if (num_types<1)
- return nRead;
- if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
- return nRead;
- }
- xkb->map->num_types= num_types;
- if (num_types<XkbNumRequiredTypes) {
- _XkbLibError(_XkbErrMissingReqTypes,"ReadXkmKeyTypes",0);
- return -1;
- }
- type= xkb->map->types;
- for (i=0;i<num_types;i++,type++) {
- if ((int)fread(&wire,SIZEOF(xkmKeyTypeDesc),1,file)<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
- return -1;
- }
- nRead+= SIZEOF(xkmKeyTypeDesc);
- if (((i==XkbOneLevelIndex)&&(wire.numLevels!=1))||
- (((i==XkbTwoLevelIndex)||(i==XkbAlphabeticIndex)||
- ((i)==XkbKeypadIndex))&&(wire.numLevels!=2))) {
- _XkbLibError(_XkbErrBadTypeWidth,"ReadXkmKeyTypes",i);
- return -1;
- }
- tmp= wire.nMapEntries;
- XkmInsureTypedSize(type->map,type->map_count,&tmp,XkbKTMapEntryRec);
- if ((wire.nMapEntries>0)&&(type->map==NULL)) {
- _XkbLibError(_XkbErrBadValue,"ReadXkmKeyTypes",wire.nMapEntries);
- return -1;
- }
- for (n=0,entry= type->map;n<wire.nMapEntries;n++,entry++) {
- if (fread(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file)<(int)1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
- return -1;
- }
- nRead+= SIZEOF(xkmKTMapEntryDesc);
- entry->active= (wire_entry.virtualMods==0);
- entry->level= wire_entry.level;
- entry->mods.mask= wire_entry.realMods;
- entry->mods.real_mods= wire_entry.realMods;
- entry->mods.vmods= wire_entry.virtualMods;
- }
- nRead+= XkmGetCountedString(file,buf,100);
- if (((i==XkbOneLevelIndex)&&(strcmp(buf,"ONE_LEVEL")!=0))||
- ((i==XkbTwoLevelIndex)&&(strcmp(buf,"TWO_LEVEL")!=0))||
- ((i==XkbAlphabeticIndex)&&(strcmp(buf,"ALPHABETIC")!=0))||
- ((i==XkbKeypadIndex)&&(strcmp(buf,"KEYPAD")!=0))) {
- _XkbLibError(_XkbErrBadTypeName,"ReadXkmKeyTypes",0);
- return -1;
- }
- if (buf[0]!='\0') {
- type->name= XkbInternAtom(buf,FALSE);
- }
- else type->name= None;
-
- if (wire.preserve) {
- xkmModsDesc p_entry;
- XkbModsPtr pre;
- XkmInsureTypedSize(type->preserve,type->map_count,&tmp,
- XkbModsRec);
- if (type->preserve==NULL) {
- _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
- return -1;
- }
- for (n=0,pre=type->preserve;n<wire.nMapEntries;n++,pre++) {
- if (fread(&p_entry,SIZEOF(xkmModsDesc),1,file)<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
- return -1;
- }
- nRead+= SIZEOF(xkmModsDesc);
- pre->mask= p_entry.realMods;
- pre->real_mods= p_entry.realMods;
- pre->vmods= p_entry.virtualMods;
- }
- }
- if (wire.nLevelNames>0) {
- int width= wire.numLevels;
- if (wire.nLevelNames>(unsigned)width) {
- _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
- return -1;
- }
- XkmInsureTypedSize(type->level_names,type->num_levels,&width,Atom);
- if (type->level_names!=NULL) {
- for (n=0;n<wire.nLevelNames;n++) {
- if ((tmp=XkmGetCountedString(file,buf,100))<1)
- return -1;
- nRead+= tmp;
- if (strlen(buf)==0)
- type->level_names[n]= None;
- else type->level_names[n]= XkbInternAtom(buf,0);
- }
- }
- }
- type->mods.mask= wire.realMods;
- type->mods.real_mods= wire.realMods;
- type->mods.vmods= wire.virtualMods;
- type->num_levels= wire.numLevels;
- type->map_count= wire.nMapEntries;
- }
- if (changes) {
- changes->map.changed|= XkbKeyTypesMask;
- changes->map.first_type= 0;
- changes->map.num_types= xkb->map->num_types;
- }
- return nRead;
-}
-
-/***====================================================================***/
-
-static int
-ReadXkmCompatMap(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
-{
-register int i;
-unsigned num_si,groups;
-char name[100];
-XkbSymInterpretPtr interp;
-xkmSymInterpretDesc wire;
-unsigned tmp;
-int nRead=0;
-XkbCompatMapPtr compat;
-XkbAction *act;
-
- if ((tmp= XkmGetCountedString(file,name,100))<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0);
- return -1;
- }
- nRead+= tmp;
- if (name[0]!='\0') {
- if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0);
- return -1;
- }
- xkb->names->compat= XkbInternAtom(name,FALSE);
- }
- num_si= XkmGetCARD16(file,&nRead);
- groups= XkmGetCARD8(file,&nRead);
- nRead+= XkmSkipPadding(file,1);
- if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success)
- return -1;
- compat= xkb->compat;
- compat->num_si= num_si;
- interp= compat->sym_interpret;
- for (i=0;i<num_si;i++,interp++) {
- tmp= fread(&wire,SIZEOF(xkmSymInterpretDesc),1,file);
- nRead+= tmp*SIZEOF(xkmSymInterpretDesc);
- interp->sym= wire.sym;
- interp->mods= wire.mods;
- interp->match= wire.match;
- interp->virtual_mod= wire.virtualMod;
- interp->flags= wire.flags;
- interp->act.type= wire.actionType;
- act = (XkbAction *) &interp->act;
-
- switch (interp->act.type) {
- case XkbSA_SetMods:
- case XkbSA_LatchMods:
- case XkbSA_LockMods:
- act->mods.flags = wire.actionData[0];
- act->mods.mask = wire.actionData[1];
- act->mods.real_mods = wire.actionData[2];
- act->mods.vmods1 = wire.actionData[3];
- act->mods.vmods2 = wire.actionData[4];
- break;
- case XkbSA_SetGroup:
- case XkbSA_LatchGroup:
- case XkbSA_LockGroup:
- act->group.flags = wire.actionData[0];
- act->group.group_XXX = wire.actionData[1];
- break;
- case XkbSA_MovePtr:
- act->ptr.flags = wire.actionData[0];
- act->ptr.high_XXX = wire.actionData[1];
- act->ptr.low_XXX = wire.actionData[2];
- act->ptr.high_YYY = wire.actionData[3];
- act->ptr.low_YYY = wire.actionData[4];
- break;
- case XkbSA_PtrBtn:
- case XkbSA_LockPtrBtn:
- act->btn.flags = wire.actionData[0];
- act->btn.count = wire.actionData[1];
- act->btn.button = wire.actionData[2];
- break;
- case XkbSA_DeviceBtn:
- case XkbSA_LockDeviceBtn:
- act->devbtn.flags = wire.actionData[0];
- act->devbtn.count = wire.actionData[1];
- act->devbtn.button = wire.actionData[2];
- act->devbtn.device = wire.actionData[3];
- break;
- case XkbSA_SetPtrDflt:
- act->dflt.flags = wire.actionData[0];
- act->dflt.affect = wire.actionData[1];
- act->dflt.valueXXX = wire.actionData[2];
- break;
- case XkbSA_ISOLock:
- act->iso.flags = wire.actionData[0];
- act->iso.mask = wire.actionData[1];
- act->iso.real_mods = wire.actionData[2];
- act->iso.group_XXX = wire.actionData[3];
- act->iso.affect = wire.actionData[4];
- act->iso.vmods1 = wire.actionData[5];
- act->iso.vmods2 = wire.actionData[6];
- break;
- case XkbSA_SwitchScreen:
- act->screen.flags = wire.actionData[0];
- act->screen.screenXXX = wire.actionData[1];
- break;
- case XkbSA_SetControls:
- case XkbSA_LockControls:
- act->ctrls.flags = wire.actionData[0];
- act->ctrls.ctrls3 = wire.actionData[1];
- act->ctrls.ctrls2 = wire.actionData[2];
- act->ctrls.ctrls1 = wire.actionData[3];
- act->ctrls.ctrls0 = wire.actionData[4];
- break;
- case XkbSA_RedirectKey:
- act->redirect.new_key = wire.actionData[0];
- act->redirect.mods_mask = wire.actionData[1];
- act->redirect.mods = wire.actionData[2];
- act->redirect.vmods_mask0 = wire.actionData[3];
- act->redirect.vmods_mask1 = wire.actionData[4];
- act->redirect.vmods0 = wire.actionData[4];
- act->redirect.vmods1 = wire.actionData[5];
- break;
- case XkbSA_DeviceValuator:
- act->devval.device = wire.actionData[0];
- act->devval.v1_what = wire.actionData[1];
- act->devval.v1_ndx = wire.actionData[2];
- act->devval.v1_value = wire.actionData[3];
- act->devval.v2_what = wire.actionData[4];
- act->devval.v2_ndx = wire.actionData[5];
- act->devval.v2_what = wire.actionData[6];
- break;
-
- case XkbSA_XFree86Private:
- /* copy the kind of action */
- strncpy((char*)act->any.data, (char*)wire.actionData,
- XkbAnyActionDataSize);
- break ;
-
- case XkbSA_Terminate:
- /* no args, kinda (note: untrue for xfree86). */
- break;
- case XkbSA_ActionMessage:
- /* unsupported. */
- break;
- }
- }
- if ((num_si>0)&&(changes)) {
- changes->compat.first_si= 0;
- changes->compat.num_si= num_si;
- }
- if (groups) {
- register unsigned bit;
- for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
- xkmModsDesc md;
- if (groups&bit) {
- tmp= fread(&md,SIZEOF(xkmModsDesc),1,file);
- nRead+= tmp*SIZEOF(xkmModsDesc);
- xkb->compat->groups[i].real_mods= md.realMods;
- xkb->compat->groups[i].vmods= md.virtualMods;
- if (md.virtualMods != 0) {
- unsigned mask;
- if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask))
- xkb->compat->groups[i].mask= md.realMods|mask;
- }
- else xkb->compat->groups[i].mask= md.realMods;
- }
- }
- if (changes)
- changes->compat.changed_groups|= groups;
- }
- return nRead;
-}
-
-static int
-ReadXkmIndicators(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
-{
-register unsigned nLEDs;
-xkmIndicatorMapDesc wire;
-char buf[100];
-unsigned tmp;
-int nRead=0;
-
- if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) {
- _XkbLibError(_XkbErrBadAlloc,"indicator rec",0);
- return -1;
- }
- if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"indicator names",0);
- return -1;
- }
- nLEDs= XkmGetCARD8(file,&nRead);
- nRead+= XkmSkipPadding(file,3);
- xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead);
- while (nLEDs-->0) {
- Atom name;
- XkbIndicatorMapPtr map;
-
- if ((tmp=XkmGetCountedString(file,buf,100))<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
- return -1;
- }
- nRead+= tmp;
- if (buf[0]!='\0')
- name= XkbInternAtom(buf,FALSE);
- else name= None;
- if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
- return -1;
- }
- nRead+= tmp*SIZEOF(xkmIndicatorMapDesc);
- if (xkb->names) {
- xkb->names->indicators[wire.indicator-1]= name;
- if (changes)
- changes->names.changed_indicators|= (1<<(wire.indicator-1));
- }
- map= &xkb->indicators->maps[wire.indicator-1];
- map->flags= wire.flags;
- map->which_groups= wire.which_groups;
- map->groups= wire.groups;
- map->which_mods= wire.which_mods;
- map->mods.mask= wire.real_mods;
- map->mods.real_mods= wire.real_mods;
- map->mods.vmods= wire.vmods;
- map->ctrls= wire.ctrls;
- }
- return nRead;
-}
-
-static XkbKeyTypePtr
-FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms)
-{
- if ((!xkb)||(!xkb->map))
- return NULL;
- if (name!=None) {
- register unsigned i;
- for (i=0;i<xkb->map->num_types;i++) {
- if (xkb->map->types[i].name==name) {
- if (xkb->map->types[i].num_levels!=width)
- DebugF("Group width mismatch between key and type\n");
- return &xkb->map->types[i];
- }
- }
- }
- if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol)))
- return &xkb->map->types[XkbOneLevelIndex];
- if (syms!=NULL) {
- if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1]))
- return &xkb->map->types[XkbAlphabeticIndex];
- else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1]))
- return &xkb->map->types[XkbKeypadIndex];
- }
- return &xkb->map->types[XkbTwoLevelIndex];
-}
-
-static int
-ReadXkmSymbols(FILE *file,XkbDescPtr xkb)
-{
-register int i,g,s,totalVModMaps;
-xkmKeySymMapDesc wireMap;
-char buf[100];
-unsigned minKC,maxKC,groupNames,tmp;
-int nRead=0;
-
- if ((tmp=XkmGetCountedString(file,buf,100))<1)
- return -1;
- nRead+= tmp;
- minKC= XkmGetCARD8(file,&nRead);
- maxKC= XkmGetCARD8(file,&nRead);
- groupNames= XkmGetCARD8(file,&nRead);
- totalVModMaps= XkmGetCARD8(file,&nRead);
- if (XkbAllocNames(xkb,
- XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask,
- 0,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"physical names",0);
- return -1;
- }
- if ((buf[0]!='\0')&&(xkb->names)) {
- Atom name;
- name= XkbInternAtom(buf,0);
- xkb->names->symbols= name;
- xkb->names->phys_symbols= name;
- }
- for (i=0,g=1;i<XkbNumKbdGroups;i++,g<<=1) {
- if (groupNames&g) {
- if ((tmp=XkmGetCountedString(file,buf,100))<1)
- return -1;
- nRead+= tmp;
- if ((buf[0]!='\0')&&(xkb->names)) {
- Atom name;
- name= XkbInternAtom(buf,0);
- xkb->names->groups[i]= name;
- }
- else xkb->names->groups[i]= None;
- }
- }
- if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"server map",0);
- return -1;
- }
- if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"client map",0);
- return -1;
- }
- if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"controls",0);
- return -1;
- }
- if ((xkb->map==NULL)||(xkb->server==NULL))
- return -1;
- if (xkb->min_key_code<8) xkb->min_key_code= minKC;
- if (xkb->max_key_code<8) xkb->max_key_code= maxKC;
- if ((minKC>=8)&&(minKC<xkb->min_key_code))
- xkb->min_key_code= minKC;
- if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) {
- _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC);
- return -1;
- }
- for (i=minKC;i<=(int)maxKC;i++) {
- Atom typeName[XkbNumKbdGroups];
- XkbKeyTypePtr type[XkbNumKbdGroups];
- if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0);
- return -1;
- }
- nRead+= tmp*SIZEOF(xkmKeySymMapDesc);
- bzero((char *)typeName,XkbNumKbdGroups*sizeof(Atom));
- bzero((char *)type,XkbNumKbdGroups*sizeof(XkbKeyTypePtr));
- if (wireMap.flags&XkmKeyHasTypes) {
- register int g;
- for (g=0;g<XkbNumKbdGroups;g++) {
- if ((wireMap.flags&(1<<g))&&
- ((tmp=XkmGetCountedString(file,buf,100))>0)) {
- typeName[g]= XkbInternAtom(buf,1);
- nRead+= tmp;
- }
- type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL);
- if (type[g]==NULL) {
- _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0);
- return -1;
- }
- if (typeName[g]==type[g]->name)
- xkb->server->explicit[i]|= (1<<g);
- }
- }
- if (wireMap.flags&XkmRepeatingKey) {
- xkb->ctrls->per_key_repeat[i/8]|= (1<<(i%8));
- xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
- }
- else if (wireMap.flags&XkmNonRepeatingKey) {
- xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8));
- xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
- }
- xkb->map->modmap[i]= wireMap.modifier_map;
- if (XkbNumGroups(wireMap.num_groups)>0) {
- KeySym *sym;
- int nSyms;
-
- if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups)
- xkb->ctrls->num_groups= wireMap.num_groups;
- nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width;
- sym= XkbResizeKeySyms(xkb,i,nSyms);
- if (!sym)
- return -1;
- for (s=0;s<nSyms;s++) {
- *sym++= XkmGetCARD32(file,&nRead);
- }
- if (wireMap.flags&XkmKeyHasActions) {
- XkbAction * act;
- act= XkbResizeKeyActions(xkb,i,nSyms);
- for (s=0;s<nSyms;s++,act++) {
- tmp=fread(act,SIZEOF(xkmActionDesc),1,file);
- nRead+= tmp*SIZEOF(xkmActionDesc);
- }
- xkb->server->explicit[i]|= XkbExplicitInterpretMask;
- }
- }
- for (g=0;g<XkbNumGroups(wireMap.num_groups);g++) {
- if (((xkb->server->explicit[i]&(1<<g))==0)||(type[g]==NULL)) {
- KeySym *tmpSyms;
- tmpSyms= XkbKeySymsPtr(xkb,i)+(wireMap.width*g);
- type[g]= FindTypeForKey(xkb,None,wireMap.width,tmpSyms);
- }
- xkb->map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]);
- }
- xkb->map->key_sym_map[i].group_info= wireMap.num_groups;
- xkb->map->key_sym_map[i].width= wireMap.width;
- if (wireMap.flags&XkmKeyHasBehavior) {
- xkmBehaviorDesc b;
- tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file);
- nRead+= tmp*SIZEOF(xkmBehaviorDesc);
- xkb->server->behaviors[i].type= b.type;
- xkb->server->behaviors[i].data= b.data;
- xkb->server->explicit[i]|= XkbExplicitBehaviorMask;
- }
- }
- if (totalVModMaps>0) {
- xkmVModMapDesc v;
- for (i=0;i<totalVModMaps;i++) {
- tmp= fread(&v,SIZEOF(xkmVModMapDesc),1,file);
- nRead+= tmp*SIZEOF(xkmVModMapDesc);
- if (tmp>0)
- xkb->server->vmodmap[v.key]= v.vmods;
- }
- }
- return nRead;
-}
-
-static int
-ReadXkmGeomDoodad(
- FILE * file,
- XkbGeometryPtr geom,
- XkbSectionPtr section)
-{
-XkbDoodadPtr doodad;
-xkmDoodadDesc doodadWire;
-char buf[100];
-unsigned tmp;
-int nRead=0;
-
- nRead+= XkmGetCountedString(file,buf,100);
- tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file);
- nRead+= SIZEOF(xkmDoodadDesc)*tmp;
- doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(buf,FALSE));
- if (!doodad)
- return nRead;
- doodad->any.type= doodadWire.any.type;
- doodad->any.priority= doodadWire.any.priority;
- doodad->any.top= doodadWire.any.top;
- doodad->any.left= doodadWire.any.left;
- switch (doodadWire.any.type) {
- case XkbOutlineDoodad:
- case XkbSolidDoodad:
- doodad->shape.angle= doodadWire.shape.angle;
- doodad->shape.color_ndx= doodadWire.shape.color_ndx;
- doodad->shape.shape_ndx= doodadWire.shape.shape_ndx;
- break;
- case XkbTextDoodad:
- doodad->text.angle= doodadWire.text.angle;
- doodad->text.width= doodadWire.text.width;
- doodad->text.height= doodadWire.text.height;
- doodad->text.color_ndx= doodadWire.text.color_ndx;
- nRead+= XkmGetCountedString(file,buf,100);
- doodad->text.text= _XkbDupString(buf);
- nRead+= XkmGetCountedString(file,buf,100);
- doodad->text.font= _XkbDupString(buf);
- break;
- case XkbIndicatorDoodad:
- doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx;
- doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx;
- doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx;
- break;
- case XkbLogoDoodad:
- doodad->logo.angle= doodadWire.logo.angle;
- doodad->logo.color_ndx= doodadWire.logo.color_ndx;
- doodad->logo.shape_ndx= doodadWire.logo.shape_ndx;
- nRead+= XkmGetCountedString(file,buf,100);
- doodad->logo.logo_name= _XkbDupString(buf);
- break;
- default:
- /* report error? */
- return nRead;
- }
- return nRead;
-}
-
-static int
-ReadXkmGeomOverlay( FILE * file,
- XkbGeometryPtr geom,
- XkbSectionPtr section)
-{
-char buf[100];
-unsigned tmp;
-int nRead=0;
-XkbOverlayPtr ol;
-XkbOverlayRowPtr row;
-xkmOverlayDesc olWire;
-xkmOverlayRowDesc rowWire;
-register int r;
-
- nRead+= XkmGetCountedString(file,buf,100);
- tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file);
- nRead+= tmp*SIZEOF(xkmOverlayDesc);
- ol= XkbAddGeomOverlay(section,XkbInternAtom(buf,FALSE),
- olWire.num_rows);
- if (!ol)
- return nRead;
- for (r=0;r<olWire.num_rows;r++) {
- int k;
- xkmOverlayKeyDesc keyWire;
- tmp= fread(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file);
- nRead+= tmp*SIZEOF(xkmOverlayRowDesc);
- row= XkbAddGeomOverlayRow(ol,rowWire.row_under,rowWire.num_keys);
- if (!row) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomOverlay",0);
- return nRead;
- }
- for (k=0;k<rowWire.num_keys;k++) {
- tmp= fread(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file);
- nRead+= tmp*SIZEOF(xkmOverlayKeyDesc);
- memcpy(row->keys[k].over.name,keyWire.over,XkbKeyNameLength);
- memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength);
- }
- row->num_keys= rowWire.num_keys;
- }
- return nRead;
-}
-
-static int
-ReadXkmGeomSection( FILE * file,
- XkbGeometryPtr geom)
-{
-register int i;
-XkbSectionPtr section;
-xkmSectionDesc sectionWire;
-unsigned tmp;
-int nRead= 0;
-char buf[100];
-Atom nameAtom;
-
- nRead+= XkmGetCountedString(file,buf,100);
- nameAtom= XkbInternAtom(buf,FALSE);
- tmp= fread(&sectionWire,SIZEOF(xkmSectionDesc),1,file);
- nRead+= SIZEOF(xkmSectionDesc)*tmp;
- section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows,
- sectionWire.num_doodads,
- sectionWire.num_overlays);
- if (!section) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
- return nRead;
- }
- section->top= sectionWire.top;
- section->left= sectionWire.left;
- section->width= sectionWire.width;
- section->height= sectionWire.height;
- section->angle= sectionWire.angle;
- section->priority= sectionWire.priority;
- if (sectionWire.num_rows>0) {
- register int k;
- XkbRowPtr row;
- xkmRowDesc rowWire;
- XkbKeyPtr key;
- xkmKeyDesc keyWire;
-
- for (i=0;i<sectionWire.num_rows;i++) {
- tmp= fread(&rowWire,SIZEOF(xkmRowDesc),1,file);
- nRead+= SIZEOF(xkmRowDesc)*tmp;
- row= XkbAddGeomRow(section,rowWire.num_keys);
- if (!row) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
- return nRead;
- }
- row->top= rowWire.top;
- row->left= rowWire.left;
- row->vertical= rowWire.vertical;
- for (k=0;k<rowWire.num_keys;k++) {
- tmp= fread(&keyWire,SIZEOF(xkmKeyDesc),1,file);
- nRead+= SIZEOF(xkmKeyDesc)*tmp;
- key= XkbAddGeomKey(row);
- if (!key) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
- return nRead;
- }
- memcpy(key->name.name,keyWire.name,XkbKeyNameLength);
- key->gap= keyWire.gap;
- key->shape_ndx= keyWire.shape_ndx;
- key->color_ndx= keyWire.color_ndx;
- }
- }
- }
- if (sectionWire.num_doodads>0) {
- for (i=0;i<sectionWire.num_doodads;i++) {
- tmp= ReadXkmGeomDoodad(file,geom,section);
- nRead+= tmp;
- if (tmp<1)
- return nRead;
- }
- }
- if (sectionWire.num_overlays>0) {
- for (i=0;i<sectionWire.num_overlays;i++) {
- tmp= ReadXkmGeomOverlay(file,geom,section);
- nRead+= tmp;
- if (tmp<1)
- return nRead;
- }
- }
- return nRead;
-}
-
-static int
-ReadXkmGeometry(FILE *file,XkbDescPtr xkb)
-{
-register int i;
-char buf[100];
-unsigned tmp;
-int nRead= 0;
-xkmGeometryDesc wireGeom;
-XkbGeometryPtr geom;
-XkbGeometrySizesRec sizes;
-
- nRead+= XkmGetCountedString(file,buf,100);
- tmp= fread(&wireGeom,SIZEOF(xkmGeometryDesc),1,file);
- nRead+= tmp*SIZEOF(xkmGeometryDesc);
- sizes.which= XkbGeomAllMask;
- sizes.num_properties= wireGeom.num_properties;
- sizes.num_colors= wireGeom.num_colors;
- sizes.num_shapes= wireGeom.num_shapes;
- sizes.num_sections= wireGeom.num_sections;
- sizes.num_doodads= wireGeom.num_doodads;
- sizes.num_key_aliases= wireGeom.num_key_aliases;
- if (XkbAllocGeometry(xkb,&sizes)!=Success) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
- return nRead;
- }
- geom= xkb->geom;
- geom->name= XkbInternAtom(buf,FALSE);
- geom->width_mm= wireGeom.width_mm;
- geom->height_mm= wireGeom.height_mm;
- nRead+= XkmGetCountedString(file,buf,100);
- geom->label_font= _XkbDupString(buf);
- if (wireGeom.num_properties>0) {
- char val[1024];
- for (i=0;i<wireGeom.num_properties;i++) {
- nRead+= XkmGetCountedString(file,buf,100);
- nRead+= XkmGetCountedString(file,val,1024);
- if (XkbAddGeomProperty(geom,buf,val)==NULL) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
- return nRead;
- }
- }
- }
- if (wireGeom.num_colors>0) {
- for (i=0;i<wireGeom.num_colors;i++) {
- nRead+= XkmGetCountedString(file,buf,100);
- if (XkbAddGeomColor(geom,buf,i)==NULL) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
- return nRead;
- }
- }
- }
- geom->base_color= &geom->colors[wireGeom.base_color_ndx];
- geom->label_color= &geom->colors[wireGeom.label_color_ndx];
- if (wireGeom.num_shapes>0) {
- XkbShapePtr shape;
- xkmShapeDesc shapeWire;
- Atom nameAtom;
- for (i=0;i<wireGeom.num_shapes;i++) {
- register int n;
- XkbOutlinePtr ol;
- xkmOutlineDesc olWire;
- nRead+= XkmGetCountedString(file,buf,100);
- nameAtom= XkbInternAtom(buf,FALSE);
- tmp= fread(&shapeWire,SIZEOF(xkmShapeDesc),1,file);
- nRead+= tmp*SIZEOF(xkmShapeDesc);
- shape= XkbAddGeomShape(geom,nameAtom,shapeWire.num_outlines);
- if (!shape) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
- return nRead;
- }
- for (n=0;n<shapeWire.num_outlines;n++) {
- register int p;
- xkmPointDesc ptWire;
- tmp= fread(&olWire,SIZEOF(xkmOutlineDesc),1,file);
- nRead+= tmp*SIZEOF(xkmOutlineDesc);
- ol= XkbAddGeomOutline(shape,olWire.num_points);
- if (!ol) {
- _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
- return nRead;
- }
- ol->num_points= olWire.num_points;
- ol->corner_radius= olWire.corner_radius;
- for (p=0;p<olWire.num_points;p++) {
- tmp= fread(&ptWire,SIZEOF(xkmPointDesc),1,file);
- nRead+= tmp*SIZEOF(xkmPointDesc);
- ol->points[p].x= ptWire.x;
- ol->points[p].y= ptWire.y;
- if (ptWire.x<shape->bounds.x1) shape->bounds.x1= ptWire.x;
- if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x;
- if (ptWire.y<shape->bounds.y1) shape->bounds.y1= ptWire.y;
- if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y;
- }
- }
- if (shapeWire.primary_ndx!=XkbNoShape)
- shape->primary= &shape->outlines[shapeWire.primary_ndx];
- if (shapeWire.approx_ndx!=XkbNoShape)
- shape->approx= &shape->outlines[shapeWire.approx_ndx];
- }
- }
- if (wireGeom.num_sections>0) {
- for (i=0;i<wireGeom.num_sections;i++) {
- tmp= ReadXkmGeomSection(file,geom);
- nRead+= tmp;
- if (tmp==0)
- return nRead;
- }
- }
- if (wireGeom.num_doodads>0) {
- for (i=0;i<wireGeom.num_doodads;i++) {
- tmp= ReadXkmGeomDoodad(file,geom,NULL);
- nRead+= tmp;
- if (tmp==0)
- return nRead;
- }
- }
- if ((wireGeom.num_key_aliases>0)&&(geom->key_aliases)) {
- int sz= XkbKeyNameLength*2;
- int num= wireGeom.num_key_aliases;
- if (fread(geom->key_aliases,sz,num,file)!=num) {
- _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0);
- return -1;
- }
- nRead+= (num*sz);
- geom->num_key_aliases= num;
- }
- return nRead;
-}
-
-Bool
-XkmProbe(FILE *file)
-{
-unsigned hdr,tmp;
-int nRead=0;
-
- hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
- tmp= XkmGetCARD32(file,&nRead);
- if (tmp!=hdr) {
- if ((tmp&(~0xff))==(hdr&(~0xff))) {
- _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff);
- }
- return 0;
- }
- return 1;
-}
-
-static Bool
-XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc)
-{
-unsigned hdr,tmp;
-int nRead=0;
-unsigned i,size_toc;
-
- hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
- tmp= XkmGetCARD32(file,&nRead);
- if (tmp!=hdr) {
- if ((tmp&(~0xff))==(hdr&(~0xff))) {
- _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff);
- }
- else {
- _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp);
- }
- return 0;
- }
- fread(file_info,SIZEOF(xkmFileInfo),1,file);
- size_toc= file_info->num_toc;
- if (size_toc>max_toc) {
- DebugF("Warning! Too many TOC entries; last %d ignored\n",
- size_toc-max_toc);
- size_toc= max_toc;
- }
- for (i=0;i<size_toc;i++) {
- fread(&toc[i],SIZEOF(xkmSectionInfo),1,file);
- }
- return 1;
-}
-
-/***====================================================================***/
-
-#define MAX_TOC 16
-unsigned
-XkmReadFile(FILE *file,unsigned need,unsigned want,XkbDescPtr *xkb)
-{
-register unsigned i;
-xkmSectionInfo toc[MAX_TOC],tmpTOC;
-xkmFileInfo fileInfo;
-unsigned tmp,nRead=0;
-unsigned which= need|want;
-
- if (!XkmReadTOC(file,&fileInfo,MAX_TOC,toc))
- return which;
- if ((fileInfo.present&need)!=need) {
- _XkbLibError(_XkbErrIllegalContents,"XkmReadFile",
- need&(~fileInfo.present));
- return which;
- }
- if (*xkb==NULL)
- *xkb= XkbAllocKeyboard();
- for (i=0;i<fileInfo.num_toc;i++) {
- fseek(file,toc[i].offset,SEEK_SET);
- tmp= fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file);
- nRead= tmp*SIZEOF(xkmSectionInfo);
- if ((tmpTOC.type!=toc[i].type)||(tmpTOC.format!=toc[i].format)||
- (tmpTOC.size!=toc[i].size)||(tmpTOC.offset!=toc[i].offset)) {
- return which;
- }
- if ((which&(1<<tmpTOC.type))==0) {
- continue;
- }
- switch (tmpTOC.type) {
- case XkmVirtualModsIndex:
- tmp= ReadXkmVirtualMods(file,*xkb,NULL);
- break;
- case XkmTypesIndex:
- tmp= ReadXkmKeyTypes(file,*xkb,NULL);
- break;
- case XkmCompatMapIndex:
- tmp= ReadXkmCompatMap(file,*xkb,NULL);
- break;
- case XkmKeyNamesIndex:
- tmp= ReadXkmKeycodes(file,*xkb,NULL);
- break;
- case XkmIndicatorsIndex:
- tmp= ReadXkmIndicators(file,*xkb,NULL);
- break;
- case XkmSymbolsIndex:
- tmp= ReadXkmSymbols(file,*xkb);
- break;
- case XkmGeometryIndex:
- tmp= ReadXkmGeometry(file,*xkb);
- break;
- default:
- _XkbLibError(_XkbErrBadImplementation,
- XkbConfigText(tmpTOC.type,XkbMessage),0);
- tmp= 0;
- break;
- }
- if (tmp>0) {
- nRead+= tmp;
- which&= ~(1<<toc[i].type);
- (*xkb)->defined|= (1<<toc[i].type);
- }
- if (nRead!=tmpTOC.size) {
- _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage),
- nRead-tmpTOC.size);
- }
- }
- return which;
-}
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation, and that the name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+
+#include <X11/Xos.h>
+#include <X11/Xfuncs.h>
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XKMformat.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "xkbstr.h"
+#include "xkbsrv.h"
+#include "xkbgeom.h"
+
+Atom
+XkbInternAtom(char *str,Bool only_if_exists)
+{
+ if (str==NULL)
+ return None;
+ return MakeAtom(str,strlen(str),!only_if_exists);
+}
+
+char *
+_XkbDupString(const char *str)
+{
+char *new;
+
+ if (str==NULL)
+ return NULL;
+ new= calloc(strlen(str)+1,sizeof(char));
+ if (new)
+ strcpy(new,str);
+ return new;
+}
+
+/***====================================================================***/
+
+static void *
+XkmInsureSize(void *oldPtr,int oldCount,int *newCountRtrn,int elemSize)
+{
+int newCount= *newCountRtrn;
+
+ if (oldPtr==NULL) {
+ if (newCount==0)
+ return NULL;
+ oldPtr= calloc(newCount,elemSize);
+ }
+ else if (oldCount<newCount) {
+ oldPtr= realloc(oldPtr,newCount*elemSize);
+ if (oldPtr!=NULL) {
+ char *tmp= (char *)oldPtr;
+ bzero(&tmp[oldCount*elemSize],(newCount-oldCount)*elemSize);
+ }
+ }
+ else if (newCount<oldCount) {
+ *newCountRtrn= oldCount;
+ }
+ return oldPtr;
+}
+
+#define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t))))
+
+static CARD8
+XkmGetCARD8(FILE *file,int *pNRead)
+{
+int tmp;
+ tmp= getc(file);
+ if (pNRead&&(tmp!=EOF))
+ (*pNRead)+= 1;
+ return tmp;
+}
+
+static CARD16
+XkmGetCARD16(FILE *file,int *pNRead)
+{
+CARD16 val;
+
+ if ((fread(&val,2,1,file)==1)&&(pNRead))
+ (*pNRead)+= 2;
+ return val;
+}
+
+static CARD32
+XkmGetCARD32(FILE *file,int *pNRead)
+{
+CARD32 val;
+
+ if ((fread(&val,4,1,file)==1)&&(pNRead))
+ (*pNRead)+= 4;
+ return val;
+}
+
+static int
+XkmSkipPadding(FILE *file,unsigned pad)
+{
+register int i,nRead=0;
+
+ for (i=0;i<pad;i++) {
+ if (getc(file)!=EOF)
+ nRead++;
+ }
+ return nRead;
+}
+
+static int
+XkmGetCountedString(FILE *file,char *str,int max_len)
+{
+int count,nRead=0;
+
+ count= XkmGetCARD16(file,&nRead);
+ if (count>0) {
+ int tmp;
+ if (count>max_len) {
+ tmp= fread(str,1,max_len,file);
+ while (tmp<count) {
+ if ((getc(file))!=EOF)
+ tmp++;
+ else break;
+ }
+ }
+ else {
+ tmp= fread(str,1,count,file);
+ }
+ nRead+= tmp;
+ }
+ if (count>=max_len) str[max_len-1]= '\0';
+ else str[count]= '\0';
+ count= XkbPaddedSize(nRead)-nRead;
+ if (count>0)
+ nRead+= XkmSkipPadding(file,count);
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmVirtualMods(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
+{
+register unsigned int i,bit;
+unsigned int bound,named,tmp;
+int nRead=0;
+
+ if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
+ return -1;
+ }
+ bound= XkmGetCARD16(file,&nRead);
+ named= XkmGetCARD16(file,&nRead);
+ for (i=tmp=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (bound&bit) {
+ xkb->server->vmods[i]= XkmGetCARD8(file,&nRead);
+ if (changes)
+ changes->map.vmods|= bit;
+ tmp++;
+ }
+ }
+ if ((i= XkbPaddedSize(tmp)-tmp)>0)
+ nRead+= XkmSkipPadding(file,i);
+ if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
+ return -1;
+ }
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ char name[100];
+ if (named&bit) {
+ if (nRead+=XkmGetCountedString(file,name,100)) {
+ xkb->names->vmods[i]= XkbInternAtom(name,FALSE);
+ if (changes)
+ changes->names.changed_vmods|= bit;
+ }
+ }
+ }
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmKeycodes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
+{
+register int i;
+unsigned minKC,maxKC,nAl;
+int nRead=0;
+char name[100];
+XkbKeyNamePtr pN;
+
+ name[0]= '\0';
+ nRead+= XkmGetCountedString(file,name,100);
+ minKC= XkmGetCARD8(file,&nRead);
+ maxKC= XkmGetCARD8(file,&nRead);
+ if (xkb->min_key_code==0) {
+ xkb->min_key_code= minKC;
+ xkb->max_key_code= maxKC;
+ }
+ else {
+ if (minKC<xkb->min_key_code)
+ xkb->min_key_code= minKC;
+ if (maxKC>xkb->max_key_code) {
+ _XkbLibError(_XkbErrBadValue,"ReadXkmKeycodes",maxKC);
+ return -1;
+ }
+ }
+ nAl= XkmGetCARD8(file,&nRead);
+ nRead+= XkmSkipPadding(file,1);
+
+#define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask)
+ if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ if (name[0]!='\0') {
+ xkb->names->keycodes= XkbInternAtom(name,FALSE);
+ }
+
+ for (pN=&xkb->names->keys[minKC],i=minKC;i<=(int)maxKC;i++,pN++) {
+ if (fread(pN,1,XkbKeyNameLength,file)!=XkbKeyNameLength) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ nRead+= XkbKeyNameLength;
+ }
+ if (nAl>0) {
+ XkbKeyAliasPtr pAl;
+ for (pAl= xkb->names->key_aliases,i=0;i<nAl;i++,pAl++) {
+ int tmp;
+ tmp= fread(pAl,1,2*XkbKeyNameLength,file);
+ if (tmp!=2*XkbKeyNameLength) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ nRead+= 2*XkbKeyNameLength;
+ }
+ if (changes)
+ changes->names.changed|= XkbKeyAliasesMask;
+ }
+ if (changes)
+ changes->names.changed|= XkbKeyNamesMask;
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmKeyTypes(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
+{
+register unsigned i,n;
+unsigned num_types;
+int nRead=0;
+int tmp;
+XkbKeyTypePtr type;
+xkmKeyTypeDesc wire;
+XkbKTMapEntryPtr entry;
+xkmKTMapEntryDesc wire_entry;
+char buf[100];
+
+ if ((tmp= XkmGetCountedString(file,buf,100))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ nRead+= tmp;
+ if (buf[0]!='\0') {
+ if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ xkb->names->types= XkbInternAtom(buf,FALSE);
+ }
+ num_types= XkmGetCARD16(file,&nRead);
+ nRead+= XkmSkipPadding(file,2);
+ if (num_types<1)
+ return nRead;
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
+ return nRead;
+ }
+ xkb->map->num_types= num_types;
+ if (num_types<XkbNumRequiredTypes) {
+ _XkbLibError(_XkbErrMissingReqTypes,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ type= xkb->map->types;
+ for (i=0;i<num_types;i++,type++) {
+ if ((int)fread(&wire,SIZEOF(xkmKeyTypeDesc),1,file)<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ nRead+= SIZEOF(xkmKeyTypeDesc);
+ if (((i==XkbOneLevelIndex)&&(wire.numLevels!=1))||
+ (((i==XkbTwoLevelIndex)||(i==XkbAlphabeticIndex)||
+ ((i)==XkbKeypadIndex))&&(wire.numLevels!=2))) {
+ _XkbLibError(_XkbErrBadTypeWidth,"ReadXkmKeyTypes",i);
+ return -1;
+ }
+ tmp= wire.nMapEntries;
+ XkmInsureTypedSize(type->map,type->map_count,&tmp,XkbKTMapEntryRec);
+ if ((wire.nMapEntries>0)&&(type->map==NULL)) {
+ _XkbLibError(_XkbErrBadValue,"ReadXkmKeyTypes",wire.nMapEntries);
+ return -1;
+ }
+ for (n=0,entry= type->map;n<wire.nMapEntries;n++,entry++) {
+ if (fread(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file)<(int)1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ nRead+= SIZEOF(xkmKTMapEntryDesc);
+ entry->active= (wire_entry.virtualMods==0);
+ entry->level= wire_entry.level;
+ entry->mods.mask= wire_entry.realMods;
+ entry->mods.real_mods= wire_entry.realMods;
+ entry->mods.vmods= wire_entry.virtualMods;
+ }
+ nRead+= XkmGetCountedString(file,buf,100);
+ if (((i==XkbOneLevelIndex)&&(strcmp(buf,"ONE_LEVEL")!=0))||
+ ((i==XkbTwoLevelIndex)&&(strcmp(buf,"TWO_LEVEL")!=0))||
+ ((i==XkbAlphabeticIndex)&&(strcmp(buf,"ALPHABETIC")!=0))||
+ ((i==XkbKeypadIndex)&&(strcmp(buf,"KEYPAD")!=0))) {
+ _XkbLibError(_XkbErrBadTypeName,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ if (buf[0]!='\0') {
+ type->name= XkbInternAtom(buf,FALSE);
+ }
+ else type->name= None;
+
+ if (wire.preserve) {
+ xkmModsDesc p_entry;
+ XkbModsPtr pre;
+ XkmInsureTypedSize(type->preserve,type->map_count,&tmp,
+ XkbModsRec);
+ if (type->preserve==NULL) {
+ _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ for (n=0,pre=type->preserve;n<wire.nMapEntries;n++,pre++) {
+ if (fread(&p_entry,SIZEOF(xkmModsDesc),1,file)<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ nRead+= SIZEOF(xkmModsDesc);
+ pre->mask= p_entry.realMods;
+ pre->real_mods= p_entry.realMods;
+ pre->vmods= p_entry.virtualMods;
+ }
+ }
+ if (wire.nLevelNames>0) {
+ int width= wire.numLevels;
+ if (wire.nLevelNames>(unsigned)width) {
+ _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ XkmInsureTypedSize(type->level_names,type->num_levels,&width,Atom);
+ if (type->level_names!=NULL) {
+ for (n=0;n<wire.nLevelNames;n++) {
+ if ((tmp=XkmGetCountedString(file,buf,100))<1)
+ return -1;
+ nRead+= tmp;
+ if (strlen(buf)==0)
+ type->level_names[n]= None;
+ else type->level_names[n]= XkbInternAtom(buf,0);
+ }
+ }
+ }
+ type->mods.mask= wire.realMods;
+ type->mods.real_mods= wire.realMods;
+ type->mods.vmods= wire.virtualMods;
+ type->num_levels= wire.numLevels;
+ type->map_count= wire.nMapEntries;
+ }
+ if (changes) {
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type= 0;
+ changes->map.num_types= xkb->map->num_types;
+ }
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmCompatMap(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
+{
+register int i;
+unsigned num_si,groups;
+char name[100];
+XkbSymInterpretPtr interp;
+xkmSymInterpretDesc wire;
+unsigned tmp;
+int nRead=0;
+XkbCompatMapPtr compat;
+XkbAction *act;
+
+ if ((tmp= XkmGetCountedString(file,name,100))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0);
+ return -1;
+ }
+ nRead+= tmp;
+ if (name[0]!='\0') {
+ if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0);
+ return -1;
+ }
+ xkb->names->compat= XkbInternAtom(name,FALSE);
+ }
+ num_si= XkmGetCARD16(file,&nRead);
+ groups= XkmGetCARD8(file,&nRead);
+ nRead+= XkmSkipPadding(file,1);
+ if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success)
+ return -1;
+ compat= xkb->compat;
+ compat->num_si= num_si;
+ interp= compat->sym_interpret;
+ for (i=0;i<num_si;i++,interp++) {
+ tmp= fread(&wire,SIZEOF(xkmSymInterpretDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmSymInterpretDesc);
+ interp->sym= wire.sym;
+ interp->mods= wire.mods;
+ interp->match= wire.match;
+ interp->virtual_mod= wire.virtualMod;
+ interp->flags= wire.flags;
+ interp->act.type= wire.actionType;
+ act = (XkbAction *) &interp->act;
+
+ switch (interp->act.type) {
+ case XkbSA_SetMods:
+ case XkbSA_LatchMods:
+ case XkbSA_LockMods:
+ act->mods.flags = wire.actionData[0];
+ act->mods.mask = wire.actionData[1];
+ act->mods.real_mods = wire.actionData[2];
+ act->mods.vmods1 = wire.actionData[3];
+ act->mods.vmods2 = wire.actionData[4];
+ break;
+ case XkbSA_SetGroup:
+ case XkbSA_LatchGroup:
+ case XkbSA_LockGroup:
+ act->group.flags = wire.actionData[0];
+ act->group.group_XXX = wire.actionData[1];
+ break;
+ case XkbSA_MovePtr:
+ act->ptr.flags = wire.actionData[0];
+ act->ptr.high_XXX = wire.actionData[1];
+ act->ptr.low_XXX = wire.actionData[2];
+ act->ptr.high_YYY = wire.actionData[3];
+ act->ptr.low_YYY = wire.actionData[4];
+ break;
+ case XkbSA_PtrBtn:
+ case XkbSA_LockPtrBtn:
+ act->btn.flags = wire.actionData[0];
+ act->btn.count = wire.actionData[1];
+ act->btn.button = wire.actionData[2];
+ break;
+ case XkbSA_DeviceBtn:
+ case XkbSA_LockDeviceBtn:
+ act->devbtn.flags = wire.actionData[0];
+ act->devbtn.count = wire.actionData[1];
+ act->devbtn.button = wire.actionData[2];
+ act->devbtn.device = wire.actionData[3];
+ break;
+ case XkbSA_SetPtrDflt:
+ act->dflt.flags = wire.actionData[0];
+ act->dflt.affect = wire.actionData[1];
+ act->dflt.valueXXX = wire.actionData[2];
+ break;
+ case XkbSA_ISOLock:
+ act->iso.flags = wire.actionData[0];
+ act->iso.mask = wire.actionData[1];
+ act->iso.real_mods = wire.actionData[2];
+ act->iso.group_XXX = wire.actionData[3];
+ act->iso.affect = wire.actionData[4];
+ act->iso.vmods1 = wire.actionData[5];
+ act->iso.vmods2 = wire.actionData[6];
+ break;
+ case XkbSA_SwitchScreen:
+ act->screen.flags = wire.actionData[0];
+ act->screen.screenXXX = wire.actionData[1];
+ break;
+ case XkbSA_SetControls:
+ case XkbSA_LockControls:
+ act->ctrls.flags = wire.actionData[0];
+ act->ctrls.ctrls3 = wire.actionData[1];
+ act->ctrls.ctrls2 = wire.actionData[2];
+ act->ctrls.ctrls1 = wire.actionData[3];
+ act->ctrls.ctrls0 = wire.actionData[4];
+ break;
+ case XkbSA_RedirectKey:
+ act->redirect.new_key = wire.actionData[0];
+ act->redirect.mods_mask = wire.actionData[1];
+ act->redirect.mods = wire.actionData[2];
+ act->redirect.vmods_mask0 = wire.actionData[3];
+ act->redirect.vmods_mask1 = wire.actionData[4];
+ act->redirect.vmods0 = wire.actionData[4];
+ act->redirect.vmods1 = wire.actionData[5];
+ break;
+ case XkbSA_DeviceValuator:
+ act->devval.device = wire.actionData[0];
+ act->devval.v1_what = wire.actionData[1];
+ act->devval.v1_ndx = wire.actionData[2];
+ act->devval.v1_value = wire.actionData[3];
+ act->devval.v2_what = wire.actionData[4];
+ act->devval.v2_ndx = wire.actionData[5];
+ act->devval.v2_what = wire.actionData[6];
+ break;
+
+ case XkbSA_XFree86Private:
+ /* copy the kind of action */
+ strncpy((char*)act->any.data, (char*)wire.actionData,
+ XkbAnyActionDataSize);
+ break ;
+
+ case XkbSA_Terminate:
+ /* no args, kinda (note: untrue for xfree86). */
+ break;
+ case XkbSA_ActionMessage:
+ /* unsupported. */
+ break;
+ }
+ }
+ if ((num_si>0)&&(changes)) {
+ changes->compat.first_si= 0;
+ changes->compat.num_si= num_si;
+ }
+ if (groups) {
+ register unsigned bit;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ xkmModsDesc md;
+ if (groups&bit) {
+ tmp= fread(&md,SIZEOF(xkmModsDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmModsDesc);
+ xkb->compat->groups[i].real_mods= md.realMods;
+ xkb->compat->groups[i].vmods= md.virtualMods;
+ if (md.virtualMods != 0) {
+ unsigned mask;
+ if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask))
+ xkb->compat->groups[i].mask= md.realMods|mask;
+ }
+ else xkb->compat->groups[i].mask= md.realMods;
+ }
+ }
+ if (changes)
+ changes->compat.changed_groups|= groups;
+ }
+ return nRead;
+}
+
+static int
+ReadXkmIndicators(FILE *file,XkbDescPtr xkb,XkbChangesPtr changes)
+{
+register unsigned nLEDs;
+xkmIndicatorMapDesc wire;
+char buf[100];
+unsigned tmp;
+int nRead=0;
+
+ if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) {
+ _XkbLibError(_XkbErrBadAlloc,"indicator rec",0);
+ return -1;
+ }
+ if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"indicator names",0);
+ return -1;
+ }
+ nLEDs= XkmGetCARD8(file,&nRead);
+ nRead+= XkmSkipPadding(file,3);
+ xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead);
+ while (nLEDs-->0) {
+ Atom name;
+ XkbIndicatorMapPtr map;
+
+ if ((tmp=XkmGetCountedString(file,buf,100))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
+ return -1;
+ }
+ nRead+= tmp;
+ if (buf[0]!='\0')
+ name= XkbInternAtom(buf,FALSE);
+ else name= None;
+ if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
+ return -1;
+ }
+ nRead+= tmp*SIZEOF(xkmIndicatorMapDesc);
+ if (xkb->names) {
+ xkb->names->indicators[wire.indicator-1]= name;
+ if (changes)
+ changes->names.changed_indicators|= (1<<(wire.indicator-1));
+ }
+ map= &xkb->indicators->maps[wire.indicator-1];
+ map->flags= wire.flags;
+ map->which_groups= wire.which_groups;
+ map->groups= wire.groups;
+ map->which_mods= wire.which_mods;
+ map->mods.mask= wire.real_mods;
+ map->mods.real_mods= wire.real_mods;
+ map->mods.vmods= wire.vmods;
+ map->ctrls= wire.ctrls;
+ }
+ return nRead;
+}
+
+static XkbKeyTypePtr
+FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms)
+{
+ if ((!xkb)||(!xkb->map))
+ return NULL;
+ if (name!=None) {
+ register unsigned i;
+ for (i=0;i<xkb->map->num_types;i++) {
+ if (xkb->map->types[i].name==name) {
+ if (xkb->map->types[i].num_levels!=width)
+ DebugF("Group width mismatch between key and type\n");
+ return &xkb->map->types[i];
+ }
+ }
+ }
+ if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol)))
+ return &xkb->map->types[XkbOneLevelIndex];
+ if (syms!=NULL) {
+ if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1]))
+ return &xkb->map->types[XkbAlphabeticIndex];
+ else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1]))
+ return &xkb->map->types[XkbKeypadIndex];
+ }
+ return &xkb->map->types[XkbTwoLevelIndex];
+}
+
+static int
+ReadXkmSymbols(FILE *file,XkbDescPtr xkb)
+{
+register int i,g,s,totalVModMaps;
+xkmKeySymMapDesc wireMap;
+char buf[100];
+unsigned minKC,maxKC,groupNames,tmp;
+int nRead=0;
+
+ if ((tmp=XkmGetCountedString(file,buf,100))<1)
+ return -1;
+ nRead+= tmp;
+ minKC= XkmGetCARD8(file,&nRead);
+ maxKC= XkmGetCARD8(file,&nRead);
+ groupNames= XkmGetCARD8(file,&nRead);
+ totalVModMaps= XkmGetCARD8(file,&nRead);
+ if (XkbAllocNames(xkb,
+ XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask,
+ 0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"physical names",0);
+ return -1;
+ }
+ if ((buf[0]!='\0')&&(xkb->names)) {
+ Atom name;
+ name= XkbInternAtom(buf,0);
+ xkb->names->symbols= name;
+ xkb->names->phys_symbols= name;
+ }
+ for (i=0,g=1;i<XkbNumKbdGroups;i++,g<<=1) {
+ if (groupNames&g) {
+ if ((tmp=XkmGetCountedString(file,buf,100))<1)
+ return -1;
+ nRead+= tmp;
+ if ((buf[0]!='\0')&&(xkb->names)) {
+ Atom name;
+ name= XkbInternAtom(buf,0);
+ xkb->names->groups[i]= name;
+ }
+ else xkb->names->groups[i]= None;
+ }
+ }
+ if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"server map",0);
+ return -1;
+ }
+ if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"client map",0);
+ return -1;
+ }
+ if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"controls",0);
+ return -1;
+ }
+ if ((xkb->map==NULL)||(xkb->server==NULL))
+ return -1;
+ if (xkb->min_key_code<8) xkb->min_key_code= minKC;
+ if (xkb->max_key_code<8) xkb->max_key_code= maxKC;
+ if ((minKC>=8)&&(minKC<xkb->min_key_code))
+ xkb->min_key_code= minKC;
+ if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) {
+ _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC);
+ return -1;
+ }
+ for (i=minKC;i<=(int)maxKC;i++) {
+ Atom typeName[XkbNumKbdGroups];
+ XkbKeyTypePtr type[XkbNumKbdGroups];
+ if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0);
+ return -1;
+ }
+ nRead+= tmp*SIZEOF(xkmKeySymMapDesc);
+ bzero((char *)typeName,XkbNumKbdGroups*sizeof(Atom));
+ bzero((char *)type,XkbNumKbdGroups*sizeof(XkbKeyTypePtr));
+ if (wireMap.flags&XkmKeyHasTypes) {
+ register int g;
+ for (g=0;g<XkbNumKbdGroups;g++) {
+ if ((wireMap.flags&(1<<g))&&
+ ((tmp=XkmGetCountedString(file,buf,100))>0)) {
+ typeName[g]= XkbInternAtom(buf,1);
+ nRead+= tmp;
+ }
+ type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL);
+ if (type[g]==NULL) {
+ _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0);
+ return -1;
+ }
+ if (typeName[g]==type[g]->name)
+ xkb->server->explicit[i]|= (1<<g);
+ }
+ }
+ if (wireMap.flags&XkmRepeatingKey) {
+ xkb->ctrls->per_key_repeat[i/8]|= (1<<(i%8));
+ xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
+ }
+ else if (wireMap.flags&XkmNonRepeatingKey) {
+ xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8));
+ xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
+ }
+ xkb->map->modmap[i]= wireMap.modifier_map;
+ if (XkbNumGroups(wireMap.num_groups)>0) {
+ KeySym *sym;
+ int nSyms;
+
+ if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups)
+ xkb->ctrls->num_groups= wireMap.num_groups;
+ nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width;
+ sym= XkbResizeKeySyms(xkb,i,nSyms);
+ if (!sym)
+ return -1;
+ for (s=0;s<nSyms;s++) {
+ *sym++= XkmGetCARD32(file,&nRead);
+ }
+ if (wireMap.flags&XkmKeyHasActions) {
+ XkbAction * act;
+ act= XkbResizeKeyActions(xkb,i,nSyms);
+ for (s=0;s<nSyms;s++,act++) {
+ tmp=fread(act,SIZEOF(xkmActionDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmActionDesc);
+ }
+ xkb->server->explicit[i]|= XkbExplicitInterpretMask;
+ }
+ }
+ for (g=0;g<XkbNumGroups(wireMap.num_groups);g++) {
+ if (((xkb->server->explicit[i]&(1<<g))==0)||(type[g]==NULL)) {
+ KeySym *tmpSyms;
+ tmpSyms= XkbKeySymsPtr(xkb,i)+(wireMap.width*g);
+ type[g]= FindTypeForKey(xkb,None,wireMap.width,tmpSyms);
+ }
+ xkb->map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]);
+ }
+ xkb->map->key_sym_map[i].group_info= wireMap.num_groups;
+ xkb->map->key_sym_map[i].width= wireMap.width;
+ if (wireMap.flags&XkmKeyHasBehavior) {
+ xkmBehaviorDesc b;
+ tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmBehaviorDesc);
+ xkb->server->behaviors[i].type= b.type;
+ xkb->server->behaviors[i].data= b.data;
+ xkb->server->explicit[i]|= XkbExplicitBehaviorMask;
+ }
+ }
+ if (totalVModMaps>0) {
+ xkmVModMapDesc v;
+ for (i=0;i<totalVModMaps;i++) {
+ tmp= fread(&v,SIZEOF(xkmVModMapDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmVModMapDesc);
+ if (tmp>0)
+ xkb->server->vmodmap[v.key]= v.vmods;
+ }
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeomDoodad(
+ FILE * file,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section)
+{
+XkbDoodadPtr doodad;
+xkmDoodadDesc doodadWire;
+char buf[100];
+unsigned tmp;
+int nRead=0;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file);
+ nRead+= SIZEOF(xkmDoodadDesc)*tmp;
+ doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(buf,FALSE));
+ if (!doodad)
+ return nRead;
+ doodad->any.type= doodadWire.any.type;
+ doodad->any.priority= doodadWire.any.priority;
+ doodad->any.top= doodadWire.any.top;
+ doodad->any.left= doodadWire.any.left;
+ switch (doodadWire.any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ doodad->shape.angle= doodadWire.shape.angle;
+ doodad->shape.color_ndx= doodadWire.shape.color_ndx;
+ doodad->shape.shape_ndx= doodadWire.shape.shape_ndx;
+ break;
+ case XkbTextDoodad:
+ doodad->text.angle= doodadWire.text.angle;
+ doodad->text.width= doodadWire.text.width;
+ doodad->text.height= doodadWire.text.height;
+ doodad->text.color_ndx= doodadWire.text.color_ndx;
+ nRead+= XkmGetCountedString(file,buf,100);
+ doodad->text.text= _XkbDupString(buf);
+ nRead+= XkmGetCountedString(file,buf,100);
+ doodad->text.font= _XkbDupString(buf);
+ break;
+ case XkbIndicatorDoodad:
+ doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx;
+ doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx;
+ doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx;
+ break;
+ case XkbLogoDoodad:
+ doodad->logo.angle= doodadWire.logo.angle;
+ doodad->logo.color_ndx= doodadWire.logo.color_ndx;
+ doodad->logo.shape_ndx= doodadWire.logo.shape_ndx;
+ nRead+= XkmGetCountedString(file,buf,100);
+ doodad->logo.logo_name= _XkbDupString(buf);
+ break;
+ default:
+ /* report error? */
+ return nRead;
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeomOverlay( FILE * file,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section)
+{
+char buf[100];
+unsigned tmp;
+int nRead=0;
+XkbOverlayPtr ol;
+XkbOverlayRowPtr row;
+xkmOverlayDesc olWire;
+xkmOverlayRowDesc rowWire;
+register int r;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOverlayDesc);
+ ol= XkbAddGeomOverlay(section,XkbInternAtom(buf,FALSE),
+ olWire.num_rows);
+ if (!ol)
+ return nRead;
+ for (r=0;r<olWire.num_rows;r++) {
+ int k;
+ xkmOverlayKeyDesc keyWire;
+ tmp= fread(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOverlayRowDesc);
+ row= XkbAddGeomOverlayRow(ol,rowWire.row_under,rowWire.num_keys);
+ if (!row) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomOverlay",0);
+ return nRead;
+ }
+ for (k=0;k<rowWire.num_keys;k++) {
+ tmp= fread(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOverlayKeyDesc);
+ memcpy(row->keys[k].over.name,keyWire.over,XkbKeyNameLength);
+ memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength);
+ }
+ row->num_keys= rowWire.num_keys;
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeomSection( FILE * file,
+ XkbGeometryPtr geom)
+{
+register int i;
+XkbSectionPtr section;
+xkmSectionDesc sectionWire;
+unsigned tmp;
+int nRead= 0;
+char buf[100];
+Atom nameAtom;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ nameAtom= XkbInternAtom(buf,FALSE);
+ tmp= fread(&sectionWire,SIZEOF(xkmSectionDesc),1,file);
+ nRead+= SIZEOF(xkmSectionDesc)*tmp;
+ section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows,
+ sectionWire.num_doodads,
+ sectionWire.num_overlays);
+ if (!section) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
+ return nRead;
+ }
+ section->top= sectionWire.top;
+ section->left= sectionWire.left;
+ section->width= sectionWire.width;
+ section->height= sectionWire.height;
+ section->angle= sectionWire.angle;
+ section->priority= sectionWire.priority;
+ if (sectionWire.num_rows>0) {
+ register int k;
+ XkbRowPtr row;
+ xkmRowDesc rowWire;
+ XkbKeyPtr key;
+ xkmKeyDesc keyWire;
+
+ for (i=0;i<sectionWire.num_rows;i++) {
+ tmp= fread(&rowWire,SIZEOF(xkmRowDesc),1,file);
+ nRead+= SIZEOF(xkmRowDesc)*tmp;
+ row= XkbAddGeomRow(section,rowWire.num_keys);
+ if (!row) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
+ return nRead;
+ }
+ row->top= rowWire.top;
+ row->left= rowWire.left;
+ row->vertical= rowWire.vertical;
+ for (k=0;k<rowWire.num_keys;k++) {
+ tmp= fread(&keyWire,SIZEOF(xkmKeyDesc),1,file);
+ nRead+= SIZEOF(xkmKeyDesc)*tmp;
+ key= XkbAddGeomKey(row);
+ if (!key) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
+ return nRead;
+ }
+ memcpy(key->name.name,keyWire.name,XkbKeyNameLength);
+ key->gap= keyWire.gap;
+ key->shape_ndx= keyWire.shape_ndx;
+ key->color_ndx= keyWire.color_ndx;
+ }
+ }
+ }
+ if (sectionWire.num_doodads>0) {
+ for (i=0;i<sectionWire.num_doodads;i++) {
+ tmp= ReadXkmGeomDoodad(file,geom,section);
+ nRead+= tmp;
+ if (tmp<1)
+ return nRead;
+ }
+ }
+ if (sectionWire.num_overlays>0) {
+ for (i=0;i<sectionWire.num_overlays;i++) {
+ tmp= ReadXkmGeomOverlay(file,geom,section);
+ nRead+= tmp;
+ if (tmp<1)
+ return nRead;
+ }
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeometry(FILE *file,XkbDescPtr xkb)
+{
+register int i;
+char buf[100];
+unsigned tmp;
+int nRead= 0;
+xkmGeometryDesc wireGeom;
+XkbGeometryPtr geom;
+XkbGeometrySizesRec sizes;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ tmp= fread(&wireGeom,SIZEOF(xkmGeometryDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmGeometryDesc);
+ sizes.which= XkbGeomAllMask;
+ sizes.num_properties= wireGeom.num_properties;
+ sizes.num_colors= wireGeom.num_colors;
+ sizes.num_shapes= wireGeom.num_shapes;
+ sizes.num_sections= wireGeom.num_sections;
+ sizes.num_doodads= wireGeom.num_doodads;
+ sizes.num_key_aliases= wireGeom.num_key_aliases;
+ if (XkbAllocGeometry(xkb,&sizes)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ geom= xkb->geom;
+ geom->name= XkbInternAtom(buf,FALSE);
+ geom->width_mm= wireGeom.width_mm;
+ geom->height_mm= wireGeom.height_mm;
+ nRead+= XkmGetCountedString(file,buf,100);
+ geom->label_font= _XkbDupString(buf);
+ if (wireGeom.num_properties>0) {
+ char val[1024];
+ for (i=0;i<wireGeom.num_properties;i++) {
+ nRead+= XkmGetCountedString(file,buf,100);
+ nRead+= XkmGetCountedString(file,val,1024);
+ if (XkbAddGeomProperty(geom,buf,val)==NULL) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ }
+ }
+ if (wireGeom.num_colors>0) {
+ for (i=0;i<wireGeom.num_colors;i++) {
+ nRead+= XkmGetCountedString(file,buf,100);
+ if (XkbAddGeomColor(geom,buf,i)==NULL) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ }
+ }
+ geom->base_color= &geom->colors[wireGeom.base_color_ndx];
+ geom->label_color= &geom->colors[wireGeom.label_color_ndx];
+ if (wireGeom.num_shapes>0) {
+ XkbShapePtr shape;
+ xkmShapeDesc shapeWire;
+ Atom nameAtom;
+ for (i=0;i<wireGeom.num_shapes;i++) {
+ register int n;
+ XkbOutlinePtr ol;
+ xkmOutlineDesc olWire;
+ nRead+= XkmGetCountedString(file,buf,100);
+ nameAtom= XkbInternAtom(buf,FALSE);
+ tmp= fread(&shapeWire,SIZEOF(xkmShapeDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmShapeDesc);
+ shape= XkbAddGeomShape(geom,nameAtom,shapeWire.num_outlines);
+ if (!shape) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ for (n=0;n<shapeWire.num_outlines;n++) {
+ register int p;
+ xkmPointDesc ptWire;
+ tmp= fread(&olWire,SIZEOF(xkmOutlineDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOutlineDesc);
+ ol= XkbAddGeomOutline(shape,olWire.num_points);
+ if (!ol) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ ol->num_points= olWire.num_points;
+ ol->corner_radius= olWire.corner_radius;
+ for (p=0;p<olWire.num_points;p++) {
+ tmp= fread(&ptWire,SIZEOF(xkmPointDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmPointDesc);
+ ol->points[p].x= ptWire.x;
+ ol->points[p].y= ptWire.y;
+ if (ptWire.x<shape->bounds.x1) shape->bounds.x1= ptWire.x;
+ if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x;
+ if (ptWire.y<shape->bounds.y1) shape->bounds.y1= ptWire.y;
+ if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y;
+ }
+ }
+ if (shapeWire.primary_ndx!=XkbNoShape)
+ shape->primary= &shape->outlines[shapeWire.primary_ndx];
+ if (shapeWire.approx_ndx!=XkbNoShape)
+ shape->approx= &shape->outlines[shapeWire.approx_ndx];
+ }
+ }
+ if (wireGeom.num_sections>0) {
+ for (i=0;i<wireGeom.num_sections;i++) {
+ tmp= ReadXkmGeomSection(file,geom);
+ nRead+= tmp;
+ if (tmp==0)
+ return nRead;
+ }
+ }
+ if (wireGeom.num_doodads>0) {
+ for (i=0;i<wireGeom.num_doodads;i++) {
+ tmp= ReadXkmGeomDoodad(file,geom,NULL);
+ nRead+= tmp;
+ if (tmp==0)
+ return nRead;
+ }
+ }
+ if ((wireGeom.num_key_aliases>0)&&(geom->key_aliases)) {
+ int sz= XkbKeyNameLength*2;
+ int num= wireGeom.num_key_aliases;
+ if (fread(geom->key_aliases,sz,num,file)!=num) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0);
+ return -1;
+ }
+ nRead+= (num*sz);
+ geom->num_key_aliases= num;
+ }
+ return nRead;
+}
+
+Bool
+XkmProbe(FILE *file)
+{
+unsigned hdr,tmp;
+int nRead=0;
+
+ hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
+ tmp= XkmGetCARD32(file,&nRead);
+ if (tmp!=hdr) {
+ if ((tmp&(~0xff))==(hdr&(~0xff))) {
+ _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+static Bool
+XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc)
+{
+unsigned hdr,tmp;
+int nRead=0;
+unsigned i,size_toc;
+
+ hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
+ tmp= XkmGetCARD32(file,&nRead);
+ if (tmp!=hdr) {
+ if ((tmp&(~0xff))==(hdr&(~0xff))) {
+ _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff);
+ }
+ else {
+ _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp);
+ }
+ return 0;
+ }
+ fread(file_info,SIZEOF(xkmFileInfo),1,file);
+ size_toc= file_info->num_toc;
+ if (size_toc>max_toc) {
+ DebugF("Warning! Too many TOC entries; last %d ignored\n",
+ size_toc-max_toc);
+ size_toc= max_toc;
+ }
+ for (i=0;i<size_toc;i++) {
+ fread(&toc[i],SIZEOF(xkmSectionInfo),1,file);
+ }
+ return 1;
+}
+
+/***====================================================================***/
+
+#define MAX_TOC 16
+unsigned
+XkmReadFile(FILE *file,unsigned need,unsigned want,XkbDescPtr *xkb)
+{
+register unsigned i;
+xkmSectionInfo toc[MAX_TOC],tmpTOC;
+xkmFileInfo fileInfo;
+unsigned tmp,nRead=0;
+unsigned which= need|want;
+
+ if (!XkmReadTOC(file,&fileInfo,MAX_TOC,toc))
+ return which;
+ if ((fileInfo.present&need)!=need) {
+ _XkbLibError(_XkbErrIllegalContents,"XkmReadFile",
+ need&(~fileInfo.present));
+ return which;
+ }
+ if (*xkb==NULL)
+ *xkb= XkbAllocKeyboard();
+ for (i=0;i<fileInfo.num_toc;i++) {
+ fseek(file,toc[i].offset,SEEK_SET);
+ tmp= fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file);
+ nRead= tmp*SIZEOF(xkmSectionInfo);
+ if ((tmpTOC.type!=toc[i].type)||(tmpTOC.format!=toc[i].format)||
+ (tmpTOC.size!=toc[i].size)||(tmpTOC.offset!=toc[i].offset)) {
+ return which;
+ }
+ if ((which&(1<<tmpTOC.type))==0) {
+ continue;
+ }
+ switch (tmpTOC.type) {
+ case XkmVirtualModsIndex:
+ tmp= ReadXkmVirtualMods(file,*xkb,NULL);
+ break;
+ case XkmTypesIndex:
+ tmp= ReadXkmKeyTypes(file,*xkb,NULL);
+ break;
+ case XkmCompatMapIndex:
+ tmp= ReadXkmCompatMap(file,*xkb,NULL);
+ break;
+ case XkmKeyNamesIndex:
+ tmp= ReadXkmKeycodes(file,*xkb,NULL);
+ break;
+ case XkmIndicatorsIndex:
+ tmp= ReadXkmIndicators(file,*xkb,NULL);
+ break;
+ case XkmSymbolsIndex:
+ tmp= ReadXkmSymbols(file,*xkb);
+ break;
+ case XkmGeometryIndex:
+ tmp= ReadXkmGeometry(file,*xkb);
+ break;
+ default:
+ _XkbLibError(_XkbErrBadImplementation,
+ XkbConfigText(tmpTOC.type,XkbMessage),0);
+ tmp= 0;
+ break;
+ }
+ if (tmp>0) {
+ nRead+= tmp;
+ which&= ~(1<<toc[i].type);
+ (*xkb)->defined|= (1<<toc[i].type);
+ }
+ if (nRead!=tmpTOC.size) {
+ _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage),
+ nRead-tmpTOC.size);
+ }
+ }
+ return which;
+}