diff options
Diffstat (limited to 'nx-X11/programs/Xserver/xkb')
33 files changed, 19575 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/xkb/Imakefile b/nx-X11/programs/Xserver/xkb/Imakefile new file mode 100644 index 000000000..a718545b1 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/Imakefile @@ -0,0 +1,106 @@ +XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ + + + + +XCOMM $XFree86: xc/programs/Xserver/xkb/Imakefile,v 3.21 2002/12/09 23:00:42 dawes Exp $ + +#define SGIHyperOpt +#include <Server.tmpl> + +#ifdef SGIArchitecture +EXTRA_ALLOC_DEFINES = -DFORCE_ALLOCA +#endif + +#if BuildXInputExt +XKBXI_SRCS = xkbPrOtherEv.c +XKBXI_OBJS = xkbPrOtherEv.o +#endif + +#ifdef DfltDisableXKB +XKB_DISABLE = -DXKB_DFLT_DISABLED=1 +#else +XKB_DISABLE = -DXKB_DFLT_DISABLED=0 +#endif + +XKB_DDXDEFS = XkbServerDefines + +#if defined(NXAgentServer) && NXAgentServer +NX_DEFINES = -DNXAGENT_SERVER +#endif + +#if (defined(XF86Server) && XF86Server) || (defined(XorgServer) && XorgServer) +XF86INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) + XF86_OBJS = xf86KillSrv.o xf86VT.o xf86Private.o +#endif + + DDX_SRCS = ddxBeep.c ddxCtrls.c ddxFakeBtn.c ddxFakeMtn.c ddxInit.c \ + ddxKeyClick.c ddxKillSrv.c ddxLEDs.c ddxVT.c ddxLoad.c \ + ddxList.c ddxConfig.c ddxDevBtn.c ddxPrivate.c xkbconfig.c + DDX_OBJS = ddxBeep.o ddxCtrls.o ddxFakeBtn.o ddxFakeMtn.o ddxInit.o \ + ddxKeyClick.o ddxKillSrv.o ddxLEDs.o ddxVT.o ddxLoad.o \ + ddxList.o ddxConfig.o ddxDevBtn.o ddxPrivate.o xkbconfig.o + SRCS = xkb.c xkbUtils.c xkbEvents.c xkbAccessX.c xkbSwap.c \ + xkbLEDs.c xkbInit.c xkbActions.c xkbPrKeyEv.c \ + xkmread.c xkbtext.c xkbfmisc.c xkberrs.c xkbout.c maprules.c \ + XKBMisc.c XKBMAlloc.c XKBAlloc.c XKBGAlloc.c \ + $(XKBXI_SRCS) $(DDX_SRCS) + OBJS = xkb.o xkbUtils.o xkbEvents.o xkbAccessX.o xkbSwap.o \ + xkbLEDs.o xkbInit.o xkbActions.o xkbPrKeyEv.o \ + xkmread.o xkbtext.o xkbfmisc.o xkberrs.o xkbout.o maprules.o \ + XKBMisc.o XKBMAlloc.o XKBAlloc.o XKBGAlloc.o \ + $(XKBXI_OBJS) $(DDX_OBJS) + INCLUDES = -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(SERVERSRC)/Xext \ + -I$(SERVERSRC)/mi $(XF86INCLUDES) + LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln + +DEFINES = -DXKB_IN_SERVER $(EXTRA_ALLOC_DEFINES) $(XKB_DDXDEFS) $(NX_DEFINES) +XKB_DEFINES = -DXKB_BASE_DIRECTORY=\"$(LIBDIR)/xkb\" $(XKB_DISABLE) + +NormalLibraryObjectRule() +NormalLibraryTarget(xkb,$(OBJS)) +LintLibraryTarget(xkb,$(SRCS)) +NormalLintTarget($(SRCS)) + +#if (defined(XF86Server) && XF86Server) || (defined(XorgServer) && XorgServer) +ObjectFromSpecialSource(xf86KillSrv,ddxKillSrv,-DXF86DDXACTIONS) +ObjectFromSpecialSource(xf86VT,ddxVT,-DXF86DDXACTIONS) +ObjectFromSpecialSource(xf86Private,ddxPrivate,-DXF86DDXACTIONS) +AllTarget($(XF86_OBJS)) +#endif + +SpecialCObjectRule(xkbInit,$(ICONFIGFILES),$(XKB_DEFINES)) + +LinkSourceFile(maprules.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkmread.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkbtext.c,$(XKBFILELIBSRC)) +XCOMM avoid clash between XKBMisc.c and xkbmisc.c on NT +LinkFile(xkbfmisc.c,$(XKBFILELIBSRC)/xkbmisc.c) +LinkSourceFile(xkberrs.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkbconfig.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkbout.c,$(XKBFILELIBSRC)) +LinkSourceFile(XKBMisc.c,$(XLIBSRC)) +LinkSourceFile(XKBMAlloc.c,$(XLIBSRC)) +LinkSourceFile(XKBAlloc.c,$(XLIBSRC)) +LinkSourceFile(XKBGAlloc.c,$(XLIBSRC)) + +LinkSourceFile(modinit.h,../Xext/extmod) + +#if BuildLibraries +#if UseConfDirForXkb +LinkConfDirectory(xkb,.,xkb,.) +ODIR = $(CONFDIR) +#else +ODIR = $(LIBDIR) +#endif +#ifdef VarDbDirectory +NDIR = $(VARDBDIR) +#else +NDIR = $(CONFDIR) +#endif +#if !UseConfDirForXkb || defined(VarDbDirectory) +LinkConfDirectoryLong(xkb,xkb,compiled,compiled,$(ODIR),$(NDIR)) +#endif +#endif + +DependTarget() diff --git a/nx-X11/programs/Xserver/xkb/Imakefile.NX.original b/nx-X11/programs/Xserver/xkb/Imakefile.NX.original new file mode 100644 index 000000000..a718545b1 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/Imakefile.NX.original @@ -0,0 +1,106 @@ +XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ + + + + +XCOMM $XFree86: xc/programs/Xserver/xkb/Imakefile,v 3.21 2002/12/09 23:00:42 dawes Exp $ + +#define SGIHyperOpt +#include <Server.tmpl> + +#ifdef SGIArchitecture +EXTRA_ALLOC_DEFINES = -DFORCE_ALLOCA +#endif + +#if BuildXInputExt +XKBXI_SRCS = xkbPrOtherEv.c +XKBXI_OBJS = xkbPrOtherEv.o +#endif + +#ifdef DfltDisableXKB +XKB_DISABLE = -DXKB_DFLT_DISABLED=1 +#else +XKB_DISABLE = -DXKB_DFLT_DISABLED=0 +#endif + +XKB_DDXDEFS = XkbServerDefines + +#if defined(NXAgentServer) && NXAgentServer +NX_DEFINES = -DNXAGENT_SERVER +#endif + +#if (defined(XF86Server) && XF86Server) || (defined(XorgServer) && XorgServer) +XF86INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) + XF86_OBJS = xf86KillSrv.o xf86VT.o xf86Private.o +#endif + + DDX_SRCS = ddxBeep.c ddxCtrls.c ddxFakeBtn.c ddxFakeMtn.c ddxInit.c \ + ddxKeyClick.c ddxKillSrv.c ddxLEDs.c ddxVT.c ddxLoad.c \ + ddxList.c ddxConfig.c ddxDevBtn.c ddxPrivate.c xkbconfig.c + DDX_OBJS = ddxBeep.o ddxCtrls.o ddxFakeBtn.o ddxFakeMtn.o ddxInit.o \ + ddxKeyClick.o ddxKillSrv.o ddxLEDs.o ddxVT.o ddxLoad.o \ + ddxList.o ddxConfig.o ddxDevBtn.o ddxPrivate.o xkbconfig.o + SRCS = xkb.c xkbUtils.c xkbEvents.c xkbAccessX.c xkbSwap.c \ + xkbLEDs.c xkbInit.c xkbActions.c xkbPrKeyEv.c \ + xkmread.c xkbtext.c xkbfmisc.c xkberrs.c xkbout.c maprules.c \ + XKBMisc.c XKBMAlloc.c XKBAlloc.c XKBGAlloc.c \ + $(XKBXI_SRCS) $(DDX_SRCS) + OBJS = xkb.o xkbUtils.o xkbEvents.o xkbAccessX.o xkbSwap.o \ + xkbLEDs.o xkbInit.o xkbActions.o xkbPrKeyEv.o \ + xkmread.o xkbtext.o xkbfmisc.o xkberrs.o xkbout.o maprules.o \ + XKBMisc.o XKBMAlloc.o XKBAlloc.o XKBGAlloc.o \ + $(XKBXI_OBJS) $(DDX_OBJS) + INCLUDES = -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(SERVERSRC)/Xext \ + -I$(SERVERSRC)/mi $(XF86INCLUDES) + LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln + +DEFINES = -DXKB_IN_SERVER $(EXTRA_ALLOC_DEFINES) $(XKB_DDXDEFS) $(NX_DEFINES) +XKB_DEFINES = -DXKB_BASE_DIRECTORY=\"$(LIBDIR)/xkb\" $(XKB_DISABLE) + +NormalLibraryObjectRule() +NormalLibraryTarget(xkb,$(OBJS)) +LintLibraryTarget(xkb,$(SRCS)) +NormalLintTarget($(SRCS)) + +#if (defined(XF86Server) && XF86Server) || (defined(XorgServer) && XorgServer) +ObjectFromSpecialSource(xf86KillSrv,ddxKillSrv,-DXF86DDXACTIONS) +ObjectFromSpecialSource(xf86VT,ddxVT,-DXF86DDXACTIONS) +ObjectFromSpecialSource(xf86Private,ddxPrivate,-DXF86DDXACTIONS) +AllTarget($(XF86_OBJS)) +#endif + +SpecialCObjectRule(xkbInit,$(ICONFIGFILES),$(XKB_DEFINES)) + +LinkSourceFile(maprules.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkmread.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkbtext.c,$(XKBFILELIBSRC)) +XCOMM avoid clash between XKBMisc.c and xkbmisc.c on NT +LinkFile(xkbfmisc.c,$(XKBFILELIBSRC)/xkbmisc.c) +LinkSourceFile(xkberrs.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkbconfig.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkbout.c,$(XKBFILELIBSRC)) +LinkSourceFile(XKBMisc.c,$(XLIBSRC)) +LinkSourceFile(XKBMAlloc.c,$(XLIBSRC)) +LinkSourceFile(XKBAlloc.c,$(XLIBSRC)) +LinkSourceFile(XKBGAlloc.c,$(XLIBSRC)) + +LinkSourceFile(modinit.h,../Xext/extmod) + +#if BuildLibraries +#if UseConfDirForXkb +LinkConfDirectory(xkb,.,xkb,.) +ODIR = $(CONFDIR) +#else +ODIR = $(LIBDIR) +#endif +#ifdef VarDbDirectory +NDIR = $(VARDBDIR) +#else +NDIR = $(CONFDIR) +#endif +#if !UseConfDirForXkb || defined(VarDbDirectory) +LinkConfDirectoryLong(xkb,xkb,compiled,compiled,$(ODIR),$(NDIR)) +#endif +#endif + +DependTarget() diff --git a/nx-X11/programs/Xserver/xkb/Imakefile.X.original b/nx-X11/programs/Xserver/xkb/Imakefile.X.original new file mode 100644 index 000000000..a91f8ff86 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/Imakefile.X.original @@ -0,0 +1,102 @@ +XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ + + + + +XCOMM $XFree86: xc/programs/Xserver/xkb/Imakefile,v 3.21 2002/12/09 23:00:42 dawes Exp $ + +#define SGIHyperOpt +#include <Server.tmpl> + +#ifdef SGIArchitecture +EXTRA_ALLOC_DEFINES = -DFORCE_ALLOCA +#endif + +#if BuildXInputExt +XKBXI_SRCS = xkbPrOtherEv.c +XKBXI_OBJS = xkbPrOtherEv.o +#endif + +#ifdef DfltDisableXKB +XKB_DISABLE = -DXKB_DFLT_DISABLED=1 +#else +XKB_DISABLE = -DXKB_DFLT_DISABLED=0 +#endif + +XKB_DDXDEFS = XkbServerDefines + +#if (defined(XF86Server) && XF86Server) || (defined(XorgServer) && XorgServer) +XF86INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) + XF86_OBJS = xf86KillSrv.o xf86VT.o xf86Private.o +#endif + + DDX_SRCS = ddxBeep.c ddxCtrls.c ddxFakeBtn.c ddxFakeMtn.c ddxInit.c \ + ddxKeyClick.c ddxKillSrv.c ddxLEDs.c ddxVT.c ddxLoad.c \ + ddxList.c ddxConfig.c ddxDevBtn.c ddxPrivate.c xkbconfig.c + DDX_OBJS = ddxBeep.o ddxCtrls.o ddxFakeBtn.o ddxFakeMtn.o ddxInit.o \ + ddxKeyClick.o ddxKillSrv.o ddxLEDs.o ddxVT.o ddxLoad.o \ + ddxList.o ddxConfig.o ddxDevBtn.o ddxPrivate.o xkbconfig.o + SRCS = xkb.c xkbUtils.c xkbEvents.c xkbAccessX.c xkbSwap.c \ + xkbLEDs.c xkbInit.c xkbActions.c xkbPrKeyEv.c \ + xkmread.c xkbtext.c xkbfmisc.c xkberrs.c xkbout.c maprules.c \ + XKBMisc.c XKBMAlloc.c XKBAlloc.c XKBGAlloc.c \ + $(XKBXI_SRCS) $(DDX_SRCS) + OBJS = xkb.o xkbUtils.o xkbEvents.o xkbAccessX.o xkbSwap.o \ + xkbLEDs.o xkbInit.o xkbActions.o xkbPrKeyEv.o \ + xkmread.o xkbtext.o xkbfmisc.o xkberrs.o xkbout.o maprules.o \ + XKBMisc.o XKBMAlloc.o XKBAlloc.o XKBGAlloc.o \ + $(XKBXI_OBJS) $(DDX_OBJS) + INCLUDES = -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(SERVERSRC)/Xext \ + -I$(SERVERSRC)/mi $(XF86INCLUDES) + LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln + +DEFINES = -DXKB_IN_SERVER $(EXTRA_ALLOC_DEFINES) $(XKB_DDXDEFS) +XKB_DEFINES = -DXKB_BASE_DIRECTORY=\"$(LIBDIR)/xkb\" $(XKB_DISABLE) + +NormalLibraryObjectRule() +NormalLibraryTarget(xkb,$(OBJS)) +LintLibraryTarget(xkb,$(SRCS)) +NormalLintTarget($(SRCS)) + +#if (defined(XF86Server) && XF86Server) || (defined(XorgServer) && XorgServer) +ObjectFromSpecialSource(xf86KillSrv,ddxKillSrv,-DXF86DDXACTIONS) +ObjectFromSpecialSource(xf86VT,ddxVT,-DXF86DDXACTIONS) +ObjectFromSpecialSource(xf86Private,ddxPrivate,-DXF86DDXACTIONS) +AllTarget($(XF86_OBJS)) +#endif + +SpecialCObjectRule(xkbInit,$(ICONFIGFILES),$(XKB_DEFINES)) + +LinkSourceFile(maprules.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkmread.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkbtext.c,$(XKBFILELIBSRC)) +XCOMM avoid clash between XKBMisc.c and xkbmisc.c on NT +LinkFile(xkbfmisc.c,$(XKBFILELIBSRC)/xkbmisc.c) +LinkSourceFile(xkberrs.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkbconfig.c,$(XKBFILELIBSRC)) +LinkSourceFile(xkbout.c,$(XKBFILELIBSRC)) +LinkSourceFile(XKBMisc.c,$(XLIBSRC)) +LinkSourceFile(XKBMAlloc.c,$(XLIBSRC)) +LinkSourceFile(XKBAlloc.c,$(XLIBSRC)) +LinkSourceFile(XKBGAlloc.c,$(XLIBSRC)) + +LinkSourceFile(modinit.h,../Xext/extmod) + +#if BuildLibraries +#if UseConfDirForXkb +LinkConfDirectory(xkb,.,xkb,.) +ODIR = $(CONFDIR) +#else +ODIR = $(LIBDIR) +#endif +#ifdef VarDbDirectory +NDIR = $(VARDBDIR) +#else +NDIR = $(CONFDIR) +#endif +#if !UseConfDirForXkb || defined(VarDbDirectory) +LinkConfDirectoryLong(xkb,xkb,compiled,compiled,$(ODIR),$(NDIR)) +#endif +#endif + +DependTarget() diff --git a/nx-X11/programs/Xserver/xkb/ddxBeep.c b/nx-X11/programs/Xserver/xkb/ddxBeep.c new file mode 100644 index 000000000..429d1e778 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxBeep.c @@ -0,0 +1,370 @@ +/* $Xorg: ddxBeep.c,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxBeep.c,v 3.9 2002/12/05 21:59:00 paulo Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> + +#if (defined(__osf__) && defined(__alpha)) +#include <sys/sysinfo.h> +#include <alpha/hal_sysinfo.h> +#include <alpha/prom.h> +#endif + +/*#define FALLING_TONE 1*/ +/*#define RISING_TONE 1*/ +#define FALLING_TONE 10 +#define RISING_TONE 10 +#define SHORT_TONE 50 +#define SHORT_DELAY 60 +#define LONG_TONE 75 +#define VERY_LONG_TONE 100 +#define LONG_DELAY 85 +#define CLICK_DURATION 1 + +#define DEEP_PITCH 250 +#define LOW_PITCH 500 +#define MID_PITCH 1000 +#define HIGH_PITCH 2000 +#define CLICK_PITCH 1500 + +static unsigned long atomGeneration= 0; +static Atom featureOn; +static Atom featureOff; +static Atom featureChange; +static Atom ledOn; +static Atom ledOff; +static Atom ledChange; +static Atom slowWarn; +static Atom slowPress; +static Atom slowReject; +static Atom slowAccept; +static Atom slowRelease; +static Atom stickyLatch; +static Atom stickyLock; +static Atom stickyUnlock; +static Atom bounceReject; +static char doesPitch = 1; + +#define FEATURE_ON "AX_FeatureOn" +#define FEATURE_OFF "AX_FeatureOff" +#define FEATURE_CHANGE "AX_FeatureChange" +#define LED_ON "AX_IndicatorOn" +#define LED_OFF "AX_IndicatorOff" +#define LED_CHANGE "AX_IndicatorChange" +#define SLOW_WARN "AX_SlowKeysWarning" +#define SLOW_PRESS "AX_SlowKeyPress" +#define SLOW_REJECT "AX_SlowKeyReject" +#define SLOW_ACCEPT "AX_SlowKeyAccept" +#define SLOW_RELEASE "AX_SlowKeyRelease" +#define STICKY_LATCH "AX_StickyLatch" +#define STICKY_LOCK "AX_StickyLock" +#define STICKY_UNLOCK "AX_StickyUnlock" +#define BOUNCE_REJECT "AX_BounceKeyReject" + +#define MAKE_ATOM(a) MakeAtom(a,sizeof(a)-1,True) + +static void +_XkbDDXBeepInitAtoms(void) +{ + featureOn= MAKE_ATOM(FEATURE_ON); + featureOff= MAKE_ATOM(FEATURE_OFF); + featureChange= MAKE_ATOM(FEATURE_CHANGE); + ledOn= MAKE_ATOM(LED_ON); + ledOff= MAKE_ATOM(LED_OFF); + ledChange= MAKE_ATOM(LED_CHANGE); + slowWarn= MAKE_ATOM(SLOW_WARN); + slowPress= MAKE_ATOM(SLOW_PRESS); + slowReject= MAKE_ATOM(SLOW_REJECT); + slowAccept= MAKE_ATOM(SLOW_ACCEPT); + slowRelease= MAKE_ATOM(SLOW_RELEASE); + stickyLatch= MAKE_ATOM(STICKY_LATCH); + stickyLock= MAKE_ATOM(STICKY_LOCK); + stickyUnlock= MAKE_ATOM(STICKY_UNLOCK); + bounceReject= MAKE_ATOM(BOUNCE_REJECT); +#if (defined(__osf__) && defined(__alpha)) + /* [[[ WDW - Some bells do not allow for pitch changes. + * Maybe this could become part of the keymap? ]]] + */ + { + char keyboard[8]; + + /* Find the class of keyboard being used. + */ + keyboard[0] = '\0'; + if (-1 == getsysinfo(GSI_KEYBOARD, + keyboard, sizeof(keyboard), + 0, NULL)) + keyboard[0] = '\0'; + + if ((strcmp(keyboard,"LK201") == 0) || + (strcmp(keyboard,"LK401") == 0) || + (strcmp(keyboard,"LK421") == 0) || + (strcmp(keyboard,"LK443") == 0)) + doesPitch = 0; + } +#else +#if defined(sun) + doesPitch = 0; +#endif +#endif + return; +} + +static CARD32 +_XkbDDXBeepExpire(OsTimerPtr timer,CARD32 now,pointer arg) +{ +DeviceIntPtr dev= (DeviceIntPtr)arg; +KbdFeedbackPtr feed; +KeybdCtrl * ctrl; +XkbSrvInfoPtr xkbInfo; +CARD32 next; +int pitch,duration; +int oldPitch,oldDuration; +Atom name; + + if ((dev==NULL)||(dev->key==NULL)||(dev->key->xkbInfo==NULL)|| + (dev->kbdfeed==NULL)) + return 0; + if (atomGeneration!=serverGeneration) { + _XkbDDXBeepInitAtoms(); + atomGeneration= serverGeneration; + } + + feed= dev->kbdfeed; + ctrl= &feed->ctrl; + xkbInfo= dev->key->xkbInfo; + next= 0; + pitch= oldPitch= ctrl->bell_pitch; + duration= oldDuration= ctrl->bell_duration; +#ifdef DEBUG + if (xkbDebugFlags>1) + ErrorF("beep: %d (count= %d)\n",xkbInfo->beepType,xkbInfo->beepCount); +#endif + name= None; + switch (xkbInfo->beepType) { + default: + ErrorF("Unknown beep type %d\n",xkbInfo->beepType); + case _BEEP_NONE: + duration= 0; + break; + + /* When an LED is turned on, we want a high-pitched beep. + * When the LED it turned off, we want a low-pitched beep. + * If we cannot do pitch, we want a single beep for on and two + * beeps for off. + */ + case _BEEP_LED_ON: + if (name==None) name= ledOn; + duration= SHORT_TONE; + pitch= HIGH_PITCH; + break; + case _BEEP_LED_OFF: + if (name==None) name= ledOff; + duration= SHORT_TONE; + pitch= LOW_PITCH; + if (!doesPitch && xkbInfo->beepCount<1) + next = SHORT_DELAY; + break; + + /* When a Feature is turned on, we want an up-siren. + * When a Feature is turned off, we want a down-siren. + * If we cannot do pitch, we want a single beep for on and two + * beeps for off. + */ + case _BEEP_FEATURE_ON: + if (name==None) name= featureOn; + if (xkbInfo->beepCount<1) { + pitch= LOW_PITCH; + duration= VERY_LONG_TONE; + if (doesPitch) + next= SHORT_DELAY; + } + else { + pitch= MID_PITCH; + duration= SHORT_TONE; + } + break; + + case _BEEP_FEATURE_OFF: + if (name==None) name= featureOff; + if (xkbInfo->beepCount<1) { + pitch= MID_PITCH; + if (doesPitch) + duration= VERY_LONG_TONE; + else duration= SHORT_TONE; + next= SHORT_DELAY; + } + else { + pitch= LOW_PITCH; + duration= SHORT_TONE; + } + break; + + /* Two high beeps indicate an LED or Feature changed + * state, but that another LED or Feature is also on. + * [[[WDW - This is not in AccessDOS ]]] + */ + case _BEEP_LED_CHANGE: + if (name==None) name= ledChange; + case _BEEP_FEATURE_CHANGE: + if (name==None) name= featureChange; + duration= SHORT_TONE; + pitch= HIGH_PITCH; + if (xkbInfo->beepCount<1) { + next= SHORT_DELAY; + } + break; + + /* Three high-pitched beeps are the warning that SlowKeys + * is going to be turned on or off. + */ + case _BEEP_SLOW_WARN: + if (name==None) name= slowWarn; + duration= SHORT_TONE; + pitch= HIGH_PITCH; + if (xkbInfo->beepCount<2) + next= SHORT_DELAY; + break; + + /* Click on SlowKeys press and accept. + * Deep pitch when a SlowKey or BounceKey is rejected. + * [[[WDW - Rejects are not in AccessDOS ]]] + * If we cannot do pitch, we want single beeps. + */ + case _BEEP_SLOW_PRESS: + if (name==None) name= slowPress; + case _BEEP_SLOW_ACCEPT: + if (name==None) name= slowAccept; + case _BEEP_SLOW_RELEASE: + if (name==None) name= slowRelease; + duration= CLICK_DURATION; + pitch= CLICK_PITCH; + break; + case _BEEP_BOUNCE_REJECT: + if (name==None) name= bounceReject; + case _BEEP_SLOW_REJECT: + if (name==None) name= slowReject; + duration= SHORT_TONE; + pitch= DEEP_PITCH; + break; + + /* Low followed by high pitch when a StickyKey is latched. + * High pitch when a StickyKey is locked. + * Low pitch when unlocked. + * If we cannot do pitch, two beeps for latch, nothing for + * lock, and two for unlock. + */ + case _BEEP_STICKY_LATCH: + if (name==None) name= stickyLatch; + duration= SHORT_TONE; + if (xkbInfo->beepCount<1) { + next= SHORT_DELAY; + pitch= LOW_PITCH; + } + else pitch= HIGH_PITCH; + break; + case _BEEP_STICKY_LOCK: + if (name==None) name= stickyLock; + if (doesPitch) { + duration= SHORT_TONE; + pitch= HIGH_PITCH; + } + break; + case _BEEP_STICKY_UNLOCK: + if (name==None) name= stickyUnlock; + duration= SHORT_TONE; + pitch= LOW_PITCH; + if (!doesPitch && xkbInfo->beepCount<1) + next = SHORT_DELAY; + break; + } + if (timer == NULL && duration>0) { + CARD32 starttime = GetTimeInMillis(); + CARD32 elapsedtime; + + ctrl->bell_duration= duration; + ctrl->bell_pitch= pitch; + if (xkbInfo->beepCount==0) { + XkbHandleBell(0,0,dev,ctrl->bell,(pointer)ctrl,KbdFeedbackClass,name,None, + NULL); + } + else if (xkbInfo->desc->ctrls->enabled_ctrls&XkbAudibleBellMask) { + (*dev->kbdfeed->BellProc)(ctrl->bell,dev,(pointer)ctrl,KbdFeedbackClass); + } + ctrl->bell_duration= oldDuration; + ctrl->bell_pitch= oldPitch; + xkbInfo->beepCount++; + + /* Some DDX schedule the beep and return immediately, others don't + return until the beep is completed. We measure the time and if + it's less than the beep duration, make sure not to schedule the + next beep until after the current one finishes. */ + + elapsedtime = GetTimeInMillis(); + if (elapsedtime > starttime) { /* watch out for millisecond counter + overflow! */ + elapsedtime -= starttime; + } else { + elapsedtime = 0; + } + if (elapsedtime < duration) { + next += duration - elapsedtime; + } + + } + return next; +} + +int +XkbDDXAccessXBeep(DeviceIntPtr dev,unsigned what,unsigned which) +{ +XkbSrvInfoRec *xkbInfo= dev->key->xkbInfo; +CARD32 next; + + xkbInfo->beepType= what; + xkbInfo->beepCount= 0; + next= _XkbDDXBeepExpire(NULL,0,(pointer)dev); + if (next>0) { + xkbInfo->beepTimer= TimerSet(xkbInfo->beepTimer, + 0, next, + _XkbDDXBeepExpire, (pointer)dev); + } + return 1; +} diff --git a/nx-X11/programs/Xserver/xkb/ddxConfig.c b/nx-X11/programs/Xserver/xkb/ddxConfig.c new file mode 100644 index 000000000..b023531dc --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxConfig.c @@ -0,0 +1,215 @@ +/* $Xorg: ddxConfig.c,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxConfig.c,v 3.8 2002/12/20 20:18:35 paulo Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "os.h" +#define XKBSRV_NEED_FILE_FUNCS +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XKBconfig.h> + +Bool +XkbDDXApplyConfig(XPointer cfg_in,XkbSrvInfoPtr info) +{ +XkbConfigRtrnPtr rtrn; +XkbDescPtr xkb; +Bool ok; +XkbEventCauseRec cause; + + xkb= info->desc; + rtrn= (XkbConfigRtrnPtr)cfg_in; + if (rtrn==NULL) + return True; + ok= XkbCFApplyRtrnValues(rtrn,XkbCFDflts,xkb); + if (rtrn->initial_mods.replace) { + info->state.locked_mods= rtrn->initial_mods.mods; + } + else { + info->state.locked_mods|= rtrn->initial_mods.mods; + if (rtrn->initial_mods.mods_clear) + info->state.locked_mods&= ~rtrn->initial_mods.mods_clear; + } + XkbComputeDerivedState(info); + XkbSetCauseUnknown(&cause); + XkbUpdateIndicators(info->device,XkbAllIndicatorsMask,False,NULL,&cause); + if (info->device && info->device->kbdfeed) { + DeviceIntPtr dev; + KeybdCtrl newCtrl; + dev= info->device; + newCtrl= dev->kbdfeed->ctrl; + if (rtrn->click_volume>=0) + newCtrl.click= rtrn->click_volume; + if (rtrn->bell_volume>=0) + newCtrl.bell= rtrn->bell_volume; + if (rtrn->bell_pitch>0) + newCtrl.bell_pitch= rtrn->bell_pitch; + if (rtrn->bell_duration>0) + newCtrl.bell_duration= rtrn->bell_duration; + if (dev->kbdfeed->CtrlProc) + (*dev->kbdfeed->CtrlProc)(dev,&newCtrl); + } + XkbCFFreeRtrn(rtrn,XkbCFDflts,xkb); + return ok; +} + +XPointer +XkbDDXPreloadConfig( char ** rulesRtrn, + XkbRF_VarDefsPtr defs, + XkbComponentNamesPtr names, + DeviceIntPtr dev) +{ +char buf[PATH_MAX]; +char * dName; +FILE * file; +XkbConfigRtrnPtr rtrn; + +#if defined(MetroLink) + if (dev && dev->name) + dName= dev->name; + else dName= ""; + /* It doesn't appear that XkbBaseDirectory could ever get set to NULL */ + sprintf(buf,"%s/X%s-config%s%s",XkbBaseDirectory,display, + (dName[0]?".":""),dName); +#else + if (dev && dev->name) + dName= dev->name; + else dName= ""; + if (XkbBaseDirectory!=NULL) { + if (strlen(XkbBaseDirectory)+strlen(display) + +strlen(dName)+10+(dName[0]?1:0) > PATH_MAX) + { +#ifdef DEBUG + ErrorF("path exceeds max length\n"); +#endif + return NULL; + } + sprintf(buf,"%s/X%s-config%s%s",XkbBaseDirectory,display, + (dName[0]?".":""),dName); + } + else { + if (strlen(display)+strlen(dName)+10+(dName[0]?1:0) > PATH_MAX) + { +#ifdef DEBUG + ErrorF("path exceeds max length\n"); +#endif + return NULL; + } + sprintf(buf,"X%s-config%s%s",display,(dName[0]?".":""),dName); + } +#endif +#ifdef __UNIXOS2__ + strcpy(buf,(char*)__XOS2RedirRoot(buf)); +#endif +#ifdef DEBUG + ErrorF("Looking for keyboard configuration in %s...",buf); +#endif + file= fopen(buf,"r"); + if (file==NULL) { +#ifdef DEBUG + ErrorF("file not found\n"); +#endif + return NULL; + } + rtrn= _XkbTypedCalloc(1,XkbConfigRtrnRec); + if (rtrn!=NULL) { + if (!XkbCFParse(file,XkbCFDflts,NULL,rtrn)) { +#ifdef DEBUG + ErrorF("error\n"); +#endif + ErrorF("Error parsing config file: "); + XkbCFReportError(stderr,buf,rtrn->error,rtrn->line); + _XkbFree(rtrn); + fclose(file); + return NULL; + } +#ifdef DEBUG + ErrorF("found it\n"); +#endif + if (rtrn->rules_file) { + *rulesRtrn= rtrn->rules_file; + rtrn->rules_file= NULL; + } + if (rtrn->model) { + defs->model= rtrn->model; + rtrn->model= NULL; + } + if (rtrn->layout) { + defs->layout= rtrn->layout; + rtrn->layout= NULL; + } + if (rtrn->variant) { + defs->variant= rtrn->variant; + rtrn->variant= NULL; + } + if (rtrn->options) { + defs->options= rtrn->options; + rtrn->options= NULL; + } + XkbSetRulesUsed(defs); + + if (rtrn->keycodes!=NULL) { + if (names->keycodes) _XkbFree(names->keycodes); + names->keycodes= rtrn->keycodes; + rtrn->keycodes= NULL; + } + if (rtrn->geometry!=NULL) { + if (names->geometry) _XkbFree(names->geometry); + names->geometry= rtrn->geometry; + rtrn->geometry= NULL; + } + if (rtrn->symbols!=NULL) { + if (rtrn->phys_symbols==NULL) + rtrn->phys_symbols= _XkbDupString(names->symbols); + if (names->symbols) _XkbFree(names->symbols); + names->symbols= rtrn->symbols; + rtrn->symbols= NULL; + } + if (rtrn->types!=NULL) { + if (names->types) _XkbFree(names->types); + names->types= rtrn->types; + rtrn->types= NULL; + } + if (rtrn->compat!=NULL) { + if (names->compat) _XkbFree(names->compat); + names->compat= rtrn->compat; + rtrn->compat= NULL; + } + } + fclose(file); + return (XPointer)rtrn; +} diff --git a/nx-X11/programs/Xserver/xkb/ddxCtrls.c b/nx-X11/programs/Xserver/xkb/ddxCtrls.c new file mode 100644 index 000000000..2e4e106ce --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxCtrls.c @@ -0,0 +1,131 @@ +/* $Xorg: ddxCtrls.c,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxCtrls.c,v 1.3 2001/01/17 22:37:14 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> + +void +XkbDDXKeybdCtrlProc(DeviceIntPtr dev,KeybdCtrl *ctrl) +{ +int realRepeat; + + realRepeat= ctrl->autoRepeat; + if ((dev->kbdfeed)&&(XkbDDXUsesSoftRepeat(dev))) + ctrl->autoRepeat= 0; +#ifdef DEBUG +if (xkbDebugFlags&0x4) { + ErrorF("XkbDDXKeybdCtrlProc: setting repeat to %d (real repeat is %d)\n", + ctrl->autoRepeat,realRepeat); +} +#endif + if (dev->key && dev->key->xkbInfo && dev->key->xkbInfo->kbdProc) + (*dev->key->xkbInfo->kbdProc)(dev,ctrl); + ctrl->autoRepeat= realRepeat; + return; +} + + +int +XkbDDXUsesSoftRepeat(DeviceIntPtr pXDev) +{ +#ifndef XKB_ALWAYS_USES_SOFT_REPEAT + if (pXDev && pXDev->kbdfeed ) { + if (pXDev->kbdfeed->ctrl.autoRepeat) { + if (pXDev->key && pXDev->key->xkbInfo) { + XkbDescPtr xkb; + xkb= pXDev->key->xkbInfo->desc; + if ((xkb->ctrls->repeat_delay == 660) && + (xkb->ctrls->repeat_interval == 40) && + ((xkb->ctrls->enabled_ctrls&(XkbSlowKeysMask| + XkbBounceKeysMask| + XkbMouseKeysMask))==0)) { + return 0; + } + return ((xkb->ctrls->enabled_ctrls&XkbRepeatKeysMask)!=0); + } + } + } + return 0; +#else + return 1; +#endif +} + +void +XkbDDXChangeControls(DeviceIntPtr dev,XkbControlsPtr old,XkbControlsPtr new) +{ +unsigned changed, i; +unsigned char *rep_old, *rep_new, *rep_fb; + + changed= new->enabled_ctrls^old->enabled_ctrls; +#ifdef NOTDEF + if (changed&XkbRepeatKeysMask) { + if (dev->kbdfeed) { + int realRepeat; + + if (new->enabled_ctrls&XkbRepeatKeysMask) + dev->kbdfeed->ctrl.autoRepeat= realRepeat= 1; + else dev->kbdfeed->ctrl.autoRepeat= realRepeat= 0; + + if (XkbDDXUsesSoftRepeat(dev)) + dev->kbdfeed->ctrl.autoRepeat= FALSE; + if (dev->kbdfeed->CtrlProc) + (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl); + dev->kbdfeed->ctrl.autoRepeat= realRepeat; + } + } +#endif + for (rep_old = old->per_key_repeat, + rep_new = new->per_key_repeat, + rep_fb = dev->kbdfeed->ctrl.autoRepeats, + i = 0; i < XkbPerKeyBitArraySize; i++) { + if (rep_old[i] != rep_new[i]) { + rep_fb[i] = rep_new[i]; + changed &= XkbPerKeyRepeatMask; + } + } + + if (changed&XkbPerKeyRepeatMask) { + if (dev->kbdfeed->CtrlProc) + (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl); + } + return; +} + diff --git a/nx-X11/programs/Xserver/xkb/ddxDevBtn.c b/nx-X11/programs/Xserver/xkb/ddxDevBtn.c new file mode 100644 index 000000000..d0e37f263 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxDevBtn.c @@ -0,0 +1,102 @@ +/* $Xorg: ddxDevBtn.c,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxDevBtn.c,v 3.3 2001/08/23 21:49:51 tsi Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> + +extern int DeviceValuator; + +void +XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button) +{ +int * devVal; +INT32 * evVal; +xEvent events[2]; +deviceKeyButtonPointer *btn; +deviceValuator * val; +int x,y; +int nAxes, i, count; + + if ((dev==(DeviceIntPtr)LookupPointerDevice())||(!dev->public.on)) + return; + + nAxes = (dev->valuator?dev->valuator->numAxes:0); + if (nAxes > 6) + nAxes = 6; + + GetSpritePosition(&x,&y); + btn= (deviceKeyButtonPointer *) &events[0]; + val= (deviceValuator *) &events[1]; + if (press) btn->type= DeviceButtonPress; + else btn->type= DeviceButtonRelease; + btn->detail= button; + btn->time= GetTimeInMillis(); + btn->root_x= x; + btn->root_y= y; + btn->deviceid= dev->id; + count= 1; + if (nAxes>0) { + btn->deviceid|= 0x80; + val->type = DeviceValuator; + val->deviceid = dev->id; + val->first_valuator = 0; + + evVal= &val->valuator0; + devVal= dev->valuator->axisVal; + for (i=nAxes;i>0;i--) { + *evVal++ = *devVal++; + if (evVal > &val->valuator5) { + int tmp = val->first_valuator+6; + val->num_valuators = 6; + val++; + evVal= &val->valuator0; + val->first_valuator= tmp; + } + } + if ((nAxes % 6) != 0) { + val->num_valuators = (nAxes % 6); + } + count= 1+((nAxes+5)/6); + } + + (*dev->public.processInputProc)((xEventPtr)btn, dev, count); + return; +} diff --git a/nx-X11/programs/Xserver/xkb/ddxFakeBtn.c b/nx-X11/programs/Xserver/xkb/ddxFakeBtn.c new file mode 100644 index 000000000..73c8a2415 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxFakeBtn.c @@ -0,0 +1,61 @@ +/* $Xorg: ddxFakeBtn.c,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86$ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> + +void +XkbDDXFakePointerButton(int event,int button) +{ +xEvent ev; +int x,y; +DevicePtr ptr; + + if ((ptr = LookupPointerDevice())==NULL) + return; + GetSpritePosition(&x,&y); + ev.u.u.type = event; + ev.u.u.detail = button; + ev.u.keyButtonPointer.time = GetTimeInMillis(); + ev.u.keyButtonPointer.rootX = x; + ev.u.keyButtonPointer.rootY = y; + (*ptr->processInputProc)( &ev, (DeviceIntPtr)ptr, 1 ); + return; +} diff --git a/nx-X11/programs/Xserver/xkb/ddxFakeMtn.c b/nx-X11/programs/Xserver/xkb/ddxFakeMtn.c new file mode 100644 index 000000000..ffd6f5d79 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxFakeMtn.c @@ -0,0 +1,122 @@ +/* $XdotOrg: xc/programs/Xserver/xkb/ddxFakeMtn.c,v 1.5 2005/07/03 07:02:09 daniels Exp $ */ +/* $Xorg: ddxFakeMtn.c,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxFakeMtn.c,v 1.5 2003/09/13 16:39:01 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif + +#include "mipointer.h" +#include "mipointrst.h" + +void +XkbDDXFakePointerMotion(unsigned flags,int x,int y) +{ +int oldX,oldY; +ScreenPtr pScreen, oldScreen; + + GetSpritePosition(&oldX, &oldY); + pScreen = oldScreen = GetSpriteWindow()->drawable.pScreen; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) { + BoxRec box; + int i; + + if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum], + oldX, oldY, &box)) { + FOR_NSCREENS(i) { + if(i == pScreen->myNum) + continue; + if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], + oldX, oldY, &box)) { + pScreen = screenInfo.screens[i]; + break; + } + } + } + oldScreen = pScreen; + + if (flags&XkbSA_MoveAbsoluteX) + oldX= x; + else oldX+= x; + if (flags&XkbSA_MoveAbsoluteY) + oldY= y; + else oldY+= y; + + if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum], + oldX, oldY, &box)) { + FOR_NSCREENS(i) { + if(i == pScreen->myNum) + continue; + if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], + oldX, oldY, &box)) { + pScreen = screenInfo.screens[i]; + break; + } + } + } + oldX -= panoramiXdataPtr[pScreen->myNum].x; + oldY -= panoramiXdataPtr[pScreen->myNum].y; + } + else +#endif + { + if (flags&XkbSA_MoveAbsoluteX) + oldX= x; + else oldX+= x; + if (flags&XkbSA_MoveAbsoluteY) + oldY= y; + else oldY+= y; + +#define GetScreenPrivate(s) ((miPointerScreenPtr) ((s)->devPrivates[miPointerScreenIndex].ptr)) + (*(GetScreenPrivate(oldScreen))->screenFuncs->CursorOffScreen) + (&pScreen, &oldX, &oldY); + } + + if (pScreen != oldScreen) + NewCurrentScreen(pScreen, oldX, oldY); + if (pScreen->SetCursorPosition) + (*pScreen->SetCursorPosition)(pScreen, oldX, oldY, TRUE); +} diff --git a/nx-X11/programs/Xserver/xkb/ddxInit.c b/nx-X11/programs/Xserver/xkb/ddxInit.c new file mode 100644 index 000000000..8b76b7cb1 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxInit.c @@ -0,0 +1,48 @@ +/* $Xorg: ddxInit.c,v 1.3 2000/08/17 19:53:45 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86$ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> + +int +XkbDDXInitDevice(DeviceIntPtr dev) +{ + return 1; +} diff --git a/nx-X11/programs/Xserver/xkb/ddxKeyClick.c b/nx-X11/programs/Xserver/xkb/ddxKeyClick.c new file mode 100644 index 000000000..c940e5321 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxKeyClick.c @@ -0,0 +1,52 @@ +/* $Xorg: ddxKeyClick.c,v 1.3 2000/08/17 19:53:46 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86$ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> + +void +XkbDDXKeyClick(DeviceIntPtr pXDev,int keycode,int synthetic) +{ +#ifdef DEBUG + if (xkbDebugFlags) + ErrorF("Click.\n"); +#endif + return; +} diff --git a/nx-X11/programs/Xserver/xkb/ddxKillSrv.c b/nx-X11/programs/Xserver/xkb/ddxKillSrv.c new file mode 100644 index 000000000..ee0acb028 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxKillSrv.c @@ -0,0 +1,61 @@ +/* $Xorg: ddxKillSrv.c,v 1.3 2000/08/17 19:53:46 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxKillSrv.c,v 1.3 2002/11/23 19:27:50 tsi Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> + +#ifdef XF86DDXACTIONS +#include "xf86.h" +#endif + +int +XkbDDXTerminateServer(DeviceIntPtr dev,KeyCode key,XkbAction *act) +{ +#ifdef XF86DDXACTIONS + xf86ProcessActionEvent(ACTION_TERMINATE, NULL); +#else + GiveUp(1); +#endif + return 0; +} diff --git a/nx-X11/programs/Xserver/xkb/ddxLEDs.c b/nx-X11/programs/Xserver/xkb/ddxLEDs.c new file mode 100644 index 000000000..fb5f72bf8 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxLEDs.c @@ -0,0 +1,74 @@ +/* $Xorg: ddxLEDs.c,v 1.3 2000/08/17 19:53:46 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86$ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> + +void +XkbDDXUpdateIndicators(DeviceIntPtr dev,CARD32 new) +{ + dev->kbdfeed->ctrl.leds= new; + (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl); + return; +} + +void +XkbDDXUpdateDeviceIndicators( DeviceIntPtr dev, + XkbSrvLedInfoPtr sli, + CARD32 new) +{ + if (sli->fb.kf==dev->kbdfeed) + XkbDDXUpdateIndicators(dev,new); + else if (sli->class==KbdFeedbackClass) { + KbdFeedbackPtr kf; + kf= sli->fb.kf; + if (kf && kf->CtrlProc) { + (*kf->CtrlProc)(dev,&kf->ctrl); + } + } + else if (sli->class==LedFeedbackClass) { + LedFeedbackPtr lf; + lf= sli->fb.lf; + if (lf && lf->CtrlProc) { + (*lf->CtrlProc)(dev,&lf->ctrl); + } + } + return; +} diff --git a/nx-X11/programs/Xserver/xkb/ddxList.c b/nx-X11/programs/Xserver/xkb/ddxList.c new file mode 100644 index 000000000..9c961e934 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxList.c @@ -0,0 +1,304 @@ +/* $Xorg: ddxList.c,v 1.3 2000/08/17 19:53:46 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxList.c,v 3.8 2003/07/16 01:39:05 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#define NEED_EVENTS 1 +#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 <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> + +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif + +#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] = { + "keymap", "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= _XkbTypedRealloc(list->pool,list->szPool,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"); + xfree (buf); + buf = NULL; + } + 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"); + xfree (buf); + buf = NULL; + } + 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 +#ifdef DEBUG_CMD + ErrorF("xkb executes: %s\n",buf); +#endif + if (System(buf) < 0) + ErrorF("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; + 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("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,_XkbListKeymaps,list,client); + if (status==Success) + 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/nx-X11/programs/Xserver/xkb/ddxLoad.c b/nx-X11/programs/Xserver/xkb/ddxLoad.c new file mode 100644 index 000000000..8def401e8 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxLoad.c @@ -0,0 +1,965 @@ +/* $Xorg: ddxLoad.c,v 1.3 2000/08/17 19:53:46 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxLoad.c,v 3.35 2003/10/02 13:30:12 eich Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef HAVE_XKB_CONFIG_H +#include <xkb-config.h> +#endif + +#include <errno.h> +#include <stdio.h> +#include <ctype.h> +#define NEED_EVENTS 1 +#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 <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> +#include "xkb.h" + +#if defined(CSRG_BASED) || defined(linux) || defined(__sgi) || defined(AIXV3) || defined(__osf__) || defined(__GNU__) +#include <paths.h> +#endif + +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#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(__UNIXOS2__) || 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("Starting '%s' failed!\n", cmdline); + } + else + { + ErrorF("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 + +#ifdef MAKE_XKM_OUTPUT_DIR +/* Borrow trans_mkdir from Xtransutil.c to more safely make directories */ +# undef X11_t +# define TRANS_SERVER +# define PRMSG(lvl,x,a,b,c) \ + if (lvl <= 1) { LogMessage(X_ERROR,x,a,b,c); } else ((void)0) +# include <X11/Xtrans/Xtransutil.c> +# ifndef XKM_OUTPUT_DIR_MODE +# define XKM_OUTPUT_DIR_MODE 0755 +# endif +#endif + +#ifdef NXAGENT_SERVER + +#define NX_XKB_BASE_DIRECTORY "/usr/lib/X11/xkb" +#define NX_XKB_ALTERNATE_BASE_DIRECTORY "/usr/share/X11/xkb" +#define NX_KEYMAP_DIR_FILE "keymap.dir" +#define NX_ALT_XKBCOMP_PATH "/usr/bin" + +static char _NXXkbBasePath[PATH_MAX]; +static char _NXXkbCompPath[PATH_MAX]; + +static int NXVerifyXkbBaseDirectory(const char *dirPath) +{ + int size; + char *keymapDirFilePath; + struct stat keymapDirFileStat; + + /* + * If keymap.dir file + * is not present into + * Xkb Base Directory, + * we suppose that the + * path is not valid. + */ + + size = strlen(dirPath) + strlen("/") + + strlen(NX_KEYMAP_DIR_FILE) + 1; + + if ((keymapDirFilePath = malloc((size + 1) * sizeof(char))) == NULL) + { + FatalError("NXVerifyXkbBaseDirectory: malloc failed.\n"); + } + + strcpy(keymapDirFilePath, dirPath); + strcat(keymapDirFilePath, "/"); + strcat(keymapDirFilePath, NX_KEYMAP_DIR_FILE); + + #ifdef TEST + fprintf(stderr, "NXVerifyXkbBaseDirectory: Looking for [%s] file.\n", + keymapDirFilePath); + #endif + + if (stat(keymapDirFilePath, &keymapDirFileStat) != 0) + { + + #ifdef TEST + fprintf(stderr, "NXVerifyXkbBaseDirectory: Can't find the keymap.dir file [%s].\n", + keymapDirFilePath); + #endif + + free(keymapDirFilePath); + + return 0; + } + + #ifdef TEST + fprintf(stderr, "NXVerifyXkbBaseDirectory: Xkb Base Directory [%s] is valid.\n", + dirPath); + #endif + + free(keymapDirFilePath); + + return 1; +} + +/* + * This function returns the directory + * containing the configuration files. + * This directory is referred by Xkb- + * BaseDirectory variable (generally + * it contains the hardcoded path at + * compile time). If the directory + * does not exist, the function will + * try a set of well known directories. + */ + +char *_NXGetXkbBasePath(const char *path) +{ + /* + * Check the xkb base directory only once. + */ + + if (*_NXXkbBasePath != '\0') + { + return _NXXkbBasePath; + } + + if (NXVerifyXkbBaseDirectory(XkbBaseDirectory) == 1) + { + if (strlen(XkbBaseDirectory) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n"); + #endif + + goto _NXGetXkbBasePathError; + } + + strcpy(_NXXkbBasePath, XkbBaseDirectory); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n", + _NXXkbBasePath); + #endif + + return _NXXkbBasePath; + } + + if (NXVerifyXkbBaseDirectory(NX_XKB_BASE_DIRECTORY) == 1) + { + if (strlen(NX_XKB_BASE_DIRECTORY) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n"); + #endif + + goto _NXGetXkbBasePathError; + } + + strcpy(_NXXkbBasePath, NX_XKB_BASE_DIRECTORY); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n", + _NXXkbBasePath); + #endif + + return _NXXkbBasePath; + } + + if (NXVerifyXkbBaseDirectory(NX_XKB_ALTERNATE_BASE_DIRECTORY) == 1) + { + if (strlen(NX_XKB_ALTERNATE_BASE_DIRECTORY) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n"); + #endif + + goto _NXGetXkbBasePathError; + } + + strcpy(_NXXkbBasePath, NX_XKB_ALTERNATE_BASE_DIRECTORY); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n", + _NXXkbBasePath); + #endif + + return _NXXkbBasePath; + } + +_NXGetXkbBasePathError: + + if (strlen(path) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n"); + #endif + } + + strcpy(_NXXkbBasePath, path); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: Using default xkb base path [%s].\n", + _NXXkbBasePath); + #endif + + return _NXXkbBasePath; +} + +static int NXVerifyXkbCompPath(char *path) +{ + char *xkbCompPath; + int xkbCompPathSize; + struct stat xkbCompPathStat; + + if (path == NULL) + { + return 0; + } + + xkbCompPathSize = strlen(path) + strlen("/") + + strlen("xkbcomp") + 1; + + if ((xkbCompPath = malloc((xkbCompPathSize + 1) * sizeof(char))) == NULL) + { + FatalError("NXVerifyXkbCompPath: WARNING! malloc failed.\n"); + + return 0; + } + + strcpy(xkbCompPath, path); + strcat(xkbCompPath, "/"); + strcat(xkbCompPath, "xkbcomp"); + + if (stat(xkbCompPath, &xkbCompPathStat) != 0) + { + #ifdef NX_TRANS_TEST + fprintf(stderr, "NXVerifyXkbCompPath: WARNING! Failed to stat xkbcomp path [%s].\n", + xkbCompPath); + #endif + + free(xkbCompPath); + + return 0; + } + + free(xkbCompPath); + + return 1; +} + +/* + * This function returns the directory + * containing the xkbcomp executable. + * The function will first try to locate + * the executable in the hardcoded path + * (the same path as the "base" xkb one) + * and, if the xkbcomp file couldn't be + * found, the function will not include + * an explicit path and will rely on the + * PATH environment to list the directory. + */ + +char *_NXGetXkbCompPath(const char *path) +{ + + char * xkbCompPath; + + /* + * Check the xkbcomp executable + * directory only once. + */ + + if (*_NXXkbCompPath != '\0') + { + return _NXXkbCompPath; + } + + xkbCompPath = _NXGetXkbBasePath(path); + + if (NXVerifyXkbCompPath(xkbCompPath) == 1) + { + if (strlen(xkbCompPath) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n"); + #endif + + goto _NXGetXkbCompPathError; + } + + strcpy(_NXXkbCompPath, xkbCompPath); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: Using xkbcomp path [%s].\n", + _NXXkbCompPath); + #endif + + return _NXXkbCompPath; + } + + xkbCompPath = NX_ALT_XKBCOMP_PATH; + + if (NXVerifyXkbCompPath(xkbCompPath) == 1) + { + if (strlen(xkbCompPath) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n"); + #endif + + goto _NXGetXkbCompPathError; + } + + strcpy(_NXXkbCompPath, xkbCompPath); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: Using NX xkbcomp path [%s].\n", + _NXXkbCompPath); + #endif + + return _NXXkbCompPath; + } + +_NXGetXkbCompPathError: + + if (strlen(path) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n"); + #endif + } + + strcpy(_NXXkbCompPath, path); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: Using default xkbcomp path [%s].\n", + _NXXkbCompPath); + #endif + + return _NXXkbCompPath; +} + +#endif + +static void +OutputDirectory( + char* outdir, + size_t size) +{ +#ifndef WIN32 + if (getuid() == 0 && (strlen(XKM_OUTPUT_DIR) < size) +#ifdef MAKE_XKM_OUTPUT_DIR + && (trans_mkdir(XKM_OUTPUT_DIR, XKM_OUTPUT_DIR_MODE) == 0) +#endif + ) + { + /* if server running as root it *may* be able to write */ + /* FIXME: check whether directory is writable at all */ + (void) strcpy (outdir, XKM_OUTPUT_DIR); + } else +#endif +#ifdef _PATH_VARTMP + if ((strlen(_PATH_VARTMP) + 1) < size) + { + (void) strcpy (outdir, _PATH_VARTMP); + if (outdir[strlen(outdir) - 1] != '/') /* Hi IBM, Digital */ + (void) strcat (outdir, "/"); + } else +#endif +#ifdef WIN32 + if (strlen(Win32TempDir()) + 1 < size) + { + (void) strcpy(outdir, Win32TempDir()); + (void) strcat(outdir, "\\"); + } else +#endif + if (strlen("/tmp/") < size) + { + (void) strcpy (outdir, "/tmp/"); + } +} + +Bool +XkbDDXCompileNamedKeymap( XkbDescPtr xkb, + XkbComponentNamesPtr names, + char * nameRtrn, + int nameRtrnLen) +{ +char *cmd = NULL,file[PATH_MAX],xkm_output_dir[PATH_MAX],*map,*outFile; + + if (names->keymap==NULL) + return False; + strncpy(file,names->keymap,PATH_MAX); file[PATH_MAX-1]= '\0'; + if ((map= strrchr(file,'('))!=NULL) { + char *tmp; + if ((tmp= strrchr(map,')'))!=NULL) { + *map++= '\0'; + *tmp= '\0'; + } + else { + map= NULL; + } + } + if ((outFile= strrchr(file,'/'))!=NULL) + outFile= _XkbDupString(&outFile[1]); + else outFile= _XkbDupString(file); + XkbEnsureSafeMapName(outFile); + OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); + +#ifdef NXAGENT_SERVER + + if (_NXGetXkbCompPath(XkbBaseDirectory) != NULL) + { + +#else + + if (XkbBaseDirectory!=NULL) { + +#endif + +#ifndef __UNIXOS2__ + +#ifdef NXAGENT_SERVER + char *xkbbasedir = _NXGetXkbCompPath(XkbBaseDirectory); + char *xkbbindir = _NXGetXkbCompPath(XkbBinDirectory); +#else + char *xkbbasedir = XkbBaseDirectory; + char *xkbbindir = XkbBinDirectory; +#endif + +#else + /* relocate the basedir and replace the slashes with backslashes */ +#ifdef NXAGENT_SERVER + char *xkbbasedir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBaseDirectory)); + char *xkbbindir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBinDirectory)); +#else + char *xkbbasedir = (char*)__XOS2RedirRoot(XkbBaseDirectory); + char *xkbbindir = (char*)__XOS2RedirRoot(XkbBinDirectory); +#endif + int i; + + for (i=0; i<strlen(xkbbasedir); i++) + if (xkbbasedir[i]=='/') xkbbasedir[i]='\\'; + for (i=0; i<strlen(xkbbindir); i++) + if (xkbbindir[i]=='/') xkbbindir[i]='\\'; +#endif + + cmd = Xprintf("\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"", + xkbbindir, + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + xkbbasedir,(map?"-m ":""),(map?map:""), + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file, + xkm_output_dir,outFile); + } + else { + cmd = Xprintf("xkbcomp -w %d -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"", + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + (map?"-m ":""),(map?map:""), + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file, + xkm_output_dir,outFile); + } +#ifdef DEBUG + if (xkbDebugFlags) { + ErrorF("XkbDDXCompileNamedKeymap compiling keymap using:\n"); + ErrorF(" \"cmd\"\n"); + } +#endif +#ifdef DEBUG_CMD + ErrorF("xkb executes: %s\n",cmd); +#endif + if (System(cmd)==0) { + if (nameRtrn) { + strncpy(nameRtrn,outFile,nameRtrnLen); + nameRtrn[nameRtrnLen-1]= '\0'; + } + if (outFile!=NULL) + _XkbFree(outFile); + if (cmd!=NULL) + xfree(cmd); + return True; + } +#ifdef DEBUG + ErrorF("Error compiling keymap (%s)\n",names->keymap); +#endif + if (outFile!=NULL) + _XkbFree(outFile); + if (cmd!=NULL) + xfree(cmd); + return False; +} + +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]; + +#ifdef WIN32 +char tmpname[PATH_MAX]; +#endif + if ((names->keymap==NULL)||(names->keymap[0]=='\0')) { + sprintf(keymap,"server-%s",display); + } + else { + if (strlen(names->keymap) > PATH_MAX - 1) { + ErrorF("name of keymap (%s) exceeds max length\n", names->keymap); + return False; + } + strcpy(keymap,names->keymap); + } + + XkbEnsureSafeMapName(keymap); + OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); +#ifdef WIN32 + strcpy(tmpname, Win32TempDir()); + strcat(tmpname, "\\xkb_XXXXXX"); + (void) mktemp(tmpname); +#endif + +#ifdef NXAGENT_SERVER + if (_NXGetXkbCompPath(XkbBaseDirectory)!=NULL) { +#else + if (XkbBaseDirectory!=NULL) { +#endif + +#ifndef WIN32 + char *xkmfile = "-"; +#else + /* 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 *xkmfile = tmpname; +#endif +#ifndef __UNIXOS2__ +#ifdef NXAGENT_SERVER + char *xkbbasedir = _NXGetXkbCompPath(XkbBaseDirectory); + char *xkbbindir = _NXGetXkbCompPath(XkbBinDirectory); +#else + char *xkbbasedir = XkbBaseDirectory; + char *xkbbindir = XkbBinDirectory; +#endif +#else + int i; +#ifdef NXAGENT_SERVER + char *xkbbasedir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBaseDirectory)); + char *xkbbindir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBinDirectory)); +#else + char *xkbbasedir = (char*)__XOS2RedirRoot(XkbBaseDirectory); + char *xkbbindir = (char*)__XOS2RedirRoot(XkbBinDirectory); +#endif + for (i=0; i<strlen(xkbbasedir); i++) + if (xkbbasedir[i]=='/') xkbbasedir[i]='\\'; + for (i=0; i<strlen(xkbbindir); i++) + if (xkbbindir[i]=='/') xkbbindir[i]='\\'; +#endif + + buf = Xprintf( + "\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm \"%s\" -em1 %s -emp %s -eml %s \"%s%s.xkm\"", + xkbbindir, + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + xkbbasedir, xkmfile, + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1, + xkm_output_dir,keymap); + } + else { +#ifndef WIN32 + char *xkmfile = "-"; +#else + char *xkmfile = tmpname; +#endif + buf = Xprintf( + "xkbcomp -w %d -xkm \"%s\" -em1 %s -emp %s -eml %s \"%s%s.xkm\"", + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + xkmfile, + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1, + xkm_output_dir,keymap); + } + + #ifdef TEST + fprintf(stderr, "XkbDDXCompileKeymapByNames: Executing command [%s].\n", buf); + #endif + +#ifndef WIN32 + out= Popen(buf,"w"); +#else + out= fopen(tmpname, "w"); +#endif + + if (out!=NULL) { +#ifdef DEBUG + if (xkbDebugFlags) { + ErrorF("XkbDDXCompileKeymapByNames compiling keymap:\n"); + XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need); + } +#endif + XkbWriteXKBKeymapForNames(out,names,NULL,xkb,want,need); +#ifndef WIN32 +#ifdef __sun + if (Pclose(out) != 0) + { + ErrorF("Warning: Spurious failure reported in Pclose() runnning 'xkbcomp'.\n"); + } + if (1) +#else + if (Pclose(out)==0) +#endif +#else + if (fclose(out)==0 && System(buf) >= 0) +#endif + { +#ifdef DEBUG_CMD + ErrorF("xkb executes: %s\n",buf); + ErrorF("xkbcomp input:\n"); + XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need); + ErrorF("end xkbcomp input\n"); +#endif + if (nameRtrn) { + strncpy(nameRtrn,keymap,nameRtrnLen); + nameRtrn[nameRtrnLen-1]= '\0'; + } +#if defined(Lynx) && defined(__i386__) && defined(NEED_POPEN_WORKAROUND) + /* somehow popen/pclose is broken on LynxOS AT 2.3.0/2.4.0! + * the problem usually shows up with XF86Setup + * this hack waits at max 5 seconds after pclose() returns + * for the output of the xkbcomp output file. + * I didn't manage to get a patch in time for the 3.2 release + */ + { + int i; + char name[PATH_MAX]; +#ifdef NXAGENT_SERVER + if (_NXGetXkbCompPath(XkbBaseDirectory)!=NULL) + sprintf(name,"%s/%s%s.xkm", _NXGetXkbCompPath(XkbBaseDirectory) + ,xkm_output_dir, keymap); +#else + if (XkbBaseDirectory!=NULL) + sprintf(name,"%s/%s%s.xkm", XkbBaseDirectory + ,xkm_output_dir, keymap); +#endif + else + sprintf(name,"%s%s.xkm", xkm_output_dir, keymap); + for (i = 0; i < 10; i++) { + if (access(name, 0) == 0) break; + usleep(500000); + } +#ifdef DEBUG + if (i) ErrorF(">>>> Waited %d times for %s\n", i, name); +#endif + } +#endif + if (buf != NULL) + xfree (buf); + return True; + } +#ifdef DEBUG + else + ErrorF("Error compiling keymap (%s)\n",keymap); +#endif +#ifdef WIN32 + /* remove the temporary file */ + unlink(tmpname); +#endif + } +#ifdef DEBUG + else { +#ifndef WIN32 + ErrorF("Could not invoke keymap compiler\n"); +#else + ErrorF("Could not open file %s\n", tmpname); +#endif + } +#endif + if (nameRtrn) + nameRtrn[0]= '\0'; + if (buf != NULL) + xfree (buf); + return False; +} + +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, + XkbFileInfo * finfoRtrn, + char * nameRtrn, + int nameRtrnLen) +{ +XkbDescPtr xkb; +FILE * file; +char fileName[PATH_MAX]; +unsigned missing; + + bzero(finfoRtrn,sizeof(XkbFileInfo)); + 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)) { + if (names->keymap==NULL) { + bzero(finfoRtrn,sizeof(XkbFileInfo)); + if (xkb && XkbDetermineFileType(finfoRtrn,XkbXKMFile,NULL) && + ((finfoRtrn->defined&need)==need) ) { + finfoRtrn->xkb= xkb; + nameRtrn[0]= '\0'; + return finfoRtrn->defined; + } + return 0; + } + else if (!XkbDDXCompileNamedKeymap(xkb,names,nameRtrn,nameRtrnLen)) { +#ifdef NOISY + ErrorF("Couldn't compile keymap file\n"); +#endif + return 0; + } + } + else if (!XkbDDXCompileKeymapByNames(xkb,names,want,need, + nameRtrn,nameRtrnLen)){ +#ifdef NOISY + ErrorF("Couldn't compile keymap file\n"); +#endif + 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,finfoRtrn); + if (finfoRtrn->xkb==NULL) { + LogMessage(X_ERROR, "Error loading keymap %s\n",fileName); + fclose(file); + (void) unlink (fileName); + return 0; + } +#ifdef DEBUG + else if (xkbDebugFlags) { + ErrorF("Loaded %s, defined=0x%x\n",fileName,finfoRtrn->defined); + } +#endif + 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 (XkbBaseDirectory==NULL) { + if (strlen(rules_name)+7 > PATH_MAX) + return False; + sprintf(buf,"rules/%s",rules_name); + } + else { + if (strlen(XkbBaseDirectory)+strlen(rules_name)+8 > PATH_MAX) + return False; + sprintf(buf,"%s/rules/%s",XkbBaseDirectory,rules_name); + } + if ((file= fopen(buf,"r"))==NULL) + return False; + if ((rules= XkbRF_Create(0,0))==NULL) { + fclose(file); + return False; + } + if (!XkbRF_LoadRules(file,rules)) { + fclose(file); + XkbRF_Free(rules,True); + return False; + } + bzero((char *)names,sizeof(XkbComponentNamesRec)); + complete= XkbRF_GetComponents(rules,defs,names); + fclose(file); + XkbRF_Free(rules,True); + return complete; +} + + diff --git a/nx-X11/programs/Xserver/xkb/ddxLoad.c.NX.original b/nx-X11/programs/Xserver/xkb/ddxLoad.c.NX.original new file mode 100644 index 000000000..8def401e8 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxLoad.c.NX.original @@ -0,0 +1,965 @@ +/* $Xorg: ddxLoad.c,v 1.3 2000/08/17 19:53:46 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxLoad.c,v 3.35 2003/10/02 13:30:12 eich Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef HAVE_XKB_CONFIG_H +#include <xkb-config.h> +#endif + +#include <errno.h> +#include <stdio.h> +#include <ctype.h> +#define NEED_EVENTS 1 +#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 <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> +#include "xkb.h" + +#if defined(CSRG_BASED) || defined(linux) || defined(__sgi) || defined(AIXV3) || defined(__osf__) || defined(__GNU__) +#include <paths.h> +#endif + +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#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(__UNIXOS2__) || 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("Starting '%s' failed!\n", cmdline); + } + else + { + ErrorF("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 + +#ifdef MAKE_XKM_OUTPUT_DIR +/* Borrow trans_mkdir from Xtransutil.c to more safely make directories */ +# undef X11_t +# define TRANS_SERVER +# define PRMSG(lvl,x,a,b,c) \ + if (lvl <= 1) { LogMessage(X_ERROR,x,a,b,c); } else ((void)0) +# include <X11/Xtrans/Xtransutil.c> +# ifndef XKM_OUTPUT_DIR_MODE +# define XKM_OUTPUT_DIR_MODE 0755 +# endif +#endif + +#ifdef NXAGENT_SERVER + +#define NX_XKB_BASE_DIRECTORY "/usr/lib/X11/xkb" +#define NX_XKB_ALTERNATE_BASE_DIRECTORY "/usr/share/X11/xkb" +#define NX_KEYMAP_DIR_FILE "keymap.dir" +#define NX_ALT_XKBCOMP_PATH "/usr/bin" + +static char _NXXkbBasePath[PATH_MAX]; +static char _NXXkbCompPath[PATH_MAX]; + +static int NXVerifyXkbBaseDirectory(const char *dirPath) +{ + int size; + char *keymapDirFilePath; + struct stat keymapDirFileStat; + + /* + * If keymap.dir file + * is not present into + * Xkb Base Directory, + * we suppose that the + * path is not valid. + */ + + size = strlen(dirPath) + strlen("/") + + strlen(NX_KEYMAP_DIR_FILE) + 1; + + if ((keymapDirFilePath = malloc((size + 1) * sizeof(char))) == NULL) + { + FatalError("NXVerifyXkbBaseDirectory: malloc failed.\n"); + } + + strcpy(keymapDirFilePath, dirPath); + strcat(keymapDirFilePath, "/"); + strcat(keymapDirFilePath, NX_KEYMAP_DIR_FILE); + + #ifdef TEST + fprintf(stderr, "NXVerifyXkbBaseDirectory: Looking for [%s] file.\n", + keymapDirFilePath); + #endif + + if (stat(keymapDirFilePath, &keymapDirFileStat) != 0) + { + + #ifdef TEST + fprintf(stderr, "NXVerifyXkbBaseDirectory: Can't find the keymap.dir file [%s].\n", + keymapDirFilePath); + #endif + + free(keymapDirFilePath); + + return 0; + } + + #ifdef TEST + fprintf(stderr, "NXVerifyXkbBaseDirectory: Xkb Base Directory [%s] is valid.\n", + dirPath); + #endif + + free(keymapDirFilePath); + + return 1; +} + +/* + * This function returns the directory + * containing the configuration files. + * This directory is referred by Xkb- + * BaseDirectory variable (generally + * it contains the hardcoded path at + * compile time). If the directory + * does not exist, the function will + * try a set of well known directories. + */ + +char *_NXGetXkbBasePath(const char *path) +{ + /* + * Check the xkb base directory only once. + */ + + if (*_NXXkbBasePath != '\0') + { + return _NXXkbBasePath; + } + + if (NXVerifyXkbBaseDirectory(XkbBaseDirectory) == 1) + { + if (strlen(XkbBaseDirectory) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n"); + #endif + + goto _NXGetXkbBasePathError; + } + + strcpy(_NXXkbBasePath, XkbBaseDirectory); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n", + _NXXkbBasePath); + #endif + + return _NXXkbBasePath; + } + + if (NXVerifyXkbBaseDirectory(NX_XKB_BASE_DIRECTORY) == 1) + { + if (strlen(NX_XKB_BASE_DIRECTORY) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n"); + #endif + + goto _NXGetXkbBasePathError; + } + + strcpy(_NXXkbBasePath, NX_XKB_BASE_DIRECTORY); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n", + _NXXkbBasePath); + #endif + + return _NXXkbBasePath; + } + + if (NXVerifyXkbBaseDirectory(NX_XKB_ALTERNATE_BASE_DIRECTORY) == 1) + { + if (strlen(NX_XKB_ALTERNATE_BASE_DIRECTORY) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n"); + #endif + + goto _NXGetXkbBasePathError; + } + + strcpy(_NXXkbBasePath, NX_XKB_ALTERNATE_BASE_DIRECTORY); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n", + _NXXkbBasePath); + #endif + + return _NXXkbBasePath; + } + +_NXGetXkbBasePathError: + + if (strlen(path) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n"); + #endif + } + + strcpy(_NXXkbBasePath, path); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbBasePath: Using default xkb base path [%s].\n", + _NXXkbBasePath); + #endif + + return _NXXkbBasePath; +} + +static int NXVerifyXkbCompPath(char *path) +{ + char *xkbCompPath; + int xkbCompPathSize; + struct stat xkbCompPathStat; + + if (path == NULL) + { + return 0; + } + + xkbCompPathSize = strlen(path) + strlen("/") + + strlen("xkbcomp") + 1; + + if ((xkbCompPath = malloc((xkbCompPathSize + 1) * sizeof(char))) == NULL) + { + FatalError("NXVerifyXkbCompPath: WARNING! malloc failed.\n"); + + return 0; + } + + strcpy(xkbCompPath, path); + strcat(xkbCompPath, "/"); + strcat(xkbCompPath, "xkbcomp"); + + if (stat(xkbCompPath, &xkbCompPathStat) != 0) + { + #ifdef NX_TRANS_TEST + fprintf(stderr, "NXVerifyXkbCompPath: WARNING! Failed to stat xkbcomp path [%s].\n", + xkbCompPath); + #endif + + free(xkbCompPath); + + return 0; + } + + free(xkbCompPath); + + return 1; +} + +/* + * This function returns the directory + * containing the xkbcomp executable. + * The function will first try to locate + * the executable in the hardcoded path + * (the same path as the "base" xkb one) + * and, if the xkbcomp file couldn't be + * found, the function will not include + * an explicit path and will rely on the + * PATH environment to list the directory. + */ + +char *_NXGetXkbCompPath(const char *path) +{ + + char * xkbCompPath; + + /* + * Check the xkbcomp executable + * directory only once. + */ + + if (*_NXXkbCompPath != '\0') + { + return _NXXkbCompPath; + } + + xkbCompPath = _NXGetXkbBasePath(path); + + if (NXVerifyXkbCompPath(xkbCompPath) == 1) + { + if (strlen(xkbCompPath) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n"); + #endif + + goto _NXGetXkbCompPathError; + } + + strcpy(_NXXkbCompPath, xkbCompPath); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: Using xkbcomp path [%s].\n", + _NXXkbCompPath); + #endif + + return _NXXkbCompPath; + } + + xkbCompPath = NX_ALT_XKBCOMP_PATH; + + if (NXVerifyXkbCompPath(xkbCompPath) == 1) + { + if (strlen(xkbCompPath) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n"); + #endif + + goto _NXGetXkbCompPathError; + } + + strcpy(_NXXkbCompPath, xkbCompPath); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: Using NX xkbcomp path [%s].\n", + _NXXkbCompPath); + #endif + + return _NXXkbCompPath; + } + +_NXGetXkbCompPathError: + + if (strlen(path) + 1 > PATH_MAX) + { + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n"); + #endif + } + + strcpy(_NXXkbCompPath, path); + + #ifdef TEST + fprintf(stderr, "_NXGetXkbCompPath: Using default xkbcomp path [%s].\n", + _NXXkbCompPath); + #endif + + return _NXXkbCompPath; +} + +#endif + +static void +OutputDirectory( + char* outdir, + size_t size) +{ +#ifndef WIN32 + if (getuid() == 0 && (strlen(XKM_OUTPUT_DIR) < size) +#ifdef MAKE_XKM_OUTPUT_DIR + && (trans_mkdir(XKM_OUTPUT_DIR, XKM_OUTPUT_DIR_MODE) == 0) +#endif + ) + { + /* if server running as root it *may* be able to write */ + /* FIXME: check whether directory is writable at all */ + (void) strcpy (outdir, XKM_OUTPUT_DIR); + } else +#endif +#ifdef _PATH_VARTMP + if ((strlen(_PATH_VARTMP) + 1) < size) + { + (void) strcpy (outdir, _PATH_VARTMP); + if (outdir[strlen(outdir) - 1] != '/') /* Hi IBM, Digital */ + (void) strcat (outdir, "/"); + } else +#endif +#ifdef WIN32 + if (strlen(Win32TempDir()) + 1 < size) + { + (void) strcpy(outdir, Win32TempDir()); + (void) strcat(outdir, "\\"); + } else +#endif + if (strlen("/tmp/") < size) + { + (void) strcpy (outdir, "/tmp/"); + } +} + +Bool +XkbDDXCompileNamedKeymap( XkbDescPtr xkb, + XkbComponentNamesPtr names, + char * nameRtrn, + int nameRtrnLen) +{ +char *cmd = NULL,file[PATH_MAX],xkm_output_dir[PATH_MAX],*map,*outFile; + + if (names->keymap==NULL) + return False; + strncpy(file,names->keymap,PATH_MAX); file[PATH_MAX-1]= '\0'; + if ((map= strrchr(file,'('))!=NULL) { + char *tmp; + if ((tmp= strrchr(map,')'))!=NULL) { + *map++= '\0'; + *tmp= '\0'; + } + else { + map= NULL; + } + } + if ((outFile= strrchr(file,'/'))!=NULL) + outFile= _XkbDupString(&outFile[1]); + else outFile= _XkbDupString(file); + XkbEnsureSafeMapName(outFile); + OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); + +#ifdef NXAGENT_SERVER + + if (_NXGetXkbCompPath(XkbBaseDirectory) != NULL) + { + +#else + + if (XkbBaseDirectory!=NULL) { + +#endif + +#ifndef __UNIXOS2__ + +#ifdef NXAGENT_SERVER + char *xkbbasedir = _NXGetXkbCompPath(XkbBaseDirectory); + char *xkbbindir = _NXGetXkbCompPath(XkbBinDirectory); +#else + char *xkbbasedir = XkbBaseDirectory; + char *xkbbindir = XkbBinDirectory; +#endif + +#else + /* relocate the basedir and replace the slashes with backslashes */ +#ifdef NXAGENT_SERVER + char *xkbbasedir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBaseDirectory)); + char *xkbbindir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBinDirectory)); +#else + char *xkbbasedir = (char*)__XOS2RedirRoot(XkbBaseDirectory); + char *xkbbindir = (char*)__XOS2RedirRoot(XkbBinDirectory); +#endif + int i; + + for (i=0; i<strlen(xkbbasedir); i++) + if (xkbbasedir[i]=='/') xkbbasedir[i]='\\'; + for (i=0; i<strlen(xkbbindir); i++) + if (xkbbindir[i]=='/') xkbbindir[i]='\\'; +#endif + + cmd = Xprintf("\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"", + xkbbindir, + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + xkbbasedir,(map?"-m ":""),(map?map:""), + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file, + xkm_output_dir,outFile); + } + else { + cmd = Xprintf("xkbcomp -w %d -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"", + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + (map?"-m ":""),(map?map:""), + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file, + xkm_output_dir,outFile); + } +#ifdef DEBUG + if (xkbDebugFlags) { + ErrorF("XkbDDXCompileNamedKeymap compiling keymap using:\n"); + ErrorF(" \"cmd\"\n"); + } +#endif +#ifdef DEBUG_CMD + ErrorF("xkb executes: %s\n",cmd); +#endif + if (System(cmd)==0) { + if (nameRtrn) { + strncpy(nameRtrn,outFile,nameRtrnLen); + nameRtrn[nameRtrnLen-1]= '\0'; + } + if (outFile!=NULL) + _XkbFree(outFile); + if (cmd!=NULL) + xfree(cmd); + return True; + } +#ifdef DEBUG + ErrorF("Error compiling keymap (%s)\n",names->keymap); +#endif + if (outFile!=NULL) + _XkbFree(outFile); + if (cmd!=NULL) + xfree(cmd); + return False; +} + +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]; + +#ifdef WIN32 +char tmpname[PATH_MAX]; +#endif + if ((names->keymap==NULL)||(names->keymap[0]=='\0')) { + sprintf(keymap,"server-%s",display); + } + else { + if (strlen(names->keymap) > PATH_MAX - 1) { + ErrorF("name of keymap (%s) exceeds max length\n", names->keymap); + return False; + } + strcpy(keymap,names->keymap); + } + + XkbEnsureSafeMapName(keymap); + OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); +#ifdef WIN32 + strcpy(tmpname, Win32TempDir()); + strcat(tmpname, "\\xkb_XXXXXX"); + (void) mktemp(tmpname); +#endif + +#ifdef NXAGENT_SERVER + if (_NXGetXkbCompPath(XkbBaseDirectory)!=NULL) { +#else + if (XkbBaseDirectory!=NULL) { +#endif + +#ifndef WIN32 + char *xkmfile = "-"; +#else + /* 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 *xkmfile = tmpname; +#endif +#ifndef __UNIXOS2__ +#ifdef NXAGENT_SERVER + char *xkbbasedir = _NXGetXkbCompPath(XkbBaseDirectory); + char *xkbbindir = _NXGetXkbCompPath(XkbBinDirectory); +#else + char *xkbbasedir = XkbBaseDirectory; + char *xkbbindir = XkbBinDirectory; +#endif +#else + int i; +#ifdef NXAGENT_SERVER + char *xkbbasedir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBaseDirectory)); + char *xkbbindir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBinDirectory)); +#else + char *xkbbasedir = (char*)__XOS2RedirRoot(XkbBaseDirectory); + char *xkbbindir = (char*)__XOS2RedirRoot(XkbBinDirectory); +#endif + for (i=0; i<strlen(xkbbasedir); i++) + if (xkbbasedir[i]=='/') xkbbasedir[i]='\\'; + for (i=0; i<strlen(xkbbindir); i++) + if (xkbbindir[i]=='/') xkbbindir[i]='\\'; +#endif + + buf = Xprintf( + "\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm \"%s\" -em1 %s -emp %s -eml %s \"%s%s.xkm\"", + xkbbindir, + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + xkbbasedir, xkmfile, + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1, + xkm_output_dir,keymap); + } + else { +#ifndef WIN32 + char *xkmfile = "-"; +#else + char *xkmfile = tmpname; +#endif + buf = Xprintf( + "xkbcomp -w %d -xkm \"%s\" -em1 %s -emp %s -eml %s \"%s%s.xkm\"", + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + xkmfile, + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1, + xkm_output_dir,keymap); + } + + #ifdef TEST + fprintf(stderr, "XkbDDXCompileKeymapByNames: Executing command [%s].\n", buf); + #endif + +#ifndef WIN32 + out= Popen(buf,"w"); +#else + out= fopen(tmpname, "w"); +#endif + + if (out!=NULL) { +#ifdef DEBUG + if (xkbDebugFlags) { + ErrorF("XkbDDXCompileKeymapByNames compiling keymap:\n"); + XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need); + } +#endif + XkbWriteXKBKeymapForNames(out,names,NULL,xkb,want,need); +#ifndef WIN32 +#ifdef __sun + if (Pclose(out) != 0) + { + ErrorF("Warning: Spurious failure reported in Pclose() runnning 'xkbcomp'.\n"); + } + if (1) +#else + if (Pclose(out)==0) +#endif +#else + if (fclose(out)==0 && System(buf) >= 0) +#endif + { +#ifdef DEBUG_CMD + ErrorF("xkb executes: %s\n",buf); + ErrorF("xkbcomp input:\n"); + XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need); + ErrorF("end xkbcomp input\n"); +#endif + if (nameRtrn) { + strncpy(nameRtrn,keymap,nameRtrnLen); + nameRtrn[nameRtrnLen-1]= '\0'; + } +#if defined(Lynx) && defined(__i386__) && defined(NEED_POPEN_WORKAROUND) + /* somehow popen/pclose is broken on LynxOS AT 2.3.0/2.4.0! + * the problem usually shows up with XF86Setup + * this hack waits at max 5 seconds after pclose() returns + * for the output of the xkbcomp output file. + * I didn't manage to get a patch in time for the 3.2 release + */ + { + int i; + char name[PATH_MAX]; +#ifdef NXAGENT_SERVER + if (_NXGetXkbCompPath(XkbBaseDirectory)!=NULL) + sprintf(name,"%s/%s%s.xkm", _NXGetXkbCompPath(XkbBaseDirectory) + ,xkm_output_dir, keymap); +#else + if (XkbBaseDirectory!=NULL) + sprintf(name,"%s/%s%s.xkm", XkbBaseDirectory + ,xkm_output_dir, keymap); +#endif + else + sprintf(name,"%s%s.xkm", xkm_output_dir, keymap); + for (i = 0; i < 10; i++) { + if (access(name, 0) == 0) break; + usleep(500000); + } +#ifdef DEBUG + if (i) ErrorF(">>>> Waited %d times for %s\n", i, name); +#endif + } +#endif + if (buf != NULL) + xfree (buf); + return True; + } +#ifdef DEBUG + else + ErrorF("Error compiling keymap (%s)\n",keymap); +#endif +#ifdef WIN32 + /* remove the temporary file */ + unlink(tmpname); +#endif + } +#ifdef DEBUG + else { +#ifndef WIN32 + ErrorF("Could not invoke keymap compiler\n"); +#else + ErrorF("Could not open file %s\n", tmpname); +#endif + } +#endif + if (nameRtrn) + nameRtrn[0]= '\0'; + if (buf != NULL) + xfree (buf); + return False; +} + +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, + XkbFileInfo * finfoRtrn, + char * nameRtrn, + int nameRtrnLen) +{ +XkbDescPtr xkb; +FILE * file; +char fileName[PATH_MAX]; +unsigned missing; + + bzero(finfoRtrn,sizeof(XkbFileInfo)); + 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)) { + if (names->keymap==NULL) { + bzero(finfoRtrn,sizeof(XkbFileInfo)); + if (xkb && XkbDetermineFileType(finfoRtrn,XkbXKMFile,NULL) && + ((finfoRtrn->defined&need)==need) ) { + finfoRtrn->xkb= xkb; + nameRtrn[0]= '\0'; + return finfoRtrn->defined; + } + return 0; + } + else if (!XkbDDXCompileNamedKeymap(xkb,names,nameRtrn,nameRtrnLen)) { +#ifdef NOISY + ErrorF("Couldn't compile keymap file\n"); +#endif + return 0; + } + } + else if (!XkbDDXCompileKeymapByNames(xkb,names,want,need, + nameRtrn,nameRtrnLen)){ +#ifdef NOISY + ErrorF("Couldn't compile keymap file\n"); +#endif + 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,finfoRtrn); + if (finfoRtrn->xkb==NULL) { + LogMessage(X_ERROR, "Error loading keymap %s\n",fileName); + fclose(file); + (void) unlink (fileName); + return 0; + } +#ifdef DEBUG + else if (xkbDebugFlags) { + ErrorF("Loaded %s, defined=0x%x\n",fileName,finfoRtrn->defined); + } +#endif + 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 (XkbBaseDirectory==NULL) { + if (strlen(rules_name)+7 > PATH_MAX) + return False; + sprintf(buf,"rules/%s",rules_name); + } + else { + if (strlen(XkbBaseDirectory)+strlen(rules_name)+8 > PATH_MAX) + return False; + sprintf(buf,"%s/rules/%s",XkbBaseDirectory,rules_name); + } + if ((file= fopen(buf,"r"))==NULL) + return False; + if ((rules= XkbRF_Create(0,0))==NULL) { + fclose(file); + return False; + } + if (!XkbRF_LoadRules(file,rules)) { + fclose(file); + XkbRF_Free(rules,True); + return False; + } + bzero((char *)names,sizeof(XkbComponentNamesRec)); + complete= XkbRF_GetComponents(rules,defs,names); + fclose(file); + XkbRF_Free(rules,True); + return complete; +} + + diff --git a/nx-X11/programs/Xserver/xkb/ddxLoad.c.X.original b/nx-X11/programs/Xserver/xkb/ddxLoad.c.X.original new file mode 100644 index 000000000..e355b1796 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxLoad.c.X.original @@ -0,0 +1,604 @@ +/* $Xorg: ddxLoad.c,v 1.3 2000/08/17 19:53:46 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxLoad.c,v 3.35 2003/10/02 13:30:12 eich Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef HAVE_XKB_CONFIG_H +#include <xkb-config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#define NEED_EVENTS 1 +#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 <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> +#include "xkb.h" + +#if defined(CSRG_BASED) || defined(linux) || defined(__sgi) || defined(AIXV3) || defined(__osf__) || defined(__GNU__) +#include <paths.h> +#endif + +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#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(__UNIXOS2__) || 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("Starting '%s' failed!\n", cmdline); + } + else + { + ErrorF("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 + +#ifdef MAKE_XKM_OUTPUT_DIR +/* Borrow trans_mkdir from Xtransutil.c to more safely make directories */ +# undef X11_t +# define TRANS_SERVER +# define PRMSG(lvl,x,a,b,c) \ + if (lvl <= 1) { LogMessage(X_ERROR,x,a,b,c); } else ((void)0) +# include <X11/Xtrans/Xtransutil.c> +# ifndef XKM_OUTPUT_DIR_MODE +# define XKM_OUTPUT_DIR_MODE 0755 +# endif +#endif + +static void +OutputDirectory( + char* outdir, + size_t size) +{ +#ifndef WIN32 + if (getuid() == 0 && (strlen(XKM_OUTPUT_DIR) < size) +#ifdef MAKE_XKM_OUTPUT_DIR + && (trans_mkdir(XKM_OUTPUT_DIR, XKM_OUTPUT_DIR_MODE) == 0) +#endif + ) + { + /* if server running as root it *may* be able to write */ + /* FIXME: check whether directory is writable at all */ + (void) strcpy (outdir, XKM_OUTPUT_DIR); + } else +#endif +#ifdef _PATH_VARTMP + if ((strlen(_PATH_VARTMP) + 1) < size) + { + (void) strcpy (outdir, _PATH_VARTMP); + if (outdir[strlen(outdir) - 1] != '/') /* Hi IBM, Digital */ + (void) strcat (outdir, "/"); + } else +#endif +#ifdef WIN32 + if (strlen(Win32TempDir()) + 1 < size) + { + (void) strcpy(outdir, Win32TempDir()); + (void) strcat(outdir, "\\"); + } else +#endif + if (strlen("/tmp/") < size) + { + (void) strcpy (outdir, "/tmp/"); + } +} + +Bool +XkbDDXCompileNamedKeymap( XkbDescPtr xkb, + XkbComponentNamesPtr names, + char * nameRtrn, + int nameRtrnLen) +{ +char *cmd = NULL,file[PATH_MAX],xkm_output_dir[PATH_MAX],*map,*outFile; + + if (names->keymap==NULL) + return False; + strncpy(file,names->keymap,PATH_MAX); file[PATH_MAX-1]= '\0'; + if ((map= strrchr(file,'('))!=NULL) { + char *tmp; + if ((tmp= strrchr(map,')'))!=NULL) { + *map++= '\0'; + *tmp= '\0'; + } + else { + map= NULL; + } + } + if ((outFile= strrchr(file,'/'))!=NULL) + outFile= _XkbDupString(&outFile[1]); + else outFile= _XkbDupString(file); + XkbEnsureSafeMapName(outFile); + OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); + + if (XkbBaseDirectory!=NULL) { +#ifndef __UNIXOS2__ + char *xkbbasedir = XkbBaseDirectory; + char *xkbbindir = XkbBinDirectory; +#else + /* relocate the basedir and replace the slashes with backslashes */ + char *xkbbasedir = (char*)__XOS2RedirRoot(XkbBaseDirectory); + char *xkbbindir = (char*)__XOS2RedirRoot(XkbBinDirectory); + int i; + + for (i=0; i<strlen(xkbbasedir); i++) + if (xkbbasedir[i]=='/') xkbbasedir[i]='\\'; + for (i=0; i<strlen(xkbbindir); i++) + if (xkbbindir[i]=='/') xkbbindir[i]='\\'; +#endif + + cmd = Xprintf("\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"", + xkbbindir, + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + xkbbasedir,(map?"-m ":""),(map?map:""), + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file, + xkm_output_dir,outFile); + } + else { + cmd = Xprintf("xkbcomp -w %d -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"", + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + (map?"-m ":""),(map?map:""), + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file, + xkm_output_dir,outFile); + } +#ifdef DEBUG + if (xkbDebugFlags) { + ErrorF("XkbDDXCompileNamedKeymap compiling keymap using:\n"); + ErrorF(" \"cmd\"\n"); + } +#endif +#ifdef DEBUG_CMD + ErrorF("xkb executes: %s\n",cmd); +#endif + if (System(cmd)==0) { + if (nameRtrn) { + strncpy(nameRtrn,outFile,nameRtrnLen); + nameRtrn[nameRtrnLen-1]= '\0'; + } + if (outFile!=NULL) + _XkbFree(outFile); + if (cmd!=NULL) + xfree(cmd); + return True; + } +#ifdef DEBUG + ErrorF("Error compiling keymap (%s)\n",names->keymap); +#endif + if (outFile!=NULL) + _XkbFree(outFile); + if (cmd!=NULL) + xfree(cmd); + return False; +} + +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]; + +#ifdef WIN32 +char tmpname[PATH_MAX]; +#endif + if ((names->keymap==NULL)||(names->keymap[0]=='\0')) { + sprintf(keymap,"server-%s",display); + } + else { + if (strlen(names->keymap) > PATH_MAX - 1) { + ErrorF("name of keymap (%s) exceeds max length\n", names->keymap); + return False; + } + strcpy(keymap,names->keymap); + } + + XkbEnsureSafeMapName(keymap); + OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); +#ifdef WIN32 + strcpy(tmpname, Win32TempDir()); + strcat(tmpname, "\\xkb_XXXXXX"); + (void) mktemp(tmpname); +#endif + if (XkbBaseDirectory!=NULL) { +#ifndef WIN32 + char *xkmfile = "-"; +#else + /* 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 *xkmfile = tmpname; +#endif +#ifndef __UNIXOS2__ + char *xkbbasedir = XkbBaseDirectory; + char *xkbbindir = XkbBinDirectory; +#else + int i; + char *xkbbasedir = (char*)__XOS2RedirRoot(XkbBaseDirectory); + char *xkbbindir = (char*)__XOS2RedirRoot(XkbBinDirectory); + for (i=0; i<strlen(xkbbasedir); i++) + if (xkbbasedir[i]=='/') xkbbasedir[i]='\\'; + for (i=0; i<strlen(xkbbindir); i++) + if (xkbbindir[i]=='/') xkbbindir[i]='\\'; +#endif + + buf = Xprintf( + "\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm \"%s\" -em1 %s -emp %s -eml %s \"%s%s.xkm\"", + xkbbindir, + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + xkbbasedir, xkmfile, + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1, + xkm_output_dir,keymap); + } + else { +#ifndef WIN32 + char *xkmfile = "-"; +#else + char *xkmfile = tmpname; +#endif + buf = Xprintf( + "xkbcomp -w %d -xkm \"%s\" -em1 %s -emp %s -eml %s \"%s%s.xkm\"", + ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)), + xkmfile, + PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1, + xkm_output_dir,keymap); + } + +#ifndef WIN32 + out= Popen(buf,"w"); +#else + out= fopen(tmpname, "w"); +#endif + + if (out!=NULL) { +#ifdef DEBUG + if (xkbDebugFlags) { + ErrorF("XkbDDXCompileKeymapByNames compiling keymap:\n"); + XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need); + } +#endif + XkbWriteXKBKeymapForNames(out,names,NULL,xkb,want,need); +#ifndef WIN32 + if (Pclose(out)==0) +#else + if (fclose(out)==0 && System(buf) >= 0) +#endif + { +#ifdef DEBUG_CMD + ErrorF("xkb executes: %s\n",buf); + ErrorF("xkbcomp input:\n"); + XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need); + ErrorF("end xkbcomp input\n"); +#endif + if (nameRtrn) { + strncpy(nameRtrn,keymap,nameRtrnLen); + nameRtrn[nameRtrnLen-1]= '\0'; + } +#if defined(Lynx) && defined(__i386__) && defined(NEED_POPEN_WORKAROUND) + /* somehow popen/pclose is broken on LynxOS AT 2.3.0/2.4.0! + * the problem usually shows up with XF86Setup + * this hack waits at max 5 seconds after pclose() returns + * for the output of the xkbcomp output file. + * I didn't manage to get a patch in time for the 3.2 release + */ + { + int i; + char name[PATH_MAX]; + if (XkbBaseDirectory!=NULL) + sprintf(name,"%s/%s%s.xkm", XkbBaseDirectory + ,xkm_output_dir, keymap); + else + sprintf(name,"%s%s.xkm", xkm_output_dir, keymap); + for (i = 0; i < 10; i++) { + if (access(name, 0) == 0) break; + usleep(500000); + } +#ifdef DEBUG + if (i) ErrorF(">>>> Waited %d times for %s\n", i, name); +#endif + } +#endif + if (buf != NULL) + xfree (buf); + return True; + } +#ifdef DEBUG + else + ErrorF("Error compiling keymap (%s)\n",keymap); +#endif +#ifdef WIN32 + /* remove the temporary file */ + unlink(tmpname); +#endif + } +#ifdef DEBUG + else { +#ifndef WIN32 + ErrorF("Could not invoke keymap compiler\n"); +#else + ErrorF("Could not open file %s\n", tmpname); +#endif + } +#endif + if (nameRtrn) + nameRtrn[0]= '\0'; + if (buf != NULL) + xfree (buf); + return False; +} + +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, + XkbFileInfo * finfoRtrn, + char * nameRtrn, + int nameRtrnLen) +{ +XkbDescPtr xkb; +FILE * file; +char fileName[PATH_MAX]; +unsigned missing; + + bzero(finfoRtrn,sizeof(XkbFileInfo)); + 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)) { + if (names->keymap==NULL) { + bzero(finfoRtrn,sizeof(XkbFileInfo)); + if (xkb && XkbDetermineFileType(finfoRtrn,XkbXKMFile,NULL) && + ((finfoRtrn->defined&need)==need) ) { + finfoRtrn->xkb= xkb; + nameRtrn[0]= '\0'; + return finfoRtrn->defined; + } + return 0; + } + else if (!XkbDDXCompileNamedKeymap(xkb,names,nameRtrn,nameRtrnLen)) { +#ifdef NOISY + ErrorF("Couldn't compile keymap file\n"); +#endif + return 0; + } + } + else if (!XkbDDXCompileKeymapByNames(xkb,names,want,need, + nameRtrn,nameRtrnLen)){ +#ifdef NOISY + ErrorF("Couldn't compile keymap file\n"); +#endif + 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,finfoRtrn); + if (finfoRtrn->xkb==NULL) { + LogMessage(X_ERROR, "Error loading keymap %s\n",fileName); + fclose(file); + (void) unlink (fileName); + return 0; + } +#ifdef DEBUG + else if (xkbDebugFlags) { + ErrorF("Loaded %s, defined=0x%x\n",fileName,finfoRtrn->defined); + } +#endif + 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 (XkbBaseDirectory==NULL) { + if (strlen(rules_name)+7 > PATH_MAX) + return False; + sprintf(buf,"rules/%s",rules_name); + } + else { + if (strlen(XkbBaseDirectory)+strlen(rules_name)+8 > PATH_MAX) + return False; + sprintf(buf,"%s/rules/%s",XkbBaseDirectory,rules_name); + } + if ((file= fopen(buf,"r"))==NULL) + return False; + if ((rules= XkbRF_Create(0,0))==NULL) { + fclose(file); + return False; + } + if (!XkbRF_LoadRules(file,rules)) { + fclose(file); + XkbRF_Free(rules,True); + return False; + } + bzero((char *)names,sizeof(XkbComponentNamesRec)); + complete= XkbRF_GetComponents(rules,defs,names); + fclose(file); + XkbRF_Free(rules,True); + return complete; +} + + diff --git a/nx-X11/programs/Xserver/xkb/ddxPrivate.c b/nx-X11/programs/Xserver/xkb/ddxPrivate.c new file mode 100644 index 000000000..5c0bca4cd --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxPrivate.c @@ -0,0 +1,46 @@ +/* $XFree86: xc/programs/Xserver/xkb/ddxPrivate.c,v 1.2 2003/04/03 16:20:22 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include "windowstr.h" +#define XKBSRV_NEED_FILE_FUNCS +#include <X11/extensions/XKBsrv.h> + +#ifdef XF86DDXACTIONS +#include "xf86.h" +#endif + +int +XkbDDXPrivate(DeviceIntPtr dev,KeyCode key,XkbAction *act) +{ +#ifdef XF86DDXACTIONS + XkbAnyAction *xf86act = &(act->any); + char msgbuf[XkbAnyActionDataSize+1]; + + if (xf86act->type == XkbSA_XFree86Private) { + memcpy(msgbuf, xf86act->data, XkbAnyActionDataSize); + msgbuf[XkbAnyActionDataSize]= '\0'; + if (_XkbStrCaseCmp(msgbuf, "-vmode")==0) + xf86ProcessActionEvent(ACTION_PREV_MODE, NULL); + else if (_XkbStrCaseCmp(msgbuf, "+vmode")==0) + xf86ProcessActionEvent(ACTION_NEXT_MODE, NULL); + else if (_XkbStrCaseCmp(msgbuf, "ungrab")==0) + xf86ProcessActionEvent(ACTION_DISABLEGRAB, NULL); + else if (_XkbStrCaseCmp(msgbuf, "clsgrb")==0) + xf86ProcessActionEvent(ACTION_CLOSECLIENT, NULL); + else + xf86ProcessActionEvent(ACTION_MESSAGE, (void *) msgbuf); + } +#endif + return 0; +} + diff --git a/nx-X11/programs/Xserver/xkb/ddxVT.c b/nx-X11/programs/Xserver/xkb/ddxVT.c new file mode 100644 index 000000000..1b7853fa0 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/ddxVT.c @@ -0,0 +1,72 @@ +/* $Xorg: ddxVT.c,v 1.3 2000/08/17 19:53:46 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/ddxVT.c,v 1.3 2002/11/23 19:27:50 tsi Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XI.h> + +#ifdef XF86DDXACTIONS +#include "xf86.h" +#endif + +int +XkbDDXSwitchScreen(DeviceIntPtr dev,KeyCode key,XkbAction *act) +{ +#ifdef XF86DDXACTIONS + { + int scrnnum = XkbSAScreen(&act->screen); + + if (act->screen.flags & XkbSA_SwitchApplication) { + if (act->screen.flags & XkbSA_SwitchAbsolute) + xf86ProcessActionEvent(ACTION_SWITCHSCREEN,(void *) &scrnnum); + else { + if (scrnnum < 0) + xf86ProcessActionEvent(ACTION_SWITCHSCREEN_PREV,NULL); + else + xf86ProcessActionEvent(ACTION_SWITCHSCREEN_NEXT,NULL); + } + } + } +#endif + return 1; +} diff --git a/nx-X11/programs/Xserver/xkb/xkb.c b/nx-X11/programs/Xserver/xkb/xkb.c new file mode 100644 index 000000000..240509079 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkb.c @@ -0,0 +1,6233 @@ +/* $Xorg: xkb.c,v 1.3 2000/08/17 19:53:46 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/xkb.c,v 3.22tsi Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <X11/X.h> +#define NEED_EVENTS +#define NEED_REPLIES +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" +#define XKBSRV_NEED_FILE_FUNCS +#include <X11/extensions/XKBsrv.h> +#include "extnsionst.h" +#include "xkb.h" + +#include <X11/extensions/XI.h> + + int XkbEventBase; + int XkbErrorBase; + int XkbReqCode; + int XkbKeyboardErrorCode; +Atom xkbONE_LEVEL; +Atom xkbTWO_LEVEL; +Atom xkbKEYPAD; +CARD32 xkbDebugFlags = 0; +CARD32 xkbDebugCtrls = 0; + +#ifndef XKB_SRV_UNSUPPORTED_XI_FEATURES +#define XKB_SRV_UNSUPPORTED_XI_FEATURES XkbXI_KeyboardsMask +#endif + +unsigned XkbXIUnsupported= XKB_SRV_UNSUPPORTED_XI_FEATURES; + +RESTYPE RT_XKBCLIENT; + +/***====================================================================***/ + +#define CHK_DEVICE(d,sp,lf) {\ + int why;\ + d = (DeviceIntPtr)lf((sp),&why);\ + if (!dev) {\ + client->errorValue = _XkbErrCode2(why,(sp));\ + return XkbKeyboardErrorCode;\ + }\ +} + +#define CHK_KBD_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupKeyboard) +#define CHK_LED_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupLedDevice) +#define CHK_BELL_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupBellDevice) +#define CHK_ANY_DEVICE(d,sp) CHK_DEVICE(d,sp,_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 != XkbMajorVersion) { + /* pre-release version 0.65 is compatible with 1.00 */ + supported= ((XkbMajorVersion==1)&& + (stuff->wantedMajor==0)&&(stuff->wantedMinor==65)); + } + else supported = 1; + +#ifdef XKB_SWAPPING_BUSTED + if (client->swapped) + supported= 0; +#endif + + if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) { + client->xkbClientFlags= _XkbClientInitialized; + client->vMajor= stuff->wantedMajor; + client->vMinor= stuff->wantedMinor; + } + else if (xkbDebugFlags&0x1) { + ErrorF("Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n", + client->index, + (long)client->clientAsMask, + stuff->wantedMajor,stuff->wantedMinor, + XkbMajorVersion,XkbMinorVersion); + } + rep.type = X_Reply; + rep.supported = supported; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.serverMajor = XkbMajorVersion; + rep.serverMinor = XkbMinorVersion; + 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); + + 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("Extra data (%d bytes) after SelectEvents\n",dataLeft); + return BadLength; + } + return client->noClientException; + } + return BadAlloc; +} + +/***====================================================================***/ + +int +ProcXkbBell(ClientPtr client) +{ + REQUEST(xkbBellReq); + DeviceIntPtr dev; + WindowPtr pWin; + int base; + int newPercent,oldPitch,oldDuration; + pointer ctrl; + + REQUEST_SIZE_MATCH(xkbBellReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + CHK_BELL_DEVICE(dev,stuff->deviceSpec); + CHK_ATOM_OR_NONE(stuff->name); + + 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->bellClass == KbdFeedbackClass) { + KbdFeedbackPtr k; + if (stuff->bellID==XkbDfltXIId) + k= dev->kbdfeed; + else { + for (k=dev->kbdfeed; k; k=k->next) { + if (k->ctrl.id == stuff->bellID) + break; + } + } + if (!k) { + client->errorValue= _XkbErrCode2(0x5,stuff->bellID); + return BadValue; + } + base = k->ctrl.bell; + ctrl = (pointer) &(k->ctrl); + oldPitch= k->ctrl.bell_pitch; + oldDuration= k->ctrl.bell_duration; + if (stuff->pitch!=0) { + if (stuff->pitch==-1) + k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch; + else k->ctrl.bell_pitch= stuff->pitch; + } + if (stuff->duration!=0) { + if (stuff->duration==-1) + k->ctrl.bell_duration= defaultKeyboardControl.bell_duration; + else k->ctrl.bell_duration= stuff->duration; + } + } + else if (stuff->bellClass == BellFeedbackClass) { + BellFeedbackPtr b; + if (stuff->bellID==XkbDfltXIId) + b= dev->bell; + else { + for (b=dev->bell; b; b=b->next) { + if (b->ctrl.id == stuff->bellID) + break; + } + } + if (!b) { + client->errorValue = _XkbErrCode2(0x6,stuff->bellID); + return BadValue; + } + base = b->ctrl.percent; + ctrl = (pointer) &(b->ctrl); + oldPitch= b->ctrl.pitch; + oldDuration= b->ctrl.duration; + if (stuff->pitch!=0) { + if (stuff->pitch==-1) + b->ctrl.pitch= defaultKeyboardControl.bell_pitch; + else b->ctrl.pitch= stuff->pitch; + } + if (stuff->duration!=0) { + if (stuff->duration==-1) + b->ctrl.duration= defaultKeyboardControl.bell_duration; + else b->ctrl.duration= stuff->duration; + } + } + else { + client->errorValue = _XkbErrCode2(0x7,stuff->bellClass);; + return BadValue; + } + if (stuff->window!=None) { + pWin= (WindowPtr)LookupIDByType(stuff->window,RT_WINDOW); + if (pWin==NULL) { + client->errorValue= stuff->window; + return BadValue; + } + } + else pWin= NULL; + + newPercent= (base*stuff->percent)/100; + if (stuff->percent < 0) + newPercent= base+newPercent; + else newPercent= base-newPercent+stuff->percent; + XkbHandleBell(stuff->forceSound, stuff->eventOnly, + dev, newPercent, ctrl, stuff->bellClass, + stuff->name, pWin, client); + if ((stuff->pitch!=0)||(stuff->duration!=0)) { + if (stuff->bellClass == KbdFeedbackClass) { + KbdFeedbackPtr k; + k= (KbdFeedbackPtr)ctrl; + if (stuff->pitch!=0) + k->ctrl.bell_pitch= oldPitch; + if (stuff->duration!=0) + k->ctrl.bell_duration= oldDuration; + } + else { + BellFeedbackPtr b; + b= (BellFeedbackPtr)ctrl; + if (stuff->pitch!=0) + b->ctrl.pitch= oldPitch; + if (stuff->duration!=0) + b->ctrl.duration= oldDuration; + } + } + return Success; +} + +/***====================================================================***/ + +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); + + 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 = dev->key->state&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; + XkbStateRec oldState,*newState; + CARD16 changed; + + REQUEST(xkbLatchLockStateReq); + REQUEST_SIZE_MATCH(xkbLatchLockStateReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + CHK_KBD_DEVICE(dev,stuff->deviceSpec); + CHK_MASK_MATCH(0x01,stuff->affectModLocks,stuff->modLocks); + CHK_MASK_MATCH(0x01,stuff->affectModLatches,stuff->modLatches); + + status = Success; + oldState= dev->key->xkbInfo->state; + newState= &dev->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(dev,stuff->affectModLatches,stuff->modLatches); + if (( status == Success ) && stuff->latchGroup ) + status=XkbLatchGroup(dev,stuff->groupLatch); + + if ( status != Success ) + return status; + + XkbComputeDerivedState(dev->key->xkbInfo); + dev->key->state= XkbStateFieldFromRec(newState); + + changed = XkbStateChangedFlags(&oldState,newState); + if (changed) { + xkbStateNotify sn; + sn.keycode= 0; + sn.eventType= 0; + sn.requestMajor = XkbReqCode; + sn.requestMinor = X_kbLatchLockState; + sn.changed= changed; + XkbSendStateNotify(dev,&sn); + changed= XkbIndicatorsToUpdate(dev,changed,False); + if (changed) { + XkbEventCauseRec cause; + XkbSetCauseXkbReq(&cause,X_kbLatchLockState,client); + XkbUpdateIndicators(dev,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); + + xkb = dev->key->xkbInfo->desc->ctrls; + rep.type = X_Reply; + rep.length = (SIZEOF(xkbGetControlsReply)- + SIZEOF(xGenericReply)) >> 2; + 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; + 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); + CHK_MASK_LEGAL(0x01,stuff->changeCtrls,XkbAllControlsMask); + + xkbi = dev->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(dev,&old,ctrl); + if (XkbComputeControlsNotify(dev,&old,ctrl,&cn,False)) { + cn.keycode= 0; + cn.eventType = 0; + cn.requestMajor = XkbReqCode; + cn.requestMinor = X_kbSetControls; + XkbSendControlsNotify(dev,&cn); + } + if ((sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0))!=NULL) + XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause); +#ifndef NO_CLEAR_LATCHES_FOR_STICKY_KEYS_OFF + /* If sticky keys were disabled, clear all locks and latches */ + if ((old.enabled_ctrls&XkbStickyKeysMask)&& + (!(ctrl->enabled_ctrls&XkbStickyKeysMask))) { + XkbClearAllLatchesAndLocks(dev,xkbi,True,&cause); + } +#endif + return client->noClientException; +} + +int +XkbSetRepeatRate(DeviceIntPtr dev,int timeout,int interval,int major,int minor) +{ +int changed= 0; +XkbControlsRec old,*xkb; + + if ((!dev)||(!dev->key)||(!dev->key->xkbInfo)) + return 0; + xkb= dev->key->xkbInfo->desc->ctrls; + old= *xkb; + if ((timeout!=0) && (xkb->repeat_delay!=timeout)) { + xkb->repeat_delay= timeout; + changed++; + } + if ((interval!=0) && (xkb->repeat_interval!=interval)) { + xkb->repeat_interval= interval; + changed++; + } + if (changed) { + xkbControlsNotify cn; + XkbDDXChangeControls(dev,&old,xkb); + if (XkbComputeControlsNotify(dev,&old,xkb,&cn,False)) { + cn.keycode= 0; + cn.eventType = 0; + cn.requestMajor = major; + cn.requestMinor = minor; + XkbSendControlsNotify(dev,&cn); + } + } + return 1; +} + +int +XkbGetRepeatRate(DeviceIntPtr dev,int *timeout,int *interval) +{ +XkbControlsPtr xkb; + + if ((!dev)||(!dev->key)||(!dev->key->xkbInfo)) + return 0; + xkb= dev->key->xkbInfo->desc->ctrls; + if (timeout) *timeout= xkb->repeat_delay; + if (interval) *interval= xkb->repeat_interval; + return 1; +} + +/***====================================================================***/ + +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= (char *)ALLOCATE_LOCAL(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("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); + DEALLOCATE_LOCAL((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); + 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=(XkbRadioGroupPtr)_XkbRealloc(xkbi->radioGroups,sz); + else xkbi->radioGroups= (XkbRadioGroupPtr)_XkbCalloc(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; +} + +int +ProcXkbSetMap(ClientPtr client) +{ + DeviceIntPtr dev; + XkbSrvInfoPtr xkbi; + XkbDescPtr xkb; + XkbChangesRec change; + XkbEventCauseRec cause; + int nTypes,nActions,error; + char * tmp; + CARD8 mapWidths[XkbMaxLegalKeyCode+1]; + CARD16 symsPerKey[XkbMaxLegalKeyCode+1]; + Bool sentNKN; + + REQUEST(xkbSetMapReq); + REQUEST_AT_LEAST_SIZE(xkbSetMapReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + CHK_KBD_DEVICE(dev,stuff->deviceSpec); + CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask); + + XkbSetCauseXkbReq(&cause,X_kbSetMap,client); + xkbi= dev->key->xkbInfo; + xkb = xkbi->desc; + + if ((xkb->min_key_code!=stuff->minKeyCode)|| + (xkb->max_key_code!=stuff->maxKeyCode)) { + if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */ + stuff->minKeyCode= xkb->min_key_code; + stuff->maxKeyCode= xkb->max_key_code; + } + else { + if (!XkbIsLegalKeycode(stuff->minKeyCode)) { + client->errorValue= _XkbErrCode3(2,stuff->minKeyCode, + stuff->maxKeyCode); + return BadValue; + } + if (stuff->minKeyCode>stuff->maxKeyCode) { + client->errorValue= _XkbErrCode3(3,stuff->minKeyCode, + stuff->maxKeyCode); + return BadMatch; + } + } + } + + tmp = (char *)&stuff[1]; + if ((stuff->present&XkbKeyTypesMask)&& + (!CheckKeyTypes(client,xkb,stuff,(xkbKeyTypeWireDesc **)&tmp, + &nTypes,mapWidths))) { + client->errorValue = nTypes; + return BadValue; + } + if ((stuff->present&XkbKeySymsMask)&& + (!CheckKeySyms(client,xkb,stuff,nTypes,mapWidths,symsPerKey, + (xkbSymMapWireDesc **)&tmp,&error))) { + client->errorValue = error; + return BadValue; + } + + if ((stuff->present&XkbKeyActionsMask)&& + (!CheckKeyActions(xkb,stuff,nTypes,mapWidths,symsPerKey, + (CARD8 **)&tmp,&nActions))) { + client->errorValue = nActions; + return BadValue; + } + + if ((stuff->present&XkbKeyBehaviorsMask)&& + (!CheckKeyBehaviors(xkb,stuff,(xkbBehaviorWireDesc**)&tmp,&error))) { + client->errorValue = error; + return BadValue; + } + + if ((stuff->present&XkbVirtualModsMask)&& + (!CheckVirtualMods(xkb,stuff,(CARD8 **)&tmp,&error))) { + client->errorValue= error; + return BadValue; + } + if ((stuff->present&XkbExplicitComponentsMask)&& + (!CheckKeyExplicit(xkb,stuff,(CARD8 **)&tmp,&error))) { + client->errorValue= error; + return BadValue; + } + if ((stuff->present&XkbModifierMapMask)&& + (!CheckModifierMap(xkb,stuff,(CARD8 **)&tmp,&error))) { + client->errorValue= error; + return BadValue; + } + if ((stuff->present&XkbVirtualModMapMask)&& + (!CheckVirtualModMap(xkb,stuff,(xkbVModMapWireDesc **)&tmp,&error))) { + client->errorValue= error; + return BadValue; + } + if (((tmp-((char *)stuff))/4)!=stuff->length) { + ErrorF("Internal error! Bad length in XkbSetMap (after check)\n"); + client->errorValue = tmp-((char *)&stuff[1]); + return BadLength; + } + bzero(&change,sizeof(change)); + sentNKN= False; + if ((xkb->min_key_code!=stuff->minKeyCode)|| + (xkb->max_key_code!=stuff->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,stuff->minKeyCode,stuff->maxKeyCode, + &change); + if (status!=Success) + return status; + 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; + } + tmp = (char *)&stuff[1]; + if (stuff->present&XkbKeyTypesMask) { + tmp = SetKeyTypes(xkb,stuff,(xkbKeyTypeWireDesc *)tmp,&change); + if (!tmp) goto allocFailure; + } + if (stuff->present&XkbKeySymsMask) { + tmp = SetKeySyms(client,xkb,stuff,(xkbSymMapWireDesc *)tmp,&change,dev); + if (!tmp) goto allocFailure; + } + if (stuff->present&XkbKeyActionsMask) { + tmp = SetKeyActions(xkb,stuff,(CARD8 *)tmp,&change); + if (!tmp) goto allocFailure; + } + if (stuff->present&XkbKeyBehaviorsMask) { + tmp= SetKeyBehaviors(xkbi,stuff,(xkbBehaviorWireDesc *)tmp,&change); + if (!tmp) goto allocFailure; + } + if (stuff->present&XkbVirtualModsMask) + tmp= SetVirtualMods(xkbi,stuff,(CARD8 *)tmp,&change); + if (stuff->present&XkbExplicitComponentsMask) + tmp= SetKeyExplicit(xkbi,stuff,(CARD8 *)tmp,&change); + if (stuff->present&XkbModifierMapMask) + tmp= SetModifierMap(xkbi,stuff,(CARD8 *)tmp,&change); + if (stuff->present&XkbVirtualModMapMask) + tmp= SetVirtualModMap(xkbi,stuff,(xkbVModMapWireDesc *)tmp,&change); + if (((tmp-((char *)stuff))/4)!=stuff->length) { + ErrorF("Internal error! Bad length in XkbSetMap (after set)\n"); + client->errorValue = tmp-((char *)&stuff[1]); + return BadLength; + } + if (stuff->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); + + XkbUpdateCoreDescription(dev,False); + return client->noClientException; +allocFailure: + return BadAlloc; +} + +/***====================================================================***/ + +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 = (char *)ALLOCATE_LOCAL(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); + DEALLOCATE_LOCAL((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); + + 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); +} + +int +ProcXkbSetCompatMap(ClientPtr client) +{ + DeviceIntPtr dev; + XkbSrvInfoPtr xkbi; + XkbDescPtr xkb; + XkbCompatMapPtr compat; + char * data; + int nGroups; + register unsigned i,bit; + + REQUEST(xkbSetCompatMapReq); + REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + CHK_KBD_DEVICE(dev,stuff->deviceSpec); + + data = (char *)&stuff[1]; + xkbi = dev->key->xkbInfo; + xkb= xkbi->desc; + compat= xkb->compat; + if ((stuff->nSI>0)||(stuff->truncateSI)) { + xkbSymInterpretWireDesc *wire; + if (stuff->firstSI>compat->num_si) { + client->errorValue = _XkbErrCode2(0x02,compat->num_si); + return BadValue; + } + wire= (xkbSymInterpretWireDesc *)data; + wire+= stuff->nSI; + data = (char *)wire; + } + nGroups= 0; + if (stuff->groups!=0) { + for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { + if ( stuff->groups&bit ) + nGroups++; + } + } + data+= nGroups*SIZEOF(xkbModsWireDesc); + if (((data-((char *)stuff))/4)!=stuff->length) { + return BadLength; + } + data = (char *)&stuff[1]; + if (stuff->nSI>0) { + xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data; + XkbSymInterpretPtr sym; + if ((unsigned)(stuff->firstSI+stuff->nSI)>compat->num_si) { + compat->num_si= stuff->firstSI+stuff->nSI; + compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret, + compat->num_si, + XkbSymInterpretRec); + if (!compat->sym_interpret) { + compat->num_si= 0; + return BadAlloc; + } + } + else if (stuff->truncateSI) { + compat->num_si = stuff->firstSI+stuff->nSI; + } + sym = &compat->sym_interpret[stuff->firstSI]; + for (i=0;i<stuff->nSI;i++,wire++,sym++) { + if (client->swapped) { + register 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 (stuff->truncateSI) { + compat->num_si = stuff->firstSI; + } + + if (stuff->groups!=0) { + register unsigned i,bit; + xkbModsWireDesc *wire = (xkbModsWireDesc *)data; + for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { + if (stuff->groups&bit) { + if (client->swapped) { + register 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 *)stuff))); + if ((i/4)!=stuff->length) { + ErrorF("Internal length error on read in ProcXkbSetCompatMap\n"); + return BadLength; + } + + if (dev->xkb_interest) { + xkbCompatMapNotify ev; + ev.deviceID = dev->id; + ev.changedGroups = stuff->groups; + ev.firstSI = stuff->firstSI; + ev.nSI = stuff->nSI; + ev.nTotalSI = compat->num_si; + XkbSendCompatMapNotify(dev,&ev); + } + + if (stuff->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); + XkbUpdateCoreDescription(dev,False); + XkbSendNotification(dev,&change,&cause); + } + 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); + + 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; +} + +/***====================================================================***/ + +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; +} + +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= (CARD8 *)ALLOCATE_LOCAL(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); + DEALLOCATE_LOCAL((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); + + 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); +} + +int +ProcXkbSetIndicatorMap(ClientPtr client) +{ + register int i,bit; + int nIndicators,why; + DeviceIntPtr dev; + XkbSrvInfoPtr xkbi; + xkbIndicatorMapWireDesc *from; + XkbSrvLedInfoPtr sli; + XkbEventCauseRec cause; + + REQUEST(xkbSetIndicatorMapReq); + REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + dev = _XkbLookupKeyboard(stuff->deviceSpec,&why); + if (!dev) { + client->errorValue = _XkbErrCode2(why,stuff->deviceSpec); + return XkbKeyboardErrorCode; + } + xkbi= dev->key->xkbInfo; + + 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; + } + + sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, + XkbXI_IndicatorMapsMask); + if (!sli) + return BadAlloc; + + from = (xkbIndicatorMapWireDesc *)&stuff[1]; + for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { + if (stuff->which&bit) { + if (client->swapped) { + register 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]; + for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { + if (stuff->which&bit) { + sli->maps[i].flags = from->flags; + sli->maps[i].which_groups = from->whichGroups; + sli->maps[i].groups = from->groups; + sli->maps[i].which_mods = from->whichMods; + sli->maps[i].mods.mask = from->mods; + sli->maps[i].mods.real_mods = from->mods; + sli->maps[i].mods.vmods= from->virtualMods; + sli->maps[i].ctrls = from->ctrls; + if (from->virtualMods!=0) { + unsigned tmp; + tmp= XkbMaskForVMask(xkbi->desc,from->virtualMods); + sli->maps[i].mods.mask= from->mods|tmp; + } + from++; + } + } + + XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client); + XkbApplyLedMapChanges(dev,sli,stuff->which,NULL,NULL,&cause); + return client->noClientException; +} + +/***====================================================================***/ + +int +ProcXkbGetNamedIndicator(ClientPtr client) +{ + DeviceIntPtr dev; + xkbGetNamedIndicatorReply rep; + register int i = 0; + XkbSrvLedInfoPtr sli; + XkbIndicatorMapPtr map = NULL; + Bool supported; + + REQUEST(xkbGetNamedIndicatorReq); + REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + CHK_LED_DEVICE(dev,stuff->deviceSpec); + CHK_ATOM_ONLY(stuff->indicator); + + sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0); + if (!sli) + return BadAlloc; + + supported= True; + if (XkbXIUnsupported&XkbXI_IndicatorsMask) { + if ((dev!=(DeviceIntPtr)LookupKeyboardDevice())|| + ((sli->flags&XkbSLI_IsDefault)==0)) { + supported= False; + } + } + + if (supported) { + 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)&&(supported)) { + 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= supported; + } + 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); + if (!supported) { + xkbExtensionDeviceNotify edev; + + bzero(&edev,sizeof(xkbExtensionDeviceNotify)); + edev.reason= XkbXI_UnsupportedFeatureMask; + edev.ledClass= stuff->ledClass; + edev.ledID= stuff->ledID; + edev.ledsDefined= sli->namesPresent|sli->mapsPresent; + edev.ledState= sli->effectiveState; + edev.firstBtn= 0; + edev.nBtns= 0; + edev.unsupported= XkbXIUnsupported&XkbXI_IndicatorsMask; + edev.supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported); + XkbSendExtensionDeviceNotify(dev,client,&edev); + } + return client->noClientException; +} + +int +ProcXkbSetNamedIndicator(ClientPtr client) +{ + DeviceIntPtr dev,kbd; + XkbIndicatorMapPtr map; + XkbSrvLedInfoPtr sli; + register int led = 0; + unsigned extDevReason; + unsigned statec,namec,mapc; + XkbEventCauseRec cause; + xkbExtensionDeviceNotify ed; + XkbChangesRec changes; + + REQUEST(xkbSetNamedIndicatorReq); + REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + CHK_LED_DEVICE(dev,stuff->deviceSpec); + CHK_ATOM_ONLY(stuff->indicator); + CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup); + CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods); + + extDevReason= 0; + + sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID, + XkbXI_IndicatorsMask); + if (!sli) + return BadAlloc; + + if (XkbXIUnsupported&XkbXI_IndicatorsMask) { + if ((dev!=(DeviceIntPtr)LookupKeyboardDevice())|| + ((sli->flags&XkbSLI_IsDefault)==0)) { + bzero(&ed,sizeof(xkbExtensionDeviceNotify)); + ed.reason= XkbXI_UnsupportedFeatureMask; + ed.ledClass= stuff->ledClass; + ed.ledID= stuff->ledID; + ed.ledsDefined= sli->namesPresent|sli->mapsPresent; + ed.ledState= sli->effectiveState; + ed.firstBtn= 0; + ed.nBtns= 0; + ed.unsupported= XkbXIUnsupported&XkbXI_IndicatorsMask; + ed.supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported); + XkbSendExtensionDeviceNotify(dev,client,&ed); + return client->noClientException; + } + } + + statec= mapc= namec= 0; + map= NULL; + if (sli->names && sli->maps) { + for (led=0;(led<XkbNumIndicators)&&(map==NULL);led++) { + if (sli->names[led]==stuff->indicator) { + map= &sli->maps[led]; + break; + } + } + } + if (map==NULL) { + if (!stuff->createMap) + return client->noClientException; + for (led=0,map=NULL;(led<XkbNumIndicators)&&(map==NULL);led++) { + if ((sli->names[led]==None)&&(!XkbIM_InUse(&sli->maps[led]))) { + map= &sli->maps[led]; + sli->names[led]= stuff->indicator; + break; + } + } + if (map==NULL) + return client->noClientException; + 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= (DeviceIntPtr)LookupKeyboardDevice(); + XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause); + 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; + + length= rep->length*4; + which= rep->which; + if (client->swapped) { + register int n; + swaps(&rep->sequenceNumber,n); + swapl(&rep->length,n); + swapl(&rep->which,n); + swaps(&rep->virtualMods,n); + swapl(&rep->indicators,n); + } + + start = desc = (char *)ALLOCATE_LOCAL(length); + if ( !start ) + return BadAlloc; + if (which&XkbKeycodesNameMask) { + *((CARD32 *)desc)= xkb->names->keycodes; + if (client->swapped) { + register int n; + swapl(desc,n); + } + desc+= 4; + } + if (which&XkbGeometryNameMask) { + *((CARD32 *)desc)= xkb->names->geometry; + if (client->swapped) { + register int n; + swapl(desc,n); + } + desc+= 4; + } + if (which&XkbSymbolsNameMask) { + *((CARD32 *)desc)= xkb->names->symbols; + if (client->swapped) { + register int n; + swapl(desc,n); + } + desc+= 4; + } + if (which&XkbPhysSymbolsNameMask) { + register CARD32 *atm= (CARD32 *)desc; + atm[0]= (CARD32)xkb->names->phys_symbols; + if (client->swapped) { + register int n; + swapl(&atm[0],n); + } + desc+= 4; + } + if (which&XkbTypesNameMask) { + *((CARD32 *)desc)= (CARD32)xkb->names->types; + if (client->swapped) { + register int n; + swapl(desc,n); + } + desc+= 4; + } + if (which&XkbCompatNameMask) { + *((CARD32 *)desc)= (CARD32)xkb->names->compat; + if (client->swapped) { + register int n; + 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) { + register int n; + swapl(atm,n); + } + } + desc= (char *)atm; + } + if (which&XkbKTLevelNamesMask) { + 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) { + register unsigned n; + 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) { + register unsigned n; + swapl(atm,n); + } + } + desc+= rep->nRadioGroups*4; + } + if ((desc-start)!=(length)) { + ErrorF("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); + DEALLOCATE_LOCAL((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); + CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); + + xkb = dev->key->xkbInfo->desc; + 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) +{ +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; +} + +int +ProcXkbSetNames(ClientPtr client) +{ + DeviceIntPtr dev; + XkbDescRec *xkb; + XkbNamesRec *names; + xkbNamesNotify nn; + CARD32 *tmp; + Atom bad; + + REQUEST(xkbSetNamesReq); + REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + CHK_KBD_DEVICE(dev,stuff->deviceSpec); + CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); + + xkb = dev->key->xkbInfo->desc; + names = xkb->names; + 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; + } + } + if (stuff->which&XkbKeyTypeNamesMask) { + register 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) { + register 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; + } + if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups, + stuff->nKeyAliases)!=Success) { + return BadAlloc; + } + + /* everything is okay -- update names */ + 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) { + _XkbFree(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) { + _XkbFree(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 client->noClientException; +} + +/***====================================================================***/ + +#include <X11/extensions/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; + + len= (str?strlen(str):0); + 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("Unknown doodad type %d in XkbWriteGeomDoodads\n", + doodad->any.type); + ErrorF("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(§ionWire->name,n); + swaps(§ionWire->top,n); + swaps(§ionWire->left,n); + swaps(§ionWire->width,n); + swaps(§ionWire->height,n); + swaps(§ionWire->angle,n); + } + wire= (char *)§ionWire[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,§ion->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= (char *)ALLOCATE_LOCAL(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("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) + DEALLOCATE_LOCAL((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); + 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= (char *)_XkbAlloc(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); + val= _GetCountedString(&wire,client->swapped); + if ((!name)||(!val)||(XkbAddGeomProperty(geom,name,val)==NULL)) + return BadAlloc; + } + + 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)||(!XkbAddGeomColor(geom,name,geom->num_colors))) + return BadAlloc; + } + 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; +} + +int +ProcXkbSetGeometry(ClientPtr client) +{ + DeviceIntPtr dev; + XkbGeometryPtr geom,old; + XkbGeometrySizesRec sizes; + Status status; + XkbDescPtr xkb; + Bool new_name; + xkbNewKeyboardNotify nkn; + + REQUEST(xkbSetGeometryReq); + REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + CHK_KBD_DEVICE(dev,stuff->deviceSpec); + CHK_ATOM_OR_NONE(stuff->name); + + 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 +ProcXkbPerClientFlags(ClientPtr client) +{ + DeviceIntPtr dev; + xkbPerClientFlagsReply rep; + XkbInterestPtr interest; + + REQUEST(xkbPerClientFlagsReq); + REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + CHK_KBD_DEVICE(dev,stuff->deviceSpec); + CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask); + CHK_MASK_MATCH(0x02,stuff->change,stuff->value); + + interest = XkbFindClientResource((DevicePtr)dev,client); + 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= (unsigned char *)_XkbCalloc(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 { + _XkbFree(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); + + status= Success; + str= (unsigned char *)&stuff[1]; + bzero(&list,sizeof(XkbSrvListInfoRec)); + list.maxRtrn= stuff->maxNames; + list.pattern[_XkbListKeymaps]= GetComponentSpec(&str,False,&status); + 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) { + _XkbFree(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 = list.nFound[_XkbListKeymaps]; + 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); + _XkbFree(list.pool); + list.pool= NULL; + } + return client->noClientException; +} + +/***====================================================================***/ + +int +ProcXkbGetKbdByName(ClientPtr client) +{ + DeviceIntPtr dev; + XkbFileInfo finfo; + xkbGetKbdByNameReply rep; + xkbGetMapReply mrep; + xkbGetCompatMapReply crep; + xkbGetIndicatorMapReply irep; + xkbGetNamesReply nrep; + xkbGetGeometryReply grep; + XkbComponentNamesRec names; + XkbDescPtr xkb; + unsigned char * str; + char mapFile[PATH_MAX]; + unsigned len; + unsigned fwant,fneed,reported; + int status; + Bool geom_changed; + + REQUEST(xkbGetKbdByNameReq); + REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + CHK_KBD_DEVICE(dev,stuff->deviceSpec); + + xkb = dev->key->xkbInfo->desc; + status= Success; + str= (unsigned char *)&stuff[1]; + names.keymap= GetComponentSpec(&str,True,&status); + 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.keymap) { + 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; + } + } + else { + geom_changed= True; + } + + 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; + } + rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&finfo, + mapFile,PATH_MAX); + rep.newKeyboard= False; + rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0; + + stuff->want|= stuff->need; + if (finfo.xkb==NULL) + rep.reported= 0; + else { + if (stuff->load) + rep.loaded= True; + if (stuff->load || + ((rep.reported&XkbGBN_SymbolsMask) && (finfo.xkb->compat))) { + XkbChangesRec changes; + bzero(&changes,sizeof(changes)); + XkbUpdateDescActions(finfo.xkb, + finfo.xkb->min_key_code,XkbNumKeys(finfo.xkb), + &changes); + } + + if (finfo.xkb->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 = finfo.xkb->min_key_code; + mrep.maxKeyCode = finfo.xkb->max_key_code; + mrep.present = 0; + mrep.totalSyms = mrep.totalActs = + mrep.totalKeyBehaviors= mrep.totalKeyExplicit= + mrep.totalModMapKeys= 0; + if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) { + mrep.present|= XkbKeyTypesMask; + mrep.firstType = 0; + mrep.nTypes = mrep.totalTypes= finfo.xkb->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= finfo.xkb->min_key_code; + mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(finfo.xkb); + } + 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 = finfo.xkb->min_key_code; + mrep.nKeyActs = mrep.nKeyBehaviors = + mrep.nKeyExplicit = XkbNumKeys(finfo.xkb); + } + else { + mrep.virtualMods= 0; + mrep.firstKeyAct= mrep.firstKeyBehavior= + mrep.firstKeyExplicit = 0; + mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0; + } + XkbComputeGetMapReplySize(finfo.xkb,&mrep); + rep.length+= SIZEOF(xGenericReply)/4+mrep.length; + } + if (finfo.xkb->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= finfo.xkb->compat->num_si; + XkbComputeGetCompatMapReplySize(finfo.xkb->compat,&crep); + rep.length+= SIZEOF(xGenericReply)/4+crep.length; + } + if (finfo.xkb->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(finfo.xkb->indicators,&irep); + rep.length+= SIZEOF(xGenericReply)/4+irep.length; + } + if (finfo.xkb->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= finfo.xkb->min_key_code; + nrep.maxKeyCode= finfo.xkb->max_key_code; + if (rep.reported&XkbGBN_OtherNamesMask) { + nrep.which= XkbAllNamesMask; + if (finfo.xkb->map!=NULL) + nrep.nTypes= finfo.xkb->map->num_types; + else nrep.nTypes= 0; + nrep.nKTLevels= 0; + nrep.groupNames= XkbAllGroupsMask; + nrep.virtualMods= XkbAllVirtualModsMask; + nrep.indicators= XkbAllIndicatorsMask; + nrep.nRadioGroups= finfo.xkb->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= finfo.xkb->min_key_code; + nrep.nKeys= XkbNumKeys(finfo.xkb); + nrep.nKeyAliases= finfo.xkb->names->num_key_aliases; + if (nrep.nKeyAliases) + nrep.which|= XkbKeyAliasesMask; + } + else { + nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask); + nrep.firstKey= nrep.nKeys= 0; + nrep.nKeyAliases= 0; + } + XkbComputeGetNamesReplySize(finfo.xkb,&nrep); + rep.length+= SIZEOF(xGenericReply)/4+nrep.length; + } + if (finfo.xkb->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(finfo.xkb->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,finfo.xkb,&mrep); + if (reported&XkbGBN_CompatMapMask) + XkbSendCompatMap(client,finfo.xkb->compat,&crep); + if (reported&XkbGBN_IndicatorMapMask) + XkbSendIndicatorMap(client,finfo.xkb->indicators,&irep); + if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask)) + XkbSendNames(client,finfo.xkb,&nrep); + if (reported&XkbGBN_GeometryMask) + XkbSendGeometry(client,finfo.xkb->geom,&grep,False); + if (rep.loaded) { + XkbDescPtr old_xkb; + xkbNewKeyboardNotify nkn; + int i,nG,nTG; + old_xkb= xkb; + xkb= finfo.xkb; + dev->key->xkbInfo->desc= xkb; + finfo.xkb= 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; + + memcpy(dev->key->modifierMap,xkb->map->modmap,xkb->max_key_code+1); + XkbUpdateCoreDescription(dev,True); + + if (dev->kbdfeed && dev->kbdfeed->xkb_sli) { + XkbSrvLedInfoPtr old_sli; + XkbSrvLedInfoPtr sli; + old_sli = dev->kbdfeed->xkb_sli; + dev->kbdfeed->xkb_sli = NULL; + sli = XkbAllocSrvLedInfo(dev,dev->kbdfeed,NULL,0); + if (sli) { + sli->explicitState = old_sli->explicitState; + sli->effectiveState = old_sli->effectiveState; + } + dev->kbdfeed->xkb_sli = sli; + XkbFreeSrvLedInfo(old_sli); + } + + nkn.deviceID= nkn.oldDeviceID= dev->id; + nkn.minKeyCode= finfo.xkb->min_key_code; + nkn.maxKeyCode= finfo.xkb->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 ((finfo.xkb!=NULL)&&(finfo.xkb!=xkb)) { + XkbFreeKeyboard(finfo.xkb,XkbAllComponentsMask,True); + finfo.xkb= NULL; + } + if (names.keymap) { _XkbFree(names.keymap); names.keymap= NULL; } + if (names.keycodes) { _XkbFree(names.keycodes); names.keycodes= NULL; } + if (names.types) { _XkbFree(names.types); names.types= NULL; } + if (names.compat) { _XkbFree(names.compat); names.compat= NULL; } + if (names.symbols) { _XkbFree(names.symbols); names.symbols= NULL; } + if (names.geometry) { _XkbFree(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) { + if (rep->supported&XkbXI_IndicatorsMask) { + 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,supported; +char * str; + + REQUEST(xkbGetDeviceInfoReq); + REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + wanted= stuff->wanted; + + CHK_ANY_DEVICE(dev,stuff->deviceSpec); + 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; + wanted&= ~XkbXIUnsupported; + + 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&(~XkbXIUnsupported); + rep.unsupported = XkbXIUnsupported; + 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->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; + supported= rep.supported; + 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= (char*) ALLOCATE_LOCAL(nameLen); + if (!str) + return BadAlloc; + XkbWriteCountedString(str,dev->name,client->swapped); + WriteToClient(client,nameLen,str); + DEALLOCATE_LOCAL(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) { +#ifdef DEBUG + ErrorF("Internal Error! BadLength in ProcXkbGetDeviceInfo\n"); + ErrorF(" Wrote %d fewer bytes than expected\n",length); +#endif + return BadLength; + } + if (stuff->wanted&(~supported)) { + xkbExtensionDeviceNotify ed; + bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify)); + ed.ledClass= ledClass; + ed.ledID= ledID; + ed.ledsDefined= 0; + ed.ledState= 0; + ed.firstBtn= ed.nBtns= 0; + ed.reason= XkbXI_UnsupportedFeatureMask; + ed.supported= supported; + ed.unsupported= stuff->wanted&(~supported); + XkbSendExtensionDeviceNotify(dev,client,&ed); + } + 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= (DeviceIntPtr)LookupKeyboardDevice(); + + XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause); + ledWire= (xkbDeviceLedsWireDesc *)mapWire; + } + return (char *)ledWire; +} + +int +ProcXkbSetDeviceInfo(ClientPtr client) +{ +DeviceIntPtr dev; +unsigned change; +char * wire; +xkbExtensionDeviceNotify ed; + + REQUEST(xkbSetDeviceInfoReq); + REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); + + if (!(client->xkbClientFlags&_XkbClientInitialized)) + return BadAccess; + + change= stuff->change; + + CHK_ANY_DEVICE(dev,stuff->deviceSpec); + CHK_MASK_LEGAL(0x01,change,(XkbXI_AllFeaturesMask&(~XkbXI_KeyboardsMask))); + + wire= (char *)&stuff[1]; + if (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; + + bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify)); + ed.deviceID= dev->id; + wire= (char *)&stuff[1]; + if (change&XkbXI_ButtonActionsMask) { + int nBtns,sz,i; + XkbAction * acts; + DeviceIntPtr kbd; + + nBtns= dev->button->numButtons; + acts= dev->button->xkb_acts; + if (acts==NULL) { + acts= _XkbTypedCalloc(nBtns,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= (DeviceIntPtr)LookupKeyboardDevice(); + 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,change,stuff->nDeviceLedFBs, + &status,client,&ed); + if (status!=Success) + return status; + } + if ((stuff->change)&&(ed.reason)) + XkbSendExtensionDeviceNotify(dev,client,&ed); + return client->noClientException; +} + +/***====================================================================***/ + +int +ProcXkbSetDebuggingFlags(ClientPtr client) +{ +CARD32 newFlags,newCtrls,extraLength; +xkbSetDebuggingFlagsReply rep; + + REQUEST(xkbSetDebuggingFlagsReq); + REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); + + newFlags= xkbDebugFlags&(~stuff->affectFlags); + newFlags|= (stuff->flags&stuff->affectFlags); + newCtrls= xkbDebugCtrls&(~stuff->affectCtrls); + newCtrls|= (stuff->ctrls&stuff->affectCtrls); + if (xkbDebugFlags || newFlags || stuff->msgLength) { + ErrorF("XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags); + if (newCtrls!=xkbDebugCtrls) + ErrorF("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("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("XkbDebug: message not null-terminated\n"); + return BadValue; + } + ErrorF("XkbDebug: %s\n",msg); + } + xkbDebugFlags = newFlags; + xkbDebugCtrls = newCtrls; + + XkbDisableLockActions= (xkbDebugCtrls&XkbDF_DisableLocks); + + 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("Internal Error! bad RemoveResourceClient in XkbClientGone\n"); + } + return 1; +} + +/*ARGSUSED*/ +static void +XkbResetProc(ExtensionEntry *extEntry) +{ +} + +void +XkbExtensionInit(INITARGS) +{ + ExtensionEntry *extEntry; + + if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors, + ProcXkbDispatch, SProcXkbDispatch, + XkbResetProc, StandardMinorOpcode))) { + XkbReqCode = (unsigned char)extEntry->base; + XkbEventBase = (unsigned char)extEntry->eventBase; + XkbErrorBase = (unsigned char)extEntry->errorBase; + XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard; + RT_XKBCLIENT = CreateNewResourceType(XkbClientGone); + } + return; +} + + diff --git a/nx-X11/programs/Xserver/xkb/xkb.h b/nx-X11/programs/Xserver/xkb/xkb.h new file mode 100644 index 000000000..704cd49c0 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkb.h @@ -0,0 +1,72 @@ +/* $XFree86$ */ + +/* #include "XKBfile.h" */ + +extern int ProcXkbUseExtension(ClientPtr client); +extern int ProcXkbSelectEvents(ClientPtr client); +extern int ProcXkbBell(ClientPtr client); +extern int ProcXkbGetState(ClientPtr client); +extern int ProcXkbLatchLockState(ClientPtr client); +extern int ProcXkbGetControls(ClientPtr client); +extern int ProcXkbSetControls(ClientPtr client); +extern int ProcXkbGetMap(ClientPtr client); +extern int ProcXkbSetMap(ClientPtr client); +extern int ProcXkbGetCompatMap(ClientPtr client); +extern int ProcXkbSetCompatMap(ClientPtr client); +extern int ProcXkbGetIndicatorState(ClientPtr client); +extern int ProcXkbGetIndicatorMap(ClientPtr client); +extern int ProcXkbSetIndicatorMap(ClientPtr client); +extern int ProcXkbGetNamedIndicator(ClientPtr client); +extern int ProcXkbSetNamedIndicator(ClientPtr client); +extern int ProcXkbGetNames(ClientPtr client); +extern int ProcXkbSetNames(ClientPtr client); +extern int ProcXkbGetGeometry(ClientPtr client); +extern int ProcXkbSetGeometry(ClientPtr client); +extern int ProcXkbPerClientFlags(ClientPtr client); +extern int ProcXkbListComponents(ClientPtr client); +extern int ProcXkbGetKbdByName(ClientPtr client); +extern int ProcXkbGetDeviceInfo(ClientPtr client); +extern int ProcXkbSetDeviceInfo(ClientPtr client); +extern int ProcXkbSetDebuggingFlags(ClientPtr client); + +extern int XkbSetRepeatRate(DeviceIntPtr dev, int timeout, int interval, int major, int minor); +extern int XkbGetRepeatRate(DeviceIntPtr dev, int *timeout, int *interval); + +extern Status XkbComputeGetIndicatorMapReplySize( + XkbIndicatorPtr indicators, + xkbGetIndicatorMapReply *rep); +extern int XkbSendIndicatorMap( + ClientPtr client, + XkbIndicatorPtr indicators, + xkbGetIndicatorMapReply *rep); + +extern void XkbComputeCompatState(XkbSrvInfoPtr xkbi); +extern void XkbSetPhysicalLockingKey(DeviceIntPtr dev, unsigned key); + +extern Bool XkbFilterEvents(ClientPtr pClient, int nEvents, xEvent *xE); + +extern Bool XkbApplyLEDChangeToKeyboard( + XkbSrvInfoPtr xkbi, + XkbIndicatorMapPtr map, + Bool on, + XkbChangesPtr change); + +extern Bool XkbWriteRulesProp(ClientPtr client, pointer closure); + +extern XkbAction XkbGetButtonAction(DeviceIntPtr kbd, DeviceIntPtr dev, int button); + +/* extern Status XkbMergeFile(XkbDescPtr xkb, XkbFileInfo finfo); */ + +extern Bool XkbDDXCompileNamedKeymap( + XkbDescPtr xkb, + XkbComponentNamesPtr names, + char * nameRtrn, + int nameRtrnLen); + +extern Bool XkbDDXCompileKeymapByNames( + XkbDescPtr xkb, + XkbComponentNamesPtr names, + unsigned want, + unsigned need, + char * nameRtrn, + int nameRtrnLen); diff --git a/nx-X11/programs/Xserver/xkb/xkbAccessX.c b/nx-X11/programs/Xserver/xkb/xkbAccessX.c new file mode 100644 index 000000000..b31ca7ed5 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbAccessX.c @@ -0,0 +1,754 @@ +/* $Xorg: xkbAccessX.c,v 1.4 2001/02/05 18:50:20 coskrey Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/xkbAccessX.c,v 1.9 2001/08/23 14:33:25 alanh Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <math.h> +#ifdef __QNX__ +#include <limits.h> +#endif +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "inputstr.h" +#include <X11/extensions/XKBsrv.h> +#if !defined(WIN32) && !defined(Lynx) +#include <sys/time.h> +#endif + +int XkbDfltRepeatDelay= 660; +int XkbDfltRepeatInterval= 40; +pointer XkbLastRepeatEvent= NULL; + +#define DFLT_TIMEOUT_CTRLS (XkbAX_KRGMask|XkbStickyKeysMask|XkbMouseKeysMask) +#define DFLT_TIMEOUT_OPTS (XkbAX_IndicatorFBMask) + +unsigned short XkbDfltAccessXTimeout= 120; +unsigned int XkbDfltAccessXTimeoutMask= DFLT_TIMEOUT_CTRLS; +unsigned int XkbDfltAccessXTimeoutValues= 0; +unsigned int XkbDfltAccessXTimeoutOptionsMask= DFLT_TIMEOUT_OPTS; +unsigned int XkbDfltAccessXTimeoutOptionsValues= 0; +unsigned int XkbDfltAccessXFeedback= XkbAccessXFeedbackMask; +unsigned short XkbDfltAccessXOptions= XkbAX_AllOptionsMask & ~(XkbAX_IndicatorFBMask|XkbAX_SKReleaseFBMask|XkbAX_SKRejectFBMask); + +void +AccessXComputeCurveFactor(XkbSrvInfoPtr xkbi,XkbControlsPtr ctrls) +{ + xkbi->mouseKeysCurve= 1.0+(((double)ctrls->mk_curve)*0.001); + xkbi->mouseKeysCurveFactor= ( ((double)ctrls->mk_max_speed)/ + pow((double)ctrls->mk_time_to_max,xkbi->mouseKeysCurve)); + return; +} + +void +AccessXInit(DeviceIntPtr keybd) +{ +XkbSrvInfoPtr xkbi = keybd->key->xkbInfo; +XkbControlsPtr ctrls = xkbi->desc->ctrls; + + xkbi->shiftKeyCount= 0; + xkbi->mouseKeysCounter= 0; + xkbi->inactiveKey= 0; + xkbi->slowKey= 0; + xkbi->repeatKey= 0; + xkbi->krgTimerActive= _OFF_TIMER; + xkbi->beepType= _BEEP_NONE; + xkbi->beepCount= 0; + xkbi->mouseKeyTimer= NULL; + xkbi->slowKeysTimer= NULL; + xkbi->bounceKeysTimer= NULL; + xkbi->repeatKeyTimer= NULL; + xkbi->krgTimer= NULL; + xkbi->beepTimer= NULL; + ctrls->repeat_delay = XkbDfltRepeatDelay; + ctrls->repeat_interval = XkbDfltRepeatInterval; + ctrls->debounce_delay = 300; + ctrls->slow_keys_delay = 300; + ctrls->mk_delay = 160; + ctrls->mk_interval = 40; + ctrls->mk_time_to_max = 30; + ctrls->mk_max_speed = 30; + ctrls->mk_curve = 500; + ctrls->mk_dflt_btn = 1; + ctrls->ax_timeout = XkbDfltAccessXTimeout; + ctrls->axt_ctrls_mask = XkbDfltAccessXTimeoutMask; + ctrls->axt_ctrls_values = XkbDfltAccessXTimeoutValues; + ctrls->axt_opts_mask = XkbDfltAccessXTimeoutOptionsMask; + ctrls->axt_opts_values = XkbDfltAccessXTimeoutOptionsValues; + if (XkbDfltAccessXTimeout) + ctrls->enabled_ctrls |= XkbAccessXTimeoutMask; + else + ctrls->enabled_ctrls &= ~XkbAccessXTimeoutMask; + ctrls->enabled_ctrls |= XkbDfltAccessXFeedback; + ctrls->ax_options = XkbDfltAccessXOptions; + AccessXComputeCurveFactor(xkbi,ctrls); + return; +} + +/************************************************************************/ +/* */ +/* AccessXKeyboardEvent */ +/* */ +/* Generate a synthetic keyboard event. */ +/* */ +/************************************************************************/ +static void +AccessXKeyboardEvent(DeviceIntPtr keybd, + BYTE type, + BYTE keyCode, + Bool isRepeat) +{ +xEvent xE; + + xE.u.u.type = type; + xE.u.u.detail = keyCode; + xE.u.keyButtonPointer.time = GetTimeInMillis(); +#ifdef DEBUG + if (xkbDebugFlags&0x8) { + ErrorF("AXKE: Key %d %s\n",keyCode,(xE.u.u.type==KeyPress?"down":"up")); + } +#endif + + if (_XkbIsPressEvent(type)) + XkbDDXKeyClick(keybd,keyCode,TRUE); + else if (isRepeat) + XkbLastRepeatEvent= (pointer)&xE; + XkbProcessKeyboardEvent(&xE,keybd,1L); + XkbLastRepeatEvent= NULL; + return; + +} /* AccessXKeyboardEvent */ + +/************************************************************************/ +/* */ +/* AccessXKRGTurnOn */ +/* */ +/* Turn the keyboard response group on. */ +/* */ +/************************************************************************/ +static void +AccessXKRGTurnOn(DeviceIntPtr dev,CARD16 KRGControl,xkbControlsNotify *pCN) +{ +XkbSrvInfoPtr xkbi = dev->key->xkbInfo; +XkbControlsPtr ctrls = xkbi->desc->ctrls; +XkbControlsRec old; +XkbEventCauseRec cause; +XkbSrvLedInfoPtr sli; + + old= *ctrls; + ctrls->enabled_ctrls |= (KRGControl&XkbAX_KRGMask); + if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False)) + XkbSendControlsNotify(dev,pCN); + cause.kc= pCN->keycode; + cause.event= pCN->eventType; + cause.mjr= pCN->requestMajor; + cause.mnr= pCN->requestMinor; + sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); + XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause); + if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) + XkbDDXAccessXBeep(dev,_BEEP_FEATURE_ON,KRGControl); + return; + +} /* AccessXKRGTurnOn */ + +/************************************************************************/ +/* */ +/* AccessXKRGTurnOff */ +/* */ +/* Turn the keyboard response group off. */ +/* */ +/************************************************************************/ +static void +AccessXKRGTurnOff(DeviceIntPtr dev,xkbControlsNotify *pCN) +{ +XkbSrvInfoPtr xkbi = dev->key->xkbInfo; +XkbControlsPtr ctrls = xkbi->desc->ctrls; +XkbControlsRec old; +XkbEventCauseRec cause; +XkbSrvLedInfoPtr sli; + + old = *ctrls; + ctrls->enabled_ctrls &= ~XkbAX_KRGMask; + if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False)) + XkbSendControlsNotify(dev,pCN); + cause.kc= pCN->keycode; + cause.event= pCN->eventType; + cause.mjr= pCN->requestMajor; + cause.mnr= pCN->requestMinor; + sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); + XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause); + if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) { + unsigned changes= old.enabled_ctrls^ctrls->enabled_ctrls; + XkbDDXAccessXBeep(dev,_BEEP_FEATURE_OFF,changes); + } + return; + +} /* AccessXKRGTurnOff */ + +/************************************************************************/ +/* */ +/* AccessXStickyKeysTurnOn */ +/* */ +/* Turn StickyKeys on. */ +/* */ +/************************************************************************/ +static void +AccessXStickyKeysTurnOn(DeviceIntPtr dev,xkbControlsNotify *pCN) +{ +XkbSrvInfoPtr xkbi = dev->key->xkbInfo; +XkbControlsPtr ctrls = xkbi->desc->ctrls; +XkbControlsRec old; +XkbEventCauseRec cause; +XkbSrvLedInfoPtr sli; + + old = *ctrls; + ctrls->enabled_ctrls |= XkbStickyKeysMask; + xkbi->shiftKeyCount = 0; + if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False)) + XkbSendControlsNotify(dev,pCN); + cause.kc= pCN->keycode; + cause.event= pCN->eventType; + cause.mjr= pCN->requestMajor; + cause.mnr= pCN->requestMinor; + sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); + XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause); + if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) { + XkbDDXAccessXBeep(dev,_BEEP_FEATURE_ON,XkbStickyKeysMask); + } + return; + +} /* AccessXStickyKeysTurnOn */ + +/************************************************************************/ +/* */ +/* AccessXStickyKeysTurnOff */ +/* */ +/* Turn StickyKeys off. */ +/* */ +/************************************************************************/ +static void +AccessXStickyKeysTurnOff(DeviceIntPtr dev,xkbControlsNotify *pCN) +{ +XkbSrvInfoPtr xkbi = dev->key->xkbInfo; +XkbControlsPtr ctrls = xkbi->desc->ctrls; +XkbControlsRec old; +XkbEventCauseRec cause; +XkbSrvLedInfoPtr sli; + + old = *ctrls; + ctrls->enabled_ctrls &= ~XkbStickyKeysMask; + xkbi->shiftKeyCount = 0; + if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False)) + XkbSendControlsNotify(dev,pCN); + + cause.kc= pCN->keycode; + cause.event= pCN->eventType; + cause.mjr= pCN->requestMajor; + cause.mnr= pCN->requestMinor; + sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); + XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause); + if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) { + XkbDDXAccessXBeep(dev,_BEEP_FEATURE_OFF,XkbStickyKeysMask); + } +#ifndef NO_CLEAR_LATCHES_FOR_STICKY_KEYS_OFF + XkbClearAllLatchesAndLocks(dev,xkbi,False,&cause); +#endif + return; +} /* AccessXStickyKeysTurnOff */ + +static CARD32 +AccessXKRGExpire(OsTimerPtr timer,CARD32 now,pointer arg) +{ +XkbSrvInfoPtr xkbi= ((DeviceIntPtr)arg)->key->xkbInfo; +xkbControlsNotify cn; + + if (xkbi->krgTimerActive==_KRG_WARN_TIMER) { + XkbDDXAccessXBeep((DeviceIntPtr)arg,_BEEP_SLOW_WARN,XkbStickyKeysMask); + xkbi->krgTimerActive= _KRG_TIMER; + return 4000; + } + xkbi->krgTimerActive= _OFF_TIMER; + cn.keycode = 0; + cn.eventType = 0; + cn.requestMajor = 0; + cn.requestMinor = 0; + if (xkbi->desc->ctrls->enabled_ctrls&XkbSlowKeysMask) + AccessXKRGTurnOff((DeviceIntPtr)arg,&cn); + else AccessXKRGTurnOn((DeviceIntPtr)arg,XkbSlowKeysMask,&cn); + return 0; +} + +static CARD32 +AccessXRepeatKeyExpire(OsTimerPtr timer,CARD32 now,pointer arg) +{ +XkbSrvInfoPtr xkbi= ((DeviceIntPtr)arg)->key->xkbInfo; +KeyCode key; + + if (xkbi->repeatKey==0) + return 0; + key= xkbi->repeatKey; + AccessXKeyboardEvent((DeviceIntPtr)arg,KeyRelease,key,True); + AccessXKeyboardEvent((DeviceIntPtr)arg,KeyPress,key,True); + return xkbi->desc->ctrls->repeat_interval; +} + +void +AccessXCancelRepeatKey(XkbSrvInfoPtr xkbi,KeyCode key) +{ + if (xkbi->repeatKey==key) + xkbi->repeatKey= 0; + return; +} + +static CARD32 +AccessXSlowKeyExpire(OsTimerPtr timer,CARD32 now,pointer arg) +{ +DeviceIntPtr keybd; +XkbSrvInfoPtr xkbi; +XkbDescPtr xkb; +XkbControlsPtr ctrls; + + keybd= (DeviceIntPtr)arg; + xkbi= keybd->key->xkbInfo; + xkb= xkbi->desc; + ctrls= xkb->ctrls; + if (xkbi->slowKey!=0) { + xkbAccessXNotify ev; + KeySym *sym= XkbKeySymsPtr(xkb,xkbi->slowKey); + ev.detail= XkbAXN_SKAccept; + ev.keycode= xkbi->slowKey; + ev.slowKeysDelay= ctrls->slow_keys_delay; + ev.debounceDelay= ctrls->debounce_delay; + XkbSendAccessXNotify(keybd,&ev); + if (XkbAX_NeedFeedback(ctrls,XkbAX_SKAcceptFBMask)) + XkbDDXAccessXBeep(keybd,_BEEP_SLOW_ACCEPT,XkbSlowKeysMask); + AccessXKeyboardEvent(keybd,KeyPress,xkbi->slowKey,False); + /* check for magic sequences */ + if ((ctrls->enabled_ctrls&XkbAccessXKeysMask) && + ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L))) + xkbi->shiftKeyCount++; + + /* Start repeating if necessary. Stop autorepeating if the user + * presses a non-modifier key that doesn't autorepeat. + */ + if (keybd->kbdfeed->ctrl.autoRepeat && + ((xkbi->slowKey != xkbi->mouseKey) || (!xkbi->mouseKeysAccel)) && + (ctrls->enabled_ctrls&XkbRepeatKeysMask)) { +#ifndef AIXV3 + if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,xkbi->slowKey)) +#endif + { + xkbi->repeatKey = xkbi->slowKey; + xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer, + 0, ctrls->repeat_delay, + AccessXRepeatKeyExpire, (pointer)keybd); + } + } + } + return 0; +} + +static CARD32 +AccessXBounceKeyExpire(OsTimerPtr timer,CARD32 now,pointer arg) +{ +XkbSrvInfoPtr xkbi= ((DeviceIntPtr)arg)->key->xkbInfo; + + xkbi->inactiveKey= 0; + return 0; +} + +static CARD32 +AccessXTimeoutExpire(OsTimerPtr timer,CARD32 now,pointer arg) +{ +DeviceIntPtr dev = (DeviceIntPtr)arg; +XkbSrvInfoPtr xkbi= dev->key->xkbInfo; +XkbControlsPtr ctrls= xkbi->desc->ctrls; +XkbControlsRec old; +xkbControlsNotify cn; +XkbEventCauseRec cause; +XkbSrvLedInfoPtr sli; + + if (xkbi->lastPtrEventTime) { + unsigned timeToWait = (ctrls->ax_timeout*1000); + unsigned timeElapsed = (now-xkbi->lastPtrEventTime); + + if (timeToWait > timeElapsed) + return (timeToWait - timeElapsed); + } + old= *ctrls; + xkbi->shiftKeyCount= 0; + ctrls->enabled_ctrls&= ~ctrls->axt_ctrls_mask; + ctrls->enabled_ctrls|= + (ctrls->axt_ctrls_values&ctrls->axt_ctrls_mask); + if (ctrls->axt_opts_mask) { + ctrls->ax_options&= ~ctrls->axt_opts_mask; + ctrls->ax_options|= (ctrls->axt_opts_values&ctrls->axt_opts_mask); + } + if (XkbComputeControlsNotify(dev,&old,ctrls,&cn,False)) { + cn.keycode = 0; + cn.eventType = 0; + cn.requestMajor = 0; + cn.requestMinor = 0; + XkbSendControlsNotify(dev,&cn); + } + XkbSetCauseUnknown(&cause); + sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); + XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause); + if (ctrls->ax_options!=old.ax_options) { + unsigned set,cleared,bell; + set= ctrls->ax_options&(~old.ax_options); + cleared= (~ctrls->ax_options)&old.ax_options; + if (set && cleared) bell= _BEEP_FEATURE_CHANGE; + else if (set) bell= _BEEP_FEATURE_ON; + else bell= _BEEP_FEATURE_OFF; + XkbDDXAccessXBeep(dev,bell,XkbAccessXTimeoutMask); + } + xkbi->krgTimerActive= _OFF_TIMER; + return 0; +} + + +/************************************************************************/ +/* */ +/* AccessXFilterPressEvent */ +/* */ +/* Filter events before they get any further if SlowKeys is turned on. */ +/* In addition, this routine handles the ever so popular magic key */ +/* acts for turning various accessibility features on/off. */ +/* */ +/* Returns TRUE if this routine has discarded the event. */ +/* Returns FALSE if the event needs further processing. */ +/* */ +/************************************************************************/ +Bool +AccessXFilterPressEvent( register xEvent * xE, + register DeviceIntPtr keybd, + int count) +{ +XkbSrvInfoPtr xkbi = keybd->key->xkbInfo; +XkbControlsPtr ctrls = xkbi->desc->ctrls; +Bool ignoreKeyEvent = FALSE; +KeyCode key = xE->u.u.detail; +KeySym * sym = XkbKeySymsPtr(xkbi->desc,key); + + if (ctrls->enabled_ctrls&XkbAccessXKeysMask) { + /* check for magic sequences */ + if ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L)) { + if (XkbAX_NeedFeedback(ctrls,XkbAX_SlowWarnFBMask)) { + xkbi->krgTimerActive = _KRG_WARN_TIMER; + xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 4000, + AccessXKRGExpire, (pointer)keybd); + } + else { + xkbi->krgTimerActive = _KRG_TIMER; + xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 8000, + AccessXKRGExpire, (pointer)keybd); + } + if (!(ctrls->enabled_ctrls & XkbSlowKeysMask)) { + CARD32 now= GetTimeInMillis(); + if ((now-xkbi->lastShiftEventTime)>15000) + xkbi->shiftKeyCount= 1; + else xkbi->shiftKeyCount++; + xkbi->lastShiftEventTime= now; + } + } + else { + if (xkbi->krgTimerActive) { + xkbi->krgTimer= TimerSet(xkbi->krgTimer,0, 0, NULL, NULL); + xkbi->krgTimerActive= _OFF_TIMER; + } + } + } + + /* Don't transmit the KeyPress if SlowKeys is turned on; + * The wakeup handler will synthesize one for us if the user + * has held the key long enough. + */ + if (ctrls->enabled_ctrls & XkbSlowKeysMask) { + xkbAccessXNotify ev; + /* If key was already pressed, ignore subsequent press events + * from the server's autorepeat + */ + if(xkbi->slowKey == key) + return TRUE; + ev.detail= XkbAXN_SKPress; + ev.keycode= key; + ev.slowKeysDelay= ctrls->slow_keys_delay; + ev.debounceDelay= ctrls->debounce_delay; + XkbSendAccessXNotify(keybd,&ev); + if (XkbAX_NeedFeedback(ctrls,XkbAX_SKPressFBMask)) + XkbDDXAccessXBeep(keybd,_BEEP_SLOW_PRESS,XkbSlowKeysMask); + xkbi->slowKey= key; + xkbi->slowKeysTimer = TimerSet(xkbi->slowKeysTimer, + 0, ctrls->slow_keys_delay, + AccessXSlowKeyExpire, (pointer)keybd); + ignoreKeyEvent = TRUE; + } + + /* Don't transmit the KeyPress if BounceKeys is turned on + * and the user pressed the same key within a given time period + * from the last release. + */ + else if ((ctrls->enabled_ctrls & XkbBounceKeysMask) && + (key == xkbi->inactiveKey)) { + if (XkbAX_NeedFeedback(ctrls,XkbAX_BKRejectFBMask)) + XkbDDXAccessXBeep(keybd,_BEEP_BOUNCE_REJECT,XkbBounceKeysMask); + ignoreKeyEvent = TRUE; + } + + /* Start repeating if necessary. Stop autorepeating if the user + * presses a non-modifier key that doesn't autorepeat. + */ + if (XkbDDXUsesSoftRepeat(keybd)) { + if ((keybd->kbdfeed->ctrl.autoRepeat) && + ((ctrls->enabled_ctrls&(XkbSlowKeysMask|XkbRepeatKeysMask))== + XkbRepeatKeysMask)) { +#ifndef AIXV3 + if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,key)) +#endif + { +#ifdef DEBUG + if (xkbDebugFlags&0x10) + ErrorF("Starting software autorepeat...\n"); +#endif + xkbi->repeatKey = key; + xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer, + 0, ctrls->repeat_delay, + AccessXRepeatKeyExpire, (pointer)keybd); + } + } + } + + /* Check for two keys being pressed at the same time. This section + * essentially says the following: + * + * If StickyKeys is on, and a modifier is currently being held down, + * and one of the following is true: the current key is not a modifier + * or the currentKey is a modifier, but not the only modifier being + * held down, turn StickyKeys off if the TwoKeys off ctrl is set. + */ + if ((ctrls->enabled_ctrls & XkbStickyKeysMask) && + (xkbi->state.base_mods!=0) && + (XkbAX_NeedOption(ctrls,XkbAX_TwoKeysMask))) { + xkbControlsNotify cn; + cn.keycode = key; + cn.eventType = KeyPress; + cn.requestMajor = 0; + cn.requestMinor = 0; + AccessXStickyKeysTurnOff(keybd,&cn); + } + + if (!ignoreKeyEvent) + XkbProcessKeyboardEvent(xE,keybd,count); + return ignoreKeyEvent; +} /* AccessXFilterPressEvent */ + +/************************************************************************/ +/* */ +/* AccessXFilterReleaseEvent */ +/* */ +/* Filter events before they get any further if SlowKeys is turned on. */ +/* In addition, this routine handles the ever so popular magic key */ +/* acts for turning various accessibility features on/off. */ +/* */ +/* Returns TRUE if this routine has discarded the event. */ +/* Returns FALSE if the event needs further processing. */ +/* */ +/************************************************************************/ +Bool +AccessXFilterReleaseEvent( register xEvent * xE, + register DeviceIntPtr keybd, + int count) +{ +XkbSrvInfoPtr xkbi = keybd->key->xkbInfo; +XkbControlsPtr ctrls = xkbi->desc->ctrls; +KeyCode key = xE->u.u.detail; +Bool ignoreKeyEvent = FALSE; + + /* Don't transmit the KeyRelease if BounceKeys is on and + * this is the release of a key that was ignored due to + * BounceKeys. + */ + if (ctrls->enabled_ctrls & XkbBounceKeysMask) { + if ((key!=xkbi->mouseKey)&&(!BitIsOn(keybd->key->down,key))) + ignoreKeyEvent = TRUE; + xkbi->inactiveKey= key; + xkbi->bounceKeysTimer= TimerSet(xkbi->bounceKeysTimer, 0, + ctrls->debounce_delay, + AccessXBounceKeyExpire, (pointer)keybd); + } + + /* Don't transmit the KeyRelease if SlowKeys is turned on and + * the user didn't hold the key long enough. We know we passed + * the key if the down bit was set by CoreProcessKeyboadEvent. + */ + if (ctrls->enabled_ctrls & XkbSlowKeysMask) { + xkbAccessXNotify ev; + unsigned beep_type; + ev.keycode= key; + ev.slowKeysDelay= ctrls->slow_keys_delay; + ev.debounceDelay= ctrls->debounce_delay; + if (BitIsOn(keybd->key->down,key) | (xkbi->mouseKey == key)) { + ev.detail= XkbAXN_SKRelease; + beep_type= _BEEP_SLOW_RELEASE; + } + else { + ev.detail= XkbAXN_SKReject; + beep_type= _BEEP_SLOW_REJECT; + ignoreKeyEvent = TRUE; + } + XkbSendAccessXNotify(keybd,&ev); + if (XkbAX_NeedFeedback(ctrls,XkbAX_SKRejectFBMask)) { + XkbDDXAccessXBeep(keybd,beep_type,XkbSlowKeysMask); + } + if (xkbi->slowKey==key) + xkbi->slowKey= 0; + } + + /* Stop Repeating if the user releases the key that is currently + * repeating. + */ + if (xkbi->repeatKey==key) { + xkbi->repeatKey= 0; + } + + if ((ctrls->enabled_ctrls&XkbAccessXTimeoutMask)&&(ctrls->ax_timeout>0)) { + xkbi->lastPtrEventTime= 0; + xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, + ctrls->ax_timeout*1000, + AccessXTimeoutExpire, (pointer)keybd); + xkbi->krgTimerActive= _ALL_TIMEOUT_TIMER; + } + else if (xkbi->krgTimerActive!=_OFF_TIMER) { + xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 0, NULL, NULL); + xkbi->krgTimerActive= _OFF_TIMER; + } + + /* Keep track of how many times the Shift key has been pressed. + * If it has been pressed and released 5 times in a row, toggle + * the state of StickyKeys. + */ + if ((!ignoreKeyEvent)&&(xkbi->shiftKeyCount)) { + KeySym *pSym= XkbKeySymsPtr(xkbi->desc,key); + if ((pSym[0]!=XK_Shift_L)&&(pSym[0]!=XK_Shift_R)) { + xkbi->shiftKeyCount= 0; + } + else if (xkbi->shiftKeyCount>=5) { + xkbControlsNotify cn; + cn.keycode = key; + cn.eventType = KeyPress; + cn.requestMajor = 0; + cn.requestMinor = 0; + if (ctrls->enabled_ctrls & XkbStickyKeysMask) + AccessXStickyKeysTurnOff(keybd,&cn); + else + AccessXStickyKeysTurnOn(keybd,&cn); + xkbi->shiftKeyCount= 0; + } + } + + if (!ignoreKeyEvent) + XkbProcessKeyboardEvent(xE,keybd,count); + return ignoreKeyEvent; + +} /* AccessXFilterReleaseEvent */ + +/************************************************************************/ +/* */ +/* ProcessPointerEvent */ +/* */ +/* This routine merely sets the shiftKeyCount and clears the keyboard */ +/* response group timer (if necessary) on a mouse event. This is so */ +/* multiple shifts with just the mouse and shift-drags with the mouse */ +/* don't accidentally turn on StickyKeys or the Keyboard Response Group.*/ +/* */ +/************************************************************************/ +void +ProcessPointerEvent( register xEvent * xE, + register DeviceIntPtr mouse, + int count) +{ +DeviceIntPtr dev = (DeviceIntPtr)LookupKeyboardDevice(); +XkbSrvInfoPtr xkbi = dev->key->xkbInfo; +unsigned changed = 0; + + xkbi->shiftKeyCount = 0; + xkbi->lastPtrEventTime= xE->u.keyButtonPointer.time; + + if (xE->u.u.type==ButtonPress) { + changed |= XkbPointerButtonMask; + } + else if (xE->u.u.type==ButtonRelease) { + xkbi->lockedPtrButtons&= ~(1<<(xE->u.u.detail&0x7)); + changed |= XkbPointerButtonMask; + } + CoreProcessPointerEvent(xE,mouse,count); + + xkbi->state.ptr_buttons = mouse->button->state; + + /* clear any latched modifiers */ + if ( xkbi->state.latched_mods && (xE->u.u.type==ButtonRelease) ) { + unsigned changed_leds; + XkbStateRec oldState; + XkbSrvLedInfoPtr sli; + + sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); + oldState= xkbi->state; + XkbLatchModifiers(dev,0xFF,0x00); + + XkbComputeDerivedState(xkbi); + changed |= XkbStateChangedFlags(&oldState,&xkbi->state); + if (changed&sli->usedComponents) { + changed_leds= XkbIndicatorsToUpdate(dev,changed,False); + if (changed_leds) { + XkbEventCauseRec cause; + XkbSetCauseKey(&cause,(xE->u.u.detail&0x7),xE->u.u.type); + XkbUpdateIndicators(dev,changed_leds,True,NULL,&cause); + } + } + dev->key->state= XkbStateFieldFromRec(&xkbi->state); + } + + if (((xkbi->flags&_XkbStateNotifyInProgress)==0)&&(changed!=0)) { + xkbStateNotify sn; + sn.keycode= xE->u.u.detail; + sn.eventType= xE->u.u.type; + sn.requestMajor = sn.requestMinor = 0; + sn.changed= changed; + XkbSendStateNotify(dev,&sn); + } + +} /* ProcessPointerEvent */ + + + + diff --git a/nx-X11/programs/Xserver/xkb/xkbActions.c b/nx-X11/programs/Xserver/xkb/xkbActions.c new file mode 100644 index 000000000..b767658f3 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbActions.c @@ -0,0 +1,1432 @@ +/* $Xorg: xkbActions.c,v 1.3 2000/08/17 19:53:47 cpqbld Exp $ */ +/* $XdotOrg: xc/programs/Xserver/xkb/xkbActions.c,v 1.7 2005/07/03 08:53:54 daniels Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/xkbActions.c,v 3.13 2003/07/16 01:39:08 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <math.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "misc.h" +#include "inputstr.h" +#include <X11/extensions/XKBsrv.h> +#include "xkb.h" +#include <ctype.h> + +static unsigned int _xkbServerGeneration; +int xkbDevicePrivateIndex = -1; + +void +xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, + pointer data) +{ + xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); + ProcessInputProc tmp = device->public.processInputProc; + if(xkbPrivPtr->unwrapProc) + xkbPrivPtr->unwrapProc = NULL; + + UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr); + proc(device,data); + WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, + tmp,xkbUnwrapProc); +} + + +void +XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc) +{ + xkbDeviceInfoPtr xkbPrivPtr; + + if (serverGeneration != _xkbServerGeneration) { + if ((xkbDevicePrivateIndex = AllocateDevicePrivateIndex()) == -1) + return; + _xkbServerGeneration = serverGeneration; + } + if (!AllocateDevicePrivate(device, xkbDevicePrivateIndex)) + return; + + xkbPrivPtr = (xkbDeviceInfoPtr) xalloc(sizeof(xkbDeviceInfoRec)); + if (!xkbPrivPtr) + return; + xkbPrivPtr->unwrapProc = NULL; + + device->devPrivates[xkbDevicePrivateIndex].ptr = xkbPrivPtr; + WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, + proc,xkbUnwrapProc); +} + +#ifdef XINPUT +extern void ProcessOtherEvent( + xEvent * /* xE */, + DeviceIntPtr /* dev */, + int /* count */ +); +#endif + +/***====================================================================***/ + +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 (XkbDisableLockActions) { + switch (act->type) { + case XkbSA_LockMods: + fake.mods.type = XkbSA_SetMods; + fake.mods.flags = 0; + fake.mods.mask = act->mods.mask; + return fake; + case XkbSA_LatchMods: + fake.mods.type = XkbSA_SetMods; + fake.mods.flags = 0; + fake.mods.mask = act->mods.mask; + return fake; + case XkbSA_ISOLock: + if (act->iso.flags&XkbSA_ISODfltIsGroup) { + fake.group.type = XkbSA_SetGroup; + fake.group.flags = act->iso.flags&XkbSA_GroupAbsolute; + XkbSASetGroup(&fake.group,XkbSAGroup(&act->iso)); + } + else { + fake.mods.type = XkbSA_SetMods; + fake.mods.flags = 0; + fake.mods.mask = act->iso.mask; + } + return fake; + case XkbSA_LockGroup: + case XkbSA_LatchGroup: + /* We want everything from the latch/lock action except the + * type should be changed to set. + */ + fake = *act; + fake.group.type = XkbSA_SetGroup; + return fake; + } + } + else + 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= xkbState->group; + if (effectiveGroup!=XkbGroup1Index) { + if (XkbKeyNumGroups(xkb,key)>(unsigned)1) { + if (effectiveGroup>=XkbKeyNumGroups(xkb,key)) { + unsigned gi= XkbKeyGroupInfo(xkb,key); + switch (XkbOutOfRangeGroupAction(gi)) { + default: + case XkbWrapIntoRange: + effectiveGroup %= XkbKeyNumGroups(xkb,key); + break; + case XkbClampIntoRange: + effectiveGroup = XkbKeyNumGroups(xkb,key)-1; + break; + case XkbRedirectIntoRange: + effectiveGroup= XkbOutOfRangeGroupInfo(gi); + if (effectiveGroup>=XkbKeyNumGroups(xkb,key)) + effectiveGroup= 0; + break; + } + } + } + else 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; +} + +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 + +typedef struct _XkbFilter { + CARD16 keycode; + CARD8 what; + CARD8 active; + CARD8 filterOthers; + CARD32 priv; + XkbAction upAction; + int (*filter)( + XkbSrvInfoPtr /* xkbi */, + struct _XkbFilter * /* filter */, + unsigned /* keycode */, + XkbAction * /* action */ + ); + struct _XkbFilter *next; +} XkbFilterRec,*XkbFilterPtr; + +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; + } + XkbDDXFakePointerMotion(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 (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); + XkbDDXFakePointerMotion(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); + XkbDDXFakePointerButton(ButtonPress,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++) { + XkbDDXFakePointerButton(ButtonPress,button); + XkbDDXFakePointerButton(ButtonRelease,button); + } + filter->upAction.type= XkbSA_NoAction; + } + else XkbDDXFakePointerButton(ButtonPress,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; + 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: + XkbDDXFakePointerButton(ButtonRelease,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; + 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) +{ +unsigned realMods; +xEvent ev; +int x,y; +XkbStateRec old; +unsigned mods,mask,oldCoreState = 0,oldCorePrevState = 0; +xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device); + + if ((filter->keycode!=0)&&(filter->keycode!=keycode)) + return 1; + + GetSpritePosition(&x,&y); + ev.u.keyButtonPointer.time = GetTimeInMillis(); + ev.u.keyButtonPointer.rootX = x; + ev.u.keyButtonPointer.rootY = 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.u.u.type = KeyPress; + ev.u.u.detail = 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; + oldCoreState= xkbi->device->key->state; + oldCorePrevState= xkbi->device->key->prev_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); + xkbi->device->key->state= xkbi->device->key->prev_state= + xkbi->state.mods; + } + + realMods = xkbi->device->key->modifierMap[ev.u.u.detail]; + xkbi->device->key->modifierMap[ev.u.u.detail] = 0; + UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr); + xkbi->device->public.processInputProc(&ev,xkbi->device,1); + COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, + ProcessKeyboardEvent,xkbUnwrapProc); + xkbi->device->key->modifierMap[ev.u.u.detail] = realMods; + + if ( mask || mods ) { + xkbi->device->key->state= oldCoreState; + xkbi->device->key->prev_state= oldCorePrevState; + xkbi->state= old; + } + } + else if (filter->keycode==keycode) { + + ev.u.u.type = KeyRelease; + ev.u.u.detail = 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; + oldCoreState= xkbi->device->key->state; + oldCorePrevState= xkbi->device->key->prev_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); + xkbi->device->key->state= xkbi->device->key->prev_state= + xkbi->state.mods; + } + + realMods = xkbi->device->key->modifierMap[ev.u.u.detail]; + xkbi->device->key->modifierMap[ev.u.u.detail] = 0; + UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr); + xkbi->device->public.processInputProc(&ev,xkbi->device,1); + COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, + ProcessKeyboardEvent,xkbUnwrapProc); + xkbi->device->key->modifierMap[ev.u.u.detail] = realMods; + + if ( mask || mods ) { + xkbi->device->key->state= oldCoreState; + xkbi->device->key->prev_state= oldCorePrevState; + xkbi->state= old; + } + + filter->keycode= 0; + filter->active= 0; + } + return 0; +} + +static int +_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi, + XkbFilterPtr filter, + unsigned keycode, + XkbAction * pAction) +{ + if (filter->keycode==0) { /* initial press */ + DeviceIntPtr dev = xkbi->device; + 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; +} + +#ifdef XFree86Server +static int +_XkbFilterXF86Private( XkbSrvInfoPtr xkbi, + XkbFilterPtr filter, + unsigned keycode, + XkbAction * pAction) +{ + if (filter->keycode==0) { /* initial press */ + DeviceIntPtr dev = xkbi->device; + 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; +} +#endif + +#ifdef XINPUT + +static int +_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi, + XkbFilterPtr filter, + unsigned keycode, + XkbAction * pAction) +{ +DeviceIntPtr dev; +int button; + + if (filter->keycode==0) { /* initial press */ + dev= _XkbLookupButtonDevice(pAction->devbtn.device,NULL); + if ((!dev)||(!dev->public.on)||(&dev->public==LookupPointerDevice())) + 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)|| + (dev->button->down[button/8]&(1L<<(button%8)))) + return 0; + XkbDDXFakeDeviceButton(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++) { + XkbDDXFakeDeviceButton(dev,True,button); + XkbDDXFakeDeviceButton(dev,False,button); + } + filter->upAction.type= XkbSA_NoAction; + } + else XkbDDXFakeDeviceButton(dev,True,button); + break; + } + } + else if (filter->keycode==keycode) { + int button; + + filter->active= 0; + dev= _XkbLookupButtonDevice(filter->upAction.devbtn.device,NULL); + if ((!dev)||(!dev->public.on)||(&dev->public==LookupPointerDevice())) + return 1; + + button= filter->upAction.btn.button; + switch (filter->upAction.type) { + case XkbSA_LockDeviceBtn: + if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)|| + ((dev->button->down[button/8]&(1L<<(button%8)))==0)) + return 0; + XkbDDXFakeDeviceButton(dev,False,button); + break; + case XkbSA_DeviceBtn: + XkbDDXFakeDeviceButton(dev,False,button); + break; + } + filter->active = 0; + } + return 0; +} +#endif + +static int szFilters = 0; +static XkbFilterPtr filters = NULL; + +static XkbFilterPtr +_XkbNextFreeFilter( + void +) +{ +register int i; + + if (szFilters==0) { + szFilters = 4; + filters = _XkbTypedCalloc(szFilters,XkbFilterRec); + /* 6/21/93 (ef) -- XXX! deal with allocation failure */ + } + for (i=0;i<szFilters;i++) { + if (!filters[i].active) { + filters[i].keycode = 0; + return &filters[i]; + } + } + szFilters*=2; + filters= _XkbTypedRealloc(filters,szFilters,XkbFilterRec); + /* 6/21/93 (ef) -- XXX! deal with allocation failure */ + bzero(&filters[szFilters/2],(szFilters/2)*sizeof(XkbFilterRec)); + return &filters[szFilters/2]; +} + +static int +_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction) +{ +register int i,send; + + send= 1; + for (i=0;i<szFilters;i++) { + if ((filters[i].active)&&(filters[i].filter)) + send= ((*filters[i].filter)(xkbi,&filters[i],kc,pAction)&&send); + } + return send; +} + +void +XkbHandleActions(DeviceIntPtr dev,DeviceIntPtr kbd,xEvent *xE,int count) +{ +int key,bit,i; +CARD8 realMods; +XkbSrvInfoPtr xkbi; +KeyClassPtr keyc; +int changed,sendEvent; +Bool genStateNotify; +XkbStateRec oldState; +XkbAction act; +XkbFilterPtr filter; +Bool keyEvent; +Bool pressEvent; +#ifdef XINPUT +Bool xiEvent; +#endif + +xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); + + keyc= kbd->key; + xkbi= keyc->xkbInfo; + key= xE->u.u.detail; + if ((xkbi->flags&_XkbStateNotifyInProgress)==0) { + oldState= xkbi->state; + xkbi->flags|= _XkbStateNotifyInProgress; + genStateNotify= True; + } + else genStateNotify= False; + + xkbi->clearMods = xkbi->setMods = 0; + xkbi->groupChange = 0; + + sendEvent = 1; +#ifdef XINPUT + keyEvent= ((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)|| + (xE->u.u.type==KeyRelease)||(xE->u.u.type==DeviceKeyRelease)); + pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)|| + (xE->u.u.type==ButtonPress)||(xE->u.u.type==DeviceButtonPress); + xiEvent= (xE->u.u.type==DeviceKeyPress)||(xE->u.u.type==DeviceKeyRelease)|| + (xE->u.u.type==DeviceButtonPress)|| + (xE->u.u.type==DeviceButtonRelease); +#else + keyEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease); + pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==ButtonPress); +#endif + + 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(); + sendEvent = _XkbFilterSetState(xkbi,filter,key,&act); + break; + case XkbSA_LatchMods: + case XkbSA_LatchGroup: + filter = _XkbNextFreeFilter(); + sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act); + break; + case XkbSA_LockMods: + case XkbSA_LockGroup: + filter = _XkbNextFreeFilter(); + sendEvent=_XkbFilterLockState(xkbi,filter,key,&act); + break; + case XkbSA_ISOLock: + filter = _XkbNextFreeFilter(); + sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act); + break; + case XkbSA_MovePtr: + filter = _XkbNextFreeFilter(); + sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act); + break; + case XkbSA_PtrBtn: + case XkbSA_LockPtrBtn: + case XkbSA_SetPtrDflt: + filter = _XkbNextFreeFilter(); + sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act); + break; + case XkbSA_Terminate: + sendEvent= XkbDDXTerminateServer(dev,key,&act); + break; + case XkbSA_SwitchScreen: + filter = _XkbNextFreeFilter(); + sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act); + break; + case XkbSA_SetControls: + case XkbSA_LockControls: + filter = _XkbNextFreeFilter(); + sendEvent=_XkbFilterControls(xkbi,filter,key,&act); + break; + case XkbSA_ActionMessage: + filter = _XkbNextFreeFilter(); + sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act); + break; + case XkbSA_RedirectKey: + filter = _XkbNextFreeFilter(); + sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act); + break; +#ifdef XINPUT + case XkbSA_DeviceBtn: + case XkbSA_LockDeviceBtn: + filter = _XkbNextFreeFilter(); + sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act); + break; +#endif +#ifdef XFree86Server + case XkbSA_XFree86Private: + filter = _XkbNextFreeFilter(); + sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act); + break; +#endif + } + } + } + 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) { +#ifdef XINPUT + if (xiEvent) + ProcessOtherEvent(xE,dev,count); + else +#endif + if (keyEvent) { + realMods = keyc->modifierMap[key]; + keyc->modifierMap[key] = 0; + UNWRAP_PROCESS_INPUT_PROC(dev,xkbPrivPtr); + dev->public.processInputProc(xE,dev,count); + COND_WRAP_PROCESS_INPUT_PROC(dev, xkbPrivPtr, + ProcessKeyboardEvent,xkbUnwrapProc); + keyc->modifierMap[key] = realMods; + } + else CoreProcessPointerEvent(xE,dev,count); + } + else if (keyEvent) + FixKeyState(xE,dev); + + xkbi->prev_state= oldState; + XkbComputeDerivedState(xkbi); + keyc->prev_state= keyc->state; + keyc->state= XkbStateFieldFromRec(&xkbi->state); + changed = XkbStateChangedFlags(&oldState,&xkbi->state); + if (genStateNotify) { + if (changed) { + xkbStateNotify sn; + sn.keycode= key; + sn.eventType= xE->u.u.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,xE->u.u.type); + XkbUpdateIndicators(dev,changed,True,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(); + _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(); + _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; +} + diff --git a/nx-X11/programs/Xserver/xkb/xkbDflts.h b/nx-X11/programs/Xserver/xkb/xkbDflts.h new file mode 100644 index 000000000..e0b54c55b --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbDflts.h @@ -0,0 +1,524 @@ +/* $Xorg: xkbDflts.h,v 1.3 2000/08/17 19:53:47 cpqbld Exp $ */ +/* $XFree86: xc/programs/Xserver/xkb/xkbDflts.h,v 1.2 2001/10/28 03:34:20 tsi Exp $ */ +/* This file generated automatically by xkbcomp */ +/* DO NOT EDIT */ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef DEFAULT_H +#define DEFAULT_H 1 + +#ifndef XKB_IN_SERVER +#define GET_ATOM(d,s) XInternAtom(d,s,0) +#define DPYTYPE Display * +#else +#define GET_ATOM(d,s) MakeAtom(s,strlen(s),1) +#define DPYTYPE char * +#endif +#define NUM_KEYS 1 + +#define vmod_NumLock 0 +#define vmod_Alt 1 +#define vmod_LevelThree 2 +#define vmod_AltGr 3 +#define vmod_ScrollLock 4 + +#define vmod_NumLockMask (1<<0) +#define vmod_AltMask (1<<1) +#define vmod_LevelThreeMask (1<<2) +#define vmod_AltGrMask (1<<3) +#define vmod_ScrollLockMask (1<<4) + +/* types name is "default" */ +static Atom lnames_ONE_LEVEL[1]; + +static XkbKTMapEntryRec map_TWO_LEVEL[1]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } } +}; +static Atom lnames_TWO_LEVEL[2]; + +static XkbKTMapEntryRec map_ALPHABETIC[2]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } }, + { 1, 0, { LockMask, LockMask, 0 } } +}; +static XkbModsRec preserve_ALPHABETIC[2]= { + { 0, 0, 0 }, + { LockMask, LockMask, 0 } +}; +static Atom lnames_ALPHABETIC[2]; + +static XkbKTMapEntryRec map_KEYPAD[2]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } }, + { 0, 1, { 0, 0, vmod_NumLockMask } } +}; +static Atom lnames_KEYPAD[2]; + +static XkbKTMapEntryRec map_PC_BREAK[1]= { + { 1, 1, { ControlMask, ControlMask, 0 } } +}; +static Atom lnames_PC_BREAK[2]; + +static XkbKTMapEntryRec map_PC_SYSRQ[1]= { + { 0, 1, { 0, 0, vmod_AltMask } } +}; +static Atom lnames_PC_SYSRQ[2]; + +static XkbKTMapEntryRec map_CTRL_ALT[1]= { + { 0, 1, { ControlMask, ControlMask, vmod_AltMask } } +}; +static Atom lnames_CTRL_ALT[2]; + +static XkbKTMapEntryRec map_THREE_LEVEL[3]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } }, + { 0, 2, { 0, 0, vmod_LevelThreeMask } }, + { 0, 2, { ShiftMask, ShiftMask, vmod_LevelThreeMask } } +}; +static Atom lnames_THREE_LEVEL[3]; + +static XkbKTMapEntryRec map_SHIFT_ALT[1]= { + { 0, 1, { ShiftMask, ShiftMask, vmod_AltMask } } +}; +static Atom lnames_SHIFT_ALT[2]; + +static XkbKeyTypeRec dflt_types[]= { + { + { 0, 0, 0 }, + 1, + 0, NULL, NULL, + None, lnames_ONE_LEVEL + }, + { + { ShiftMask, ShiftMask, 0 }, + 2, + 1, map_TWO_LEVEL, NULL, + None, lnames_TWO_LEVEL + }, + { + { ShiftMask|LockMask, ShiftMask|LockMask, 0 }, + 2, + 2, map_ALPHABETIC, preserve_ALPHABETIC, + None, lnames_ALPHABETIC + }, + { + { ShiftMask, ShiftMask, vmod_NumLockMask }, + 2, + 2, map_KEYPAD, NULL, + None, lnames_KEYPAD + }, + { + { ControlMask, ControlMask, 0 }, + 2, + 1, map_PC_BREAK, NULL, + None, lnames_PC_BREAK + }, + { + { 0, 0, vmod_AltMask }, + 2, + 1, map_PC_SYSRQ, NULL, + None, lnames_PC_SYSRQ + }, + { + { ControlMask, ControlMask, vmod_AltMask }, + 2, + 1, map_CTRL_ALT, NULL, + None, lnames_CTRL_ALT + }, + { + { ShiftMask, ShiftMask, vmod_LevelThreeMask }, + 3, + 3, map_THREE_LEVEL, NULL, + None, lnames_THREE_LEVEL + }, + { + { ShiftMask, ShiftMask, vmod_AltMask }, + 2, + 1, map_SHIFT_ALT, NULL, + None, lnames_SHIFT_ALT + } +}; +#define num_dflt_types (sizeof(dflt_types)/sizeof(XkbKeyTypeRec)) + + +static void +initTypeNames(DPYTYPE dpy) +{ + dflt_types[0].name= GET_ATOM(dpy,"ONE_LEVEL"); + lnames_ONE_LEVEL[0]= GET_ATOM(dpy,"Any"); + dflt_types[1].name= GET_ATOM(dpy,"TWO_LEVEL"); + lnames_TWO_LEVEL[0]= GET_ATOM(dpy,"Base"); + lnames_TWO_LEVEL[1]= GET_ATOM(dpy,"Shift"); + dflt_types[2].name= GET_ATOM(dpy,"ALPHABETIC"); + lnames_ALPHABETIC[0]= GET_ATOM(dpy,"Base"); + lnames_ALPHABETIC[1]= GET_ATOM(dpy,"Caps"); + dflt_types[3].name= GET_ATOM(dpy,"KEYPAD"); + lnames_KEYPAD[0]= GET_ATOM(dpy,"Base"); + lnames_KEYPAD[1]= GET_ATOM(dpy,"Number"); + dflt_types[4].name= GET_ATOM(dpy,"PC_BREAK"); + lnames_PC_BREAK[0]= GET_ATOM(dpy,"Base"); + lnames_PC_BREAK[1]= GET_ATOM(dpy,"Control"); + dflt_types[5].name= GET_ATOM(dpy,"PC_SYSRQ"); + lnames_PC_SYSRQ[0]= GET_ATOM(dpy,"Base"); + lnames_PC_SYSRQ[1]= GET_ATOM(dpy,"Alt"); + dflt_types[6].name= GET_ATOM(dpy,"CTRL+ALT"); + lnames_CTRL_ALT[0]= GET_ATOM(dpy,"Base"); + lnames_CTRL_ALT[1]= GET_ATOM(dpy,"Ctrl+Alt"); + dflt_types[7].name= GET_ATOM(dpy,"THREE_LEVEL"); + lnames_THREE_LEVEL[0]= GET_ATOM(dpy,"Base"); + lnames_THREE_LEVEL[1]= GET_ATOM(dpy,"Shift"); + lnames_THREE_LEVEL[2]= GET_ATOM(dpy,"Level3"); + dflt_types[8].name= GET_ATOM(dpy,"SHIFT+ALT"); + lnames_SHIFT_ALT[0]= GET_ATOM(dpy,"Base"); + lnames_SHIFT_ALT[1]= GET_ATOM(dpy,"Shift+Alt"); +} +/* compat name is "default" */ +static XkbSymInterpretRec dfltSI[69]= { + { XK_ISO_Level2_Latch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_Exactly, ShiftMask, + 255, + { XkbSA_LatchMods, { 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Eisu_Shift, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Eisu_toggle, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Kana_Shift, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Kana_Lock, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Shift_Lock, 0x0000, + XkbSI_AnyOf, ShiftMask|LockMask, + 255, + { XkbSA_LockMods, { 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Num_Lock, 0x0000, + XkbSI_AnyOf, 0xff, + 0, + { XkbSA_LockMods, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_Alt_L, 0x0000, + XkbSI_AnyOf, 0xff, + 1, + { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Alt_R, 0x0000, + XkbSI_AnyOf, 0xff, + 1, + { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Scroll_Lock, 0x0000, + XkbSI_AnyOf, 0xff, + 4, + { XkbSA_LockMods, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Lock, 0x0000, + XkbSI_AnyOf, 0xff, + 255, + { XkbSA_ISOLock, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Level3_Shift, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOf, 0xff, + 2, + { XkbSA_SetMods, { 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } } }, + { XK_ISO_Level3_Latch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOf, 0xff, + 2, + { XkbSA_LatchMods, { 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } } }, + { XK_Mode_switch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_SetGroup, { 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_1, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_End, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_2, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_Down, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_3, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_Next, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_4, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Left, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_6, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Right, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_7, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_Home, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_8, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_Up, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_9, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_Prior, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_5, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Begin, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_F1, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Divide, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_F2, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Multiply, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_F3, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Subtract, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Separator, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Add, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_0, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Insert, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Decimal, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Delete, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button_Dflt, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button1, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button2, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button3, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick_Dflt, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick1, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick2, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick3, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag_Dflt, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag1, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag2, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag3, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_EnableKeys, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00 } } }, + { XK_Pointer_Accelerate, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00 } } }, + { XK_Pointer_DfltBtnNext, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DfltBtnPrev, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_AccessX_Enable, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 } } }, + +#ifndef NX_TRANS_SOCKET + + /* + * Make sure that the server can't be killed + * by pressing this key-sequence. + */ + + { XK_Terminate_Server, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_Terminate, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + +#endif + + { XK_ISO_Group_Latch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_LatchGroup, { 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Next_Group, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_LockGroup, { 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Prev_Group, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_LockGroup, { 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_First_Group, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockGroup, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Last_Group, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockGroup, { 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { NoSymbol, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_LockMods, { 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { NoSymbol, 0x0000, + XkbSI_AnyOf, 0xff, + 255, + { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } } +}; +#define num_dfltSI (sizeof(dfltSI)/sizeof(XkbSymInterpretRec)) + +static XkbCompatMapRec compatMap= { + dfltSI, + { /* group compatibility */ + { 0, 0, 0 }, + { 0, 0, vmod_AltGrMask }, + { 0, 0, vmod_AltGrMask }, + { 0, 0, vmod_AltGrMask } + }, + num_dfltSI, num_dfltSI +}; + +static XkbIndicatorRec indicators= { + 0x0, + { + { 0x80, 0, 0x00, XkbIM_UseEffective, { LockMask, LockMask, 0 }, 0 }, + { 0x80, 0, 0x00, XkbIM_UseEffective, { 0, 0, vmod_NumLockMask }, 0 }, + { 0x80, 0, 0x00, XkbIM_UseLocked, { ShiftMask, ShiftMask, 0 }, 0 }, + { 0x80, 0, 0x00, 0, { 0, 0, 0 }, XkbMouseKeysMask }, + { 0x80, 0, 0x00, XkbIM_UseLocked, { 0, 0, vmod_ScrollLockMask }, 0 }, + { 0x80, XkbIM_UseEffective, 0xfe, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 } + } +}; +static void +initIndicatorNames(DPYTYPE dpy,XkbDescPtr xkb) +{ + xkb->names->indicators[ 0]= GET_ATOM(dpy,"Caps Lock"); + xkb->names->indicators[ 1]= GET_ATOM(dpy,"Num Lock"); + xkb->names->indicators[ 2]= GET_ATOM(dpy,"Shift Lock"); + xkb->names->indicators[ 3]= GET_ATOM(dpy,"Mouse Keys"); + xkb->names->indicators[ 4]= GET_ATOM(dpy,"Scroll Lock"); + xkb->names->indicators[ 5]= GET_ATOM(dpy,"Group 2"); +} +#endif /* DEFAULT_H */ diff --git a/nx-X11/programs/Xserver/xkb/xkbDflts.h.NX.original b/nx-X11/programs/Xserver/xkb/xkbDflts.h.NX.original new file mode 100644 index 000000000..e0b54c55b --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbDflts.h.NX.original @@ -0,0 +1,524 @@ +/* $Xorg: xkbDflts.h,v 1.3 2000/08/17 19:53:47 cpqbld Exp $ */ +/* $XFree86: xc/programs/Xserver/xkb/xkbDflts.h,v 1.2 2001/10/28 03:34:20 tsi Exp $ */ +/* This file generated automatically by xkbcomp */ +/* DO NOT EDIT */ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef DEFAULT_H +#define DEFAULT_H 1 + +#ifndef XKB_IN_SERVER +#define GET_ATOM(d,s) XInternAtom(d,s,0) +#define DPYTYPE Display * +#else +#define GET_ATOM(d,s) MakeAtom(s,strlen(s),1) +#define DPYTYPE char * +#endif +#define NUM_KEYS 1 + +#define vmod_NumLock 0 +#define vmod_Alt 1 +#define vmod_LevelThree 2 +#define vmod_AltGr 3 +#define vmod_ScrollLock 4 + +#define vmod_NumLockMask (1<<0) +#define vmod_AltMask (1<<1) +#define vmod_LevelThreeMask (1<<2) +#define vmod_AltGrMask (1<<3) +#define vmod_ScrollLockMask (1<<4) + +/* types name is "default" */ +static Atom lnames_ONE_LEVEL[1]; + +static XkbKTMapEntryRec map_TWO_LEVEL[1]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } } +}; +static Atom lnames_TWO_LEVEL[2]; + +static XkbKTMapEntryRec map_ALPHABETIC[2]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } }, + { 1, 0, { LockMask, LockMask, 0 } } +}; +static XkbModsRec preserve_ALPHABETIC[2]= { + { 0, 0, 0 }, + { LockMask, LockMask, 0 } +}; +static Atom lnames_ALPHABETIC[2]; + +static XkbKTMapEntryRec map_KEYPAD[2]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } }, + { 0, 1, { 0, 0, vmod_NumLockMask } } +}; +static Atom lnames_KEYPAD[2]; + +static XkbKTMapEntryRec map_PC_BREAK[1]= { + { 1, 1, { ControlMask, ControlMask, 0 } } +}; +static Atom lnames_PC_BREAK[2]; + +static XkbKTMapEntryRec map_PC_SYSRQ[1]= { + { 0, 1, { 0, 0, vmod_AltMask } } +}; +static Atom lnames_PC_SYSRQ[2]; + +static XkbKTMapEntryRec map_CTRL_ALT[1]= { + { 0, 1, { ControlMask, ControlMask, vmod_AltMask } } +}; +static Atom lnames_CTRL_ALT[2]; + +static XkbKTMapEntryRec map_THREE_LEVEL[3]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } }, + { 0, 2, { 0, 0, vmod_LevelThreeMask } }, + { 0, 2, { ShiftMask, ShiftMask, vmod_LevelThreeMask } } +}; +static Atom lnames_THREE_LEVEL[3]; + +static XkbKTMapEntryRec map_SHIFT_ALT[1]= { + { 0, 1, { ShiftMask, ShiftMask, vmod_AltMask } } +}; +static Atom lnames_SHIFT_ALT[2]; + +static XkbKeyTypeRec dflt_types[]= { + { + { 0, 0, 0 }, + 1, + 0, NULL, NULL, + None, lnames_ONE_LEVEL + }, + { + { ShiftMask, ShiftMask, 0 }, + 2, + 1, map_TWO_LEVEL, NULL, + None, lnames_TWO_LEVEL + }, + { + { ShiftMask|LockMask, ShiftMask|LockMask, 0 }, + 2, + 2, map_ALPHABETIC, preserve_ALPHABETIC, + None, lnames_ALPHABETIC + }, + { + { ShiftMask, ShiftMask, vmod_NumLockMask }, + 2, + 2, map_KEYPAD, NULL, + None, lnames_KEYPAD + }, + { + { ControlMask, ControlMask, 0 }, + 2, + 1, map_PC_BREAK, NULL, + None, lnames_PC_BREAK + }, + { + { 0, 0, vmod_AltMask }, + 2, + 1, map_PC_SYSRQ, NULL, + None, lnames_PC_SYSRQ + }, + { + { ControlMask, ControlMask, vmod_AltMask }, + 2, + 1, map_CTRL_ALT, NULL, + None, lnames_CTRL_ALT + }, + { + { ShiftMask, ShiftMask, vmod_LevelThreeMask }, + 3, + 3, map_THREE_LEVEL, NULL, + None, lnames_THREE_LEVEL + }, + { + { ShiftMask, ShiftMask, vmod_AltMask }, + 2, + 1, map_SHIFT_ALT, NULL, + None, lnames_SHIFT_ALT + } +}; +#define num_dflt_types (sizeof(dflt_types)/sizeof(XkbKeyTypeRec)) + + +static void +initTypeNames(DPYTYPE dpy) +{ + dflt_types[0].name= GET_ATOM(dpy,"ONE_LEVEL"); + lnames_ONE_LEVEL[0]= GET_ATOM(dpy,"Any"); + dflt_types[1].name= GET_ATOM(dpy,"TWO_LEVEL"); + lnames_TWO_LEVEL[0]= GET_ATOM(dpy,"Base"); + lnames_TWO_LEVEL[1]= GET_ATOM(dpy,"Shift"); + dflt_types[2].name= GET_ATOM(dpy,"ALPHABETIC"); + lnames_ALPHABETIC[0]= GET_ATOM(dpy,"Base"); + lnames_ALPHABETIC[1]= GET_ATOM(dpy,"Caps"); + dflt_types[3].name= GET_ATOM(dpy,"KEYPAD"); + lnames_KEYPAD[0]= GET_ATOM(dpy,"Base"); + lnames_KEYPAD[1]= GET_ATOM(dpy,"Number"); + dflt_types[4].name= GET_ATOM(dpy,"PC_BREAK"); + lnames_PC_BREAK[0]= GET_ATOM(dpy,"Base"); + lnames_PC_BREAK[1]= GET_ATOM(dpy,"Control"); + dflt_types[5].name= GET_ATOM(dpy,"PC_SYSRQ"); + lnames_PC_SYSRQ[0]= GET_ATOM(dpy,"Base"); + lnames_PC_SYSRQ[1]= GET_ATOM(dpy,"Alt"); + dflt_types[6].name= GET_ATOM(dpy,"CTRL+ALT"); + lnames_CTRL_ALT[0]= GET_ATOM(dpy,"Base"); + lnames_CTRL_ALT[1]= GET_ATOM(dpy,"Ctrl+Alt"); + dflt_types[7].name= GET_ATOM(dpy,"THREE_LEVEL"); + lnames_THREE_LEVEL[0]= GET_ATOM(dpy,"Base"); + lnames_THREE_LEVEL[1]= GET_ATOM(dpy,"Shift"); + lnames_THREE_LEVEL[2]= GET_ATOM(dpy,"Level3"); + dflt_types[8].name= GET_ATOM(dpy,"SHIFT+ALT"); + lnames_SHIFT_ALT[0]= GET_ATOM(dpy,"Base"); + lnames_SHIFT_ALT[1]= GET_ATOM(dpy,"Shift+Alt"); +} +/* compat name is "default" */ +static XkbSymInterpretRec dfltSI[69]= { + { XK_ISO_Level2_Latch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_Exactly, ShiftMask, + 255, + { XkbSA_LatchMods, { 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Eisu_Shift, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Eisu_toggle, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Kana_Shift, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Kana_Lock, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Shift_Lock, 0x0000, + XkbSI_AnyOf, ShiftMask|LockMask, + 255, + { XkbSA_LockMods, { 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Num_Lock, 0x0000, + XkbSI_AnyOf, 0xff, + 0, + { XkbSA_LockMods, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_Alt_L, 0x0000, + XkbSI_AnyOf, 0xff, + 1, + { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Alt_R, 0x0000, + XkbSI_AnyOf, 0xff, + 1, + { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Scroll_Lock, 0x0000, + XkbSI_AnyOf, 0xff, + 4, + { XkbSA_LockMods, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Lock, 0x0000, + XkbSI_AnyOf, 0xff, + 255, + { XkbSA_ISOLock, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Level3_Shift, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOf, 0xff, + 2, + { XkbSA_SetMods, { 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } } }, + { XK_ISO_Level3_Latch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOf, 0xff, + 2, + { XkbSA_LatchMods, { 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } } }, + { XK_Mode_switch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_SetGroup, { 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_1, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_End, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_2, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_Down, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_3, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_Next, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_4, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Left, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_6, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Right, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_7, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_Home, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_8, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_Up, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_9, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_Prior, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_5, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Begin, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_F1, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Divide, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_F2, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Multiply, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_F3, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Subtract, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Separator, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Add, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_0, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Insert, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Decimal, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Delete, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button_Dflt, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button1, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button2, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button3, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick_Dflt, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick1, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick2, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick3, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag_Dflt, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag1, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag2, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag3, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_EnableKeys, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00 } } }, + { XK_Pointer_Accelerate, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00 } } }, + { XK_Pointer_DfltBtnNext, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DfltBtnPrev, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_AccessX_Enable, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 } } }, + +#ifndef NX_TRANS_SOCKET + + /* + * Make sure that the server can't be killed + * by pressing this key-sequence. + */ + + { XK_Terminate_Server, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_Terminate, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + +#endif + + { XK_ISO_Group_Latch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_LatchGroup, { 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Next_Group, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_LockGroup, { 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Prev_Group, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_LockGroup, { 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_First_Group, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockGroup, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Last_Group, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockGroup, { 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { NoSymbol, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_LockMods, { 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { NoSymbol, 0x0000, + XkbSI_AnyOf, 0xff, + 255, + { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } } +}; +#define num_dfltSI (sizeof(dfltSI)/sizeof(XkbSymInterpretRec)) + +static XkbCompatMapRec compatMap= { + dfltSI, + { /* group compatibility */ + { 0, 0, 0 }, + { 0, 0, vmod_AltGrMask }, + { 0, 0, vmod_AltGrMask }, + { 0, 0, vmod_AltGrMask } + }, + num_dfltSI, num_dfltSI +}; + +static XkbIndicatorRec indicators= { + 0x0, + { + { 0x80, 0, 0x00, XkbIM_UseEffective, { LockMask, LockMask, 0 }, 0 }, + { 0x80, 0, 0x00, XkbIM_UseEffective, { 0, 0, vmod_NumLockMask }, 0 }, + { 0x80, 0, 0x00, XkbIM_UseLocked, { ShiftMask, ShiftMask, 0 }, 0 }, + { 0x80, 0, 0x00, 0, { 0, 0, 0 }, XkbMouseKeysMask }, + { 0x80, 0, 0x00, XkbIM_UseLocked, { 0, 0, vmod_ScrollLockMask }, 0 }, + { 0x80, XkbIM_UseEffective, 0xfe, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 } + } +}; +static void +initIndicatorNames(DPYTYPE dpy,XkbDescPtr xkb) +{ + xkb->names->indicators[ 0]= GET_ATOM(dpy,"Caps Lock"); + xkb->names->indicators[ 1]= GET_ATOM(dpy,"Num Lock"); + xkb->names->indicators[ 2]= GET_ATOM(dpy,"Shift Lock"); + xkb->names->indicators[ 3]= GET_ATOM(dpy,"Mouse Keys"); + xkb->names->indicators[ 4]= GET_ATOM(dpy,"Scroll Lock"); + xkb->names->indicators[ 5]= GET_ATOM(dpy,"Group 2"); +} +#endif /* DEFAULT_H */ diff --git a/nx-X11/programs/Xserver/xkb/xkbDflts.h.X.original b/nx-X11/programs/Xserver/xkb/xkbDflts.h.X.original new file mode 100644 index 000000000..e3dd9cdda --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbDflts.h.X.original @@ -0,0 +1,513 @@ +/* $Xorg: xkbDflts.h,v 1.3 2000/08/17 19:53:47 cpqbld Exp $ */ +/* $XFree86: xc/programs/Xserver/xkb/xkbDflts.h,v 1.2 2001/10/28 03:34:20 tsi Exp $ */ +/* This file generated automatically by xkbcomp */ +/* DO NOT EDIT */ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef DEFAULT_H +#define DEFAULT_H 1 + +#ifndef XKB_IN_SERVER +#define GET_ATOM(d,s) XInternAtom(d,s,0) +#define DPYTYPE Display * +#else +#define GET_ATOM(d,s) MakeAtom(s,strlen(s),1) +#define DPYTYPE char * +#endif +#define NUM_KEYS 1 + +#define vmod_NumLock 0 +#define vmod_Alt 1 +#define vmod_LevelThree 2 +#define vmod_AltGr 3 +#define vmod_ScrollLock 4 + +#define vmod_NumLockMask (1<<0) +#define vmod_AltMask (1<<1) +#define vmod_LevelThreeMask (1<<2) +#define vmod_AltGrMask (1<<3) +#define vmod_ScrollLockMask (1<<4) + +/* types name is "default" */ +static Atom lnames_ONE_LEVEL[1]; + +static XkbKTMapEntryRec map_TWO_LEVEL[1]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } } +}; +static Atom lnames_TWO_LEVEL[2]; + +static XkbKTMapEntryRec map_ALPHABETIC[2]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } }, + { 1, 0, { LockMask, LockMask, 0 } } +}; +static XkbModsRec preserve_ALPHABETIC[2]= { + { 0, 0, 0 }, + { LockMask, LockMask, 0 } +}; +static Atom lnames_ALPHABETIC[2]; + +static XkbKTMapEntryRec map_KEYPAD[2]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } }, + { 0, 1, { 0, 0, vmod_NumLockMask } } +}; +static Atom lnames_KEYPAD[2]; + +static XkbKTMapEntryRec map_PC_BREAK[1]= { + { 1, 1, { ControlMask, ControlMask, 0 } } +}; +static Atom lnames_PC_BREAK[2]; + +static XkbKTMapEntryRec map_PC_SYSRQ[1]= { + { 0, 1, { 0, 0, vmod_AltMask } } +}; +static Atom lnames_PC_SYSRQ[2]; + +static XkbKTMapEntryRec map_CTRL_ALT[1]= { + { 0, 1, { ControlMask, ControlMask, vmod_AltMask } } +}; +static Atom lnames_CTRL_ALT[2]; + +static XkbKTMapEntryRec map_THREE_LEVEL[3]= { + { 1, 1, { ShiftMask, ShiftMask, 0 } }, + { 0, 2, { 0, 0, vmod_LevelThreeMask } }, + { 0, 2, { ShiftMask, ShiftMask, vmod_LevelThreeMask } } +}; +static Atom lnames_THREE_LEVEL[3]; + +static XkbKTMapEntryRec map_SHIFT_ALT[1]= { + { 0, 1, { ShiftMask, ShiftMask, vmod_AltMask } } +}; +static Atom lnames_SHIFT_ALT[2]; + +static XkbKeyTypeRec dflt_types[]= { + { + { 0, 0, 0 }, + 1, + 0, NULL, NULL, + None, lnames_ONE_LEVEL + }, + { + { ShiftMask, ShiftMask, 0 }, + 2, + 1, map_TWO_LEVEL, NULL, + None, lnames_TWO_LEVEL + }, + { + { ShiftMask|LockMask, ShiftMask|LockMask, 0 }, + 2, + 2, map_ALPHABETIC, preserve_ALPHABETIC, + None, lnames_ALPHABETIC + }, + { + { ShiftMask, ShiftMask, vmod_NumLockMask }, + 2, + 2, map_KEYPAD, NULL, + None, lnames_KEYPAD + }, + { + { ControlMask, ControlMask, 0 }, + 2, + 1, map_PC_BREAK, NULL, + None, lnames_PC_BREAK + }, + { + { 0, 0, vmod_AltMask }, + 2, + 1, map_PC_SYSRQ, NULL, + None, lnames_PC_SYSRQ + }, + { + { ControlMask, ControlMask, vmod_AltMask }, + 2, + 1, map_CTRL_ALT, NULL, + None, lnames_CTRL_ALT + }, + { + { ShiftMask, ShiftMask, vmod_LevelThreeMask }, + 3, + 3, map_THREE_LEVEL, NULL, + None, lnames_THREE_LEVEL + }, + { + { ShiftMask, ShiftMask, vmod_AltMask }, + 2, + 1, map_SHIFT_ALT, NULL, + None, lnames_SHIFT_ALT + } +}; +#define num_dflt_types (sizeof(dflt_types)/sizeof(XkbKeyTypeRec)) + + +static void +initTypeNames(DPYTYPE dpy) +{ + dflt_types[0].name= GET_ATOM(dpy,"ONE_LEVEL"); + lnames_ONE_LEVEL[0]= GET_ATOM(dpy,"Any"); + dflt_types[1].name= GET_ATOM(dpy,"TWO_LEVEL"); + lnames_TWO_LEVEL[0]= GET_ATOM(dpy,"Base"); + lnames_TWO_LEVEL[1]= GET_ATOM(dpy,"Shift"); + dflt_types[2].name= GET_ATOM(dpy,"ALPHABETIC"); + lnames_ALPHABETIC[0]= GET_ATOM(dpy,"Base"); + lnames_ALPHABETIC[1]= GET_ATOM(dpy,"Caps"); + dflt_types[3].name= GET_ATOM(dpy,"KEYPAD"); + lnames_KEYPAD[0]= GET_ATOM(dpy,"Base"); + lnames_KEYPAD[1]= GET_ATOM(dpy,"Number"); + dflt_types[4].name= GET_ATOM(dpy,"PC_BREAK"); + lnames_PC_BREAK[0]= GET_ATOM(dpy,"Base"); + lnames_PC_BREAK[1]= GET_ATOM(dpy,"Control"); + dflt_types[5].name= GET_ATOM(dpy,"PC_SYSRQ"); + lnames_PC_SYSRQ[0]= GET_ATOM(dpy,"Base"); + lnames_PC_SYSRQ[1]= GET_ATOM(dpy,"Alt"); + dflt_types[6].name= GET_ATOM(dpy,"CTRL+ALT"); + lnames_CTRL_ALT[0]= GET_ATOM(dpy,"Base"); + lnames_CTRL_ALT[1]= GET_ATOM(dpy,"Ctrl+Alt"); + dflt_types[7].name= GET_ATOM(dpy,"THREE_LEVEL"); + lnames_THREE_LEVEL[0]= GET_ATOM(dpy,"Base"); + lnames_THREE_LEVEL[1]= GET_ATOM(dpy,"Shift"); + lnames_THREE_LEVEL[2]= GET_ATOM(dpy,"Level3"); + dflt_types[8].name= GET_ATOM(dpy,"SHIFT+ALT"); + lnames_SHIFT_ALT[0]= GET_ATOM(dpy,"Base"); + lnames_SHIFT_ALT[1]= GET_ATOM(dpy,"Shift+Alt"); +} +/* compat name is "default" */ +static XkbSymInterpretRec dfltSI[69]= { + { XK_ISO_Level2_Latch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_Exactly, ShiftMask, + 255, + { XkbSA_LatchMods, { 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Eisu_Shift, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Eisu_toggle, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Kana_Shift, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Kana_Lock, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Shift_Lock, 0x0000, + XkbSI_AnyOf, ShiftMask|LockMask, + 255, + { XkbSA_LockMods, { 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Num_Lock, 0x0000, + XkbSI_AnyOf, 0xff, + 0, + { XkbSA_LockMods, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_Alt_L, 0x0000, + XkbSI_AnyOf, 0xff, + 1, + { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Alt_R, 0x0000, + XkbSI_AnyOf, 0xff, + 1, + { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Scroll_Lock, 0x0000, + XkbSI_AnyOf, 0xff, + 4, + { XkbSA_LockMods, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Lock, 0x0000, + XkbSI_AnyOf, 0xff, + 255, + { XkbSA_ISOLock, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Level3_Shift, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOf, 0xff, + 2, + { XkbSA_SetMods, { 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } } }, + { XK_ISO_Level3_Latch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOf, 0xff, + 2, + { XkbSA_LatchMods, { 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } } }, + { XK_Mode_switch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_SetGroup, { 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_1, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_End, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_2, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_Down, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_3, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_Next, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 } } }, + { XK_KP_4, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Left, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_6, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Right, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_7, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_Home, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_8, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_Up, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_9, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_Prior, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00 } } }, + { XK_KP_5, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Begin, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_F1, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Divide, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_F2, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Multiply, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_F3, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Subtract, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Separator, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Add, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_0, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Insert, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Decimal, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_KP_Delete, 0x0001, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button_Dflt, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button1, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button2, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Button3, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick_Dflt, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick1, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick2, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DblClick3, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_PtrBtn, { 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag_Dflt, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag1, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag2, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_Drag3, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_EnableKeys, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00 } } }, + { XK_Pointer_Accelerate, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00 } } }, + { XK_Pointer_DfltBtnNext, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_Pointer_DfltBtnPrev, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_SetPtrDflt, { 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_AccessX_Enable, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 } } }, + { XK_Terminate_Server, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_Terminate, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Group_Latch, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_LatchGroup, { 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Next_Group, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_LockGroup, { 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Prev_Group, 0x0000, + XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff, + 3, + { XkbSA_LockGroup, { 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_First_Group, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockGroup, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { XK_ISO_Last_Group, 0x0000, + XkbSI_AnyOfOrNone, 0xff, + 255, + { XkbSA_LockGroup, { 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + { NoSymbol, 0x0000, + XkbSI_Exactly, LockMask, + 255, + { XkbSA_LockMods, { 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 } } }, + { NoSymbol, 0x0000, + XkbSI_AnyOf, 0xff, + 255, + { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } } +}; +#define num_dfltSI (sizeof(dfltSI)/sizeof(XkbSymInterpretRec)) + +static XkbCompatMapRec compatMap= { + dfltSI, + { /* group compatibility */ + { 0, 0, 0 }, + { 0, 0, vmod_AltGrMask }, + { 0, 0, vmod_AltGrMask }, + { 0, 0, vmod_AltGrMask } + }, + num_dfltSI, num_dfltSI +}; + +static XkbIndicatorRec indicators= { + 0x0, + { + { 0x80, 0, 0x00, XkbIM_UseEffective, { LockMask, LockMask, 0 }, 0 }, + { 0x80, 0, 0x00, XkbIM_UseEffective, { 0, 0, vmod_NumLockMask }, 0 }, + { 0x80, 0, 0x00, XkbIM_UseLocked, { ShiftMask, ShiftMask, 0 }, 0 }, + { 0x80, 0, 0x00, 0, { 0, 0, 0 }, XkbMouseKeysMask }, + { 0x80, 0, 0x00, XkbIM_UseLocked, { 0, 0, vmod_ScrollLockMask }, 0 }, + { 0x80, XkbIM_UseEffective, 0xfe, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }, + { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 } + } +}; +static void +initIndicatorNames(DPYTYPE dpy,XkbDescPtr xkb) +{ + xkb->names->indicators[ 0]= GET_ATOM(dpy,"Caps Lock"); + xkb->names->indicators[ 1]= GET_ATOM(dpy,"Num Lock"); + xkb->names->indicators[ 2]= GET_ATOM(dpy,"Shift Lock"); + xkb->names->indicators[ 3]= GET_ATOM(dpy,"Mouse Keys"); + xkb->names->indicators[ 4]= GET_ATOM(dpy,"Scroll Lock"); + xkb->names->indicators[ 5]= GET_ATOM(dpy,"Group 2"); +} +#endif /* DEFAULT_H */ diff --git a/nx-X11/programs/Xserver/xkb/xkbEvents.c b/nx-X11/programs/Xserver/xkb/xkbEvents.c new file mode 100644 index 000000000..8305208a0 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbEvents.c @@ -0,0 +1,1057 @@ +/* $Xorg: xkbEvents.c,v 1.3 2000/08/17 19:53:47 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/xkbEvents.c,v 3.11 2003/07/16 01:39:10 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include <X11/extensions/XI.h> +#include "inputstr.h" +#include "windowstr.h" +#include <X11/extensions/XKBsrv.h> +#include "xkb.h" + +/***====================================================================***/ + +void +XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN) +{ +register int i; +Time time; +CARD16 changed; + + pNKN->type = XkbEventCode + XkbEventBase; + pNKN->xkbType = XkbNewKeyboardNotify; + pNKN->time = time = GetTimeInMillis(); + changed = pNKN->changed; + + for (i=1; i<currentMaxClients; i++) { + if ((!clients[i]) || clients[i]->clientGone || + (clients[i]->requestVector==InitialVector)) { + continue; + } + + if (clients[i]->xkbClientFlags&_XkbClientInitialized) { + if (clients[i]->newKeyboardNotifyMask&changed) { + pNKN->sequenceNumber = clients[i]->sequence; + pNKN->time = time; + pNKN->changed = changed; + if ( clients[i]->swapped ) { + register int n; + swaps(&pNKN->sequenceNumber,n); + swapl(&pNKN->time,n); + swaps(&pNKN->changed,n); + } + WriteToClient(clients[i],sizeof(xEvent),(char *)pNKN); + if (changed&XkbNKN_KeycodesMask) { + clients[i]->minKC= pNKN->minKeyCode; + clients[i]->maxKC= pNKN->maxKeyCode; + } + } + } + else if (changed&XkbNKN_KeycodesMask) { + xEvent event; + event.u.u.type= MappingNotify; + event.u.mappingNotify.request= MappingKeyboard; + event.u.mappingNotify.firstKeyCode= clients[i]->minKC; + event.u.mappingNotify.count= clients[i]->maxKC-clients[i]->minKC+1; + event.u.u.sequenceNumber= clients[i]->sequence; + if (clients[i]->swapped) { + int n; + swaps(&event.u.u.sequenceNumber,n); + } + WriteToClient(clients[i],SIZEOF(xEvent), (char *)&event); + event.u.mappingNotify.request= MappingModifier; + WriteToClient(clients[i],SIZEOF(xEvent), (char *)&event); + } + } + 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) + 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)) { + 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; +} + +/***====================================================================***/ + +void +XkbSendMapNotify(DeviceIntPtr kbd,xkbMapNotify *pMN) +{ +int i; +XkbSrvInfoPtr xkbi; +unsigned time = 0,initialized; +CARD16 changed; + + xkbi = kbd->key->xkbInfo; + initialized= 0; + + changed = pMN->changed; + pMN->minKeyCode= xkbi->desc->min_key_code; + pMN->maxKeyCode= xkbi->desc->max_key_code; + for (i=1; i<currentMaxClients; i++) { + if (clients[i] && ! clients[i]->clientGone && + (clients[i]->requestVector != InitialVector) && + (clients[i]->xkbClientFlags&_XkbClientInitialized) && + (clients[i]->mapNotifyMask&changed)) + { + if (!initialized) { + pMN->type = XkbEventCode + XkbEventBase; + pMN->xkbType = XkbMapNotify; + pMN->deviceID = kbd->id; + time = GetTimeInMillis(); + initialized= 1; + } + pMN->time= time; + pMN->sequenceNumber = clients[i]->sequence; + pMN->changed = changed; + if ( clients[i]->swapped ) { + register int n; + swaps(&pMN->sequenceNumber,n); + swapl(&pMN->time,n); + swaps(&pMN->changed,n); + } + WriteToClient(clients[i],sizeof(xEvent),(char *)pMN); + } + } + return; +} + +int +XkbComputeControlsNotify( DeviceIntPtr kbd, + XkbControlsPtr old, + XkbControlsPtr new, + xkbControlsNotify * pCN, + Bool forceCtrlProc) +{ +int i; +CARD32 changedControls; + + changedControls= 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) + 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)) { + 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; +} + +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) && + (((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; + + xkbi = kbd->key->xkbInfo; + + if ((force||(xkbi->desc->ctrls->enabled_ctrls&XkbAudibleBellMask))&& + (!eventOnly)) { + (*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)) { + 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))) { + 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)) { + 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)) { + 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; + + xkbi = kbd->key->xkbInfo; + interest = kbd->xkb_interest; + if (!interest) + return; + + 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)) { + 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, supported = 0; + + 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)) { + if (!initialized) { + pEv->type = XkbEventCode + XkbEventBase; + pEv->xkbType = XkbExtensionDeviceNotify; + pEv->deviceID = dev->id; + pEv->sequenceNumber = interest->client->sequence; + pEv->time = time = GetTimeInMillis(); + supported= pEv->supported; + initialized= 1; + } + else { + pEv->sequenceNumber = interest->client->sequence; + pEv->time = time; + pEv->ledsDefined= defined; + pEv->ledState= state; + pEv->reason= reason; + pEv->supported= supported; + } + if (client!=interest->client) { + /* only report UnsupportedFeature to the client that */ + /* issued the failing request */ + pEv->reason&= ~XkbXI_UnsupportedFeatureMask; + if ((interest->extDevNotifyMask&reason)==0) + continue; + } + 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; + 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; + 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); + 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); + in.state= sli->effectiveState; + in.changed= pChanges->indicators.state_changes; + XkbSendIndicatorNotify(kbd,XkbIndicatorStateNotify,&in); + } + if (pChanges->names.changed) { + xkbNamesNotify nn; + 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; + 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; +} + +/***====================================================================***/ + +Bool +XkbFilterEvents(ClientPtr pClient,int nEvents,xEvent *xE) +{ +int i, button_mask; +DeviceIntPtr pXDev = (DeviceIntPtr)LookupKeyboardDevice(); +XkbSrvInfoPtr xkbi; + + xkbi= pXDev->key->xkbInfo; + if ( pClient->xkbClientFlags & _XkbClientInitialized ) { +#ifdef DEBUG + if ((xkbDebugFlags&0x10)&& + ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) { + ErrorF("XKbFilterWriteEvents:\n"); + ErrorF(" Event state= 0x%04x\n",xE[0].u.keyButtonPointer.state); + ErrorF(" XkbLastRepeatEvent!=xE (0x%x!=0x%x) %s\n", + XkbLastRepeatEvent,xE, + ((XkbLastRepeatEvent!=(pointer)xE)?"True":"False")); + ErrorF(" (xkbClientEventsFlags&XWDA)==0 (0x%x) %s\n", + pClient->xkbClientFlags, + (_XkbWantsDetectableAutoRepeat(pClient)?"True":"False")); + ErrorF(" !IsRelease(%d) %s\n",xE[0].u.u.type, + (!_XkbIsReleaseEvent(xE[0].u.u.type))?"True":"False"); + } +#endif /* DEBUG */ + if ( (XkbLastRepeatEvent==(pointer)xE) && + (_XkbWantsDetectableAutoRepeat(pClient)) && + (_XkbIsReleaseEvent(xE[0].u.u.type)) ) { + return False; + } + if ((pXDev->grab != NullGrab) && pXDev->fromPassiveGrab && + ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) { + register unsigned state,flags; + + flags= pClient->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; + } + button_mask = 1 << xE[0].u.u.detail; + if (xE[0].u.u.type == ButtonPress && + ((xE[0].u.keyButtonPointer.state >> 7) & button_mask) == button_mask && + (xkbi->lockedPtrButtons & button_mask) == button_mask) { +#ifdef DEBUG + /* If the MouseKeys is pressed, and the "real" mouse is also pressed + * when the mouse is released, the server does not behave properly. + * Faking a release of the button here solves the problem. + */ + ErrorF("Faking release of button %d\n", xE[0].u.u.detail); +#endif + XkbDDXFakePointerButton(ButtonRelease, xE[0].u.u.detail); + } + } + else { + register CARD8 type; + + for (i=0;i<nEvents;i++) { + type= xE[i].u.u.type; +#ifdef DEBUG + if ((xkbDebugFlags&0x4)&& + ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) { + XkbStatePtr s= &xkbi->state; + ErrorF("XKbFilterWriteEvents (non-XKB):\n"); + ErrorF("event= 0x%04x\n",xE[0].u.keyButtonPointer.state); + ErrorF("lookup= 0x%02x, grab= 0x%02x\n",s->lookup_mods, + s->grab_mods); + ErrorF("compat lookup= 0x%02x, grab= 0x%02x\n", + s->compat_lookup_mods, + s->compat_grab_mods); + } +#endif + if ( (type>=KeyPress)&&(type<=MotionNotify) ) { + CARD16 old,new; + + old= xE[i].u.keyButtonPointer.state&(~0x1f00); + new= xE[i].u.keyButtonPointer.state&0x1F00; + + if (old==XkbStateFieldFromRec(&xkbi->state)) + new|= xkbi->state.compat_lookup_mods; + else new|= xkbi->state.compat_grab_mods; + xE[i].u.keyButtonPointer.state= new; + } + else if ((type==EnterNotify)||(type==LeaveNotify)) { + xE->u.enterLeave.state&= 0x1F00; + xE->u.enterLeave.state|= xkbi->state.compat_grab_mods; + } + button_mask = 1 << xE[i].u.u.detail; + if (type == ButtonPress && + ((xE[i].u.keyButtonPointer.state >> 7) & button_mask) == button_mask && + (xkbi->lockedPtrButtons & button_mask) == button_mask) { +#ifdef DEBUG + ErrorF("Faking release of button %d\n", xE[i].u.u.detail); +#endif + XkbDDXFakePointerButton(ButtonRelease, xE[i].u.u.detail); + } + } + } + return True; +} + +/***====================================================================***/ + +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 = _XkbTypedAlloc(XkbInterestRec); + bzero(interest,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 +XkbRemoveClient(DevicePtr inDev,ClientPtr client) +{ +XkbSrvInfoPtr xkbi; +DeviceIntPtr dev = (DeviceIntPtr)inDev; +XkbInterestPtr interest; +unsigned long autoCtrls,autoValues; +Bool found; + + found= False; + autoCtrls= autoValues= 0; + if ( dev->xkb_interest ) { + interest = dev->xkb_interest; + if (interest && (interest->client==client)){ + dev->xkb_interest = interest->next; + autoCtrls= interest->autoCtrls; + autoValues= interest->autoCtrlValues; + _XkbFree(interest); + found= True; + } + while ((!found)&&(interest->next)) { + if (interest->next->client==client) { + XkbInterestPtr victim = interest->next; + interest->next = victim->next; + autoCtrls= victim->autoCtrls; + autoValues= victim->autoCtrlValues; + _XkbFree(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; +} + +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; + 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; + _XkbFree(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; + _XkbFree(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/nx-X11/programs/Xserver/xkb/xkbInit.c b/nx-X11/programs/Xserver/xkb/xkbInit.c new file mode 100644 index 000000000..a338de8ad --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbInit.c @@ -0,0 +1,1037 @@ +/* $Xorg: xkbInit.c,v 1.3 2000/08/17 19:53:47 cpqbld Exp $ */ +/* $XdotOrg: xc/programs/Xserver/xkb/xkbInit.c,v 1.9 2005/10/19 22:45:54 ajax Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/xkbInit.c,v 3.32tsi Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef HAVE_XKB_CONFIG_H +#include <xkb-config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <unistd.h> +#include <math.h> +#define NEED_EVENTS 1 +#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 <X11/extensions/XKBsrv.h> +#include <X11/extensions/XKBgeom.h> +#include <X11/extensions/XKMformat.h> +#include <X11/extensions/XKBfile.h> +#include "xkb.h" + +#define CREATE_ATOM(s) MakeAtom(s,sizeof(s)-1,1) + +#ifdef sgi +#define LED_CAPS 5 +#define LED_NUM 6 +#define LED_SCROLL 7 +#define PHYS_LEDS 0x7f +#define LED_COMPOSE 8 +#else +#if defined(ultrix) || defined(__osf__) || 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 +#endif + +#define MAX_TOC 16 +typedef struct _SrvXkmInfo { + DeviceIntPtr dev; + FILE * file; + XkbFileInfo xkbinfo; +} SrvXkmInfo; + + +/***====================================================================***/ + +#ifndef XKB_BASE_DIRECTORY +#define XKB_BASE_DIRECTORY "/usr/lib/X11/xkb" +#endif +#ifndef XKB_BIN_DIRECTORY +#define XKB_BIN_DIRECTORY XKB_BASE_DIRECTORY +#endif +#ifndef XKB_DFLT_RULES_FILE +#define XKB_DFLT_RULES_FILE "rules" +#endif +#ifndef XKB_DFLT_KB_LAYOUT +#define XKB_DFLT_KB_LAYOUT "us" +#endif +#ifndef XKB_DFLT_KB_MODEL +#define XKB_DFLT_KB_MODEL "dflt" +#endif +#ifndef XKB_DFLT_KB_VARIANT +#define XKB_DFLT_KB_VARIANT NULL +#endif +#ifndef XKB_DFLT_KB_OPTIONS +#define XKB_DFLT_KB_OPTIONS NULL +#endif +#ifndef XKB_DFLT_DISABLED +#define XKB_DFLT_DISABLED True +#endif +#ifndef XKB_DFLT_RULES_PROP +#define XKB_DFLT_RULES_PROP True +#endif + +char * XkbBaseDirectory= XKB_BASE_DIRECTORY; +char * XkbBinDirectory= XKB_BIN_DIRECTORY; +char * XkbInitialMap= NULL; +int XkbWantAccessX= 0; +static XkbFileInfo * _XkbInitFileInfo= NULL; +char * XkbDB= NULL; +int XkbAutoLoad= 1; + +static Bool rulesDefined= False; +static char * XkbRulesFile= NULL; +static char * XkbModelDflt= NULL; +static char * XkbLayoutDflt= NULL; +static char * XkbVariantDflt= NULL; +static char * XkbOptionsDflt= NULL; + +char * XkbModelUsed= NULL; +char * XkbLayoutUsed= NULL; +char * XkbVariantUsed= NULL; +char * XkbOptionsUsed= NULL; + +int _XkbClientMajor= XkbMajorVersion; +int _XkbClientMinor= XkbMinorVersion; + +Bool noXkbExtension= XKB_DFLT_DISABLED; +Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP; + +/***====================================================================***/ + +char * +XkbGetRulesDflts(XkbRF_VarDefsPtr defs) +{ + if (XkbModelDflt) defs->model= XkbModelDflt; + else defs->model= XKB_DFLT_KB_MODEL; + if (XkbLayoutDflt) defs->layout= XkbLayoutDflt; + else defs->layout= XKB_DFLT_KB_LAYOUT; + if (XkbVariantDflt) defs->variant= XkbVariantDflt; + else defs->variant= XKB_DFLT_KB_VARIANT; + if (XkbOptionsDflt) defs->options= XkbOptionsDflt; + else defs->options= XKB_DFLT_KB_OPTIONS; + return (rulesDefined?XkbRulesFile:XKB_DFLT_RULES_FILE); +} + +Bool +XkbWriteRulesProp(ClientPtr client, pointer closure) +{ +int len,out; +Atom name; +char * pval; + + if (rulesDefined && (!XkbRulesFile)) + return False; + len= (XkbRulesFile?strlen(XkbRulesFile):strlen(XKB_DFLT_RULES_FILE)); + 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("Atom error: %s not created\n",_XKB_RF_NAMES_PROP_ATOM); + return True; + } + pval= (char*) ALLOCATE_LOCAL(len); + if (!pval) { + ErrorF("Allocation error: %s proprerty not created\n", + _XKB_RF_NAMES_PROP_ATOM); + return True; + } + out= 0; + if (XkbRulesFile) { + strcpy(&pval[out],XkbRulesFile); + out+= strlen(XkbRulesFile); + } else { + strcpy(&pval[out],XKB_DFLT_RULES_FILE); + out+= strlen(XKB_DFLT_RULES_FILE); + } + 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("Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n", + out,len); + } + ChangeWindowProperty(WindowTable[0],name,XA_STRING,8,PropModeReplace, + len,pval,True); + DEALLOCATE_LOCAL(pval); + return True; +} + +void +XkbSetRulesUsed(XkbRF_VarDefsPtr defs) +{ + if (XkbModelUsed) + _XkbFree(XkbModelUsed); + XkbModelUsed= (defs->model?_XkbDupString(defs->model):NULL); + if (XkbLayoutUsed) + _XkbFree(XkbLayoutUsed); + XkbLayoutUsed= (defs->layout?_XkbDupString(defs->layout):NULL); + if (XkbVariantUsed) + _XkbFree(XkbVariantUsed); + XkbVariantUsed= (defs->variant?_XkbDupString(defs->variant):NULL); + if (XkbOptionsUsed) + _XkbFree(XkbOptionsUsed); + XkbOptionsUsed= (defs->options?_XkbDupString(defs->options):NULL); + if (XkbWantRulesProp) + QueueWorkProc(XkbWriteRulesProp,NULL,NULL); + return; +} + +void +XkbSetRulesDflts(char *rulesFile,char *model,char *layout, + char *variant,char *options) +{ + if (XkbRulesFile) + _XkbFree(XkbRulesFile); + XkbRulesFile= _XkbDupString(rulesFile); + rulesDefined= True; + if (model) { + if (XkbModelDflt) + _XkbFree(XkbModelDflt); + XkbModelDflt= _XkbDupString(model); + } + if (layout) { + if (XkbLayoutDflt) + _XkbFree(XkbLayoutDflt); + XkbLayoutDflt= _XkbDupString(layout); + } + if (variant) { + if (XkbVariantDflt) + _XkbFree(XkbVariantDflt); + XkbVariantDflt= _XkbDupString(variant); + } + if (options) { + if (XkbOptionsDflt) + _XkbFree(XkbOptionsDflt); + XkbOptionsDflt= _XkbDupString(options); + } + return; +} + +/***====================================================================***/ + +#if defined(luna) +#define XKB_DDX_PERMANENT_LOCK 1 +#endif + +#include "xkbDflts.h" + +/* A dummy to keep the compiler quiet */ +pointer xkbBogus = &indicators; + +static Bool +XkbInitKeyTypes(XkbDescPtr xkb,SrvXkmInfo *file) +{ + if (file->xkbinfo.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,SrvXkmInfo *file) +{ + xkbi->nRadioGroups = 0; + xkbi->radioGroups = NULL; + return; +} + + +static Status +XkbInitCompatStructs(XkbDescPtr xkb,SrvXkmInfo *file) +{ +register int i; +XkbCompatMapPtr compat; + + if (file->xkbinfo.defined&XkmCompatMapMask) + return Success; + 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,SrvXkmInfo *file) +{ + XkbInitKeyTypes(xkb,file); + XkbInitCompatStructs(xkb,file); + return; +} + +/***====================================================================***/ + +static Status +XkbInitNames(XkbSrvInfoPtr xkbi,SrvXkmInfo *file) +{ +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 ((file->xkbinfo.defined&XkmVirtualModsMask)==0) { + 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 (((file->xkbinfo.defined&XkmIndicatorsMask)==0)|| + ((file->xkbinfo.defined&XkmGeometryMask)==0)) { + 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 + } +#ifdef DEBUG_RADIO_GROUPS + if (names->num_rg<1) { + names->radio_groups= (Atom *)_XkbCalloc(RG_COUNT, sizeof(Atom)); + if (names->radio_groups) { + names->num_rg = RG_COUNT; + names->radio_groups[RG_BOGUS_FUNCTION_GROUP]= CREATE_ATOM("BOGUS"); + } + } +#endif + if (xkb->geom!=NULL) + names->geometry= xkb->geom->name; + else names->geometry= unknown; + return Success; +} + +static Status +XkbInitIndicatorMap(XkbSrvInfoPtr xkbi,SrvXkmInfo *file) +{ +XkbDescPtr xkb; +XkbIndicatorPtr map; +XkbSrvLedInfoPtr sli; + + xkb= xkbi->desc; + if (XkbAllocIndicatorMaps(xkb)!=Success) + return BadAlloc; + if ((file->xkbinfo.defined&XkmIndicatorsMask)==0) { + 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; + +/* Metro Link */ + 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; +/* Metro Link */ + } + sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0); + if (sli) + XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask); + return Success; +} + +static Status +XkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi,SrvXkmInfo *file) +{ +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 ((file->xkbinfo.defined&XkmSymbolsMask)==0) + 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; +} + +void +XkbInitDevice(DeviceIntPtr pXDev) +{ +int i; +XkbSrvInfoPtr xkbi; +XkbChangesRec changes; +SrvXkmInfo file; +unsigned check; +XkbEventCauseRec cause; + + file.dev= pXDev; + file.file=NULL; + bzero(&file.xkbinfo,sizeof(XkbFileInfo)); + bzero(&changes,sizeof(XkbChangesRec)); + if (XkbAutoLoad && (XkbInitialMap!=NULL)) { + if ((file.file=XkbDDXOpenConfigFile(XkbInitialMap,NULL,0))!=NULL) { + XkmReadFile(file.file,0,XkmKeymapLegal,&file.xkbinfo); + if (file.xkbinfo.xkb==NULL) { + LogMessage(X_ERROR, + "Error loading keymap file %s (%s in %s)\n" + "\treverting to defaults\n", + XkbInitialMap, _XkbErrMessages[_XkbErrCode], + (_XkbErrLocation?_XkbErrLocation:"unknown")); + fclose(file.file); + file.file= NULL; + bzero(&file.xkbinfo,sizeof(XkbFileInfo)); + } + else { + if (_XkbInitFileInfo!=NULL) { + XkbDescPtr tmp; + if ((tmp=_XkbInitFileInfo->xkb)!=NULL) { + XkbFreeKeyboard(tmp,XkbAllComponentsMask,True); + _XkbInitFileInfo->xkb= NULL; + } + } + _XkbInitFileInfo= &file.xkbinfo; + } + } + else { + LogMessage(X_ERROR, "Error opening keymap file %s, reverting to defaults\n", + XkbInitialMap); + } + } + pXDev->key->xkbInfo= xkbi= _XkbTypedCalloc(1,XkbSrvInfoRec); + if ( xkbi ) { + XkbDescPtr xkb; + if ((_XkbInitFileInfo!=NULL)&&(_XkbInitFileInfo->xkb!=NULL)) { + file.xkbinfo= *_XkbInitFileInfo; + xkbi->desc= _XkbInitFileInfo->xkb; + _XkbInitFileInfo= NULL; + } + else { + xkbi->desc= XkbAllocKeyboard(); + if (!xkbi->desc) + FatalError("Couldn't allocate keyboard description\n"); + xkbi->desc->min_key_code = pXDev->key->curKeySyms.minKeyCode; + xkbi->desc->max_key_code = pXDev->key->curKeySyms.maxKeyCode; + } + xkb= xkbi->desc; + if (xkb->min_key_code == 0) + xkb->min_key_code = pXDev->key->curKeySyms.minKeyCode; + if (xkb->max_key_code == 0) + xkb->max_key_code = pXDev->key->curKeySyms.maxKeyCode; + if ((pXDev->key->curKeySyms.minKeyCode!=xkbi->desc->min_key_code)|| + (pXDev->key->curKeySyms.maxKeyCode!=xkbi->desc->max_key_code)) { + /* 12/9/95 (ef) -- XXX! Maybe we should try to fix up one or */ + /* the other here, but for now just complain */ + /* can't just update the core range without */ + /* reallocating the KeySymsRec (pain) */ + ErrorF("Internal Error!! XKB and core keymap have different range\n"); + } + if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) + FatalError("Couldn't allocate client map in XkbInitDevice\n"); + i= XkbNumKeys(xkb)/3+1; + if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,i)!=Success) + FatalError("Couldn't allocate server map in XkbInitDevice\n"); + + xkbi->dfltPtrDelta=1; + xkbi->device = pXDev; + + file.xkbinfo.xkb= xkb; + XkbInitSemantics(xkb,&file); + XkbInitNames(xkbi,&file); + XkbInitRadioGroups(xkbi,&file); + + /* 12/31/94 (ef) -- XXX! Should check if state loaded from file */ + bzero(&xkbi->state,sizeof(XkbStateRec)); + + XkbInitControls(pXDev,xkbi,&file); + + if (file.xkbinfo.defined&XkmSymbolsMask) + memcpy(pXDev->key->modifierMap,xkb->map->modmap,xkb->max_key_code+1); + else + memcpy(xkb->map->modmap,pXDev->key->modifierMap,xkb->max_key_code+1); + + XkbInitIndicatorMap(xkbi,&file); + + XkbDDXInitDevice(pXDev); + + if (!(file.xkbinfo.defined&XkmSymbolsMask)) { + XkbUpdateKeyTypesFromCore(pXDev,xkb->min_key_code,XkbNumKeys(xkb), + &changes); + } + else { + XkbUpdateCoreDescription(pXDev,True); + } + XkbSetCauseUnknown(&cause); + XkbUpdateActions(pXDev,xkb->min_key_code, XkbNumKeys(xkb),&changes, + &check,&cause); + /* For sanity. The first time the connection + * is opened, the client side min and max are set + * using QueryMinMaxKeyCodes() which grabs them + * from pXDev. + */ + pXDev->key->curKeySyms.minKeyCode = xkb->min_key_code; + pXDev->key->curKeySyms.maxKeyCode = xkb->max_key_code; + } + if (file.file!=NULL) + fclose(file.file); + return; +} + +#if MAP_LENGTH > XkbMaxKeyCount +#undef XkbMaxKeyCount +#define XkbMaxKeyCount MAP_LENGTH +#endif + +Bool +XkbInitKeyboardDeviceStruct( + DeviceIntPtr dev, + XkbComponentNamesPtr names, + KeySymsPtr pSymsIn, + CARD8 pModsIn[], + void (*bellProc)( + int /*percent*/, + DeviceIntPtr /*device*/, + pointer /*ctrl*/, + int), + void (*ctrlProc)( + DeviceIntPtr /*device*/, + KeybdCtrl * /*ctrl*/)) +{ +XkbFileInfo finfo; +KeySymsRec tmpSyms,*pSyms; +CARD8 tmpMods[XkbMaxLegalKeyCode+1],*pMods; +char name[PATH_MAX],*rules; +Bool ok=False; +XPointer config; +XkbComponentNamesRec cfgNames; +XkbRF_VarDefsRec defs; + + if ((dev->key!=NULL)||(dev->kbdfeed!=NULL)) + return False; + pSyms= pSymsIn; + pMods= pModsIn; + bzero(&defs,sizeof(XkbRF_VarDefsRec)); + bzero(&cfgNames,sizeof(XkbComponentNamesRec)); + rules= XkbGetRulesDflts(&defs); + config= XkbDDXPreloadConfig(&rules,&defs,&cfgNames,dev); + + /* + * The strings are duplicated because it is not guaranteed that + * they are allocated, or that they are allocated for every server + * generation. Eventually they will be freed at the end of this + * function. + */ + if (names->keymap) names->keymap = _XkbDupString(names->keymap); + if (names->keycodes) names->keycodes = _XkbDupString(names->keycodes); + if (names->types) names->types = _XkbDupString(names->types); + if (names->compat) names->compat = _XkbDupString(names->compat); + if (names->geometry) names->geometry = _XkbDupString(names->geometry); + if (names->symbols) names->symbols = _XkbDupString(names->symbols); + + if (defs.model && defs.layout && rules) { + XkbComponentNamesRec rNames; + bzero(&rNames,sizeof(XkbComponentNamesRec)); + if (XkbDDXNamesFromRules(dev,rules,&defs,&rNames)) { + if (rNames.keymap) { + if (!names->keymap) + names->keymap = rNames.keymap; + else _XkbFree(rNames.keymap); + } + if (rNames.keycodes) { + if (!names->keycodes) + names->keycodes = rNames.keycodes; + else + _XkbFree(rNames.keycodes); + } + if (rNames.types) { + if (!names->types) + names->types = rNames.types; + else _XkbFree(rNames.types); + } + if (rNames.compat) { + if (!names->compat) + names->compat = rNames.compat; + else _XkbFree(rNames.compat); + } + if (rNames.symbols) { + if (!names->symbols) + names->symbols = rNames.symbols; + else _XkbFree(rNames.symbols); + } + if (rNames.geometry) { + if (!names->geometry) + names->geometry = rNames.geometry; + else _XkbFree(rNames.geometry); + } + XkbSetRulesUsed(&defs); + } + } + if (cfgNames.keymap){ + if (names->keymap) _XkbFree(names->keymap); + names->keymap= cfgNames.keymap; + } + if (cfgNames.keycodes){ + if (names->keycodes) _XkbFree(names->keycodes); + names->keycodes= cfgNames.keycodes; + } + if (cfgNames.types) { + if (names->types) _XkbFree(names->types); + names->types= cfgNames.types; + } + if (cfgNames.compat) { + if (names->compat) _XkbFree(names->compat); + names->compat= cfgNames.compat; + } + if (cfgNames.symbols){ + if (names->symbols) _XkbFree(names->symbols); + names->symbols= cfgNames.symbols; + } + if (cfgNames.geometry) { + if (names->geometry) _XkbFree(names->geometry); + names->geometry= cfgNames.geometry; + } + + if (names->keymap) { + XkbComponentNamesRec tmpNames; + bzero(&tmpNames,sizeof(XkbComponentNamesRec)); + tmpNames.keymap = names->keymap; + ok = (Bool) XkbDDXLoadKeymapByNames(dev,&tmpNames,XkmAllIndicesMask,0, + &finfo,name,PATH_MAX); + } + if (!(ok && (finfo.xkb!=NULL))) + ok = (Bool) XkbDDXLoadKeymapByNames(dev,names,XkmAllIndicesMask,0, + &finfo,name,PATH_MAX); + + if (ok && (finfo.xkb!=NULL)) { + XkbDescPtr xkb; + KeyCode minKC,maxKC; + + xkb= finfo.xkb; + minKC= xkb->min_key_code; + maxKC= xkb->max_key_code; + if (XkbIsLegalKeycode(minKC)&&XkbIsLegalKeycode(maxKC)&&(minKC<=maxKC)&& + ((minKC!=pSyms->minKeyCode)||(maxKC!=pSyms->maxKeyCode))) { + if (xkb->map!=NULL) { + KeySym *inSym,*outSym; + int width= pSymsIn->mapWidth; + + tmpSyms.minKeyCode= minKC; + tmpSyms.maxKeyCode= maxKC; + + if (minKC<pSymsIn->minKeyCode) + minKC= pSymsIn->minKeyCode; + if (maxKC>pSymsIn->maxKeyCode) + maxKC= pSymsIn->maxKeyCode; + + tmpSyms.mapWidth= width; + tmpSyms.map= _XkbTypedCalloc(width*XkbNumKeys(xkb),KeySym); + inSym= &pSymsIn->map[(minKC-pSymsIn->minKeyCode)*width]; + outSym= &tmpSyms.map[(minKC-tmpSyms.minKeyCode)*width]; + memcpy(outSym,inSym,((maxKC-minKC+1)*width)*sizeof(KeySym)); + pSyms= &tmpSyms; + } + if ((xkb->map!=NULL)&&(xkb->map->modmap!=NULL)) { + bzero(tmpMods,XkbMaxKeyCount); + memcpy(tmpMods,xkb->map->modmap,maxKC+1); + pMods= tmpMods; + } + } + _XkbInitFileInfo= &finfo; + } + else { + LogMessage(X_WARNING, "Couldn't load XKB keymap, falling back to pre-XKB keymap\n"); + } + ok= InitKeyboardDeviceStruct((DevicePtr)dev,pSyms,pMods,bellProc,ctrlProc); + if ((config!=NULL)&&(dev && dev->key && dev->key->xkbInfo)) + XkbDDXApplyConfig(config,dev->key->xkbInfo); + _XkbInitFileInfo= NULL; + if ((pSyms==&tmpSyms)&&(pSyms->map!=NULL)) { + _XkbFree(pSyms->map); + pSyms->map= NULL; + } + + if (names->keymap) _XkbFree(names->keymap); + names->keymap = NULL; + if (names->keycodes) _XkbFree(names->keycodes); + names->keycodes = NULL; + if (names->types) _XkbFree(names->types); + names->types = NULL; + if (names->compat) _XkbFree(names->compat); + names->compat = NULL; + if (names->geometry) _XkbFree(names->geometry); + names->geometry = NULL; + if (names->symbols) _XkbFree(names->symbols); + names->symbols = NULL; + + return ok; +} + +/***====================================================================***/ + + /* + * InitKeyClassDeviceStruct initializes the key class before it + * initializes the keyboard feedback class for a device. + * UpdateActions can't set up the correct autorepeat for keyboard + * initialization because the keyboard feedback isn't created yet. + * Instead, UpdateActions notes the "correct" autorepeat in the + * SrvInfo structure and InitKbdFeedbackClass calls UpdateAutoRepeat + * to apply the computed autorepeat once the feedback class exists. + * + * DIX will apply the changed autorepeat, so there's no need to + * do so here. This function returns True if both RepeatKeys and + * the core protocol autorepeat ctrls are set (i.e. should use + * software autorepeat), false otherwise. + * + * This function also computes the autorepeat accelerators for the + * default indicator feedback. + */ +int +XkbFinishDeviceInit(DeviceIntPtr pXDev) +{ +XkbSrvInfoPtr xkbi; +XkbDescPtr xkb; +int softRepeat; +XkbSrvLedInfoPtr sli; + + xkbi = NULL; + if (pXDev && pXDev->key && pXDev->key->xkbInfo && pXDev->kbdfeed) { + xkbi= pXDev->key->xkbInfo; + xkb= xkbi->desc; + if (pXDev->kbdfeed) { + xkbi->kbdProc= pXDev->kbdfeed->CtrlProc; + pXDev->kbdfeed->CtrlProc= XkbDDXKeybdCtrlProc; + } + if (pXDev->kbdfeed->ctrl.autoRepeat) + xkb->ctrls->enabled_ctrls|= XkbRepeatKeysMask; + softRepeat= (xkb->ctrls->enabled_ctrls&XkbRepeatKeysMask)!=0; + if (pXDev->kbdfeed) { + memcpy(pXDev->kbdfeed->ctrl.autoRepeats, + xkb->ctrls->per_key_repeat,XkbPerKeyBitArraySize); + softRepeat= softRepeat&&pXDev->kbdfeed->ctrl.autoRepeat; + } + } + else softRepeat= 0; + sli= XkbFindSrvLedInfo(pXDev,XkbDfltXIClass,XkbDfltXIId,0); + if (sli && xkbi) + XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask); +#ifdef DEBUG + else ErrorF("No indicator feedback in XkbFinishInit (shouldn't happen)!\n"); +#endif + return softRepeat; +} + + /* + * 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) { + _XkbFree(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; + } + _XkbFree(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 (strcmp(argv[i],"-kb")==0) { + noXkbExtension= True; + return 1; + } + else if (strcmp(argv[i],"+kb")==0) { + noXkbExtension= False; + return 1; + } + else if (strncmp(argv[i], "-xkbdir", 7) == 0) { + if(++i < argc) { +#if !defined(WIN32) && !defined(__UNIXOS2__) && !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], "-xkbmap", 7) == 0) { + if(++i < argc) { + if (strlen(argv[i]) < PATH_MAX) { + XkbInitialMap= argv[i]; + return 2; + } else { + LogMessage(X_ERROR, "-xkbmap pathname too long\n"); + return -1; + } + } + else { + return -1; + } + } + else if (strncmp(argv[i], "-xkbdb", 7) == 0) { + if(++i < argc) { + if (strlen(argv[i]) < PATH_MAX) { + XkbDB= argv[i]; + return 2; + } else { + LogMessage(X_ERROR, "-xkbdb pathname too long\n"); + return -1; + } + } + else { + return -1; + } + } + else if (strncmp(argv[i], "-noloadxkb", 7) == 0) { + XkbAutoLoad= 0; + 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], "-ar1") == 0) { /* -ar1 int */ + if (++i >= argc) UseMsg (); + XkbDfltRepeatDelay = (long)atoi(argv[i]); + return 2; + } + if (strcmp (argv[i], "-ar2") == 0) { /* -ar2 int */ + if (++i >= argc) UseMsg (); + XkbDfltRepeatInterval = (long)atoi(argv[i]); + return 2; + } + return 0; +} + +void +XkbUseMsg(void) +{ + ErrorF("The X Keyboard Extension adds the following arguments:\n"); + ErrorF("-kb disable the X Keyboard Extension\n"); + ErrorF("+kb enable the X Keyboard Extension\n"); + ErrorF("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n"); + ErrorF(" enable/disable accessx key sequences\n"); + ErrorF("-ar1 set XKB autorepeat delay\n"); + ErrorF("-ar2 set XKB autorepeat interval\n"); + ErrorF("-noloadxkb don't load XKB keymap description\n"); + ErrorF("-xkbdb file that contains default XKB keymaps\n"); + ErrorF("-xkbmap XKB keyboard description to load on startup\n"); +} diff --git a/nx-X11/programs/Xserver/xkb/xkbLEDs.c b/nx-X11/programs/Xserver/xkb/xkbLEDs.c new file mode 100644 index 000000000..e04c05f14 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbLEDs.c @@ -0,0 +1,1067 @@ +/* $Xorg: xkbLEDs.c,v 1.4 2001/05/10 19:54:01 steve Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/xkbLEDs.c,v 3.7 2003/07/16 01:39:10 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <math.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" + +#include <X11/extensions/XI.h> +#include <X11/extensions/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 (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. + */ +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); +} + +/***====================================================================***/ + + /* + * 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; +} + +/***====================================================================***/ + + /* + * 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; +} + +/***====================================================================***/ + + /* + * 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 +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 + * 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) + dev= (DeviceIntPtr)LookupKeyboardDevice(); + + 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 (!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= _XkbTypedCalloc(1,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= _XkbTypedCalloc(1,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= _XkbTypedCalloc(XkbNumIndicators,Atom); + if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask)) + sli->maps= _XkbTypedCalloc(XkbNumIndicators,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) _XkbFree(sli->maps); + if (sli->names) _XkbFree(sli->names); + } + sli->maps= NULL; + sli->names= NULL; + _XkbFree(sli); + return; +} + + +/***====================================================================***/ + + /* + * 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= _XkbTypedCalloc(XkbNumIndicators,Atom); + if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask)) + sli->maps= _XkbTypedCalloc(XkbNumIndicators,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 && (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= (DeviceIntPtr)LookupKeyboardDevice(); + + 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&(~XkbXIUnsupported)); + ed->ledClass= sli->class; + ed->ledID= sli->id; + ed->ledsDefined= sli->namesPresent|sli->mapsPresent; + ed->ledState= sli->effectiveState; + ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorNamesMask; + ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported); + + 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= (DeviceIntPtr)LookupKeyboardDevice(); + + 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&(~XkbXIUnsupported)); + ed->ledClass= sli->class; + ed->ledID= sli->id; + ed->ledsDefined= sli->namesPresent|sli->mapsPresent; + ed->ledState= sli->effectiveState; + ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorMapsMask; + ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported); + + 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= (DeviceIntPtr)LookupKeyboardDevice(); + 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&(~XkbXIUnsupported)); + ed->ledClass= sli->class; + ed->ledID= sli->id; + ed->ledsDefined= sli->namesPresent|sli->mapsPresent; + ed->ledState= sli->effectiveState; + ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorStateMask; + ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported); + } + + 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; +} + +/***====================================================================***/ + +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= (DeviceIntPtr)LookupKeyboardDevice(); + + 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&(~XkbXIUnsupported)); + ed->ledClass= sli->class; + ed->ledID= sli->id; + ed->ledsDefined= sli->namesPresent|sli->mapsPresent; + ed->ledState= sli->effectiveState; + ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorStateMask; + ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported); + + 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 +_UpdateButtonVMods( XkbDescPtr xkb, + unsigned num_btns, + XkbAction * acts, + unsigned changed, + xkbExtensionDeviceNotify * ed_inout) +{ +register int i; + + for (i=0;i<num_btns;i++,acts++) { + if ((acts->any.type!=XkbSA_NoAction)&& + XkbUpdateActionVirtualMods(xkb,acts,changed)) { + if ((ed_inout->reason&XkbXI_ButtonActionsMask)==0) { + ed_inout->reason|= XkbXI_ButtonActionsMask; + ed_inout->firstBtn= i; + ed_inout->nBtns= 1; + } + else { + ed_inout->nBtns= (i-ed_inout->firstBtn)+1; + } + } + } + return; +} + +static void +_UpdateMapVMods( XkbDescPtr xkb, + register XkbIndicatorMapPtr map, + unsigned changed_vmods, + unsigned * changed_maps_rtrn) +{ +register int i; + + *changed_maps_rtrn= 0; + for (i=0;i<XkbNumIndicators;i++,map++) { + if (map->mods.vmods&changed_vmods) { + map->mods.mask= map->mods.real_mods; + map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods); + *changed_maps_rtrn|= (1L<<i); + } + } + return; +} + +static void +_UpdateDeviceVMods( DeviceIntPtr dev, + XkbDescPtr xkb, + unsigned changed, + XkbEventCausePtr cause) +{ +xkbExtensionDeviceNotify ed; +XkbSrvLedInfoPtr sli; +unsigned changed_maps; + + bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify)); + ed.deviceID= dev->id; + if ((dev->button)&&(dev->button->xkb_acts)) { + _UpdateButtonVMods(xkb,dev->button->numButtons, + dev->button->xkb_acts,changed,&ed); + } + if (dev->kbdfeed) { + KbdFeedbackPtr kf; + for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) { + if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL)) + continue; + sli= kf->xkb_sli; + _UpdateMapVMods(xkb,sli->maps,changed,&changed_maps); + if (changed_maps) { + if (ed.reason&XkbXI_IndicatorsMask) { + XkbSendExtensionDeviceNotify(dev,NULL,&ed); + ed.reason= 0; + ed.firstBtn= ed.nBtns; + } + ed.ledClass= sli->class; + ed.ledID= sli->id; + ed.ledsDefined= sli->namesPresent|sli->mapsPresent; + ed.reason|= XkbXI_IndicatorMapsMask; + XkbUpdateLedAutoState(dev,sli,changed_maps,&ed,NULL,cause); + } + } + } + if (dev->leds) { + LedFeedbackPtr lf; + for (lf=dev->leds;lf!=NULL;lf=lf->next) { + if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL)) + continue; + sli= lf->xkb_sli; + _UpdateMapVMods(xkb,sli->maps,changed,&changed_maps); + if (changed_maps) { + if (ed.reason&XkbXI_IndicatorsMask) { + XkbSendExtensionDeviceNotify(dev,NULL,&ed); + ed.reason= 0; + ed.firstBtn= ed.nBtns; + } + ed.ledClass= sli->class; + ed.ledID= sli->id; + ed.ledsDefined= sli->namesPresent|sli->mapsPresent; + ed.reason|= XkbXI_IndicatorMapsMask; + XkbUpdateLedAutoState(dev,sli,changed_maps,&ed,NULL,cause); + } + } + } + if (ed.reason!=0) + XkbSendExtensionDeviceNotify(dev,NULL,&ed); + return; +} + +void +XkbApplyVModChangesToAllDevices( DeviceIntPtr dev, + XkbDescPtr xkb, + unsigned changed, + XkbEventCausePtr cause) +{ +DeviceIntPtr edev; + if (dev!=(DeviceIntPtr)LookupKeyboardDevice()) + return; + for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) { + if (edev->key) + continue; + _UpdateDeviceVMods(edev,xkb,changed,cause); + } + for (edev=inputInfo.off_devices;edev!=NULL;edev=edev->next) { + if (edev->key) + continue; + _UpdateDeviceVMods(edev,xkb,changed,cause); + } + return; +} diff --git a/nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c b/nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c new file mode 100644 index 000000000..ee521be69 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c @@ -0,0 +1,188 @@ +/* $Xorg: xkbPrKeyEv.c,v 1.3 2000/08/17 19:53:48 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/xkbPrKeyEv.c,v 3.8 2001/01/17 22:37:15 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <math.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "misc.h" +#include "inputstr.h" +#include <X11/extensions/XKBsrv.h> +#include <ctype.h> + + +/***====================================================================***/ + +void +XkbProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count) +{ +KeyClassPtr keyc = keybd->key; +XkbSrvInfoPtr xkbi; +int key; +XkbBehavior behavior; +unsigned ndx; + + xkbi= keyc->xkbInfo; + key= xE->u.u.detail; +#ifdef DEBUG + if (xkbDebugFlags&0x8) { + ErrorF("XkbPKE: Key %d %s\n",key,(xE->u.u.type==KeyPress?"down":"up")); + } +#endif + + if ( (xkbi->repeatKey==key) && (xE->u.u.type==KeyRelease) && + ((xkbi->desc->ctrls->enabled_ctrls&XkbRepeatKeysMask)==0) ) { + AccessXCancelRepeatKey(xkbi,key); + } + + behavior= xkbi->desc->server->behaviors[key]; + /* The "permanent" flag indicates a hard-wired behavior that occurs */ + /* below XKB, such as a key that physically locks. XKB does not */ + /* do anything to implement the behavior, but it *does* report that */ + /* key is hardwired */ + if ((behavior.type&XkbKB_Permanent)==0) { + switch (behavior.type) { + case XkbKB_Default: + if (( xE->u.u.type == KeyPress ) && + (keyc->down[key>>3] & (1<<(key&7)))) { + XkbLastRepeatEvent= (pointer)xE; + xE->u.u.type = KeyRelease; + XkbHandleActions(keybd,keybd,xE,count); + xE->u.u.type = KeyPress; + XkbHandleActions(keybd,keybd,xE,count); + XkbLastRepeatEvent= NULL; + return; + } + else if ((xE->u.u.type==KeyRelease) && + (!(keyc->down[key>>3]&(1<<(key&7))))) { + XkbLastRepeatEvent= (pointer)&xE; + xE->u.u.type = KeyPress; + XkbHandleActions(keybd,keybd,xE,count); + xE->u.u.type = KeyRelease; + XkbHandleActions(keybd,keybd,xE,count); + XkbLastRepeatEvent= NULL; + return; + } + break; + case XkbKB_Lock: + if ( xE->u.u.type == KeyRelease ) + return; + else { + int bit= 1<<(key&7); + if ( keyc->down[key>>3]&bit ) + xE->u.u.type= KeyRelease; + } + break; + case XkbKB_RadioGroup: + ndx= (behavior.data&(~XkbKB_RGAllowNone)); + if ( ndx<xkbi->nRadioGroups ) { + XkbRadioGroupPtr rg; + + if ( xE->u.u.type == KeyRelease ) + return; + + rg = &xkbi->radioGroups[ndx]; + if ( rg->currentDown == xE->u.u.detail ) { + if (behavior.data&XkbKB_RGAllowNone) { + xE->u.u.type = KeyRelease; + XkbHandleActions(keybd,keybd,xE,count); + rg->currentDown= 0; + } + return; + } + if ( rg->currentDown!=0 ) { + int key = xE->u.u.detail; + xE->u.u.type= KeyRelease; + xE->u.u.detail= rg->currentDown; + XkbHandleActions(keybd,keybd,xE,count); + xE->u.u.type= KeyPress; + xE->u.u.detail= key; + } + rg->currentDown= key; + } + else ErrorF("InternalError! Illegal radio group %d\n",ndx); + break; + case XkbKB_Overlay1: case XkbKB_Overlay2: + { + unsigned which; + if (behavior.type==XkbKB_Overlay1) which= XkbOverlay1Mask; + else which= XkbOverlay2Mask; + if ( (xkbi->desc->ctrls->enabled_ctrls&which)==0 ) + break; + if ((behavior.data>=xkbi->desc->min_key_code)&& + (behavior.data<=xkbi->desc->max_key_code)) { + xE->u.u.detail= behavior.data; + /* 9/11/94 (ef) -- XXX! need to match release with */ + /* press even if the state of the */ + /* corresponding overlay control */ + /* changes while the key is down */ + } + } + break; + default: + ErrorF("unknown key behavior 0x%04x\n",behavior.type); +#if defined(MetroLink) + return; +#else + break; +#endif + } + } + XkbHandleActions(keybd,keybd,xE,count); + return; +} + +void +ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count) +{ +KeyClassPtr keyc = keybd->key; +XkbSrvInfoPtr xkbi; + + xkbi= keyc->xkbInfo; + +#ifdef DEBUG + if (xkbDebugFlags&0x8) { + int key= xE->u.u.detail; + ErrorF("PKE: Key %d %s\n",key,(xE->u.u.type==KeyPress?"down":"up")); + } +#endif + if ((xkbi->desc->ctrls->enabled_ctrls&XkbAllFilteredEventsMask)==0) + XkbProcessKeyboardEvent(xE,keybd,count); + else if (xE->u.u.type==KeyPress) + AccessXFilterPressEvent(xE,keybd,count); + else if (xE->u.u.type==KeyRelease) + AccessXFilterReleaseEvent(xE,keybd,count); + return; +} + diff --git a/nx-X11/programs/Xserver/xkb/xkbPrOtherEv.c b/nx-X11/programs/Xserver/xkb/xkbPrOtherEv.c new file mode 100644 index 000000000..82f476790 --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbPrOtherEv.c @@ -0,0 +1,84 @@ +/* $Xorg: xkbPrOtherEv.c,v 1.3 2000/08/17 19:53:48 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86$ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <math.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/keysym.h> +#include "misc.h" +#include "inputstr.h" +#include <X11/extensions/XKBsrv.h> + +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> + +extern void ProcessOtherEvent( + xEvent * /* xE */, + DeviceIntPtr /* dev */, + int /* count */ +); + +/***====================================================================***/ + +void +XkbProcessOtherEvent(xEvent *xE,DeviceIntPtr dev,int count) +{ +Bool xkbCares,isBtn; + + xkbCares= True; + isBtn= False; + switch ( xE->u.u.type ) { + case KeyPress: xE->u.u.type= DeviceKeyPress; break; + case KeyRelease: xE->u.u.type= DeviceKeyRelease; break; + case ButtonPress: xE->u.u.type= DeviceButtonPress; + isBtn= True; + break; + case ButtonRelease: xE->u.u.type= DeviceButtonRelease; + isBtn= True; + break; + default: xkbCares= False; break; + } + if (xkbCares) { + if ((!isBtn)||((dev->button)&&(dev->button->xkb_acts))) { + DeviceIntPtr kbd; + if (dev->key) kbd= dev; + else kbd= (DeviceIntPtr)LookupKeyboardDevice(); + XkbHandleActions(dev,kbd,xE,count); + return; + } + } + ProcessOtherEvent(xE,dev,count); + return; +} + diff --git a/nx-X11/programs/Xserver/xkb/xkbSwap.c b/nx-X11/programs/Xserver/xkb/xkbSwap.c new file mode 100644 index 000000000..be1cd94fc --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbSwap.c @@ -0,0 +1,597 @@ +/* $Xorg: xkbSwap.c,v 1.3 2000/08/17 19:53:48 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/xkbSwap.c,v 3.4 2003/09/13 16:39:01 dawes Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "stdio.h" +#include <X11/X.h> +#define NEED_EVENTS +#define NEED_REPLIES +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XKBstr.h> +#include "extnsionst.h" +#include "xkb.h" + + /* + * REQUEST SWAPPING + */ +static int +SProcXkbUseExtension(ClientPtr client) +{ +register int n; + + REQUEST(xkbUseExtensionReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbUseExtensionReq); + swaps(&stuff->wantedMajor,n); + swaps(&stuff->wantedMinor,n); + return ProcXkbUseExtension(client); +} + +static int +SProcXkbSelectEvents(ClientPtr client) +{ +register int n; + + REQUEST(xkbSelectEventsReq); + + swaps(&stuff->length,n); + REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->affectWhich,n); + swaps(&stuff->clear,n); + swaps(&stuff->selectAll,n); + swaps(&stuff->affectMap,n); + swaps(&stuff->map,n); + if ((stuff->affectWhich&(~XkbMapNotifyMask))!=0) { + union { + BOOL *b; + CARD8 *c8; + CARD16 *c16; + CARD32 *c32; + } from; + 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)||(ndx==XkbMapNotify)) + continue; + maskLeft&= ~bit; + if ((stuff->selectAll&bit)||(stuff->clear&bit)) + continue; + switch (ndx) { + case XkbNewKeyboardNotify: + case XkbStateNotify: + case XkbNamesNotify: + case XkbAccessXNotify: + case XkbExtensionDeviceNotify: + size= 2; + break; + case XkbControlsNotify: + case XkbIndicatorStateNotify: + case XkbIndicatorMapNotify: + size= 4; + break; + case XkbBellNotify: + case XkbActionMessage: + case XkbCompatMapNotify: + size= 1; + break; + default: + client->errorValue = _XkbErrCode2(0x1,bit); + return BadValue; + } + if (dataLeft<(size*2)) + return BadLength; + if (size==2) { + swaps(&from.c16[0],n); + swaps(&from.c16[1],n); + } + else if (size==4) { + swapl(&from.c32[0],n); + swapl(&from.c32[1],n); + } + else { + size= 2; + } + from.c8+= (size*2); + dataLeft-= (size*2); + } + if (dataLeft>2) { + ErrorF("Extra data (%d bytes) after SelectEvents\n",dataLeft); + return BadLength; + } + } + return ProcXkbSelectEvents(client); +} + +static int +SProcXkbBell(ClientPtr client) +{ +register int n; + + REQUEST(xkbBellReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbBellReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->bellClass,n); + swaps(&stuff->bellID,n); + swapl(&stuff->name,n); + swapl(&stuff->window,n); + swaps(&stuff->pitch,n); + swaps(&stuff->duration,n); + return ProcXkbBell(client); +} + +static int +SProcXkbGetState(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetStateReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbGetStateReq); + swaps(&stuff->deviceSpec,n); + return ProcXkbGetState(client); +} + +static int +SProcXkbLatchLockState(ClientPtr client) +{ +register int n; + + REQUEST(xkbLatchLockStateReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbLatchLockStateReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->groupLatch,n); + return ProcXkbLatchLockState(client); +} + +static int +SProcXkbGetControls(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetControlsReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbGetControlsReq); + swaps(&stuff->deviceSpec,n); + return ProcXkbGetControls(client); +} + +static int +SProcXkbSetControls(ClientPtr client) +{ +register int n; + + REQUEST(xkbSetControlsReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbSetControlsReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->affectInternalVMods,n); + swaps(&stuff->internalVMods,n); + swaps(&stuff->affectIgnoreLockVMods,n); + swaps(&stuff->ignoreLockVMods,n); + swaps(&stuff->axOptions,n); + swapl(&stuff->affectEnabledCtrls,n); + swapl(&stuff->enabledCtrls,n); + swapl(&stuff->changeCtrls,n); + swaps(&stuff->repeatDelay,n); + swaps(&stuff->repeatInterval,n); + swaps(&stuff->slowKeysDelay,n); + swaps(&stuff->debounceDelay,n); + swaps(&stuff->mkDelay,n); + swaps(&stuff->mkInterval,n); + swaps(&stuff->mkTimeToMax,n); + swaps(&stuff->mkMaxSpeed,n); + swaps(&stuff->mkCurve,n); + swaps(&stuff->axTimeout,n); + swapl(&stuff->axtCtrlsMask,n); + swapl(&stuff->axtCtrlsValues,n); + swaps(&stuff->axtOptsMask,n); + swaps(&stuff->axtOptsValues,n); + return ProcXkbSetControls(client); +} + +static int +SProcXkbGetMap(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetMapReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbGetMapReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->full,n); + swaps(&stuff->partial,n); + swaps(&stuff->virtualMods,n); + return ProcXkbGetMap(client); +} + +static int +SProcXkbSetMap(ClientPtr client) +{ +register int n; + + REQUEST(xkbSetMapReq); + + swaps(&stuff->length,n); + REQUEST_AT_LEAST_SIZE(xkbSetMapReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->present,n); + swaps(&stuff->flags,n); + swaps(&stuff->totalSyms,n); + swaps(&stuff->totalActs,n); + swaps(&stuff->virtualMods,n); + return ProcXkbSetMap(client); +} + + +static int +SProcXkbGetCompatMap(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetCompatMapReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbGetCompatMapReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->firstSI,n); + swaps(&stuff->nSI,n); + return ProcXkbGetCompatMap(client); +} + +static int +SProcXkbSetCompatMap(ClientPtr client) +{ +register int n; + + REQUEST(xkbSetCompatMapReq); + + swaps(&stuff->length,n); + REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->firstSI,n); + swaps(&stuff->nSI,n); + return ProcXkbSetCompatMap(client); +} + +static int +SProcXkbGetIndicatorState(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetIndicatorStateReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq); + swaps(&stuff->deviceSpec,n); + return ProcXkbGetIndicatorState(client); +} + +static int +SProcXkbGetIndicatorMap(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetIndicatorMapReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq); + swaps(&stuff->deviceSpec,n); + swapl(&stuff->which,n); + return ProcXkbGetIndicatorMap(client); +} + +static int +SProcXkbSetIndicatorMap(ClientPtr client) +{ +register int n; + + REQUEST(xkbSetIndicatorMapReq); + + swaps(&stuff->length,n); + REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq); + swaps(&stuff->deviceSpec,n); + swapl(&stuff->which,n); + return ProcXkbSetIndicatorMap(client); +} + +static int +SProcXkbGetNamedIndicator(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetNamedIndicatorReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->ledClass,n); + swaps(&stuff->ledID,n); + swapl(&stuff->indicator,n); + return ProcXkbGetNamedIndicator(client); +} + +static int +SProcXkbSetNamedIndicator(ClientPtr client) +{ +register int n; + + REQUEST(xkbSetNamedIndicatorReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->ledClass,n); + swaps(&stuff->ledID,n); + swapl(&stuff->indicator,n); + swaps(&stuff->virtualMods,n); + swapl(&stuff->ctrls,n); + return ProcXkbSetNamedIndicator(client); +} + + +static int +SProcXkbGetNames(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetNamesReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbGetNamesReq); + swaps(&stuff->deviceSpec,n); + swapl(&stuff->which,n); + return ProcXkbGetNames(client); +} + +static int +SProcXkbSetNames(ClientPtr client) +{ +register int n; + + REQUEST(xkbSetNamesReq); + + swaps(&stuff->length,n); + REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->virtualMods,n); + swapl(&stuff->which,n); + swapl(&stuff->indicators,n); + swaps(&stuff->totalKTLevelNames,n); + return ProcXkbSetNames(client); +} + +static int +SProcXkbGetGeometry(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetGeometryReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbGetGeometryReq); + swaps(&stuff->deviceSpec,n); + swapl(&stuff->name,n); + return ProcXkbGetGeometry(client); +} + +static int +SProcXkbSetGeometry(ClientPtr client) +{ +register int n; + + REQUEST(xkbSetGeometryReq); + + swaps(&stuff->length,n); + REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); + swaps(&stuff->deviceSpec,n); + swapl(&stuff->name,n); + swaps(&stuff->widthMM,n); + swaps(&stuff->heightMM,n); + swaps(&stuff->nProperties,n); + swaps(&stuff->nColors,n); + swaps(&stuff->nDoodads,n); + swaps(&stuff->nKeyAliases,n); + return ProcXkbSetGeometry(client); +} + +static int +SProcXkbPerClientFlags(ClientPtr client) +{ +register int n; + + REQUEST(xkbPerClientFlagsReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); + swaps(&stuff->deviceSpec,n); + swapl(&stuff->change,n); + swapl(&stuff->value,n); + swapl(&stuff->ctrlsToChange,n); + swapl(&stuff->autoCtrls,n); + swapl(&stuff->autoCtrlValues,n); + return ProcXkbPerClientFlags(client); +} + +static int +SProcXkbListComponents(ClientPtr client) +{ +register int n; + + REQUEST(xkbListComponentsReq); + + swaps(&stuff->length,n); + REQUEST_AT_LEAST_SIZE(xkbListComponentsReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->maxNames,n); + return ProcXkbListComponents(client); +} + +static int +SProcXkbGetKbdByName(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetKbdByNameReq); + + swaps(&stuff->length,n); + REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->want,n); + swaps(&stuff->need,n); + return ProcXkbGetKbdByName(client); +} + +static int +SProcXkbGetDeviceInfo(ClientPtr client) +{ +register int n; + + REQUEST(xkbGetDeviceInfoReq); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->wanted,n); + swaps(&stuff->ledClass,n); + swaps(&stuff->ledID,n); + return ProcXkbGetDeviceInfo(client); +} + +static int +SProcXkbSetDeviceInfo(ClientPtr client) +{ +register int n; + + REQUEST(xkbSetDeviceInfoReq); + + swaps(&stuff->length,n); + REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); + swaps(&stuff->deviceSpec,n); + swaps(&stuff->change,n); + swaps(&stuff->nDeviceLedFBs,n); + return ProcXkbSetDeviceInfo(client); +} + +static int +SProcXkbSetDebuggingFlags(ClientPtr client) +{ +register int n; + + REQUEST(xkbSetDebuggingFlagsReq); + + swaps(&stuff->length,n); + REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); + swapl(&stuff->affectFlags,n); + swapl(&stuff->flags,n); + swapl(&stuff->affectCtrls,n); + swapl(&stuff->ctrls,n); + swaps(&stuff->msgLength,n); + return ProcXkbSetDebuggingFlags(client); +} + +int +SProcXkbDispatch (ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) + { + case X_kbUseExtension: + return SProcXkbUseExtension(client); + case X_kbSelectEvents: + return SProcXkbSelectEvents(client); + case X_kbBell: + return SProcXkbBell(client); + case X_kbGetState: + return SProcXkbGetState(client); + case X_kbLatchLockState: + return SProcXkbLatchLockState(client); + case X_kbGetControls: + return SProcXkbGetControls(client); + case X_kbSetControls: + return SProcXkbSetControls(client); + case X_kbGetMap: + return SProcXkbGetMap(client); + case X_kbSetMap: + return SProcXkbSetMap(client); + case X_kbGetCompatMap: + return SProcXkbGetCompatMap(client); + case X_kbSetCompatMap: + return SProcXkbSetCompatMap(client); + case X_kbGetIndicatorState: + return SProcXkbGetIndicatorState(client); + case X_kbGetIndicatorMap: + return SProcXkbGetIndicatorMap(client); + case X_kbSetIndicatorMap: + return SProcXkbSetIndicatorMap(client); + case X_kbGetNamedIndicator: + return SProcXkbGetNamedIndicator(client); + case X_kbSetNamedIndicator: + return SProcXkbSetNamedIndicator(client); + case X_kbGetNames: + return SProcXkbGetNames(client); + case X_kbSetNames: + return SProcXkbSetNames(client); + case X_kbGetGeometry: + return SProcXkbGetGeometry(client); + case X_kbSetGeometry: + return SProcXkbSetGeometry(client); + case X_kbPerClientFlags: + return SProcXkbPerClientFlags(client); + case X_kbListComponents: + return SProcXkbListComponents(client); + case X_kbGetKbdByName: + return SProcXkbGetKbdByName(client); + case X_kbGetDeviceInfo: + return SProcXkbGetDeviceInfo(client); + case X_kbSetDeviceInfo: + return SProcXkbSetDeviceInfo(client); + case X_kbSetDebuggingFlags: + return SProcXkbSetDebuggingFlags(client); + default: + return BadRequest; + } +} diff --git a/nx-X11/programs/Xserver/xkb/xkbUtils.c b/nx-X11/programs/Xserver/xkb/xkbUtils.c new file mode 100644 index 000000000..f3c3ff8ca --- /dev/null +++ b/nx-X11/programs/Xserver/xkb/xkbUtils.c @@ -0,0 +1,987 @@ +/* $Xorg: xkbUtils.c,v 1.3 2000/08/17 19:53:48 cpqbld Exp $ */ +/************************************************************ +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. + +********************************************************/ +/* $XFree86: xc/programs/Xserver/xkb/xkbUtils.c,v 3.16 2003/11/03 05:12:02 tsi Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <math.h> +#define NEED_EVENTS 1 +#include <X11/X.h> +#include <X11/Xproto.h> +#define XK_CYRILLIC +#include <X11/keysym.h> +#include "misc.h" +#include "inputstr.h" + +#define XKBSRV_NEED_FILE_FUNCS +#include <X11/extensions/XKBsrv.h> +#include <X11/extensions/XKBgeom.h> +#include "xkb.h" + +#ifdef MODE_SWITCH +extern Bool noKME; /* defined in os/utils.c */ +#endif + +int XkbDisableLockActions = 0; + +/***====================================================================***/ + +#ifndef RETURN_SHOULD_REPEAT +#if (defined(__osf__) && defined(__alpha)) +#define RETURN_SHOULD_REPEAT 1 +#else +#define RETURN_SHOULD_REPEAT 0 +#endif +#endif + +/***====================================================================***/ + +DeviceIntPtr +_XkbLookupAnyDevice(int id,int *why_rtrn) +{ +DeviceIntPtr dev = NULL; + + dev= (DeviceIntPtr)LookupKeyboardDevice(); + if ((id==XkbUseCoreKbd)||(dev->id==id)) + return dev; + + dev= (DeviceIntPtr)LookupPointerDevice(); + if ((id==XkbUseCorePtr)||(dev->id==id)) + return dev; + + if (id&(~0xff)) + dev = NULL; + + dev= (DeviceIntPtr)LookupDevice(id); + if (dev!=NULL) + return dev; + if ((!dev)&&(why_rtrn)) + *why_rtrn= XkbErr_BadDevice; + return dev; +} + +DeviceIntPtr +_XkbLookupKeyboard(int id,int *why_rtrn) +{ +DeviceIntPtr dev = NULL; + + if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL) + return NULL; + else if ((!dev->key)||(!dev->key->xkbInfo)) { + if (why_rtrn) + *why_rtrn= XkbErr_BadClass; + return NULL; + } + return dev; +} + +DeviceIntPtr +_XkbLookupBellDevice(int id,int *why_rtrn) +{ +DeviceIntPtr dev = NULL; + + if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL) + return NULL; + else if ((!dev->kbdfeed)&&(!dev->bell)) { + if (why_rtrn) + *why_rtrn= XkbErr_BadClass; + return NULL; + } + return dev; +} + +DeviceIntPtr +_XkbLookupLedDevice(int id,int *why_rtrn) +{ +DeviceIntPtr dev = NULL; + + if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL) + return NULL; + else if ((!dev->kbdfeed)&&(!dev->leds)) { + if (why_rtrn) + *why_rtrn= XkbErr_BadClass; + return NULL; + } + return dev; +} + +DeviceIntPtr +_XkbLookupButtonDevice(int id,int *why_rtrn) +{ +DeviceIntPtr dev = NULL; + + if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL) + return NULL; + else if (!dev->button) { + if (why_rtrn) + *why_rtrn= XkbErr_BadClass; + return NULL; + } + return dev; +} + +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; +} + + +Bool +XkbApplyVModChanges( XkbSrvInfoPtr xkbi, + unsigned changed, + XkbChangesPtr changes, + unsigned * needChecksRtrn, + XkbEventCausePtr cause) +{ +XkbDescPtr xkb; +Bool check; + + xkb= xkbi->desc; +#ifdef DEBUG +{ +register unsigned i,bit; + for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { + if ((changed&bit)==0) + continue; + if (xkbDebugFlags) + ErrorF("Should be applying: change vmod %d to 0x%x\n",i, + xkb->server->vmods[i]); + } +} +#endif + check= XkbApplyVirtualModChanges(xkb,changed,changes); + XkbApplyVModChangesToAllDevices(xkbi->device,xkb,changed,cause); + + if (needChecksRtrn!=NULL) { + if (check) + *needChecksRtrn= XkbStateNotifyMask|XkbIndicatorStateNotifyMask; + else *needChecksRtrn= 0; + } + else if (check) { + /* 7/12/95 (ef) -- XXX check compatibility and/or indicator state */ + } + return 1; +} + +/***====================================================================***/ + +void +XkbUpdateKeyTypesFromCore( DeviceIntPtr pXDev, + KeyCode first, + CARD8 num, + XkbChangesPtr changes) +{ +XkbDescPtr xkb; +unsigned key,nG,explicit; +KeySymsPtr pCore; +int types[XkbNumKbdGroups]; +KeySym tsyms[XkbMaxSymsPerKey],*syms; +XkbMapChangesPtr mc; + + xkb= pXDev->key->xkbInfo->desc; +#ifdef NOTYET + if (first<xkb->min_key_code) { + if (first>=XkbMinLegalKeyCode) { + xkb->min_key_code= first; + /* 1/12/95 (ef) -- XXX! should zero out the new maps */ + changes->map.changed|= XkbKeycodesMask; +generate a NewKeyboard notify here? + } + } +#endif + 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); + + pCore= &pXDev->key->curKeySyms; + syms= &pCore->map[(first-xkb->min_key_code)*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,32); + + XkbUpdateDescActions(xkb,first,num,changes); + + if ((pXDev->kbdfeed)&& + (changes->ctrls.enabled_ctrls_changes&XkbPerKeyRepeatMask)) { + memcpy(pXDev->kbdfeed->ctrl.autoRepeats,repeat, 32); + (*pXDev->kbdfeed->CtrlProc)(pXDev, &pXDev->kbdfeed->ctrl); + } + return; +} + +void +XkbUpdateCoreDescription(DeviceIntPtr keybd,Bool resize) +{ +register int key,tmp; +int maxSymsPerKey,maxKeysPerMod; +int first,last,firstCommon,lastCommon; +XkbDescPtr xkb; +KeyClassPtr keyc; +CARD8 keysPerMod[XkbNumModifiers]; + + if (!keybd || !keybd->key || !keybd->key->xkbInfo) + return; + xkb= keybd->key->xkbInfo->desc; + keyc= keybd->key; + maxSymsPerKey= maxKeysPerMod= 0; + bzero(keysPerMod,sizeof(keysPerMod)); + memcpy(keyc->modifierMap,xkb->map->modmap,xkb->max_key_code+1); + if ((xkb->min_key_code==keyc->curKeySyms.minKeyCode)&& + (xkb->max_key_code==keyc->curKeySyms.maxKeyCode)) { + first= firstCommon= xkb->min_key_code; + last= lastCommon= xkb->max_key_code; + } + else if (resize) { + keyc->curKeySyms.minKeyCode= xkb->min_key_code; + keyc->curKeySyms.maxKeyCode= xkb->max_key_code; + tmp= keyc->curKeySyms.mapWidth*_XkbCoreNumKeys(keyc); + keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym); + if (!keyc->curKeySyms.map) + FatalError("Couldn't allocate keysyms\n"); + first= firstCommon= xkb->min_key_code; + last= lastCommon= xkb->max_key_code; + } + else { + if (xkb->min_key_code<keyc->curKeySyms.minKeyCode) { + first= xkb->min_key_code; + firstCommon= keyc->curKeySyms.minKeyCode; + } + else { + firstCommon= xkb->min_key_code; + first= keyc->curKeySyms.minKeyCode; + } + if (xkb->max_key_code>keyc->curKeySyms.maxKeyCode) { + lastCommon= keyc->curKeySyms.maxKeyCode; + last= xkb->max_key_code; + } + else { + lastCommon= xkb->max_key_code; + last= keyc->curKeySyms.maxKeyCode; + } + } + + /* determine sizes */ + for (key=first;key<=last;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; + } + 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 (_XkbCoreKeycodeInRange(keyc,key)) { + if (keyc->modifierMap[key]!=0) { + register unsigned bit,i,mask; + mask= keyc->modifierMap[key]; + for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) { + if (mask&bit) { + keysPerMod[i]++; + if (keysPerMod[i]>maxKeysPerMod) + maxKeysPerMod= keysPerMod[i]; + } + } + } + } + } + + if (maxKeysPerMod>0) { + tmp= maxKeysPerMod*XkbNumModifiers; + if (keyc->modifierKeyMap==NULL) + keyc->modifierKeyMap= (KeyCode *)_XkbCalloc(1, tmp); + else if (keyc->maxKeysPerModifier<maxKeysPerMod) + keyc->modifierKeyMap= (KeyCode *)_XkbRealloc(keyc->modifierKeyMap,tmp); + if (keyc->modifierKeyMap==NULL) + FatalError("Couldn't allocate modifierKeyMap in UpdateCore\n"); + bzero(keyc->modifierKeyMap,tmp); + } + else if ((keyc->maxKeysPerModifier>0)&&(keyc->modifierKeyMap!=NULL)) { + _XkbFree(keyc->modifierKeyMap); + keyc->modifierKeyMap= NULL; + } + keyc->maxKeysPerModifier= maxKeysPerMod; + + if (maxSymsPerKey>0) { + tmp= maxSymsPerKey*_XkbCoreNumKeys(keyc); + keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym); + if (keyc->curKeySyms.map==NULL) + FatalError("Couldn't allocate symbols map in UpdateCore\n"); + } + else if ((keyc->curKeySyms.mapWidth>0)&&(keyc->curKeySyms.map!=NULL)) { + _XkbFree(keyc->curKeySyms.map); + keyc->curKeySyms.map= NULL; + } + keyc->curKeySyms.mapWidth= maxSymsPerKey; + + bzero(keysPerMod,sizeof(keysPerMod)); + for (key=firstCommon;key<=lastCommon;key++) { + if (keyc->curKeySyms.map!=NULL) { + KeySym *pCore,*pXKB; + unsigned nGroups,groupWidth,n,nOut; + + nGroups= XkbKeyNumGroups(xkb,key); + n= (key-keyc->curKeySyms.minKeyCode)*maxSymsPerKey; + pCore= &keyc->curKeySyms.map[n]; + bzero(pCore,maxSymsPerKey*sizeof(KeySym)); + 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; + } + 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); + } + if (!pCore[2] && !pCore[3] && maxSymsPerKey >= 6 && + (pCore[4] || pCore[5])) { + pCore[2] = pCore[4]; + pCore[3] = pCore[5]; + } + } + if (keyc->modifierMap[key]!=0) { + register unsigned bit,i,mask; + mask= keyc->modifierMap[key]; + for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) { + if (mask&bit) { + tmp= i*maxKeysPerMod+keysPerMod[i]; + keyc->modifierKeyMap[tmp]= key; + keysPerMod[i]++; + } + } + } + } +#ifdef MODE_SWITCH + /* Fix up any of the KME stuff if we changed the core description. + */ + if (!noKME) + HandleKeyBinding(keyc, &keyc->curKeySyms); +#endif + return; +} + +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; +} + +void +XkbApplyMappingChange( DeviceIntPtr kbd, + CARD8 request, + KeyCode firstKey, + CARD8 num, + ClientPtr client) +{ +XkbEventCauseRec cause; +XkbChangesRec changes; +unsigned check; + + if (kbd->key->xkbInfo==NULL) + XkbInitDevice(kbd); + bzero(&changes,sizeof(XkbChangesRec)); + check= 0; + if (request==MappingKeyboard) { + XkbSetCauseCoreReq(&cause,X_ChangeKeyboardMapping,client); + XkbUpdateKeyTypesFromCore(kbd,firstKey,num,&changes); + XkbUpdateActions(kbd,firstKey,num,&changes,&check,&cause); + if (check) + XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause); + } + else if (request==MappingModifier) { + XkbDescPtr xkb= kbd->key->xkbInfo->desc; + + XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client); + + num = xkb->max_key_code-xkb->min_key_code+1; + memcpy(xkb->map->modmap,kbd->key->modifierMap,xkb->max_key_code+1); + + changes.map.changed|= XkbModifierMapMask; + changes.map.first_modmap_key= xkb->min_key_code; + changes.map.num_modmap_keys= num; + XkbUpdateActions(kbd,xkb->min_key_code,num,&changes,&check,&cause); + if (check) + XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause); + } + /* 3/26/94 (ef) -- XXX! Doesn't deal with input extension requests */ + XkbSendNotification(kbd,&changes,&cause); + return; +} + +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; +} + +void +XkbComputeCompatState(XkbSrvInfoPtr xkbi) +{ +CARD16 grp_mask; +XkbStatePtr state= &xkbi->state; +XkbCompatMapPtr map; + + 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; + + state->mods= (state->base_mods|state->latched_mods); + state->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(grp,ctrls); + + grp= state->locked_group+state->base_group+state->latched_group; + if (grp>=ctrls->num_groups) + state->group= XkbAdjustGroup(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; +} + +/***====================================================================***/ + +void +XkbSetPhysicalLockingKey(DeviceIntPtr dev,unsigned key) +{ +XkbDescPtr xkb; + + xkb= dev->key->xkbInfo->desc; + if ((key>=xkb->min_key_code) && (key<=xkb->max_key_code)) { + xkb->server->behaviors[key].type= XkbKB_Lock|XkbKB_Permanent; + } + else ErrorF("Internal Error! Bad XKB info in SetPhysicalLockingKey\n"); + 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; + else if ((name==xkb->names->geometry)&&(xkb->geom==NULL)) { + FILE *file= XkbDDXOpenConfigFile(XkbInitialMap,NULL,0); + if (file!=NULL) { + XkbFileInfo xkbFInfo; + xkmFileInfo finfo; + xkmSectionInfo toc[MAX_TOC],*entry; + bzero(&xkbFInfo,sizeof(xkbFInfo)); + xkbFInfo.xkb= xkb; + if (XkmReadTOC(file,&finfo,MAX_TOC,toc)) { + entry= XkmFindTOCEntry(&finfo,toc,XkmGeometryIndex); + if (entry!=NULL) + XkmReadFileSection(file,entry,&xkbFInfo,NULL); + } + fclose(file); + if (xkb->geom) { + *shouldFree= 0; + 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; + } +} |