static void do_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) { int i; xEvent core_mn; deviceMappingNotify xi_mn; /* The map in ButtonClassRec refers to button numbers, whereas the * protocol is zero-indexed. Sigh. */ memcpy(&(dev->button->map[1]), map, len); core_mn.u.u.type = MappingNotify; core_mn.u.mappingNotify.request = MappingPointer; /* 0 is the server client. */ for (i = 1; i < currentMaxClients; i++) { /* Don't send irrelevant events to naïve clients. */ if (!clients[i] || clients[i]->clientState != ClientStateRunning) continue; if (!XIShouldNotify(clients[i], dev)) continue; core_mn.u.u.sequenceNumber = clients[i]->sequence; WriteEventsToClient(clients[i], 1, &core_mn); } xi_mn.type = DeviceMappingNotify; xi_mn.request = MappingPointer; xi_mn.deviceid = dev->id; xi_mn.time = GetTimeInMillis(); SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1); }
/* * This function sends out two kinds of notification: * - Core mapping notify events sent to clients for whom kbd is the * current core ('picked') keyboard _and_ have not explicitly * selected for XKB mapping notify events; * - Xi mapping events, sent unconditionally to all clients who have * explicitly selected for them (including those who have explicitly * selected for XKB mapping notify events!). */ static void XkbSendLegacyMapNotify(DeviceIntPtr kbd, CARD16 xkb_event, CARD16 changed, int first_key, int num_keys) { int i; int keymap_changed = 0; int modmap_changed = 0; CARD32 time = GetTimeInMillis(); if (xkb_event == XkbNewKeyboardNotify) { if (changed & XkbNKN_KeycodesMask) { keymap_changed = 1; modmap_changed = 1; } } else if (xkb_event == XkbMapNotify) { if (changed & XkbKeySymsMask) keymap_changed = 1; if (changed & XkbModifierMapMask) modmap_changed = 1; } if (!keymap_changed && !modmap_changed) return; /* 0 is serverClient. */ for (i = 1; i < currentMaxClients; i++) { if (!clients[i] || clients[i]->clientState != ClientStateRunning) continue; /* XKB allows clients to restrict the MappingNotify events sent to * them. This was broken for three years. Sorry. */ if (xkb_event == XkbMapNotify && (clients[i]->xkbClientFlags & _XkbClientInitialized) && !(clients[i]->mapNotifyMask & changed)) continue; /* Emulate previous server behaviour: any client which has activated * XKB will not receive core events emulated from a NewKeyboardNotify * at all. */ if (xkb_event == XkbNewKeyboardNotify && (clients[i]->xkbClientFlags & _XkbClientInitialized)) continue; /* Don't send core events to clients who don't know about us. */ if (!XIShouldNotify(clients[i], kbd)) continue; if (keymap_changed) { xEvent core_mn; core_mn.u.u.type = MappingNotify; core_mn.u.mappingNotify.request = MappingKeyboard; /* Clip the keycode range to what the client knows about, so it * doesn't freak out. */ if (first_key >= clients[i]->minKC) core_mn.u.mappingNotify.firstKeyCode = first_key; else core_mn.u.mappingNotify.firstKeyCode = clients[i]->minKC; if (first_key + num_keys - 1 <= clients[i]->maxKC) core_mn.u.mappingNotify.count = num_keys; else core_mn.u.mappingNotify.count = clients[i]->maxKC - clients[i]->minKC + 1; WriteEventsToClient(clients[i], 1, &core_mn); } if (modmap_changed) { xEvent core_mn; core_mn.u.mappingNotify.request = MappingModifier; core_mn.u.mappingNotify.firstKeyCode = 0; core_mn.u.mappingNotify.count = 0; core_mn.u.u.type = MappingNotify; WriteEventsToClient(clients[i], 1, &core_mn); } } /* Hmm, maybe we can accidentally generate Xi events for core devices * here? Clients might be upset, but that seems better than the * alternative of stale keymaps. -ds */ if (keymap_changed) { deviceMappingNotify xi_mn; xi_mn.type = DeviceMappingNotify; xi_mn.deviceid = kbd->id; xi_mn.request = MappingKeyboard; xi_mn.firstKeyCode = first_key; xi_mn.count = num_keys; xi_mn.time = time; SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1); } if (modmap_changed) { deviceMappingNotify xi_mn; xi_mn.type = DeviceMappingNotify; xi_mn.deviceid = kbd->id; xi_mn.request = MappingModifier; xi_mn.firstKeyCode = 0; xi_mn.count = 0; xi_mn.time = time; SendEventToAllWindows(kbd, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1); } }