Commit f0c0ff41 authored by Ulrich Sibiller's avatar Ulrich Sibiller

copy files from libX11 to xserver dir

Before those files where symlinked in the makefile. While trying to upgrade libX11 to 1.3.4 it turned out that the symlinked did not work in the xserver anymore. Upstream has copies of those files, too.
parent 168c063d
......@@ -72,12 +72,6 @@ AllTarget($(XF86_OBJS))
SpecialCObjectRule(xkbInit,$(ICONFIGFILES),$(XKB_DEFINES))
XCOMM avoid clash between XKBMisc.c and xkbmisc.c on NT
LinkSourceFile(XKBMisc.c,$(XLIBSRC))
LinkSourceFile(XKBMAlloc.c,$(XLIBSRC))
LinkSourceFile(XKBAlloc.c,$(XLIBSRC))
LinkSourceFile(XKBGAlloc.c,$(XLIBSRC))
LinkSourceFile(modinit.h,../Xext/extmod)
#if BuildLibraries
......
/************************************************************
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation, and that the name of Silicon Graphics not be
used in advertising or publicity pertaining to distribution
of the software without specific prior written permission.
Silicon Graphics makes no representation about the suitability
of this software for any purpose. It is provided "as is"
without any express or implied warranty.
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
THE USE OR PERFORMANCE OF THIS SOFTWARE.
********************************************************/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#elif defined(HAVE_CONFIG_H)
#include <config.h>
#endif
#ifndef XKB_IN_SERVER
#include <stdio.h>
#include "Xlibint.h"
#include "XKBlibint.h"
#include <nx-X11/extensions/XKBgeom.h>
#include <nx-X11/extensions/XKBproto.h>
#include "XKBlibint.h"
#else
#include <stdio.h>
#include <nx-X11/X.h>
#include <nx-X11/Xproto.h>
#include "misc.h"
#include "inputstr.h"
#include <nx-X11/extensions/XKBsrv.h>
#include <nx-X11/extensions/XKBgeom.h>
#endif /* XKB_IN_SERVER */
/***===================================================================***/
/*ARGSUSED*/
Status
XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI)
{
XkbCompatMapPtr compat;
XkbSymInterpretRec *prev_interpret;
if (!xkb)
return BadMatch;
if (xkb->compat) {
if (xkb->compat->size_si>=nSI)
return Success;
compat= xkb->compat;
compat->size_si= nSI;
if (compat->sym_interpret==NULL)
compat->num_si= 0;
prev_interpret = compat->sym_interpret;
compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret,
nSI,XkbSymInterpretRec);
if (compat->sym_interpret==NULL) {
_XkbFree(prev_interpret);
compat->size_si= compat->num_si= 0;
return BadAlloc;
}
if (compat->num_si!=0) {
_XkbClearElems(compat->sym_interpret,compat->num_si,
compat->size_si-1,XkbSymInterpretRec);
}
return Success;
}
compat= _XkbTypedCalloc(1,XkbCompatMapRec);
if (compat==NULL)
return BadAlloc;
if (nSI>0) {
compat->sym_interpret= _XkbTypedCalloc(nSI,XkbSymInterpretRec);
if (!compat->sym_interpret) {
_XkbFree(compat);
return BadAlloc;
}
}
compat->size_si= nSI;
compat->num_si= 0;
bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
xkb->compat= compat;
return Success;
}
void
XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap)
{
register XkbCompatMapPtr compat;
if ((xkb==NULL)||(xkb->compat==NULL))
return;
compat= xkb->compat;
if (freeMap)
which= XkbAllCompatMask;
if (which&XkbGroupCompatMask)
bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
if (which&XkbSymInterpMask) {
if ((compat->sym_interpret)&&(compat->size_si>0))
_XkbFree(compat->sym_interpret);
compat->size_si= compat->num_si= 0;
compat->sym_interpret= NULL;
}
if (freeMap) {
_XkbFree(compat);
xkb->compat= NULL;
}
return;
}
/***===================================================================***/
Status
XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases)
{
XkbNamesPtr names;
if (xkb==NULL)
return BadMatch;
if (xkb->names==NULL) {
xkb->names = _XkbTypedCalloc(1,XkbNamesRec);
if (xkb->names==NULL)
return BadAlloc;
}
names= xkb->names;
if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){
register int i;
XkbKeyTypePtr type;
type= xkb->map->types;
for (i=0;i<xkb->map->num_types;i++,type++) {
if (type->level_names==NULL) {
type->level_names= _XkbTypedCalloc(type->num_levels,Atom);
if (type->level_names==NULL)
return BadAlloc;
}
}
}
if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) {
if ((!XkbIsLegalKeycode(xkb->min_key_code))||
(!XkbIsLegalKeycode(xkb->max_key_code))||
(xkb->max_key_code<xkb->min_key_code))
return BadValue;
names->keys= _XkbTypedCalloc((xkb->max_key_code+1),XkbKeyNameRec);
if (names->keys==NULL)
return BadAlloc;
}
if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) {
if (names->key_aliases==NULL) {
names->key_aliases= _XkbTypedCalloc(nTotalAliases,XkbKeyAliasRec);
}
else if (nTotalAliases>names->num_key_aliases) {
XkbKeyAliasRec *prev_aliases = names->key_aliases;
names->key_aliases= _XkbTypedRealloc(names->key_aliases,
nTotalAliases,XkbKeyAliasRec);
if (names->key_aliases!=NULL) {
_XkbClearElems(names->key_aliases,names->num_key_aliases,
nTotalAliases-1,XkbKeyAliasRec);
} else {
_XkbFree(prev_aliases);
}
}
if (names->key_aliases==NULL) {
names->num_key_aliases= 0;
return BadAlloc;
}
names->num_key_aliases= nTotalAliases;
}
if ((which&XkbRGNamesMask)&&(nTotalRG>0)) {
if (names->radio_groups==NULL) {
names->radio_groups= _XkbTypedCalloc(nTotalRG,Atom);
}
else if (nTotalRG>names->num_rg) {
Atom *prev_radio_groups = names->radio_groups;
names->radio_groups= _XkbTypedRealloc(names->radio_groups,nTotalRG,
Atom);
if (names->radio_groups!=NULL) {
_XkbClearElems(names->radio_groups,names->num_rg,nTotalRG-1,
Atom);
} else {
_XkbFree(prev_radio_groups);
}
}
if (names->radio_groups==NULL)
return BadAlloc;
names->num_rg= nTotalRG;
}
return Success;
}
void
XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap)
{
XkbNamesPtr names;
if ((xkb==NULL)||(xkb->names==NULL))
return;
names= xkb->names;
if (freeMap)
which= XkbAllNamesMask;
if (which&XkbKTLevelNamesMask) {
XkbClientMapPtr map= xkb->map;
if ((map!=NULL)&&(map->types!=NULL)) {
register int i;
register XkbKeyTypePtr type;
type= map->types;
for (i=0;i<map->num_types;i++,type++) {
if (type->level_names!=NULL) {
_XkbFree(type->level_names);
type->level_names= NULL;
}
}
}
}
if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
_XkbFree(names->keys);
names->keys= NULL;
names->num_keys= 0;
}
if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){
_XkbFree(names->key_aliases);
names->key_aliases=NULL;
names->num_key_aliases=0;
}
if ((which&XkbRGNamesMask)&&(names->radio_groups)) {
_XkbFree(names->radio_groups);
names->radio_groups= NULL;
names->num_rg= 0;
}
if (freeMap) {
_XkbFree(names);
xkb->names= NULL;
}
return;
}
/***===================================================================***/
/*ARGSUSED*/
Status
XkbAllocControls(XkbDescPtr xkb,unsigned which)
{
if (xkb==NULL)
return BadMatch;
if (xkb->ctrls==NULL) {
xkb->ctrls= _XkbTypedCalloc(1,XkbControlsRec);
if (!xkb->ctrls)
return BadAlloc;
}
return Success;
}
/*ARGSUSED*/
void
XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap)
{
if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) {
_XkbFree(xkb->ctrls);
xkb->ctrls= NULL;
}
return;
}
/***===================================================================***/
Status
XkbAllocIndicatorMaps(XkbDescPtr xkb)
{
if (xkb==NULL)
return BadMatch;
if (xkb->indicators==NULL) {
xkb->indicators= _XkbTypedCalloc(1,XkbIndicatorRec);
if (!xkb->indicators)
return BadAlloc;
}
return Success;
}
void
XkbFreeIndicatorMaps(XkbDescPtr xkb)
{
if ((xkb!=NULL)&&(xkb->indicators!=NULL)) {
_XkbFree(xkb->indicators);
xkb->indicators= NULL;
}
return;
}
/***====================================================================***/
XkbDescRec *
XkbAllocKeyboard(void)
{
XkbDescRec *xkb;
xkb = _XkbTypedCalloc(1,XkbDescRec);
if (xkb)
xkb->device_spec= XkbUseCoreKbd;
return xkb;
}
void
XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll)
{
if (xkb==NULL)
return;
if (freeAll)
which= XkbAllComponentsMask;
if (which&XkbClientMapMask)
XkbFreeClientMap(xkb,XkbAllClientInfoMask,True);
if (which&XkbServerMapMask)
XkbFreeServerMap(xkb,XkbAllServerInfoMask,True);
if (which&XkbCompatMapMask)
XkbFreeCompatMap(xkb,XkbAllCompatMask,True);
if (which&XkbIndicatorMapMask)
XkbFreeIndicatorMaps(xkb);
if (which&XkbNamesMask)
XkbFreeNames(xkb,XkbAllNamesMask,True);
if ((which&XkbGeometryMask) && (xkb->geom!=NULL))
XkbFreeGeometry(xkb->geom,XkbGeomAllMask,True);
if (which&XkbControlsMask)
XkbFreeControls(xkb,XkbAllControlsMask,True);
if (freeAll)
_XkbFree(xkb);
return;
}
/***====================================================================***/
XkbDeviceLedInfoPtr
XkbAddDeviceLedInfo(XkbDeviceInfoPtr devi,unsigned ledClass,unsigned ledId)
{
XkbDeviceLedInfoPtr devli;
register int i;
if ((!devi)||(!XkbSingleXIClass(ledClass))||(!XkbSingleXIId(ledId)))
return NULL;
for (i=0,devli=devi->leds;i<devi->num_leds;i++,devli++) {
if ((devli->led_class==ledClass)&&(devli->led_id==ledId))
return devli;
}
if (devi->num_leds>=devi->sz_leds) {
XkbDeviceLedInfoRec *prev_leds = devi->leds;
if (devi->sz_leds>0) devi->sz_leds*= 2;
else devi->sz_leds= 1;
devi->leds= _XkbTypedRealloc(devi->leds,devi->sz_leds,
XkbDeviceLedInfoRec);
if (!devi->leds) {
_XkbFree(prev_leds);
devi->sz_leds= devi->num_leds= 0;
return NULL;
}
i= devi->num_leds;
for (devli=&devi->leds[i];i<devi->sz_leds;i++,devli++) {
bzero(devli,sizeof(XkbDeviceLedInfoRec));
devli->led_class= XkbXINone;
devli->led_id= XkbXINone;
}
}
devli= &devi->leds[devi->num_leds++];
bzero(devli,sizeof(XkbDeviceLedInfoRec));
devli->led_class= ledClass;
devli->led_id= ledId;
return devli;
}
Status
XkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi,unsigned newTotal)
{
XkbAction *prev_btn_acts;
if ((!devi)||(newTotal>255))
return BadValue;
if ((devi->btn_acts!=NULL)&&(newTotal==devi->num_btns))
return Success;
if (newTotal==0) {
if (devi->btn_acts!=NULL) {
_XkbFree(devi->btn_acts);
devi->btn_acts= NULL;
}
devi->num_btns= 0;
return Success;
}
prev_btn_acts = devi->btn_acts;
devi->btn_acts= _XkbTypedRealloc(devi->btn_acts,newTotal,XkbAction);
if (devi->btn_acts==NULL) {
_XkbFree(prev_btn_acts);
devi->num_btns= 0;
return BadAlloc;
}
if (newTotal>devi->num_btns) {
XkbAction *act;
act= &devi->btn_acts[devi->num_btns];
bzero((char *)act,(newTotal-devi->num_btns)*sizeof(XkbAction));
}
devi->num_btns= newTotal;
return Success;
}
/*ARGSUSED*/
XkbDeviceInfoPtr
XkbAllocDeviceInfo(unsigned deviceSpec,unsigned nButtons,unsigned szLeds)
{
XkbDeviceInfoPtr devi;
devi= _XkbTypedCalloc(1,XkbDeviceInfoRec);
if (devi!=NULL) {
devi->device_spec= deviceSpec;
devi->has_own_state= False;
devi->num_btns= 0;
devi->btn_acts= NULL;
if (nButtons>0) {
devi->num_btns= nButtons;
devi->btn_acts= _XkbTypedCalloc(nButtons,XkbAction);
if (!devi->btn_acts) {
_XkbFree(devi);
return NULL;
}
}
devi->dflt_kbd_fb= XkbXINone;
devi->dflt_led_fb= XkbXINone;
devi->num_leds= 0;
devi->sz_leds= 0;
devi->leds= NULL;
if (szLeds>0) {
devi->sz_leds= szLeds;
devi->leds= _XkbTypedCalloc(szLeds,XkbDeviceLedInfoRec);
if (!devi->leds) {
if (devi->btn_acts)
_XkbFree(devi->btn_acts);
_XkbFree(devi);
return NULL;
}
}
}
return devi;
}
void
XkbFreeDeviceInfo(XkbDeviceInfoPtr devi,unsigned which,Bool freeDevI)
{
if (devi) {
if (freeDevI) {
which= XkbXI_AllDeviceFeaturesMask;
if (devi->name) {
_XkbFree(devi->name);
devi->name= NULL;
}
}
if ((which&XkbXI_ButtonActionsMask)&&(devi->btn_acts)) {
_XkbFree(devi->btn_acts);
devi->num_btns= 0;
devi->btn_acts= NULL;
}
if ((which&XkbXI_IndicatorsMask)&&(devi->leds)) {
register int i;
if ((which&XkbXI_IndicatorsMask)==XkbXI_IndicatorsMask) {
_XkbFree(devi->leds);
devi->sz_leds= devi->num_leds= 0;
devi->leds= NULL;
}
else {
XkbDeviceLedInfoPtr devli;
for (i=0,devli=devi->leds;i<devi->num_leds;i++,devli++) {
if (which&XkbXI_IndicatorMapsMask)
bzero((char *)&devli->maps[0],sizeof(devli->maps));
else bzero((char *)&devli->names[0],sizeof(devli->names));
}
}
}
if (freeDevI)
_XkbFree(devi);
}
return;
}
/************************************************************
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation, and that the name of Silicon Graphics not be
used in advertising or publicity pertaining to distribution
of the software without specific prior written permission.
Silicon Graphics makes no representation about the suitability
of this software for any purpose. It is provided "as is"
without any express or implied warranty.
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
THE USE OR PERFORMANCE OF THIS SOFTWARE.
********************************************************/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#elif defined(HAVE_CONFIG_H)
#include <config.h>
#endif
#ifndef XKB_IN_SERVER
#include <stdio.h>
#include "Xlibint.h"
#include "XKBlibint.h"
#include <nx-X11/extensions/XKBgeom.h>
#include <nx-X11/extensions/XKBproto.h>
#else
#include <stdio.h>
#include <nx-X11/X.h>
#include <nx-X11/Xproto.h>
#include "misc.h"
#include "inputstr.h"
#include <nx-X11/extensions/XKBsrv.h>
#include <nx-X11/extensions/XKBgeom.h>
#endif /* XKB_IN_SERVER */
#ifdef X_NOT_POSIX
#define Size_t unsigned int
#else
#define Size_t size_t
#endif
/***====================================================================***/
static void
_XkbFreeGeomLeafElems( Bool freeAll,
int first,
int count,
unsigned short * num_inout,
unsigned short * sz_inout,
char ** elems,
unsigned int elem_sz)
{
if ((freeAll)||(*elems==NULL)) {
*num_inout= *sz_inout= 0;
if (*elems!=NULL) {
_XkbFree(*elems);
*elems= NULL;
}
return;
}
if ((first>=(*num_inout))||(first<0)||(count<1))
return;
if (first+count>=(*num_inout)) {
/* truncating the array is easy */
(*num_inout)= first;
}
else {
char * ptr;
int extra;
ptr= *elems;
extra= ((*num_inout)-(first+count))*elem_sz;
if (extra>0)
memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
(*num_inout)-= count;
}
return;
}
typedef void (*ContentsClearFunc)(
char * /* priv */
);
static void
_XkbFreeGeomNonLeafElems( Bool freeAll,
int first,
int count,
unsigned short * num_inout,
unsigned short * sz_inout,
char ** elems,
unsigned int elem_sz,
ContentsClearFunc freeFunc)
{
register int i;
register char *ptr;
if (freeAll) {
first= 0;
count= (*num_inout);
}
else if ((first>=(*num_inout))||(first<0)||(count<1))
return;
else if (first+count>(*num_inout))
count= (*num_inout)-first;
if (*elems==NULL)
return;
if (freeFunc) {
ptr= *elems;
ptr+= first*elem_sz;
for (i=0;i<count;i++) {
(*freeFunc)(ptr);
ptr+= elem_sz;
}
}
if (freeAll) {
(*num_inout)= (*sz_inout)= 0;
if (*elems) {
_XkbFree(*elems);
*elems= NULL;
}
}
else if (first+count>=(*num_inout))
*num_inout= first;
else {
i= ((*num_inout)-(first+count))*elem_sz;
ptr= *elems;
memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
(*num_inout)-= count;
}
return;
}
/***====================================================================***/
static void
_XkbClearProperty(char *prop_in)
{
XkbPropertyPtr prop= (XkbPropertyPtr)prop_in;
if (prop->name) {
_XkbFree(prop->name);
prop->name= NULL;
}
if (prop->value) {
_XkbFree(prop->value);
prop->value= NULL;
}
return;
}
void
XkbFreeGeomProperties( XkbGeometryPtr geom,
int first,
int count,
Bool freeAll)
{
_XkbFreeGeomNonLeafElems(freeAll,first,count,
&geom->num_properties,&geom->sz_properties,
(char **)&geom->properties,
sizeof(XkbPropertyRec),_XkbClearProperty);
return;
}
/***====================================================================***/
void
XkbFreeGeomKeyAliases( XkbGeometryPtr geom,
int first,
int count,
Bool freeAll)
{
_XkbFreeGeomLeafElems(freeAll,first,count,
&geom->num_key_aliases,&geom->sz_key_aliases,
(char **)&geom->key_aliases,
sizeof(XkbKeyAliasRec));
return;
}
/***====================================================================***/
static void
_XkbClearColor(char *color_in)
{
XkbColorPtr color= (XkbColorPtr)color_in;
if (color->spec)
_XkbFree(color->spec);
return;
}
void
XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
{
_XkbFreeGeomNonLeafElems(freeAll,first,count,
&geom->num_colors,&geom->sz_colors,
(char **)&geom->colors,
sizeof(XkbColorRec),_XkbClearColor);
return;
}
/***====================================================================***/
void
XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
{
_XkbFreeGeomLeafElems(freeAll,first,count,
&outline->num_points,&outline->sz_points,
(char **)&outline->points,
sizeof(XkbPointRec));
return;
}
/***====================================================================***/
static void
_XkbClearOutline(char *outline_in)
{
XkbOutlinePtr outline= (XkbOutlinePtr)outline_in;
if (outline->points!=NULL)
XkbFreeGeomPoints(outline,0,outline->num_points,True);
return;
}
void
XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll)
{
_XkbFreeGeomNonLeafElems(freeAll,first,count,
&shape->num_outlines,&shape->sz_outlines,
(char **)&shape->outlines,
sizeof(XkbOutlineRec),_XkbClearOutline);
return;
}
/***====================================================================***/
static void
_XkbClearShape(char *shape_in)
{
XkbShapePtr shape= (XkbShapePtr)shape_in;
if (shape->outlines)
XkbFreeGeomOutlines(shape,0,shape->num_outlines,True);
return;
}
void
XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
{
_XkbFreeGeomNonLeafElems(freeAll,first,count,
&geom->num_shapes,&geom->sz_shapes,
(char **)&geom->shapes,
sizeof(XkbShapeRec),_XkbClearShape);
return;
}
/***====================================================================***/
void
XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
{
_XkbFreeGeomLeafElems(freeAll,first,count,
&row->num_keys,&row->sz_keys,
(char **)&row->keys,
sizeof(XkbOverlayKeyRec));
return;
}
/***====================================================================***/
static void
_XkbClearOverlayRow(char *row_in)
{
XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in;
if (row->keys!=NULL)
XkbFreeGeomOverlayKeys(row,0,row->num_keys,True);
return;
}
void
XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
{
_XkbFreeGeomNonLeafElems(freeAll,first,count,
&overlay->num_rows,&overlay->sz_rows,
(char **)&overlay->rows,
sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
return;
}
/***====================================================================***/
static void
_XkbClearOverlay(char *overlay_in)
{
XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in;
if (overlay->rows!=NULL)
XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,True);
return;
}
void
XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll)
{
_XkbFreeGeomNonLeafElems(freeAll,first,count,
&section->num_overlays,&section->sz_overlays,
(char **)&section->overlays,
sizeof(XkbOverlayRec),_XkbClearOverlay);
return;
}
/***====================================================================***/
void
XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
{
_XkbFreeGeomLeafElems(freeAll,first,count,
&row->num_keys,&row->sz_keys,
(char **)&row->keys,
sizeof(XkbKeyRec));
return;
}
/***====================================================================***/
static void
_XkbClearRow(char *row_in)
{
XkbRowPtr row= (XkbRowPtr)row_in;
if (row->keys!=NULL)
XkbFreeGeomKeys(row,0,row->num_keys,True);
return;
}
void
XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
{
_XkbFreeGeomNonLeafElems(freeAll,first,count,
&section->num_rows,&section->sz_rows,
(char **)&section->rows,
sizeof(XkbRowRec),_XkbClearRow);
}
/***====================================================================***/
static void
_XkbClearSection(char *section_in)
{
XkbSectionPtr section= (XkbSectionPtr)section_in;
if (section->rows!=NULL)
XkbFreeGeomRows(section,0,section->num_rows,True);
if (section->doodads!=NULL) {
XkbFreeGeomDoodads(section->doodads,section->num_doodads,True);
section->doodads= NULL;
}
return;
}
void
XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
{
_XkbFreeGeomNonLeafElems(freeAll,first,count,
&geom->num_sections,&geom->sz_sections,
(char **)&geom->sections,
sizeof(XkbSectionRec),_XkbClearSection);
return;
}
/***====================================================================***/
static void
_XkbClearDoodad(char *doodad_in)
{
XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in;
switch (doodad->any.type) {
case XkbTextDoodad:
{
if (doodad->text.text!=NULL) {
_XkbFree(doodad->text.text);
doodad->text.text= NULL;
}
if (doodad->text.font!=NULL) {
_XkbFree(doodad->text.font);
doodad->text.font= NULL;
}
}
break;
case XkbLogoDoodad:
{
if (doodad->logo.logo_name!=NULL) {
_XkbFree(doodad->logo.logo_name);
doodad->logo.logo_name= NULL;
}
}
break;
}
return;
}
void
XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
{
register int i;
register XkbDoodadPtr doodad;
if (doodads) {
for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
_XkbClearDoodad((char *)doodad);
}
if (freeAll)
_XkbFree(doodads);
}
return;
}
void
XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
{
if (geom==NULL)
return;
if (freeMap)
which= XkbGeomAllMask;
if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
XkbFreeGeomProperties(geom,0,geom->num_properties,True);
if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
XkbFreeGeomColors(geom,0,geom->num_colors,True);
if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
XkbFreeGeomShapes(geom,0,geom->num_shapes,True);
if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
XkbFreeGeomSections(geom,0,geom->num_sections,True);
if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,True);
geom->doodads= NULL;
geom->num_doodads= geom->sz_doodads= 0;
}
if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,True);
if (freeMap) {
if (geom->label_font!=NULL) {
_XkbFree(geom->label_font);
geom->label_font= NULL;
}
_XkbFree(geom);
}
return;
}
/***====================================================================***/
static Status
_XkbGeomAlloc( XPointer * old,
unsigned short * num,
unsigned short * total,
int num_new,
Size_t sz_elem)
{
if (num_new<1)
return Success;
if ((*old)==NULL)
*num= *total= 0;
if ((*num)+num_new<=(*total))
return Success;
*total= (*num)+num_new;
if ((*old)!=NULL)
(*old)= (XPointer)_XkbRealloc((*old),(*total)*sz_elem);
else (*old)= (XPointer)_XkbCalloc((*total),sz_elem);
if ((*old)==NULL) {
*total= *num= 0;
return BadAlloc;
}
if (*num>0) {
char *tmp= (char *)(*old);
bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
}
return Success;
}
#define _XkbAllocProps(g,n) _XkbGeomAlloc((XPointer *)&(g)->properties,\
&(g)->num_properties,&(g)->sz_properties,\
(n),sizeof(XkbPropertyRec))
#define _XkbAllocColors(g,n) _XkbGeomAlloc((XPointer *)&(g)->colors,\
&(g)->num_colors,&(g)->sz_colors,\
(n),sizeof(XkbColorRec))
#define _XkbAllocShapes(g,n) _XkbGeomAlloc((XPointer *)&(g)->shapes,\
&(g)->num_shapes,&(g)->sz_shapes,\
(n),sizeof(XkbShapeRec))
#define _XkbAllocSections(g,n) _XkbGeomAlloc((XPointer *)&(g)->sections,\
&(g)->num_sections,&(g)->sz_sections,\
(n),sizeof(XkbSectionRec))
#define _XkbAllocDoodads(g,n) _XkbGeomAlloc((XPointer *)&(g)->doodads,\
&(g)->num_doodads,&(g)->sz_doodads,\
(n),sizeof(XkbDoodadRec))
#define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases,\
&(g)->num_key_aliases,&(g)->sz_key_aliases,\
(n),sizeof(XkbKeyAliasRec))
#define _XkbAllocOutlines(s,n) _XkbGeomAlloc((XPointer *)&(s)->outlines,\
&(s)->num_outlines,&(s)->sz_outlines,\
(n),sizeof(XkbOutlineRec))
#define _XkbAllocRows(s,n) _XkbGeomAlloc((XPointer *)&(s)->rows,\
&(s)->num_rows,&(s)->sz_rows,\
(n),sizeof(XkbRowRec))
#define _XkbAllocPoints(o,n) _XkbGeomAlloc((XPointer *)&(o)->points,\
&(o)->num_points,&(o)->sz_points,\
(n),sizeof(XkbPointRec))
#define _XkbAllocKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
&(r)->num_keys,&(r)->sz_keys,\
(n),sizeof(XkbKeyRec))
#define _XkbAllocOverlays(s,n) _XkbGeomAlloc((XPointer *)&(s)->overlays,\
&(s)->num_overlays,&(s)->sz_overlays,\
(n),sizeof(XkbOverlayRec))
#define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((XPointer *)&(o)->rows,\
&(o)->num_rows,&(o)->sz_rows,\
(n),sizeof(XkbOverlayRowRec))
#define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
&(r)->num_keys,&(r)->sz_keys,\
(n),sizeof(XkbOverlayKeyRec))
Status
XkbAllocGeomProps(XkbGeometryPtr geom,int nProps)
{
return _XkbAllocProps(geom,nProps);
}
Status
XkbAllocGeomColors(XkbGeometryPtr geom,int nColors)
{
return _XkbAllocColors(geom,nColors);
}
Status
XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases)
{
return _XkbAllocKeyAliases(geom,nKeyAliases);
}
Status
XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes)
{
return _XkbAllocShapes(geom,nShapes);
}
Status
XkbAllocGeomSections(XkbGeometryPtr geom,int nSections)
{
return _XkbAllocSections(geom,nSections);
}
Status
XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays)
{
return _XkbAllocOverlays(section,nOverlays);
}
Status
XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows)
{
return _XkbAllocOverlayRows(overlay,nRows);
}
Status
XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys)
{
return _XkbAllocOverlayKeys(row,nKeys);
}
Status
XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads)
{
return _XkbAllocDoodads(geom,nDoodads);
}
Status
XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads)
{
return _XkbAllocDoodads(section,nDoodads);
}
Status
XkbAllocGeomOutlines(XkbShapePtr shape,int nOL)
{
return _XkbAllocOutlines(shape,nOL);
}
Status
XkbAllocGeomRows(XkbSectionPtr section,int nRows)
{
return _XkbAllocRows(section,nRows);
}
Status
XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts)
{
return _XkbAllocPoints(ol,nPts);
}
Status
XkbAllocGeomKeys(XkbRowPtr row,int nKeys)
{
return _XkbAllocKeys(row,nKeys);
}
Status
XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes)
{
XkbGeometryPtr geom;
Status rtrn;
if (xkb->geom==NULL) {
xkb->geom= _XkbTypedCalloc(1,XkbGeometryRec);
if (!xkb->geom)
return BadAlloc;
}
geom= xkb->geom;
if ((sizes->which&XkbGeomPropertiesMask)&&
((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
goto BAIL;
}
if ((sizes->which&XkbGeomColorsMask)&&
((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
goto BAIL;
}
if ((sizes->which&XkbGeomShapesMask)&&
((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
goto BAIL;
}
if ((sizes->which&XkbGeomSectionsMask)&&
((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
goto BAIL;
}
if ((sizes->which&XkbGeomDoodadsMask)&&
((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
goto BAIL;
}
if ((sizes->which&XkbGeomKeyAliasesMask)&&
((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
goto BAIL;
}
return Success;
BAIL:
XkbFreeGeometry(geom,XkbGeomAllMask,True);
xkb->geom= NULL;
return rtrn;
}
/***====================================================================***/
XkbPropertyPtr
XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value)
{
register int i;
register XkbPropertyPtr prop;
if ((!geom)||(!name)||(!value))
return NULL;
for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
if ((prop->name)&&(strcmp(name,prop->name)==0)) {
if (prop->value)
_XkbFree(prop->value);
prop->value= (char *)_XkbAlloc(strlen(value)+1);
if (prop->value)
strcpy(prop->value,value);
return prop;
}
}
if ((geom->num_properties>=geom->sz_properties)&&
(_XkbAllocProps(geom,1)!=Success)) {
return NULL;
}
prop= &geom->properties[geom->num_properties];
prop->name= (char *)_XkbAlloc(strlen(name)+1);
if (!name)
return NULL;
strcpy(prop->name,name);
prop->value= (char *)_XkbAlloc(strlen(value)+1);
if (!value) {
_XkbFree(prop->name);
prop->name= NULL;
return NULL;
}
strcpy(prop->value,value);
geom->num_properties++;
return prop;
}
XkbKeyAliasPtr
XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr)
{
register int i;
register XkbKeyAliasPtr alias;
if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0]))
return NULL;
for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) {
if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) {
bzero(alias->real,XkbKeyNameLength);
strncpy(alias->real,realStr,XkbKeyNameLength);
return alias;
}
}
if ((geom->num_key_aliases>=geom->sz_key_aliases)&&
(_XkbAllocKeyAliases(geom,1)!=Success)) {
return NULL;
}
alias= &geom->key_aliases[geom->num_key_aliases];
bzero(alias,sizeof(XkbKeyAliasRec));
strncpy(alias->alias,aliasStr,XkbKeyNameLength);
strncpy(alias->real,realStr,XkbKeyNameLength);
geom->num_key_aliases++;
return alias;
}
XkbColorPtr
XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel)
{
register int i;
register XkbColorPtr color;
if ((!geom)||(!spec))
return NULL;
for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
color->pixel= pixel;
return color;
}
}
if ((geom->num_colors>=geom->sz_colors)&&
(_XkbAllocColors(geom,1)!=Success)) {
return NULL;
}
color= &geom->colors[geom->num_colors];
color->pixel= pixel;
color->spec= (char *)_XkbAlloc(strlen(spec)+1);
if (!color->spec)
return NULL;
strcpy(color->spec,spec);
geom->num_colors++;
return color;
}
XkbOutlinePtr
XkbAddGeomOutline(XkbShapePtr shape,int sz_points)
{
XkbOutlinePtr outline;
if ((!shape)||(sz_points<0))
return NULL;
if ((shape->num_outlines>=shape->sz_outlines)&&
(_XkbAllocOutlines(shape,1)!=Success)) {
return NULL;
}
outline= &shape->outlines[shape->num_outlines];
bzero(outline,sizeof(XkbOutlineRec));
if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
return NULL;
shape->num_outlines++;
return outline;
}
XkbShapePtr
XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines)
{
XkbShapePtr shape;
register int i;
if ((!geom)||(!name)||(sz_outlines<0))
return NULL;
if (geom->num_shapes>0) {
for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
if (name==shape->name)
return shape;
}
}
if ((geom->num_shapes>=geom->sz_shapes)&&
(_XkbAllocShapes(geom,1)!=Success))
return NULL;
shape= &geom->shapes[geom->num_shapes];
bzero(shape,sizeof(XkbShapeRec));
if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
return NULL;
shape->name= name;
shape->primary= shape->approx= NULL;
geom->num_shapes++;
return shape;
}
XkbKeyPtr
XkbAddGeomKey(XkbRowPtr row)
{
XkbKeyPtr key;
if (!row)
return NULL;
if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
return NULL;
key= &row->keys[row->num_keys++];
bzero(key,sizeof(XkbKeyRec));
return key;
}
XkbRowPtr
XkbAddGeomRow(XkbSectionPtr section,int sz_keys)
{
XkbRowPtr row;
if ((!section)||(sz_keys<0))
return NULL;
if ((section->num_rows>=section->sz_rows)&&
(_XkbAllocRows(section,1)!=Success))
return NULL;
row= &section->rows[section->num_rows];
bzero(row,sizeof(XkbRowRec));
if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
return NULL;
section->num_rows++;
return row;
}
XkbSectionPtr
XkbAddGeomSection( XkbGeometryPtr geom,
Atom name,
int sz_rows,
int sz_doodads,
int sz_over)
{
register int i;
XkbSectionPtr section;
if ((!geom)||(name==None)||(sz_rows<0))
return NULL;
for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
if (section->name!=name)
continue;
if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
return NULL;
return section;
}
if ((geom->num_sections>=geom->sz_sections)&&
(_XkbAllocSections(geom,1)!=Success))
return NULL;
section= &geom->sections[geom->num_sections];
if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
return NULL;
if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
if (section->rows) {
_XkbFree(section->rows);
section->rows= NULL;
section->sz_rows= section->num_rows= 0;
}
return NULL;
}
section->name= name;
geom->num_sections++;
return section;
}
XkbDoodadPtr
XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name)
{
XkbDoodadPtr old,doodad;
register int i,nDoodads;
if ((!geom)||(name==None))
return NULL;
if ((section!=NULL)&&(section->num_doodads>0)) {
old= section->doodads;
nDoodads= section->num_doodads;
}
else {
old= geom->doodads;
nDoodads= geom->num_doodads;
}
for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
if (doodad->any.name==name)
return doodad;
}
if (section) {
if ((section->num_doodads>=geom->sz_doodads)&&
(_XkbAllocDoodads(section,1)!=Success)) {
return NULL;
}
doodad= &section->doodads[section->num_doodads++];
}
else {
if ((geom->num_doodads>=geom->sz_doodads)&&
(_XkbAllocDoodads(geom,1)!=Success))
return NULL;
doodad= &geom->doodads[geom->num_doodads++];
}
bzero(doodad,sizeof(XkbDoodadRec));
doodad->any.name= name;
return doodad;
}
XkbOverlayKeyPtr
XkbAddGeomOverlayKey( XkbOverlayPtr overlay,
XkbOverlayRowPtr row,
char * over,
char * under)
{
register int i;
XkbOverlayKeyPtr key;
XkbSectionPtr section;
XkbRowPtr row_under;
Bool found;
if ((!overlay)||(!row)||(!over)||(!under))
return NULL;
section= overlay->section_under;
if (row->row_under>=section->num_rows)
return NULL;
row_under= &section->rows[row->row_under];
for (i=0,found=False;i<row_under->num_keys;i++) {
if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) {
found= True;
break;
}
}
if (!found)
return NULL;
if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success))
return NULL;
key= &row->keys[row->num_keys];
strncpy(key->under.name,under,XkbKeyNameLength);
strncpy(key->over.name,over,XkbKeyNameLength);
row->num_keys++;
return key;
}
XkbOverlayRowPtr
XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys)
{
register int i;
XkbOverlayRowPtr row;
if ((!overlay)||(sz_keys<0))
return NULL;
if (row_under>=overlay->section_under->num_rows)
return NULL;
for (i=0;i<overlay->num_rows;i++) {
if (overlay->rows[i].row_under==row_under) {
row= &overlay->rows[i];
if ((row->sz_keys<sz_keys)&&
(_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
return NULL;
}
return &overlay->rows[i];
}
}
if ((overlay->num_rows>=overlay->sz_rows)&&
(_XkbAllocOverlayRows(overlay,1)!=Success))
return NULL;
row= &overlay->rows[overlay->num_rows];
bzero(row,sizeof(XkbOverlayRowRec));
if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
return NULL;
row->row_under= row_under;
overlay->num_rows++;
return row;
}
XkbOverlayPtr
XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows)
{
register int i;
XkbOverlayPtr overlay;
if ((!section)||(name==None)||(sz_rows==0))
return NULL;
for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
if (overlay->name==name) {
if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
return NULL;
return overlay;
}
}
if ((section->num_overlays>=section->sz_overlays)&&
(_XkbAllocOverlays(section,1)!=Success))
return NULL;
overlay= &section->overlays[section->num_overlays];
if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
return NULL;
overlay->name= name;
overlay->section_under= section;
section->num_overlays++;
return overlay;
}
/************************************************************
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation, and that the name of Silicon Graphics not be
used in advertising or publicity pertaining to distribution
of the software without specific prior written permission.
Silicon Graphics makes no representation about the suitability
of this software for any purpose. It is provided "as is"
without any express or implied warranty.
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
THE USE OR PERFORMANCE OF THIS SOFTWARE.
********************************************************/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#elif defined(HAVE_CONFIG_H)
#include <config.h>
#endif
#ifndef XKB_IN_SERVER
#include <stdio.h>
#include "Xlibint.h"
#include <nx-X11/extensions/XKBproto.h>
#include <nx-X11/keysym.h>
#include "XKBlibint.h"
#else
#include <stdio.h>
#include <nx-X11/X.h>
#include <nx-X11/Xproto.h>
#include "misc.h"
#include "inputstr.h"
#include <nx-X11/keysym.h>
#define XKBSRV_NEED_FILE_FUNCS
#include <nx-X11/extensions/XKBsrv.h>
#endif /* XKB_IN_SERVER */
/***====================================================================***/
Status
XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes)
{
register int i;
XkbClientMapPtr map;
if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes)))
return BadValue;
if ((which&XkbKeySymsMask)&&
((!XkbIsLegalKeycode(xkb->min_key_code))||
(!XkbIsLegalKeycode(xkb->max_key_code))||
(xkb->max_key_code<xkb->min_key_code))) {
#ifdef DEBUG
fprintf(stderr,"bad keycode (%d,%d) in XkbAllocClientMap\n",
xkb->min_key_code,xkb->max_key_code);
#endif
return BadValue;
}
if (xkb->map==NULL) {
map= _XkbTypedCalloc(1,XkbClientMapRec);
if (map==NULL)
return BadAlloc;
xkb->map= map;
}
else map= xkb->map;
if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) {
if (map->types==NULL) {
map->types= _XkbTypedCalloc(nTotalTypes,XkbKeyTypeRec);
if (map->types==NULL)
return BadAlloc;
map->num_types= 0;
map->size_types= nTotalTypes;
}
else if (map->size_types<nTotalTypes) {
XkbKeyTypeRec *prev_types = map->types;
map->types= _XkbTypedRealloc(map->types,nTotalTypes,XkbKeyTypeRec);
if (map->types==NULL) {
_XkbFree(prev_types);
map->num_types= map->size_types= 0;
return BadAlloc;
}
map->size_types= nTotalTypes;
bzero(&map->types[map->num_types],
((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec)));
}
}
if (which&XkbKeySymsMask) {
int nKeys= XkbNumKeys(xkb);
if (map->syms==NULL) {
map->size_syms= (nKeys*15)/10;
map->syms= _XkbTypedCalloc(map->size_syms,KeySym);
if (!map->syms) {
map->size_syms= 0;
return BadAlloc;
}
map->num_syms= 1;
map->syms[0]= NoSymbol;
}
if (map->key_sym_map==NULL) {
i= xkb->max_key_code+1;
map->key_sym_map= _XkbTypedCalloc(i,XkbSymMapRec);
if (map->key_sym_map==NULL)
return BadAlloc;
}
}
if (which&XkbModifierMapMask) {
if ((!XkbIsLegalKeycode(xkb->min_key_code))||
(!XkbIsLegalKeycode(xkb->max_key_code))||
(xkb->max_key_code<xkb->min_key_code))
return BadMatch;
if (map->modmap==NULL) {
i= xkb->max_key_code+1;
map->modmap= _XkbTypedCalloc(i,unsigned char);
if (map->modmap==NULL)
return BadAlloc;
}
}
return Success;
}
Status
XkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions)
{
register int i;
XkbServerMapPtr map;
if (xkb==NULL)
return BadMatch;
if (xkb->server==NULL) {
map= _XkbTypedCalloc(1,XkbServerMapRec);
if (map==NULL)
return BadAlloc;
for (i=0;i<XkbNumVirtualMods;i++) {
map->vmods[i]= XkbNoModifierMask;
}
xkb->server= map;
}
else map= xkb->server;
if (which&XkbExplicitComponentsMask) {
if ((!XkbIsLegalKeycode(xkb->min_key_code))||
(!XkbIsLegalKeycode(xkb->max_key_code))||
(xkb->max_key_code<xkb->min_key_code))
return BadMatch;
if (map->explicit==NULL) {
i= xkb->max_key_code+1;
map->explicit= _XkbTypedCalloc(i,unsigned char);
if (map->explicit==NULL)
return BadAlloc;
}
}
if (which&XkbKeyActionsMask) {
if ((!XkbIsLegalKeycode(xkb->min_key_code))||
(!XkbIsLegalKeycode(xkb->max_key_code))||
(xkb->max_key_code<xkb->min_key_code))
return BadMatch;
if (nNewActions<1)
nNewActions= 1;
if (map->acts==NULL) {
map->acts= _XkbTypedCalloc((nNewActions+1),XkbAction);
if (map->acts==NULL)
return BadAlloc;
map->num_acts= 1;
map->size_acts= nNewActions+1;
}
else if ((map->size_acts-map->num_acts)<nNewActions) {
unsigned need;
XkbAction *prev_acts = map->acts;
need= map->num_acts+nNewActions;
map->acts= _XkbTypedRealloc(map->acts,need,XkbAction);
if (map->acts==NULL) {
_XkbFree(prev_acts);
map->num_acts= map->size_acts= 0;
return BadAlloc;
}
map->size_acts= need;
bzero(&map->acts[map->num_acts],
((map->size_acts-map->num_acts)*sizeof(XkbAction)));
}
if (map->key_acts==NULL) {
i= xkb->max_key_code+1;
map->key_acts= _XkbTypedCalloc(i,unsigned short);
if (map->key_acts==NULL)
return BadAlloc;
}
}
if (which&XkbKeyBehaviorsMask) {
if ((!XkbIsLegalKeycode(xkb->min_key_code))||
(!XkbIsLegalKeycode(xkb->max_key_code))||
(xkb->max_key_code<xkb->min_key_code))
return BadMatch;
if (map->behaviors==NULL) {
i= xkb->max_key_code+1;
map->behaviors= _XkbTypedCalloc(i,XkbBehavior);
if (map->behaviors==NULL)
return BadAlloc;
}
}
if (which&XkbVirtualModMapMask) {
if ((!XkbIsLegalKeycode(xkb->min_key_code))||
(!XkbIsLegalKeycode(xkb->max_key_code))||
(xkb->max_key_code<xkb->min_key_code))
return BadMatch;
if (map->vmodmap==NULL) {
i= xkb->max_key_code+1;
map->vmodmap= _XkbTypedCalloc(i,unsigned short);
if (map->vmodmap==NULL)
return BadAlloc;
}
}
return Success;
}
/***====================================================================***/
Status
XkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into)
{
if ((!from)||(!into))
return BadMatch;
if (into->map) {
_XkbFree(into->map);
into->map= NULL;
}
if (into->preserve) {
_XkbFree(into->preserve);
into->preserve= NULL;
}
if (into->level_names) {
_XkbFree(into->level_names);
into->level_names= NULL;
}
*into= *from;
if ((from->map)&&(into->map_count>0)) {
into->map= _XkbTypedCalloc(into->map_count,XkbKTMapEntryRec);
if (!into->map)
return BadAlloc;
memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec));
}
if ((from->preserve)&&(into->map_count>0)) {
into->preserve= _XkbTypedCalloc(into->map_count,XkbModsRec);
if (!into->preserve)
return BadAlloc;
memcpy(into->preserve,from->preserve,
into->map_count*sizeof(XkbModsRec));
}
if ((from->level_names)&&(into->num_levels>0)) {
into->level_names= _XkbTypedCalloc(into->num_levels,Atom);
if (!into->level_names)
return BadAlloc;
memcpy(into->level_names,from->level_names,
into->num_levels*sizeof(Atom));
}
return Success;
}
Status
XkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types)
{
register int i,rtrn;
if ((!from)||(!into)||(num_types<0))
return BadMatch;
for (i=0;i<num_types;i++) {
if ((rtrn= XkbCopyKeyType(from++,into++))!=Success)
return rtrn;
}
return Success;
}
XkbKeyTypePtr
XkbAddKeyType( XkbDescPtr xkb,
Atom name,
int map_count,
Bool want_preserve,
int num_lvls)
{
register int i;
unsigned tmp;
XkbKeyTypePtr type;
XkbClientMapPtr map;
if ((!xkb)||(num_lvls<1))
return NULL;
map= xkb->map;
if ((map)&&(map->types)) {
for (i=0;i<map->num_types;i++) {
if (map->types[i].name==name) {
Status status;
status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls);
return (status==Success?&map->types[i]:NULL);
}
}
}
if ((!map)||(!map->types)||(!map->num_types<XkbNumRequiredTypes)) {
tmp= XkbNumRequiredTypes+1;
if (XkbAllocClientMap(xkb,XkbKeyTypesMask,tmp)!=Success)
return NULL;
tmp= 0;
if (map->num_types<=XkbKeypadIndex)
tmp|= XkbKeypadMask;
if (map->num_types<=XkbAlphabeticIndex)
tmp|= XkbAlphabeticMask;
if (map->num_types<=XkbTwoLevelIndex)
tmp|= XkbTwoLevelMask;
if (map->num_types<=XkbOneLevelIndex)
tmp|= XkbOneLevelMask;
if (XkbInitCanonicalKeyTypes(xkb,tmp,XkbNoModifier)==Success) {
for (i=0;i<map->num_types;i++) {
Status status;
if (map->types[i].name!=name)
continue;
status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls);
return (status==Success?&map->types[i]:NULL);
}
}
}
if ((map->num_types<=map->size_types)&&
(XkbAllocClientMap(xkb,XkbKeyTypesMask,map->num_types+1)!=Success)) {
return NULL;
}
type= &map->types[map->num_types];
map->num_types++;
bzero((char *)type,sizeof(XkbKeyTypeRec));
type->num_levels= num_lvls;
type->map_count= map_count;
type->name= name;
if (map_count>0) {
type->map= _XkbTypedCalloc(map_count,XkbKTMapEntryRec);
if (!type->map) {
map->num_types--;
return NULL;
}
if (want_preserve) {
type->preserve= _XkbTypedCalloc(map_count,XkbModsRec);
if (!type->preserve) {
_XkbFree(type->map);
map->num_types--;
return NULL;
}
}
}
return type;
}
Status
XkbResizeKeyType( XkbDescPtr xkb,
int type_ndx,
int map_count,
Bool want_preserve,
int new_num_lvls)
{
XkbKeyTypePtr type;
KeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys;
if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)||
(new_num_lvls<1))
return BadValue;
switch (type_ndx) {
case XkbOneLevelIndex:
if (new_num_lvls!=1)
return BadMatch;
break;
case XkbTwoLevelIndex:
case XkbAlphabeticIndex:
case XkbKeypadIndex:
if (new_num_lvls!=2)
return BadMatch;
break;
}
type= &xkb->map->types[type_ndx];
if (map_count==0) {
if (type->map!=NULL)
_XkbFree(type->map);
type->map= NULL;
if (type->preserve!=NULL)
_XkbFree(type->preserve);
type->preserve= NULL;
type->map_count= 0;
}
else {
XkbKTMapEntryRec *prev_map = type->map;
if ((map_count>type->map_count)||(type->map==NULL))
type->map=_XkbTypedRealloc(type->map,map_count,XkbKTMapEntryRec);
if (!type->map) {
if (prev_map)
_XkbFree(prev_map);
return BadAlloc;
}
if (want_preserve) {
XkbModsRec *prev_preserve = type->preserve;
if ((map_count>type->map_count)||(type->preserve==NULL)) {
type->preserve= _XkbTypedRealloc(type->preserve,map_count,
XkbModsRec);
}
if (!type->preserve) {
if (prev_preserve)
_XkbFree(prev_preserve);
return BadAlloc;
}
}
else if (type->preserve!=NULL) {
_XkbFree(type->preserve);
type->preserve= NULL;
}
type->map_count= map_count;
}
if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) {
Atom * prev_level_names = type->level_names;
type->level_names=_XkbTypedRealloc(type->level_names,new_num_lvls,Atom);
if (!type->level_names) {
if (prev_level_names)
_XkbFree(prev_level_names);
return BadAlloc;
}
}
/*
* Here's the theory:
* If the width of the type changed, we might have to resize the symbol
* maps for any keys that use the type for one or more groups. This is
* expensive, so we'll try to cull out any keys that are obviously okay:
* In any case:
* - keys that have a group width <= the old width are okay (because
* they could not possibly have been associated with the old type)
* If the key type increased in size:
* - keys that already have a group width >= to the new width are okay
* + keys that have a group width >= the old width but < the new width
* might have to be enlarged.
* If the key type decreased in size:
* - keys that have a group width > the old width don't have to be
* resized (because they must have some other wider type associated
* with some group).
* + keys that have a group width == the old width might have to be
* shrunk.
* The possibilities marked with '+' require us to examine the key types
* associated with each group for the key.
*/
bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode));
nMatchingKeys= 0;
if (new_num_lvls>type->num_levels) {
int nTotal;
KeySym * newSyms;
int width,match,nResize;
register int i,g,nSyms;
nResize= 0;
for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
width= XkbKeyGroupsWidth(xkb,i);
if (width<type->num_levels)
continue;
for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
matchingKeys[nMatchingKeys++]= i;
match= 1;
}
}
if ((!match)||(width>=new_num_lvls))
nTotal+= XkbKeyNumSyms(xkb,i);
else {
nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
nResize++;
}
}
if (nResize>0) {
int nextMatch;
xkb->map->size_syms= (nTotal*12)/10;
newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym);
if (newSyms==NULL)
return BadAlloc;
nextMatch= 0;
nSyms= 1;
for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
if (matchingKeys[nextMatch]==i) {
KeySym *pOld;
nextMatch++;
width= XkbKeyGroupsWidth(xkb,i);
pOld= XkbKeySymsPtr(xkb,i);
for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) {
memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g],
width*sizeof(KeySym));
}
xkb->map->key_sym_map[i].offset= nSyms;
nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
}
else {
memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),
XkbKeyNumSyms(xkb,i)*sizeof(KeySym));
xkb->map->key_sym_map[i].offset= nSyms;
nSyms+= XkbKeyNumSyms(xkb,i);
}
}
type->num_levels= new_num_lvls;
_XkbFree(xkb->map->syms);
xkb->map->syms= newSyms;
xkb->map->num_syms= nSyms;
return Success;
}
}
else if (new_num_lvls<type->num_levels) {
int width,match;
register int g,i;
for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
width= XkbKeyGroupsWidth(xkb,i);
if (width<type->num_levels)
continue;
for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
matchingKeys[nMatchingKeys++]= i;
match= 1;
}
}
}
}
if (nMatchingKeys>0) {
int key,firstClear;
register int i,g;
if (new_num_lvls>type->num_levels)
firstClear= type->num_levels;
else firstClear= new_num_lvls;
for (i=0;i<nMatchingKeys;i++) {
KeySym * pSyms;
int width,nClear;
key= matchingKeys[i];
width= XkbKeyGroupsWidth(xkb,key);
nClear= width-firstClear;
pSyms= XkbKeySymsPtr(xkb,key);
for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) {
if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) {
if (nClear>0)
bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym));
}
}
}
}
type->num_levels= new_num_lvls;
return Success;
}
KeySym *
XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed)
{
register int i,nSyms,nKeySyms;
unsigned nOldSyms;
KeySym *newSyms;
if (needed==0) {
xkb->map->key_sym_map[key].offset= 0;
return xkb->map->syms;
}
nOldSyms= XkbKeyNumSyms(xkb,key);
if (nOldSyms>=(unsigned)needed) {
return XkbKeySymsPtr(xkb,key);
}
if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) {
if (nOldSyms>0) {
memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key),
nOldSyms*sizeof(KeySym));
}
if ((needed-nOldSyms)>0) {
bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)],
(needed-nOldSyms)*sizeof(KeySym));
}
xkb->map->key_sym_map[key].offset = xkb->map->num_syms;
xkb->map->num_syms+= needed;
return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
}
xkb->map->size_syms+= (needed>32?needed:32);
newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym);
if (newSyms==NULL)
return NULL;
newSyms[0]= NoSymbol;
nSyms = 1;
for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
int nCopy;
nCopy= nKeySyms= XkbKeyNumSyms(xkb,i);
if ((nKeySyms==0)&&(i!=key))
continue;
if (i==key)
nKeySyms= needed;
if (nCopy!=0)
memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym));
if (nKeySyms>nCopy)
bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym));
xkb->map->key_sym_map[i].offset = nSyms;
nSyms+= nKeySyms;
}
_XkbFree(xkb->map->syms);
xkb->map->syms = newSyms;
xkb->map->num_syms = nSyms;
return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
}
static unsigned
_ExtendRange( unsigned int old_flags,
unsigned int flag,
KeyCode newKC,
KeyCode * old_min,
unsigned char * old_num)
{
if ((old_flags&flag)==0) {
old_flags|= flag;
*old_min= newKC;
*old_num= 1;
}
else {
int last= (*old_min)+(*old_num)-1;
if (newKC<*old_min) {
*old_min= newKC;
*old_num= (last-newKC)+1;
}
else if (newKC>last) {
*old_num= (newKC-(*old_min))+1;
}
}
return old_flags;
}
Status
XkbChangeKeycodeRange( XkbDescPtr xkb,
int minKC,
int maxKC,
XkbChangesPtr changes)
{
int tmp;
if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode))
return BadValue;
if (minKC>maxKC)
return BadMatch;
if (minKC<xkb->min_key_code) {
if (changes)
changes->map.min_key_code= minKC;
tmp= xkb->min_key_code-minKC;
if (xkb->map) {
if (xkb->map->key_sym_map) {
bzero((char *)&xkb->map->key_sym_map[minKC],
tmp*sizeof(XkbSymMapRec));
if (changes) {
changes->map.changed= _ExtendRange(changes->map.changed,
XkbKeySymsMask,minKC,
&changes->map.first_key_sym,
&changes->map.num_key_syms);
}
}
if (xkb->map->modmap) {
bzero((char *)&xkb->map->modmap[minKC],tmp);
if (changes) {
changes->map.changed= _ExtendRange(changes->map.changed,
XkbModifierMapMask,minKC,
&changes->map.first_modmap_key,
&changes->map.num_modmap_keys);
}
}
}
if (xkb->server) {
if (xkb->server->behaviors) {
bzero((char *)&xkb->server->behaviors[minKC],
tmp*sizeof(XkbBehavior));
if (changes) {
changes->map.changed= _ExtendRange(changes->map.changed,
XkbKeyBehaviorsMask,minKC,
&changes->map.first_key_behavior,
&changes->map.num_key_behaviors);
}
}
if (xkb->server->key_acts) {
bzero((char *)&xkb->server->key_acts[minKC],
tmp*sizeof(unsigned short));
if (changes) {
changes->map.changed= _ExtendRange(changes->map.changed,
XkbKeyActionsMask,minKC,
&changes->map.first_key_act,
&changes->map.num_key_acts);
}
}
if (xkb->server->vmodmap) {
bzero((char *)&xkb->server->vmodmap[minKC],
tmp*sizeof(unsigned short));
if (changes) {
changes->map.changed= _ExtendRange(changes->map.changed,
XkbVirtualModMapMask,minKC,
&changes->map.first_modmap_key,
&changes->map.num_vmodmap_keys);
}
}
}
if ((xkb->names)&&(xkb->names->keys)) {
bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec));
if (changes) {
changes->names.changed= _ExtendRange(changes->names.changed,
XkbKeyNamesMask,minKC,
&changes->names.first_key,
&changes->names.num_keys);
}
}
xkb->min_key_code= minKC;
}
if (maxKC>xkb->max_key_code) {
if (changes)
changes->map.max_key_code= maxKC;
tmp= maxKC-xkb->max_key_code;
if (xkb->map) {
if (xkb->map->key_sym_map) {
XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map;
xkb->map->key_sym_map= _XkbTypedRealloc(xkb->map->key_sym_map,
(maxKC+1),XkbSymMapRec);
if (!xkb->map->key_sym_map) {
_XkbFree(prev_key_sym_map);
return BadAlloc;
}
#ifdef NXAGENT_SERVER
bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code+1],
tmp*sizeof(XkbSymMapRec));
#else
bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code],
tmp*sizeof(XkbSymMapRec));
#endif
if (changes) {
changes->map.changed= _ExtendRange(changes->map.changed,
XkbKeySymsMask,maxKC,
&changes->map.first_key_sym,
&changes->map.num_key_syms);
}
}
if (xkb->map->modmap) {
unsigned char *prev_modmap = xkb->map->modmap;
xkb->map->modmap= _XkbTypedRealloc(xkb->map->modmap,
(maxKC+1),unsigned char);
if (!xkb->map->modmap) {
_XkbFree(prev_modmap);
return BadAlloc;
}
#ifdef NXAGENT_SERVER
bzero((char *)&xkb->map->modmap[xkb->max_key_code+1],tmp);
#else
bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp);
#endif
if (changes) {
changes->map.changed= _ExtendRange(changes->map.changed,
XkbModifierMapMask,maxKC,
&changes->map.first_modmap_key,
&changes->map.num_modmap_keys);
}
}
}
if (xkb->server) {
if (xkb->server->behaviors) {
XkbBehavior *prev_behaviors = xkb->server->behaviors;
xkb->server->behaviors=_XkbTypedRealloc(xkb->server->behaviors,
(maxKC+1),XkbBehavior);
if (!xkb->server->behaviors) {
_XkbFree(prev_behaviors);
return BadAlloc;
}
#ifdef NXAGENT_SERVER
bzero((char *)&xkb->server->behaviors[xkb->max_key_code+1],
tmp*sizeof(XkbBehavior));
#else
bzero((char *)&xkb->server->behaviors[xkb->max_key_code],
tmp*sizeof(XkbBehavior));
#endif
if (changes) {
changes->map.changed= _ExtendRange(changes->map.changed,
XkbKeyBehaviorsMask,maxKC,
&changes->map.first_key_behavior,
&changes->map.num_key_behaviors);
}
}
if (xkb->server->key_acts) {
unsigned short *prev_key_acts = xkb->server->key_acts;
xkb->server->key_acts= _XkbTypedRealloc(xkb->server->key_acts,
(maxKC+1),unsigned short);
if (!xkb->server->key_acts) {
_XkbFree(prev_key_acts);
return BadAlloc;
}
#ifdef NXAGENT_SERVER
bzero((char *)&xkb->server->key_acts[xkb->max_key_code+1],
tmp*sizeof(unsigned short));
#else
bzero((char *)&xkb->server->key_acts[xkb->max_key_code],
tmp*sizeof(unsigned short));
#endif
if (changes) {
changes->map.changed= _ExtendRange(changes->map.changed,
XkbKeyActionsMask,maxKC,
&changes->map.first_key_act,
&changes->map.num_key_acts);
}
}
if (xkb->server->vmodmap) {
unsigned short *prev_vmodmap = xkb->server->vmodmap;
xkb->server->vmodmap= _XkbTypedRealloc(xkb->server->vmodmap,
(maxKC+1),unsigned short);
if (!xkb->server->vmodmap) {
_XkbFree(prev_vmodmap);
return BadAlloc;
}
#ifdef NXAGENT_SERVER
bzero((char *)&xkb->server->vmodmap[xkb->max_key_code+1],
tmp*sizeof(unsigned short));
#else
bzero((char *)&xkb->server->vmodmap[xkb->max_key_code],
tmp*sizeof(unsigned short));
#endif
if (changes) {
changes->map.changed= _ExtendRange(changes->map.changed,
XkbVirtualModMapMask,maxKC,
&changes->map.first_modmap_key,
&changes->map.num_vmodmap_keys);
}
}
}
if ((xkb->names)&&(xkb->names->keys)) {
XkbKeyNameRec *prev_keys = xkb->names->keys;
xkb->names->keys= _XkbTypedRealloc(xkb->names->keys,
(maxKC+1),XkbKeyNameRec);
if (!xkb->names->keys) {
_XkbFree(prev_keys);
return BadAlloc;
}
#ifdef NXAGENT_SERVER
bzero((char *)&xkb->names->keys[xkb->max_key_code+1],
tmp*sizeof(XkbKeyNameRec));
#else
bzero((char *)&xkb->names->keys[xkb->max_key_code],
tmp*sizeof(XkbKeyNameRec));
#endif
if (changes) {
changes->names.changed= _ExtendRange(changes->names.changed,
XkbKeyNamesMask,maxKC,
&changes->names.first_key,
&changes->names.num_keys);
}
}
xkb->max_key_code= maxKC;
}
return Success;
}
XkbAction *
XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed)
{
register int i,nActs;
XkbAction *newActs;
if (needed==0) {
xkb->server->key_acts[key]= 0;
return NULL;
}
if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed))
return XkbKeyActionsPtr(xkb,key);
if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) {
xkb->server->key_acts[key]= xkb->server->num_acts;
xkb->server->num_acts+= needed;
return &xkb->server->acts[xkb->server->key_acts[key]];
}
xkb->server->size_acts= xkb->server->num_acts+needed+8;
newActs = _XkbTypedCalloc(xkb->server->size_acts,XkbAction);
if (newActs==NULL)
return NULL;
newActs[0].type = XkbSA_NoAction;
nActs = 1;
for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
int nKeyActs,nCopy;
if ((xkb->server->key_acts[i]==0)&&(i!=key))
continue;
nCopy= nKeyActs= XkbKeyNumActions(xkb,i);
if (i==key) {
nKeyActs= needed;
if (needed<nCopy)
nCopy= needed;
}
if (nCopy>0)
memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i),
nCopy*sizeof(XkbAction));
if (nCopy<nKeyActs)
bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction));
xkb->server->key_acts[i]= nActs;
nActs+= nKeyActs;
}
_XkbFree(xkb->server->acts);
xkb->server->acts = newActs;
xkb->server->num_acts= nActs;
return &xkb->server->acts[xkb->server->key_acts[key]];
}
void
XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
{
XkbClientMapPtr map;
if ((xkb==NULL)||(xkb->map==NULL))
return;
if (freeMap)
what= XkbAllClientInfoMask;
map= xkb->map;
if (what&XkbKeyTypesMask) {
if (map->types!=NULL) {
if (map->num_types>0) {
register int i;
XkbKeyTypePtr type;
for (i=0,type=map->types;i<map->num_types;i++,type++) {
if (type->map!=NULL) {
_XkbFree(type->map);
type->map= NULL;
}
if (type->preserve!=NULL) {
_XkbFree(type->preserve);
type->preserve= NULL;
}
type->map_count= 0;
if (type->level_names!=NULL) {
_XkbFree(type->level_names);
type->level_names= NULL;
}
}
}
_XkbFree(map->types);
map->num_types= map->size_types= 0;
map->types= NULL;
}
}
if (what&XkbKeySymsMask) {
if (map->key_sym_map!=NULL) {
_XkbFree(map->key_sym_map);
map->key_sym_map= NULL;
}
if (map->syms!=NULL) {
_XkbFree(map->syms);
map->size_syms= map->num_syms= 0;
map->syms= NULL;
}
}
if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) {
_XkbFree(map->modmap);
map->modmap= NULL;
}
if (freeMap) {
_XkbFree(xkb->map);
xkb->map= NULL;
}
return;
}
void
XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
{
XkbServerMapPtr map;
if ((xkb==NULL)||(xkb->server==NULL))
return;
if (freeMap)
what= XkbAllServerInfoMask;
map= xkb->server;
if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) {
_XkbFree(map->explicit);
map->explicit= NULL;
}
if (what&XkbKeyActionsMask) {
if (map->key_acts!=NULL) {
_XkbFree(map->key_acts);
map->key_acts= NULL;
}
if (map->acts!=NULL) {
_XkbFree(map->acts);
map->num_acts= map->size_acts= 0;
map->acts= NULL;
}
}
if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) {
_XkbFree(map->behaviors);
map->behaviors= NULL;
}
if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) {
_XkbFree(map->vmodmap);
map->vmodmap= NULL;
}
if (freeMap) {
_XkbFree(xkb->server);
xkb->server= NULL;
}
return;
}
/************************************************************
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation, and that the name of Silicon Graphics not be
used in advertising or publicity pertaining to distribution
of the software without specific prior written permission.
Silicon Graphics makes no representation about the suitability
of this software for any purpose. It is provided "as is"
without any express or implied warranty.
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
THE USE OR PERFORMANCE OF THIS SOFTWARE.
********************************************************/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#elif defined(HAVE_CONFIG_H)
#include <config.h>
#endif
#ifndef XKB_IN_SERVER
#include <stdio.h>
#include "Xlibint.h"
#include <nx-X11/extensions/XKBproto.h>
#include <nx-X11/keysym.h>
#include "XKBlibint.h"
#else
#include <stdio.h>
#include <nx-X11/X.h>
#include <nx-X11/Xproto.h>
#include "misc.h"
#include "inputstr.h"
#include <nx-X11/keysym.h>
#define XKBSRV_NEED_FILE_FUNCS
#include <nx-X11/extensions/XKBsrv.h>
#endif /* XKB_IN_SERVER */
/***====================================================================***/
#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec))
static XkbKTMapEntryRec map2Level[]= {
{ True, ShiftMask, {1, ShiftMask, 0} }
};
static XkbKTMapEntryRec mapAlpha[]= {
{ True, ShiftMask, { 1, ShiftMask, 0 } },
{ True, LockMask, { 0, LockMask, 0 } }
};
static XkbModsRec preAlpha[]= {
{ 0, 0, 0 },
{ LockMask, LockMask, 0 }
};
#define NL_VMOD_MASK 0
static XkbKTMapEntryRec mapKeypad[]= {
{ True, ShiftMask, { 1, ShiftMask, 0 } },
{ False, 0, { 1, 0, NL_VMOD_MASK } }
};
static XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = {
{ { 0, 0, 0 },
1, /* num_levels */
0, /* map_count */
NULL, NULL,
None, NULL
},
{ { ShiftMask, ShiftMask, 0 },
2, /* num_levels */
mapSize(map2Level), /* map_count */
map2Level, NULL,
None, NULL
},
{ { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
2, /* num_levels */
mapSize(mapAlpha), /* map_count */
mapAlpha, preAlpha,
None, NULL
},
{ { ShiftMask, ShiftMask, NL_VMOD_MASK },
2, /* num_levels */
mapSize(mapKeypad), /* map_count */
mapKeypad, NULL,
None, NULL
}
};
Status
XkbInitCanonicalKeyTypes(XkbDescPtr xkb,unsigned which,int keypadVMod)
{
XkbClientMapPtr map;
XkbKeyTypePtr from,to;
Status rtrn;
if (!xkb)
return BadMatch;
rtrn= XkbAllocClientMap(xkb,XkbKeyTypesMask,XkbNumRequiredTypes);
if (rtrn!=Success)
return rtrn;
map= xkb->map;
if ((which&XkbAllRequiredTypes)==0)
return Success;
rtrn= Success;
from= canonicalTypes;
to= map->types;
if (which&XkbOneLevelMask)
rtrn= XkbCopyKeyType(&from[XkbOneLevelIndex],&to[XkbOneLevelIndex]);
if ((which&XkbTwoLevelMask)&&(rtrn==Success))
rtrn= XkbCopyKeyType(&from[XkbTwoLevelIndex],&to[XkbTwoLevelIndex]);
if ((which&XkbAlphabeticMask)&&(rtrn==Success))
rtrn= XkbCopyKeyType(&from[XkbAlphabeticIndex],&to[XkbAlphabeticIndex]);
if ((which&XkbKeypadMask)&&(rtrn==Success)) {
XkbKeyTypePtr type;
rtrn= XkbCopyKeyType(&from[XkbKeypadIndex],&to[XkbKeypadIndex]);
type= &to[XkbKeypadIndex];
if ((keypadVMod>=0)&&(keypadVMod<XkbNumVirtualMods)&&(rtrn==Success)) {
type->mods.vmods= (1<<keypadVMod);
type->map[0].active= True;
type->map[0].mods.mask= ShiftMask;
type->map[0].mods.real_mods= ShiftMask;
type->map[0].mods.vmods= 0;
type->map[0].level= 1;
type->map[1].active= False;
type->map[1].mods.mask= 0;
type->map[1].mods.real_mods= 0;
type->map[1].mods.vmods= (1<<keypadVMod);
type->map[1].level= 1;
}
}
return Success;
}
/***====================================================================***/
#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
int
XkbKeyTypesForCoreSymbols( XkbDescPtr xkb,
int map_width,
KeySym * core_syms,
unsigned int protected,
int * types_inout,
KeySym * xkb_syms_rtrn)
{
register int i;
unsigned int empty;
int nSyms[XkbNumKbdGroups];
int nGroups,tmp,groupsWidth;
/* Section 12.2 of the protocol describes this process in more detail */
/* Step 1: find the # of symbols in the core mapping per group */
groupsWidth= 2;
for (i=0;i<XkbNumKbdGroups;i++) {
if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) {
nSyms[i]= xkb->map->types[types_inout[i]].num_levels;
if (nSyms[i]>groupsWidth)
groupsWidth= nSyms[i];
}
else {
types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */
nSyms[i]= 2;
}
}
if (nSyms[XkbGroup1Index]<2)
nSyms[XkbGroup1Index]= 2;
if (nSyms[XkbGroup2Index]<2)
nSyms[XkbGroup2Index]= 2;
/* Step 2: Copy the symbols from the core ordering to XKB ordering */
/* symbols in the core are in the order: */
/* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0);
xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1);
for (i=2;i<nSyms[XkbGroup1Index];i++) {
xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i);
}
xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2);
xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3);
tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */
for (i=2;i<nSyms[XkbGroup2Index];i++) {
xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i);
}
tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index];
if ((tmp>=map_width)&&
((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) {
nSyms[XkbGroup3Index]= 0;
nSyms[XkbGroup4Index]= 0;
nGroups= 2;
}
else {
nGroups= 3;
for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) {
xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp);
}
if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) {
nGroups= 4;
for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) {
xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp);
}
}
else {
nSyms[XkbGroup4Index]= 0;
}
}
/* steps 3&4: alphanumeric expansion, assign canonical types */
empty= 0;
for (i=0;i<nGroups;i++) {
KeySym *syms;
syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) {
KeySym upper,lower;
XConvertCase(syms[0],&lower,&upper);
if (upper!=lower) {
xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower;
xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper;
if ((protected&(1<<i))==0)
types_inout[i]= XkbAlphabeticIndex;
}
else if ((protected&(1<<i))==0) {
types_inout[i]= XkbOneLevelIndex;
/* nSyms[i]= 1;*/
}
}
if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) {
if (IsKeypadKey(syms[0])||IsKeypadKey(syms[1]))
types_inout[i]= XkbKeypadIndex;
else {
KeySym upper,lower;
XConvertCase(syms[0],&lower,&upper);
if ((syms[0]==lower)&&(syms[1]==upper))
types_inout[i]= XkbAlphabeticIndex;
}
}
if (syms[0]==NoSymbol) {
register int n;
Bool found;
for (n=1,found=False;(!found)&&(n<nSyms[i]);n++) {
found= (syms[n]!=NoSymbol);
}
if (!found)
empty|= (1<<i);
}
}
/* step 5: squoosh out empty groups */
if (empty) {
for (i=nGroups-1;i>=0;i--) {
if (((empty&(1<<i))==0)||(protected&(1<<i)))
break;
nGroups--;
}
}
if (nGroups<1)
return 0;
/* step 6: replicate group 1 into group two, if necessary */
if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) {
if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) {
nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index];
types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index];
memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn,
2*sizeof(KeySym));
}
else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) {
memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]],
(char *)xkb_syms_rtrn,
nSyms[XkbGroup1Index]*sizeof(KeySym));
}
}
/* step 7: check for all groups identical or all width 1 */
if (nGroups>1) {
Bool sameType,allOneLevel;
allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1);
for (i=1,sameType=True;(allOneLevel||sameType)&&(i<nGroups);i++) {
sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index]));
if (allOneLevel)
allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
}
if ((sameType)&&
(!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
register int s;
Bool identical;
for (i=1,identical=True;identical&&(i<nGroups);i++) {
KeySym *syms;
syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
for (s=0;identical&&(s<nSyms[i]);s++) {
if (syms[s]!=xkb_syms_rtrn[s])
identical= False;
}
}
if (identical)
nGroups= 1;
}
if (allOneLevel && (nGroups>1)) {
KeySym *syms;
syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]];
nSyms[XkbGroup1Index]= 1;
for (i=1;i<nGroups;i++) {
xkb_syms_rtrn[i]= syms[0];
syms+= nSyms[i];
nSyms[i]= 1;
}
}
}
return nGroups;
}
static XkbSymInterpretPtr
_XkbFindMatchingInterp( XkbDescPtr xkb,
KeySym sym,
unsigned int real_mods,
unsigned int level)
{
register unsigned i;
XkbSymInterpretPtr interp,rtrn;
CARD8 mods;
rtrn= NULL;
interp= xkb->compat->sym_interpret;
for (i=0;i<xkb->compat->num_si;i++,interp++) {
if ((interp->sym==NoSymbol)||(sym==interp->sym)) {
int match;
if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0))
mods= real_mods;
else mods= 0;
switch (interp->match&XkbSI_OpMask) {
case XkbSI_NoneOf:
match= ((interp->mods&mods)==0);
break;
case XkbSI_AnyOfOrNone:
match= ((mods==0)||((interp->mods&mods)!=0));
break;
case XkbSI_AnyOf:
match= ((interp->mods&mods)!=0);
break;
case XkbSI_AllOf:
match= ((interp->mods&mods)==interp->mods);
break;
case XkbSI_Exactly:
match= (interp->mods==mods);
break;
default:
match= 0;
break;
}
if (match) {
if (interp->sym!=NoSymbol) {
return interp;
}
else if (rtrn==NULL) {
rtrn= interp;
}
}
}
}
return rtrn;
}
static void
_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey)
{
KeyCode last;
last= (*pFirst)+(*pNum);
if (newKey<*pFirst) {
*pFirst= newKey;
*pNum= (last-newKey)+1;
}
else if (newKey>last) {
*pNum= (last-*pFirst)+1;
}
return;
}
static void
_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
{
unsigned tmp;
switch (act->type) {
case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
if (act->mods.flags&XkbSA_UseModMapMods)
act->mods.real_mods= act->mods.mask= mods;
if ((tmp= XkbModActionVMods(&act->mods))!=0) {
XkbVirtualModsToReal(xkb,tmp,&tmp);
act->mods.mask|= tmp;
}
break;
case XkbSA_ISOLock:
if (act->iso.flags&XkbSA_UseModMapMods)
act->iso.real_mods= act->iso.mask= mods;
if ((tmp= XkbModActionVMods(&act->iso))!=0) {
XkbVirtualModsToReal(xkb,tmp,&tmp);
act->iso.mask|= tmp;
}
break;
}
return;
}
#define IBUF_SIZE 8
Bool
XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes)
{
KeySym * syms;
unsigned char explicit,mods;
XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE];
int n,nSyms,found;
unsigned changed,tmp;
if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)||
(!xkb->compat)||(!xkb->compat->sym_interpret)||
(key<xkb->min_key_code)||(key>xkb->max_key_code)) {
return False;
}
if (((!xkb->server)||(!xkb->server->key_acts))&&
(XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) {
return False;
}
changed= 0; /* keeps track of what has changed in _this_ call */
explicit= xkb->server->explicit[key];
if (explicit&XkbExplicitInterpretMask) /* nothing to do */
return True;
mods= (xkb->map->modmap?xkb->map->modmap[key]:0);
nSyms= XkbKeyNumSyms(xkb,key);
syms= XkbKeySymsPtr(xkb,key);
if (nSyms>IBUF_SIZE) {
interps= _XkbTypedCalloc(nSyms,XkbSymInterpretPtr);
if (interps==NULL) {
interps= ibuf;
nSyms= IBUF_SIZE;
}
}
else {
interps= ibuf;
}
found= 0;
for (n=0;n<nSyms;n++) {
unsigned level= (n%XkbKeyGroupsWidth(xkb,key));
interps[n]= NULL;
if (syms[n]!=NoSymbol) {
interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level);
if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction)
found++;
else interps[n]= NULL;
}
}
/* 1/28/96 (ef) -- XXX! WORKING HERE */
if (!found) {
if (xkb->server->key_acts[key]!=0) {
xkb->server->key_acts[key]= 0;
changed|= XkbKeyActionsMask;
}
}
else {
XkbAction *pActs;
unsigned int new_vmodmask;
changed|= XkbKeyActionsMask;
pActs= XkbResizeKeyActions(xkb,key,nSyms);
if (!pActs)
return False;
new_vmodmask= 0;
for (n=0;n<nSyms;n++) {
if (interps[n]) {
unsigned effMods;
pActs[n]= *((XkbAction *)&interps[n]->act);
if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) {
effMods= mods;
if (interps[n]->virtual_mod!=XkbNoModifier)
new_vmodmask|= (1<<interps[n]->virtual_mod);
}
else effMods= 0;
_XkbSetActionKeyMods(xkb,&pActs[n],effMods);
}
else pActs[n].type= XkbSA_NoAction;
}
if (((explicit&XkbExplicitVModMapMask)==0)&&
(xkb->server->vmodmap[key]!=new_vmodmask)) {
changed|= XkbVirtualModMapMask;
xkb->server->vmodmap[key]= new_vmodmask;
}
if (interps[0]) {
if ((interps[0]->flags&XkbSI_LockingKey)&&
((explicit&XkbExplicitBehaviorMask)==0)) {
xkb->server->behaviors[key].type= XkbKB_Lock;
changed|= XkbKeyBehaviorsMask;
}
if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
CARD8 old;
old= xkb->ctrls->per_key_repeat[key/8];
if (interps[0]->flags&XkbSI_AutoRepeat)
xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8));
if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
}
}
}
if ((!found)||(interps[0]==NULL)) {
if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
CARD8 old;
old= xkb->ctrls->per_key_repeat[key/8];
#ifdef RETURN_SHOULD_REPEAT
if (*XkbKeySymsPtr(xkb,key) != XK_Return)
#endif
xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
}
if (((explicit&XkbExplicitBehaviorMask)==0)&&
(xkb->server->behaviors[key].type==XkbKB_Lock)) {
xkb->server->behaviors[key].type= XkbKB_Default;
changed|= XkbKeyBehaviorsMask;
}
}
if (changes) {
XkbMapChangesPtr mc;
mc= &changes->map;
tmp= (changed&mc->changed);
if (tmp&XkbKeyActionsMask)
_XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key);
else if (changed&XkbKeyActionsMask) {
mc->changed|= XkbKeyActionsMask;
mc->first_key_act= key;
mc->num_key_acts= 1;
}
if (tmp&XkbKeyBehaviorsMask) {
_XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors,
key);
}
else if (changed&XkbKeyBehaviorsMask) {
mc->changed|= XkbKeyBehaviorsMask;
mc->first_key_behavior= key;
mc->num_key_behaviors= 1;
}
if (tmp&XkbVirtualModMapMask)
_XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key);
else if (changed&XkbVirtualModMapMask) {
mc->changed|= XkbVirtualModMapMask;
mc->first_vmodmap_key= key;
mc->num_vmodmap_keys= 1;
}
mc->changed|= changed;
}
if (interps!=ibuf)
_XkbFree(interps);
return True;
}
Bool
XkbUpdateMapFromCore( XkbDescPtr xkb,
KeyCode first_key,
int num_keys,
int map_width,
KeySym * core_keysyms,
XkbChangesPtr changes)
{
register int key,last_key;
KeySym * syms;
syms= &core_keysyms[(first_key-xkb->min_key_code)*map_width];
if (changes) {
if (changes->map.changed&XkbKeySymsMask) {
_XkbAddKeyChange(&changes->map.first_key_sym,
&changes->map.num_key_syms,first_key);
if (num_keys>1) {
_XkbAddKeyChange(&changes->map.first_key_sym,
&changes->map.num_key_syms,
first_key+num_keys-1);
}
}
else {
changes->map.changed|= XkbKeySymsMask;
changes->map.first_key_sym= first_key;
changes->map.num_key_syms= num_keys;
}
}
last_key= first_key+num_keys-1;
for (key=first_key;key<=last_key;key++,syms+= map_width) {
XkbMapChangesPtr mc;
unsigned explicit;
KeySym tsyms[XkbMaxSymsPerKey];
int types[XkbNumKbdGroups];
int nG;
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,map_width,syms,explicit,types,tsyms);
if (changes)
mc= &changes->map;
else mc= NULL;
XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
XkbApplyCompatMapToKey(xkb,key,changes);
}
if ((xkb->server->vmods!=NULL)&&(xkb->map->modmap!=NULL)&&(changes)&&
(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 && (changes->map.changed&XkbVirtualModsMask))
XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
return True;
}
Status
XkbChangeTypesOfKey( XkbDescPtr xkb,
int key,
int nGroups,
unsigned groups,
int * newTypesIn,
XkbMapChangesPtr changes)
{
XkbKeyTypePtr pOldType,pNewType;
register int i;
int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
(!xkb->map->types)||((groups&XkbAllGroupsMask)==0)||
(nGroups>XkbNumKbdGroups)) {
return BadMatch;
}
if (nGroups==0) {
for (i=0;i<XkbNumKbdGroups;i++) {
xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex;
}
i= xkb->map->key_sym_map[key].group_info;
i= XkbSetNumGroups(i,0);
xkb->map->key_sym_map[key].group_info= i;
XkbResizeKeySyms(xkb,key,0);
return Success;
}
nOldGroups= XkbKeyNumGroups(xkb,key);
oldWidth= XkbKeyGroupsWidth(xkb,key);
for (width=i=0;i<nGroups;i++) {
if (groups&(1<<i))
newTypes[i]= newTypesIn[i];
else if (i<nOldGroups)
newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i);
else if (nOldGroups>0)
newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
else newTypes[i]= XkbTwoLevelIndex;
if (newTypes[i]>xkb->map->num_types)
return BadMatch;
pNewType= &xkb->map->types[newTypes[i]];
if (pNewType->num_levels>width)
width= pNewType->num_levels;
}
if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups))
xkb->ctrls->num_groups= nGroups;
if ((width!=oldWidth)||(nGroups!=nOldGroups)) {
KeySym oldSyms[XkbMaxSymsPerKey],*pSyms;
int nCopy;
if (nOldGroups==0) {
pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
if (pSyms!=NULL) {
i= xkb->map->key_sym_map[key].group_info;
i= XkbSetNumGroups(i,nGroups);
xkb->map->key_sym_map[key].group_info= i;
xkb->map->key_sym_map[key].width= width;
for (i=0;i<nGroups;i++) {
xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
}
return Success;
}
return BadAlloc;
}
pSyms= XkbKeySymsPtr(xkb,key);
memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
if (pSyms==NULL)
return BadAlloc;
bzero(pSyms,width*nGroups*sizeof(KeySym));
for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
pOldType= XkbKeyKeyType(xkb,key,i);
pNewType= &xkb->map->types[newTypes[i]];
if (pNewType->num_levels>pOldType->num_levels)
nCopy= pOldType->num_levels;
else nCopy= pNewType->num_levels;
memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym));
}
if (XkbKeyHasActions(xkb,key)) {
XkbAction oldActs[XkbMaxSymsPerKey],*pActs;
pActs= XkbKeyActionsPtr(xkb,key);
memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction));
pActs= XkbResizeKeyActions(xkb,key,width*nGroups);
if (pActs==NULL)
return BadAlloc;
bzero(pActs,width*nGroups*sizeof(XkbAction));
for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
pOldType= XkbKeyKeyType(xkb,key,i);
pNewType= &xkb->map->types[newTypes[i]];
if (pNewType->num_levels>pOldType->num_levels)
nCopy= pOldType->num_levels;
else nCopy= pNewType->num_levels;
memcpy(&pActs[i*width],&oldActs[i*oldWidth],
nCopy*sizeof(XkbAction));
}
}
i= xkb->map->key_sym_map[key].group_info;
i= XkbSetNumGroups(i,nGroups);
xkb->map->key_sym_map[key].group_info= i;
xkb->map->key_sym_map[key].width= width;
}
width= 0;
for (i=0;i<nGroups;i++) {
xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
if (xkb->map->types[newTypes[i]].num_levels>width)
width= xkb->map->types[newTypes[i]].num_levels;
}
xkb->map->key_sym_map[key].width= width;
if (changes!=NULL) {
if (changes->changed&XkbKeySymsMask) {
_XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms,
key);
}
else {
changes->changed|= XkbKeySymsMask;
changes->first_key_sym= key;
changes->num_key_syms= 1;
}
}
return Success;
}
/***====================================================================***/
Bool
XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn)
{
register int i,bit;
register unsigned mask;
if (xkb==NULL)
return False;
if (virtual_mask==0) {
*mask_rtrn= 0;
return True;
}
if (xkb->server==NULL)
return False;
for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
if (virtual_mask&bit)
mask|= xkb->server->vmods[i];
}
*mask_rtrn= mask;
return True;
}
/***====================================================================***/
Bool
XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed)
{
unsigned int tmp;
switch (act->type) {
case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) {
XkbVirtualModsToReal(xkb,tmp,&tmp);
act->mods.mask= act->mods.real_mods;
act->mods.mask|= tmp;
return True;
}
break;
case XkbSA_ISOLock:
if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) {
XkbVirtualModsToReal(xkb,tmp,&tmp);
act->iso.mask= act->iso.real_mods;
act->iso.mask|= tmp;
return True;
}
break;
}
return False;
}
void
XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb,
XkbKeyTypePtr type,
unsigned int changed,
XkbChangesPtr changes)
{
register unsigned int i;
unsigned int mask = 0;
XkbVirtualModsToReal(xkb,type->mods.vmods,&mask);
type->mods.mask= type->mods.real_mods|mask;
if ((type->map_count>0)&&(type->mods.vmods!=0)) {
XkbKTMapEntryPtr entry;
for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
if (entry->mods.vmods!=0) {
XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask);
entry->mods.mask=entry->mods.real_mods|mask;
/* entry is active if vmods are bound*/
entry->active= (mask!=0);
}
else entry->active= 1;
}
}
if (changes) {
int type_ndx;
type_ndx= type-xkb->map->types;
if ((type_ndx<0)||(type_ndx>xkb->map->num_types))
return;
if (changes->map.changed&XkbKeyTypesMask) {
int last;
last= changes->map.first_type+changes->map.num_types-1;
if (type_ndx<changes->map.first_type) {
changes->map.first_type= type_ndx;
changes->map.num_types= (last-type_ndx)+1;
}
else if (type_ndx>last) {
changes->map.num_types= (type_ndx-changes->map.first_type)+1;
}
}
else {
changes->map.changed|= XkbKeyTypesMask;
changes->map.first_type= type_ndx;
changes->map.num_types= 1;
}
}
return;
}
Bool
XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes)
{
register int i;
unsigned int checkState = 0;
if ((!xkb) || (!xkb->map) || (changed==0))
return False;
for (i=0;i<xkb->map->num_types;i++) {
if (xkb->map->types[i].mods.vmods & changed)
XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes);
}
if (changed&xkb->ctrls->internal.vmods) {
unsigned int newMask = 0;
XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask);
newMask|= xkb->ctrls->internal.real_mods;
if (xkb->ctrls->internal.mask!=newMask) {
xkb->ctrls->internal.mask= newMask;
if (changes) {
changes->ctrls.changed_ctrls|= XkbInternalModsMask;
checkState= True;
}
}
}
if (changed&xkb->ctrls->ignore_lock.vmods) {
unsigned int newMask = 0;
XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask);
newMask|= xkb->ctrls->ignore_lock.real_mods;
if (xkb->ctrls->ignore_lock.mask!=newMask) {
xkb->ctrls->ignore_lock.mask= newMask;
if (changes) {
changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask;
checkState= True;
}
}
}
if (xkb->indicators!=NULL) {
XkbIndicatorMapPtr map;
map= &xkb->indicators->maps[0];
for (i=0;i<XkbNumIndicators;i++,map++) {
if (map->mods.vmods&changed) {
unsigned int newMask = 0;
XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask);
newMask|= map->mods.real_mods;
if (newMask!=map->mods.mask) {
map->mods.mask= newMask;
if (changes) {
changes->indicators.map_changes|= (1<<i);
checkState= True;
}
}
}
}
}
if (xkb->compat!=NULL) {
XkbCompatMapPtr compat;
compat= xkb->compat;
for (i=0;i<XkbNumKbdGroups;i++) {
unsigned int newMask = 0;
XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask);
newMask|= compat->groups[i].real_mods;
if (compat->groups[i].mask!=newMask) {
compat->groups[i].mask= newMask;
if (changes) {
changes->compat.changed_groups|= (1<<i);
checkState= True;
}
}
}
}
if (xkb->map && xkb->server) {
int highChange = 0, lowChange = -1;
for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
if (XkbKeyHasActions(xkb,i)) {
register XkbAction *pAct;
register int n;
pAct= XkbKeyActionsPtr(xkb,i);
for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) {
if ((pAct->type!=XkbSA_NoAction)&&
XkbUpdateActionVirtualMods(xkb,pAct,changed)) {
if (lowChange<0)
lowChange= i;
highChange= i;
}
}
}
}
if (changes && (lowChange>0)) { /* something changed */
if (changes->map.changed&XkbKeyActionsMask) {
int last;
if (changes->map.first_key_act<lowChange)
lowChange= changes->map.first_key_act;
last= changes->map.first_key_act+changes->map.num_key_acts-1;
if (last>highChange)
highChange= last;
}
changes->map.changed|= XkbKeyActionsMask;
changes->map.first_key_act= lowChange;
changes->map.num_key_acts= (highChange-lowChange)+1;
}
}
return checkState;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment