aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/xkb/xkbUtils.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/xkb/xkbUtils.c')
-rw-r--r--xorg-server/xkb/xkbUtils.c247
1 files changed, 164 insertions, 83 deletions
diff --git a/xorg-server/xkb/xkbUtils.c b/xorg-server/xkb/xkbUtils.c
index b5c0ac271..71b0f6661 100644
--- a/xorg-server/xkb/xkbUtils.c
+++ b/xorg-server/xkb/xkbUtils.c
@@ -23,6 +23,30 @@ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
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.
+
+*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
@@ -55,22 +79,15 @@ _XkbLookupAnyDevice(DeviceIntPtr *pDev, int id, ClientPtr client,
{
int rc = XkbKeyboardErrorCode;
- if (id == XkbUseCoreKbd) {
- if (inputInfo.keyboard)
- id = inputInfo.keyboard->id;
- else
- goto out;
- }
- if (id == XkbUseCorePtr) {
- if (inputInfo.pointer)
- id = inputInfo.pointer->id;
- else
- goto out;
- }
+ if (id == XkbUseCoreKbd)
+ id = PickKeyboard(client)->id;
+ else if (id == XkbUseCorePtr)
+ id = PickPointer(client)->id;
+
rc = dixLookupDevice(pDev, id, client, access_mode);
-out:
if (rc != Success)
*xkb_err = XkbErr_BadDevice;
+
return rc;
}
@@ -944,41 +961,12 @@ XkbConvertCase(register KeySym sym, KeySym *lower, KeySym *upper)
}
}
-
-/**
- * Copy an XKB map from src to dst, reallocating when necessary: if some
- * map components are present in one, but not in the other, the destination
- * components will be allocated or freed as necessary.
- *
- * Basic map consistency is assumed on both sides, so maps with random
- * uninitialised data (e.g. names->radio_grous == NULL, names->num_rg == 19)
- * _will_ cause failures. You've been warned.
- *
- * Returns TRUE on success, or FALSE on failure. If this function fails,
- * dst may be in an inconsistent state: all its pointers are guaranteed
- * to remain valid, but part of the map may be from src and part from dst.
- *
- * FIXME: This function wants to be broken up into multiple functions.
- */
-Bool
-XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
+static Bool
+_XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
{
- int i = 0, j = 0, k = 0;
void *tmp = NULL;
- XkbColorPtr scolor = NULL, dcolor = NULL;
- XkbDoodadPtr sdoodad = NULL, ddoodad = NULL;
+ int i;
XkbKeyTypePtr stype = NULL, dtype = NULL;
- XkbOutlinePtr soutline = NULL, doutline = NULL;
- XkbPropertyPtr sprop = NULL, dprop = NULL;
- XkbRowPtr srow = NULL, drow = NULL;
- XkbSectionPtr ssection = NULL, dsection = NULL;
- XkbShapePtr sshape = NULL, dshape = NULL;
- DeviceIntPtr pDev = NULL, tmpDev = NULL;
- xkbMapNotify mn;
- xkbNewKeyboardNotify nkn;
-
- if (!src || !dst || src == dst)
- return FALSE;
/* client map */
if (src->map) {
@@ -1227,6 +1215,14 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
XkbFreeClientMap(dst, XkbAllClientInfoMask, True);
}
+ return TRUE;
+}
+
+static Bool
+_XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+
/* server map */
if (src->server) {
if (!dst->server) {
@@ -1355,37 +1351,13 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
XkbFreeServerMap(dst, XkbAllServerInfoMask, True);
}
- /* indicators */
- if (src->indicators) {
- if (!dst->indicators) {
- dst->indicators = xalloc(sizeof(XkbIndicatorRec));
- if (!dst->indicators)
- return FALSE;
- }
- memcpy(dst->indicators, src->indicators, sizeof(XkbIndicatorRec));
- }
- else {
- if (dst->indicators) {
- xfree(dst->indicators);
- dst->indicators = NULL;
- }
- }
+ return TRUE;
+}
- /* controls */
- if (src->ctrls) {
- if (!dst->ctrls) {
- dst->ctrls = xalloc(sizeof(XkbControlsRec));
- if (!dst->ctrls)
- return FALSE;
- }
- memcpy(dst->ctrls, src->ctrls, sizeof(XkbControlsRec));
- }
- else {
- if (dst->ctrls) {
- xfree(dst->ctrls);
- dst->ctrls = NULL;
- }
- }
+static Bool
+_XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
/* names */
if (src->names) {
@@ -1480,6 +1452,14 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
XkbFreeNames(dst, XkbAllNamesMask, True);
}
+ return TRUE;
+}
+
+static Bool
+_XkbCopyCompat(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+
/* compat */
if (src->compat) {
if (!dst->compat) {
@@ -1524,6 +1504,22 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
XkbFreeCompatMap(dst, XkbAllCompatMask, True);
}
+ return TRUE;
+}
+
+static Bool
+_XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst)
+{
+ void *tmp = NULL;
+ int i = 0, j = 0, k = 0;
+ XkbColorPtr scolor = NULL, dcolor = NULL;
+ XkbDoodadPtr sdoodad = NULL, ddoodad = NULL;
+ XkbOutlinePtr soutline = NULL, doutline = NULL;
+ XkbPropertyPtr sprop = NULL, dprop = NULL;
+ XkbRowPtr srow = NULL, drow = NULL;
+ XkbSectionPtr ssection = NULL, dsection = NULL;
+ XkbShapePtr sshape = NULL, dshape = NULL;
+
/* geometry */
if (src->geom) {
if (!dst->geom) {
@@ -2020,9 +2016,9 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
strcpy(dst->geom->label_font, src->geom->label_font);
i = XkbGeomColorIndex(src->geom, src->geom->label_color);
- dst->geom->label_color = &(src->geom->colors[i]);
+ dst->geom->label_color = &(dst->geom->colors[i]);
i = XkbGeomColorIndex(src->geom, src->geom->base_color);
- dst->geom->base_color = &(src->geom->colors[i]);
+ dst->geom->base_color = &(dst->geom->colors[i]);
}
else {
if (dst->geom->label_font) {
@@ -2046,6 +2042,91 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
}
}
+ return TRUE;
+}
+
+static Bool
+_XkbCopyIndicators(XkbDescPtr src, XkbDescPtr dst)
+{
+ /* indicators */
+ if (src->indicators) {
+ if (!dst->indicators) {
+ dst->indicators = xalloc(sizeof(XkbIndicatorRec));
+ if (!dst->indicators)
+ return FALSE;
+ }
+ memcpy(dst->indicators, src->indicators, sizeof(XkbIndicatorRec));
+ }
+ else {
+ if (dst->indicators) {
+ xfree(dst->indicators);
+ dst->indicators = NULL;
+ }
+ }
+ return TRUE;
+}
+
+static Bool
+_XkbCopyControls(XkbDescPtr src, XkbDescPtr dst)
+{
+ /* controls */
+ if (src->ctrls) {
+ if (!dst->ctrls) {
+ dst->ctrls = xalloc(sizeof(XkbControlsRec));
+ if (!dst->ctrls)
+ return FALSE;
+ }
+ memcpy(dst->ctrls, src->ctrls, sizeof(XkbControlsRec));
+ }
+ else {
+ if (dst->ctrls) {
+ xfree(dst->ctrls);
+ dst->ctrls = NULL;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Copy an XKB map from src to dst, reallocating when necessary: if some
+ * map components are present in one, but not in the other, the destination
+ * components will be allocated or freed as necessary.
+ *
+ * Basic map consistency is assumed on both sides, so maps with random
+ * uninitialised data (e.g. names->radio_grous == NULL, names->num_rg == 19)
+ * _will_ cause failures. You've been warned.
+ *
+ * Returns TRUE on success, or FALSE on failure. If this function fails,
+ * dst may be in an inconsistent state: all its pointers are guaranteed
+ * to remain valid, but part of the map may be from src and part from dst.
+ *
+ */
+
+Bool
+XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
+{
+ DeviceIntPtr pDev = NULL, tmpDev = NULL;
+ xkbMapNotify mn;
+ xkbNewKeyboardNotify nkn;
+
+ if (!src || !dst || src == dst)
+ return FALSE;
+
+ if (!_XkbCopyClientMap(src, dst))
+ return FALSE;
+ if (!_XkbCopyServerMap(src, dst))
+ return FALSE;
+ if (!_XkbCopyIndicators(src, dst))
+ return FALSE;
+ if (!_XkbCopyControls(src, dst))
+ return FALSE;
+ if (!_XkbCopyNames(src, dst))
+ return FALSE;
+ if (!_XkbCopyCompat(src, dst))
+ return FALSE;
+ if (!_XkbCopyGeom(src, dst))
+ return FALSE;
+
if (inputInfo.keyboard->key->xkbInfo &&
inputInfo.keyboard->key->xkbInfo->desc == dst) {
pDev = inputInfo.keyboard;
@@ -2060,9 +2141,9 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
}
}
for (tmpDev = inputInfo.off_devices; tmpDev && !pDev;
- tmpDev = tmpDev->next) {
+ tmpDev = tmpDev->next) {
if (tmpDev->key && tmpDev->key->xkbInfo &&
- tmpDev->key->xkbInfo->desc == dst) {
+ tmpDev->key->xkbInfo->desc == dst) {
pDev = tmpDev;
break;
}
@@ -2071,14 +2152,14 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
if (sendNotifies) {
if (!pDev) {
- ErrorF("XkbCopyKeymap: asked for notifies, but can't find device!\n");
+ ErrorF("[xkb] XkbCopyKeymap: asked for notifies, but can't find device!\n");
}
else {
/* send NewKeyboardNotify if the keycode range changed, else
* just MapNotify. we also need to send NKN if the geometry
* changed (obviously ...). */
if ((src->min_key_code != dst->min_key_code ||
- src->max_key_code != dst->max_key_code) && sendNotifies) {
+ src->max_key_code != dst->max_key_code)) {
nkn.oldMinKeyCode = dst->min_key_code;
nkn.oldMaxKeyCode = dst->max_key_code;
nkn.deviceID = nkn.oldDeviceID = pDev->id;
@@ -2088,8 +2169,8 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies)
nkn.requestMinor = X_kbSetMap; /* XXX bare-faced lie */
nkn.changed = XkbAllNewKeyboardEventsMask;
XkbSendNewKeyboardNotify(pDev, &nkn);
- }
- else if (sendNotifies) {
+ } else
+ {
mn.deviceID = pDev->id;
mn.minKeyCode = src->min_key_code;
mn.maxKeyCode = src->max_key_code;