inpututils.c revision 1b5d61b8
16747b715Smrg/*
26747b715Smrg * Copyright © 2008 Daniel Stone
36747b715Smrg *
46747b715Smrg * Permission is hereby granted, free of charge, to any person obtaining a
56747b715Smrg * copy of this software and associated documentation files (the "Software"),
66747b715Smrg * to deal in the Software without restriction, including without limitation
76747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
86747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the
96747b715Smrg * Software is furnished to do so, subject to the following conditions:
106747b715Smrg *
116747b715Smrg * The above copyright notice and this permission notice (including the next
126747b715Smrg * paragraph) shall be included in all copies or substantial portions of the
136747b715Smrg * Software.
146747b715Smrg *
156747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
166747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
176747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
186747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
196747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
206747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
216747b715Smrg * DEALINGS IN THE SOFTWARE.
226747b715Smrg *
236747b715Smrg * Author: Daniel Stone <daniel@fooishbar.org>
246747b715Smrg */
256747b715Smrg
266747b715Smrg#ifdef HAVE_DIX_CONFIG_H
276747b715Smrg#include "dix-config.h"
286747b715Smrg#endif
296747b715Smrg
306747b715Smrg#include "exevents.h"
316747b715Smrg#include "exglobals.h"
326747b715Smrg#include "misc.h"
336747b715Smrg#include "input.h"
346747b715Smrg#include "inputstr.h"
356747b715Smrg#include "xace.h"
366747b715Smrg#include "xkbsrv.h"
376747b715Smrg#include "xkbstr.h"
389ace9065Smrg#include "inpututils.h"
3935c4bbdfSmrg#include "eventstr.h"
4035c4bbdfSmrg#include "scrnintstr.h"
4135c4bbdfSmrg#include "optionstr.h"
426747b715Smrg
436747b715Smrg/* Check if a button map change is okay with the device.
446747b715Smrg * Returns -1 for BadValue, as it collides with MappingBusy. */
456747b715Smrgstatic int
466747b715Smrgcheck_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, CARD32 *errval_out,
476747b715Smrg                    ClientPtr client)
486747b715Smrg{
496747b715Smrg    int i, ret;
506747b715Smrg
5135c4bbdfSmrg    if (!dev || !dev->button) {
526747b715Smrg        client->errorValue = (dev) ? dev->id : 0;
536747b715Smrg        return BadDevice;
546747b715Smrg    }
556747b715Smrg
566747b715Smrg    ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
5735c4bbdfSmrg    if (ret != Success) {
586747b715Smrg        client->errorValue = dev->id;
596747b715Smrg        return ret;
606747b715Smrg    }
616747b715Smrg
626747b715Smrg    for (i = 0; i < len; i++) {
6335c4bbdfSmrg        if (dev->button->map[i + 1] != map[i] &&
6435c4bbdfSmrg            button_is_down(dev, i + 1, BUTTON_PROCESSED))
656747b715Smrg            return MappingBusy;
666747b715Smrg    }
676747b715Smrg
686747b715Smrg    return Success;
696747b715Smrg}
706747b715Smrg
716747b715Smrgstatic void
726747b715Smrgdo_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client)
736747b715Smrg{
746747b715Smrg    int i;
7535c4bbdfSmrg    xEvent core_mn = { .u.u.type = MappingNotify };
766747b715Smrg    deviceMappingNotify xi_mn;
776747b715Smrg
786747b715Smrg    /* The map in ButtonClassRec refers to button numbers, whereas the
796747b715Smrg     * protocol is zero-indexed.  Sigh. */
806747b715Smrg    memcpy(&(dev->button->map[1]), map, len);
816747b715Smrg
826747b715Smrg    core_mn.u.mappingNotify.request = MappingPointer;
836747b715Smrg
846747b715Smrg    /* 0 is the server client. */
856747b715Smrg    for (i = 1; i < currentMaxClients; i++) {
866747b715Smrg        /* Don't send irrelevant events to naïve clients. */
876747b715Smrg        if (!clients[i] || clients[i]->clientState != ClientStateRunning)
886747b715Smrg            continue;
896747b715Smrg
906747b715Smrg        if (!XIShouldNotify(clients[i], dev))
916747b715Smrg            continue;
926747b715Smrg
936747b715Smrg        WriteEventsToClient(clients[i], 1, &core_mn);
946747b715Smrg    }
956747b715Smrg
9635c4bbdfSmrg    xi_mn = (deviceMappingNotify) {
9735c4bbdfSmrg        .type = DeviceMappingNotify,
9835c4bbdfSmrg        .request = MappingPointer,
9935c4bbdfSmrg        .deviceid = dev->id,
10035c4bbdfSmrg        .time = GetTimeInMillis()
10135c4bbdfSmrg    };
1026747b715Smrg
1036747b715Smrg    SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) &xi_mn, 1);
1046747b715Smrg}
1056747b715Smrg
1066747b715Smrg/*
1076747b715Smrg * Does what it says on the box, both for core and Xi.
1086747b715Smrg *
1096747b715Smrg * Faithfully reports any errors encountered while trying to apply the map
1106747b715Smrg * to the requested device, faithfully ignores any errors encountered while
1116747b715Smrg * trying to apply the map to its master/slaves.
1126747b715Smrg */
1136747b715Smrgint
1146747b715SmrgApplyPointerMapping(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client)
1156747b715Smrg{
1166747b715Smrg    int ret;
1176747b715Smrg
1186747b715Smrg    /* If we can't perform the change on the requested device, bail out. */
1196747b715Smrg    ret = check_butmap_change(dev, map, len, &client->errorValue, client);
1206747b715Smrg    if (ret != Success)
1216747b715Smrg        return ret;
1226747b715Smrg    do_butmap_change(dev, map, len, client);
1236747b715Smrg
1246747b715Smrg    return Success;
1256747b715Smrg}
1266747b715Smrg
1276747b715Smrg/* Check if a modifier map change is okay with the device.
1286747b715Smrg * Returns -1 for BadValue, as it collides with MappingBusy; this particular
1296747b715Smrg * caveat can be removed with LegalModifier, as we have no other reason to
1306747b715Smrg * set MappingFailed.  Sigh. */
1316747b715Smrgstatic int
1326747b715Smrgcheck_modmap_change(ClientPtr client, DeviceIntPtr dev, KeyCode *modmap)
1336747b715Smrg{
1346747b715Smrg    int ret, i;
1356747b715Smrg    XkbDescPtr xkb;
1366747b715Smrg
1376747b715Smrg    ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
1386747b715Smrg    if (ret != Success)
1396747b715Smrg        return ret;
1406747b715Smrg
1416747b715Smrg    if (!dev->key)
1426747b715Smrg        return BadMatch;
1436747b715Smrg    xkb = dev->key->xkbInfo->desc;
1446747b715Smrg
1456747b715Smrg    for (i = 0; i < MAP_LENGTH; i++) {
1466747b715Smrg        if (!modmap[i])
1476747b715Smrg            continue;
1486747b715Smrg
1496747b715Smrg        /* Check that all the new modifiers fall within the advertised
1506747b715Smrg         * keycode range. */
1516747b715Smrg        if (i < xkb->min_key_code || i > xkb->max_key_code) {
1526747b715Smrg            client->errorValue = i;
1536747b715Smrg            return -1;
1546747b715Smrg        }
1556747b715Smrg
1566747b715Smrg        /* Make sure the mapping is okay with the DDX. */
1576747b715Smrg        if (!LegalModifier(i, dev)) {
1586747b715Smrg            client->errorValue = i;
1596747b715Smrg            return MappingFailed;
1606747b715Smrg        }
1616747b715Smrg
1626747b715Smrg        /* None of the new modifiers may be down while we change the
1636747b715Smrg         * map. */
1646747b715Smrg        if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) {
1656747b715Smrg            client->errorValue = i;
1666747b715Smrg            return MappingBusy;
1676747b715Smrg        }
1686747b715Smrg    }
1696747b715Smrg
1706747b715Smrg    /* None of the old modifiers may be down while we change the map,
1716747b715Smrg     * either. */
1726747b715Smrg    for (i = xkb->min_key_code; i < xkb->max_key_code; i++) {
1736747b715Smrg        if (!xkb->map->modmap[i])
1746747b715Smrg            continue;
1756747b715Smrg        if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) {
1766747b715Smrg            client->errorValue = i;
1776747b715Smrg            return MappingBusy;
1786747b715Smrg        }
1796747b715Smrg    }
1806747b715Smrg
1816747b715Smrg    return Success;
1826747b715Smrg}
1836747b715Smrg
1846747b715Smrgstatic int
1856747b715Smrgcheck_modmap_change_slave(ClientPtr client, DeviceIntPtr master,
1866747b715Smrg                          DeviceIntPtr slave, CARD8 *modmap)
1876747b715Smrg{
1886747b715Smrg    XkbDescPtr master_xkb, slave_xkb;
1896747b715Smrg    int i, j;
1906747b715Smrg
1916747b715Smrg    if (!slave->key || !master->key)
1926747b715Smrg        return 0;
1936747b715Smrg
1946747b715Smrg    master_xkb = master->key->xkbInfo->desc;
1956747b715Smrg    slave_xkb = slave->key->xkbInfo->desc;
1966747b715Smrg
1976747b715Smrg    /* Ignore devices with a clearly different keymap. */
1986747b715Smrg    if (slave_xkb->min_key_code != master_xkb->min_key_code ||
1996747b715Smrg        slave_xkb->max_key_code != master_xkb->max_key_code)
2006747b715Smrg        return 0;
2016747b715Smrg
2026747b715Smrg    for (i = 0; i < MAP_LENGTH; i++) {
2036747b715Smrg        if (!modmap[i])
2046747b715Smrg            continue;
2056747b715Smrg
2066747b715Smrg        /* If we have different symbols for any modifier on an
2076747b715Smrg         * extended keyboard, ignore the whole remap request. */
2086747b715Smrg        for (j = 0;
2096747b715Smrg             j < XkbKeyNumSyms(slave_xkb, i) &&
21035c4bbdfSmrg             j < XkbKeyNumSyms(master_xkb, i); j++)
21135c4bbdfSmrg            if (XkbKeySymsPtr(slave_xkb, i)[j] !=
21235c4bbdfSmrg                XkbKeySymsPtr(master_xkb, i)[j])
2136747b715Smrg                return 0;
2146747b715Smrg    }
2156747b715Smrg
2166747b715Smrg    if (check_modmap_change(client, slave, modmap) != Success)
2176747b715Smrg        return 0;
2186747b715Smrg
2196747b715Smrg    return 1;
2206747b715Smrg}
2216747b715Smrg
2226747b715Smrg/* Actually change the modifier map, and send notifications.  Cannot fail. */
2236747b715Smrgstatic void
2246747b715Smrgdo_modmap_change(ClientPtr client, DeviceIntPtr dev, CARD8 *modmap)
2256747b715Smrg{
2266747b715Smrg    XkbApplyMappingChange(dev, NULL, 0, 0, modmap, serverClient);
2276747b715Smrg}
2286747b715Smrg
2296747b715Smrg/* Rebuild modmap (key -> mod) from map (mod -> key). */
23035c4bbdfSmrgstatic int
23135c4bbdfSmrgbuild_modmap_from_modkeymap(CARD8 *modmap, KeyCode *modkeymap,
23235c4bbdfSmrg                            int max_keys_per_mod)
2336747b715Smrg{
2346747b715Smrg    int i, len = max_keys_per_mod * 8;
2356747b715Smrg
2366747b715Smrg    memset(modmap, 0, MAP_LENGTH);
2376747b715Smrg
2386747b715Smrg    for (i = 0; i < len; i++) {
2396747b715Smrg        if (!modkeymap[i])
2406747b715Smrg            continue;
2416747b715Smrg
24235c4bbdfSmrg#if MAP_LENGTH < 256
2436747b715Smrg        if (modkeymap[i] >= MAP_LENGTH)
2446747b715Smrg            return BadValue;
24535c4bbdfSmrg#endif
2466747b715Smrg
2476747b715Smrg        if (modmap[modkeymap[i]])
2486747b715Smrg            return BadValue;
2496747b715Smrg
2506747b715Smrg        modmap[modkeymap[i]] = 1 << (i / max_keys_per_mod);
2516747b715Smrg    }
2526747b715Smrg
2536747b715Smrg    return Success;
2546747b715Smrg}
2556747b715Smrg
2566747b715Smrgint
2576747b715Smrgchange_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap,
2586747b715Smrg              int max_keys_per_mod)
2596747b715Smrg{
2606747b715Smrg    int ret;
2616747b715Smrg    CARD8 modmap[MAP_LENGTH];
2626747b715Smrg    DeviceIntPtr tmp;
2636747b715Smrg
2646747b715Smrg    ret = build_modmap_from_modkeymap(modmap, modkeymap, max_keys_per_mod);
2656747b715Smrg    if (ret != Success)
2666747b715Smrg        return ret;
2676747b715Smrg
2686747b715Smrg    /* If we can't perform the change on the requested device, bail out. */
2696747b715Smrg    ret = check_modmap_change(client, dev, modmap);
2706747b715Smrg    if (ret != Success)
2716747b715Smrg        return ret;
2726747b715Smrg    do_modmap_change(client, dev, modmap);
2736747b715Smrg
2746747b715Smrg    /* Change any attached masters/slaves. */
2756747b715Smrg    if (IsMaster(dev)) {
2766747b715Smrg        for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
27735c4bbdfSmrg            if (!IsMaster(tmp) && GetMaster(tmp, MASTER_KEYBOARD) == dev)
2786747b715Smrg                if (check_modmap_change_slave(client, dev, tmp, modmap))
2796747b715Smrg                    do_modmap_change(client, tmp, modmap);
2806747b715Smrg        }
2816747b715Smrg    }
28235c4bbdfSmrg    else if (!IsFloating(dev) &&
28335c4bbdfSmrg             GetMaster(dev, MASTER_KEYBOARD)->lastSlave == dev) {
2846747b715Smrg        /* If this fails, expect the results to be weird. */
2851b5d61b8Smrg        if (check_modmap_change(client, dev->master, modmap) == Success)
28635c4bbdfSmrg            do_modmap_change(client, dev->master, modmap);
2876747b715Smrg    }
2886747b715Smrg
2896747b715Smrg    return Success;
2906747b715Smrg}
2916747b715Smrg
29235c4bbdfSmrgint
29335c4bbdfSmrggenerate_modkeymap(ClientPtr client, DeviceIntPtr dev,
29435c4bbdfSmrg                   KeyCode **modkeymap_out, int *max_keys_per_mod_out)
2956747b715Smrg{
2966747b715Smrg    CARD8 keys_per_mod[8];
2976747b715Smrg    int max_keys_per_mod;
2988223e2f2Smrg    KeyCode *modkeymap = NULL;
2996747b715Smrg    int i, j, ret;
3006747b715Smrg
3016747b715Smrg    ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess);
3026747b715Smrg    if (ret != Success)
3036747b715Smrg        return ret;
3046747b715Smrg
3056747b715Smrg    if (!dev->key)
3066747b715Smrg        return BadMatch;
3076747b715Smrg
3086747b715Smrg    /* Count the number of keys per modifier to determine how wide we
3096747b715Smrg     * should make the map. */
3106747b715Smrg    max_keys_per_mod = 0;
3116747b715Smrg    for (i = 0; i < 8; i++)
3126747b715Smrg        keys_per_mod[i] = 0;
3136747b715Smrg    for (i = 8; i < MAP_LENGTH; i++) {
3146747b715Smrg        for (j = 0; j < 8; j++) {
3156747b715Smrg            if (dev->key->xkbInfo->desc->map->modmap[i] & (1 << j)) {
3166747b715Smrg                if (++keys_per_mod[j] > max_keys_per_mod)
3176747b715Smrg                    max_keys_per_mod = keys_per_mod[j];
3186747b715Smrg            }
3196747b715Smrg        }
3206747b715Smrg    }
3216747b715Smrg
3228223e2f2Smrg    if (max_keys_per_mod != 0) {
3238223e2f2Smrg        modkeymap = calloc(max_keys_per_mod * 8, sizeof(KeyCode));
3248223e2f2Smrg        if (!modkeymap)
3258223e2f2Smrg            return BadAlloc;
3266747b715Smrg
3278223e2f2Smrg        for (i = 0; i < 8; i++)
3288223e2f2Smrg            keys_per_mod[i] = 0;
3296747b715Smrg
3308223e2f2Smrg        for (i = 8; i < MAP_LENGTH; i++) {
3318223e2f2Smrg            for (j = 0; j < 8; j++) {
3328223e2f2Smrg                if (dev->key->xkbInfo->desc->map->modmap[i] & (1 << j)) {
3338223e2f2Smrg                    modkeymap[(j * max_keys_per_mod) + keys_per_mod[j]] = i;
3348223e2f2Smrg                    keys_per_mod[j]++;
3358223e2f2Smrg                }
3366747b715Smrg            }
3376747b715Smrg        }
3386747b715Smrg    }
3396747b715Smrg
3406747b715Smrg    *max_keys_per_mod_out = max_keys_per_mod;
3416747b715Smrg    *modkeymap_out = modkeymap;
3426747b715Smrg
3436747b715Smrg    return Success;
3446747b715Smrg}
3456747b715Smrg
3466747b715Smrg/**
3476747b715Smrg * Duplicate the InputAttributes in the most obvious way.
3486747b715Smrg * No special memory handling is used to give drivers the maximum
3496747b715Smrg * flexibility with the data. Drivers should be able to call realloc on the
3506747b715Smrg * product string if needed and perform similar operations.
3516747b715Smrg */
35235c4bbdfSmrgInputAttributes *
35335c4bbdfSmrgDuplicateInputAttributes(InputAttributes * attrs)
3546747b715Smrg{
3556747b715Smrg    InputAttributes *new_attr;
3566747b715Smrg    int ntags = 0;
3576747b715Smrg    char **tags, **new_tags;
3586747b715Smrg
3596747b715Smrg    if (!attrs)
3606747b715Smrg        return NULL;
3616747b715Smrg
3626747b715Smrg    if (!(new_attr = calloc(1, sizeof(InputAttributes))))
3636747b715Smrg        goto unwind;
3646747b715Smrg
3656747b715Smrg    if (attrs->product && !(new_attr->product = strdup(attrs->product)))
3666747b715Smrg        goto unwind;
3676747b715Smrg    if (attrs->vendor && !(new_attr->vendor = strdup(attrs->vendor)))
3686747b715Smrg        goto unwind;
3696747b715Smrg    if (attrs->device && !(new_attr->device = strdup(attrs->device)))
3706747b715Smrg        goto unwind;
3716747b715Smrg    if (attrs->pnp_id && !(new_attr->pnp_id = strdup(attrs->pnp_id)))
3726747b715Smrg        goto unwind;
3736747b715Smrg    if (attrs->usb_id && !(new_attr->usb_id = strdup(attrs->usb_id)))
3746747b715Smrg        goto unwind;
3756747b715Smrg
3766747b715Smrg    new_attr->flags = attrs->flags;
3776747b715Smrg
37835c4bbdfSmrg    if ((tags = attrs->tags)) {
37935c4bbdfSmrg        while (*tags++)
3806747b715Smrg            ntags++;
3816747b715Smrg
38235c4bbdfSmrg        new_attr->tags = calloc(ntags + 1, sizeof(char *));
3836747b715Smrg        if (!new_attr->tags)
3846747b715Smrg            goto unwind;
3856747b715Smrg
3866747b715Smrg        tags = attrs->tags;
3876747b715Smrg        new_tags = new_attr->tags;
3886747b715Smrg
38935c4bbdfSmrg        while (*tags) {
3906747b715Smrg            *new_tags = strdup(*tags);
3916747b715Smrg            if (!*new_tags)
3926747b715Smrg                goto unwind;
3936747b715Smrg
3946747b715Smrg            tags++;
3956747b715Smrg            new_tags++;
3966747b715Smrg        }
3976747b715Smrg    }
3986747b715Smrg
3996747b715Smrg    return new_attr;
4006747b715Smrg
40135c4bbdfSmrg unwind:
4026747b715Smrg    FreeInputAttributes(new_attr);
4036747b715Smrg    return NULL;
4046747b715Smrg}
4056747b715Smrg
4066747b715Smrgvoid
40735c4bbdfSmrgFreeInputAttributes(InputAttributes * attrs)
4086747b715Smrg{
4096747b715Smrg    char **tags;
4106747b715Smrg
4116747b715Smrg    if (!attrs)
4126747b715Smrg        return;
4136747b715Smrg
4146747b715Smrg    free(attrs->product);
4156747b715Smrg    free(attrs->vendor);
4166747b715Smrg    free(attrs->device);
4176747b715Smrg    free(attrs->pnp_id);
4186747b715Smrg    free(attrs->usb_id);
4196747b715Smrg
4206747b715Smrg    if ((tags = attrs->tags))
42135c4bbdfSmrg        while (*tags)
4226747b715Smrg            free(*tags++);
4236747b715Smrg
4246747b715Smrg    free(attrs->tags);
4256747b715Smrg    free(attrs);
4266747b715Smrg}
4276747b715Smrg
4289ace9065Smrg/**
4299ace9065Smrg * Alloc a valuator mask large enough for num_valuators.
4309ace9065Smrg */
43135c4bbdfSmrgValuatorMask *
4329ace9065Smrgvaluator_mask_new(int num_valuators)
4339ace9065Smrg{
4349ace9065Smrg    /* alloc a fixed size mask for now and ignore num_valuators. in the
4359ace9065Smrg     * flying-car future, when we can dynamically alloc the masks and are
4369ace9065Smrg     * not constrained by signals, we can start using num_valuators */
4379ace9065Smrg    ValuatorMask *mask = calloc(1, sizeof(ValuatorMask));
43835c4bbdfSmrg
43935c4bbdfSmrg    if (mask == NULL)
44035c4bbdfSmrg        return NULL;
44135c4bbdfSmrg
4429ace9065Smrg    mask->last_bit = -1;
4439ace9065Smrg    return mask;
4449ace9065Smrg}
4459ace9065Smrg
4469ace9065Smrgvoid
4479ace9065Smrgvaluator_mask_free(ValuatorMask **mask)
4489ace9065Smrg{
4499ace9065Smrg    free(*mask);
4509ace9065Smrg    *mask = NULL;
4519ace9065Smrg}
4529ace9065Smrg
4539ace9065Smrg/**
4549ace9065Smrg * Sets a range of valuators between first_valuator and num_valuators with
4559ace9065Smrg * the data in the valuators array. All other values are set to 0.
4569ace9065Smrg */
4579ace9065Smrgvoid
45835c4bbdfSmrgvaluator_mask_set_range(ValuatorMask *mask, int first_valuator,
45935c4bbdfSmrg                        int num_valuators, const int *valuators)
4609ace9065Smrg{
4619ace9065Smrg    int i;
4629ace9065Smrg
4639ace9065Smrg    valuator_mask_zero(mask);
4649ace9065Smrg
46535c4bbdfSmrg    for (i = first_valuator;
46635c4bbdfSmrg         i < min(first_valuator + num_valuators, MAX_VALUATORS); i++)
4679ace9065Smrg        valuator_mask_set(mask, i, valuators[i - first_valuator]);
4689ace9065Smrg}
4699ace9065Smrg
4709ace9065Smrg/**
4719ace9065Smrg * Reset mask to zero.
4729ace9065Smrg */
4739ace9065Smrgvoid
4749ace9065Smrgvaluator_mask_zero(ValuatorMask *mask)
4759ace9065Smrg{
4769ace9065Smrg    memset(mask, 0, sizeof(*mask));
4779ace9065Smrg    mask->last_bit = -1;
4789ace9065Smrg}
4799ace9065Smrg
4809ace9065Smrg/**
4819ace9065Smrg * Returns the current size of the mask (i.e. the highest number of
4829ace9065Smrg * valuators currently set + 1).
4839ace9065Smrg */
4849ace9065Smrgint
4859ace9065Smrgvaluator_mask_size(const ValuatorMask *mask)
4869ace9065Smrg{
4879ace9065Smrg    return mask->last_bit + 1;
4889ace9065Smrg}
4899ace9065Smrg
4909ace9065Smrg/**
4919ace9065Smrg * Returns the number of valuators set in the given mask.
4929ace9065Smrg */
4939ace9065Smrgint
4949ace9065Smrgvaluator_mask_num_valuators(const ValuatorMask *mask)
4959ace9065Smrg{
4969ace9065Smrg    return CountBits(mask->mask, min(mask->last_bit + 1, MAX_VALUATORS));
4979ace9065Smrg}
4989ace9065Smrg
4999ace9065Smrg/**
5009ace9065Smrg * Return true if the valuator is set in the mask, or false otherwise.
5019ace9065Smrg */
5029ace9065Smrgint
5039ace9065Smrgvaluator_mask_isset(const ValuatorMask *mask, int valuator)
5049ace9065Smrg{
5059ace9065Smrg    return mask->last_bit >= valuator && BitIsOn(mask->mask, valuator);
5069ace9065Smrg}
5079ace9065Smrg
50835c4bbdfSmrgstatic inline void
50935c4bbdfSmrg_valuator_mask_set_double(ValuatorMask *mask, int valuator, double data)
51035c4bbdfSmrg{
51135c4bbdfSmrg    mask->last_bit = max(valuator, mask->last_bit);
51235c4bbdfSmrg    SetBit(mask->mask, valuator);
51335c4bbdfSmrg    mask->valuators[valuator] = data;
51435c4bbdfSmrg}
51535c4bbdfSmrg
5169ace9065Smrg/**
51735c4bbdfSmrg * Set the valuator to the given floating-point data.
51835c4bbdfSmrg */
51935c4bbdfSmrgvoid
52035c4bbdfSmrgvaluator_mask_set_double(ValuatorMask *mask, int valuator, double data)
52135c4bbdfSmrg{
52235c4bbdfSmrg    BUG_WARN_MSG(mask->has_unaccelerated,
52335c4bbdfSmrg                 "Do not mix valuator types, zero mask first\n");
52435c4bbdfSmrg    _valuator_mask_set_double(mask, valuator, data);
52535c4bbdfSmrg}
52635c4bbdfSmrg
52735c4bbdfSmrg/**
52835c4bbdfSmrg * Set the valuator to the given integer data.
5299ace9065Smrg */
5309ace9065Smrgvoid
5319ace9065Smrgvaluator_mask_set(ValuatorMask *mask, int valuator, int data)
5329ace9065Smrg{
53335c4bbdfSmrg    valuator_mask_set_double(mask, valuator, data);
53435c4bbdfSmrg}
53535c4bbdfSmrg
53635c4bbdfSmrg/**
53735c4bbdfSmrg * Return the requested valuator value as a double. If the mask bit is not
53835c4bbdfSmrg * set for the given valuator, the returned value is undefined.
53935c4bbdfSmrg */
54035c4bbdfSmrgdouble
54135c4bbdfSmrgvaluator_mask_get_double(const ValuatorMask *mask, int valuator)
54235c4bbdfSmrg{
54335c4bbdfSmrg    return mask->valuators[valuator];
5449ace9065Smrg}
5459ace9065Smrg
5469ace9065Smrg/**
54735c4bbdfSmrg * Return the requested valuator value as an integer, rounding towards zero.
54835c4bbdfSmrg * If the mask bit is not set for the given valuator, the returned value is
54935c4bbdfSmrg * undefined.
5509ace9065Smrg */
5519ace9065Smrgint
5529ace9065Smrgvaluator_mask_get(const ValuatorMask *mask, int valuator)
5539ace9065Smrg{
55435c4bbdfSmrg    return trunc(valuator_mask_get_double(mask, valuator));
55535c4bbdfSmrg}
55635c4bbdfSmrg
55735c4bbdfSmrg/**
55835c4bbdfSmrg * Set value to the requested valuator. If the mask bit is set for this
55935c4bbdfSmrg * valuator, value contains the requested valuator value and TRUE is
56035c4bbdfSmrg * returned.
56135c4bbdfSmrg * If the mask bit is not set for this valuator, value is unchanged and
56235c4bbdfSmrg * FALSE is returned.
56335c4bbdfSmrg */
56435c4bbdfSmrgBool
56535c4bbdfSmrgvaluator_mask_fetch_double(const ValuatorMask *mask, int valuator,
56635c4bbdfSmrg                           double *value)
56735c4bbdfSmrg{
56835c4bbdfSmrg    if (valuator_mask_isset(mask, valuator)) {
56935c4bbdfSmrg        *value = valuator_mask_get_double(mask, valuator);
57035c4bbdfSmrg        return TRUE;
57135c4bbdfSmrg    }
57235c4bbdfSmrg    else
57335c4bbdfSmrg        return FALSE;
57435c4bbdfSmrg}
57535c4bbdfSmrg
57635c4bbdfSmrg/**
57735c4bbdfSmrg * Set value to the requested valuator. If the mask bit is set for this
57835c4bbdfSmrg * valuator, value contains the requested valuator value and TRUE is
57935c4bbdfSmrg * returned.
58035c4bbdfSmrg * If the mask bit is not set for this valuator, value is unchanged and
58135c4bbdfSmrg * FALSE is returned.
58235c4bbdfSmrg */
58335c4bbdfSmrgBool
58435c4bbdfSmrgvaluator_mask_fetch(const ValuatorMask *mask, int valuator, int *value)
58535c4bbdfSmrg{
58635c4bbdfSmrg    if (valuator_mask_isset(mask, valuator)) {
58735c4bbdfSmrg        *value = valuator_mask_get(mask, valuator);
58835c4bbdfSmrg        return TRUE;
58935c4bbdfSmrg    }
59035c4bbdfSmrg    else
59135c4bbdfSmrg        return FALSE;
5929ace9065Smrg}
5939ace9065Smrg
5949ace9065Smrg/**
5959ace9065Smrg * Remove the valuator from the mask.
5969ace9065Smrg */
5979ace9065Smrgvoid
5989ace9065Smrgvaluator_mask_unset(ValuatorMask *mask, int valuator)
5999ace9065Smrg{
6009ace9065Smrg    if (mask->last_bit >= valuator) {
6019ace9065Smrg        int i, lastbit = -1;
6029ace9065Smrg
6039ace9065Smrg        ClearBit(mask->mask, valuator);
60435c4bbdfSmrg        mask->valuators[valuator] = 0.0;
60535c4bbdfSmrg        mask->unaccelerated[valuator] = 0.0;
6069ace9065Smrg
6079ace9065Smrg        for (i = 0; i <= mask->last_bit; i++)
6089ace9065Smrg            if (valuator_mask_isset(mask, i))
6099ace9065Smrg                lastbit = max(lastbit, i);
6109ace9065Smrg        mask->last_bit = lastbit;
61135c4bbdfSmrg
61235c4bbdfSmrg        if (mask->last_bit == -1)
61335c4bbdfSmrg            mask->has_unaccelerated = FALSE;
6149ace9065Smrg    }
6159ace9065Smrg}
6169ace9065Smrg
6179ace9065Smrgvoid
6189ace9065Smrgvaluator_mask_copy(ValuatorMask *dest, const ValuatorMask *src)
6199ace9065Smrg{
6209ace9065Smrg    if (src)
6219ace9065Smrg        memcpy(dest, src, sizeof(*dest));
6229ace9065Smrg    else
6239ace9065Smrg        valuator_mask_zero(dest);
6249ace9065Smrg}
6259ace9065Smrg
62635c4bbdfSmrgBool
62735c4bbdfSmrgvaluator_mask_has_unaccelerated(const ValuatorMask *mask)
62835c4bbdfSmrg{
62935c4bbdfSmrg    return mask->has_unaccelerated;
63035c4bbdfSmrg}
63135c4bbdfSmrg
63235c4bbdfSmrgvoid
63335c4bbdfSmrgvaluator_mask_drop_unaccelerated(ValuatorMask *mask)
63435c4bbdfSmrg{
63535c4bbdfSmrg    memset(mask->unaccelerated, 0, sizeof(mask->unaccelerated));
63635c4bbdfSmrg    mask->has_unaccelerated = FALSE;
63735c4bbdfSmrg}
63835c4bbdfSmrg
6391b5d61b8Smrgvoid
6401b5d61b8Smrgvaluator_mask_set_absolute_unaccelerated(ValuatorMask *mask,
6411b5d61b8Smrg                                         int valuator,
6421b5d61b8Smrg                                         int absolute,
6431b5d61b8Smrg                                         double unaccel)
6441b5d61b8Smrg{
6451b5d61b8Smrg    BUG_WARN_MSG(mask->last_bit != -1 && !mask->has_unaccelerated,
6461b5d61b8Smrg                 "Do not mix valuator types, zero mask first\n");
6471b5d61b8Smrg    _valuator_mask_set_double(mask, valuator, absolute);
6481b5d61b8Smrg    mask->has_unaccelerated = TRUE;
6491b5d61b8Smrg    mask->unaccelerated[valuator] = unaccel;
6501b5d61b8Smrg}
6511b5d61b8Smrg
65235c4bbdfSmrg/**
65335c4bbdfSmrg * Set both accelerated and unaccelerated value for this mask.
65435c4bbdfSmrg */
65535c4bbdfSmrgvoid
65635c4bbdfSmrgvaluator_mask_set_unaccelerated(ValuatorMask *mask,
65735c4bbdfSmrg                                int valuator,
65835c4bbdfSmrg                                double accel,
65935c4bbdfSmrg                                double unaccel)
66035c4bbdfSmrg{
66135c4bbdfSmrg    BUG_WARN_MSG(mask->last_bit != -1 && !mask->has_unaccelerated,
66235c4bbdfSmrg                 "Do not mix valuator types, zero mask first\n");
66335c4bbdfSmrg    _valuator_mask_set_double(mask, valuator, accel);
66435c4bbdfSmrg    mask->has_unaccelerated = TRUE;
66535c4bbdfSmrg    mask->unaccelerated[valuator] = unaccel;
66635c4bbdfSmrg}
66735c4bbdfSmrg
66835c4bbdfSmrgdouble
66935c4bbdfSmrgvaluator_mask_get_accelerated(const ValuatorMask *mask,
67035c4bbdfSmrg                              int valuator)
67135c4bbdfSmrg{
67235c4bbdfSmrg    return valuator_mask_get_double(mask, valuator);
67335c4bbdfSmrg}
67435c4bbdfSmrg
67535c4bbdfSmrgdouble
67635c4bbdfSmrgvaluator_mask_get_unaccelerated(const ValuatorMask *mask,
67735c4bbdfSmrg                                int valuator)
67835c4bbdfSmrg{
67935c4bbdfSmrg    return mask->unaccelerated[valuator];
68035c4bbdfSmrg}
68135c4bbdfSmrg
68235c4bbdfSmrgBool
68335c4bbdfSmrgvaluator_mask_fetch_unaccelerated(const ValuatorMask *mask,
68435c4bbdfSmrg                                  int valuator,
68535c4bbdfSmrg                                  double *accel,
68635c4bbdfSmrg                                  double *unaccel)
68735c4bbdfSmrg{
68835c4bbdfSmrg    if (valuator_mask_isset(mask, valuator)) {
68935c4bbdfSmrg        if (accel)
69035c4bbdfSmrg            *accel = valuator_mask_get_accelerated(mask, valuator);
69135c4bbdfSmrg        if (unaccel)
69235c4bbdfSmrg            *unaccel = valuator_mask_get_unaccelerated(mask, valuator);
69335c4bbdfSmrg        return TRUE;
69435c4bbdfSmrg    }
69535c4bbdfSmrg    else
69635c4bbdfSmrg        return FALSE;
69735c4bbdfSmrg}
69835c4bbdfSmrg
6999ace9065Smrgint
70035c4bbdfSmrgCountBits(const uint8_t * mask, int len)
7019ace9065Smrg{
7029ace9065Smrg    int i;
7039ace9065Smrg    int ret = 0;
7049ace9065Smrg
7059ace9065Smrg    for (i = 0; i < len; i++)
7069ace9065Smrg        if (BitIsOn(mask, i))
7079ace9065Smrg            ret++;
7089ace9065Smrg
7099ace9065Smrg    return ret;
7109ace9065Smrg}
71135c4bbdfSmrg
71235c4bbdfSmrg/**
71335c4bbdfSmrg * Verifies sanity of the event. If the event is not an internal event,
71435c4bbdfSmrg * memdumps the first 32 bytes of event to the log, a backtrace, then kill
71535c4bbdfSmrg * the server.
71635c4bbdfSmrg */
71735c4bbdfSmrgvoid
71835c4bbdfSmrgverify_internal_event(const InternalEvent *ev)
71935c4bbdfSmrg{
72035c4bbdfSmrg    if (ev && ev->any.header != ET_Internal) {
72135c4bbdfSmrg        int i;
72235c4bbdfSmrg        const unsigned char *data = (const unsigned char *) ev;
72335c4bbdfSmrg
72435c4bbdfSmrg        ErrorF("dix: invalid event type %d\n", ev->any.header);
72535c4bbdfSmrg
72635c4bbdfSmrg        for (i = 0; i < sizeof(xEvent); i++, data++) {
72735c4bbdfSmrg            ErrorF("%02hhx ", *data);
72835c4bbdfSmrg
72935c4bbdfSmrg            if ((i % 8) == 7)
73035c4bbdfSmrg                ErrorF("\n");
73135c4bbdfSmrg        }
73235c4bbdfSmrg
73335c4bbdfSmrg        xorg_backtrace();
73435c4bbdfSmrg        FatalError("Wrong event type %d. Aborting server\n", ev->any.header);
73535c4bbdfSmrg    }
73635c4bbdfSmrg}
73735c4bbdfSmrg
73835c4bbdfSmrg/**
73935c4bbdfSmrg * Initializes the given event to zero (or default values), for the given
74035c4bbdfSmrg * device.
74135c4bbdfSmrg */
74235c4bbdfSmrgvoid
7431b5d61b8Smrginit_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms,
7441b5d61b8Smrg                  enum DeviceEventSource source_type)
74535c4bbdfSmrg{
74635c4bbdfSmrg    memset(event, 0, sizeof(DeviceEvent));
74735c4bbdfSmrg    event->header = ET_Internal;
74835c4bbdfSmrg    event->length = sizeof(DeviceEvent);
74935c4bbdfSmrg    event->time = ms;
75035c4bbdfSmrg    event->deviceid = dev->id;
75135c4bbdfSmrg    event->sourceid = dev->id;
7521b5d61b8Smrg    event->source_type = source_type;
75335c4bbdfSmrg}
75435c4bbdfSmrg
75535c4bbdfSmrgint
75635c4bbdfSmrgevent_get_corestate(DeviceIntPtr mouse, DeviceIntPtr kbd)
75735c4bbdfSmrg{
75835c4bbdfSmrg    int corestate;
75935c4bbdfSmrg
76035c4bbdfSmrg    /* core state needs to be assembled BEFORE the device is updated. */
76135c4bbdfSmrg    corestate = (kbd &&
76235c4bbdfSmrg                 kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->
76335c4bbdfSmrg                                                  state) : 0;
76435c4bbdfSmrg    corestate |= (mouse && mouse->button) ? (mouse->button->state) : 0;
76535c4bbdfSmrg    corestate |= (mouse && mouse->touch) ? (mouse->touch->state) : 0;
76635c4bbdfSmrg
76735c4bbdfSmrg    return corestate;
76835c4bbdfSmrg}
76935c4bbdfSmrg
77035c4bbdfSmrgvoid
77135c4bbdfSmrgevent_set_state(DeviceIntPtr mouse, DeviceIntPtr kbd, DeviceEvent *event)
77235c4bbdfSmrg{
77335c4bbdfSmrg    int i;
77435c4bbdfSmrg
77535c4bbdfSmrg    for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
77635c4bbdfSmrg        if (BitIsOn(mouse->button->down, i))
77735c4bbdfSmrg            SetBit(event->buttons, mouse->button->map[i]);
77835c4bbdfSmrg
77935c4bbdfSmrg    if (mouse && mouse->touch && mouse->touch->buttonsDown > 0)
78035c4bbdfSmrg        SetBit(event->buttons, mouse->button->map[1]);
78135c4bbdfSmrg
78235c4bbdfSmrg    if (kbd && kbd->key) {
78335c4bbdfSmrg        XkbStatePtr state;
78435c4bbdfSmrg
78535c4bbdfSmrg        /* we need the state before the event happens */
78635c4bbdfSmrg        if (event->type == ET_KeyPress || event->type == ET_KeyRelease)
78735c4bbdfSmrg            state = &kbd->key->xkbInfo->prev_state;
78835c4bbdfSmrg        else
78935c4bbdfSmrg            state = &kbd->key->xkbInfo->state;
79035c4bbdfSmrg
79135c4bbdfSmrg        event->mods.base = state->base_mods;
79235c4bbdfSmrg        event->mods.latched = state->latched_mods;
79335c4bbdfSmrg        event->mods.locked = state->locked_mods;
79435c4bbdfSmrg        event->mods.effective = state->mods;
79535c4bbdfSmrg
79635c4bbdfSmrg        event->group.base = state->base_group;
79735c4bbdfSmrg        event->group.latched = state->latched_group;
79835c4bbdfSmrg        event->group.locked = state->locked_group;
79935c4bbdfSmrg        event->group.effective = state->group;
80035c4bbdfSmrg    }
80135c4bbdfSmrg}
80235c4bbdfSmrg
80335c4bbdfSmrg/**
80435c4bbdfSmrg * Return the event filter mask for the given device and the given core or
80535c4bbdfSmrg * XI1 protocol type.
80635c4bbdfSmrg */
80735c4bbdfSmrgMask
80835c4bbdfSmrgevent_get_filter_from_type(DeviceIntPtr dev, int evtype)
80935c4bbdfSmrg{
81035c4bbdfSmrg    return event_filters[dev ? dev->id : 0][evtype];
81135c4bbdfSmrg}
81235c4bbdfSmrg
81335c4bbdfSmrg/**
81435c4bbdfSmrg * Return the event filter mask for the given device and the given core or
81535c4bbdfSmrg * XI2 protocol type.
81635c4bbdfSmrg */
81735c4bbdfSmrgMask
81835c4bbdfSmrgevent_get_filter_from_xi2type(int evtype)
81935c4bbdfSmrg{
82035c4bbdfSmrg    return (1 << (evtype % 8));
82135c4bbdfSmrg}
82235c4bbdfSmrg
82335c4bbdfSmrgBool
82435c4bbdfSmrgpoint_on_screen(ScreenPtr pScreen, int x, int y)
82535c4bbdfSmrg{
82635c4bbdfSmrg    return x >= pScreen->x && x < pScreen->x + pScreen->width &&
82735c4bbdfSmrg        y >= pScreen->y && y < pScreen->y + pScreen->height;
82835c4bbdfSmrg}
82935c4bbdfSmrg
83035c4bbdfSmrg/**
83135c4bbdfSmrg * Update desktop dimensions on the screenInfo struct.
83235c4bbdfSmrg */
83335c4bbdfSmrgvoid
83435c4bbdfSmrgupdate_desktop_dimensions(void)
83535c4bbdfSmrg{
83635c4bbdfSmrg    int i;
83735c4bbdfSmrg    int x1 = INT_MAX, y1 = INT_MAX;     /* top-left */
83835c4bbdfSmrg    int x2 = INT_MIN, y2 = INT_MIN;     /* bottom-right */
83935c4bbdfSmrg
84035c4bbdfSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
84135c4bbdfSmrg        ScreenPtr screen = screenInfo.screens[i];
84235c4bbdfSmrg
84335c4bbdfSmrg        x1 = min(x1, screen->x);
84435c4bbdfSmrg        y1 = min(y1, screen->y);
84535c4bbdfSmrg        x2 = max(x2, screen->x + screen->width);
84635c4bbdfSmrg        y2 = max(y2, screen->y + screen->height);
84735c4bbdfSmrg    }
84835c4bbdfSmrg
84935c4bbdfSmrg    screenInfo.x = x1;
85035c4bbdfSmrg    screenInfo.y = y1;
85135c4bbdfSmrg    screenInfo.width = x2 - x1;
85235c4bbdfSmrg    screenInfo.height = y2 - y1;
85335c4bbdfSmrg}
85435c4bbdfSmrg
85535c4bbdfSmrg/*
85635c4bbdfSmrg * Delete the element with the key from the list, freeing all memory
85735c4bbdfSmrg * associated with the element..
85835c4bbdfSmrg */
85935c4bbdfSmrgstatic void
86035c4bbdfSmrginput_option_free(InputOption *o)
86135c4bbdfSmrg{
86235c4bbdfSmrg    free(o->opt_name);
86335c4bbdfSmrg    free(o->opt_val);
86435c4bbdfSmrg    free(o->opt_comment);
86535c4bbdfSmrg    free(o);
86635c4bbdfSmrg}
86735c4bbdfSmrg
86835c4bbdfSmrg/*
86935c4bbdfSmrg * Create a new InputOption with the key/value pair provided.
87035c4bbdfSmrg * If a list is provided, the new options is added to the list and the list
87135c4bbdfSmrg * is returned.
87235c4bbdfSmrg *
87335c4bbdfSmrg * If a new option is added to a list that already contains that option, the
87435c4bbdfSmrg * previous option is overwritten.
87535c4bbdfSmrg *
87635c4bbdfSmrg * @param list The list to add to.
87735c4bbdfSmrg * @param key Option key, will be copied.
87835c4bbdfSmrg * @param value Option value, will be copied.
87935c4bbdfSmrg *
88035c4bbdfSmrg * @return If list is not NULL, the list with the new option added. If list
88135c4bbdfSmrg * is NULL, a new option list with one element. On failure, NULL is
88235c4bbdfSmrg * returned.
88335c4bbdfSmrg */
88435c4bbdfSmrgInputOption *
88535c4bbdfSmrginput_option_new(InputOption *list, const char *key, const char *value)
88635c4bbdfSmrg{
88735c4bbdfSmrg    InputOption *opt = NULL;
88835c4bbdfSmrg
88935c4bbdfSmrg    if (!key)
89035c4bbdfSmrg        return NULL;
89135c4bbdfSmrg
89235c4bbdfSmrg    if (list) {
89335c4bbdfSmrg        nt_list_for_each_entry(opt, list, list.next) {
89435c4bbdfSmrg            if (strcmp(input_option_get_key(opt), key) == 0) {
89535c4bbdfSmrg                input_option_set_value(opt, value);
89635c4bbdfSmrg                return list;
89735c4bbdfSmrg            }
89835c4bbdfSmrg        }
89935c4bbdfSmrg    }
90035c4bbdfSmrg
90135c4bbdfSmrg    opt = calloc(1, sizeof(InputOption));
90235c4bbdfSmrg    if (!opt)
90335c4bbdfSmrg        return NULL;
90435c4bbdfSmrg
90535c4bbdfSmrg    nt_list_init(opt, list.next);
90635c4bbdfSmrg    input_option_set_key(opt, key);
90735c4bbdfSmrg    input_option_set_value(opt, value);
90835c4bbdfSmrg
90935c4bbdfSmrg    if (list) {
91035c4bbdfSmrg        nt_list_append(opt, list, InputOption, list.next);
91135c4bbdfSmrg
91235c4bbdfSmrg        return list;
91335c4bbdfSmrg    }
91435c4bbdfSmrg    else
91535c4bbdfSmrg        return opt;
91635c4bbdfSmrg}
91735c4bbdfSmrg
91835c4bbdfSmrgInputOption *
91935c4bbdfSmrginput_option_free_element(InputOption *list, const char *key)
92035c4bbdfSmrg{
92135c4bbdfSmrg    InputOption *element;
92235c4bbdfSmrg
92335c4bbdfSmrg    nt_list_for_each_entry(element, list, list.next) {
92435c4bbdfSmrg        if (strcmp(input_option_get_key(element), key) == 0) {
92535c4bbdfSmrg            nt_list_del(element, list, InputOption, list.next);
92635c4bbdfSmrg
92735c4bbdfSmrg            input_option_free(element);
92835c4bbdfSmrg            break;
92935c4bbdfSmrg        }
93035c4bbdfSmrg    }
93135c4bbdfSmrg    return list;
93235c4bbdfSmrg}
93335c4bbdfSmrg
93435c4bbdfSmrg/**
93535c4bbdfSmrg * Free the list pointed at by opt.
93635c4bbdfSmrg */
93735c4bbdfSmrgvoid
93835c4bbdfSmrginput_option_free_list(InputOption **opt)
93935c4bbdfSmrg{
94035c4bbdfSmrg    InputOption *element, *tmp;
94135c4bbdfSmrg
94235c4bbdfSmrg    nt_list_for_each_entry_safe(element, tmp, *opt, list.next) {
94335c4bbdfSmrg        nt_list_del(element, *opt, InputOption, list.next);
94435c4bbdfSmrg
94535c4bbdfSmrg        input_option_free(element);
94635c4bbdfSmrg    }
94735c4bbdfSmrg    *opt = NULL;
94835c4bbdfSmrg}
94935c4bbdfSmrg
95035c4bbdfSmrg/**
95135c4bbdfSmrg * Find the InputOption with the given option name.
95235c4bbdfSmrg *
95335c4bbdfSmrg * @return The InputOption or NULL if not present.
95435c4bbdfSmrg */
95535c4bbdfSmrgInputOption *
95635c4bbdfSmrginput_option_find(InputOption *list, const char *key)
95735c4bbdfSmrg{
95835c4bbdfSmrg    InputOption *element;
95935c4bbdfSmrg
96035c4bbdfSmrg    nt_list_for_each_entry(element, list, list.next) {
96135c4bbdfSmrg        if (strcmp(input_option_get_key(element), key) == 0)
96235c4bbdfSmrg            return element;
96335c4bbdfSmrg    }
96435c4bbdfSmrg
96535c4bbdfSmrg    return NULL;
96635c4bbdfSmrg}
96735c4bbdfSmrg
96835c4bbdfSmrgconst char *
96935c4bbdfSmrginput_option_get_key(const InputOption *opt)
97035c4bbdfSmrg{
97135c4bbdfSmrg    return opt->opt_name;
97235c4bbdfSmrg}
97335c4bbdfSmrg
97435c4bbdfSmrgconst char *
97535c4bbdfSmrginput_option_get_value(const InputOption *opt)
97635c4bbdfSmrg{
97735c4bbdfSmrg    return opt->opt_val;
97835c4bbdfSmrg}
97935c4bbdfSmrg
98035c4bbdfSmrgvoid
98135c4bbdfSmrginput_option_set_key(InputOption *opt, const char *key)
98235c4bbdfSmrg{
98335c4bbdfSmrg    free(opt->opt_name);
98435c4bbdfSmrg    if (key)
98535c4bbdfSmrg        opt->opt_name = strdup(key);
98635c4bbdfSmrg}
98735c4bbdfSmrg
98835c4bbdfSmrgvoid
98935c4bbdfSmrginput_option_set_value(InputOption *opt, const char *value)
99035c4bbdfSmrg{
99135c4bbdfSmrg    free(opt->opt_val);
99235c4bbdfSmrg    if (value)
99335c4bbdfSmrg        opt->opt_val = strdup(value);
99435c4bbdfSmrg}
99535c4bbdfSmrg
99635c4bbdfSmrg/* FP1616/FP3232 conversion functions.
99735c4bbdfSmrg * Fixed point types are encoded as signed integral and unsigned frac. So any
99835c4bbdfSmrg * negative number -n.m is encoded as floor(n) + (1 - 0.m).
99935c4bbdfSmrg */
100035c4bbdfSmrgdouble
100135c4bbdfSmrgfp1616_to_double(FP1616 in)
100235c4bbdfSmrg{
100335c4bbdfSmrg    return pixman_fixed_to_double(in);
100435c4bbdfSmrg}
100535c4bbdfSmrg
100635c4bbdfSmrgdouble
100735c4bbdfSmrgfp3232_to_double(FP3232 in)
100835c4bbdfSmrg{
100935c4bbdfSmrg    double ret;
101035c4bbdfSmrg
101135c4bbdfSmrg    ret = (double) in.integral;
101235c4bbdfSmrg    ret += (double) in.frac * (1.0 / (1ULL << 32));     /* Optimized: ldexp((double)in.frac, -32); */
101335c4bbdfSmrg    return ret;
101435c4bbdfSmrg}
101535c4bbdfSmrg
101635c4bbdfSmrgFP1616
101735c4bbdfSmrgdouble_to_fp1616(double in)
101835c4bbdfSmrg{
101935c4bbdfSmrg    return pixman_double_to_fixed(in);
102035c4bbdfSmrg}
102135c4bbdfSmrg
102235c4bbdfSmrgFP3232
102335c4bbdfSmrgdouble_to_fp3232(double in)
102435c4bbdfSmrg{
102535c4bbdfSmrg    FP3232 ret;
102635c4bbdfSmrg    int32_t integral;
102735c4bbdfSmrg    double tmp;
102835c4bbdfSmrg    uint32_t frac_d;
102935c4bbdfSmrg
103035c4bbdfSmrg    tmp = floor(in);
103135c4bbdfSmrg    integral = (int32_t) tmp;
103235c4bbdfSmrg
103335c4bbdfSmrg    tmp = (in - integral) * (1ULL << 32);       /* Optimized: ldexp(in - integral, 32) */
103435c4bbdfSmrg    frac_d = (uint32_t) tmp;
103535c4bbdfSmrg
103635c4bbdfSmrg    ret.integral = integral;
103735c4bbdfSmrg    ret.frac = frac_d;
103835c4bbdfSmrg    return ret;
103935c4bbdfSmrg}
104035c4bbdfSmrg
104135c4bbdfSmrg/**
104235c4bbdfSmrg * DO NOT USE THIS FUNCTION. It only exists for the test cases. Use
104335c4bbdfSmrg * xi2mask_new() instead to get the standard sized masks.
104435c4bbdfSmrg *
104535c4bbdfSmrg * @param nmasks The number of masks (== number of devices)
104635c4bbdfSmrg * @param size The size of the masks in bytes
104735c4bbdfSmrg * @return The new mask or NULL on allocation error.
104835c4bbdfSmrg */
104935c4bbdfSmrgXI2Mask *
105035c4bbdfSmrgxi2mask_new_with_size(size_t nmasks, size_t size)
105135c4bbdfSmrg{
105235c4bbdfSmrg    int i;
105335c4bbdfSmrg    int alloc_size;
105435c4bbdfSmrg    unsigned char *cursor;
105535c4bbdfSmrg    XI2Mask *mask;
105635c4bbdfSmrg
105735c4bbdfSmrg    alloc_size = sizeof(struct _XI2Mask)
105835c4bbdfSmrg	       + nmasks * sizeof(unsigned char *)
105935c4bbdfSmrg	       + nmasks * size;
106035c4bbdfSmrg
106135c4bbdfSmrg    mask = calloc(1, alloc_size);
106235c4bbdfSmrg
106335c4bbdfSmrg    if (!mask)
106435c4bbdfSmrg        return NULL;
106535c4bbdfSmrg
106635c4bbdfSmrg    mask->nmasks = nmasks;
106735c4bbdfSmrg    mask->mask_size = size;
106835c4bbdfSmrg
106935c4bbdfSmrg    mask->masks = (unsigned char **)(mask + 1);
107035c4bbdfSmrg    cursor = (unsigned char *)(mask + 1) + nmasks * sizeof(unsigned char *);
107135c4bbdfSmrg
107235c4bbdfSmrg    for (i = 0; i < nmasks; i++) {
107335c4bbdfSmrg        mask->masks[i] = cursor;
107435c4bbdfSmrg	cursor += size;
107535c4bbdfSmrg    }
107635c4bbdfSmrg    return mask;
107735c4bbdfSmrg}
107835c4bbdfSmrg
107935c4bbdfSmrg/**
108035c4bbdfSmrg * Create a new XI2 mask of the standard size, i.e. for all devices + fake
108135c4bbdfSmrg * devices and for the highest supported XI2 event type.
108235c4bbdfSmrg *
108335c4bbdfSmrg * @return The new mask or NULL on allocation error.
108435c4bbdfSmrg */
108535c4bbdfSmrgXI2Mask *
108635c4bbdfSmrgxi2mask_new(void)
108735c4bbdfSmrg{
108835c4bbdfSmrg    return xi2mask_new_with_size(EMASKSIZE, XI2MASKSIZE);
108935c4bbdfSmrg}
109035c4bbdfSmrg
109135c4bbdfSmrg/**
109235c4bbdfSmrg * Frees memory associated with mask and resets mask to NULL.
109335c4bbdfSmrg */
109435c4bbdfSmrgvoid
109535c4bbdfSmrgxi2mask_free(XI2Mask **mask)
109635c4bbdfSmrg{
109735c4bbdfSmrg    if (!(*mask))
109835c4bbdfSmrg        return;
109935c4bbdfSmrg
110035c4bbdfSmrg    free((*mask));
110135c4bbdfSmrg    *mask = NULL;
110235c4bbdfSmrg}
110335c4bbdfSmrg
110435c4bbdfSmrg/**
110535c4bbdfSmrg * Test if the bit for event type is set for this device only.
110635c4bbdfSmrg *
110735c4bbdfSmrg * @return TRUE if the bit is set, FALSE otherwise
110835c4bbdfSmrg */
110935c4bbdfSmrgBool
111035c4bbdfSmrgxi2mask_isset_for_device(XI2Mask *mask, const DeviceIntPtr dev, int event_type)
111135c4bbdfSmrg{
111235c4bbdfSmrg    BUG_WARN(dev->id < 0);
111335c4bbdfSmrg    BUG_WARN(dev->id >= mask->nmasks);
111435c4bbdfSmrg    BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size);
111535c4bbdfSmrg
111635c4bbdfSmrg    return BitIsOn(mask->masks[dev->id], event_type);
111735c4bbdfSmrg}
111835c4bbdfSmrg
111935c4bbdfSmrg/**
112035c4bbdfSmrg * Test if the bit for event type is set for this device, or the
112135c4bbdfSmrg * XIAllDevices/XIAllMasterDevices (if applicable) is set.
112235c4bbdfSmrg *
112335c4bbdfSmrg * @return TRUE if the bit is set, FALSE otherwise
112435c4bbdfSmrg */
112535c4bbdfSmrgBool
112635c4bbdfSmrgxi2mask_isset(XI2Mask *mask, const DeviceIntPtr dev, int event_type)
112735c4bbdfSmrg{
112835c4bbdfSmrg    int set = 0;
112935c4bbdfSmrg
113035c4bbdfSmrg    if (xi2mask_isset_for_device(mask, inputInfo.all_devices, event_type))
113135c4bbdfSmrg        set = 1;
113235c4bbdfSmrg    else if (xi2mask_isset_for_device(mask, dev, event_type))
113335c4bbdfSmrg        set = 1;
113435c4bbdfSmrg    else if (IsMaster(dev) && xi2mask_isset_for_device(mask, inputInfo.all_master_devices, event_type))
113535c4bbdfSmrg        set = 1;
113635c4bbdfSmrg
113735c4bbdfSmrg    return set;
113835c4bbdfSmrg}
113935c4bbdfSmrg
114035c4bbdfSmrg/**
114135c4bbdfSmrg * Set the mask bit for this event type for this device.
114235c4bbdfSmrg */
114335c4bbdfSmrgvoid
114435c4bbdfSmrgxi2mask_set(XI2Mask *mask, int deviceid, int event_type)
114535c4bbdfSmrg{
114635c4bbdfSmrg    BUG_WARN(deviceid < 0);
114735c4bbdfSmrg    BUG_WARN(deviceid >= mask->nmasks);
114835c4bbdfSmrg    BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size);
114935c4bbdfSmrg
115035c4bbdfSmrg    SetBit(mask->masks[deviceid], event_type);
115135c4bbdfSmrg}
115235c4bbdfSmrg
115335c4bbdfSmrg/**
115435c4bbdfSmrg * Zero out the xi2mask, for the deviceid given. If the deviceid is < 0, all
115535c4bbdfSmrg * masks are zeroed.
115635c4bbdfSmrg */
115735c4bbdfSmrgvoid
115835c4bbdfSmrgxi2mask_zero(XI2Mask *mask, int deviceid)
115935c4bbdfSmrg{
116035c4bbdfSmrg    int i;
116135c4bbdfSmrg
116235c4bbdfSmrg    BUG_WARN(deviceid > 0 && deviceid >= mask->nmasks);
116335c4bbdfSmrg
116435c4bbdfSmrg    if (deviceid >= 0)
116535c4bbdfSmrg        memset(mask->masks[deviceid], 0, mask->mask_size);
116635c4bbdfSmrg    else
116735c4bbdfSmrg        for (i = 0; i < mask->nmasks; i++)
116835c4bbdfSmrg            memset(mask->masks[i], 0, mask->mask_size);
116935c4bbdfSmrg}
117035c4bbdfSmrg
117135c4bbdfSmrg/**
117235c4bbdfSmrg * Merge source into dest, i.e. dest |= source.
117335c4bbdfSmrg * If the masks are of different size, only the overlapping section is merged.
117435c4bbdfSmrg */
117535c4bbdfSmrgvoid
117635c4bbdfSmrgxi2mask_merge(XI2Mask *dest, const XI2Mask *source)
117735c4bbdfSmrg{
117835c4bbdfSmrg    int i, j;
117935c4bbdfSmrg
118035c4bbdfSmrg    for (i = 0; i < min(dest->nmasks, source->nmasks); i++)
118135c4bbdfSmrg        for (j = 0; j < min(dest->mask_size, source->mask_size); j++)
118235c4bbdfSmrg            dest->masks[i][j] |= source->masks[i][j];
118335c4bbdfSmrg}
118435c4bbdfSmrg
118535c4bbdfSmrg/**
118635c4bbdfSmrg * @return The number of masks in mask
118735c4bbdfSmrg */
118835c4bbdfSmrgsize_t
118935c4bbdfSmrgxi2mask_num_masks(const XI2Mask *mask)
119035c4bbdfSmrg{
119135c4bbdfSmrg    return mask->nmasks;
119235c4bbdfSmrg}
119335c4bbdfSmrg
119435c4bbdfSmrg/**
119535c4bbdfSmrg * @return The size of each mask in bytes
119635c4bbdfSmrg */
119735c4bbdfSmrgsize_t
119835c4bbdfSmrgxi2mask_mask_size(const XI2Mask *mask)
119935c4bbdfSmrg{
120035c4bbdfSmrg    return mask->mask_size;
120135c4bbdfSmrg}
120235c4bbdfSmrg
120335c4bbdfSmrg/**
120435c4bbdfSmrg * Set the mask for the given deviceid to the source mask.
120535c4bbdfSmrg * If the mask given is larger than the target memory, only the overlapping
120635c4bbdfSmrg * parts are copied.
120735c4bbdfSmrg */
120835c4bbdfSmrgvoid
120935c4bbdfSmrgxi2mask_set_one_mask(XI2Mask *xi2mask, int deviceid, const unsigned char *mask,
121035c4bbdfSmrg                     size_t mask_size)
121135c4bbdfSmrg{
121235c4bbdfSmrg    BUG_WARN(deviceid < 0);
121335c4bbdfSmrg    BUG_WARN(deviceid >= xi2mask->nmasks);
121435c4bbdfSmrg
121535c4bbdfSmrg    memcpy(xi2mask->masks[deviceid], mask, min(xi2mask->mask_size, mask_size));
121635c4bbdfSmrg}
121735c4bbdfSmrg
121835c4bbdfSmrg/**
121935c4bbdfSmrg * Get a reference to the XI2mask for this particular device.
122035c4bbdfSmrg */
122135c4bbdfSmrgconst unsigned char *
122235c4bbdfSmrgxi2mask_get_one_mask(const XI2Mask *mask, int deviceid)
122335c4bbdfSmrg{
122435c4bbdfSmrg    BUG_WARN(deviceid < 0);
122535c4bbdfSmrg    BUG_WARN(deviceid >= mask->nmasks);
122635c4bbdfSmrg
122735c4bbdfSmrg    return mask->masks[deviceid];
122835c4bbdfSmrg}
1229