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