debian/patches/130_fedora_fix_procxkbsetxyz_to_work_on_all.patch   | 2245 
++++++++++
 debian/patches/136_fedora_force_switchcorekeyboard_for_evdev.patch |   69 
 2 files changed, 2314 insertions(+)

New commits:
commit 02def36766818699103799a478a44a3d0e17eac0
Author: Timo Aaltonen <[EMAIL PROTECTED]>
Date:   Wed Aug 6 13:56:10 2008 +0300

    actually add the patches.

diff --git a/debian/patches/130_fedora_fix_procxkbsetxyz_to_work_on_all.patch 
b/debian/patches/130_fedora_fix_procxkbsetxyz_to_work_on_all.patch
new file mode 100644
index 0000000..13e197a
--- /dev/null
+++ b/debian/patches/130_fedora_fix_procxkbsetxyz_to_work_on_all.patch
@@ -0,0 +1,2245 @@
+From 6d1201b05ed61aec508d5d9f88e3a2d33be39849 Mon Sep 17 00:00:00 2001
+From: Peter Hutterer <[EMAIL PROTECTED]>
+Date: Thu, 31 Jul 2008 16:03:21 +0930
+Subject: [PATCH] xkb: fix up ProcXkbSetXYZ to work on all core devices.
+
+Simple principle: if the client requests an xkb change on the core keyboard,
+apply the same change to all core-sending keyboard devices. This way, if you
+change the layout on the VCK, you get the same layout on all devices.
+
+That's the theory anyway, the implementation makes you want to gauge your eyes
+out.
+---
+ xkb/xkb.c | 1880 +++++++++++++++++++++++++++++++++++++++----------------------
+ 1 files changed, 1210 insertions(+), 670 deletions(-)
+
+diff --git a/xkb/xkb.c b/xkb/xkb.c
+index 07f57a7..cc2f77c 100644
+--- a/xkb/xkb.c
++++ b/xkb/xkb.c
+@@ -24,6 +24,31 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ 
+ ********************************************************/
+ 
++/* Copyright © 2008 Red Hat, Inc.
++
++Permission is hereby granted, free of charge, to any person obtaining a
++copy of this software and associated documentation files (the "Software"),
++to deal in the Software without restriction, including without limitation
++the rights to use, copy, modify, merge, publish, distribute, sublicense,
++and/or sell copies of the Software, and to permit persons to whom the
++Software is furnished to do so, subject to the following conditions:
++
++The above copyright notice and this permission notice (including the next
++paragraph) shall be included in all copies or substantial portions of the
++Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
++THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++DEALINGS IN THE SOFTWARE.
++
++Authors: Peter Hutterer
++
++*/
++
+ #ifdef HAVE_DIX_CONFIG_H
+ #include <dix-config.h>
+ #endif
+@@ -348,17 +373,119 @@ ProcXkbSelectEvents(ClientPtr client)
+ }
+ 
+ /***====================================================================***/
++/**
++ * Ring a bell on the given device for the given client.
++ */
++static int
++_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin,
++         int bellClass, int bellID, int pitch, int duration,
++         int percent, int forceSound, int eventOnly, Atom name)
++{
++    int         base;
++    pointer     ctrl;
++    int         oldPitch, oldDuration;
++    int         newPercent;
++
++    if (bellClass == KbdFeedbackClass) {
++        KbdFeedbackPtr        k;
++        if (bellID==XkbDfltXIId)
++            k= dev->kbdfeed;
++        else {
++            for (k=dev->kbdfeed; k; k=k->next) {
++                if (k->ctrl.id == bellID)
++                    break;
++            }
++        }
++        if (!k) {
++            client->errorValue = _XkbErrCode2(0x5,bellID);
++            return BadValue;
++        }
++        base = k->ctrl.bell;
++        ctrl = (pointer) &(k->ctrl);
++        oldPitch= k->ctrl.bell_pitch;
++        oldDuration= k->ctrl.bell_duration;
++        if (pitch!=0) {
++            if (pitch==-1)
++                k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch;
++            else k->ctrl.bell_pitch= pitch;
++        }
++        if (duration!=0) {
++            if (duration==-1)
++                k->ctrl.bell_duration= defaultKeyboardControl.bell_duration;
++            else k->ctrl.bell_duration= duration;
++        }
++    }
++    else if (bellClass == BellFeedbackClass) {
++        BellFeedbackPtr       b;
++        if (bellID==XkbDfltXIId)
++            b= dev->bell;
++        else {
++            for (b=dev->bell; b; b=b->next) {
++                if (b->ctrl.id == bellID)
++                    break;
++            }
++        }
++        if (!b) {
++            client->errorValue = _XkbErrCode2(0x6,bellID);
++            return BadValue;
++        }
++        base = b->ctrl.percent;
++        ctrl = (pointer) &(b->ctrl);
++        oldPitch= b->ctrl.pitch;
++        oldDuration= b->ctrl.duration;
++        if (pitch!=0) {
++            if (pitch==-1)
++                b->ctrl.pitch= defaultKeyboardControl.bell_pitch;
++            else b->ctrl.pitch= pitch;
++        }
++        if (duration!=0) {
++            if (duration==-1)
++                b->ctrl.duration= defaultKeyboardControl.bell_duration;
++            else b->ctrl.duration= duration;
++        }
++    }
++    else {
++        client->errorValue = _XkbErrCode2(0x7, bellClass);;
++        return BadValue;
++    }
++
++    newPercent = (base * percent)/100;
++    if (percent < 0)
++         newPercent = base + newPercent;
++    else newPercent = base - newPercent + percent;
++
++    XkbHandleBell(forceSound, eventOnly,
++                  dev, newPercent, ctrl, bellClass,
++                  name, pWin, client);
++    if ((pitch!=0)||(duration!=0)) {
++        if (bellClass == KbdFeedbackClass) {
++            KbdFeedbackPtr      k;
++            k= (KbdFeedbackPtr)ctrl;
++            if (pitch!=0)
++                k->ctrl.bell_pitch= oldPitch;
++            if (duration!=0)
++                k->ctrl.bell_duration= oldDuration;
++        }
++        else {
++            BellFeedbackPtr     b;
++            b= (BellFeedbackPtr)ctrl;
++            if (pitch!=0)
++                b->ctrl.pitch= oldPitch;
++            if (duration!=0)
++                b->ctrl.duration= oldDuration;
++        }
++    }
++
++    return Success;
++}
+ 
+-/* FIXME: Needs to ding on all core-sending devices. */
+ int
+ ProcXkbBell(ClientPtr client)
+ {
+     REQUEST(xkbBellReq);
+     DeviceIntPtr dev;
+     WindowPtr  pWin;
+-    int rc, base;
+-    int newPercent,oldPitch,oldDuration;
+-    pointer ctrl;
++    int rc;
+ 
+     REQUEST_SIZE_MATCH(xkbBellReq);
+ 
+@@ -368,6 +495,7 @@ ProcXkbBell(ClientPtr client)
+     CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess);
+     CHK_ATOM_OR_NONE(stuff->name);
+ 
++    /* device-independent checks request for sane values */
+     if ((stuff->forceSound)&&(stuff->eventOnly)) {
+       client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly);
+       return BadMatch;
+@@ -390,68 +518,7 @@ ProcXkbBell(ClientPtr client)
+            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) {
+       rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+       if (rc != Success) {
+@@ -461,32 +528,39 @@ ProcXkbBell(ClientPtr client)
+     }
+     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;
+-      }
++    /* Client wants to ring a bell on the core keyboard?
++       Ring the bell on the core keyboard (which does nothing, but if that
++       fails the client is screwed anyway), and then on all extension devices.
++       Fail if the core keyboard fails but not the extension devices.  this
++       may cause some keyboards to ding and others to stay silent. Fix
++       your client to use explicit keyboards to avoid this.
++
++       dev is the device the client requested.
++     */
++    rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID,
++                  stuff->pitch, stuff->duration, stuff->percent,
++                  stuff->forceSound, stuff->eventOnly, stuff->name);
++
++    if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) ||
++                            (stuff->deviceSpec == XkbUseCorePtr)))
++    {
++        DeviceIntPtr other;
++        for (other = inputInfo.devices; other; other = other->next)
++        {
++            if ((other != dev) && other->key && other->coreEvents)
++            {
++                rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 
DixBellAccess);
++                if (rc == Success)
++                    _XkbBell(client, other, pWin, stuff->bellClass,
++                             stuff->bellID, stuff->pitch, stuff->duration,
++                             stuff->percent, stuff->forceSound,
++                             stuff->eventOnly, stuff->name);
++            }
++        }
++        rc = Success; /* reset to success, that's what we got for the VCK */
+     }
+-    return Success;
++
++    return rc;
+ }
+ 
+ /***====================================================================***/
+@@ -2283,158 +2357,165 @@ XkbServerMapPtr              srv = 
xkbi->desc->server;
+     return (char *)wire;
+ }
+ 
+-/* FIXME: Needs to set map on all core-sending devices. */
+-int
+-ProcXkbSetMap(ClientPtr client)
++/**
++ * Check if the given request can be applied to the given device but don't
++ * actually do anything..
++ */
++static int
++_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char* 
values)
+ {
+-    DeviceIntPtr      dev;
+-    XkbSrvInfoPtr     xkbi;
+-    XkbDescPtr                xkb;
+-    XkbChangesRec     change;
+-    XkbEventCauseRec  cause;
+-    int                       nTypes = 0,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, client, DixManageAccess);
+-    CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask);
++    XkbSrvInfoPtr       xkbi;
++    XkbDescPtr          xkb;
++    int                 error;
++    int                 nTypes = 0, nActions;
++    CARD8               mapWidths[XkbMaxLegalKeyCode + 1];
++    CARD16              symsPerKey[XkbMaxLegalKeyCode + 1];
+ 
+-    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 ((xkb->min_key_code != req->minKeyCode)||
++        (xkb->max_key_code != req->maxKeyCode)) {
+       if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */
+-          stuff->minKeyCode= xkb->min_key_code;
+-          stuff->maxKeyCode= xkb->max_key_code;
++          req->minKeyCode= xkb->min_key_code;
++          req->maxKeyCode= xkb->max_key_code;
+       }
+       else {
+-          if (!XkbIsLegalKeycode(stuff->minKeyCode)) {
+-              client->errorValue= _XkbErrCode3(2,stuff->minKeyCode,
+-                                                      stuff->maxKeyCode);
++          if (!XkbIsLegalKeycode(req->minKeyCode)) {
++              client->errorValue = _XkbErrCode3(2, req->minKeyCode, 
req->maxKeyCode);
+               return BadValue;
+           }
+-          if (stuff->minKeyCode>stuff->maxKeyCode) {
+-              client->errorValue= _XkbErrCode3(3,stuff->minKeyCode,
+-                                                      stuff->maxKeyCode);
++          if (req->minKeyCode > req->maxKeyCode) {
++              client->errorValue = _XkbErrCode3(3, req->minKeyCode, 
req->maxKeyCode);
+               return BadMatch;
+           }
+       }
+     }
+ 
+-    tmp = (char *)&stuff[1];
+-    if ((stuff->present&XkbKeyTypesMask)&&
+-      (!CheckKeyTypes(client,xkb,stuff,(xkbKeyTypeWireDesc **)&tmp,
++    if ((req->present & XkbKeyTypesMask) &&
++      (!CheckKeyTypes(client,xkb,req,(xkbKeyTypeWireDesc **)&values,
+                                               &nTypes,mapWidths))) {
+       client->errorValue = nTypes;
+       return BadValue;
+     }
+-    if ((stuff->present&XkbKeySymsMask)&&
+-      (!CheckKeySyms(client,xkb,stuff,nTypes,mapWidths,symsPerKey,
+-                                      (xkbSymMapWireDesc **)&tmp,&error))) {
++    if ((req->present & XkbKeySymsMask) &&
++      (!CheckKeySyms(client,xkb,req,nTypes,mapWidths,symsPerKey,
++                                      (xkbSymMapWireDesc **)&values,&error))) 
{
+       client->errorValue = error;
+       return BadValue;
+     }
+ 
+-    if ((stuff->present&XkbKeyActionsMask)&&
+-      (!CheckKeyActions(xkb,stuff,nTypes,mapWidths,symsPerKey,
+-                                              (CARD8 **)&tmp,&nActions))) {
++    if ((req->present & XkbKeyActionsMask) &&
++      (!CheckKeyActions(xkb,req,nTypes,mapWidths,symsPerKey,
++                                              (CARD8 **)&values,&nActions))) {
+       client->errorValue = nActions;
+       return BadValue;
+     }
+ 
+-    if ((stuff->present&XkbKeyBehaviorsMask)&&
+-      (!CheckKeyBehaviors(xkb,stuff,(xkbBehaviorWireDesc**)&tmp,&error))) {
++    if ((req->present & XkbKeyBehaviorsMask) &&
++      (!CheckKeyBehaviors(xkb,req,(xkbBehaviorWireDesc**)&values,&error))) {
+       client->errorValue = error;
+       return BadValue;
+     }
+ 
+-    if ((stuff->present&XkbVirtualModsMask)&&
+-      (!CheckVirtualMods(xkb,stuff,(CARD8 **)&tmp,&error))) {
++    if ((req->present & XkbVirtualModsMask) &&
++      (!CheckVirtualMods(xkb,req,(CARD8 **)&values,&error))) {
+       client->errorValue= error;
+       return BadValue;
+     }
+-    if ((stuff->present&XkbExplicitComponentsMask)&&
+-      (!CheckKeyExplicit(xkb,stuff,(CARD8 **)&tmp,&error))) {
++    if ((req->present&XkbExplicitComponentsMask) &&
++      (!CheckKeyExplicit(xkb,req,(CARD8 **)&values,&error))) {
+       client->errorValue= error;
+       return BadValue;
+     }
+-    if ((stuff->present&XkbModifierMapMask)&&
+-      (!CheckModifierMap(xkb,stuff,(CARD8 **)&tmp,&error))) {
++    if ((req->present&XkbModifierMapMask) &&
++      (!CheckModifierMap(xkb,req,(CARD8 **)&values,&error))) {
+       client->errorValue= error;
+       return BadValue;
+     }
+-    if ((stuff->present&XkbVirtualModMapMask)&&
+-      (!CheckVirtualModMap(xkb,stuff,(xkbVModMapWireDesc **)&tmp,&error))) {
++    if ((req->present&XkbVirtualModMapMask) &&
++      (!CheckVirtualModMap(xkb,req,(xkbVModMapWireDesc **)&values,&error))) {
+       client->errorValue= error;
+       return BadValue;
+     }
+-    if (((tmp-((char *)stuff))/4)!=stuff->length) {
++
++    if (((values-((char *)req))/4)!= req->length) {
+       ErrorF("Internal error! Bad length in XkbSetMap (after check)\n");
+-      client->errorValue = tmp-((char *)&stuff[1]);
++      client->errorValue = values-((char *)&req[1]);
+       return BadLength;
+     }
+-    bzero(&change,sizeof(change));
+-    sentNKN= False;
+-    if ((xkb->min_key_code!=stuff->minKeyCode)||
+-                              (xkb->max_key_code!=stuff->maxKeyCode)) {
++
++    return Success;
++}
++
++/**
++ * Apply the given request on the given device.
++ */
++static int
++_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char 
*values)
++{
++    XkbEventCauseRec  cause;
++    XkbChangesRec     change;
++    Bool              sentNKN;
++    XkbSrvInfoPtr       xkbi;
++    XkbDescPtr          xkb;
++
++    xkbi= dev->key->xkbInfo;
++    xkb = xkbi->desc;
++
++    XkbSetCauseXkbReq(&cause,X_kbSetMap,client);
++    bzero(&change, sizeof(change));
++    sentNKN = False;
++    if ((xkb->min_key_code!=req->minKeyCode)||
++        (xkb->max_key_code!=req->maxKeyCode)) {
+       Status                  status;
+       xkbNewKeyboardNotify    nkn;
+-      nkn.deviceID= nkn.oldDeviceID= dev->id;
+-      nkn.oldMinKeyCode= xkb->min_key_code;
+-      nkn.oldMaxKeyCode= xkb->max_key_code;
+-      status= XkbChangeKeycodeRange(xkb,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;
++      nkn.deviceID = nkn.oldDeviceID = dev->id;
++      nkn.oldMinKeyCode = xkb->min_key_code;
++      nkn.oldMaxKeyCode = xkb->max_key_code;
++      status= XkbChangeKeycodeRange(xkb, req->minKeyCode,
++                                      req->maxKeyCode, &change);
++      if (status != Success)
++          return status; /* oh-oh. what about the other keyboards? */
++      nkn.minKeyCode = xkb->min_key_code;
++      nkn.maxKeyCode = xkb->max_key_code;
++      nkn.requestMajor = XkbReqCode;
++      nkn.requestMinor = X_kbSetMap;
++      nkn.changed = XkbNKN_KeycodesMask;
+       XkbSendNewKeyboardNotify(dev,&nkn);
+-      sentNKN= True;
+-    }
+-    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) {
++      sentNKN = True;
++    }
++
++    if (req->present&XkbKeyTypesMask) {
++      values = SetKeyTypes(xkb,req,(xkbKeyTypeWireDesc *)values,&change);
++      if (!values)    goto allocFailure;
++    }
++    if (req->present&XkbKeySymsMask) {
++      values = SetKeySyms(client,xkb,req,(xkbSymMapWireDesc 
*)values,&change,dev);
++      if (!values)    goto allocFailure;
++    }
++    if (req->present&XkbKeyActionsMask) {
++      values = SetKeyActions(xkb,req,(CARD8 *)values,&change);
++      if (!values)    goto allocFailure;
++    }
++    if (req->present&XkbKeyBehaviorsMask) {
++      values= SetKeyBehaviors(xkbi,req,(xkbBehaviorWireDesc *)values,&change);
++      if (!values)    goto allocFailure;
++    }
++    if (req->present&XkbVirtualModsMask)
++      values= SetVirtualMods(xkbi,req,(CARD8 *)values,&change);
++    if (req->present&XkbExplicitComponentsMask)
++      values= SetKeyExplicit(xkbi,req,(CARD8 *)values,&change);
++    if (req->present&XkbModifierMapMask)
++      values= SetModifierMap(xkbi,req,(CARD8 *)values,&change);
++    if (req->present&XkbVirtualModMapMask)
++      values= SetVirtualModMap(xkbi,req,(xkbVModMapWireDesc *)values,&change);
++    if (((values-((char *)req))/4)!=req->length) {
+       ErrorF("Internal error! Bad length in XkbSetMap (after set)\n");
+-      client->errorValue = tmp-((char *)&stuff[1]);
++      client->errorValue = values-((char *)&req[1]);
+       return BadLength;
+     }
+-    if (stuff->flags&XkbSetMapRecomputeActions) {
++    if (req->flags&XkbSetMapRecomputeActions) {
+       KeyCode         first,last,firstMM,lastMM;
+       if (change.map.num_key_syms>0) {
+           first= change.map.first_key_sym;
+@@ -2467,11 +2548,82 @@ ProcXkbSetMap(ClientPtr client)
+       XkbSendNotification(dev,&change,&cause);
+ 
+     XkbUpdateCoreDescription(dev,False);
+-    return client->noClientException;
++    return Success;
+ allocFailure:
+     return BadAlloc;
+ }
+ 
++
++int
++ProcXkbSetMap(ClientPtr client)
++{
++    DeviceIntPtr      dev;
++    char *            tmp;
++    int                 rc;
++
++    REQUEST(xkbSetMapReq);
++    REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
++
++    if (!(client->xkbClientFlags&_XkbClientInitialized))
++      return BadAccess;
++
++    CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
++    CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask);
++
++    tmp = (char *)&stuff[1];
++
++    /* Check if we can to the SetMap on the requested device. If this
++       succeeds, do the same thing for all extension devices (if needed).
++       If any of them fails, fail.  */
++    rc = _XkbSetMapChecks(client, dev, stuff, tmp);
++
++    if (rc != Success)
++        return rc;
++
++    if (stuff->deviceSpec == XkbUseCoreKbd)
++    {
++        DeviceIntPtr other;
++        for (other = inputInfo.devices; other; other = other->next)
++        {
++            if ((other != dev) && other->key && other->coreEvents)
++            {
++                rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 
DixManageAccess);
++                if (rc == Success)
++                {
++                    rc = _XkbSetMapChecks(client, other, stuff, tmp);
++                    if (rc != Success)
++                        return rc;
++                }
++            }
++        }
++    }
++
++    /* We know now that we will succed with the SetMap. In theory anyway. */
++    rc = _XkbSetMap(client, dev, stuff, tmp);
++    if (rc != Success)
++        return rc;
++
++    if (stuff->deviceSpec == XkbUseCoreKbd)
++    {
++        DeviceIntPtr other;
++        for (other = inputInfo.devices; other; other = other->next)
++        {
++            if ((other != dev) && other->key && other->coreEvents)
++            {
++                rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 
DixManageAccess);
++                if (rc == Success)
++                    _XkbSetMap(client, other, stuff, tmp);
++                /* ignore rc. if the SetMap failed although the check above
++                   reported true there isn't much we can do. we still need to
++                   set all other devices, hoping that at least they stay in
++                   sync. */
++            }
++        }
++    }
++
++    return client->noClientException;
++}
++
+ /***====================================================================***/
+ 
+ static Status
+@@ -2600,57 +2752,58 @@ ProcXkbGetCompatMap(ClientPtr client)
+     return XkbSendCompatMap(client,compat,&rep);
+ }
+ 
+-/* FIXME: Needs to set compat map on all core-sending devices. */
+-int
+-ProcXkbSetCompatMap(ClientPtr client)
++/**
++ * Apply the given request on the given device.
++ * If dryRun is True, then value checks are performed, but the device isn't
++ * modified.
++ */
++static int
++_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
++                 xkbSetCompatMapReq *req, char* data, BOOL dryRun)
+ {
+-    DeviceIntPtr      dev;
+-    XkbSrvInfoPtr     xkbi;
+-    XkbDescPtr                xkb;
+-    XkbCompatMapPtr   compat;
+-    char      *       data;
+-    int                       nGroups;
+-    register unsigned i,bit;
++    XkbSrvInfoPtr       xkbi;
++    XkbDescPtr          xkb;
++    XkbCompatMapPtr     compat;
++    int                 nGroups;
++    unsigned            i,bit;
+ 
+-    REQUEST(xkbSetCompatMapReq);
+-    REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
+-
+-    if (!(client->xkbClientFlags&_XkbClientInitialized))
+-      return BadAccess;
+-
+-    CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+-
+-    data = (char *)&stuff[1];
+     xkbi = dev->key->xkbInfo;
+-    xkb= xkbi->desc;
+-    compat= xkb->compat;
+-    if ((stuff->nSI>0)||(stuff->truncateSI)) {
++    xkb = xkbi->desc;
++    compat = xkb->compat;
++
++    if ((req->nSI>0)||(req->truncateSI)) {
+       xkbSymInterpretWireDesc *wire;
+-      if (stuff->firstSI>compat->num_si) {
++      if (req->firstSI>compat->num_si) {
+           client->errorValue = _XkbErrCode2(0x02,compat->num_si);
+           return BadValue;
+       }
+       wire= (xkbSymInterpretWireDesc *)data;
+-      wire+= stuff->nSI;
++      wire+= req->nSI;
+       data = (char *)wire;
+     }
++
+     nGroups= 0;
+-    if (stuff->groups!=0) {
++    if (req->groups!=0) {
+       for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+-          if ( stuff->groups&bit )
++          if ( req->groups&bit )
+               nGroups++;
+       }
+     }
+     data+= nGroups*SIZEOF(xkbModsWireDesc);
+-    if (((data-((char *)stuff))/4)!=stuff->length) {
++    if (((data-((char *)req))/4)!=req->length) {
+       return BadLength;
+     }
+-    data = (char *)&stuff[1];
+-    if (stuff->nSI>0) {
++
++    /* Done all the checks we can do */
++    if (dryRun)
++        return Success;
++
++    data = (char *)&req[1];
++    if (req->nSI>0) {
+       xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
+       XkbSymInterpretPtr      sym;
+-      if ((unsigned)(stuff->firstSI+stuff->nSI)>compat->num_si) {
+-          compat->num_si= stuff->firstSI+stuff->nSI;
++      if ((unsigned)(req->firstSI+req->nSI)>compat->num_si) {
++          compat->num_si= req->firstSI+req->nSI;
+           compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret,
+                                                  compat->num_si,
+                                                  XkbSymInterpretRec);
+@@ -2659,13 +2812,13 @@ ProcXkbSetCompatMap(ClientPtr client)
+               return BadAlloc;
+           }
+       }
+-      else if (stuff->truncateSI) {
+-          compat->num_si = stuff->firstSI+stuff->nSI;
++      else if (req->truncateSI) {
++          compat->num_si = req->firstSI+req->nSI;
+       }
+-      sym = &compat->sym_interpret[stuff->firstSI];
+-      for (i=0;i<stuff->nSI;i++,wire++,sym++) {
++      sym = &compat->sym_interpret[req->firstSI];
++      for (i=0;i<req->nSI;i++,wire++,sym++) {
+           if (client->swapped) {
+-              register int n;
++              int n;
+               swapl(&wire->sym,n);
+           }
+           sym->sym= wire->sym;
+@@ -2674,21 +2827,21 @@ ProcXkbSetCompatMap(ClientPtr client)
+           sym->flags= wire->flags;
+           sym->virtual_mod= wire->virtualMod;
+           memcpy((char *)&sym->act,(char *)&wire->act,
+-                                              SIZEOF(xkbActionWireDesc));
++                   SIZEOF(xkbActionWireDesc));
+       }
+       data = (char *)wire;
+     }
+-    else if (stuff->truncateSI) {
+-      compat->num_si = stuff->firstSI;
++    else if (req->truncateSI) {
++      compat->num_si = req->firstSI;
+     }
+ 
+-    if (stuff->groups!=0) {
+-      register unsigned i,bit;
++    if (req->groups!=0) {
++      unsigned i, bit;
+       xkbModsWireDesc *wire = (xkbModsWireDesc *)data;
+-      for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+-          if (stuff->groups&bit) {
++      for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
++          if (req->groups & bit) {
+               if (client->swapped) {
+-                  register int n;
++                  int n;
+                   swaps(&wire->virtualMods,n);
+               }
+               compat->groups[i].mask= wire->realMods;
+@@ -2704,23 +2857,23 @@ ProcXkbSetCompatMap(ClientPtr client)
+           }
+       }
+     }
+-    i= XkbPaddedSize((data-((char *)stuff)));
+-    if ((i/4)!=stuff->length) {
+-      ErrorF("Internal length error on read in ProcXkbSetCompatMap\n");
++    i= XkbPaddedSize((data-((char *)req)));
++    if ((i/4)!=req->length) {
++      ErrorF("Internal length error on read in _XkbSetCompatMap\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.changedGroups = req->groups;
++      ev.firstSI = req->firstSI;
++      ev.nSI = req->nSI;
+       ev.nTotalSI = compat->num_si;
+       XkbSendCompatMapNotify(dev,&ev);
+     }
+ 
+-    if (stuff->recomputeActions) {
++    if (req->recomputeActions) {
+       XkbChangesRec           change;
+       unsigned                check;
+       XkbEventCauseRec        cause;
+@@ -2734,6 +2887,71 @@ ProcXkbSetCompatMap(ClientPtr client)
+       XkbUpdateCoreDescription(dev,False);
+       XkbSendNotification(dev,&change,&cause);
+     }
++    return Success;
++}
++
++int
++ProcXkbSetCompatMap(ClientPtr client)
++{
++    DeviceIntPtr        dev;
++    char                *data;
++    int                 rc;
++
++    REQUEST(xkbSetCompatMapReq);
++    REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
++
++    if (!(client->xkbClientFlags&_XkbClientInitialized))
++      return BadAccess;
++
++    CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
++
++    data = (char *)&stuff[1];
++
++    /* check first using a dry-run */
++    rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE);
++    if (rc != Success)
++        return rc;
++    if (stuff->deviceSpec == XkbUseCoreKbd)
++    {
++        DeviceIntPtr other;
++        for (other = inputInfo.devices; other; other = other->next)
++        {
++            if ((other != dev) && other->key && other->coreEvents)
++            {
++                rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 
DixManageAccess);
++                if (rc == Success)
++                {
++                    /* dry-run */
++                    rc = _XkbSetCompatMap(client, other, stuff, data, TRUE);
++                    if (rc != Success)
++                        return rc;
++                }
++            }
++        }
++    }
++
++    /* Yay, the dry-runs succeed. Let's apply */
++    rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE);
++    if (rc != Success)
++        return rc;
++    if (stuff->deviceSpec == XkbUseCoreKbd)
++    {
++        DeviceIntPtr other;
++        for (other = inputInfo.devices; other; other = other->next)
++        {
++            if ((other != dev) && other->key && other->coreEvents)
++            {
++                rc = XaceHook(XACE_DEVICE_ACCESS, client, other, 
DixManageAccess);
++                if (rc == Success)
++                {
++                    rc = _XkbSetCompatMap(client, other, stuff, data, TRUE);
++                    if (rc != Success)
++                        return rc;
++                }
++            }
++        }
++    }
++
+     return client->noClientException;
+ }
+ 
+@@ -2878,17 +3096,59 @@ XkbIndicatorPtr                leds;
+     return XkbSendIndicatorMap(client,leds,&rep);
+ }
+ 
+-/* FIXME: Needs to set indicator map on all core-sending devices. */
++/**
++ * Apply the given map to the given device. Which specifies which components
++ * to apply.
++ */
++static int
++_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev,
++                    int which, xkbIndicatorMapWireDesc *desc)
++{
++    XkbSrvInfoPtr       xkbi;
++    XkbSrvLedInfoPtr    sli;
++    XkbEventCauseRec    cause;
++    int                 i, bit;
++
++    xkbi = dev->key->xkbInfo;
++
++    sli= XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId,
++                                              XkbXI_IndicatorMapsMask);
++    if (!sli)
++      return BadAlloc;
++
++    for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
++      if (which & bit) {
++          sli->maps[i].flags = desc->flags;
++          sli->maps[i].which_groups = desc->whichGroups;
++          sli->maps[i].groups = desc->groups;
++          sli->maps[i].which_mods = desc->whichMods;
++          sli->maps[i].mods.mask = desc->mods;
++          sli->maps[i].mods.real_mods = desc->mods;
++          sli->maps[i].mods.vmods= desc->virtualMods;
++          sli->maps[i].ctrls = desc->ctrls;
++          if (desc->virtualMods!=0) {
++              unsigned tmp;
++              tmp= XkbMaskForVMask(xkbi->desc,desc->virtualMods);
++              sli->maps[i].mods.mask= desc->mods|tmp;
++          }
++          desc++;
++      }
++    }
++
++    XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client);
++    XkbApplyLedMapChanges(dev,sli,which,NULL,NULL,&cause);
++
++    return Success;
++}
++
+ int
+ ProcXkbSetIndicatorMap(ClientPtr client)
+ {
+-    register int      i,bit;
+-    int                       nIndicators;
+-    DeviceIntPtr      dev;
+-    XkbSrvInfoPtr     xkbi;
+-    xkbIndicatorMapWireDesc *from;
+-    XkbSrvLedInfoPtr  sli;
+-    XkbEventCauseRec  cause;
++    int                 i, bit;
++    int                 nIndicators;
++    DeviceIntPtr        dev;
++    xkbIndicatorMapWireDesc     *from;
++    int                 rc;
+ 
+     REQUEST(xkbSetIndicatorMapReq);
+     REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
+@@ -2898,8 +3158,6 @@ ProcXkbSetIndicatorMap(ClientPtr client)
+ 
+     CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
+ 


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to