Comment 15 for bug 311254

Revision history for this message
In , Pcpa (pcpa) wrote :

(In reply to comment #2)
> Created an attachment (id=21994) [details]
> 0001-Xi-Force-a-CopyKeyClass-on-the-VCK-when-posting-a-k.patch
>
> Something like this should fix the crash. I think my device at home is such a
> combo that posts some event through the mouse so I might be able to reproduce
> this tonight.

  As I told you in irc it corrects the crash, but it will not post
the events. To trigger the problem, it appears to be required to
have a "main" keyboard without multimedia keys, and then attach
the new keyboard with multimedia keys.

  Before using this patch I started with a patch like (don't have
access to both computers now):
-%<-
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 083bb2f..d245382 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -192,7 +192,7 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
     static DeviceIntPtr lastMapNotifyDevice = NULL;
     KeyClassPtr mk, dk; /* master, device */
     BOOL sendNotify = FALSE;
- int i;
+ int i, size;

     if (device == master)
         return;
@@ -202,17 +202,22 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)

     if (device != dixLookupPrivate(&master->devPrivates,
                                    CoreDevicePrivateKey)) {
- memcpy(mk->modifierMap, dk->modifierMap, MAP_LENGTH);
-
- if (dk->maxKeysPerModifier)
- {
- mk->modifierKeyMap = xrealloc(mk->modifierKeyMap,
- 8 * dk->maxKeysPerModifier);
+ if (dk->maxKeysPerModifier) {
+ if (mk == NULL) {
+ mk = master->key = xmalloc(sizeof(KeyClassRec));
+ if (!mk)
+ FatalError("[Xi] no memory for class shift.\n");
+ memcpy(mk, dk, sizeof(KeyClassRec));
+ mk->modifierMap = NULL;
+ }
+ size = 8 * dk->maxKeysPerModifier;
+ if (size < MAP_LENGTH)
+ size = MAP_LENGTH;
+ mk->modifierKeyMap = xrealloc(mk->modifierKeyMap, size);
             if (!mk->modifierKeyMap)
                 FatalError("[Xi] no memory for class shift.\n");
- memcpy(mk->modifierKeyMap, dk->modifierKeyMap,
- (8 * dk->maxKeysPerModifier));
- } else
+ memcpy(mk->modifierMap, dk->modifierMap, size);
+ } else if (mk)
         {
             xfree(mk->modifierKeyMap);
             mk->modifierKeyMap = NULL;
-%<-
  But it would fail a few lines below in:
            if (!XkbCopyKeymap(dk->xkbInfo->desc, mk->xkbInfo->desc, True))
                FatalError("Couldn't pivot keymap from device to core!\n");

  But I did not try a merge of the above patch with yours, neither
the remaining of the code I wrote in an attempt to "port" git master
behavior to origin/server-1.6-branch. Example, I converted
static void
ChangeMasterDeviceClasses(DeviceIntPtr device,
                          deviceClassesChangedEvent *dcce)
{...}
to something like:
static void
ChangeMasterDeviceClasses(DeviceIntPtr device)
{
    DeviceIntPtr master = device->u.master;

    if (device->isMaster)
        return;

    if (!master) /* if device was set floating between SIGIO and now */
        return;

    master->public.devicePrivate = device->public.devicePrivate;

    DeepCopyDeviceClasses(device, master);
}

mi/mieq.c was easy :-)

but still no luck in getting it to actually send the events like it
does in git master, just prevented the crash.